Entité Block



  • Bonjour j'ai créé un tapi roulant permettant de faire avancer des blocks, pour faire l'entité du block qui bouge, pour l'instant je me suis basée sur celle du sable qui tombe mais  j'ai un problème au niveau de rendu: au début j'utilisais le rendu du sable mais comme le vecteur de déplacement de mon entité et celui du sable sont différents, le rendu se fait mal. J'ai donc opté pour créer mon propre rendu. Cela fait que maintenant, lorsque l'entité apparais, mon minecraft crash:

    –-- Minecraft Crash Report ----
    // Ouch. That hurt :(
    
    Time: 23/01/16 20:41
    Description: Ticking entity
    
    java.lang.NullPointerException: Ticking entity
        at com.maxyfactory.mod.tileentity.EntityConvoyedBlock.onUpdate(EntityConvoyedBlock.java:89)
        at net.minecraft.world.World.updateEntityWithOptionalForce(World.java:2031)
        at net.minecraft.world.World.updateEntity(World.java:1997)
        at net.minecraft.world.World.updateEntities(World.java:1823)
        at net.minecraft.client.Minecraft.runTick(Minecraft.java:2184)
        at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1087)
        at net.minecraft.client.Minecraft.run(Minecraft.java:376)
        at net.minecraft.client.main.Main.main(Main.java:117)
        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(Unknown Source)
        at GradleStart.main(Unknown Source)
    
    A detailed walkthrough of the error, its code path and all known details is as follows:
    ---------------------------------------------------------------------------------------
    
    -- Head --
    Stacktrace:
        at com.maxyfactory.mod.tileentity.EntityConvoyedBlock.onUpdate(EntityConvoyedBlock.java:89)
        at net.minecraft.world.World.updateEntityWithOptionalForce(World.java:2031)
        at net.minecraft.world.World.updateEntity(World.java:1997)
    
    -- Entity being ticked --
    Details:
        Entity Type: convoyedBlock (com.maxyfactory.mod.tileentity.EntityConvoyedBlock)
        Entity ID: 27382
        Entity Name: entity.convoyedBlock.name
        Entity's Exact location: -650,72, 5,02, -986,50
        Entity's Block location: -651,00,5,00,-987,00 - World: (-651,5,-987), Chunk: (at 5,0,5 in -41,-62; contains blocks -656,0,-992 to -641,255,-977), Region: (-2,-2; contains chunks -64,-64 to -33,-33, blocks -1024,0,-1024 to -513,255,-513)
        Entity's Momentum: -0,11, 0,00, 0,00
        Entity's Rider: ~~ERROR~~ NullPointerException: null
        Entity's Vehicle: ~~ERROR~~ NullPointerException: null
    Stacktrace:
        at net.minecraft.world.World.updateEntities(World.java:1823)
    
    -- Affected level --
    Details:
        Level name: MpServer
        All players: 1 total; [EntityPlayerSP['Player773'/73, l='MpServer', x=-648,27, y=5,29, z=-987,97]]
        Chunk stats: MultiplayerChunkCache: 625, 625
        Level seed: 0
        Level generator: ID 01 - flat, ver 0\. Features enabled: false
        Level generator options:
        Level spawn location: -660,00,4,00,-948,00 - World: (-660,4,-948), Chunk: (at 12,0,12 in -42,-60; contains blocks -672,0,-960 to -657,255,-945), Region: (-2,-2; contains chunks -64,-64 to -33,-33, blocks -1024,0,-1024 to -513,255,-513)
        Level time: 390120 game time, 140244 day time
        Level dimension: 0
        Level storage version: 0x00000 - Unknown?
        Level weather: Rain time: 0 (now: false), thunder time: 0 (now: false)
        Level game mode: Game mode: creative (ID 1). Hardcore: false. Cheats: false
        Forced entities: 36 total; [EntityHorse['Cheval'/8, l='MpServer', x=-693,88, y=4,00, z=-1058,66], EntityCow['Vache'/9, l='MpServer', x=-688,84, y=4,00, z=-919,25], EntityCow['Vache'/11, l='MpServer', x=-679,50, y=4,00, z=-1008,75], EntityCow['Vache'/12, l='MpServer', x=-676,03, y=4,00, z=-936,94], EntityRabbit['Lapin'/17, l='MpServer', x=-661,41, y=4,00, z=-1042,00], EntitySheep['Mouton'/22, l='MpServer', x=-654,19, y=4,00, z=-1026,88], EntityItem['item.tile.stonebrick'/23, l='MpServer', x=-645,50, y=4,00, z=-980,88], EntityItem['item.tile.stonebrick'/24, l='MpServer', x=-641,47, y=4,00, z=-979,44], EntityItem['item.tile.stonebrick'/25, l='MpServer', x=-645,19, y=4,00, z=-977,78], EntityPlayerSP['Player773'/73, l='MpServer', x=-648,27, y=5,29, z=-987,97], EntityItem['item.tile.stonebrick'/27, l='MpServer', x=-645,59, y=4,00, z=-979,44], EntityBat['Chauve-souris'/30, l='MpServer', x=-634,25, y=6,10, z=-961,44], EntityBat['Chauve-souris'/31, l='MpServer', x=-635,53, y=5,10, z=-960,81], EntityBat['Chauve-souris'/32, l='MpServer', x=-633,81, y=5,10, z=-962,75], EntityBat['Chauve-souris'/33, l='MpServer', x=-634,25, y=6,10, z=-961,25], EntityBat['Chauve-souris'/34, l='MpServer', x=-634,47, y=6,10, z=-961,25], EntityBat['Chauve-souris'/35, l='MpServer', x=-637,19, y=5,10, z=-962,50], EntityBat['Chauve-souris'/36, l='MpServer', x=-634,25, y=6,10, z=-961,25], EntityBat['Chauve-souris'/37, l='MpServer', x=-636,75, y=6,10, z=-961,25], EntityBat['Chauve-souris'/38, l='MpServer', x=-633,81, y=5,10, z=-962,25], EntityBat['Chauve-souris'/39, l='MpServer', x=-635,75, y=5,10, z=-960,81], EntityBat['Chauve-souris'/40, l='MpServer', x=-633,88, y=5,10, z=-962,25], EntityBat['Chauve-souris'/41, l='MpServer', x=-634,63, y=6,10, z=-961,25], EntityBat['Chauve-souris'/42, l='MpServer', x=-636,63, y=6,10, z=-961,41], EntityBat['Chauve-souris'/43, l='MpServer', x=-638,25, y=6,10, z=-961,47], EntityBat['Chauve-souris'/44, l='MpServer', x=-636,75, y=6,10, z=-963,44], EntityBat['Chauve-souris'/45, l='MpServer', x=-634,25, y=6,10, z=-961,25], EntitySheep['Mouton'/46, l='MpServer', x=-618,25, y=4,00, z=-932,66], EntitySheep['Mouton'/50, l='MpServer', x=-597,94, y=4,00, z=-1063,22], EntityHorse['Cheval'/51, l='MpServer', x=-593,78, y=4,00, z=-936,44], EntitySheep['Mouton'/53, l='MpServer', x=-595,00, y=4,00, z=-1063,97], EntitySheep['Mouton'/54, l='MpServer', x=-588,19, y=4,00, z=-1036,88], EntityConvoyedBlock['entity.convoyedBlock.name'/27382, l='MpServer', x=-650,72, y=5,02, z=-986,50], EntitySheep['Mouton'/55, l='MpServer', x=-582,03, y=4,00, z=-990,03], EntitySheep['Mouton'/56, l='MpServer', x=-591,97, y=4,00, z=-966,00], EntitySheep['Mouton'/58, l='MpServer', x=-573,94, y=4,00, z=-1042,16]]
        Retry entities: 0 total; []
        Server brand: fml,forge
        Server type: Integrated singleplayer server
    Stacktrace:
        at net.minecraft.client.multiplayer.WorldClient.addWorldInfoToCrashReport(WorldClient.java:392)
        at net.minecraft.client.Minecraft.addGraphicsAndWorldToCrashReport(Minecraft.java:2614)
        at net.minecraft.client.Minecraft.run(Minecraft.java:398)
        at net.minecraft.client.main.Main.main(Main.java:117)
        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(Unknown Source)
        at GradleStart.main(Unknown Source)
    
    – System Details --
    Details:
        Minecraft Version: 1.8
        Operating System: Windows 10 (amd64) version 10.0
        Java Version: 1.8.0_66, Oracle Corporation
        Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation
        Memory: 851438000 bytes (811 MB) / 1038876672 bytes (990 MB) up to 1038876672 bytes (990 MB)
        JVM Flags: 3 total; -Xincgc -Xmx1024M -Xms1024M
        IntCache: cache: 0, tcache: 0, allocated: 0, tallocated: 0
        FML: MCP v9.10 FML v8.0.99.99 Minecraft Forge 11.14.4.1563 4 mods loaded, 4 mods active
        States: 'U' = Unloaded 'L' = Loaded 'C' = Constructed 'H' = Pre-initialized 'I' = Initialized 'J' = Post-initialized 'A' = Available 'D' = Disabled 'E' = Errored
        UCHIJAAAA    mcp{9.05} [Minecraft Coder Pack] (minecraft.jar)
        UCHIJAAAA    FML{8.0.99.99} [Forge Mod Loader] (forgeSrc-1.8-11.14.4.1563.jar)
        UCHIJAAAA    Forge{11.14.4.1563} [Minecraft Forge] (forgeSrc-1.8-11.14.4.1563.jar)
        UCHIJAAAA    maxyfactory{1.1.0-a} [Mod Maxy Factory] (bin)
        Loaded coremods (and transformers):
        GL info: ' Vendor: 'ATI Technologies Inc.' Version: '4.5.13399 Compatibility Profile Context 15.201.1151.1008' Renderer: 'AMD Radeon HD 8670D'
        Launched Version: 1.8
        LWJGL: 2.9.1
        OpenGL: AMD Radeon HD 8670D GL version 4.5.13399 Compatibility Profile Context 15.201.1151.1008, ATI Technologies Inc.
        GL Caps: Using GL 1.3 multitexturing.
    Using GL 1.3 texture combiners.
    Using framebuffer objects because OpenGL 3.0 is supported and separate blending is supported.
    Shaders are available because OpenGL 2.1 is supported.
    VBOs are available because OpenGL 1.5 is supported.
    
        Using VBOs: No
        Is Modded: Definitely; Client brand changed to 'fml,forge'
        Type: Client (map_client.txt)
        Resource Packs: []
        Current Language: Français (France)
        Profiler Position: N/A (disabled)
    

    Si j'enlève ça, je ne crash pas mais mon block n'a plus de rendu.

    EntityRegistry.registerGlobalEntityID(entityClass, entityName, entityID);
    EntityRegistry.registerModEntity(entityClass, entityName, entityID, ModMaxyFactory.instance, 64, 1, true);
    

    Dites moi, si c'est mieux d'utiliser un tileentity(dans ce cas il faut m'expliquer commen en utiliser un) ou comment régler le problème de crash.


  • Administrateurs

    Un tile entity ne sert à rien dans ce cas.
    registerGlobalEntityID ne doit pas être utilisé.

    Et ton problème est un npe à la ligne 89 de EntityConvoyedBlock



  • J'ai enlevé registerGlobalEntityID.
    A la ligne 89 , j'ai this.setDead(); dans un onUpdate() :
    (c'est le premier this.setDead(); )

    public void onUpdate()
        {
            Block block = this.fallTile.getBlock();
    
            if (block.getMaterial() == Material.air)
            {
                this.setDead();
            }
            else
            {
                this.prevPosX = this.posX;
                this.prevPosY = this.posY;
                this.prevPosZ = this.posZ;
                BlockPos blockpos;
    
                if (this.fallTime++ == 0)
                {
                    blockpos = new BlockPos(this);
    
                    if (this.worldObj.getBlockState(blockpos).getBlock() == block)
                    {
                        this.worldObj.setBlockToAir(blockpos);
                    }
                    else if (!this.worldObj.isRemote)
                    {
                        this.setDead();
                        return;
                    }
                }
    
                this.motionY -= 0.03999999910593033D;
                this.moveEntity(this.motionX, this.motionY, this.motionZ);
                this.motionY *= 0.98D;
                if (this.fallTime > 10)
                {
                    this.motionX *= 0.98D;
                    this.motionZ *= 0.98D;
                }
                if (!this.worldObj.isRemote)
                {
                    blockpos = new BlockPos(this);
    
                    if (this.fallTime > 10 && this.onGround)
                    {
                        this.motionX *= 0.699999988079071D;
                        this.motionZ *= 0.699999988079071D;
                        this.motionY *= -0.5D;
    
                        if (this.worldObj.getBlockState(blockpos).getBlock() != Blocks.piston_extension)
                        {
                            this.setDead();
    
                            if (!this.field_145808_f && this.worldObj.canBlockBePlaced(block, blockpos, true, EnumFacing.UP, (Entity)null, (ItemStack)null) && this.worldObj.setBlockState(blockpos, this.fallTile, 3))
                            {
                                if (block instanceof BlockConvoyorBelt)
                                {
                                    ((BlockConvoyorBelt)block).onEndFalling(this.worldObj, blockpos);
                                }
    
                                if (this.tileEntityData != null && block instanceof ITileEntityProvider)
                                {
                                    TileEntity tileentity = this.worldObj.getTileEntity(blockpos);
    
                                    if (tileentity != null)
                                    {
                                        NBTTagCompound nbttagcompound = new NBTTagCompound();
                                        tileentity.writeToNBT(nbttagcompound);
                                        Iterator iterator = this.tileEntityData.getKeySet().iterator();
    
                                        while (iterator.hasNext())
                                        {
                                            String s = (String)iterator.next();
                                            NBTBase nbtbase = this.tileEntityData.getTag(s);
    
                                            if (!s.equals("x") && !s.equals("y") && !s.equals("z"))
                                            {
                                                nbttagcompound.setTag(s, nbtbase.copy());
                                            }
                                        }
    
                                        tileentity.readFromNBT(nbttagcompound);
                                        tileentity.markDirty();
                                    }
                                }
                            }
                            else if (this.shouldDropItem && !this.field_145808_f && this.worldObj.getGameRules().getGameRuleBooleanValue("doTileDrops"))
                            {
                                this.entityDropItem(new ItemStack(block, 1, block.damageDropped(this.fallTile)), 0.0F);
                            }
                        }
                    }
                    else if (this.fallTime > 100 && !this.worldObj.isRemote && (blockpos.getY() < 1 || blockpos.getY() > 256) || this.fallTime > 600)
                    {
                        if (this.shouldDropItem && this.worldObj.getGameRules().getGameRuleBooleanValue("doTileDrops"))
                        {
                            this.entityDropItem(new ItemStack(block, 1, block.damageDropped(this.fallTile)), 0.0F);
                        }
    
                        this.setDead();
                    }
                }
            }
        }
    

    Je ne comprend pas ce qui ne vas pas, puisque le this.setDead(); est censé s’exécuter si le block déplacé est de l'air, ce qui n'arrive jamais.


  • Administrateurs

    Je ne comprends pas plus que toi puisqu'un this.setDead() ne peut pas causer un npe x)



  • Ou allors c'est Block block = this.fallTile.getBlock(); qui est juste au dessus le problème mais logiquement c'est un problème de rendu puisque ça fonctionne quand je me le rendu du sable ou quand je ne met pas EntityRegistry.registerModEntity(entityClass, entityName, entityID, ModMaxyFactory.instance, 64, 1, true);


  • Administrateurs

    fallTile correspond à quoi ?
    Vérifies quand même avec System.out.println(fallTile);



  • fallTile est le BlockState dans lequel est enregistré les stat du block qui est en trains de se faire déplacer (je l'ai copié sur l'entity du FallingBlock)
    System.out.println(fallTile); me met ça:
    [23:21:21] [Client thread/INFO] [STDOUT]: [com.maxyfactory.mod.entity.EntityConvoyingBlock:onUpdate:89]: null
    puis plusieurs fois ça avant de crasher
    [23:21:21] [Server thread/INFO] [STDOUT]: [com.maxyfactory.mod.entity.EntityConvoyingBlock:onUpdate:89]: minecraft:grass[snowy=false]
    Ici, c'était un block de terre que j’essayais de déplacer avec le tapis roulant.


  • Administrateurs

    [23:21:21] [Client thread/INFO] [STDOUT]: [com.maxyfactory.mod.entity.EntityConvoyingBlock:onUpdate:89]: null
    Oui donc c'est bien ça qui cause le npe.



  • Avec if (this.fallTile != null), ça fonctionne mieux : il n'y a plus de crash mais le block est invisible, il n'y a que son ombre.


  • Administrateurs

    Donc faut chercher pourquoi il est null car il ne devrait pas l'être.



  • Il n'est pas null quand je supprime ça: EntityRegistry.registerModEntity(EntityConvoyingBlock.class, "convoyingBlock", entityID, ModMaxyFactory.instance, 64, 1, true);
    Mais dans ce cas, le doRender() de la class du rendu que j’utilise n'est pas appelé.
    Ce n'est pas un problème de mon rendu car c'est une copie de celui du sable donc je ne sais pas d'où ça vient.

    EDIT : C'est bon, j'ai trouvé pourquoi fallTile était nul : je n'avais pas mis static.
    Le rendu fonctionne maintenant mais je voudrais juste savoir a quoi sert static.


  • Administrateurs

    Une variable static n'a qu'une unique instance.
    Je ne suis pas sûr que mettre static soit la bonne solution. Envoies ton code complet.



  • En effet, static n' est pas trés bon, si je met deux blocks différents sur des tapis roulants, le premiers devient le même block que le second.

    L'Entité :

    public class EntityConvoyingBlock extends EntityFallingBlock
    {
        private IBlockState fallTile;
        public int fallTime;
        public boolean shouldDropItem = true;
        private boolean field_145808_f;
        private boolean hurtEntities;
        private int fallHurtMax = 40;
        private float fallHurtAmount = 2.0F;
        public NBTTagCompound tileEntityData;
    
        public EntityConvoyingBlock(World worldIn)
        {
            super(worldIn);
        }
    
        public EntityConvoyingBlock(World worldIn, double x, double y, double z, IBlockState ConvoyingBlockState)
        {
            super(worldIn);
            this.fallTile = ConvoyingBlockState;
            this.preventEntitySpawning = true;
            this.setSize(0.98F, 0.98F);
            this.setPosition(x, y, z);
            this.motionX = 0.0D;
            this.motionY = 0.0D;
            this.motionZ = 0.0D;
            this.prevPosX = x;
            this.prevPosY = y;
            this.prevPosZ = z;
        }
    
        /**
         * returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to
         * prevent them from trampling crops
         */
        protected boolean canTriggerWalking()
        {
            return false;
        }
    
        protected void entityInit() {}
    
        /**
         * Returns true if other Entities should be prevented from moving through this Entity.
         */
        public boolean canBeCollidedWith()
        {
            return !this.isDead;
        }
    
        /**
         * Called to update the entity's position/logic.
         */
        public void onUpdate()
        {
            System.out.println(fallTile);
            if (this.fallTile != null)
            {
                Block block = this.fallTile.getBlock();
    
                if (block.getMaterial() == Material.air)
                {
                    this.setDead();
                }
                else
                {
                    this.prevPosX = this.posX;
                    this.prevPosY = this.posY;
                    this.prevPosZ = this.posZ;
                    BlockPos blockpos;
    
                    if (this.fallTime++ == 0)
                    {
                        blockpos = new BlockPos(this);
    
                        if (this.worldObj.getBlockState(blockpos).getBlock() == block)
                        {
                            this.worldObj.setBlockToAir(blockpos);
                        }
                        else if (!this.worldObj.isRemote)
                        {
                            this.setDead();
                            return;
                        }
                    }
    
                    this.motionY -= 0.03999999910593033D;
                    this.moveEntity(this.motionX, this.motionY, this.motionZ);
                    this.motionY *= 0.98D;
                    if (this.fallTime > 10 )
                    {
                        this.motionX *= 0.5D;
                        this.motionZ *= 0.5D;
                    }
                    if (!this.worldObj.isRemote)
                    {
                        blockpos = new BlockPos(this);
    
                        if (this.fallTime > 10 && this.onGround)
                        {
                            this.motionX *= 0.699999988079071D;
                            this.motionZ *= 0.699999988079071D;
                            this.motionY *= -0.5D;
    
                            if (this.worldObj.getBlockState(blockpos).getBlock() != Blocks.piston_extension)
                            {
                                this.setDead();
    
                                if (!this.field_145808_f && this.worldObj.canBlockBePlaced(block, blockpos, true, EnumFacing.UP, (Entity)null, (ItemStack)null) && this.worldObj.setBlockState(blockpos, this.fallTile, 3))
                                {
                                    if (block instanceof BlockConvoyorBelt)
                                    {
                                        ((BlockConvoyorBelt)block).onEndFalling(this.worldObj, blockpos);
                                    }
    
                                    if (this.tileEntityData != null && block instanceof ITileEntityProvider)
                                    {
                                        TileEntity tileentity = this.worldObj.getTileEntity(blockpos);
    
                                        if (tileentity != null)
                                        {
                                            NBTTagCompound nbttagcompound = new NBTTagCompound();
                                            tileentity.writeToNBT(nbttagcompound);
                                            Iterator iterator = this.tileEntityData.getKeySet().iterator();
    
                                            while (iterator.hasNext())
                                            {
                                                String s = (String)iterator.next();
                                                NBTBase nbtbase = this.tileEntityData.getTag(s);
    
                                                if (!s.equals("x") && !s.equals("y") && !s.equals("z"))
                                                {
                                                    nbttagcompound.setTag(s, nbtbase.copy());
                                                }
                                            }
    
                                            tileentity.readFromNBT(nbttagcompound);
                                            tileentity.markDirty();
                                        }
                                    }
                                }
                                else if (this.shouldDropItem && !this.field_145808_f && this.worldObj.getGameRules().getGameRuleBooleanValue("doTileDrops"))
                                {
                                    this.entityDropItem(new ItemStack(block, 1, block.damageDropped(this.fallTile)), 0.0F);
                                }
                            }
                        }
                        else if (this.fallTime > 100 && !this.worldObj.isRemote && (blockpos.getY() < 1 || blockpos.getY() > 256) || this.fallTime > 600)
                        {
                            if (this.shouldDropItem && this.worldObj.getGameRules().getGameRuleBooleanValue("doTileDrops"))
                            {
                                this.entityDropItem(new ItemStack(block, 1, block.damageDropped(this.fallTile)), 0.0F);
                            }
    
                            this.setDead();
                        }
                    }
                }
            }
        }
    
        public void fall(float distance, float damageMultiplier)
        {
    
            Block block = this.fallTile.getBlock();
    
            if (this.hurtEntities)
            {
                int i = MathHelper.ceiling_float_int(distance - 1.0F);
    
                if (i > 0)
                {
                    ArrayList arraylist = Lists.newArrayList(this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.getEntityBoundingBox()));
                    boolean flag = block == Blocks.anvil;
                    DamageSource damagesource = flag ? DamageSource.anvil : DamageSource.fallingBlock;
                    Iterator iterator = arraylist.iterator();
    
                    while (iterator.hasNext())
                    {
                        Entity entity = (Entity)iterator.next();
                        entity.attackEntityFrom(damagesource, (float)Math.min(MathHelper.floor_float((float)i * this.fallHurtAmount), this.fallHurtMax));
                    }
    
                    if (flag && (double)this.rand.nextFloat() < 0.05000000074505806D + (double)i * 0.05D)
                    {
                        int j = ((Integer)this.fallTile.getValue(BlockAnvil.DAMAGE)).intValue();
                        ++j;
    
                        if (j > 2)
                        {
                            this.field_145808_f = true;
                        }
                        else
                        {
                            this.fallTile = this.fallTile.withProperty(BlockAnvil.DAMAGE, Integer.valueOf(j));
                        }
                    }
                }
            }
        }
    
        /**
         * (abstract) Protected helper method to write subclass entity data to NBT.
         */
        protected void writeEntityToNBT(NBTTagCompound tagCompound)
        {
            Block block = this.fallTile != null ? this.fallTile.getBlock() : Blocks.air;
            ResourceLocation resourcelocation = (ResourceLocation)Block.blockRegistry.getNameForObject(block);
            tagCompound.setString("Block", resourcelocation == null ? "" : resourcelocation.toString());
            tagCompound.setByte("Data", (byte)block.getMetaFromState(this.fallTile));
            tagCompound.setByte("Time", (byte)this.fallTime);
            tagCompound.setBoolean("DropItem", this.shouldDropItem);
            tagCompound.setBoolean("HurtEntities", this.hurtEntities);
            tagCompound.setFloat("FallHurtAmount", this.fallHurtAmount);
            tagCompound.setInteger("FallHurtMax", this.fallHurtMax);
    
            if (this.tileEntityData != null)
            {
                tagCompound.setTag("TileEntityData", this.tileEntityData);
            }
        }
    
        /**
         * (abstract) Protected helper method to read subclass entity data from NBT.
         */
        protected void readEntityFromNBT(NBTTagCompound tagCompund)
        {
            int i = tagCompund.getByte("Data") & 255;
    
            if (tagCompund.hasKey("Block", 8))
            {
                this.fallTile = Block.getBlockFromName(tagCompund.getString("Block")).getStateFromMeta(i);
            }
            else if (tagCompund.hasKey("TileID", 99))
            {
                this.fallTile = Block.getBlockById(tagCompund.getInteger("TileID")).getStateFromMeta(i);
            }
            else
            {
                this.fallTile = Block.getBlockById(tagCompund.getByte("Tile") & 255).getStateFromMeta(i);
            }
    
            this.fallTime = tagCompund.getByte("Time") & 255;
            Block block = this.fallTile.getBlock();
    
            if (tagCompund.hasKey("HurtEntities", 99))
            {
                this.hurtEntities = tagCompund.getBoolean("HurtEntities");
                this.fallHurtAmount = tagCompund.getFloat("FallHurtAmount");
                this.fallHurtMax = tagCompund.getInteger("FallHurtMax");
            }
            else if (block == Blocks.anvil)
            {
                this.hurtEntities = true;
            }
    
            if (tagCompund.hasKey("DropItem", 99))
            {
                this.shouldDropItem = tagCompund.getBoolean("DropItem");
            }
    
            if (tagCompund.hasKey("TileEntityData", 10))
            {
                this.tileEntityData = tagCompund.getCompoundTag("TileEntityData");
            }
    
            if (block == null || block.getMaterial() == Material.air)
            {
                this.fallTile = Blocks.sand.getDefaultState();
            }
        }
    
        public void setHurtEntities(boolean p_145806_1_)
        {
            this.hurtEntities = p_145806_1_;
        }
    
        public void addEntityCrashInfo(CrashReportCategory category)
        {
            super.addEntityCrashInfo(category);
    
            if (this.fallTile != null)
            {
                Block block = this.fallTile.getBlock();
                category.addCrashSection("Immitating block ID", Integer.valueOf(Block.getIdFromBlock(block)));
                category.addCrashSection("Immitating block data", Integer.valueOf(block.getMetaFromState(this.fallTile)));
            }
        }
    
        @SideOnly(Side.CLIENT)
        public World getWorldObj()
        {
            return this.worldObj;
        }
    
        /**
         * Return whether this entity should be rendered as on fire.
         */
        @SideOnly(Side.CLIENT)
        public boolean canRenderOnFire()
        {
            return false;
        }
    
        public IBlockState getBlock()
        {
            return this.fallTile;
        }
    }
    

    Le Render :

    @SideOnly(Side.CLIENT)
    public class RenderConvoyingBlock extends Render
    {
    
        public RenderConvoyingBlock(RenderManager p_i46177_1_)
        {
            super(p_i46177_1_);
            this.shadowSize = 0.5F;
        }
    
        public void doRender(EntityConvoyingBlock p_180557_1_, double p_180557_2_, double p_180557_4_, double p_180557_6_, float p_180557_8_, float p_180557_9_)
        {
            System.out.println("doRender ConvoyingBlock");
            if (p_180557_1_.getBlock() != null)
            {
                this.bindTexture(TextureMap.locationBlocksTexture);
                IBlockState iblockstate = p_180557_1_.getBlock();
                Block block = iblockstate.getBlock();
                BlockPos blockpos = new BlockPos(p_180557_1_);
                World world = p_180557_1_.getWorldObj();
    
                if (iblockstate != world.getBlockState(blockpos) && block.getRenderType() != -1)
                {
                    if (block.getRenderType() == 3)
                    {
                        GlStateManager.pushMatrix();
                        GlStateManager.translate((float)p_180557_2_, (float)p_180557_4_, (float)p_180557_6_);
                        GlStateManager.disableLighting();
                        Tessellator tessellator = Tessellator.getInstance();
                        WorldRenderer worldrenderer = tessellator.getWorldRenderer();
                        worldrenderer.startDrawingQuads();
                        worldrenderer.setVertexFormat(DefaultVertexFormats.BLOCK);
                        int i = blockpos.getX();
                        int j = blockpos.getY();
                        int k = blockpos.getZ();
                        worldrenderer.setTranslation((double)((float)(-i) - 0.5F), (double)(-j), (double)((float)(-k) - 0.5F));
                        BlockRendererDispatcher blockrendererdispatcher = Minecraft.getMinecraft().getBlockRendererDispatcher();
                        IBakedModel ibakedmodel = blockrendererdispatcher.getModelFromBlockState(iblockstate, world, (BlockPos)null);
                        blockrendererdispatcher.getBlockModelRenderer().renderModel(world, ibakedmodel, iblockstate, blockpos, worldrenderer, false);
                        worldrenderer.setTranslation(0.0D, 0.0D, 0.0D);
                        tessellator.draw();
                        GlStateManager.enableLighting();
                        GlStateManager.popMatrix();
                        super.doRender(p_180557_1_, p_180557_2_, p_180557_4_, p_180557_6_, p_180557_8_, p_180557_9_);
                     }
                }
            }
        }
    
        /**
         * Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture.
         */
        protected ResourceLocation getEntityTexture(EntityConvoyingBlock entity)
        {
            return TextureMap.locationBlocksTexture;
        }
    
        /**
         * Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture.
         */
        protected ResourceLocation getEntityTexture(Entity entity)
        {
            return this.getEntityTexture((EntityConvoyingBlock)entity);
        }
    
        /**
         * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then
         * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic
         * (Render<t extends="" entity="">) and this method has signature public void func_76986_a(T entity, double d, double d1,
         * double d2, float f, float f1). But JAD is pre 1.5 so doe
         */
        public void doRender(Entity entity, double x, double y, double z, float p_76986_8_, float partialTicks)
        {
            System.out.println("doRender ConvoyingBlock-");
            this.doRender((EntityConvoyingBlock)entity, x, y, z, p_76986_8_, partialTicks);
        }
    }
    ```</t>

  • Administrateurs

    Tu enregistre comment ton rendu ? Car franchement je ne vois pas pourquoi fallTile est null.



  • Petite remarque surement intéressante:

    j'ai mis System.out.println(fallTile+" : "+this); au lieu de System.out.println(fallTile); et sa me met de manière alternée:
    [16:12:37] [Server thread/INFO] [STDOUT]: [com.maxyfactory.mod.entity.EntityConvoyingBlock:onUpdate:88]: minecraft:grass[snowy=false] : EntityConvoyingBlock['entity.maxyfactory.convoyingBlock.name'/166432, l='New World', x=-635,50, y=5,00, z=-974,50]
    et
    [16:12:37] [Client thread/INFO] [STDOUT]: [com.maxyfactory.mod.entity.EntityConvoyingBlock:onUpdate:88]: null : EntityConvoyingBlock['entity.maxyfactory.convoyingBlock.name'/166432, l='MpServer', x=-635,50, y=5,00, z=-974,50]
    quand fallTile est null, l = MpServeur alors que quand fallTile est correcte, l = New Wold (le nom de mon monde)

    Le Proxy Client :

    public class ClientProxy extends CommonProxy{
    
    @Override
    public void registerRenders()
    {
    ItemMod.registerRenders();
    BlockMod.registerRenders();
    RenderingRegistry.registerEntityRenderingHandler(EntityConvoyingBlock.class, new RenderConvoyingBlock(Minecraft.getMinecraft().getRenderManager()));
    
    }
    }
    

  • Administrateurs

    Ah surement car c'est null côté client.
    Problème de synchro du-coup.
    Utilises l'interface IAdditionnalEntityData pour synchroniser le bloc.



  • Comment fait-on pour l'utiliser ?


  • Administrateurs

    Tu ajoutés implements IAdditionalEntityData après la déclaration de ta classe (il me semble que la classe s'appelle comme ça a vérifier) puis tu ajoutés les deux méthodes qu'il te demander d'implémenter. Elles s'utilisent comme celle d'un paquet



  • Eclipse ne trouve pas IAdditionalEntityData, tu est sûr que c'est le bon mon ?
    (Désolé d'avoir été si long)


  • Administrateurs

    Non je ne suis pas sûr et je l'ai même précisé dans mon message.
    C'est IEntityAdditionalSpawnData