Крафты с учётом nbt в Таумкрафт 4.2.3.5 Нужна помощь!

В своём аддоне к таумкрафт 4.2.3.5 решил сделать крафты эссенций как у их аспектам(т.е. эссенция Victus = Aqua + Terra например). Реализовывал это так: сделал к каждой эссенции переменную ItemStack и ей задал аспекты. Пример:

ItemStack essWEATHER = new ItemStack(ConfigItems.itemEssence, 1, 1);

setAspects(essWEAPON, new AspectList().add(Aspect.WEATHER, 8));

Сам метод "setAspects" скопировал из таума. Вот он:

public static void setAspects(ItemStack itemstack, AspectList aspects)


{

if (!itemstack.hasTagCompound())

itemstack.setTagCompound(new NBTTagCompound());

aspects.writeToNBT(itemstack.getTagCompound());


}

Добавил крафт:
GameRegistry.addRecipe(essENERGY, new Object[]{ "FO ", " ", " ", ('F'), essFIRE, ('O'), essORDER });

Здесь: essENERGY - пузырёк с эссенцией "Potentia", essFIRE - "Ignis", essORDER - "Ordo".

Итак, крафтится действительно пузырёк с Potentia, но из любых пузырьков(т.е. из пузырьков с любой эссенцией).

Как это можно, да и можно ли вообще, исправить? Спасибо!
 
Вставляй код на форум с помощью этой кнопки:
h_1456662828_2721983_c5bc163655.png

Так его будет намного удобнее читать.

Посмотри класс ShapedRecipes или ShapedOreRecipe, там нет сравнения NBT. Тебе придется сделать свой класс рецепта, имплементирующий интерфейс IRecipe.
 
Asd73 написал(а):
Тебе придется сделать свой класс рецепта, имплементирующий интерфейс IRecipe.
А ссылку на какой-нибудь гайд можно, если таковой имеется? Не представляю, что это такое...
 
Гайд это хорошо, но наверняка не даст полного понимания, без которого будут возникать подобные вопросы.
Тебе стоит самому внимательно изучить как работают рецепты. Это не столь сложно, не требуется каких-то особых знаний (в отличие от графики, генерации), требуется только понимание ООП.

Я думаю, что тебе стоит делать бесформенный рецепт, а не такой как сейчас.
Попробую вкратце объяснить как работают рецепты. В классе CraftingManager есть список recipes, в который заносятся рецепты - объекты наследники IRecipe
При помещении в сетку крафта предметов, эта сетка по очереди дается этим объектам, пока какой-нибудь рецепт не ответит - "совпало!". Ну приблизительно как-то так.

Теперь посмотрим интерфейс IRecipe. В нем всего 4 метода.
boolean matches() очевидно должен отвечать совпало или нет.
ItemStack getCraftingResult() - результат крафта. Разумеется должен создавать новый ItemStack, а не выдавать ранее созданный.
int getRecipeSize(); - количество предметов из которых крафтим
ItemStack getRecipeOutput() результат рецепта. Этот итемстак не попадает в инвентарь игрока, он используется лишь для отображения в сетке крафта.

Я это не делал, поэтому за правильность не отвечаю.
Искать примеры и гайды тут нужно по ключевому слову "implements IRecipe".
[merge_posts_bbcode]Добавлено: 28.02.2016 20:24:22[/merge_posts_bbcode]

А не ты ли это http://minecrafting.ru/topic/10454/page-61#entry584774 ?
 
Asd73 написал(а):
Гайд это хорошо, но наверняка не даст полного понимания, без которого будут возникать подобные вопросы.
Тебе стоит самому внимательно изучить как работают рецепты. Это не столь сложно, не требуется каких-то особых знаний (в отличие от графики, генерации), требуется только понимание ООП.
Вот, сделал, но всё по-старому.

Код:
public class IRecipeEssence implements IRecipe{
    
    private final ItemStack recipeOutput;
    public final ArrayList recipeItems = new ArrayList();;

    
    public IRecipeEssence()
    {
        
        ItemStack essWATER = new ItemStack(ConfigItems.itemEssence, 1, 1);
        ItemEssenseCrafting.setAspects(essWATER, new AspectList().add(Aspect.WATER, 8));
        ItemStack essEARTH = new ItemStack(ConfigItems.itemEssence, 1, 1);
        ItemEssenseCrafting.setAspects(essEARTH, new AspectList().add(Aspect.EARTH, 8));
        ItemStack essHEAL = new ItemStack(ConfigItems.itemEssence, 1, 1);
        ItemEssenseCrafting.setAspects(essHEAL, new AspectList().add(Aspect.HEAL, 8));
        
        
        
        this.recipeOutput = essHEAL;
        this.recipeItems.add(essEARTH);
        this.recipeItems.add(essWATER);
    }
    
    
    
    @Override
    public boolean matches(InventoryCrafting inv, World world) {
        ArrayList arraylist = new ArrayList(this.recipeItems);

        
        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())
                        {
                            flag = true;
                            arraylist.remove(itemstack1);
                            break;
                        }
                    }

                    if (!flag)
                    {
                        return false;
                    }
                }
            }
        }

        return arraylist.isEmpty();

    }

    @Override
    public ItemStack getCraftingResult(InventoryCrafting inv) {
        // TODO Auto-generated method stub
        ItemStack essAIR = new ItemStack(ConfigItems.itemEssence, 1, 1);
        ItemEssenseCrafting.setAspects(essAIR, new AspectList().add(Aspect.AIR, 8));
        
        return this.recipeOutput.copy();
    }

    @Override
    public int getRecipeSize() {
        // TODO Auto-generated method stub
        return this.recipeItems.size();
    }

    @Override
    public ItemStack getRecipeOutput() {
        // TODO Auto-generated method stub
        return null;
    }
    
    
    
 
