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.