Убрать блок в тег, а потом достать.

Версия Minecraft
1.12.2
5,020
47
784
Здравствуйте! Появилась небольшая проблема: раньше я с тегами никогда не работал, и вот понадобилось. Собственно, я никак не могу понять, каким образом мне получать значение имени и сетать блок по его registryName. Но перед этим еще конечно хочется узнать, почему если я в одном методе в нбт сохраняю ключ, то он в него не сохраняется и в другом методе его уже не достать...

Java:
  public boolean onBlockDestroyed(ItemStack stack, World worldIn, IBlockState state, BlockPos pos, EntityLivingBase entityLiving)
    {
        ItemStack destroyBlock = new ItemStack(Item.getItemFromBlock(state.getBlock()));
        
        
        NBTTagCompound newtag = new NBTTagCompound();
        
        newtag.setString("filled", destroyBlock.getUnlocalizedName());
    
        
        
        System.out.println(stack + " ___ " + newtag);

        return true;
    }
    public EnumActionResult onItemUse(EntityPlayer player, World worldIn, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ)
    {
        ItemStack stack = player.getActiveItemStack();
        System.out.println(stack + " ___ " + stack.getTagCompound().getString("filled"));

        return EnumActionResult.PASS;
    }
 
Краш-лог
[13:42:11] [main/FATAL] [minecraft/Minecraft]: Unreported exception thrown!
java.lang.NullPointerException: null
at com.xumuk.realism.items.tools.BasicShowel.onItemUse(BasicShowel.java:62) ~[BasicShowel.class:?]
at net.minecraft.item.ItemStack.onItemUse(ItemStack.java:201) ~[ItemStack.class:?]
at net.minecraft.client.multiplayer.PlayerControllerMP.processRightClickBlock(PlayerControllerMP.java:509) ~[PlayerControllerMP.class:?]
at net.minecraft.client.Minecraft.rightClickMouse(Minecraft.java:1693) ~[Minecraft.class:?]
at net.minecraft.client.Minecraft.processKeyBinds(Minecraft.java:2380) ~[Minecraft.class:?]
at net.minecraft.client.Minecraft.runTickKeyboard(Minecraft.java:2146) ~[Minecraft.class:?]
at net.minecraft.client.Minecraft.runTick(Minecraft.java:1934) ~[Minecraft.class:?]
at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1187) ~[Minecraft.class:?]
at net.minecraft.client.Minecraft.run(Minecraft.java:441) [Minecraft.class:?]
at net.minecraft.client.main.Main.main(Main.java:118) [Main.class:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_191]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_191]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_191]
at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_191]
at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.12.jar:?]
at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.12.jar:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_191]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_191]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_191]
at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_191]
at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97) [start/:?]
at GradleStart.main(GradleStart.java:25) [start/:?]
[13:42:11] [main/INFO] [STDOUT]: [net.minecraft.init.Bootstrap:printToSYSOUT:629]: ---- Minecraft Crash Report ----
// This is a token for 1 free hug. Redeem at your nearest Mojangsta: [~~HUG~~]

Time: 9/28/19 1:42 PM
Description: Unexpected error

java.lang.NullPointerException: Unexpected error
at com.xumuk.realism.items.tools.BasicShowel.onItemUse(BasicShowel.java:62)
at net.minecraft.item.ItemStack.onItemUse(ItemStack.java:201)
at net.minecraft.client.multiplayer.PlayerControllerMP.processRightClickBlock(PlayerControllerMP.java:509)
at net.minecraft.client.Minecraft.rightClickMouse(Minecraft.java:1693)
at net.minecraft.client.Minecraft.processKeyBinds(Minecraft.java:2380)
at net.minecraft.client.Minecraft.runTickKeyboard(Minecraft.java:2146)
at net.minecraft.client.Minecraft.runTick(Minecraft.java:1934)
at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1187)
at net.minecraft.client.Minecraft.run(Minecraft.java:441)
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)
Краш-лог:
[13:42:11] [main/FATAL] [minecraft/Minecraft]: Unreported exception thrown!
java.lang.NullPointerException: null
	at com.xumuk.realism.items.tools.BasicShowel.onItemUse(BasicShowel.java:62) ~[BasicShowel.class:?]
	at net.minecraft.item.ItemStack.onItemUse(ItemStack.java:201) ~[ItemStack.class:?]
	at net.minecraft.client.multiplayer.PlayerControllerMP.processRightClickBlock(PlayerControllerMP.java:509) ~[PlayerControllerMP.class:?]
	at net.minecraft.client.Minecraft.rightClickMouse(Minecraft.java:1693) ~[Minecraft.class:?]
	at net.minecraft.client.Minecraft.processKeyBinds(Minecraft.java:2380) ~[Minecraft.class:?]
	at net.minecraft.client.Minecraft.runTickKeyboard(Minecraft.java:2146) ~[Minecraft.class:?]
	at net.minecraft.client.Minecraft.runTick(Minecraft.java:1934) ~[Minecraft.class:?]
	at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1187) ~[Minecraft.class:?]
	at net.minecraft.client.Minecraft.run(Minecraft.java:441) [Minecraft.class:?]
	at net.minecraft.client.main.Main.main(Main.java:118) [Main.class:?]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_191]
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_191]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_191]
	at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_191]
	at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.12.jar:?]
	at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.12.jar:?]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_191]
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_191]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_191]
	at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_191]
	at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97) [start/:?]
	at GradleStart.main(GradleStart.java:25) [start/:?]