И где ты в методе matches сверяешь NBT? Ты понимаешь, что делает скопированный тобой код? Если хочешь, чтобы заработало, не копируй код, работу которого не понимаешь.
Класс IRecipeEssence зря так назвал, т.к. подобным образом называют интерфейсы. Также тебе стоит делать бесформенный рецепт, ведь все равно в каком порядке смешивать (не серную кислоту разводим).

Что-то мне кажется, что и с джавой ты не в должной мере разобрался.
Например:

Код:
NBTTagCompound nbt1 = new NBTTagCompound();
nbt1.setInteger("test", 123);
NBTTagCompound nbt2 = new NBTTagCompound();
nbt2.setInteger("test", 123);
System.out.println("NBT test: " + (nbt1 == nbt2));

Если не сможешь не запуская это сказать что будет, то тебе не стоит пытаться написать этот рецепт.

Иногда создается впечатление, что многие посетители этого форума относятся к коду как... к заклинаниям!
 
Asd73 написал(а):
И где ты в методе matches сверяешь NBT? Ты понимаешь, что делает скопированный тобой код? Если хочешь, чтобы заработало, не копируй код, работу которого не понимаешь.
Класс IRecipeEssence зря так назвал, т.к. подобным образом называют интерфейсы. Также тебе стоит делать бесформенный рецепт, ведь все равно в каком порядке смешивать (не серную кислоту разводим).

Что-то мне кажется, что и с джавой ты не в должной мере разобрался.
Например:

Код:
NBTTagCompound nbt1 = new NBTTagCompound();
nbt1.setInteger("test", 123);
NBTTagCompound nbt2 = new NBTTagCompound();
nbt2.setInteger("test", 123);
System.out.println("NBT test: " + (nbt1 == nbt2));

Если не сможешь не запуская это сказать что будет, то тебе не стоит пытаться написать этот рецепт.

Иногда создается впечатление, что многие посетители этого форума относятся к коду как... к заклинаниям!
Я вот так попробовал сделать, но не помогло(вообще не стал крафтиться)
Было:
Код:
if (itemstack.getItem() == itemstack1.getItem()) 
                        {
                            
                            flag = true;
                            arraylist.remove(itemstack1);
                            break;
                        }
Стало:
Код:
if (itemstack.getItem() == itemstack1.getItem()) 
                        {
                            
                            if (itemstack.getTagCompound() == (itemstack1.getTagCompound()))
                            {
                            flag = true;
                            arraylist.remove(itemstack1);
                            break;
                            }
                        }
Т.е. добавил проверку таг'ов. Если не ошибаюсь, то nbt составляющая по большей части тут(после работы с модом nbtedit помню про таги)
[merge_posts_bbcode]Добавлено: 28.02.2016 21:19:41[/merge_posts_bbcode]

Asd73 написал(а):
Также тебе стоит делать бесформенный рецепт, ведь все равно в каком порядке смешивать (не серную кислоту разводим).
Он и так shapeless )
 
Таким образом сравнивать NBT нельзя. Я же привел пример, попробуй его выполнить.
Оператор == вернет истину только когда переменные указывают на один объект (NBTTagCompound).

А нет ли там getAspects? В конечном итоге все равно придется сравнивать аспекты.
 
Asd73 написал(а):
А нет ли там getAspects?
Нет
[merge_posts_bbcode]Добавлено: 28.02.2016 21:33:30[/merge_posts_bbcode]

Код:
NBTTagCompound nbt1 = new NBTTagCompound();
nbt1.setInteger("test", 123);
NBTTagCompound nbt2 = new NBTTagCompound();
nbt2.setInteger("test", 123);
System.out.println("NBT test: " + (nbt1 == nbt2));
Я так понимаю, вы это предлагаете? Просто "не запуская" мне кажется, что это просто выведет "тра-та-та: true", если nbt1 = nbt2, а они равны т.к. параметр "test" = 123 у каждого.

[merge_posts_bbcode]Добавлено: 28.02.2016 21:39:28[/merge_posts_bbcode]

Так, включив под вечер голову, я начинаю понимать. Вы имеете в виду:
Код:
NBTTagCompound nbt1 = new NBTTagCompound();
                            NBTTagCompound nbt2 = new NBTTagCompound();
                            
                            if (nbt1.getCompoundTag("Aspects") == nbt2.getCompoundTag("Aspects")) {
                            flag = true;
                            arraylist.remove(itemstack1);
                            break;
                            }

Но, как тут теперь приравнять nbt1 и 2 к аспектам предметов?
 
Не будет там true, потому что hashCode() вернут разные значения. Можно сравнивать через equals(), он там переопределен так как требуется.
Это основы, не зная которых будут возникать подобные вопросы. https://habrahabr.ru/post/168195/

Wayfarer написал(а):
Но, как тут теперь приравнять nbt1 и 2 к аспектам предметов?
Не знаю, я в код таумкрафта не заглядывал.
 
Да, я сказал ерунду. == действительно сравнивает ссылки.
Но equals() у Object (то есть "по умолчанию") тоже сравнивает ссылки.
 
Решил проблему - просто добавил крафт через таум api. Спасибо всем за помощь.
 
Asd73 написал(а):
Да, я сказал ерунду. == действительно сравнивает ссылки.
Но equals() у Object (то есть "по умолчанию") тоже сравнивает ссылки.
Там где надо, сравниваются именно объекты. Пример String.
 
Назад
Сверху