Jump to content

Recommended Posts

Posted

Hi all, i'm currently adding a block that has editable sides. It is very complicated, and ive got it mostly working. Only problem is, is that im using integer values in the TileEntity as values for each side. Clicking on each side with the tool cycles the values, which in turn changes the model texture on that side. Now my problem: When each side is changed, it changes both values for the integer, being the !world.isRemote, and the world.isRemote values, as rendering the block uses the client side, but storing the values is serverside. When reading from NBT it successfully updates the SERVER side value, but not the CLIENT side value. So i need to snyc them somewhere, either in the tile entity, or the block. Im in deep here!

 

The second gui accesses all sides and edits the side textures based on a button press, using packets. FYI

 

TileEntity class:

 

Spoiler

package com.zeher.orecraft.client.tileentity.capacitor;

import com.zeher.orecraft.OreCraftCore;
import com.zeher.orecraft.core.block.capacitor.BlockCapacitorBasic;
import com.zeher.orecraft.core.net.NetUtils;
import com.zeher.orecraft.core.net.packet.PacketCapacitorBasic;
import com.zeher.trzcore.api.TRZBlockPosition;
import com.zeher.trzcore.api.energy.TRZICapacitor;
import com.zeher.trzcore.api.energy.TRZItemEnergyBase;
import com.zeher.trzcore.core.block.TRZBlockEnergyPipe;
import com.zeher.trzcore.core.item.TRZItemBattery;
import com.zeher.trzcore.core.tileentity.TRZTileEntityCapacitor;

import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.inventory.ItemStackHelper;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ITickable;
import net.minecraft.util.NonNullList;
import net.minecraft.world.World;

