Синхронизация переменной в тайле и GUI

Версия Minecraft
1.7.10
12
0
Я, создавая механизмы для своего мода, столкнулся с проблемой корявого отображения количества энергии (записывается в NBT тайла) в клиентском GUI (GUI, как и элемент отображения используют CoFHLib). Синхронизируется это всё дело только при обновлении чанка. Ниже прилагаю нынешний код базового тайла, который наследуют все остальные тайлы и GUI, в котором элемент добавляется.

Java:
public abstract class BasicTileEntity extends  TileEntity  {
   

    public abstract void readCustomNBT(NBTTagCompound tags);

   
    public abstract void writeCustomNBT(NBTTagCompound tags);
   
    @Override
    public void readFromNBT(NBTTagCompound nbt) {

        super.readFromNBT(nbt);
        readCustomNBT(nbt);
       
    }

    @Override
    public void writeToNBT(NBTTagCompound nbt) {

        super.writeToNBT(nbt);
        writeCustomNBT(nbt);
       
    }

   
    @Override
    public S35PacketUpdateTileEntity getDescriptionPacket() {
        NBTTagCompound tagCompound = new NBTTagCompound();
        this.writeToNBT(tagCompound);
        S35PacketUpdateTileEntity pack = new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 0, tagCompound);
        return pack;
    }
    @Override
    public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) {
        this.readFromNBT(pkt.func_148857_g());

    }
   
   

}
Java:
public class TileEntityAssembler extends BasicTileEntity implements IEnergyHandler, IInventory{

    private ItemStack[] items = new ItemStack[10];
    
public EnergyStorage EstorageAssembler = new EnergyStorage(131072, 16384, 16384);
public TileEntityAssembler() {

}
    
     @Override
        public void readCustomNBT(NBTTagCompound nbt)
        {

            EstorageAssembler.readFromNBT(nbt);
            NBTTagList list = nbt.getTagList("Items", Constants.NBT.TAG_COMPOUND);
            items = new ItemStack[getSizeInventory()];

            for (int i = 0; i < list.tagCount(); ++i) { NBTTagCompound comp = list.getCompoundTagAt(i); int j = comp.getByte("Slot") & 255; if (j >= 0 && j < items.length)
                {
                    items[j] = ItemStack.loadItemStackFromNBT(comp);
                }
            }
        }

        @Override
        public void writeCustomNBT(NBTTagCompound nbt)
        {

                EstorageAssembler.writeToNBT(nbt);
                NBTTagList list = new NBTTagList();

                for (int i = 0; i < items.length; ++i)
                {
                    if (items[i] != null)
                    {
                        NBTTagCompound comp = new NBTTagCompound();
                        comp.setByte("Slot", (byte)i);
                        items[i].writeToNBT(comp);
                        list.appendTag(comp);
                    }
                }

                nbt.setTag("Items", list);
        }

    @Override
    public boolean canConnectEnergy(ForgeDirection from) {

        return true;
    }

    @Override
    public int receiveEnergy(ForgeDirection from, int maxReceive, boolean simulate) {

        return EstorageAssembler.receiveEnergy(maxReceive, simulate);
    }

    @Override
    public int extractEnergy(ForgeDirection from, int maxExtract, boolean simulate) {

        return 0;
    }

    @Override
    public int getEnergyStored(ForgeDirection from) {

        return EstorageAssembler.getEnergyStored();
    }

    @Override
    public int getMaxEnergyStored(ForgeDirection from) {

        return EstorageAssembler.getMaxEnergyStored();
    }
    @Override
    public int getSizeInventory() {
    
        return items.length;
    }
    @Override
    public ItemStack getStackInSlot(int slot) {

        return items[slot];
    }
    @Override
    public ItemStack decrStackSize(int slot, int amount) {
        if (items[slot] != null)
        {
            ItemStack itemstack;

            if (items[slot].stackSize == amount)
            {
                itemstack = items[slot];
                items[slot] = null;
                markDirty();
                return itemstack;
            }
            else
            {
                itemstack = items[slot].splitStack(amount);
                if (items[slot].stackSize == 0) items[slot] = null;
                markDirty();
                return itemstack;
            }
        }
        else
        {
            return null;
        }
    }
    @Override
    public ItemStack getStackInSlotOnClosing(int slot) {

        if (items[slot] != null)
        {
            ItemStack itemstack = items[slot];
            items[slot] = null;
            return itemstack;
        }
        else
        {
            return null;
        }
    }
    @Override
    public void setInventorySlotContents(int slot, ItemStack stack) {
         items[slot] = stack;
            if (stack != null && stack.stackSize > getInventoryStackLimit())
            {
                stack.stackSize = getInventoryStackLimit();
            }

            markDirty();
        
    }
    @Override
    public String getInventoryName() {

        return "container.assembler";
    }
    @Override
    public boolean hasCustomInventoryName() {

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

        return 64;
    }
    @Override
    public boolean isUseableByPlayer(EntityPlayer player) {

        return worldObj.getTileEntity(xCoord, yCoord, zCoord) != this ? false : player.getDistanceSq((double)xCoord + 0.5D, (double)yCoord + 0.5D, (double)zCoord + 0.5D) <= 64.0D;
    }
    @Override
    public void openInventory() {

        
    }
    @Override
    public void closeInventory() {

        
    }
    @Override
    public boolean isItemValidForSlot(int slot, ItemStack stack) {

        return true;
    }
    