[13:42:11] [main/INFO] [STDOUT]: [net.minecraft.init.Bootstrap:printToSYSOUT:629]: ---- Minecraft Crash Report ----
// This is a token for 1 free hug. Redeem at your nearest Mojangsta: [~~HUG~~]

Time: 9/28/19 1:42 PM
Description: Unexpected error

java.lang.NullPointerException: Unexpected error
	at com.xumuk.realism.items.tools.BasicShowel.onItemUse(BasicShowel.java:62)
	at net.minecraft.item.ItemStack.onItemUse(ItemStack.java:201)
	at net.minecraft.client.multiplayer.PlayerControllerMP.processRightClickBlock(PlayerControllerMP.java:509)
	at net.minecraft.client.Minecraft.rightClickMouse(Minecraft.java:1693)
	at net.minecraft.client.Minecraft.processKeyBinds(Minecraft.java:2380)
	at net.minecraft.client.Minecraft.runTickKeyboard(Minecraft.java:2146)
	at net.minecraft.client.Minecraft.runTick(Minecraft.java:1934)
	at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1187)
	at net.minecraft.client.Minecraft.run(Minecraft.java:441)
	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)
Решение
Не пойму, что ты хочешь и что за фигню тебе тут некоторые советуют, но вот как я сделал:

Java:
public class ItemBlockStorage extends Item {
    @Override
    public boolean onBlockDestroyed(ItemStack stack, World world, IBlockState state, BlockPos pos, EntityLivingBase entity) {
        final ResourceLocation blockRegName = ForgeRegistries.BLOCKS.getKey(state.getBlock());

        if (blockRegName != null) {
            final NBTTagCompound storage = new NBTTagCompound();
            storage.setString("blockName", blockRegName.toString());
            stack.setTagCompound(storage);
        }
        return true;
    }

