SOLVED Enregistrer les données d'un TileEntity dans un ItemStack


  • Bonjour,

    J’ai un bloc qui est associé à une TileEntity. Quand je détruit le bloc, la méthode **getDrops **est appelée.

    public java.util.List <itemstack>getDrops(net.minecraft.world.IBlockAccess world, BlockPos pos, IBlockState state, int fortune)
    

    A ce moment, je souhaiterais récupérer le TileEntity, et rajouter un nouvel **ItemStack **dans la liste à retourner en lui affectant un **NBTTagCompound **qui contient les mêmes valeur que le TileEntity.
    Le problème c’est que le méthode **breakBlock **qui fait un **removeTileEntity **est appelée avant le getDrops. Du coup impossible de conserver mes valeurs pour les mettre dans mon Item. Et vu que le **world **de **getDrops **n’est pas de type **World **mais IBlockAccess, il est impossible de détruire le **TileEntity **dans getDrops.

    Quelque aurait une idée pour résoudre mon problème ? Une méthode appelée après **getDrops **qui aurait accès au **World **?

    En espérant avoir été assez clair  👼</itemstack>

  • Modérateurs

    Si tu as qu’un seul ItemStack, tu peux utiliser la même méthode que le four:

    ​%(#a9b7c6)[[font=Consolas]public ]ItemStack %(#ffc66d)[getStackInSlotOnClosing](%(#cc7832)[int ]index)
    

    Implémentes cette méthode dans ton TileEntity et retournes l’ItemStack concerné 😉


  • Merci de ta réponse.

    Je trouve ça assez sale d’implémenter **IInventory **juste pour utiliser une de ses 17 méthodes.

    Edit : En debug il ne passe pas dans la méthode getStackInSlotOnClosing, est ce que je dois créer une classe étendant Container ou un truc comme ça, juste pour ça ? Et puis j’ai besoin de connaitre également le **BlockState **de mon Block pour savoir si je peux retourner ou non l’Item, ce serait possible ? A vrai dire le **getDrops **me semblait tout désigné pour ça je trouve ça dommage :rolleyes:

  • Administrateurs Rédacteurs Moddeurs confirmés

    Ça m’étonnerai que ça fonctionne. Le problème vient du fait que world.getTileEntity retourn null lorsqu’on l’utilise dans getDrops (il me semble).
    Je vais me pencher sur la question dans la soiré, là j’ai d’autres choses à faire.


  • Oui c’est ça il retourne null car la méthode permettant la destruction de la TileEntity est appelée avant getDrops.

    Merci de prendre mon problème en considération en tout cas  😉

  • Administrateurs Rédacteurs Moddeurs confirmés

    Le problème vient en effet du fait que la fonction harvestBlock est appelé après breakBlock.
    Du-coup l’astuce est de faire le drop dans la fonction removedByPlayer qui est appelé avant breakBlock.

    ​package com.example.examplemod;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import net.minecraft.block.Block;
    import net.minecraft.block.BlockContainer;
    import net.minecraft.block.ITileEntityProvider;
    import net.minecraft.block.material.Material;
    import net.minecraft.block.state.IBlockState;
    import net.minecraft.enchantment.EnchantmentHelper;
    import net.minecraft.entity.player.EntityPlayer;
    import net.minecraft.item.ItemStack;
    import net.minecraft.nbt.NBTTagCompound;
    import net.minecraft.stats.StatList;
    import net.minecraft.tileentity.TileEntity;
    import net.minecraft.util.BlockPos;
    import net.minecraft.world.IBlockAccess;
    import net.minecraft.world.World;
    import net.minecraftforge.common.util.FakePlayer;
    import net.minecraftforge.fml.common.Mod;
    import net.minecraftforge.fml.common.Mod.EventHandler;
    import net.minecraftforge.fml.common.event.FMLInitializationEvent;
    import net.minecraftforge.fml.common.registry.GameRegistry;
    
    @Mod(modid = ExampleMod.MODID, version = ExampleMod.VERSION)
    public class ExampleMod
    {
        public static final String MODID = "examplemod";
        public static final String VERSION = "1.0";
    
        public static Block test;
    
        @EventHandler
        public void init(FMLInitializationEvent event)
        {
            test = new BlockTest(Material.rock).setUnlocalizedName("test");
            GameRegistry.registerBlock(test, "test");
            GameRegistry.registerTileEntity(TileEntityTest.class, "examplemod:TileEntityTest");
        }
    
        public static class BlockTest extends Block
        {
            protected BlockTest(Material materialIn)
            {
                super(materialIn);
            }
    
            public List <itemstack>getDrops(IBlockAccess world, BlockPos pos, IBlockState state, int fortune)
            {
                List <itemstack>ret = new java.util.ArrayList<itemstack>();
                ret.add(new ItemStack(ExampleMod.test));
                TileEntity tile = world.getTileEntity(pos);
                if(tile instanceof TileEntityTest)
                {
                    System.out.println(((TileEntityTest)tile).getB());
                }
                System.out.println(tile);
                return ret;
            }
    
            public boolean removedByPlayer(World world, BlockPos pos, EntityPlayer player, boolean willHarvest)
            {
                if(!world.isRemote && !player.capabilities.isCreativeMode)
                {
                    int i1 = EnchantmentHelper.getFortuneModifier(player);
    
                    List <itemstack>items = getDrops(world, pos, world.getBlockState(pos), i1);
                    for (ItemStack stack : items)
                    {
                        spawnAsEntity(world, pos, stack);
                    }
                }
                return world.setBlockToAir(pos);
            }
    
            public void harvestBlock(World worldIn, EntityPlayer player, BlockPos pos, IBlockState state, TileEntity te)
            {
                System.out.println("coucou 2 ");
    
                player.triggerAchievement(StatList.mineBlockStatArray[getIdFromBlock(this)]);
                player.addExhaustion(0.025F);
            }
    
            public void breakBlock(World worldIn, BlockPos pos, IBlockState state)
            {
                if (hasTileEntity(state))
                {
                    System.out.println("coucou");
                    worldIn.removeTileEntity(pos);
                }
            }
    
            public boolean hasTileEntity(IBlockState state)
            {
                return true;
            }
    
            public TileEntity createTileEntity(World world, IBlockState state)
            {
                return new TileEntityTest();
            }
        }
    
        public static class TileEntityTest extends TileEntity
        {
            private boolean b;
    
            public void readFromNBT(NBTTagCompound compound)
            {
                super.readFromNBT(compound);
                this.b = compound.getBoolean("TestBoolean");
            }
    
            public void writeToNBT(NBTTagCompound compound)
            {
                compound.setBoolean("TestBoolean", this.b);
            }
    
            public boolean getB()
            {
                return this.b;
            }
    
            public void setB(boolean value)
            {
                this.b = value;
            }
        }
    }
    

    Et les logs :

    false
    [12:42:43] [Server thread/INFO] [STDOUT]: [com.example.examplemod.ExampleMod$BlockTest:getDrops:58]: com.example.examplemod.ExampleMod$TileEntityTest@212717f
    [12:42:43] [Server thread/INFO] [STDOUT]: [com.example.examplemod.ExampleMod$BlockTest:breakBlock:89]: coucou
    [12:42:43] [Server thread/INFO] [STDOUT]: [com.example.examplemod.ExampleMod$BlockTest:harvestBlock:79]: coucou 2
    ```</itemstack></itemstack></itemstack></itemstack>

  • Ça marche nickel, merci de ton aide. 😉