Отображение количества энергии

Версия Minecraft
1.7.10
Я сделал блок с РФ-энергией, он почти готов кроме двух вещей:
1)На стороне клиента тут выдаёт ноль, хотя на стороне сервера всё верно.Это можно починить только благодаря пакетам?
Java:
    public int getEnergyStoredScaled(int i) {
        return getInfoEnergyStored() * i / getInfoMaxEnergyStored();
    }
Остальной код:

TileEntityAssembler:
package ru.mrtenfan.assembling.tileentity;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import ru.mrtenfan.assembling.crafting.AssemblerRecipe;

public class TileEntityAssembler extends TileEntityEnergy implements ISidedInventory {

    private String localyzedName;
    private ItemStack slots[];

    public static int assemblingSpeed = 500; //in ticks
    public int cookTime;

    private static final int[] slots_any = new int[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    
    public TileEntityAssembler() {
        slots = new ItemStack[10];
    }

    public static int getAssemblingSpeed() {
        return assemblingSpeed;
    }

    @Override
    public int getSizeInventory() {
        return slots.length;
    }

    @Override
    public ItemStack getStackInSlot(int i) {
        return slots[i];
    }

    @Override
    public ItemStack decrStackSize(int i, int j) {
        if (slots[i] != null) {
            if (slots[i].stackSize <= j ) {
                ItemStack itemStack = slots[i];
                slots[i] = null;
                return itemStack;
            }

            ItemStack itemStack1 = slots[i].splitStack(j);

            if (slots[i].stackSize == 0)
                slots[i] = null;

            return itemStack1;
        }else
            return null;
    }

    @Override
    public ItemStack getStackInSlotOnClosing(int p_70304_1_) {
        return null;
    }

    @Override
    public void setInventorySlotContents(int i, ItemStack itemStack) {
        slots[i] = itemStack;
        if (itemStack != null && itemStack.stackSize > getInventoryStackLimit())
            itemStack.stackSize = getInventoryStackLimit();
    }

    @Override
    public String getInventoryName() {
        return this.hasCustomInventoryName() ? this.localyzedName : "container.assembler";
    }

    @Override
    public boolean hasCustomInventoryName() {
        return this.localyzedName != null && this.localyzedName.length() > 0;
    }

    @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 itemStack) {
        return slot == 9 ? false : true;
    }

    @Override
    public int[] getAccessibleSlotsFromSide(int side) {
        return slots_any;
    }

    @Override
    public boolean canInsertItem(int var1, ItemStack itemStack, int var3) {
        return this.isItemValidForSlot(var1, itemStack);
    }

    @Override
    public boolean canExtractItem(int var1, ItemStack itemStack, int var3) {
        return var3 != 0 || var1 != 1;
    }

    public void readFromNBT(NBTTagCompound nbt) {
        super.readFromNBT(nbt);
        NBTTagList list = nbt.getTagList("Items", 10);
        slots = new ItemStack[getSizeInventory()];

        for (int i = 0; i < list.tagCount(); i++) {
            NBTTagCompound nbt1 = (NBTTagCompound)list.getCompoundTagAt(i);
            byte b0 = nbt1.getByte("Slot");

            if (b0 >= 0 && b0 < slots.length) {
                slots[b0] = ItemStack.loadItemStackFromNBT(nbt1);
            }
        }

        cookTime = nbt.getShort("CookTime");
    }

    public void writeToNBT(NBTTagCompound nbt) {
        super.writeToNBT(nbt);
        nbt.setShort("CookTime", (short)cookTime);
        NBTTagList list = new NBTTagList();

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

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

    public int getAlloyProgressScaled(int i) {
        return this.cookTime * i / assemblingSpeed;
    }

    public boolean canAssemble() {
        ItemStack itemStacks[] = new ItemStack[9];
        for(int i = 0; i < 9; i++)
            itemStacks[i] = slots[i];
        ItemStack itemStack = AssemblerRecipe.getAssemblingResult(itemStacks);
        int i = AssemblerRecipe.getAssemblingNumberOut(itemStacks);

        if(itemStack == null) return false;
        if(slots[9] == null) return true;
        if(!slots[9].isItemEqual(itemStack)) return false;
        else return slots[9].stackSize + i <= 64;
    }

    public void assemblyItem() {
        if(canAssemble()) {
            ItemStack itemStacks[] = getInputItemStacks();
            ItemStack itemStack = AssemblerRecipe.getAssemblingResult(itemStacks);
            int[] number = AssemblerRecipe.getAssemblingNumberIn(itemStacks);

            if (slots[9] == null)
                slots[9] = itemStack.copy();
            else if (slots[9].isItemEqual(itemStack))
                slots[9].stackSize += itemStack.stackSize;

            for (int k = 0; k < 9; k++) {
                if(number[k] != 0 && slots[k] != null) {
                    if (slots[k].stackSize <= 0)
                        slots[k] = new ItemStack(slots[k].getItem().setFull3D());
                    else
                        slots[k].stackSize -= number[k];


                    if (slots[k].stackSize <= 0)
                        slots[k] = null;
                }
            }
        }
    }

    private ItemStack[] getInputItemStacks() {
        ItemStack itemStacksTimed[] = new ItemStack[9];
        int i = 0;
        do{
            itemStacksTimed[i] = slots[i];
            i++;
        } while (slots[i] != null || i < 9);
        ItemStack itemStacks[] = new ItemStack[i];
        for(int j = 0; j < itemStacks.length; j++)
            itemStacks[j] = itemStacksTimed[j];
        return itemStacks;
    }

    public boolean isAssembly() {
        return this.cookTime > 0;
    }
    
    public boolean hasEnergy() {
        return energyStorage.getEnergyStored() > 0;
    }
    
    public void updateEntity() {
        boolean flag = this.getInfoEnergyStored() > 0;
        boolean flag1 = false;
        ItemStack itemStacks[] = new ItemStack[9];
        for(int i = 0; i < itemStacks.length; i++)
            itemStacks[i] = slots[i];
        int RFPerTick = AssemblerRecipe.getUsageRF(itemStacks);
        energyStorage.setEnergyStored(getInfoEnergyStored());
            
            if (this.hasEnergy() && this.canAssemble()) {
              //this.hasEnergy() &&
                this.cookTime++;
                if(RFPerTick > 0)
                    energyStorage.modifyEnergyStored(-RFPerTick * 1);
                                                                //energyMod
                if(this.cookTime == assemblingSpeed) {
                    this.cookTime = 0;
                    this.assemblyItem();
                    flag1 = true;
                }
            }else {
                cookTime = 0;
            }
            
            if (flag != this.hasEnergy()) {
                flag1 = true;
            }
        
        if (flag1) {
            this.markDirty();
        }
    }


    @Override
    public int getInfoEnergyPerTick() {
        ItemStack itemStacks[] = new ItemStack[9];
        for(int i = 0; i < itemStacks.length; i++)
            itemStacks[i] = slots[i];
        int RFPerTick = AssemblerRecipe.getUsageRF(itemStacks);
        return RFPerTick * 1;
    }                       //energyMod

    @Override
    public int getInfoMaxEnergyPerTick() {
        return 500 * 1;
    }                                  //energyMod

    public int getEnergyStoredScaled(int i) {
        return getInfoEnergyStored() * i / getInfoMaxEnergyStored();
    }
    
}
TileEntityEnergy:
package ru.mrtenfan.assembling.tileentity;

import cofh.api.energy.EnergyStorage;
import cofh.api.energy.IEnergyReceiver;
import cofh.api.energy.IEnergyStorage;
import cofh.api.tileentity.IEnergyInfo;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;

public class TileEntityEnergy extends TileEntity implements IEnergyInfo, IEnergyReceiver {

    protected EnergyStorage energyStorage = new EnergyStorage(30000, 500);

    @Override
    public void readFromNBT(NBTTagCompound nbt) {

        super.readFromNBT(nbt);

        energyStorage.readFromNBT(nbt);
    }

    @Override
    public void writeToNBT(NBTTagCompound nbt) {

        super.writeToNBT(nbt);

        energyStorage.writeToNBT(nbt);
    }
    
    @Override
    public int receiveEnergy(ForgeDirection from, int maxReceive, boolean simulate) {
        return energyStorage.receiveEnergy(maxReceive, simulate);
    }

    @Override
    public int getEnergyStored(ForgeDirection from) {
        return energyStorage.getEnergyStored();
    }

    @Override
    public int getMaxEnergyStored(ForgeDirection from) {
        return energyStorage.getMaxEnergyStored();
    }

    @Override
    public boolean canConnectEnergy(ForgeDirection from) {
        return energyStorage.getMaxEnergyStored() > 0;
    }
    
    @Override
    public int getInfoEnergyPerTick() {
        return 0;
    }

    @Override
    public int getInfoMaxEnergyPerTick() {
        return 0;
    }

    @Override
    public int getInfoEnergyStored() {
        return energyStorage.getEnergyStored();
    }

    @Override
    public int getInfoMaxEnergyStored() {
        return energyStorage.getMaxEnergyStored();
    }
    

    /* Energy Config Class */
//    public static class EnergyConfig {
//
//        public int minPower = 1;
//        public int maxPower = 500;
//        public int maxEnergy = 30000;
//        public int minPowerLevel = 1 * maxEnergy / 10;
//        public int maxPowerLevel = 9 * maxEnergy / 10;
//        public int energyRamp = maxPowerLevel / maxPower;
//
//        public EnergyConfig() {
//
//        }
//
//        public EnergyConfig(EnergyConfig config) {
//
//            this.minPower = config.minPower;
//            this.maxPower = config.maxPower;
//            this.maxEnergy = config.maxEnergy;
//            this.minPowerLevel = config.minPowerLevel;
//            this.maxPowerLevel = config.maxPowerLevel;
//            this.energyRamp = config.energyRamp;
//        }
//
//        public EnergyConfig copy() {
//
//            return new EnergyConfig(this);
//        }
//
//        public boolean setParams(int minPower, int maxPower, int maxEnergy) {
//
//            this.minPower = minPower;
//            this.maxPower = maxPower;
//            this.maxEnergy = maxEnergy;
//            this.maxPowerLevel = maxEnergy * 8 / 10;
//            this.energyRamp = maxPower > 0 ? maxPowerLevel / maxPower : 0;
//            this.minPowerLevel = minPower * energyRamp;
//
//            return true;
//        }
//
//        public boolean setParamsPower(int maxPower) {
//
//            return setParams(maxPower / 4, maxPower, maxPower * 1200);
//        }
//
//        public boolean setParamsPower(int maxPower, int scale) {
//
//            return setParams(maxPower / 4, maxPower, maxPower * 1200 * scale);
//        }
//
//        public boolean setParamsEnergy(int maxEnergy) {
//
//            return setParams(maxEnergy / 4800, maxEnergy / 1200, maxEnergy);
//        }
//
//        public boolean setParamsEnergy(int maxEnergy, int scale) {
//
//            maxEnergy *= scale;
//            return setParams(maxEnergy / 4800, maxEnergy / 1200, maxEnergy);
//        }
//
//        public boolean setParamsDefault(int maxPower) {
//
//            this.maxPower = maxPower;
//            minPower = maxPower / 10;
//            maxEnergy = maxPower * 500;
//            minPowerLevel = 1 * maxEnergy / 10;
//            maxPowerLevel = 9 * maxEnergy / 10;
//            energyRamp = maxPowerLevel / maxPower;
//
//            return true;
//        }
//
//    }
    
    public IEnergyStorage getEnergyStorage() {
        return energyStorage;
    }
}
GUIAssembler:
package ru.mrtenfan.assembling.gui;

import org.lwjgl.opengl.GL11;

import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.util.ResourceLocation;
import ru.mrtenfan.assembling.container.ContainerAssembler;
import ru.mrtenfan.assembling.tileentity.TileEntityAssembler;

public class GUIAssembler extends GuiContainer {

    public static final ResourceLocation texture = new ResourceLocation("assembling:textures/GUI/assembly_table_GUI.png");
    
    TileEntityAssembler assembler;

    public GUIAssembler(InventoryPlayer inventory, TileEntityAssembler entity) {
        super(new ContainerAssembler(inventory, entity));

        assembler = entity;

        xSize = 176;
        ySize = 166;
    }

    public void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
        String name = this.assembler.hasCustomInventoryName() ? this.assembler.getInventoryName() : I18n.format(this.assembler.getInventoryName(), new Object[0]);

        this.fontRendererObj.drawString(name, this.xSize / 2 - this.fontRendererObj.getStringWidth(name) / 2, 4, 4210752);
        this.fontRendererObj.drawString(I18n.format("container.inventory", new Object[0]), 8, this.ySize - 96 + 4, 4210752);
        
//        if(mouseX >= 411 && mouseY >= 202 && mouseX <= 424 && mouseY <= 243)
//            System.out.println(assembler.getEnergyStoredScaled(42) + "a" + mouseX + ":" + mouseY);
    }//411:202 && 424:243

    @Override
    public void drawGuiContainerBackgroundLayer(float p_146976_1_, int p_146976_2_, int p_146976_3_) {
//        System.out.println(p_146976_2_ + ":" + p_146976_3_);
        GL11.glColor4f(1F, 1F, 1F, 1F);
        mc.getTextureManager().bindTexture(texture);
        drawTexturedModalRect(guiLeft, guiTop, 0, 0, this.xSize, this.ySize);

        if(assembler.getInfoMaxEnergyStored() > 0) {
//            System.out.println(assembler.getEnergyStorage().getEnergyStored());
            int i = assembler.getEnergyStoredScaled(42);
            drawTexturedModalRect(guiLeft + 19, guiTop + 21, 176, 17, 14, i);
        }

        if(assembler.isAssembly()) {
            int j = assembler.getAlloyProgressScaled(24);
            drawTexturedModalRect(guiLeft + 103, guiTop + 33, 176, 0, j, 17);
        }
    }
}
;
2)Как сделать отображение кол-ва энергии, по типу этого:
1586373271698.png
Спасибо!
 
Я сделал это без пакетов)
Чуть поколдовал в Container-е

Java:
package ru.mrtenfan.assembling.container;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.ICrafting;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import ru.mrtenfan.assembling.container.slots.SlotOutput;
import ru.mrtenfan.assembling.tileentity.TileEntityAssembler;

public class ContainerAssembler extends Container {
    
    TileEntityAssembler assembler;
    private int lastCookTime;
    private int lastEnergy;
    
    public ContainerAssembler(InventoryPlayer playerInv, TileEntityAssembler entity) {
        
        assembler = entity;
        
        for (int l = 0; l < 3; ++l) {
            for (int i1 = 0; i1 < 3; ++i1) {
                this.addSlotToContainer(new Slot(assembler, i1 + l * 3, 44 + i1 * 18, 16 + l * 18)); //craft matrix
            }
        }
        
        this.addSlotToContainer(new SlotOutput(playerInv.player, assembler, 9, 138, 34)); //output
        
        for (int i = 0; i < 3; ++i){
            for (int j = 0; j < 9; ++j){
                this.addSlotToContainer(new Slot(playerInv, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
              }
             }
        for (int i = 0; i < 9; ++i){
            this.addSlotToContainer(new Slot(playerInv, i, 8 + i * 18, 142));
        }
    }
    
    public void addCraftingToCrafters(ICrafting crafting) {
        super.addCraftingToCrafters(crafting);
        crafting.sendProgressBarUpdate(this, 0, this.assembler.cookTime);
        crafting.sendProgressBarUpdate(this, 1, this.assembler.getInfoEnergyStored());
    }

    @Override
    public ItemStack transferStackInSlot(EntityPlayer playerInv, int slotIn)
    {
        ItemStack itemstack = null;
        Slot slot = (Slot)this.inventorySlots.get(slotIn);

        if (slot != null && slot.getHasStack())
        {
            ItemStack itemstack1 = slot.getStack();
            itemstack = itemstack1.copy();

            if (slotIn == 2)
            {
                if (!this.mergeItemStack(itemstack1, 3, 39, true))
                {
                    return null;
                }

                slot.onSlotChange(itemstack1, itemstack);
            }
            else if (slotIn != 1 && slotIn != 0)
            {
//                if (AlloyFurnaceRecipe.getAlloyingResult(itemstack1) != null)
//                {
//                    if (!this.mergeItemStack(itemstack1, 0, 1, false))
//                    {
//                        return null;
//                    }
//                }
              //else if
                if (slotIn >= 3 && slotIn < 30)
                {
                    if (!this.mergeItemStack(itemstack1, 30, 39, false))
                    {
                        return null;
                    }
                }
                else if (slotIn >= 30 && slotIn < 39 && !this.mergeItemStack(itemstack1, 3, 30, false))
                {
                    return null;
                }
            }
            if (!this.mergeItemStack(itemstack1, 3, 39, false))
            {
                return null;
            }

            if (itemstack1.stackSize == 0)
            {
                slot.putStack((ItemStack)null);
            }
            else
            {
                slot.onSlotChanged();
            }

            if (itemstack1.stackSize == itemstack.stackSize)
            {
                return null;
            }

            slot.onPickupFromSlot(playerInv, itemstack1);
        }

        return itemstack;
    }

    @Override
    public boolean canInteractWith(EntityPlayer player) {
        return assembler.isUseableByPlayer(player);
    }
    
    public void detectAndSendChanges() {
        super.detectAndSendChanges();
        
        for(int i = 0; i < this.crafters.size(); i++) {
            ICrafting par1 = (ICrafting)this.crafters.get(i);
            if (this.lastCookTime != this.assembler.cookTime) {
                par1.sendProgressBarUpdate(this, 0, this.assembler.cookTime);
            }
            if (this.lastEnergy != this.assembler.getInfoEnergyStored()) {
                par1.sendProgressBarUpdate(this, 1, this.assembler.getInfoEnergyStored());
            }
        }

        this.lastCookTime = this.assembler.cookTime;
        this.lastEnergy = this.assembler.getInfoEnergyStored();
    }
    
    public void updateProgressBar(int i, int j) {
        if (i == 0) {
            assembler.cookTime = j;
        }
        if (i == 1) {
            assembler.getEnergyStorage().setEnergyStored(j);
        }
    }
}
Только этот индикатор сверху вниз идёт)
 

tox1cozZ

aka Agravaine
8,455
598
2,892
Свои пакеты не обязательно, S35PacketUpdateTileEntity - ванильный пакет
Чушь советуешь. Зачем обновлять каждый тик полоску, если ее видно только когда открыт инвентарь машинки? Для этого есть специальные методы в контейнере.

Только этот индикатор сверху вниз идёт)
Чел, ты же сам пишешь чтобы использовалась высота, а не ширина(переменная i):
drawTexturedModalRect(guiLeft + 19, guiTop + 21, 176, 17, 14, i);
У тебя рядом строчка с прогрессом, где ты указываешь по ширине.
 
7,099
324
1,510
Чушь советуешь. Зачем обновлять каждый тик полоску, если ее видно только когда открыт инвентарь машинки? Для этого есть специальные методы в контейнере.
Справедливо
 
Как сделать отображение кол-ва энергии, по типу этого:
Я это сделал, спасибо timaxa007.

Java:
    public void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
        int posX = (this.width - this.xSize) / 2;
        int posY = (this.height - this.ySize) / 2;
        int mouseXoffset = mouseX - posX;
        int mouseYoffset = mouseY - posY;
        String name = this.assembler.hasCustomInventoryName() ? this.assembler.getInventoryName() : I18n.format(this.assembler.getInventoryName(), new Object[0]);

        this.fontRendererObj.drawString(name, this.xSize / 2 - this.fontRendererObj.getStringWidth(name) / 2, 4, 4210752);
        this.fontRendererObj.drawString(I18n.format("container.inventory", new Object[0]), 8, this.ySize - 96 + 4, 4210752);
        
//        System.out.println(mouseXoffset + ":" + mouseYoffset);
        if (mouseXoffset >= 19 && mouseYoffset >= 21 && mouseXoffset <= 32 && mouseYoffset <= 62) {
            List text = new ArrayList();
            text.add(assembler.getInfoEnergyStored() + "/" + assembler.getInfoMaxEnergyStored() + " RF");
            drawHoveringText(text, mouseXoffset, mouseYoffset, mc.fontRenderer);
        }
    }
Если вдруг кому-нибудь понадобится.
 
Сверху