public class TileEntityCapacitorBasic extends TRZTileEntityCapacitor
        implements ISidedInventory, IInventory, ITickable, TRZICapacitor {

    private String custom_name;
    private NonNullList<ItemStack> capacitorItemStacks = NonNullList.<ItemStack>withSize(8, ItemStack.EMPTY);
    private static final int[] slots_top = { 1 };
    private static final int[] slots_bottom = { 2, 1 };
    private static final int[] slots_sides = { 1 };
    public int _power;
    public int _max_power = 20000000;

    public int energy_recieve;
    public int energy_send;

    public int up;
    public int down;
    public int north;
    public int south;
    public int east;
    public int west;

    public byte[] side_cache = { 0, 0, 0, 0, 0, 0 };

    @Override
    public int getSizeInventory() {
        return this.capacitorItemStacks.size();
    }
    
    public void cycleSide(String side){
        if(side.equals("up")){
            int i = getSide("up");
            i = i+1;
            if(i > 2){
                i= 0;
            }
            up = i;
        }
        if(side.equals("down")){
            int i = getSide("down");
            i = i+1;
            if(i > 2){
                i= 0;
            }
            down = i;
        }
        if(side.equals("east")){
            int i = getSide("east");
            i = i+1;
            if(i > 2){
                i= 0;
            }
            east = i;
        }
        if(side.equals("west")){
            int i = getSide("west");
            i = i+1;
            if(i > 2){
                i= 0;
            }
            west = i;
        }
        if(side.equals("north")){
            int i = getSide("north");
            i = i+1;
            if(i > 2){
                i= 0;
            }
            north = i;
        }
        if(side.equals("south")){
            int i = getSide("south");
            i = i+1;
            if(i > 2){
                i= 0;
            }
            south = i;
        }
        Minecraft.getMinecraft().renderGlobal.markBlockRangeForRenderUpdate(pos.getX(), pos.getY(), pos.getZ(), pos.getX(), pos.getY(), pos.getZ());
        BlockCapacitorBasic block = (BlockCapacitorBasic) world.getBlockState(pos).getBlock();
        if(block instanceof BlockCapacitorBasic){
            block.updateBlock((TileEntityCapacitorBasic) world.getTileEntity(pos), world, pos);
            block.getActualState(world.getBlockState(pos), world, pos);
        }
    }
    
    
    public void setSideNBT(String str, int value) {
        if (str == "up") {
            this.up = value;
        }
        if (str == "down") {
            this.down = value;
        }
        if (str == "north") {
            this.north = value;
        }
        if (str == "south") {
            this.south = value;
        }
        if (str == "east") {
            this.east = value;
        }
        if (str == "west") {
            this.west = value;
        }
    }

    public int getSide(String str) {
        if (str == "up") {
            return this.up;
        }
        if (str == "down") {
            return this.down;
        }
        if (str == "north") {
            return this.north;
        }
        if (str == "south") {
            return this.south;
        }
        if (str == "east") {
            return this.east;
        }
        if (str == "west") {
            return this.west;
        }
        return 0;
    }

    @Override
    public void update() {
        BlockCapacitorBasic blockToUpdate = (BlockCapacitorBasic) world.getBlockState(pos).getBlock();
        //blockToUpdate.updateBlock((TileEntityCapacitorBasic) world.getTileEntity(pos), world, pos);
        
        boolean flag = this._power > 0;
        boolean flag1 = false;
        ItemStack stackInput = capacitorItemStacks.get(1);
        ItemStack stackOutput = capacitorItemStacks.get(0);
        if (!this.world.isRemote) {
            if ((isItemPowerStorage(0)) && !(stackOutput.isEmpty()) && (this._power > 0)) {
                if (stackOutput.getItemDamage() > 0) {
                    stackOutput.setItemDamage(stackOutput.getItemDamage() - 1);
                    this._power -= TRZItemEnergyBase.getItemPower(stackOutput.getItem());
                }
            }
            if ((isItemPower(1))
                    && (this._power <= this._max_power - TRZItemEnergyBase.getItemPower(stackInput.getItem()))) {
                if (!stackInput.isItemStackDamageable()) {
                    this._power += TRZItemEnergyBase.getItemPower(stackInput.getItem());

                    flag1 = true;
                    if (!(stackInput.isEmpty())) {
                        stackInput.setCount(stackInput.getCount() - 1);
                        if (stackInput.isEmpty()) {
                            this.capacitorItemStacks.set(1, stackInput.getItem().getContainerItem(stackInput));
                        }
                    }
                } else if (stackInput.getItemDamage() < stackInput.getMaxDamage()) {
                    this._power += TRZItemEnergyBase.getItemPower(stackInput.getItem());
                    this.capacitorItemStacks.set(1,
                            new ItemStack(stackInput.getItem(), stackInput.getCount(), stackInput.getItemDamage() + 1));
                }
            }
            if (flag1) {
                this.update();
                this.markDirty();
            }
        }

        IBlockState state = world.getBlockState(this.pos);
        Block block = state.getBlock();
        if (block instanceof BlockCapacitorBasic) {
            boolean up = ((BlockCapacitorBasic) block).getSide(EnumFacing.UP, world, this.pos);
            boolean down = ((BlockCapacitorBasic) block).getSide(EnumFacing.DOWN, world, pos);
            boolean east = ((BlockCapacitorBasic) block).getSide(EnumFacing.EAST, world, this.pos);
            boolean west = ((BlockCapacitorBasic) block).getSide(EnumFacing.WEST, world, pos);
            boolean north = ((BlockCapacitorBasic) block).getSide(EnumFacing.NORTH, world, this.pos);
            boolean south = ((BlockCapacitorBasic) block).getSide(EnumFacing.SOUTH, world, pos);

            if (up) {
                TRZBlockPosition bp = new TRZBlockPosition(pos);
                bp.orientation = EnumFacing.UP;
                bp.moveForwards(1);
                Block blockUp = world.getBlockState(bp.pos).getBlock();

                if (this.up == 1) {
                    if (blockUp != null) {
                        capacitorItemStacks.set(2, new ItemStack(blockUp));
                    }
                }
                if (this.up == 1) {
                    capacitorItemStacks.set(2, ItemStack.EMPTY);
                }
                if (this.up == 2) {
                    capacitorItemStacks.set(2, new ItemStack(blockUp));
                }
            } else {
                capacitorItemStacks.set(2, ItemStack.EMPTY);
            }

            if (down) {
                TRZBlockPosition bp = new TRZBlockPosition(pos);
                bp.orientation = EnumFacing.DOWN;
                bp.moveForwards(1);
                Block blockDown = world.getBlockState(bp.pos).getBlock();

                if (this.down == 0) {
                    if (blockDown instanceof TRZBlockEnergyPipe) {
                        capacitorItemStacks.set(3, new ItemStack(blockDown));
                    } else {
                        capacitorItemStacks.set(3, ItemStack.EMPTY);
                    }
                }
                if (this.down == 1) {
                    capacitorItemStacks.set(3, ItemStack.EMPTY);
                }
                if (this.down == 2) {
                    capacitorItemStacks.set(3, new ItemStack(blockDown));
                }
            } else {
                capacitorItemStacks.set(3, ItemStack.EMPTY);
            }

            if (east) {
                TRZBlockPosition bp = new TRZBlockPosition(pos);
                bp.orientation = EnumFacing.EAST;
                bp.moveForwards(1);
                Block blockEast = world.getBlockState(bp.pos).getBlock();

                if (this.east == 0) {
                    if (blockEast instanceof TRZBlockEnergyPipe) {
                        capacitorItemStacks.set(4, new ItemStack(blockEast));
                    } else {
                        capacitorItemStacks.set(4, ItemStack.EMPTY);
                    }
                }
                if (this.east == 1) {
                    capacitorItemStacks.set(4, ItemStack.EMPTY);
                }
                if (this.east == 2) {
                    capacitorItemStacks.set(4, new ItemStack(blockEast));
                }
            } else {
                capacitorItemStacks.set(4, ItemStack.EMPTY);
            }

            if (west) {
                TRZBlockPosition bp = new TRZBlockPosition(pos);
                bp.orientation = EnumFacing.WEST;
                bp.moveForwards(1);
                Block blockWest = world.getBlockState(bp.pos).getBlock();

                if (this.west == 0) {
                    if (blockWest instanceof TRZBlockEnergyPipe) {
                        capacitorItemStacks.set(5, new ItemStack(blockWest));
                    } else {
                        capacitorItemStacks.set(5, ItemStack.EMPTY);
                    }
                }
                if (this.west == 1) {
                    capacitorItemStacks.set(5, ItemStack.EMPTY);
                }
                if (this.west == 2) {
                    capacitorItemStacks.set(5, new ItemStack(blockWest));
                } 
            } else {
                capacitorItemStacks.set(5, ItemStack.EMPTY);
            }

            if (north) {
                TRZBlockPosition bp = new TRZBlockPosition(pos);
                bp.orientation = EnumFacing.NORTH;
                bp.moveForwards(1);
                Block blockNorth = world.getBlockState(bp.pos).getBlock();

                if (this.north == 0) {
                    if (blockNorth instanceof TRZBlockEnergyPipe) {
                        capacitorItemStacks.set(6, new ItemStack(blockNorth));
                    } else {
                        capacitorItemStacks.set(6, ItemStack.EMPTY);
                    }
                }
                if (this.north == 1) {
                    capacitorItemStacks.set(6, ItemStack.EMPTY);
                }
                if (this.north == 2) {
                    capacitorItemStacks.set(6, new ItemStack(blockNorth));
                }
            } else {
                capacitorItemStacks.set(6, ItemStack.EMPTY);
            }

            if (south) {
                TRZBlockPosition bp = new TRZBlockPosition(pos);
                bp.orientation = EnumFacing.SOUTH;
                bp.moveForwards(1);
                Block blockSouth = world.getBlockState(bp.pos).getBlock();

                if (this.south == 0) {
                    if (blockSouth instanceof TRZBlockEnergyPipe) {
                        capacitorItemStacks.set(7, new ItemStack(blockSouth));
                    } else {
                        capacitorItemStacks.set(7, ItemStack.EMPTY);
                    }
                }
                if (this.south == 1) {
                    capacitorItemStacks.set(7, ItemStack.EMPTY);
                }
                if (this.south == 2) {
                    capacitorItemStacks.set(7, new ItemStack(blockSouth));
                } 
            } else {
                capacitorItemStacks.set(7, ItemStack.EMPTY);
            }
        }
    }

    private boolean isItemPowerStorage(int index) {
        if (!(this.capacitorItemStacks.get(index).isEmpty())) {
            return this.capacitorItemStacks.get(index).getItem() instanceof TRZItemBattery;
        }
        return false;
    }

    public int getPowerReaminingScaled(int par1) {
        return this._power * par1 / this._max_power;
    }

    public ItemStack getStackInSlot(int i) {
        return this.capacitorItemStacks.get(i);
    }

    @Override
    public ItemStack decrStackSize(int index, int count) {
        return ItemStackHelper.getAndSplit(this.capacitorItemStacks, index, count);
    }

    @Override
    public ItemStack removeStackFromSlot(int index) {
        return ItemStackHelper.getAndRemove(this.capacitorItemStacks, index);
    }

    public boolean isItemPower(int index) {
        return TRZItemEnergyBase.getItemPower(this.capacitorItemStacks.get(index).getItem()) > 0;
    }

    @Override
    public void setInventorySlotContents(int index, ItemStack stack) {
        ItemStack itemstack = (ItemStack) this.capacitorItemStacks.get(index);
        boolean flag = !stack.isEmpty() && stack.isItemEqual(itemstack)
                && ItemStack.areItemStackTagsEqual(stack, itemstack);
        this.capacitorItemStacks.set(index, stack);
        if (stack.getCount() > this.getInventoryStackLimit()) {
            stack.setCount(this.getInventoryStackLimit());
        }
    }

    public String getName() {
        return this.hasCustomName() ? this.custom_name : "Basic Capacitor";
    }

    public boolean hasCustomName() {
        return (this.custom_name != null) && (this.custom_name.length() > 0);
    }

    public void setGuiDisplayName(String par1Str) {
        this.custom_name = par1Str;
    }

    @Override
    public int getInventoryStackLimit() {
        return 64;
    }

    @Override
    public boolean isUsableByPlayer(EntityPlayer player) {
        return player.getDistanceSq(this.pos) <= 64.0D;
    }

    public void openInventory() {
    }

    public void closeInventory() {
    }

    @Override
    public boolean isItemValidForSlot(int i, ItemStack itemstack) {
        return true;
    }

    public void readFromNBT(NBTTagCompound compound) {
        this.capacitorItemStacks = NonNullList.<ItemStack>withSize(this.getSizeInventory(), ItemStack.EMPTY);
        ItemStackHelper.loadAllItems(compound, this.capacitorItemStacks);
        
        this._power = compound.getInteger("power");
        
        NetUtils.sendCapacitorBasicPacketNBT("up", pos, this, compound.getInteger("upDir"));
        this.setSideNBT("up", compound.getInteger("upDir"));
        System.out.println(compound.getInteger("upDir"));
        //this.up = compound.getInteger("upSide");
        this.down = compound.getInteger("downSide");
        this.east = compound.getInteger("eastSide");
        this.west = compound.getInteger("westSide");
        this.north = compound.getInteger("northSide");
        this.south = compound.getInteger("southSide");
        
        if (compound.hasKey("custom_name", 8)) {
            this.custom_name = compound.getString("custom_name");
        }
        super.readFromNBT(compound);

    }

    public NBTTagCompound writeToNBT(NBTTagCompound compound) {
        compound.setInteger("power", this._power);
        
        compound.setInteger("upDir", up);
        System.out.println(up);
        compound.setInteger("downSide", down);
        compound.setInteger("eastSide", east);
        compound.setInteger("westSide", west);
        compound.setInteger("northSide", north);
        compound.setInteger("southSide", south);
        
        ItemStackHelper.saveAllItems(compound, this.capacitorItemStacks);
        
        if (this.hasCustomName()) {
            compound.setString("custom_name", this.custom_name);
        }
        return super.writeToNBT(compound);
    }

    @Override
    public boolean isEmpty() {
        for (ItemStack itemstack : this.capacitorItemStacks) {
            if (!itemstack.isEmpty()) {
                return false;
            }
        }

        return true;
    }

    @Override
    public void openInventory(EntityPlayer player) {
        // TODO Auto-generated method stub

    }

    @Override
    public void closeInventory(EntityPlayer player) {
        // TODO Auto-generated method stub

    }

    public int getField(int id) {
        switch (id) {
        case 0:
            return this._power;
        default:
            return 0;
        }
    }

    public void setField(int id, int value) {
        switch (id) {
        case 0:
            this._power = value;
            break;
        }
    }

    public int getFieldCount() {
        return 1;
    }

    @Override
    public void clear() {
        // TODO Auto-generated method stub

    }

    @Override
    public int[] getSlotsForFace(EnumFacing side) {
        // TODO Auto-generated method stub
        return side.UP != null ? slots_top : side.DOWN != null ? slots_bottom : slots_sides;
    }

    @Override
    public boolean canInsertItem(int index, ItemStack itemStackIn, EnumFacing direction) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean canExtractItem(int index, ItemStack stack, EnumFacing direction) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean hasPower() {
        return this._power > 0;
    }

    @Override
    public int getPower() {
        return _power;
    }

    @Override
    public int getMaxSend() {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public int getMaxReceive() {
        // TODO Auto-generated method stub
        return 0;
    }

}
 

 

 

Block class:

Spoiler

package com.zeher.orecraft.core.block.capacitor;

import java.util.Random;

import javax.annotation.Nullable;

import com.zeher.orecraft.OreCraftCore;
import com.zeher.orecraft.client.tileentity.capacitor.TileEntityCapacitorAdvanced;
import com.zeher.orecraft.client.tileentity.capacitor.TileEntityCapacitorBasic;
import com.zeher.orecraft.client.tileentity.energypipe.TileEntityEnergyPipeBasic;
import com.zeher.orecraft.core.handlers.BlockHandlerOreCraft;
import com.zeher.orecraft.core.net.NetUtils;
import com.zeher.orecraft.core.net.packet.PacketCapacitorBasic;
import com.zeher.trzcore.api.TRZUtil;
import com.zeher.trzcore.api.energy.TRZPipeConnectBase;
import com.zeher.trzcore.core.block.TRZBlockCapacitor;
import com.zeher.trzcore.core.tileentity.TRZTileEntityEnergyPipe;

import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.properties.PropertyInteger;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Enchantments;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.stats.StatList;
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.IWorldNameable;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.network.internal.FMLNetworkHandler;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;

public class BlockCapacitorBasic extends TRZBlockCapacitor{
    
    private final Random capacitor_random = new Random();
    private boolean keepCapacitorInventory;
    
    public static final PropertyInteger NORTH = PropertyInteger.create("north", 0, 2);
    public static final PropertyInteger EAST = PropertyInteger.create("east", 0, 2);
    public static final PropertyInteger SOUTH = PropertyInteger.create("south", 0, 2);
    public static final PropertyInteger WEST = PropertyInteger.create("west", 0, 2);
    public static final PropertyInteger UP = PropertyInteger.create("up", 0, 2);
    public static final PropertyInteger DOWN = PropertyInteger.create("down", 0, 2);
    
    public int upSide;
    public int downSide;
    public int eastSide;
    public int westSide;
    public int northSide;
    public int southSide;

    public BlockCapacitorBasic(Material material, String name) {
        super(material, name);
        this.setDefaultState(this.blockState.getBaseState().withProperty(NORTH, 0)
                .withProperty(EAST, 0)
                .withProperty(SOUTH, 0)
                .withProperty(WEST, 0)
                .withProperty(UP, 0)
                .withProperty(DOWN, 0));
        setHardness(8);
        setResistance(10);
        
    }
    
    
    @Override
    public Item getItemDropped(IBlockState state, Random rand, int fortune)
    {
        Item item = Item.getItemFromBlock(this);
        ItemStack stack = new ItemStack(this, 1, 1000);
        return stack.getItem();
    }

    @Override
    public boolean isOpaqueCube(IBlockState state){
        return false;
    }
    
    @Override
    public boolean isFullCube(IBlockState state){
        return false;
    }
    
    public EnumBlockRenderType getRenderType(IBlockState state)
    {
        return EnumBlockRenderType.MODEL;
    }
    
    public TileEntity createNewTileEntity(World world, int i){
        return new TileEntityCapacitorBasic();
    }
    
    public void onBlockClicked(World worldIn, BlockPos pos, EntityPlayer playerIn)
    {
        updateBlock((TileEntityCapacitorBasic) worldIn.getTileEntity(pos), worldIn, pos);
        if(!(worldIn.isRemote) && !(playerIn.isSneaking()) && (TRZUtil.isHoldingHammer(playerIn))){
                FMLNetworkHandler.openGui(playerIn, OreCraftCore.instance, 0, worldIn, pos.getX(), pos.getY(), pos.getZ());
                //this.getActualState(worldIn.getBlockState(pos), worldIn, pos);
        }
    }
    
    public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ)
    {
        updateBlock((TileEntityCapacitorBasic) worldIn.getTileEntity(pos), worldIn, pos);
        this.getActualState(state, worldIn, pos);
        if(!(worldIn.isRemote) && !(playerIn.isSneaking()) && !(TRZUtil.isHoldingHammer(playerIn))){
            FMLNetworkHandler.openGui(playerIn, OreCraftCore.instance, 1, worldIn, pos.getX(), pos.getY(), pos.getZ());
        }
        if((TRZUtil.isHoldingHammer(playerIn)) && (playerIn.isSneaking()) && !(worldIn.isRemote)){
            playerIn.swingArm(EnumHand.MAIN_HAND);
                
                TileEntityCapacitorBasic tile = (TileEntityCapacitorBasic)worldIn.getTileEntity(pos);
                int set_power = tile.getPower();
                
                Item item1 = ItemBlock.getItemFromBlock(this);
                ItemStack stack = new ItemStack(item1);
                item1.setDamage(stack, item1.getMaxDamage() - (set_power / 1000));
                
                spawnAsEntity(worldIn, pos, stack);
                
                worldIn.destroyBlock(pos, false);
        }
        TileEntityCapacitorBasic tile = (TileEntityCapacitorBasic) worldIn.getTileEntity(pos);
        if ((TRZUtil.isHoldingHammer(playerIn)) && (!playerIn.isSneaking())) {
            playerIn.swingArm(EnumHand.MAIN_HAND);
            if (side.equals(EnumFacing.UP)) {
                if(worldIn.isRemote){
                    tile.cycleSide("up");
                } else {
                    tile.cycleSide("up");
                }
            }
            if (side.equals(EnumFacing.DOWN)) {
                if(worldIn.isRemote){
                    tile.cycleSide("down");
                } else {
                    tile.cycleSide("down");
                }
            }
            if (side.equals(EnumFacing.NORTH)) {
                if(worldIn.isRemote){
                    tile.cycleSide("north");
                } else {
                    tile.cycleSide("north");
                }
            }
            if (side.equals(EnumFacing.SOUTH)) {
                if(worldIn.isRemote){
                    tile.cycleSide("south");
                } else {
                    tile.cycleSide("south");
                }
            }
            if (side.equals(EnumFacing.EAST)) {
                if(worldIn.isRemote){
                    tile.cycleSide("east");
                } else {
                    tile.cycleSide("east");
                }
            }
            if (side.equals(EnumFacing.WEST)) {
                if(worldIn.isRemote){
                    tile.cycleSide("west");
                } else {
                    tile.cycleSide("west");
                }
            }
        }
        return false;
    }
    
    public void updateBlock(TileEntityCapacitorBasic tile, World world, BlockPos pos){
        if(!world.isRemote){
            if(this.upSide != tile.getSide("up")){
                this.upSide = tile.getSide("up");
            }
            if(downSide != tile.getSide("down")){
                downSide = tile.getSide("down");
            }
            if(eastSide != tile.getSide("east")){
                eastSide = tile.getSide("east");
            }
            if(westSide != tile.getSide("west")){
                westSide = tile.getSide("west");
            }
            if(northSide != tile.getSide("north")){
                northSide = tile.getSide("north");
            }
            if(southSide != tile.getSide("south")){
                southSide = tile.getSide("south");
            }
            //System.out.println(tile.getSide("up") + " " + upSide);
            this.getActualState(this.blockState.getBaseState(), world, pos);
        }
    }
    
    
    protected BlockStateContainer createBlockState()
    {
        return new BlockStateContainer(this, new IProperty[] {NORTH, EAST, WEST, SOUTH, UP, DOWN});
    }
    
    public int getMetaFromState(IBlockState state)
    {
        return 0;
    }
    
    public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos)
    {    
        TileEntityCapacitorBasic tile = (TileEntityCapacitorBasic)worldIn.getTileEntity(pos);
        
        return state.withProperty(NORTH, tile.getSide("north"))
                .withProperty(EAST, tile.getSide("east"))
                .withProperty(SOUTH, tile.getSide("south"))
                .withProperty(WEST, tile.getSide("west"))
                .withProperty(UP, tile.getSide("up"))
                .withProperty(DOWN, tile.getSide("down"));
    }
    
    public boolean getSide(EnumFacing side, World world, BlockPos pos){
        TileEntity tile = world.getTileEntity(pos);
        int northInt = 0;
        int eastInt = 0;
        int southInt = 0;
        int westInt = 0;
        int downInt = 0;
        int upInt = 0;
        if(tile != null && tile instanceof TileEntityCapacitorBasic){
            northInt = ((TileEntityCapacitorBasic) tile).getSide("north");
            eastInt = ((TileEntityCapacitorBasic) tile).getSide("east");
            southInt = ((TileEntityCapacitorBasic) tile).getSide("south");
            westInt = ((TileEntityCapacitorBasic) tile).getSide("west");
            downInt = ((TileEntityCapacitorBasic) tile).getSide("down");
            upInt = ((TileEntityCapacitorBasic) tile).getSide("up");
        } else {
            
        }
        
        boolean upBool = false;
        boolean downBool = false;
        boolean northBool = false;
        boolean southBool = false;
        boolean eastBool = false;
        boolean westBool = false;
        if(side.equals(EnumFacing.UP)){
            if(upInt == 1){
                upBool = false;
            } else if(upInt == 2 || upInt == 0){
                upBool = true;
            }
            return upBool;
        }
        
        if(side.equals(EnumFacing.DOWN)){
            if(downInt == 1){
                downBool = false;
            } else if(downInt == 2 || downInt == 0){
                downBool = true;
            }
            return downBool;
        }
        if(side.equals(EnumFacing.NORTH)){
            if(northInt == 1){
                northBool = false;
            } else if(northInt == 2 || northInt == 0){
                northBool = true;
            }
            return northBool;
        }
        if(side.equals(EnumFacing.SOUTH)){
            if(southInt == 1){
                southBool = false;
            } else if(southInt == 2 || southInt == 0){
                southBool = true;
            }
            return southBool;
        }
        if(side.equals(EnumFacing.EAST)){
            if(eastInt == 1){
                eastBool = false;
            } else if(eastInt == 2 || eastInt == 0){
                eastBool = true;
            }
            return eastBool;
        }
        if(side.equals(EnumFacing.WEST)){
            if(westInt == 1){
                westBool = false;
            } else if(westInt == 2 || westInt == 0){
                westBool = true;
            }
            return westBool;
        }
        return false;
    }
    
    public void breakBlock(World worldIn, BlockPos pos, IBlockState state)
    {
        if (!keepCapacitorInventory)
        {
          TileEntityCapacitorBasic tileentityenergystorage_1 = (TileEntityCapacitorBasic)worldIn.getTileEntity(pos);
          if (tileentityenergystorage_1 != null)
          {
            for (int j1 = 0; j1 < tileentityenergystorage_1.getSizeInventory(); j1++)
            {
              ItemStack itemstack = tileentityenergystorage_1.getStackInSlot(j1);
              if (itemstack != null)
              {
                float f = this.capacitor_random.nextFloat() * 0.8F + 0.1F;
                float f1 = this.capacitor_random.nextFloat() * 0.8F + 0.1F;
                float f2 = this.capacitor_random.nextFloat() * 0.8F + 0.1F;
                while (itemstack.getCount() > 0)
                {
                  int k1 = this.capacitor_random.nextInt(21) + 10;
                  if (k1 > itemstack.getCount()) {
                    k1 = itemstack.getCount();
                  }
                  itemstack.setCount(itemstack.getCount() - k1);
                  EntityItem entityitem = new EntityItem(worldIn, pos.getX() + f, pos.getY() + f1, pos.getZ() + f2, new ItemStack(itemstack.getItem(), k1, itemstack.getItemDamage()));
                  if (itemstack.hasTagCompound()) {
                    entityitem.getEntityItem().setTagCompound((NBTTagCompound)itemstack.getTagCompound().copy());
                  }
                  float f3 = 0.05F;
                  entityitem.posX = ((float)this.capacitor_random.nextGaussian() * f3);
                  entityitem.posY = ((float)this.capacitor_random.nextGaussian() * f3 + 0.2F);
                  entityitem.posZ = ((float)this.capacitor_random.nextGaussian() * f3);
                  worldIn.spawnEntity(entityitem);
                }
              }
            }
          }
        }
        super.breakBlock(worldIn, pos, state);
      }
    
    
    
}

 

Posted

You shouldn't change data of client tileentity, rather than that sync the data from server.

I answered about syncing here.

I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP)

II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.

Posted
36 minutes ago, Zeher_Monkey said:

Minecraft.getMinecraft().renderGlobal.markBlockRangeForRenderUpdate(pos.getX(), pos.getY(), pos.getZ(), pos.getX(), pos.getY(), pos.getZ());

Why is this client-side-only reference in common code?

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted
1 minute ago, Zeher_Monkey said:

The mark render is for updating the texure/model when the side is changed. Without that the texture doesn't change without a block update

 

You should not call the client code directly.

Look at what World#setBlock-blockstate version- calls to update the rendering.

I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP)

II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.

Posted (edited)
3 minutes ago, Abastro said:

You should not call the client code directly.

Look at what World#setBlock-blockstate version- calls to update the rendering.

I'll take a look. I'm busy right now. I've got a basic packet set up, but I can't think of how to use packets to load items/ integers. You don't happen to have an example lying around? I've been at this for hours xD I see the methods you suggested to override in TileEntity

Edited by Zeher_Monkey
Posted
1 minute ago, Zeher_Monkey said:

but I can't think of how to use packets to load items/ integers

You don't, tileentity has a built-in logic for client-server synchronization.

Look at my first reply.

 

