Posted December 7, 20168 yr Hello! I'm decently new to Minecraft modding though I'm pretty experienced in programming itself, and I've been working my first mod quite a while. I first started seven months ago, and it took me about two weeks to get everything working as I wanted, and I left off working on a 'network' for handling the Tesla capability stuff. This was for MC version 1.9-12.16.1.1887. Now, seven months later, I've picked it back up and have been working with MC version 1.10.2-12.18.2.2179. Most of my changes have been swapping over the model/block registering things and getting my block to appear in-game, but now I'm working on make a 'wire' block that will 'connect' to nearby Tesla-capable blocks. Currently, on a fresh run, I am able to place the blocks and they will successfully 'connect' by modifying the blocks' blockstates like so: Unfortunately, if I reload the world, the blocks will look like this: In my old 1.9 code, everything worked properly and going over to 1.10.2 I did not see any deprecation or errors when I copy-pasted the block and tile code, except for a few Tesla-related things. I currently have the old 1.9 code still on github here: https://github.com/PocketMilk/wipmod/tree/master/src/main/java/com/pocketmilk/techmod The relevant classes for my 1.10.2 version, having been changed quite a bit since I've been attempting to see what's wrong but are mostly the same, are these: BlockWireLow.java package com.pocketmilk.teslatech.blocks; import com.pocketmilk.teslatech.TeslaTech; import com.pocketmilk.teslatech.ref.ModRef; //import com.pocketmilk.techmod.entities.TileBattery; //import com.pocketmilk.techmod.entities.TileGenerator; import com.pocketmilk.teslatech.tiles.TileWireLow; import net.darkhax.tesla.capability.TeslaCapabilities; import net.minecraft.block.BlockContainer; import net.minecraft.block.material.Material; import net.minecraft.block.properties.IProperty; import net.minecraft.block.properties.PropertyBool; import net.minecraft.block.state.BlockStateContainer; import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumBlockRenderType; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraftforge.common.util.FakePlayer; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; public class BlockWireLow extends BlockContainer { public static final PropertyBool NORTH = PropertyBool.create("north"); public static final PropertyBool SOUTH = PropertyBool.create("south"); public static final PropertyBool EAST = PropertyBool.create("east"); public static final PropertyBool WEST = PropertyBool.create("west"); public static final PropertyBool UP = PropertyBool.create("up"); public static final PropertyBool DOWN = PropertyBool.create("down"); public BlockWireLow() { super(Material.IRON); this.setCreativeTab(TeslaTech.teslaTab); this.setRegistryName("blockwirelow"); this.setUnlocalizedName(this.getRegistryName().toString()); this.setDefaultState(this.blockState.getBaseState() .withProperty(NORTH, false) .withProperty(SOUTH, false) .withProperty(EAST, false) .withProperty(WEST, false) .withProperty(UP, false) .withProperty(DOWN, false)); } public void preInit() { this.addRecipe(); } @Override protected BlockStateContainer createBlockState() { return new BlockStateContainer(this, new IProperty[] { NORTH, SOUTH, EAST, WEST, UP, DOWN}); } @Override public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos) { TileWireLow thisTile = (TileWireLow) worldIn.getTileEntity(pos); return this.getDefaultState() .withProperty(NORTH, thisTile.connectedNorth) .withProperty(SOUTH, thisTile.connectedSouth) .withProperty(EAST, thisTile.connectedEast) .withProperty(WEST, thisTile.connectedWest) .withProperty(UP, thisTile.connectedUp) .withProperty(DOWN, thisTile.connectedDown); } @Override public boolean isOpaqueCube(IBlockState state) { return false; } @Override public boolean isFullCube(IBlockState state) { return false; } @Override public boolean isPassable(IBlockAccess worldIn, BlockPos pos) { return false; } @Override public int getMetaFromState(IBlockState state) { return 0; } @SideOnly(Side.CLIENT) public boolean shouldSideBeRendered(IBlockState blockState, IBlockAccess blockAccess, BlockPos pos, EnumFacing side) { return true; } @Override public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) { if (!world.isRemote) { if (!(player instanceof FakePlayer)) { TileEntity tileentity = world.getTileEntity(pos); if (tileentity instanceof TileWireLow) { TileWireLow tWire = (TileWireLow)tileentity; System.out.println("Blockstate at " + pos + "; Up: " + state.getValue(UP) + " and Down: " + state.getValue(DOWN)); System.out.println("Tile state at " + pos + "; Up: " + tWire.connectedUp + " and Down: " + tWire.connectedDown); System.out.println("Power in wire: " + tWire.getCapability(TeslaCapabilities.CAPABILITY_HOLDER, side).getStoredPower()); } //FMLNetworkHandler.openGui(player, TechMod.instance, SimpleGuiHandler.batteryID, world, pos.getX(), pos.getY(), pos.getZ()); } } return true; } public void addRecipe() { } // When this block is placed in the world, it will create an instance of the Generator tile entity on the same position. public TileEntity createNewTileEntity(World world, int var2) { return new TileWireLow(); } @Override public EnumBlockRenderType getRenderType (IBlockState state) { return EnumBlockRenderType.MODEL; } } TileWireLow.java package com.pocketmilk.teslatech.tiles; import java.util.Iterator; import java.util.List; import com.pocketmilk.teslatech.TeslaTech; import com.pocketmilk.teslatech.blocks.BlockWireLow; import net.darkhax.tesla.api.implementation.BaseTeslaContainer; import net.darkhax.tesla.capability.TeslaCapabilities; import net.darkhax.tesla.lib.TeslaUtils; import net.minecraft.block.state.IBlockState; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.NetworkManager; import net.minecraft.network.play.server.SPacketUpdateTileEntity; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.ITickable; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; public class TileWireLow extends TileEntity implements ITickable { private BaseTeslaContainer container; public boolean connectedNorth = false; public boolean connectedSouth = false; public boolean connectedEast = false; public boolean connectedWest = false; public boolean connectedUp = false; public boolean connectedDown = false; private boolean hasChanged = false; public TileWireLow() { super(); this.container = new BaseTeslaContainer(); } @Override public void readFromNBT(NBTTagCompound compound) { super.readFromNBT(compound); if (compound.hasKey("connectedNorth")) this.connectedNorth = compound.getBoolean("connectedNorth"); if (compound.hasKey("connectedSouth")) this.connectedSouth = compound.getBoolean("connectedSouth"); if (compound.hasKey("connectedEast")) this.connectedEast = compound.getBoolean("connectedEast"); if (compound.hasKey("connectedWest")) this.connectedWest = compound.getBoolean("connectedWest"); if (compound.hasKey("connectedUp")) this.connectedUp = compound.getBoolean("connectedUp"); if (compound.hasKey("connectedDown")) this.connectedDown = compound.getBoolean("connectedDown"); this.container = new BaseTeslaContainer(compound.getCompoundTag("TeslaContainer")); } @Override public NBTTagCompound writeToNBT (NBTTagCompound compound) { super.writeToNBT(compound); compound.setBoolean("connectedNorth", this.connectedNorth); compound.setBoolean("connectedSouth", this.connectedSouth); compound.setBoolean("connectedEast", this.connectedEast); compound.setBoolean("connectedWest", this.connectedWest); compound.setBoolean("connectedUp", this.connectedUp); compound.setBoolean("connectedDown", this.connectedDown); compound.setTag("TeslaContainer", this.container.serializeNBT()); return compound; } @Override @SuppressWarnings("unchecked") public <T> T getCapability (Capability<T> capability, EnumFacing facing) { if (capability == TeslaCapabilities.CAPABILITY_HOLDER || capability == TeslaCapabilities.CAPABILITY_PRODUCER || capability == TeslaCapabilities.CAPABILITY_CONSUMER) return (T) this.container; return super.getCapability(capability, facing); } @Override public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newState) { if (oldState.getBlock() != newState.getBlock()) { return true; } return false; } @Override public boolean hasCapability (Capability<?> capability, EnumFacing facing) { if (capability == TeslaCapabilities.CAPABILITY_CONSUMER || capability == TeslaCapabilities.CAPABILITY_PRODUCER || capability == TeslaCapabilities.CAPABILITY_HOLDER) return true; return super.hasCapability(capability, facing); } @Override public void update () { if (!this.worldObj.isRemote) { this.container.givePower(1, false); boolean tmpconnectedNorth = false; boolean tmpconnectedSouth = false; boolean tmpconnectedEast = false; boolean tmpconnectedWest = false; boolean tmpconnectedUp = false; boolean tmpconnectedDown = false; for (final EnumFacing facing : EnumFacing.values()) { final TileEntity tile = worldObj.getTileEntity(pos.offset(facing)); if (tile != null && !tile.isInvalid() && tile.hasCapability(TeslaCapabilities.CAPABILITY_HOLDER, facing)) { switch(facing) { case NORTH: tmpconnectedNorth = true; break; case SOUTH: tmpconnectedSouth = true; break; case EAST: tmpconnectedEast = true; break; case WEST: tmpconnectedWest = true; break; case UP: tmpconnectedUp = true; break; case DOWN: tmpconnectedDown = true; break; } } } if(tmpconnectedNorth != this.connectedNorth || tmpconnectedSouth != this.connectedSouth || tmpconnectedEast != this.connectedEast || tmpconnectedWest != this.connectedWest || tmpconnectedUp != this.connectedUp || tmpconnectedDown != this.connectedDown) { this.hasChanged = true; this.connectedNorth = tmpconnectedNorth; this.connectedSouth = tmpconnectedSouth; this.connectedEast = tmpconnectedEast; this.connectedWest = tmpconnectedWest; this.connectedUp = tmpconnectedUp; this.connectedDown = tmpconnectedDown; } if(this.hasChanged) this.updateState(); //this.distributePower(); } } /*public void distributePower() { int sidesConnected = 0; long powerSent = 0; if(this.connectedNorth) sidesConnected += 1; if(this.connectedSouth) sidesConnected += 1; if(this.connectedEast) sidesConnected += 1; if(this.connectedWest) sidesConnected += 1; if(this.connectedUp) sidesConnected += 1; if(this.connectedDown) sidesConnected += 1; for (final EnumFacing facing : EnumFacing.values()) { final TileEntity tile = worldObj.getTileEntity(pos.offset(facing)); if(tile instanceof TileWireLow) sidesConnected -= 1; } if (this.container.getStoredPower() > 0) { //System.out.println(sidesConnected); long powerToSend = 0; if(sidesConnected == 0) powerToSend = this.getOutputRate(); else powerToSend = (this.getOutputRate()/sidesConnected); powerSent = TeslaUtils.distributePowerEqually(worldObj, pos, powerToSend, false); System.out.println(powerSent); this.setPower(this.getPower() - powerSent); } }*/ public void updateState() { IBlockState BlockStateContainer = worldObj.getBlockState(pos); if (BlockStateContainer.getBlock() instanceof BlockWireLow) { IBlockState state = worldObj.getBlockState(pos) .withProperty(BlockWireLow.NORTH, this.connectedNorth) .withProperty(BlockWireLow.SOUTH, this.connectedSouth) .withProperty(BlockWireLow.EAST, this.connectedEast) .withProperty(BlockWireLow.WEST, this.connectedWest) .withProperty(BlockWireLow.UP, this.connectedUp) .withProperty(BlockWireLow.DOWN, this.connectedDown); worldObj.setBlockState(pos, state); } this.hasChanged = false; } @Override public SPacketUpdateTileEntity getUpdatePacket() { NBTTagCompound nbttagcompound = new NBTTagCompound(); this.writeToNBT(nbttagcompound); return new SPacketUpdateTileEntity(this.getPos(), 1, nbttagcompound); } @Override public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt) { readFromNBT(pkt.getNbtCompound()); } } From a bit of testing, the first time the block's 'getActualState' is called, the tile's 'connected' booleans are all false, however once I have control in-game and right click on the blocks, their blockState and tile values are correct even though the block's appearance hasn't changed. Breaking a block, or placing a new wire next to the existing non-connected block makes them update their appearance correctly, but only to neighboring ones. The Tesla-related power container seems to be working correctly however, and it correctly saves across game reloads. I feel like I removed or haven't added something really simply, but I can't quite figure it out.
December 7, 20168 yr Firstly, you don't need a TileEntity to do connections. Look at how fences and walls work. The block can have its own boolean method for isConnected (World, BlockPos, Facing). Since connections are all calculable from looking at neighbors, none of those states need to be saved. If your TE wasn't used for something else, then you wouldn't need it at all. Secondly, if/when you ever really need a TE to save data, make sure that the write to NBT is being called. This may require a mark-dirty somewhere. A subtle change between 1.9 and 1.10 may have stopped MC from doing it for you. But, as I said above, you shouldn't need a TE to determine these connection states anyway. You might need it to "distribute power", but the block can determine its own state to support its own rendering. The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.
December 7, 20168 yr Author Thank you for the reply! I'll give your suggestions a go and see what I can get working today.
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.