Jump to content

Recommended Posts

Posted

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:

sGOot.jpg

 

Unfortunately, if I reload the world, the blocks will look like this:

sGOq4.jpg

 

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.

Posted

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.

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.