    @Override
    public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {...

jopi

Попрошайка
1,421
30
260
@Maxik Ты не сохраняешь компаунд.
stack.getTagCompound().setInteger("JOPA", 2281337);
либо полная перезапись компаунда:
stack.stackTagCompound = new NBTTagCompound();


UPD:

Java:
 public boolean onBlockDestroyed(ItemStack stack, World worldIn, IBlockState state, BlockPos pos, EntityLivingBase entityLiving)
    {
        ItemStack destroyBlock = new ItemStack(Item.getItemFromBlock(state.getBlock()));
        
        
        NBTTagCompound newtag = new NBTTagCompound();
        
        newtag.setString("filled", destroyBlock.getUnlocalizedName());
        
        stack.stackTagCompound = newtag;
         //Либо аналог ниже:
        stack.getTagCompound().setString("filled", destroyBlock.getUnlocalizedName());
        
        System.out.println(stack + " ___ " + newtag);

        return true;
    }
    public EnumActionResult onItemUse(EntityPlayer player, World worldIn, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ)
    {
        ItemStack stack = player.getActiveItemStack();
        System.out.println(stack + " ___ " + stack.getTagCompound().getString("filled"));

        return EnumActionResult.PASS;
    }
 
5,020
47
784
Если ты про stack.writeToNBT(newtag);, то он не особо помогает :-\

@jopi то что ты предлагаешь вызывает краш, так не работает.
stack.getTagCompound().setString("filled", destroyBlock.getUnlocalizedName());
 
355
2
17
stackTagCompound - По умолчанию и равен null.

А методы writeToNBT и readFromNBT считывают компаунды из хранилища предметов, преобразовывая их собственно в эти самые IS.
Лучше всего конечно же наполнять имеющийся компаунд, если его нет - создавать новый. Иначе попросту можешь навернуть какие-то модовские теги.

Java:
NBTTagCompound compound = (itemStack.hasTagCompound()) ? itemStack.getTagCompound() : new NBTTagCompound();
compound.setString("key", "value");

...
  
itemStack.setTagCompound(compound);
 
5,020
47
784
В 1.12 такого вообще нет, держу в курсе, там геттер
stack.stackTagCompound = newtag;
А методы writeToNBT и readFromNBT считывают компаунды из хранилища предметов, преобразовывая их собственно в эти самые IS.
В итеме их нету ващет
 

jopi

Попрошайка
1,421
30
260
@Sunrise верно, но каждый раз прописывать столь длинный код [S][I][U]меня раздражает[/U][/I][/S]
Я просто оставлю это тут.

Java:
public static NBTTagCompound getCompound(ItemStack i) {
    if (i.stackTagCompound == null) {
        NBTTagCompound nbt = new NBTTagCompound("tag");
        return i.stackTagCompound = nbt;
    } else {
        return i.stackTagCompound;
    }
}
 

Icosider

Kotliner
Администратор
3,603
99
664
Не пойму, что ты хочешь и что за фигню тебе тут некоторые советуют, но вот как я сделал:

Java:
public class ItemBlockStorage extends Item {
    @Override
    public boolean onBlockDestroyed(ItemStack stack, World world, IBlockState state, BlockPos pos, EntityLivingBase entity) {
        final ResourceLocation blockRegName = ForgeRegistries.BLOCKS.getKey(state.getBlock());

        if (blockRegName != null) {
            final NBTTagCompound storage = new NBTTagCompound();
            storage.setString("blockName", blockRegName.toString());
            stack.setTagCompound(storage);
        }
        return true;
    }

    @Override
    public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {
        final ItemStack stack = player.getHeldItem(hand);
        final NBTTagCompound nbt = stack.getTagCompound();

        if (!stack.isEmpty() && nbt != null && nbt.hasKey("blockName")) {
            final String blockName = nbt.getString("blockName");
            final Block block = ForgeRegistries.BLOCKS.getValue(new ResourceLocation(blockName));
          
            if (block != null) {
                // Тут ставь свой блок или чо там хош
                return new ActionResult<>(EnumActionResult.SUCCESS, stack);
            }
        }
        return new ActionResult<>(EnumActionResult.FAIL, stack);
    }
}
Достать из стака сможешь почти в любом методе, обращаясь к blockName
UPD: Дополнил код
 
Последнее редактирование:

jopi

Попрошайка
1,421
30
260
В 1.12 такого вообще нет, держу в курсе
stack.stackTagCompound = newtag;
В итеме их нету ващет
Напиши тогда сюда пожалуйста все методы относящиейся к нбт, потому-что я не понял приколов
поскольку 1.12 [S]кал[/S] мне не знакома, я не могу точно помочь, но пример работающий 100% на 1.6.4 1.7.10 я скинул
 

jopi

Попрошайка
1,421
30
260
Не пойму, что ты хочешь и что за фигню тебе тут некоторые советуют, но вот как я сделал:

Java:
public class ItemBlockStorage extends Item {
    @Override
    public boolean onBlockDestroyed(ItemStack stack, World world, IBlockState state, BlockPos pos, EntityLivingBase entity) {
        final ResourceLocation blockRegName = ForgeRegistries.BLOCKS.getKey(state.getBlock());
       
        if (blockRegName != null) {
            final NBTTagCompound storage = new NBTTagCompound();
            storage.setString("blockName", blockRegName.toString());
            stack.setTagCompound(storage);
        }
        return true;
    }
}
Достать из стака сможешь почти в любом методе, обращаясь к blockName
Зачем постоянно создавать новый компаунд?!?!?
Взрывмозга.
Он 1 раз нулевый, а потом не нулевый, смысл создавать постоянно новый?
 

jopi

Попрошайка
1,421
30
260
В общем вот тебе универсальное решение которое по сути является скрещением всех говнокодов.
Просто пихни куда-то и вызывай каждый раз когда нужно взять нбт, я бы сделал так потому-что проверять каждый раз есть нбт или нет геморно.
Java:
public static NBTTagCompound getCompound(ItemStack i) {
    if (i.getTagCompound() == null) {
        NBTTagCompound nbt = new NBTTagCompound("tag");
        i.setTagCompound(nbt);
        return i.getTagCompound();
    } else {
        return i.getTagCompound();
    }
}
 
5,020
47
784
@Sunrise ты конечно правильно написал, но при попытке считывания все равно нулл)))

