Posted February 21, 201312 yr As a learning step on my way to building a custom ship mod, I am trying to get working a wand item that deletes a block and replaces it with an entity that looks and feels exactly like the block. Seems reasonably straightforward, and it mostly works, but when my renderer tries to access the blockId of the deleted block (which I store in the new entity) it is rendering, the code fails (so currently the best I can do is render all the entities as the same arbitrary block type...) This is because the default entity constructor, Entity(World) is called (not by me!) by cpw.mods.fml.client.FMLClientHandler.spawnEntityIntoClientWorld() at some point after my world.spawnEntityInWorld( entity ) call, and before the renderer starts rendering, which resets the blockId stored in the entity to 0 before the renderer can use it. I assume this all happens because of something I've done wrong somewhere... Is it related to something happening on the client side that shouldn't be happening? Is it anything to do with how/where I have registered my entity/renderer, etc? What can I do to stop this extra call to the default constructor of my entity? My wand item that turns a block to an entity: public class WandItem extends Item { public WandItem(int par1) { super(par1); this.setCreativeTab(CreativeTabs.tabMaterials); } public String getTextureFile() { return "/smpShipsBlocks.png"; } public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10) { if( !par3World.isRemote && par3World.blockExists(par4, par5, par6) ) {//###only place on the server side int blockID = par3World.getBlockId( par4, par5 , par6 ); //###get block type int blockMeta = par3World.getBlockMetadata( par4, par5 , par6 ); //###get block meta data par3World.setBlock(par4, par5, par6, 0 ); // set block to air BlockEntity e = new BlockEntity(par3World, par4 , par5 , par6 , blockID , blockMeta ); //###create entity, passing in blockId par3World.spawnEntityInWorld( e ); //###is this the best way to place the entity in world? //############### at this point in the code there is no problem: e.blockId is correct return true; }//if return false; }//on use }//class My entity that looks and feels like a block: public class BlockEntity extends Entity //###an entity that looks and feels like a block { public int blockId; //###stores blockId of the deleted block, so the renderer can check and render correct texture public int meta; public BlockEntity(World par1World) { //###constructor #1 - called in cpw.mods.fml.client.FMLClientHandler.spawnEntityIntoClientWorld() super(par1World); this.setSize(1.0F ,1.0F); this.yOffset = 0.5F; new Exception().printStackTrace(); } public BlockEntity(World par1World, int x, int y, int z , int blockId , int meta ) { //###constructor #2 - the one that I call from my wand item this(par1World); this.blockId = blockId; //###save the blockId this.meta = meta; this.setPosition(x+0.5F, y+0.0F, z+0.5F); } @Override public AxisAlignedBB getBoundingBox() { return this.boundingBox; } protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) { par1NBTTagCompound.setByte("Tile", (byte)this.blockId); par1NBTTagCompound.setByte("Data", (byte)this.meta); } protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) { this.blockId = par1NBTTagCompound.getByte("Tile") ; this.meta = par1NBTTagCompound.getByte("Data"); } } My renderer for the entity: @SideOnly(Side.CLIENT) public class BlockEntityRender extends Render { private RenderBlocks blockRenderer = new RenderBlocks(); public void doRender(Entity theEntity, double par2, double par4, double par6, float par8, float par9) { //########## at this point theEntity.blockId has already been reset to 0 by a call to constructor #1 of the entity this.renderBlockEntity((BlockEntity)theEntity, par2, par4, par6, par8, par9); } public void renderBlockEntity(BlockEntity theEntity, double par2, double par4, double par6, float par8, float par9) { Block b = Block.blocksList[theEntity.blockId]; //###code crashes here, because theEntityBlockId always = 0 GL11.glPushMatrix(); GL11.glTranslatef((float)par2, (float)par4, (float)par6); this.loadTexture("/terrain.png"); this.blockRenderer.renderBlockAsItem( b , 0 , theEntity.getBrightness(par9)); //###render entity as the correct block (b), according to theEntity.blockId GL11.glPopMatrix(); } } And just in case, here is my mod class, and client proxy (my common proxy has nothing happening in it): public class SMPships { public static Item wandItem; @SidedProxy(clientSide = "SMPships.ClientProxySMPships", serverSide = "SMPships.CommonProxySMPships") public static CommonProxySMPships proxy; @Init public void load(FMLInitializationEvent event) { proxy.registerRenderThings(); wandItem = new WandItem( 5000 ).setIconIndex( 5 ).setItemName( "wand" ); LanguageRegistry.addName(wandItem, "Wand" ); EntityRegistry.registerModEntity(BlockEntity.class, "grumdot_myentityblock", 2, this, 80, 3, true); //###is this the best way to register my entity type? }//load }//class public class ClientProxySMPships extends CommonProxySMPships{ @Override public void registerRenderThings() { MinecraftForgeClient.preloadTexture("smpShipsBlocks.png"); RenderingRegistry.registerEntityRenderingHandler( BlockEntity.class, new BlockEntityRender() ); //###is this the best/only way to link an entity with renderer? }//register render things }//class
February 21, 201312 yr You should use a custom spawning packet. I don't know what's the proper way to do it, but take a look at: cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration.setCustomSpawning cpw.mods.fml.common.registry.EntityRegistry.doModEntityRegistration
February 21, 201312 yr Author Thanks for the reply N1xx1. I had looked at those classes already, and made an attempt to setCustomSpawning() in EntityRegistry, but failed (perhaps because I didn't use a custom spawn packet???).... Why do I need a custom spawning packet? What (specifically) should I be planning to achieve with it? I can handle packet sending in general, but where can I get more info on custom spawning packets in particular?
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.