Крафт

Версия Minecraft
1.12.2

sk9zist :l

Исправился
981
18
157
А можно как-нибудь задавать NBT предмета, участвовавшего в крафте тому предмету, который мы скрафтили?
 
7,099
324
1,510
При помощи кастомного IRecipe. Полного гайда не припомню, могу лишь посоветовать наследовать свои рецепты extrends IForgeRegistryEntry.Impl[IRecipe] implements IRecipe, экземпляры регать через события
 

sk9zist :l

Исправился
981
18
157

sk9zist :l

Исправился
981
18
157
3,005
192
592
У тебя есть свой IRecipe, т.е. свой рецепт.
Ты как хочешь, так и делаешь.
Хочешь изменить NBT - так изменяй NBT.
 
7,099
324
1,510
Чем мне поможет IRecipe?
Тем, что ты сможешь переопределить matches и написать какую угодно проверку, подходит ли сетка крафта для этого крафта
И тем, что сможешь переопределить getCraftingResult, возвращая стак, зависящий любым образом от сетки крафта, каким тебе захочется
 

sk9zist :l

Исправился
981
18
157
Recipe.java:
public class Recipe extends net.minecraftforge.registries.IForgeRegistryEntry.Impl<IRecipe> implements IRecipe
{
    private ItemStack item;
    private ItemStack result;

    @Override
    public boolean matches(InventoryCrafting inv, World worldIn)
    {
        item = null;
        for(int i = 0; i < inv.getSizeInventory(); i++)
        {
            ItemStack stack = inv.getStackInSlot(i);
            if(stack != null)
            {
                if(stack.getItem() == RunesCollector.redirection_rune){item = stack;}
            }
        }
        return false;
    }

    @Override
    public ItemStack getCraftingResult(InventoryCrafting inv)
    {
        if(item == null) return null;
        ItemStack in = item.copy();
        ItemStack out = item.copy();
        String a_player = in.getTagCompound().getString("lastRemembered");
        out.getTagCompound().setString("lastRemembered", a_player);
        return out;
    }

    @Override
    public ItemStack getRecipeOutput()
    {
        if(item == null) return null;
        ItemStack in = item.copy();
        ItemStack out = item.copy();
        String a_player = in.getTagCompound().getString("lastRemembered");
        out.getTagCompound().setString("lastRemembered", a_player);
        return out;
    }

    @Override
    public boolean canFit(int width, int height)
    {
        return false;
    }
}

Registration.java:
@Mod.EventBusSubscriber(modid = "abc")
public class Registration
{
    @SubscribeEvent
    public static void registerRecipes(RegistryEvent.Register<IRecipe> event)
    {
        event.getRegistry().register(new Recipe());
        Log.info("recipes are registered");
    }
}

вот дапустим сделал. Итог конечно краш. А где тут регать сам крафт рецепта?
 
1,038
57
229
extends IRecipe implements IRecipe
простите, не удержался.. это надо в топ бездны запостить на bash.org

вообщето надо было просто
implements IRecipe

Потому что буква I в названии класса обычно означает Interface, то есть этот файл никак не может быть классом и от него нельзя произвести наследование коим является extends. Все интерфейсы подключаются по implements в твой класс и именно они заставляют тебя объявить в классе методы, в которых ты и укажешь что должен возвращать.
А лучше самому почитать Java наследование

 
Последнее редактирование:

sk9zist :l

Исправился
981
18
157
надо было просто
implements IRecipe
Извините, но я исследовал несколько тем, посвящённых вопросам о IRecipe, одной из них была:
Там говорилось обратное. Но ладно.
И разве если я имплементирую чисто IRecipe (в первый раз я так и делал)
мне не приходиться добавлять ещё некоторые методы?
screenshot.12268.jpg
Ладно. Такой код:
IRecipe.java (redacted):
public class Recipe implements IRecipe
{
    private ItemStack item;
    private ItemStack result;

    @Override
    public boolean matches(InventoryCrafting inv, World worldIn)
    {
        item = null;
        for(int i = 0; i < inv.getSizeInventory(); i++)
        {
            ItemStack stack = inv.getStackInSlot(i);
            if(stack != null)
            {
                if(stack.getItem() == RunesCollector.redirection_rune){item = stack;}
            }
        }
        return false;
    }