Regardless, you need to let game know that your TE is updated - similar case with World#setBlock.

I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP)

II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.

Posted
11 minutes ago, Abastro said:

You don't, tileentity has a built-in logic for client-server synchronization.

Look at my first reply.

 

Regardless, you need to let game know that your TE is updated - similar case with World#setBlock.

Alright, I'll take a look when I can. Cheers for the help :)

 

Posted (edited)
14 hours ago, Abastro said:

You don't, tileentity has a built-in logic for client-server synchronization.

Look at my first reply.

 

Regardless, you need to let game know that your TE is updated - similar case with World#setBlock.

Ive looked at the vanila code, but cant make any sense of it. Im not sure what to actually do in those functions TileEntity:getUpdatePacket/onDataPacket. I should know this :D but its new for me 

 

--EDIT--

Starting to understand...

Edited by Zeher_Monkey
Posted (edited)
14 hours ago, Abastro said:

You don't, tileentity has a built-in logic for client-server synchronization.

Look at my first reply.

 

Regardless, you need to let game know that your TE is updated - similar case with World#setBlock.

So like this? :

Spoiler

@Nullable
    public SPacketUpdateTileEntity getUpdatePacket()
    {
        NBTTagCompound tag = new NBTTagCompound();
        tag.setInteger("upSide", getSide("up"));
        
        return new SPacketUpdateTileEntity(pos, 0, tag);
    }

    public NBTTagCompound getUpdateTag()
    {
        return new NBTTagCompound();
    }
    
    public void onDataPacket(net.minecraft.network.NetworkManager net, net.minecraft.network.play.server.SPacketUpdateTileEntity pkt)
    {
        Havent figured out yet--
    }
    
    public void handleUpdateTag(NBTTagCompound tag)
    {
        this.readFromNBT(tag);
    }

 

And would i keep the original load/write NBT functions?

Edited by Zeher_Monkey
Posted

You shouldn't need to mess with packets. As long as your TE writes and reads NBT consistantly, you should only need to mark the TE after changing its data. The vanilla logic should then handle the rest.

 

If you're curious to learn what "the rest" is, then the best way to see it is in the debugger as it executes rather than by trying to trace static code. It's way more difficult to sort the client versus server paths in static code. It's way easier to see how the paths work when you can actually step through the real thing.

 

Set a couple break points and let the debugger take you on a guided tour.

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.

Posted
56 minutes ago, jeffryfisher said:

You shouldn't need to mess with packets. As long as your TE writes and reads NBT consistantly, you should only need to mark the TE after changing its data. The vanilla logic should then handle the rest.

 

