Открытие рецепта через достижение

Версия Minecraft
1.7.10
769
1
42
Добрый вечер, ребята. Можете подсказать, как использовать полученное достижение для разблокировки рецепта? Что я хочу - мне нужно получить какое-то достижение, допустим после крафта верстака, которое откроет доступ к рецепту деревянной кирки (например). Если у вас есть какие-нибудь ссылки, источники, либо примеры реализации в других модах - просьба ответить. Я нашел что-то связанное с этим:
Java:
public static Minecraft mc = FMLClientHandler.instance().getClient();
if (mc.thePlayer.getStatFileWriter().hasAchievementUnlocked(CoreAchievements.machineAch)) {
                RecipeUtil.addRecipe(new ItemStack(CoreBlocks.MachineMacerator), new Object[]{ "DQD", "GEG", "SAS",
                        'E', new ItemStack(CoreBlocks.MachineObject),
                        'A', new ItemStack(GCItems.basicItem, 1, 14),
                        'S', "ingotIron",
                        'G', new ItemStack(Blocks.glass),
                        'D', "ingotTin",
                        'Q', new ItemStack(CoreItems.CapaciousBattery)});
}
Пытаюсь выполнить такой код, но очевидно, что бред.
 
7,099
324
1,510
На самом деле все просто. Обычный рецепт обворачивешь в свой IRecipe, который позволяет скрафтить только если у игрока есть ачивка
~~~
Поздравляю с возвращением в моддинг)
 
7,099
324
1,510
Зачем именно от форменных? Лучше от IRecipe, чтобы не было конкретизации
 
5,018
47
783
О такой же как я легендарный разработчик никому не известных аддонов под галактик вернулся. Идея кстати интересная
 
5,018
47
783

tox1cozZ

aka Agravaine
8,455
598
2,892
Нет. Minecraft#thePlayer - это EntityClientPlayerMP, дочерний класс EntityPlayer, в котором могут быть свои добавленные методы.
Соответственно достать методы EntityClientPlayerMP из EntityPlayer без приведения типа не выйдет.
 
769
1
42
Да, действительно, наклеветал, пардон. В общем, пытался я сделать хоть как-то, но не выходит. Я подумал, что нужно создавать свой отдельный рецепт и создал по типу shapeless, но рецепты не пашут, не знаю что придумать, в голову ниче не лезет
Java:
    @Override
    public boolean matches(InventoryCrafting inv, World world) {
        EntityPlayer player = findPlayer(inv);
//        if (player != null && checkAchv(player, CoreAchievements.machineAch)) {
//            return this.objectRecipe.matches(inv, world);
//        }
//        return false;
        
        ArrayList arraylist = new ArrayList(this.recipeList);//метод из shapeless
        for (int i = 0; i < 3; ++i) {
            for (int j = 0; j < 3; ++j) {
                ItemStack itemstack = inv.getStackInRowAndColumn(j, i);
                if (itemstack != null) {
                    boolean flag = false;
                    Iterator iterator = arraylist.iterator();

                    while (iterator.hasNext()) {
                        ItemStack itemstack1 = (ItemStack)iterator.next();
                        if (itemstack.getItem() == itemstack1.getItem() && (itemstack1.getItemDamage() == 32767 || itemstack.getItemDamage() == itemstack1.getItemDamage())) {
                            if (player != null && checkAchv(player, CoreAchievements.machineAch)) {
                                flag = true;
                                arraylist.remove(itemstack1);
                                break;
                            }
                        }
                    }
                    if (!flag) {
                        return false;
                    }
                }
            }
        }
        return arraylist.isEmpty();
    }
    
    public boolean checkAchv(EntityPlayer player, Achievement ach) {
        if (player instanceof EntityPlayerMP && ((EntityPlayerMP)player).func_147099_x() != null) {
            StatisticsFile stats = ((EntityPlayerMP)player).func_147099_x();
            return stats.hasAchievementUnlocked(ach);
        }
        return false;
    }
 
7,099
324
1,510
Мы же обсуждали в лс, как это нужно сделать.
Допустим, ты сделал какой-то рецепт и хочешь, чтобы его могли крафтить только при наличии ачивки.
Тогда ты создаешь свой класс рецепта, который расширяет IRecipe:
Java:
class AchivmentRecipe implements IRecipe{
    private IRecipe baseRecipe
    public AchivmentRecipe(IRecipe baseRecipe){
        this.baseRecipe=baseRecipe;
    }
}
И методы, которые ты должен реализовать делаешь через делегацию baseRecipe, с добавлением своих ограничений по ачивке
Java:
public boolean matches(InventoryCrafting inv, World world) {
    return baseRecipe.matches(inv,world) && checkAchv(findPlayer(inv), CoreAchievements.machineAch); //ачивку стоит передавать через конструктор, если у тебя не одна

}

getResultStack и остальные методы реализовываешь через просто делегирование baseRecipe
 
769
1
42
Сори за тупой вопрос. Но неужели мне придется для каждого рецепта создавать отдельный класс? Окей, я сделал как пытался делать ранее но уже с ачивкой.
Java:
package vacuum.core.handler;

import java.lang.reflect.Field;

import com.google.common.base.Throwables;

import cpw.mods.fml.relauncher.ReflectionHelper;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.ContainerPlayer;
import net.minecraft.inventory.ContainerWorkbench;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.inventory.SlotCrafting;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.stats.Achievement;
import net.minecraft.stats.StatisticsFile;
import net.minecraft.world.World;
import vacuum.core.CoreAchievements;

public class CoreRecipeHandler implements IRecipe {
    
    private IRecipe baseRecipe;
    
    public CoreRecipeHandler(IRecipe baseRecipe){
        this.baseRecipe = baseRecipe;
    }
    
    @Override
    public boolean matches(InventoryCrafting inv, World world) {
        return baseRecipe.matches(inv, world) && checkAchv(findPlayer(inv), CoreAchievements.machineAch);
    }
    
    public boolean checkAchv(EntityPlayer player, Achievement ach) {
        if (player instanceof EntityPlayerMP && ((EntityPlayerMP)player).func_147099_x() != null) {
            StatisticsFile stats = ((EntityPlayerMP)player).func_147099_x();
            return stats.hasAchievementUnlocked(ach);
        }
        return false;
    }

    @Override
    public ItemStack getCraftingResult(InventoryCrafting inv) {
        return this.baseRecipe.getCraftingResult(inv);
    }

    @Override
    public int getRecipeSize() {
        return this.baseRecipe.getRecipeSize();
    }

    @Override
    public ItemStack getRecipeOutput() {
        return this.baseRecipe.getRecipeOutput();
    }
}
Что теперь? У меня есть рецепт, пусть будет такой:
Java:
GameRegistry.addRecipe(new ItemStack(CoreBlocks.CoreBlock, 4, 0), new Object[]{ "   ", " XX", " HH",
            'X', Blocks.gravel,
            'H', new ItemStack(CoreItems.Item, 1, 0)});
Мне его надо связать как-то с CoreRecipeHandler. Я еще тогда застопорился на этом моменте, ибо не понимал как обвязать.
 
Сверху