    @Override
    public ItemStack getCraftingResult(InventoryCrafting inv)
    {
        if(item == null) return null;
        ItemStack in = item.copy();
        ItemStack out = item.copy();
        String a_player = in.getTagCompound().getString("lastRemembered");
        out.getTagCompound().setString("lastRemembered", a_player);
        return out;
    }

    @Override
    public ItemStack getRecipeOutput()
    {
        if(item == null) return null;
        ItemStack in = item.copy();
        ItemStack out = item.copy();
        String a_player = in.getTagCompound().getString("lastRemembered");
        out.getTagCompound().setString("lastRemembered", a_player);
        return out;
    }

    @Override
    public boolean canFit(int width, int height)
    {
        return false;
    }

    @Override
    public IRecipe setRegistryName(ResourceLocation name)
    {
        return null;
    }

    @Override
    public ResourceLocation getRegistryName()
    {
        return null;
    }

    @Override
    public Class<IRecipe> getRegistryType()
    {
        return null;
    }
}
Всё равно краш..
Time: 11/13/19 12:48 PM
Description: Initializing game

java.lang.NullPointerException: Initializing game
at net.minecraft.client.util.RecipeBookClient.getItemStackTab(RecipeBookClient.java:43)
at net.minecraft.client.util.RecipeBookClient.rebuildTable(RecipeBookClient.java:71)
at net.minecraftforge.fml.client.FMLClientHandler.resetClientRecipeBook(FMLClientHandler.java:1080)
at net.minecraftforge.fml.common.FMLCommonHandler.resetClientRecipeBook(FMLCommonHandler.java:774)
at net.minecraftforge.common.crafting.CraftingHelper.loadRecipes(CraftingHelper.java:626)
at net.minecraftforge.fml.common.Loader.initializeMods(Loader.java:742)
at net.minecraftforge.fml.client.FMLClientHandler.finishMinecraftLoading(FMLClientHandler.java:336)
at net.minecraft.client.Minecraft.init(Minecraft.java:581)
at net.minecraft.client.Minecraft.run(Minecraft.java:421)
at net.minecraft.client.main.Main.main(Main.java:118)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
at net.minecraft.launchwrapper.Launch.main(Launch.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97)
at GradleStart.main(GradleStart.java:25)


A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------

-- Head --
Thread: Client thread
Stacktrace:
at net.minecraft.client.util.RecipeBookClient.getItemStackTab(RecipeBookClient.java:43)
at net.minecraft.client.util.RecipeBookClient.rebuildTable(RecipeBookClient.java:71)
at net.minecraftforge.fml.client.FMLClientHandler.resetClientRecipeBook(FMLClientHandler.java:1080)
at net.minecraftforge.fml.common.FMLCommonHandler.resetClientRecipeBook(FMLCommonHandler.java:774)
at net.minecraftforge.common.crafting.CraftingHelper.loadRecipes(CraftingHelper.java:626)
at net.minecraftforge.fml.common.Loader.initializeMods(Loader.java:742)
at net.minecraftforge.fml.client.FMLClientHandler.finishMinecraftLoading(FMLClientHandler.java:336)
at net.minecraft.client.Minecraft.init(Minecraft.java:581)

-- Initialization --
Details:
Stacktrace:
at net.minecraft.client.Minecraft.run(Minecraft.java:421)
at net.minecraft.client.main.Main.main(Main.java:118)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
at net.minecraft.launchwrapper.Launch.main(Launch.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97)
at GradleStart.main(GradleStart.java:25)
 
Последнее редактирование:

ReyMagos

Тег-бомбастер
412
7
121
1) У тебя в matches() всегда возвращается false. Делай true если крафт подошёл и false если нет.
2) canFit() (перевод "может вместиться") возвращает всегда false, подумай над этим...
3) Твой рецепт должен наследовать IForgeRegistryEntry<IRecipe>
4) Переопределять последние три метода не обязательно (не нужно (прям не надо) от англ. НЕ НАДО)
5) У твоего рецепта обязательно должно быть имя (не null). recipe.setRegistryName("name");
Как-то так.
 