If you're curious to learn what "the rest" is, then the best way to see it is in the debugger as it executes rather than by trying to trace static code. It's way more difficult to sort the client versus server paths in static code. It's way easier to see how the paths work when you can actually step through the real thing.

 

Set a couple break points and let the debugger take you on a guided tour.

MarkDirty()? Ive tried it and it doesnt seem to do anything. Im having a hard time actually using NBT as it doesnt always save the value in the first place. Im not sure if its how im handling the changing of the values, but everywhere the values change, i set both values (Remote and not). I works fine for _power integer, just not the side values. The only reason i ask is because when it does work, it changes the !remote value and not the remote value, so the side doesnt render correcty.

 

Thanks for the reply, ill try the breakpoints and see where it leads me. :) 

Posted
3 hours ago, jeffryfisher said:

You shouldn't need to mess with packets. As long as your TE writes and reads NBT consistantly, you should only need to mark the TE after changing its data. The vanilla logic should then handle the rest.

It won't. Now vanilla logic only syncs basic tileentity data(types and positions). So you need to implement those methods to sync fields, while you don't need to design a custom packet.

 

8 hours ago, Zeher_Monkey said:

So like this? :

  Hide contents

@Nullable
    public SPacketUpdateTileEntity getUpdatePacket()
    {
        NBTTagCompound tag = new NBTTagCompound();
        tag.setInteger("upSide", getSide("up"));
        
        return new SPacketUpdateTileEntity(pos, 0, tag);
    }

    public NBTTagCompound getUpdateTag()
    {
        return new NBTTagCompound();
    }
    
    public void onDataPacket(net.minecraft.network.NetworkManager net, net.minecraft.network.play.server.SPacketUpdateTileEntity pkt)
    {
        Havent figured out yet--
    }
    
    public void handleUpdateTag(NBTTagCompound tag)
    {
        this.readFromNBT(tag);
    }

 

And would i keep the original load/write NBT functions?

You wouldn't need getUpdateTag and handleUpdateTag. (Though I'm not sure)

The packet has a NBTTagCompound contained which can be attained by ::getCompound(). Read the data from the compound.

2 hours ago, Zeher_Monkey said:

Im not sure if its how im handling the changing of the values, but everywhere the values change, i set both values (Remote and not). I works fine for _power integer, just not the side values.

if(!world.isRemote) means you're working on server, while the opposite does on client. You shouldn't change any data values on client if it's not constantly updated one. Also you should always sync the fields from the server when it's needed.

 

Besides, did you look into the setBlock method? It calls a method which is named updateBlock or similar. You need to call it.

I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP)

II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.

Posted
20 hours ago, Abastro said:

Now vanilla logic only syncs basic tileentity data(types and positions).

Yuck... That'll be a joy to fix when I do my next upgrade. I must confess I'm still in 1.10.2. I'll probably play catch-up when 1.12 has a stable Forge release.

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.

Posted

Im updating my mod from 1.7.10 ;D This is an experiment for me, if it world itll be implemented on every machine (hopefully) Im still trying... Im also going to see if i can use TESR instead, as it wouldnt be too much of a chore, (As i already use it for other things). Maybe that will help... Ill try both methods and see which works as intended. Thanks for all the help guys, really appreciate it :) 

Posted (edited)
22 hours ago, Abastro said:

It won't. Now vanilla logic only syncs basic tileentity data(types and positions). So you need to implement those methods to sync fields, while you don't need to design a custom packet.

 

You wouldn't need getUpdateTag and handleUpdateTag. (Though I'm not sure)

The packet has a NBTTagCompound contained which can be attained by ::getCompound(). Read the data from the compound.

if(!world.isRemote) means you're working on server, while the opposite does on client. You shouldn't change any data values on client if it's not constantly updated one. Also you should always sync the fields from the server when it's needed.

 

Besides, did you look into the setBlock method? It calls a method which is named updateBlock or similar. You need to call it.

The only reason i'm changing it on the client, is because of the way i'm rendering the sides. I'm using basic fence code, which uses getActualState() which only runs on Client. Hence the need to sync the values when reentering the world... That's why i plan to see if TESR can help/solve the issue.

 

Also setBlock()? What for... To change the block with updated values? Or will that help sync? I know that is used for furnaces and the like to replace the block with the "active" version. Beyond that i'm not 100% sure. I realize it updates the block, but that's what i use the mark for render update line, its the model/texture that i'm looking to change, that's the only thing that depends on the side values in the TileEntity.

Edited by Zeher_Monkey
Posted (edited)

Same issue with TESR, sets the SERVER value but not the client value... It does grab the correct value on write, but is the read... Read seems to be called twice, one returning the correct value, the other returns 0 everytime.

--EDIT --

1 Im stupid, TESR wouldnt have solved much, all rendering is done on client. Duh

2 Write also seems to be called twice..

 

Spoiler