Java:
    public boolean onBlockDestroyed(ItemStack stack, World worldIn, IBlockState state, BlockPos pos, EntityLivingBase entityLiving)
    {
        ItemStack destroyBlock = new ItemStack(Item.getItemFromBlock(state.getBlock()));
        
        
        NBTTagCompound compound = (stack.hasTagCompound()) ? stack.getTagCompound() : new NBTTagCompound();
        
        compound.setString("filled", destroyBlock.getUnlocalizedName());
    //    stack.getTagCompound().setString("filled", destroyBlock.getUnlocalizedName());
        stack.setTagCompound(compound);
        
        System.out.println(stack + " ___ " + compound);

        return true;
    }
    public EnumActionResult onItemUse(EntityPlayer player, World worldIn, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ)
    {
        ItemStack stack = player.getActiveItemStack();
        System.out.println(stack + " ___ " + stack.getTagCompound().getString("filled"));
    
   //     worldIn.setBlockState(pos.offset(facing), Block.getBlockFromItem(stack.getItem()).getDefaultState());
        return EnumActionResult.PASS;
    }
Java:
[14:26:59] [main/FATAL] [minecraft/Minecraft]: Unreported exception thrown!
java.lang.NullPointerException: null
    at com.xumuk.realism.items.tools.BasicShowel.onItemUse(BasicShowel.java:62) ~[BasicShowel.class:?]
    at net.minecraft.item.ItemStack.onItemUse(ItemStack.java:201) ~[ItemStack.class:?]
    at net.minecraft.client.multiplayer.PlayerControllerMP.processRightClickBlock(PlayerControllerMP.java:509) ~[PlayerControllerMP.class:?]
    at net.minecraft.client.Minecraft.rightClickMouse(Minecraft.java:1693) ~[Minecraft.class:?]
    at net.minecraft.client.Minecraft.processKeyBinds(Minecraft.java:2380) ~[Minecraft.class:?]
    at net.minecraft.client.Minecraft.runTickKeyboard(Minecraft.java:2146) ~[Minecraft.class:?]
    at net.minecraft.client.Minecraft.runTick(Minecraft.java:1934) ~[Minecraft.class:?]
    at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1187) ~[Minecraft.class:?]
    at net.minecraft.client.Minecraft.run(Minecraft.java:441) [Minecraft.class:?]
    at net.minecraft.client.main.Main.main(Main.java:118) [Main.class:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_191]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_191]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_191]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_191]
    at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.12.jar:?]
    at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.12.jar:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_191]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_191]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_191]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_191]
    at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97) [start/:?]
    at GradleStart.main(GradleStart.java:25) [start/:?]
[14:26:59] [main/INFO] [STDOUT]: [net.minecraft.init.Bootstrap:printToSYSOUT:629]: ---- Minecraft Crash Report ----
// Uh... Did I do that?
 

Icosider

Kotliner
Администратор
3,603
99
664
Зачем постоянно создавать новый компаунд?!?!?
Взрывмозга.
Он 1 раз нулевый, а потом не нулевый, смысл создавать постоянно новый?
Потому что ТС не сказал зачем ему вообще хранить итем в предмете, может быть у него там капсула или ещё какая фигня.

Просто взял, оскорбил всех, а сам просто сетнул тэг, без проверки о его наличии.
Не вижу оскорблений, и что такого в том, чтобы просто сетать тег без проверки на его наличие?-_- Просто нбтшка стака заменится на новую с блоком, всё! Максимум что ты потеряешь это имя стака и другие ненужные данные.
 
5,020
47
784
355
2
17
Не вижу оскорблений, и что такого в том, чтобы просто сетать тег без проверки на его наличие?-_-
При взаимодействии с другими модами (Это конечно если такое вообще планируется), очень огромный риск сломать инструменты этих модов. Ибо зачастую всякие мультитулы хранят в тегах информацию о всяких зарядах и тд, таким мувом ты просто убиваешь эту информацию, а не дополняешь.
 
Сверху