sk9zist :l

Исправился
981
18
157
наследовать IForgeRegistryEntry<IRecipe>
Пробовал. А вообще я много разных способов перепробовал. Теперь краш всегда один и тот-же.
Да уж... Непонятнка. Хотя даже интересно, почему.
 

sk9zist :l

Исправился
981
18
157
А, забыл, вот кстати код (напоследок):

Java:
public class Recipe implements IForgeRegistryEntry<IRecipe>, IRecipe
{
    private ItemStack item;
    private ItemStack result;

    public boolean matches(InventoryCrafting inv, World worldIn)
    {
        item = null;
        for(int i = 0; i < inv.getSizeInventory(); i++)
        {
            ItemStack stack = inv.getStackInSlot(i);
            if(stack != null)
            {
                if(stack.getItem() == RunesCollector.redirection_rune){item = stack;}
            }
        }
        if(item != null)return true;
        return false;
    }

    public ItemStack getCraftingResult(InventoryCrafting inv)
    {
        if(item == null) return null;
        ItemStack in = item.copy();
        ItemStack out = item.copy();
        String a_player = in.getTagCompound().getString("lastRemembered");
        out.getTagCompound().setString("lastRemembered", a_player);
        return out;
    }

    public ItemStack getRecipeOutput()
    {
        if(item == null) return null;
        ItemStack in = item.copy();
        ItemStack out = item.copy();
        String a_player = in.getTagCompound().getString("lastRemembered");
        out.getTagCompound().setString("lastRemembered", a_player);
        return out;
    }

    public boolean canFit(int width, int height) { return width > 1 && height > 1; }

    public IRecipe setRegistryName(ResourceLocation name) { return null; }

    public ResourceLocation getRegistryName() { return new ResourceLocation("abc:recipe"); }

    public Class<IRecipe> getRegistryType() { return this.getRegistryType(); }
}
 
1,038
57
229
Там говорилось обратное. Но ладно.
И разве если я имплементирую чисто IRecipe (в первый раз я так и делал)
А это чо за хрень?
Тя на аватарке кто-то долбит в задницу? (у меня уже слов не хватает о твоих познаниях в Java). Скорее всего это даже грубо, но пусть лучше я об этом скажу..
можете смело давать мне нарушение
bcbbce7ff8.jpg

И где ты задаешь свой IReciepe.item?
Изначально он равен null, соответственно срабатывает это условие (везде!!!) и что мы имеем? правильно
java.lang.NullPointerException: Initializing game

А это краткий анализ
afce163e02.jpg
 
Последнее редактирование:

sk9zist :l

Исправился
981
18
157
Изначально он равен null, соответственно срабатывает это условие
изначально он равен null, так как item = null;
потом stack присваивается item.
А потом уже if(item = null) return null; (если проверка не прошла и stack не присвоился item)

или я что-то опять туплю, да?(
 
1,038
57
229
И когда мы туда попадаем? в какой момент он там появляется не Null?
Убирай весь код. Сделай класс пустым, а затем нажми на тот самый add unimplement methods
screenshot-12268-jpg.6891

А затем сделай как здесь. Custom IRecipe Class
И когда мы убедимся, что твой рецепт работает.. вообще работает, перейдем к следующему этапу
 

sk9zist :l

Исправился
981
18
157
И когда мы туда попадаем?
а... Вот в этой строке..
Java:
if(stack.getItem() == RunesCollector.redirection_rune){item = stack;}
а!! Понял, в первый раз там должно было быть так:
Java:
if(stack.getItem() == result.getItem()){item = stack;}
 

tox1cozZ

aka Agravaine
8,456
598
2,893
Вот тут задается этот стак.
1573645176427.png

У вас крашит из-за того что НЕЛЬЗЯ в 1.12 возвращать нулл в качестве стака. Нужно вместо нулл возвращать ItemStack.EMPTY. А проверка стака делается через ItemStack#isEmpty(), а не ItemStack == null.
 
7,099
324
1,510
Можно юзать это как пример.
Чекни класс RegistryEvents
 
Сверху