[00:05:25] [Server thread/INFO] [FML]: Loading dimension 0 (New World) (net.minecraft.server.integrated.IntegratedServer@ee6110f)
[00:05:25] [Server thread/INFO] [FML]: Loading dimension 1 (New World) (net.minecraft.server.integrated.IntegratedServer@ee6110f)
[00:05:25] [Server thread/INFO] [FML]: Loading dimension -1 (New World) (net.minecraft.server.integrated.IntegratedServer@ee6110f)
[00:05:25] [Server thread/INFO]: Preparing start region for level 0
[00:05:25] [Server thread/INFO]: [STDOUT]: READ2
[00:05:25] [Server thread/INFO]: Changing view distance to 13, from 10
[00:05:25] [Netty Local Client IO #2/INFO] [FML]: Server protocol version 2
[00:05:25] [Netty Server IO #5/INFO] [FML]: Client protocol version 2
[00:05:25] [Netty Server IO #5/INFO] [FML]: Client attempting to join with 10 mods : [email protected],nei@${mod_version},[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected]
[00:05:25] [Netty Local Client IO #2/INFO] [FML]: [Netty Local Client IO #2] Client side modded connection established
[00:05:26] [Server thread/INFO] [FML]: [Server thread] Server side modded connection established
[00:05:26] [Server thread/INFO]: Player948[local:E:de8f51c9] logged in with entity id 1079739 at (1216.7819224422944, 4.0, -290.63193636935677)
[00:05:26] [Server thread/INFO]: Player948 joined the game
[00:05:26] [Client thread/INFO]: [STDOUT]: READ0
[00:05:26] [Netty Server IO #5/INFO]: [STDOUT]: Packet Received: Basic Capacitor BlockPos: BlockPos{x=1213, y=4, z=-294}
[00:05:26] [Netty Server IO #5/INFO]: [STDOUT]: TileEntity is not null: Cycle side: up
[00:05:40] [Client thread/INFO]: [CHAT]  - Debug Begin - \nTile name: Basic Capacitor\nPower Level: 0\nUP: 0\nDOWN: 0\nNORTH:0\nSOUTH:0\nEAST:0\nWEST:0
[00:05:40] [Client thread/INFO]: [CHAT]  - Debug Begin - \nTile name: Basic Capacitor\nPower Level: 0\nUP: 0\nDOWN: 0\nNORTH:2\nSOUTH:0\nEAST:0\nWEST:0
[00:06:10] [Server thread/INFO]: [STDOUT]: WRITE2

READ is reading, WRITE is writing (to/from NBT)

Edited by Zeher_Monkey
Posted

Right so im trying out getUpdatePacket() and onDataPacket() and they arent called when the world loads, only when the block changes? Ive called the get update packet on the write to nbt function, but im not sure if thats how to do it? Also where should i be calling the setBlockState()?

Posted

Okay, so a couple of things I would like to explain:

1. Difference between TileEntity::getUpdateTag and TileEntity::getUpdatePacket.

They are build around the same purpose and cause a lot of confusion, but they are slightly different. getUpdateTag is appended to the ChunkData packet(the one player recieves from a server when loading a chunk/chunk data is changed). getUpdatePacket is sent in 2 circumstances: If a BlockState changes and the new one has a TileEntity(world::setBlockState is mostly the cause here) or if the amount of changes in the chunk is greater than 1 and less than 64(so a couple of blocks got thanged). Then the getUpdatePacket is sent for each changed blockstate with tile entity.

So you do need to override both in your tileentity. Override only getUpdatePacket - and the client will not recieve the data when the chunk is loaded or multiple blocks are changed at the same time. Override only getUpdateTag - and the clients will not see the changes upon blockstate changes.

2. Please use breakpoints to debug. They are so much nicer and handy, you have no idea. Writing stuff to output is messy, time-consuming and leads to situations when modmakers forget to remove their println debugging from the final product and the log gets overflown with useless debug information and slows the game down. Just launch any big modpack out there and watch the log. You will quickly see what I mean. A breakpoint is literally 2 clicks of  mouse to set, gives you all the info you need and even more and it will never end up in the final product.

3. getUpdateTag should return all your NBT information you need to sync. A couple of responses above you posted:

On 5/17/2017 at 6:12 PM, Zeher_Monkey said:

public NBTTagCompound getUpdateTag()
    {
        return new NBTTagCompound();
    }

That will not work. It will send an empty packet to the server upon chunk loading and your tileentity will not have any data synced. Even worse, it will completely mess everything as the tileentity will not get loaded at all! See how it is done in the base Tileentity class.

 

If you simply override both of those methods and their handlers (onDataPacket, handleUpdateTag) then your tile will get updated correctly on the client when the respective packet arrives. You still will need custom packets to sync real-time changes though.

  • Like 1
Posted (edited)
43 minutes ago, V0idWa1k3r said:

Okay, so a couple of things I would like to explain:

1. Difference between TileEntity::getUpdateTag and TileEntity::getUpdatePacket.

They are build around the same purpose and cause a lot of confusion, but they are slightly different. getUpdateTag is appended to the ChunkData packet(the one player recieves from a server when loading a chunk/chunk data is changed). getUpdatePacket is sent in 2 circumstances: If a BlockState changes and the new one has a TileEntity(world::setBlockState is mostly the cause here) or if the amount of changes in the chunk is greater than 1 and less than 64(so a couple of blocks got thanged). Then the getUpdatePacket is sent for each changed blockstate with tile entity.

So you do need to override both in your tileentity. Override only getUpdatePacket - and the client will not recieve the data when the chunk is loaded or multiple blocks are changed at the same time. Override only getUpdateTag - and the clients will not see the changes upon blockstate changes.

2. Please use breakpoints to debug. They are so much nicer and handy, you have no idea. Writing stuff to output is messy, time-consuming and leads to situations when modmakers forget to remove their println debugging from the final product and the log gets overflown with useless debug information and slows the game down. Just launch any big modpack out there and watch the log. You will quickly see what I mean. A breakpoint is literally 2 clicks of  mouse to set, gives you all the info you need and even more and it will never end up in the final product.

3. getUpdateTag should return all your NBT information you need to sync. A couple of responses above you posted:

That will not work. It will send an empty packet to the server upon chunk loading and your tileentity will not have any data synced. Even worse, it will completely mess everything as the tileentity will not get loaded at all! See how it is done in the base Tileentity class.

 

If you simply override both of those methods and their handlers (onDataPacket, handleUpdateTag) then your tile will get updated correctly on the client when the respective packet arrives. You still will need custom packets to sync real-time changes though.

Thanks for that reply. I get the idea about breakpoints, but i'g going to be honest here, ive never used them. Probably will look up a tutorial for those... Anyway i have it working! Ive changed that 

Spoiler

public void handleUpdateTag(NBTTagCompound tag)
    {
        this.readFromNBT(tag);
    }
    
    public NBTTagCompound getUpdateTag()
    {
        return writeToNBT(new NBTTagCompound());
    }

 I just copied them from TileEntity.class. Its working brilliantly now, but theres only one problem. It might be the block.setBlockState() i added to onBlockActivated() in the block code, or something else im not sure, but the second gui, which uses packets to change 'both' values, now doesnt update the int. I might try adding setBlockState to the packet in some way, but so far its working great!

Spoiler

public void readFromNBT(NBTTagCompound compound) {
        this.capacitorItemStacks = NonNullList.<ItemStack>withSize(this.getSizeInventory(), ItemStack.EMPTY);
        ItemStackHelper.loadAllItems(compound, this.capacitorItemStacks);
        this._power = compound.getInteger("power");
        
        System.out.println("READ (NBT) - " + compound.getInteger("DirUp") + " " + compound.getInteger("DirDown") + " " + compound.getInteger("DirNorth") + " " + compound.getInteger("DirSouth") + " " + compound.getInteger("DirEast") + " " + compound.getInteger("DirWest"));
        this.up = compound.getInteger("DirUp");
        this.down = compound.getInteger("DirDown");
        this.north = compound.getInteger("DirNorth");
        this.south = compound.getInteger("DirSouth");
        this.east = compound.getInteger("DirEast");
        this.west = compound.getInteger("DirWest");
        
        if (compound.hasKey("custom_name", 8)) {
            this.custom_name = compound.getString("custom_name");
        }
        super.readFromNBT(compound);
    }

    public NBTTagCompound writeToNBT(NBTTagCompound compound) {
        ItemStackHelper.saveAllItems(compound, this.capacitorItemStacks);
        compound.setInteger("power", this._power);
        
        System.out.println("WRITE (NBT)" + up + " " + down + " " + north + " " + south + " " + east + " " + west);
        compound.setInteger("DirUp", this.up);
        compound.setInteger("DirDown", this.down);
        compound.setInteger("DirNorth", this.north);
        compound.setInteger("DirSouth", this.south);
        compound.setInteger("DirEast", this.east);
        compound.setInteger("DirWest", this.west);
        
        if (this.hasCustomName()) {
            compound.setString("custom_name", this.custom_name);
        }
        return super.writeToNBT(compound);
    }
    
    @Nullable
    public SPacketUpdateTileEntity getUpdatePacket()
    {
        NBTTagCompound tag = new NBTTagCompound();
        tag.setInteger("DirUp", this.up);
        tag.setInteger("DirDown", this.down);
        tag.setInteger("DirNorth", this.north);
        tag.setInteger("DirSouth", this.south);
        tag.setInteger("DirEast", this.east);
        tag.setInteger("DirWest", this.west);
        
        System.out.println("Sending Packet - " + getSide("up") + " " + getSide("down") + " " + getSide("north") + " " + getSide("south") + " " + getSide("east") + " " + getSide("west"));
        writeToNBT(tag);
        return new SPacketUpdateTileEntity(pos, 0, tag);
    }

    public void onDataPacket(net.minecraft.network.NetworkManager net, net.minecraft.network.play.server.SPacketUpdateTileEntity pkt)
    {
        NBTTagCompound tag = pkt.getNbtCompound();
        int a = tag.getInteger("DirUp");
        int b = tag.getInteger("DirDown"); 
        int c = tag.getInteger("DirNorth");
        int d = tag.getInteger("DirSouth");
        int e = tag.getInteger("DirEast");
        int f = tag.getInteger("DirWest");
        System.out.println("Packet Received - " + a + " " + b + " " + c + " " + d + " " + e + " " + f);
        //handleUpdateTag(tag);
        this.up = a;
        this.down = b;
        this.north = c; 
        this.south = d;
        this.east = e;
        this.west = f;
    }

Im also calling getUpdatePacket() anywhere the sides are changed, not sure if its nessicary, but its there. Heres my GUI and packet class.

 

GuiCapacitorBasicDirection.java:

 

Spoiler

package com.zeher.orecraft.client.gui.direction.capacitor;

import java.io.IOException;

import org.lwjgl.opengl.GL11;

import com.zeher.orecraft.OreCraftCore;
import com.zeher.orecraft.client.container.capacitor.ContainerCapacitorBasic;
import com.zeher.orecraft.client.container.direction.capacitor.ContainerCapacitorBasicDirection;
import com.zeher.orecraft.client.container.direction.energypipe.ContainerEnergyPipeBasicDirection;
import com.zeher.orecraft.client.tileentity.capacitor.TileEntityCapacitorBasic;
import com.zeher.orecraft.client.tileentity.energypipe.TileEntityEnergyPipeBasic;
import com.zeher.orecraft.core.block.capacitor.BlockCapacitorBasic;
import com.zeher.orecraft.core.net.NetUtils;
import com.zeher.orecraft.core.net.packet.PacketCapacitorBasic;
import com.zeher.trzcore.api.TRZGuiColours;

import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.InventoryEffectRenderer;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;

public class GuiCapacitorBasicDirection extends GuiContainer {

    private GuiButton northBtn;
    private GuiButton southBtn;
    private GuiButton eastBtn;
    private GuiButton westBtn;
    private GuiButton upBtn;
    private GuiButton downBtn;
    
    private String north = "";
    private String south = "";
    private String east = "";
    private String west = "";
    private String up = "";
    private String down = "";
    
    private int screen = 0;
    
    private World world;

    private TileEntityCapacitorBasic tile;
    private static final ResourceLocation texture = new ResourceLocation("orecraft:textures/gui/container/direction/gui_direction.png");

    public GuiCapacitorBasicDirection(InventoryPlayer inventoryPlayer, TileEntityCapacitorBasic tileEntity, World world) {
        super(new ContainerCapacitorBasicDirection(inventoryPlayer, tileEntity));
        this.tile = tileEntity;
        this.world = world;
    }

    @Override
    protected void drawGuiContainerForegroundLayer(int x, int y) {
        int k = (this.width - this.xSize) / 2;
        int l = (this.height - this.ySize) / 2;        
        this.fontRendererObj.drawString("Capacitor Connections", 10, 4, 4210752);
        this.fontRendererObj.drawString("Up", 14, 35, TRZGuiColours.BLACK);
        this.fontRendererObj.drawString("Down", 120, 35, TRZGuiColours.BLACK);
        
        this.fontRendererObj.drawString("East", 9, 65, TRZGuiColours.BLACK);
        this.fontRendererObj.drawString("West", 121, 65, TRZGuiColours.BLACK);
        
        this.fontRendererObj.drawString("North", 6, 95, TRZGuiColours.BLACK);
        this.fontRendererObj.drawString("South", 118, 95, TRZGuiColours.BLACK);
        
        this.buttonList.clear();
        this.upBtn = this.addButton(new GuiButton(0, k + 32, l + 14, 40, 20, up));
        this.downBtn = this.addButton(new GuiButton(0, k + 78, l + 14, 40, 20, down));
        
        this.eastBtn = this.addButton(new GuiButton(0, k + 32, l + 44, 40, 20, east));
        this.westBtn = this.addButton(new GuiButton(0, k + 78, l + 44, 40, 20, west));
        
        this.northBtn = this.addButton(new GuiButton(0, k + 32, l + 74, 40, 20, north));
        this.southBtn = this.addButton(new GuiButton(0, k + 78, l + 74, 40, 20, south));
        
        updateSides();
    }
    
    protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3) {
        if(screen == 0){
            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
            this.mc.getTextureManager().bindTexture(texture);
            int k = (this.width - this.xSize) / 2;
            int l = (this.height - this.ySize) / 2;
            drawTexturedModalRect(k, l, 0, 0, this.xSize, this.ySize);
        } else {
            
        }
    }
    
    protected void actionPerformed(GuiButton button)
    {
        if(button == upBtn){
            NetUtils.sendCapacitorBasicPacket("up", tile.getPos(), tile);
        }
        
        if(button == downBtn){
            NetUtils.sendCapacitorBasicPacket("down", tile.getPos(), tile);
        }
        
        if(button == eastBtn){
            NetUtils.sendCapacitorBasicPacket("east", tile.getPos(), tile);
        }
        
        if(button == westBtn){
            NetUtils.sendCapacitorBasicPacket("west", tile.getPos(), tile);
        }
        
        if(button == northBtn){
            NetUtils.sendCapacitorBasicPacket("north", tile.getPos(), tile);
        }
        
        if(button == southBtn){
            NetUtils.sendCapacitorBasicPacket("south", tile.getPos(), tile);
        }
    }
    
    public void updateSides(){
        if((tile.getSide("up") == 0) && !(tile.getSide("up") == 1) && !(tile.getSide("up") == 2)){
            up = "Input";
            this.upBtn.packedFGColour = TRZGuiColours.CYAN;
        }
        if((tile.getSide("up") == 1) && !(tile.getSide("up") == 2) && !(tile.getSide("up") == 0)){
            up = "None";
            this.upBtn.packedFGColour = TRZGuiColours.RED;
        }
        if((tile.getSide("up") == 2) && !(tile.getSide("up") == 1) && !(tile.getSide("up") == 0)){
            up = "Output";
            this.upBtn.packedFGColour = TRZGuiColours.GREEN;
        }
        
        if((tile.getSide("down") == 0) && !(tile.getSide("down") == 1) && !(tile.getSide("down") == 2)){
            down = "Input";
            this.downBtn.packedFGColour = TRZGuiColours.CYAN;
        }
        if((tile.getSide("down") == 1) && !(tile.getSide("down") == 2) && !(tile.getSide("down") == 0)){
            down = "None";
            this.downBtn.packedFGColour = TRZGuiColours.RED;
        }
        if((tile.getSide("down") == 2) && !(tile.getSide("down") == 1) && !(tile.getSide("down") == 0)){
            down = "Output";
            this.downBtn.packedFGColour = TRZGuiColours.GREEN;
        }
        
        if((tile.getSide("east") == 0) && !(tile.getSide("east") == 1) && !(tile.getSide("east") == 2)){
            east = "Input";
            this.eastBtn.packedFGColour = TRZGuiColours.CYAN;
        }
        if((tile.getSide("east") == 1) && !(tile.getSide("east") == 2) && !(tile.getSide("east") == 0)){
            east = "None";
            this.eastBtn.packedFGColour = TRZGuiColours.RED;
        }
        if((tile.getSide("east") == 2) && !(tile.getSide("east") == 1) && !(tile.getSide("east") == 0)){
            east = "Output";
            this.eastBtn.packedFGColour = TRZGuiColours.GREEN;
        }
        
        if((tile.getSide("west") == 0) && !(tile.getSide("west") == 1) && !(tile.getSide("west") == 2)){
            west = "Input";
            this.westBtn.packedFGColour = TRZGuiColours.CYAN;
        }
        if((tile.getSide("west") == 1) && !(tile.getSide("west") == 2) && !(tile.getSide("west") == 0)){
            west = "None";
            this.westBtn.packedFGColour = TRZGuiColours.RED;
        }
        if((tile.getSide("west") == 2) && !(tile.getSide("west") == 1) && !(tile.getSide("west") == 0)){
            west = "Output";
            this.westBtn.packedFGColour = TRZGuiColours.GREEN;
        }
        
        if((tile.getSide("north") == 0) && !(tile.getSide("north") == 1) && !(tile.getSide("north") == 2)){
            north = "Input";
            this.northBtn.packedFGColour = TRZGuiColours.CYAN;
        }
        if((tile.getSide("north") == 1) && !(tile.getSide("north") == 2) && !(tile.getSide("north") == 0)){
            north = "None";
            this.northBtn.packedFGColour = TRZGuiColours.RED;
        }
        if((tile.getSide("north") == 2) && !(tile.getSide("north") == 1) && !(tile.getSide("north") == 0)){
            north = "Output";
            this.northBtn.packedFGColour = TRZGuiColours.GREEN;
        }
        
        if((tile.getSide("south") == 0) && !(tile.getSide("south") == 1) && !(tile.getSide("south") == 2)){
            south = "Input";
            this.southBtn.packedFGColour = TRZGuiColours.CYAN;
        }
        if((tile.getSide("south") == 1) && !(tile.getSide("south") == 2) && !(tile.getSide("south") == 0)){
            south = "None";
            this.southBtn.packedFGColour = TRZGuiColours.RED;
        }
        if((tile.getSide("south") == 2) && !(tile.getSide("south") == 1) && !(tile.getSide("south") == 0)){
            south = "Output";
            this.southBtn.packedFGColour = TRZGuiColours.GREEN;
        }
    }
    
}
 

 

PacketCapacitorBasic.java:

Spoiler

package com.zeher.orecraft.core.net.packet;

import com.zeher.orecraft.client.tileentity.capacitor.TileEntityCapacitorBasic;

import io.netty.buffer.ByteBuf;
import net.minecraft.util.IThreadListener;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.WorldServer;
import net.minecraftforge.fml.common.network.ByteBufUtils;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;

public class PacketCapacitorBasic implements IMessage {
    
    private static String side;
    private static BlockPos pos;
    private static boolean cycle;
    private static int value;
    
    public PacketCapacitorBasic(){
        
    }
    
    public PacketCapacitorBasic(String side, BlockPos pos){
        this.side = side;
        this.pos = pos;
        cycle = true;
    }
    
    public PacketCapacitorBasic(String side, BlockPos pos, boolean cycle, int value){
        this.side = side;
        this.pos = pos;
        this.cycle = cycle;
        this.value = value;
    }
    
    @Override
    public void fromBytes(ByteBuf buf) {
        side = ByteBufUtils.readUTF8String(buf);
    }

    @Override
    public void toBytes(ByteBuf buf) {
        ByteBufUtils.writeUTF8String(buf, side);
    }
    
    public static class Handler implements IMessageHandler<PacketCapacitorBasic, IMessage> {

        @SuppressWarnings("unused")
        @Override
        public IMessage onMessage(final PacketCapacitorBasic message, final MessageContext ctx) {
            TileEntityCapacitorBasic tileEntity = (TileEntityCapacitorBasic)ctx.getServerHandler().playerEntity.world.getTileEntity(pos);
            System.out.println("Packet Received: " + tileEntity.getName() + " BlockPos: " + pos);
            if(tileEntity != null){
                System.out.println("TileEntity is not null: " + "Cycle side: " + side);
                if(cycle){
                    tileEntity.cycleSide(side);
                    tileEntity.getUpdatePacket();
                } else {
                    tileEntity.setSideNBT(side, value);
                }
            } 
            if(tileEntity == null){
            System.out.println("TileEntity is NULL!. Report to mod author!");
            }
            return null;
        }
    
    }

}
 

Called from NetUtils.java :

package com.zeher.orecraft.core.net;

import com.zeher.orecraft.OreCraftCore;
import com.zeher.orecraft.client.tileentity.capacitor.*;
import com.zeher.orecraft.core.net.packet.*;

import net.minecraft.util.math.BlockPos;

public class NetUtils {

    public static void sendCapacitorBasicPacket(String side, BlockPos pos, TileEntityCapacitorBasic tile){
        OreCraftCore.network.sendToServer(new PacketCapacitorBasic(side, pos));
        tile.cycleSide(side);
        tile.getUpdatePacket();
    }
}
 

 

But thanks to your help im 90% of the way. Which i cant thank you enough for :)  :D 

 

EDIT -

Ive added this line to the packet code:

ctx.getServerHandler().playerEntity.world.setBlockState(pos, ctx.getServerHandler().playerEntity.world.getBlockState(pos));

 

Which hasnt worked -_-

 

EDIT 2

Its all working!!!!! Chopped some of the code and it works perfectly. Again i cant thank you all enough for your help! One silly coder to another, cheers. :D

 

Edited by Zeher_Monkey
Posted
18 minutes ago, Zeher_Monkey said:

tile.getUpdatePacket();

FYI: you do not need to do that. That method only creates the packet, it does not actually send it or do anything with it. So your NetUtils and MessageHandler simply create a new packet object and immidiately discard it as you are not doing anyhing with it.

Also your getUpdatePacket implementation in your tile does a lot of redundant work. It sets the values of the sides and then calls writeToNBT which

does the same. Well, at least it is doing that in the code you have posted, but you might have changed it already.

Posted (edited)

Yeah... Ive just discovered that writeToNBT isnt always called. A block update by placing and destroying a block next to it will force write to nbt, is there a way i can do that when a side is set?

 

Also what ive got now actually works in most instances, so i dont want to change too much in case it breaks again :D 

 

Ive tried these :

worldIn.setBlockState(pos, state);
worldIn.notifyBlockUpdate(pos, state, state, 3);

With no luck
        

Edited by Zeher_Monkey
Posted (edited)

Well, if something changes as the block nearby gets updated it does not mean that there is an issue with writeToNBT, it means that if you are using extended block state to render changes made to the block you need to call World::markBlockRangeForRenderUpdate to re-render it in the world in your packet as it is handled on the client

Edited by V0idWa1k3r
Misunderstood the question a bit
Posted

I hate asking so many questions but what would i call in that packet? When a side is changed to update the block using notifyBlockUpdate(), or call it when the player hits ESC, to call the writeToNbt Directly? Short of spawning a block next to is and destroying it i cant think of what to do to get that to happen.

Posted

I have misunderstood your initial question a bit. I have edited my reply to adress that:

8 minutes ago, V0idWa1k3r said:

Well, if something changes as the block nearby gets updated it does not mean that there is an issue with writeToNBT, it means that if you are using extended block state to render changes made to the block you need to call World::markBlockRangeForRenderUpdate to re-render it in the world in your packet as it is handled on the client

 

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



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • It is a rendering issue with embeddium/oculus
    • So, I have a minecraft world hosted with essential on forge 1.20.1, there's 149 mods, and the forge version is 47.3.0, and it's been like that for a good 2-3 weeks, and all of a sudden, it stopped loading, and I have 0 clue as to why, and this world means A LOT to me, so if anyone out there is able to help, I would GLADLY appreciate it. here's the link if ya wanna help:   [04Dec2024 22:42:24.552] [Worker-ResourceReload-3/ERROR][net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener/]: Couldn't parse data file slabsexpanded:snow_blockblocktoslab from slabsexpanded:recipes/snow_blockblocktoslab.json com.google.gson.JsonParseException: com.google.gson.stream.MalformedJsonException: Expected name at line 16 column 4 path $.result.item at net.minecraft.util.GsonHelper.m_13780_(GsonHelper.java:526) ~[client-1.20.1-20230612.114412-srg.jar%23490!/:?] at net.minecraft.util.GsonHelper.m_263475_(GsonHelper.java:531) ~[client-1.20.1-20230612.114412-srg.jar%23490!/:?] at net.minecraft.util.GsonHelper.m_13776_(GsonHelper.java:581) ~[client-1.20.1-20230612.114412-srg.jar%23490!/:?] at net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener.m_278771_(SimpleJsonResourceReloadListener.java:41) ~[client-1.20.1-20230612.114412-srg.jar%23490!/:?] at net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener.m_5944_(SimpleJsonResourceReloadListener.java:29) ~[client-1.20.1-20230612.114412-srg.jar%23490!/:?] at net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener.m_5944_(SimpleJsonResourceReloadListener.java:17) ~[client-1.20.1-20230612.114412-srg.jar%23490!/:?] at net.minecraft.server.packs.resources.SimplePreparableReloadListener.m_10786_(SimplePreparableReloadListener.java:11) ~[client-1.20.1-20230612.114412-srg.jar%23490!/:?] at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1768) ~[?:?] at java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1760) ~[?:?] at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373) ~[?:?] at java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182) ~[?:?] at java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655) ~[?:?] at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622) ~[?:?] at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165) ~[?:?] Caused by: com.google.gson.stream.MalformedJsonException: Expected name at line 16 column 4 path $.result.item at com.google.gson.stream.JsonReader.syntaxError(JsonReader.java:1657) ~[gson-2.10.jar%23107!/:?] at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:514) ~[gson-2.10.jar%23107!/:?] at com.google.gson.stream.JsonReader.hasNext(JsonReader.java:422) ~[gson-2.10.jar%23107!/:?] at com.google.gson.internal.bind.TypeAdapters$28.read(TypeAdapters.java:779) ~[gson-2.10.jar%23107!/:?] at com.google.gson.internal.bind.TypeAdapters$28.read(TypeAdapters.java:725) ~[gson-2.10.jar%23107!/:?] at com.google.gson.internal.bind.TypeAdapters$34$1.read(TypeAdapters.java:1007) ~[gson-2.10.jar%23107!/:?] at net.minecraft.util.GsonHelper.m_13780_(GsonHelper.java:524) ~[client-1.20.1-20230612.114412-srg.jar%23490!/:?]
    • Hello! I have been having a problem with Forgematica, Embeddium, Oculus, and create. I wanted to download litematica so I could see which blocks are in my creative mode build, so that I could collect them all in survival. However, litematica is a fabric mod. I found a port called forgematica, which I added (along with it's dependency) to my mods folder. I loaded into a new world, and built a structure. Then, I added a part from the create mod, and the game crashed instantly, with exit code -1. Thanks for any help! Crash Report and mods list: https://pastebin.com/rtzh6LAi
  • Topics

×
×
  • Create New...

Important Information

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