    public IEnergyStorage getEnergyStorage() {

        return EstorageAssembler;
    }

    public int getScaledEnergyStored(int scale) {

        return MathHelper.round((long) EstorageAssembler.getEnergyStored() * scale / EstorageAssembler.getMaxEnergyStored());
    }

    

}

Java:
public class GuiAssembler extends GuiBase {
    private static ResourceLocation texture = new ResourceLocation(Reference.ID, "textures/gui/container/guiAssembler.png");

    private InventoryPlayer inventory;
    private TileEntityAssembler te;


    public GuiAssembler(TileEntityAssembler te, EntityPlayer player)
    {
        super(new ContainerAssembler(te, player), texture);
        inventory = player.inventory;
        this.te = te;
    }
    @Override
    public void initGui() {
        super.initGui();
       
        addElement(new ElementEnergyStored(this, 8, 28, te.getEnergyStorage()));
       
    }


    @Override
    public void updateElementInformation() {
        super.updateElementInformation();
       
    }

   @Override
    protected void drawGuiContainerForegroundLayer(int par1, int par2)
    {
        fontRendererObj.drawString(I18n.format(te.getInventoryName()), (xSize / 2) - (fontRendererObj.getStringWidth(I18n.format(te.getInventoryName())) / 2), 6, 4210752, false);
        fontRendererObj.drawString(I18n.format(inventory.getInventoryName()), 8, ySize - 96 + 2, 4210752);
       
       
       
    }
 
Последнее редактирование:

timaxa007

Модератор
5,831
409
672
В твоём TileEntity нету ни чего связанного с энергией.
В контейнере должно обновляться значение, смотри в пример контейнер ванильной печи.
 
12
0
Из всех элементов, предлагаемых CoFH с контейнерами взаимодействуют единицы. Элемент, показывающий энергию, взаимодействует только с IEnergyHandler из TileEntity (добавил код проблемного тайла) и самим GUI. Обновлять значение в контейнере тут не получится. В Thermal Expansion синхронизация сделана через систему пакетов CoFH Team, но её не рационально использовать т.к я делаю не аддон к Thermal Expansion.
 
7,099
324
1,510
Обновлять значение в контейнере тут не получится
Зависит от контейнера, его можно написать так, что тайл сможет уведомлять его об изменениях

Чтобы обновить переменные клиентского тайла на 1.12.2 юзаю такой код(возможно, на 1.7.10 не сильно отличается)
BlockWandBuilder#sendUpdates
 
1,057
50
234
1.12.2
Java:
@Override
    @Nullable
    public SPacketUpdateTileEntity getUpdatePacket()  
    {
        NBTTagCompound nbttagcompound = new NBTTagCompound();
        writeToNBT(nbttagcompound);
        return new SPacketUpdateTileEntity(pos, 1, nbttagcompound);
    }
  
    @Override
    public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity packet) {
        super.onDataPacket(net, packet);
        readFromNBT(packet.getNbtCompound());      
    }
1.7.10
Java:
    @Override
    public Packet getDescriptionPacket()
    {
        NBTTagCompound data = new NBTTagCompound();
        this.writeToNBT(data);
        return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, 2, data);
    }
   
    @Override
    public void onDataPacket(NetworkManager netManager, S35PacketUpdateTileEntity packet)
    {
        readFromNBT(packet.func_148857_g());
    }
вроде это имеется ввиду
 
7,099
324
1,510
Этот кусок кода почти не отличается синтаксисом, че там трудного для понимания?
Java:
SPacketUpdateTileEntity packet = getUpdatePacket();
if (packet != null && world isinstanceOf WorldServer) {
    Chunk chunk = (WorldServer)world.getPlayerChunkMap.getEntry(pos.getX >> 4, pos.getZ >> 4);
    if (chunk != null) chunk.sendPacket(packet);
}

@BlesseNtumble, нет не это имеется ввиду, а ручная отправка пакета обновления
 
12
0
1.12.2
Java:
@Override
    @Nullable
    public SPacketUpdateTileEntity getUpdatePacket() 
    {
        NBTTagCompound nbttagcompound = new NBTTagCompound();
        writeToNBT(nbttagcompound);
        return new SPacketUpdateTileEntity(pos, 1, nbttagcompound);
    }
 
    @Override
    public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity packet) {
        super.onDataPacket(net, packet);
        readFromNBT(packet.getNbtCompound());     
    }
1.7.10
Java:
    @Override
    public Packet getDescriptionPacket()
    {
        NBTTagCompound data = new NBTTagCompound();
        this.writeToNBT(data);
        return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, 2, data);
    }
  
    @Override
    public void onDataPacket(NetworkManager netManager, S35PacketUpdateTileEntity packet)
    {
        readFromNBT(packet.func_148857_g());
    }
вроде это имеется ввиду
Данный код уже присутствует у меня в базовом тайле. Повторяю ещё раз - он синхронизирует информацию в ГУИ только при перезагрузке чанков.
 
Сверху