Guest Posted February 6, 2016 Share Posted February 6, 2016 When I place one of my blocks, the game crashes with a class cast exception when getting the icon. This is my block class: package XFactHD.thermalreactors.common.blocks.machine.fissionReactor; import XFactHD.thermalreactors.common.blocks.BlockBaseTR; import XFactHD.thermalreactors.common.blocks.ItemBlockBaseTR; import XFactHD.thermalreactors.common.util.Reference; import net.minecraft.block.material.Material; import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EnumCreatureType; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.IIcon; import net.minecraft.util.MathHelper; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; public class BlockReactorComponent extends BlockBaseTR { public BlockReactorComponent() { super("BlockReactorComponent", Material.iron, 4, ItemBlockBaseTR.class, "Casing", "ControlRod", "Core", "BasicExchanger", "AdvExchanger", "BasicDissipator", "AdvDissipator", "Glass", "Controller", "Port"); } @Override public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int meta, float hitX, float hitY, float hitZ) { TileEntity te = world.getTileEntity(x, y, z); if (te instanceof TileEntityFissionController && !((TileEntityFissionController)te).formed && !world.isRemote) { ((TileEntityFissionController)te).checkStructure(); return true; } return false; } @Override public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase entity, ItemStack stack) { if (stack.getItemDamage() == { int l = MathHelper.floor_double((double) (entity.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3; if (l == 0) { world.setBlockMetadataWithNotify(x, y, z, 8, 2); } if (l == 1) { world.setBlockMetadataWithNotify(x, y, z, 9, 2); } if (l == 2) { world.setBlockMetadataWithNotify(x, y, z, 10, 2); } if (l == 3) { world.setBlockMetadataWithNotify(x, y, z, 11, 2); } } if (stack.getItemDamage() == 9) { int l = MathHelper.floor_double((double) (entity.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3; if (l == 0) { world.setBlockMetadataWithNotify(x, y, z, 12, 2); } if (l == 1) { world.setBlockMetadataWithNotify(x, y, z, 13, 2); } if (l == 2) { world.setBlockMetadataWithNotify(x, y, z, 14, 2); } if (l == 3) { world.setBlockMetadataWithNotify(x, y, z, 15, 2); } } } @Override public void registerBlockIcons(IIconRegister iconRegister) { //Casing icons[0][0] = iconRegister.registerIcon(Reference.MOD_ID + ":" + "blockReactorComponent" + "_" + "Base"); //Control Rod icons[1][0] = iconRegister.registerIcon(Reference.MOD_ID + ":" + "blockReactorComponent" + "_" + "Base"); icons[1][1] = iconRegister.registerIcon(Reference.MOD_ID + ":" + "blockReactorComponent" + "_" + "ControlRodTop"); icons[1][2] = iconRegister.registerIcon(Reference.MOD_ID + ":" + "blockReactorComponent" + "_" + "ControlRodBottom"); //Core icons[2][0] = iconRegister.registerIcon(Reference.MOD_ID + ":" + "blockReactorComponent" + "_" + "CoreTop"); icons[2][1] = iconRegister.registerIcon(Reference.MOD_ID + ":" + "blockReactorComponent" + "_" + "CoreSide"); //Basic Heat Exchanger icons[3][0] = iconRegister.registerIcon(Reference.MOD_ID + ":" + "blockReactorComponent" + "_" + "BasicExchangerSide"); icons[3][1] = iconRegister.registerIcon(Reference.MOD_ID + ":" + "blockReactorComponent" + "_" + "BasicExchangerTop"); icons[3][2] = iconRegister.registerIcon(Reference.MOD_ID + ":" + "blockReactorComponent" + "_" + "BasicExchangerBottom"); //Advanced Heat Exchanger icons[4][0] = iconRegister.registerIcon(Reference.MOD_ID + ":" + "blockReactorComponent" + "_" + "AdvExchangerSide"); icons[4][1] = iconRegister.registerIcon(Reference.MOD_ID + ":" + "blockReactorComponent" + "_" + "AdvExchangerTop"); icons[4][2] = iconRegister.registerIcon(Reference.MOD_ID + ":" + "blockReactorComponent" + "_" + "AdvExchangerBottom"); //Basic Heat Dissipator icons[5][0] = iconRegister.registerIcon(Reference.MOD_ID + ":" + "blockReactorComponent" + "_" + "BasicDissipatorSide"); icons[5][1] = iconRegister.registerIcon(Reference.MOD_ID + ":" + "blockReactorComponent" + "_" + "BasicDissipatorTop"); icons[5][2] = iconRegister.registerIcon(Reference.MOD_ID + ":" + "blockReactorComponent" + "_" + "BasicDissipatorBottom"); //Advanced Heat Dissipator icons[6][0] = iconRegister.registerIcon(Reference.MOD_ID + ":" + "blockReactorComponent" + "_" + "AdvDissipatorSide"); icons[6][1] = iconRegister.registerIcon(Reference.MOD_ID + ":" + "blockReactorComponent" + "_" + "AdvDissipatorTop"); icons[6][2] = iconRegister.registerIcon(Reference.MOD_ID + ":" + "blockReactorComponent" + "_" + "AdvDissipatorBottom"); //Glass icons[7][0] = iconRegister.registerIcon(Reference.MOD_ID + ":" + "blockReactorComponent" + "_" + "Glass"); //Controller icons[8][0] = iconRegister.registerIcon(Reference.MOD_ID + ":" + "blockReactorComponent" + "_" + "Base"); icons[8][1] = iconRegister.registerIcon(Reference.MOD_ID + ":" + "blockReactorComponent" + "_" + "ControllerFront"); icons[8][2] = iconRegister.registerIcon(Reference.MOD_ID + ":" + "blockReactorComponent" + "_" + "ControllerFrontInactive"); icons[8][3] = iconRegister.registerIcon(Reference.MOD_ID + ":" + "blockReactorComponent" + "_" + "ControllerFrontActive"); //Port icons[9][0] = iconRegister.registerIcon(Reference.MOD_ID + ":" + "blockReactorComponent" + "_" + "Base"); icons[9][1] = iconRegister.registerIcon(Reference.MOD_ID + ":" + "blockReactorComponent" + "_" + "PortFrontIn"); icons[9][2] = iconRegister.registerIcon(Reference.MOD_ID + ":" + "blockReactorComponent" + "_" + "PortFrontOut"); } @Override public IIcon getIcon(int side, int meta) { switch (meta) { case 0: return icons[0][0]; case 1: return (side==0||side==1) ? (side==0 ? icons[1][2] : icons[1][1]) : icons[1][0]; case 2: return (side==0||side==1) ? icons[2][0] : icons[2][1]; case 3: return (side==0||side==1) ? (side==0 ? icons[3][2] : icons[3][1]) : icons[3][0]; case 4: return (side==0||side==1) ? (side==0 ? icons[4][2] : icons[4][1]) : icons[4][0]; case 5: return (side==0||side==1) ? (side==0 ? icons[5][2] : icons[5][1]) : icons[5][0]; case 6: return (side==0||side==1) ? (side==0 ? icons[6][2] : icons[6][1]) : icons[6][0]; case 7: return icons[7][0]; case 8: return side==3 ? icons[8][2] : icons[8][0]; case 9: return side==3 ? icons[9][1] : icons[9][0]; } return super.getIcon(side, meta); } @Override public IIcon getIcon(IBlockAccess world, int x, int y, int z, int side) { int meta = world.getBlockMetadata(x, y, z); TileEntity te = world.getTileEntity(x, y, z); switch (meta) { case 0: return icons[0][0]; case 1: switch (side) { case 0: return icons[1][2]; case 1: return icons[1][1]; case 2: return icons[1][0]; case 3: return icons[1][0]; case 4: return icons[1][0]; case 5: return icons[1][0]; } case 2: return (side==0||side==1) ? icons[2][0] : icons[2][1]; case 3: switch (side) { case 0: return icons[3][2]; case 1: return icons[3][1]; case 2: return icons[3][0]; case 3: return icons[3][0]; case 4: return icons[3][0]; case 5: return icons[3][0]; } case 4: switch (side) { case 0: return icons[3][2]; case 1: return icons[3][1]; case 2: return icons[3][0]; case 3: return icons[3][0]; case 4: return icons[3][0]; case 5: return icons[3][0]; } case 5: switch (side) { case 0: return icons[3][2]; case 1: return icons[3][1]; case 2: return icons[3][0]; case 3: return icons[3][0]; case 4: return icons[3][0]; case 5: return icons[3][0]; } case 6: switch (side) { case 0: return icons[3][2]; case 1: return icons[3][1]; case 2: return icons[3][0]; case 3: return icons[3][0]; case 4: return icons[3][0]; case 5: return icons[3][0]; } case 7: return icons[7][0]; case 8: switch (side) { case 0: return icons[8][0]; case 1: return icons[8][0]; case 2: int status = ((TileEntityFissionController)te).formed ? (((TileEntityFissionController)te).active ? 3 : 2) : 1; return icons[8][status]; case 3: return icons[8][0]; case 4: return icons[8][0]; case 5: return icons[8][0]; } case 9: switch (side) { case 0: return icons[8][0]; case 1: return icons[8][0]; case 2: return icons[8][0]; case 3: return icons[8][0]; case 4: return icons[8][0]; case 5: int status = ((TileEntityFissionController)te).formed ? (((TileEntityFissionController)te).active ? 3 : 2) : 1; return icons[8][status]; } case 10: switch (side) { case 0: return icons[8][0]; case 1: return icons[8][0]; case 2: return icons[8][0]; case 3: int status = ((TileEntityFissionController)te).formed ? (((TileEntityFissionController)te).active ? 3 : 2) : 1; return icons[8][status]; case 4: return icons[8][0]; case 5: return icons[8][0]; } case 11: switch (side) { case 0: return icons[8][0]; case 1: return icons[8][0]; case 2: return icons[8][0]; case 3: return icons[8][0]; case 4: int status = ((TileEntityFissionController)te).formed ? (((TileEntityFissionController)te).active ? 3 : 2) : 1; return icons[8][status]; case 5: return icons[8][0]; } case 12: switch (side) { case 0: return icons[9][0]; case 1: return icons[9][0]; case 2: int status = ((TileEntityFissionPort)te).input ? 1 : 2; return icons[9][status]; <-- This line is crashing case 3: return icons[9][0]; case 4: return icons[9][0]; case 5: return icons[9][0]; } case 13: switch (side) { case 0: return icons[9][0]; case 1: return icons[9][0]; case 2: return icons[9][0]; case 3: return icons[9][0]; case 4: return icons[9][0]; case 5: int status = ((TileEntityFissionPort)te).input ? 1 : 2; return icons[9][status]; } case 14: switch (side) { case 0: return icons[9][0]; case 1: return icons[9][0]; case 2: return icons[9][0]; case 3: int status = ((TileEntityFissionPort)te).input ? 1 : 2; return icons[9][status]; case 4: return icons[9][0]; case 5: return icons[9][0]; } case 15: switch (side) { case 0: return icons[9][0]; case 1: return icons[9][0]; case 2: return icons[9][0]; case 3: return icons[9][0]; case 4: int status = ((TileEntityFissionPort)te).input ? 1 : 2; return icons[9][status]; case 5: return icons[9][0]; } } return super.getIcon(world, x, y, z, side); } @Override public boolean isOpaqueCube() { return false; } @Override public boolean shouldSideBeRendered(IBlockAccess world, int x, int y, int z, int side) { //return !(world.getBlock(x, y, z) instanceof BlockReactorComponent && world.getBlockMetadata(x, y, z) == 7); switch (side) { case 0: return !(world.getBlock(x, y, z) instanceof BlockReactorComponent && world.getBlockMetadata(x, y, z) == 7 && world.getBlockMetadata(x, y+1, z) == 7); case 1: return !(world.getBlock(x, y, z) instanceof BlockReactorComponent && world.getBlockMetadata(x, y, z) == 7 && world.getBlockMetadata(x, y-1, z) == 7); case 2: return !(world.getBlock(x, y, z) instanceof BlockReactorComponent && world.getBlockMetadata(x, y, z) == 7 && world.getBlockMetadata(x, y, z+1) == 7); case 3: return !(world.getBlock(x, y, z) instanceof BlockReactorComponent && world.getBlockMetadata(x, y, z) == 7 && world.getBlockMetadata(x, y, z-1) == 7); case 4: return !(world.getBlock(x, y, z) instanceof BlockReactorComponent && world.getBlockMetadata(x, y, z) == 7 && world.getBlockMetadata(x+1, y, z) == 7); case 5: return !(world.getBlock(x, y, z) instanceof BlockReactorComponent && world.getBlockMetadata(x, y, z) == 7 && world.getBlockMetadata(x-1, y, z) == 7); } return true; } @Override public int getLightValue(IBlockAccess world, int x, int y, int z) { if (world.getBlock(x, y, z) instanceof BlockReactorComponent && world.getBlockMetadata(x, y, z) == 2) { return 5; } return 0; } @Override public boolean canCreatureSpawn(EnumCreatureType type, IBlockAccess world, int x, int y, int z) { return false; } @Override public TileEntity createNewTileEntity(World world, int meta) { switch (meta) { case 0: return new TileEntityFissionCasing(); case 1: return new TileEntityFissionControlRod(); case 2: return new TileEntityFissionCore(); case 3: //return new TileEntityFissionExchangerBasic(); case 4: //return new TileEntityFissionExchangerAdv(); case 5: //return new TileEntityFissionDissipatorBasic(); case 6: //return new TileEntityFissionDissipatorAdv(); case 7: return null; case 8: return new TileEntityFissionController(); case 9: return new TileEntityFissionController(); case 10: return new TileEntityFissionController(); case 11: return new TileEntityFissionController(); case 12: return new TileEntityFissionPort(); case 13: return new TileEntityFissionPort(); case 14: return new TileEntityFissionPort(); case 15: return new TileEntityFissionPort(); default: return null; } } } In getIcon(IBlockAccess world, int x, int y, int z, int side) I am looking for the metadata 12 to get the icon that should face the player. As long as the block is in the players inventory, the metadata is 9. In onBlockPlaced I am setting the block metadata to 12, 13, 14 or 15 depending on the orientation of the player. As I am telling the block in createNewTileEntity that metadata 12 should be the TileEntityFissionPort, I don't really get why it is trying to cast a TileEntityFissionController to TileEntityFissionController. For the TileEntityFissionController I am doing the same (metadata 8-11) and it is working properly. The crash report: java.lang.ClassCastException: XFactHD.thermalreactors.common.blocks.machine.fissionReactor.TileEntityFissionController cannot be cast to XFactHD.thermalreactors.common.blocks.machine.fissionReactor.TileEntityFissionPort at XFactHD.thermalreactors.common.blocks.machine.fissionReactor.BlockReactorComponent.getIcon(BlockReactorComponent.java:271) ~[blockReactorComponent.class:?] at net.minecraft.client.renderer.RenderBlocks.getBlockIcon(RenderBlocks.java:8446) ~[RenderBlocks.class:?] at net.minecraft.client.renderer.RenderBlocks.renderStandardBlockWithAmbientOcclusion(RenderBlocks.java:5248) ~[RenderBlocks.class:?] at net.minecraft.client.renderer.RenderBlocks.renderStandardBlock(RenderBlocks.java:4427) ~[RenderBlocks.class:?] at net.minecraft.client.renderer.RenderBlocks.renderBlockByRenderType(RenderBlocks.java:348) ~[RenderBlocks.class:?] at net.minecraft.client.renderer.WorldRenderer.updateRenderer(WorldRenderer.java:207) ~[WorldRenderer.class:?] at net.minecraft.client.renderer.RenderGlobal.updateRenderers(RenderGlobal.java:1618) ~[RenderGlobal.class:?] at net.minecraft.client.renderer.EntityRenderer.renderWorld(EntityRenderer.java:1263) ~[EntityRenderer.class:?] at net.minecraft.client.renderer.EntityRenderer.updateCameraAndRender(EntityRenderer.java:1087) ~[EntityRenderer.class:?] at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1067) ~[Minecraft.class:?] at net.minecraft.client.Minecraft.run(Minecraft.java:962) [Minecraft.class:?] at net.minecraft.client.main.Main.main(Main.java:164) [Main.class:?] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_45] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_45] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_45] at java.lang.reflect.Method.invoke(Method.java:497) ~[?:1.8.0_45] at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.11.jar:?] at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.11.jar:?] at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source) [start/:?] at GradleStart.main(Unknown Source) [start/:?] [01:09:49] [server thread/INFO]: Stopping server [01:09:49] [Client thread/INFO] [sTDOUT]: [net.minecraft.client.Minecraft:displayCrashReport:388]: ---- Minecraft Crash Report ---- // You're mean. Time: 06.02.16 01:09 Description: Unexpected error java.lang.ClassCastException: XFactHD.thermalreactors.common.blocks.machine.fissionReactor.TileEntityFissionController cannot be cast to XFactHD.thermalreactors.common.blocks.machine.fissionReactor.TileEntityFissionPort at XFactHD.thermalreactors.common.blocks.machine.fissionReactor.BlockReactorComponent.getIcon(BlockReactorComponent.java:271) at net.minecraft.client.renderer.RenderBlocks.getBlockIcon(RenderBlocks.java:8446) at net.minecraft.client.renderer.RenderBlocks.renderStandardBlockWithAmbientOcclusion(RenderBlocks.java:5248) at net.minecraft.client.renderer.RenderBlocks.renderStandardBlock(RenderBlocks.java:4427) at net.minecraft.client.renderer.RenderBlocks.renderBlockByRenderType(RenderBlocks.java:348) at net.minecraft.client.renderer.WorldRenderer.updateRenderer(WorldRenderer.java:207) at net.minecraft.client.renderer.RenderGlobal.updateRenderers(RenderGlobal.java:1618) at net.minecraft.client.renderer.EntityRenderer.renderWorld(EntityRenderer.java:1263) at net.minecraft.client.renderer.EntityRenderer.updateCameraAndRender(EntityRenderer.java:1087) at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1067) at net.minecraft.client.Minecraft.run(Minecraft.java:962) at net.minecraft.client.main.Main.main(Main.java:164) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) at net.minecraft.launchwrapper.Launch.main(Launch.java:28) 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 XFactHD.thermalreactors.common.blocks.machine.fissionReactor.BlockReactorComponent.getIcon(BlockReactorComponent.java:271) at net.minecraft.client.renderer.RenderBlocks.getBlockIcon(RenderBlocks.java:8446) at net.minecraft.client.renderer.RenderBlocks.renderStandardBlockWithAmbientOcclusion(RenderBlocks.java:5248) at net.minecraft.client.renderer.RenderBlocks.renderStandardBlock(RenderBlocks.java:4427) at net.minecraft.client.renderer.RenderBlocks.renderBlockByRenderType(RenderBlocks.java:348) at net.minecraft.client.renderer.WorldRenderer.updateRenderer(WorldRenderer.java:207) at net.minecraft.client.renderer.RenderGlobal.updateRenderers(RenderGlobal.java:1618) at net.minecraft.client.renderer.EntityRenderer.renderWorld(EntityRenderer.java:1263) -- Affected level -- Details: Level name: MpServer All players: 1 total; [EntityClientPlayerMP['XFactHD'/59, l='MpServer', x=273,21, y=64,62, z=402,35]] Chunk stats: MultiplayerChunkCache: 625, 625 Level seed: 0 Level generator: ID 00 - default, ver 1. Features enabled: false Level generator options: Level spawn location: World: (228,64,256), Chunk: (at 4,4,0 in 14,16; contains blocks 224,0,256 to 239,255,271), Region: (0,0; contains chunks 0,0 to 31,31, blocks 0,0,0 to 511,255,511) Level time: 1752917 game time, 6000 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: 1 total; [EntityClientPlayerMP['XFactHD'/59, l='MpServer', x=273,21, y=64,62, z=402,35]] Retry entities: 0 total; [] Server brand: fml,forge Server type: Integrated singleplayer server Stacktrace: at net.minecraft.client.multiplayer.WorldClient.addWorldInfoToCrashReport(WorldClient.java:415) at net.minecraft.client.Minecraft.addGraphicsAndWorldToCrashReport(Minecraft.java:2566) at net.minecraft.client.Minecraft.run(Minecraft.java:991) at net.minecraft.client.main.Main.main(Main.java:164) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) at net.minecraft.launchwrapper.Launch.main(Launch.java:28) at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source) at GradleStart.main(Unknown Source) -- System Details -- Details: Minecraft Version: 1.7.10 Operating System: Windows 7 (amd64) version 6.1 Java Version: 1.8.0_45, Oracle Corporation Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation Memory: 789752344 bytes (753 MB) / 1037959168 bytes (989 MB) up to 1037959168 bytes (989 MB) JVM Flags: 3 total; -Xincgc -Xmx1024M -Xms1024M AABB Pool Size: 0 (0 bytes; 0 MB) allocated, 0 (0 bytes; 0 MB) used IntCache: cache: 0, tcache: 0, allocated: 12, tallocated: 94 FML: MCP v9.05 FML v7.10.99.99 Minecraft Forge 10.13.4.1448 11 mods loaded, 11 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{7.10.99.99} [Forge Mod Loader] (forgeSrc-1.7.10-10.13.4.1448-1.7.10.jar) UCHIJAAAA Forge{10.13.4.1448} [Minecraft Forge] (forgeSrc-1.7.10-10.13.4.1448-1.7.10.jar) UCHIJAAAA CodeChickenCore{1.0.7.46} [CodeChicken Core] (minecraft.jar) UCHIJAAAA NotEnoughItems{1.0.5.111} [Not Enough Items] (NotEnoughItems-1.7.10-1.0.5.111-universal.jar) UCHIJAAAA <CoFH ASM>{000} [CoFH ASM] (minecraft.jar) UCHIJAAAA CoFHCore{1.7.10R3.0.3} [CoFH Core] (CoFHCore-[1.7.10]3.0.3-303-dev.jar) UCHIJAAAA ThermalFoundation{1.7.10R1.2.0} [Thermal Foundation] (ThermalFoundation-[1.7.10]1.2.0-102-dev.jar) UCHIJAAAA ThermalExpansion{1.7.10R4.0.3B1} [Thermal Expansion] (ThermalExpansion-[1.7.10]4.0.3B1-218-dev.jar) UCHIJAAAA thermalreactors{0.0.1.2} [ThermalReactions] (ThermalReactions) UCHIJAAAA ThermalDynamics{1.7.10R1.1.0} [Thermal Dynamics] (ThermalDynamics-[1.7.10]1.1.0-161.jar) GL info: ' Vendor: 'NVIDIA Corporation' Version: '4.5.0 NVIDIA 352.86' Renderer: 'GeForce GTX 760/PCIe/SSE2' CoFHCore: -[1.7.10]3.0.3-303 ThermalFoundation: -[1.7.10]1.2.0-102 ThermalExpansion: -[1.7.10]4.0.3B1-218 ThermalDynamics: -[1.7.10]1.1.0-161 Launched Version: 1.7.10 LWJGL: 2.9.1 OpenGL: GeForce GTX 760/PCIe/SSE2 GL version 4.5.0 NVIDIA 352.86, NVIDIA Corporation GL Caps: Using GL 1.3 multitexturing. Using framebuffer objects because OpenGL 3.0 is supported and separate blending is supported. Anisotropic filtering is supported and maximum anisotropy is 16. Shaders are available because OpenGL 2.1 is supported. Is Modded: Definitely; Client brand changed to 'fml,forge' Type: Client (map_client.txt) Resource Packs: [] Current Language: English (UK) Profiler Position: N/A (disabled) Vec3 Pool Size: 0 (0 bytes; 0 MB) allocated, 0 (0 bytes; 0 MB) used Anisotropic Filtering: Off (1) Quote Link to comment Share on other sites More sharing options...
RANKSHANK Posted February 6, 2016 Share Posted February 6, 2016 int status = ((TileEntityFissionController)te).formed ? (((TileEntityFissionController)te).active ? 3 : 2) : 1; return icons[8] Why allocate it to a variable as opposed to return icons[((TileEntityFissionController)te).formed ? (((TileEntityFissionController)te).active ? 3 : 2) : 1]; And don't run unnecessary switches. case 15: switch (side){ return icons[9][side != 4 ? 0 : (TileEntityFissionPort)te).input ? 1 : 2; ]; break; } Aside from that it's tough reading through the switch web you have there... Do you have a git or anything easier on the eyes? Quote I think its my java of the variables. Link to comment Share on other sites More sharing options...
Guest Posted February 6, 2016 Share Posted February 6, 2016 There is the class on github: https://github.com/DrakoAlcarus/ThermalReactors/blob/master/src/main/java/XFactHD/thermalreactors/common/blocks/machine/fissionReactor/BlockReactorComponent.java I know that the code is not really clean in some spaces but thanks for the hint, my way of thinking isn't always really straightforward. Quote Link to comment Share on other sites More sharing options...
ratismal Posted February 6, 2016 Share Posted February 6, 2016 You're trying to cast a TileEntityFissionController to a TileEntityFissionPort. In order to do this, one must extend the other. I'm guessing that both of those classes extend a more generic class, probably something like TileEntityReactorComponent. Thus, the cast is not going to work. This is because of inheritance. What happens is the Controller inherits everything from Component. The Port inherits everything from Component. The Port and the Controller have no relation to eachother. Casting is not possible. You should check if that tileentity is an instanceof TileEntityReactorComponent or TileEntityReactorPort before entering a switch statement that might try to cast one to the other. Quote Did I help you? Don't be afraid to give that 'thank you' button a good smack for me! It's been looking at me weirdly for a while now. Link to comment Share on other sites More sharing options...
Guest Posted February 6, 2016 Share Posted February 6, 2016 The TileEntityFissionPort class and the TileEntityFissionController extend TileEntityBaseTR, a base class for all my TEs. I know what a class cast exception means, that's not the problem. I am casting the basic TileEntity I get from some coordinates to TileEntityFissionPort when the metadata of the BlockReactorComponent at the same coordinates is 12. In createNewTileEntity I say that a block with metadata 12, 13, 14 or 15 should have that TileEntity. I am not getting why it tries to cast a TileEntityFissionPort to a TileEntityFissionController when there should be a TileEntityFissionPort at that position. Am I trying to get the TileEntity to early because I am changing the metadata in onBlockPlaced based on the player rotation? Quote Link to comment Share on other sites More sharing options...
RANKSHANK Posted February 6, 2016 Share Posted February 6, 2016 I know that the code is not really clean in some spaces but thanks for the hint, my way of thinking isn't always really straightforward. The over switching thing is more of an efficiency thing especially if you're rendering a few of these things, and readabilitywise the code boxes on here only go so far haha. Much easier to read through on git(my code gets to be an eyesore at points) That said could you add a temporary check to make sure it's not a world error @Override public IIcon getIcon(IBlockAccess world, int x, int y, int z, int side) { int meta = world.getBlockMetadata(x, y, z); TileEntity te = world.getTileEntity(x, y, z); if(meta==12) System.out.println(te.getClass() + '@' + x +',' + y + ',' + z ); Sometimes you can change a value and corrupt your test world's save data and it looks like an error on your end Quote I think its my java of the variables. Link to comment Share on other sites More sharing options...
Guest Posted February 6, 2016 Share Posted February 6, 2016 I put that check in there and in my test world as well as in a new world, it tells me that the TileEntity is TileEntityFissionController. Is the TileEntity placed before I change the metadata in onBlockPlacedBy? Also, I changed the switch statements and they like like that now: @Override public IIcon getIcon(IBlockAccess world, int x, int y, int z, int side) { int meta = world.getBlockMetadata(x, y, z); TileEntity te = world.getTileEntity(x, y, z); switch (meta) { case 0: return icons[0][0]; case 1: return (side!=0&&side!=1) ? icons[1][0] : icons[1][side==0 ? 2 : 1]; case 2: return (side==0||side==1) ? icons[2][0] : icons[2][1]; case 3: return (side!=0&&side!=1) ? icons[3][0] : icons[6][side==0 ? 2 : 1]; case 4: return (side!=0&&side!=1) ? icons[4][0] : icons[6][side==0 ? 2 : 1]; case 5: return (side!=0&&side!=1) ? icons[5][0] : icons[6][side==0 ? 2 : 1]; case 6: return (side!=0&&side!=1) ? icons[6][0] : icons[6][side==0 ? 2 : 1]; case 7: return icons[7][0]; case 8: return side != 2 ? icons[8][0] : icons[8][((TileEntityFissionController)te).formed ? (((TileEntityFissionController)te).active ? 3 : 2) : 1]; case 9: return side != 5 ? icons[8][0] : icons[8][((TileEntityFissionController)te).formed ? (((TileEntityFissionController)te).active ? 3 : 2) : 1]; case 10: return side != 3 ? icons[8][0] : icons[8][((TileEntityFissionController)te).formed ? (((TileEntityFissionController)te).active ? 3 : 2) : 1]; case 11: return side != 4 ? icons[8][0] : icons[8][((TileEntityFissionController)te).formed ? (((TileEntityFissionController)te).active ? 3 : 2) : 1]; case 12: return side != 2 ? icons[9][0] : icons[9][((TileEntityFissionPort)te).input ? 1 : 2]; case 13: return side != 5 ? icons[9][0] : icons[9][((TileEntityFissionPort)te).input ? 1 : 2]; case 14: return side != 3 ? icons[9][0] : icons[9][((TileEntityFissionPort)te).input ? 1 : 2]; case 15: return side != 4 ? icons[9][0] : icons[9][((TileEntityFissionPort)te).input ? 1 : 2]; } return super.getIcon(world, x, y, z, side); } Quote Link to comment Share on other sites More sharing options...
ratismal Posted February 6, 2016 Share Posted February 6, 2016 Is the TileEntity placed before I change the metadata in onBlockPlacedBy? Not sure, but there's an easy way to check. Do a console output to see what the meta is. You could also put console outputs in both the onBlockPlacedBy function and the createNewTileEntity functions to see which is called first. Quote Did I help you? Don't be afraid to give that 'thank you' button a good smack for me! It's been looking at me weirdly for a while now. Link to comment Share on other sites More sharing options...
Guest Posted February 6, 2016 Share Posted February 6, 2016 It seems that createNewTileEntity is called every tick which explains the problem. In the log I get several times the output from createNewTileEntity, then the output from setting the meta and after that the spam from createNewTileEntity continues. Quote Link to comment Share on other sites More sharing options...
ratismal Posted February 6, 2016 Share Posted February 6, 2016 This probably isn't the answer you're looking for, but would you consider making a new block for each tileentity? It would prevent mixing up different tileentities types, and also end up with cleaner looking code. I've never actually tried making several blocks from the same class, so I'm not too clear about the benefits of doing so. Quote Did I help you? Don't be afraid to give that 'thank you' button a good smack for me! It's been looking at me weirdly for a while now. Link to comment Share on other sites More sharing options...
coolAlias Posted February 6, 2016 Share Posted February 6, 2016 You can't have multiple TileEntities created for a single Block, and I'm pretty sure you can't register multiple tile entity classes to a single Block class (or rather, doing so wouldn't do what you want, as later registrations override the initial registration). Besides, trying to splice a Block into two different TileEntities based on metadata is ridiculous - whatever conditional functionality you want to achieve can be done in a single TileEntity class, e.g. // any TileEntity method: if (blockMeta < 7) { // perform duty 1 } else { // perform duty 2 } However, if the TileEntity's functionality is really different, you probably should consider making 2 different blocks. Quote http://i.imgur.com/NdrFdld.png[/img] Link to comment Share on other sites More sharing options...
Guest Posted February 6, 2016 Share Posted February 6, 2016 There are only 4096 possible block IDs (this is already extended by forge) so the main benefit is to save block IDs. If I did what you suggested, everybody would yell at me that I am eating up all of their block IDs. I got a solution that works perfect with blocks using the standard block rendering: I switched the facing of the blocks completely over to NBT because all the blocks that need this have a TileEntity nonetheless. Also, no matter what mod you look at (Immersive Engineering, EnderIO, PneumaticCraft), they all use those metadata based sub blocks to save block IDs, so yes, you can attach different TileEntitys to one block with different metadata. If it weren't possible or not intended to be done, why would createNewTileEntity have the block metadata as one parameter? Quote Link to comment Share on other sites More sharing options...
ratismal Posted February 6, 2016 Share Posted February 6, 2016 Also, no matter what mod you look at (Immersive Engineering, EnderIO, PneumaticCraft), they all use those metadata based sub blocks to save block IDs, so yes, you can attach different TileEntitys to one block with different metadata. Not exactly sure where you're coming from here. Here's EnderIO's blocks: EnderIO's Github Here's PneumaticCraft's blocks: PneumaticCraft's Github Out of the three examples you gave, only Immersive Engineering actually has blocks returning multiple TileEntities. It's definitely possible, but it's not a something that is widely practiced. Quote Did I help you? Don't be afraid to give that 'thank you' button a good smack for me! It's been looking at me weirdly for a while now. Link to comment Share on other sites More sharing options...
coolAlias Posted February 6, 2016 Share Posted February 6, 2016 Usually sub-blocks do not include separate tile entities, but things like wool with different colors, or logs, etc. I'm not saying it's impossible as I don't know that to be a fact, but I haven't ever seen it done and it seems like a bad idea, in my opinion. Saving a block ID is not worth the headache and fugly code caused by trying to have more than one TileEntity in a single Block. But anyway, opinions aside, it seems like the client-side version of the TileEntity is the wrong class, at least temporarily, causing your game to crash when it first tries to access the icon. If you did an instanceof check before doing any casting, as others have suggested, you could prevent the crash, allowing you to figure out if things work out after that. E.g. @Override public IIcon getIcon(IBlockAccess world, int x, int y, int z, int side) { int meta = world.getBlockMetadata(x, y, z); TileEntity te = world.getTileEntity(x, y, z); if (meta > 11) { if (!(te instanceof TileEntityFissionPort)) { // log error - incorrect TileEntity for this metadata // return base block icon } // return icons based on meta and TileEntityFissionPort } else if (meta > 7) { // same as above for other TileEntity } else { // non-TE based icons } Quote http://i.imgur.com/NdrFdld.png[/img] Link to comment Share on other sites More sharing options...
Guest Posted February 6, 2016 Share Posted February 6, 2016 Sorry, I was probably a bit to fast and didn't look at the source of EnderIO and PneumaticCraft, I should probably have done that. But nonetheless, I worked around the problem by making the block rotation NBT data based. This also means that I can now add all the blocks for the reactor in one block ID. I have to admit that I am mostly trying to learn from the code from BluSunrize because I think it is very clear and understandable but that again is an opinion. One thing that tells that metadata based subblocks with multiple tileentities should be used more is that I am seeing more and more people coming to github and saying: "Your mod isn't working, I have some kind of crash here" and then the crash report says "invalid block ID". Quote Link to comment Share on other sites More sharing options...
ratismal Posted February 6, 2016 Share Posted February 6, 2016 Glad you got it working! Don't forget to mark the thread "solved". Quote Did I help you? Don't be afraid to give that 'thank you' button a good smack for me! It's been looking at me weirdly for a while now. Link to comment Share on other sites More sharing options...
coolAlias Posted February 6, 2016 Share Posted February 6, 2016 Glad you got it working! Don't forget to mark the thread "solved". What's with so many people saying this lately? "Your mod isn't working, I have some kind of crash here" and then the crash report says "invalid block ID". Keep in mind that the only way you'll ever run out of block IDs is if you have so many mods installed that you have over 4096 blocks... that's a TON of blocks. While there are certainly some mods that could benefit from consolidating some of their blocks into one, this will only buy you a few more blocks before you run out again. There will always be a limit. I don't think the gain is generally worth it in terms of code maintainability when the blocks being consolidated are completely unrelated. I'd much rather have readable code and a few less mods than the other way around, but I often seem to be a minority in such matters Quote http://i.imgur.com/NdrFdld.png[/img] Link to comment Share on other sites More sharing options...
Guest Posted February 9, 2016 Share Posted February 9, 2016 If you have multiple tile entities for one block, you only write so many lines more as you have sub blocks, I don't think that's fugly in that matter. I mean, one tile entity, no matter if it is on a sub block or on a completely independent block, has much more code than the block class with all its sub blocks and the texture getters. Anyway, thank you all for your help. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.