Jump to content

[Solved] ClassCastException when rendering block


XFactHD

Recommended Posts

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)

Link to comment
Share on other sites

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?

I think its my java of the variables.

Link to comment
Share on other sites

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.

OGaaTMI.png

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.

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

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?

Link to comment
Share on other sites

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

I think its my java of the variables.

Link to comment
Share on other sites

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);
    }

Link to comment
Share on other sites

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.

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

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.

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

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.

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.

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

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
  }

Link to comment
Share on other sites

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".

Link to comment
Share on other sites

Glad you got it working! Don't forget to mark the thread "solved".

What's with so many people saying this lately? O.o

 

"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 :P

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.