Entité Block
-
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> -
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())); } } -
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 ?
-
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) -
Non je ne suis pas sûr et je l’ai même précisé dans mon message.
C’est IEntityAdditionalSpawnData -
J’ai essayé de faire fonctionner IEntityAdditionalSpawnData mais je n’y arrives pas, je n’ai jamais utilisé de paquet.
J’ai n’arrive pas a écrire un IBlockState dans le ByteBuf, voici un essai que j’ai fait :@Override public void writeSpawnData(ByteBuf buffer) { Object[] arr = this.fallTile.getProperties().values().toArray(); for (int i = 0 ; i <= arr.length; i++) { Object obj = arr*; buffer.writeByte((Integer) obj); } } @Override public void readSpawnData(ByteBuf additionalData) { byte[] b = additionalData.array(); for (int i = 0 ; i <= b.length; i++) { this.fallTile.withProperty(additionalData.getByte(i) /*ici, je ne sais pas quoi mettre*/, additionalData.getByte(i)); } }Puis-je avoir de l’aide, s’il vous plais.
-
Il faut envoyer l’id du bloc et le metadata.
-
Merci beaucoup, ça fonctionne maintenant voici le code ( plus simple au final ) :
@Override public void writeSpawnData(ByteBuf buffer) { int ID = Block.getIdFromBlock(this.fallTile.getBlock()); int meta = this.fallTile.getBlock().getMetaFromState(this.fallTile); buffer.writeInt(ID); buffer.writeInt(meta); } @Override public void readSpawnData(ByteBuf additionalData) { int ID = additionalData.readInt(); int meta = additionalData.readInt(); this.fallTile = Block.getBlockById(ID).getStateFromMeta(meta); }Petit screen pour montrer la beauté de mon travail
:
