com.kaijin.AdvPowerMan.tileentities.TEStorageMonitor.java Source code

Java tutorial

Introduction

Here is the source code for com.kaijin.AdvPowerMan.tileentities.TEStorageMonitor.java

Source

/*******************************************************************************
 * Copyright (c) 2012-2013 Yancarlo Ramsey and CJ Bowman
 * Licensed as open source with restrictions. Please see attached LICENSE.txt.
 ******************************************************************************/
package com.kaijin.AdvPowerMan.tileentities;

import ic2.api.tile.IEnergyStorage;
import io.netty.buffer.ByteBuf;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

import com.kaijin.AdvPowerMan.AdvancedPowerManagement;
import com.kaijin.AdvPowerMan.Info;
import com.kaijin.AdvPowerMan.items.ItemCardBase;
import com.kaijin.AdvPowerMan.items.ItemStorageLinkCard;

import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.network.Packet;
import net.minecraft.network.PacketBuffer;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.common.util.ForgeDirection;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;

public class TEStorageMonitor extends TECommon implements ISidedInventory {
    private ItemStack[] contents;

    private int tickTime = 0;
    private int tickDelay = 5;

    public int lowerBoundary = 60;
    public int upperBoundary = 90;

    private boolean tileLoaded = false;

    public int energyStored = 0;
    public int energyCapacity = 0;
    public int chargeLevel = 0;

    public boolean isPowering = false;
    public boolean blockState = false;

    public int[] targetCoords;

    private static final int[] storageMonitorSideUniversal = { Info.SM_SLOT_UNIVERSAL };

    public TEStorageMonitor() {
        super();
        contents = new ItemStack[Info.SM_INVENTORY_SIZE];
    }

    /**
     * Reads a tile entity from NBT.
     */
    @Override
    public void readFromNBT(NBTTagCompound nbttagcompound) {
        super.readFromNBT(nbttagcompound);

        // State info to remember
        isPowering = nbttagcompound.getBoolean("isPowering");
        upperBoundary = nbttagcompound.getInteger("upperBoundary");
        lowerBoundary = nbttagcompound.getInteger("lowerBoundary");

        // Our inventory
        NBTTagList nbttaglist = nbttagcompound.getTagList("Items", Constants.NBT.TAG_COMPOUND);
        // Redundant: contents = new ItemStack[Info.SM_INVENTORY_SIZE];
        for (int i = 0; i < nbttaglist.tagCount(); ++i) {
            NBTTagCompound nbttagcompound1 = (NBTTagCompound) nbttaglist.getCompoundTagAt(i);
            int j = nbttagcompound1.getByte("Slot") & 255;

            if (j >= 0 && j < contents.length) {
                contents[j] = ItemStack.loadItemStackFromNBT(nbttagcompound1);
            }
        }
    }

    /**
     * Writes a tile entity to NBT.
     */
    @Override
    public void writeToNBT(NBTTagCompound nbttagcompound) {
        super.writeToNBT(nbttagcompound);

        // State info to remember
        nbttagcompound.setBoolean("isPowering", isPowering);
        nbttagcompound.setInteger("upperBoundary", upperBoundary);
        nbttagcompound.setInteger("lowerBoundary", lowerBoundary);

        // Our inventory
        NBTTagList nbttaglist = new NBTTagList();
        for (int i = 0; i < contents.length; ++i) {
            if (contents[i] != null) {
                // if (ChargingBench.isDebugging)
                // System.out.println("WriteNBT contents[" + i + "] stack tag: "
                // + contents[i].stackTagCompound);
                NBTTagCompound nbttagcompound1 = new NBTTagCompound();
                nbttagcompound1.setByte("Slot", (byte) i);
                contents[i].writeToNBT(nbttagcompound1);
                nbttaglist.appendTag(nbttagcompound1);
            }
        }
        nbttagcompound.setTag("Items", nbttaglist);
    }

    @Override
    public int getGuiID() {
        return Info.GUI_ID_STORAGE_MONITOR;
    }

    /**
     * This will cause the block to drop anything inside it, create a new item
     * in the world of its type, invalidate the tile entity, remove itself from
     * the IC2 EnergyNet and clear the block space (set it to air)
     */
    private void selfDestroy() {
        dropContents();
        ItemStack stack = new ItemStack(AdvancedPowerManagement.blockAdvPwrMan, 1, 11);
        dropItem(stack);
        worldObj.setBlockToAir(xCoord, yCoord, zCoord);
        this.invalidate();
    }

    public void dropItem(ItemStack item) {
        EntityItem entityitem = new EntityItem(worldObj, (double) xCoord + 0.5D, (double) yCoord + 0.5D,
                (double) zCoord + 0.5D, item);
        entityitem.delayBeforeCanPickup = 10;
        worldObj.spawnEntityInWorld(entityitem);
    }

    @Override
    public void dropContents() {
        ItemStack item;
        int i;
        for (i = 0; i < contents.length; ++i) {
            item = contents[i];
            if (item != null && item.stackSize > 0)
                dropItem(item);
        }
    }

    public boolean isItemValid(int slot, ItemStack stack) {
        // Decide if the item is valid to place in a slot
        return stack != null && stack.getItem() instanceof ItemStorageLinkCard;
    }

    /**
     * Runs once on tile entity load to make sure all of our internals are setup
     * correctly
     */
    private void onLoad() {
        if (!AdvancedPowerManagement.proxy.isClient()) {
            tileLoaded = true;
            checkInventory();
            if (targetCoords != null) {
                TileEntity tile = null;
                if (targetCoords[3] == worldObj.provider.dimensionId) {
                    tile = worldObj.getTileEntity(targetCoords[0], targetCoords[1], targetCoords[2]);
                }

                if (tile instanceof IEnergyStorage) {
                    energyStored = ((IEnergyStorage) tile).getStored();
                    energyCapacity = ((IEnergyStorage) tile).getCapacity();
                    blockState = true;
                } else {
                    energyStored = 0;
                    energyCapacity = 0;
                    blockState = false;
                }
            }
            chargeLevel = gaugeEnergyScaled(12);

            if (energyCapacity > 0) // Avoid divide by zero and also test if the
            // remote energy storage is valid
            {
                updateRedstone();
            } else if (isPowering) // If we're emitting redstone at this point, we
                                   // need to shut it off
            {
                isPowering = false;
                worldObj.notifyBlocksOfNeighborChange(xCoord, yCoord, zCoord,
                        worldObj.getBlock(xCoord, yCoord, zCoord));
            }
            worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
        }
    }

    @Override
    public void updateEntity() // TODO Marked for easy access
    {
        if (AdvancedPowerManagement.proxy.isClient())
            return;

        if (!tileLoaded) {
            onLoad();
        }

        // Delayed work
        if (tickTime > 0) {
            tickTime--;
        } else {
            tickTime = tickDelay;
            if (targetCoords != null) {
                TileEntity tile = null;
                if (targetCoords[3] == worldObj.provider.dimensionId) {
                    tile = worldObj.getTileEntity(targetCoords[0], targetCoords[1], targetCoords[2]);
                }

                if (tile instanceof IEnergyStorage) {
                    // if (ChargingBench.isDebugging)
                    // System.out.println("updateEntity - check energy level of remote block");
                    energyStored = ((IEnergyStorage) tile).getStored();
                    energyCapacity = ((IEnergyStorage) tile).getCapacity();
                    if (!blockState) {
                        worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
                    }
                    blockState = true;
                } else {
                    energyStored = 0;
                    energyCapacity = 0;
                    if (blockState) {
                        worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
                    }
                    blockState = false;
                }
            }

            if (energyCapacity > 0) // Avoid divide by zero and also test if the
            // remote energy storage is valid
            {
                updateRedstone();
            } else if (isPowering) // If we're emitting redstone at this point, we
                                   // need to shut it off
            {
                isPowering = false;
                worldObj.notifyBlocksOfNeighborChange(xCoord, yCoord, zCoord,
                        worldObj.getBlock(xCoord, yCoord, zCoord));
            }

            // Trigger this only when charge level passes where it would need to
            // update the client texture
            int oldChargeLevel = chargeLevel;
            chargeLevel = gaugeEnergyScaled(12);
            if (oldChargeLevel != chargeLevel) {
                // if (ChargingBench.isDebugging)
                // System.out.println("TE oldChargeLevel: " + oldChargeLevel +
                // " chargeLevel: " + chargeLevel);
                worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
            }
        }
    }

    private void updateRedstone() {
        float chargePercent = ((float) energyStored * 100.0F) / (float) energyCapacity;
        if ((isPowering == false && chargePercent < lowerBoundary)
                || (isPowering == true && chargePercent >= upperBoundary)) {
            if (Info.isDebugging)
                System.out.println("Storage Monitor toggling redstone. chargePercent:" + chargePercent);
            isPowering = !isPowering;
            worldObj.notifyBlocksOfNeighborChange(xCoord, yCoord, zCoord,
                    worldObj.getBlock(xCoord, yCoord, zCoord));
            worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
        }
    }

    private void checkInventory() {
        ItemStack item = getStackInSlot(Info.SM_SLOT_UNIVERSAL);
        if (item == null || !(item.getItem() instanceof ItemStorageLinkCard)) {
            targetCoords = null;
            energyCapacity = 0;
            energyStored = 0;
            blockState = false;
        } else {
            targetCoords = ItemCardBase.getCoordinates(item);
            ItemCardBase.setCoordinates(item, targetCoords); // Make sure old
            // cards have a
            // dimension
            // number
        }
        worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
    }

    boolean receivingRedstoneSignal() {
        return worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord);
    }

    public int gaugeEnergyScaled(int gaugeSize) {
        if (energyStored <= 0 || energyCapacity <= 0) {
            return 0;
        }

        int result = energyStored * gaugeSize / energyCapacity;
        if (result > gaugeSize)
            result = gaugeSize;

        return result;
    }

    // Networking stuff

    /**
     * Packet reception by server of what button was clicked on the client's
     * GUI.
     * 
     * @param id
     *            = the button ID
     */
    @Override
    public void receiveGuiButton(int id) {
        switch (id) {
        case 0:
            upperBoundary -= 10;
            if (upperBoundary < 1)
                upperBoundary = 1;
            if (upperBoundary < lowerBoundary)
                lowerBoundary = upperBoundary;
            break;
        case 1:
            upperBoundary -= 1;
            if (upperBoundary < 1)
                upperBoundary = 1;
            if (upperBoundary < lowerBoundary)
                lowerBoundary = upperBoundary;
            break;
        case 2:
            upperBoundary += 1;
            if (upperBoundary > 100)
                upperBoundary = 100;
            break;
        case 3:
            upperBoundary += 10;
            if (upperBoundary == 11)
                upperBoundary = 10;
            if (upperBoundary > 100)
                upperBoundary = 100;
            break;
        case 4:
            lowerBoundary -= 10;
            if (lowerBoundary < 1)
                lowerBoundary = 1;
            break;
        case 5:
            lowerBoundary -= 1;
            if (lowerBoundary < 1)
                lowerBoundary = 1;
            break;
        case 6:
            lowerBoundary += 1;
            if (lowerBoundary > 100)
                lowerBoundary = 100;
            if (lowerBoundary > upperBoundary)
                upperBoundary = lowerBoundary;
            break;
        case 7:
            lowerBoundary += 10;
            if (lowerBoundary == 11)
                lowerBoundary = 10;
            if (lowerBoundary > 100)
                lowerBoundary = 100;
            if (lowerBoundary > upperBoundary)
                upperBoundary = lowerBoundary;
            break;
        }
    }

    @Override
    public Packet getDescriptionPacket() {
        return createDescPacket();
    }

    @Override
    protected void addUniqueDescriptionData(ByteBuf data) throws IOException {
        data.writeInt(chargeLevel);
        data.writeBoolean(isPowering);
        data.writeBoolean(blockState);
    }

    @SideOnly(Side.CLIENT)
    @Override
    public void receiveDescriptionData(int packetID, ByteBuf stream) {
        final int a;
        final boolean b;
        final boolean c;
        // try
        // {
        a = stream.readInt();
        b = stream.readBoolean();
        c = stream.readBoolean();
        /*
         * } catch (IOException e) { logDescPacketError(e); return; }
         */

        chargeLevel = a;
        isPowering = b;
        blockState = c;
        worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
    }

    // ISidedInventory

    /*
     * @Override public int getStartInventorySide(ForgeDirection side) { return
     * Info.SM_SLOT_UNIVERSAL; }
     * 
     * @Override public int getSizeInventorySide(int side) { // Each side
     * accesses a single slot return 1; }
     */

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

    @Override
    public boolean isItemValidForSlot(int i, ItemStack stack) {
        // Decide if the item is a link card
        return (i == Info.SM_SLOT_UNIVERSAL && stack != null && stack.getItem() instanceof ItemStorageLinkCard);
    }

    // Returns true if automation can insert the given item in the given slot
    // from the given side. Args: Slot, item, side
    @Override
    public boolean canInsertItem(int i, ItemStack itemstack, int j) // canInsertItem
    {
        return true;
    }

    // Returns true if automation can extract the given item in the given slot
    // from the given side. Args: Slot, item, side
    @Override
    public boolean canExtractItem(int i, ItemStack itemstack, int j) // canExtractItem
    {
        return true;
    }

    // IInventory

    @Override
    public boolean hasCustomInventoryName() {
        return false;
    }

    @Override
    public int getSizeInventory() {
        // Only input/output slots are accessible to machines
        return 1;
    }

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

    @Override
    public ItemStack decrStackSize(int slot, int amount) {
        if (contents[slot] != null) {
            ItemStack output;

            if (contents[slot].stackSize <= amount) {
                output = contents[slot];
                contents[slot] = null;
                this.markDirty(slot);
                return output;
            } else {
                output = contents[slot].splitStack(amount);

                if (contents[slot].stackSize == 0) {
                    contents[slot] = null;
                }
                this.markDirty(slot);
                return output;
            }
        } else {
            return null;
        }
    }

    @Override
    public ItemStack getStackInSlotOnClosing(int slot) {
        if (contents[slot] == null) {
            return null;
        }

        ItemStack stack = contents[slot];
        contents[slot] = null;
        return stack;
    }

    @Override
    public void setInventorySlotContents(int slot, ItemStack itemstack) {
        contents[slot] = itemstack;

        if (Info.isDebugging && itemstack != null) {
            if (AdvancedPowerManagement.proxy.isServer()) {
                System.out.println("Server assigned stack tag: " + itemstack.stackTagCompound);
                // if (itemstack.stackTagCompound != null)
                // System.out.println("     " +
                // itemstack.stackTagCompound.getTags().toString());
            }
            if (AdvancedPowerManagement.proxy.isClient()) {
                System.out.println("Client assigned stack tag: " + itemstack.stackTagCompound);
                // if (itemstack.stackTagCompound != null)
                // System.out.println("     " +
                // itemstack.stackTagCompound.getTags().toString());
            }
        }
        if (itemstack != null && itemstack.stackSize > getInventoryStackLimit()) {
            itemstack.stackSize = getInventoryStackLimit();
        }
        this.markDirty(slot);
    }

    @Override
    public void markDirty(int slot) {
        this.markDirty();
    }

    @Override
    public void markDirty() {
        if (Info.isDebugging)
            System.out.println("TEStorageMonitor.onInventoryChanged");
        checkInventory();
        super.markDirty();
    }

    @Override
    public String getInventoryName() {
        return Info.KEY_BLOCK_NAMES[11] + Info.KEY_NAME_SUFFIX;
    }

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

    @Override
    public boolean isUseableByPlayer(EntityPlayer entityplayer) {
        if (worldObj.getTileEntity(xCoord, yCoord, zCoord) != this) {
            return false;
        }

        return entityplayer.getDistanceSq((double) xCoord + 0.5D, (double) yCoord + 0.5D,
                (double) zCoord + 0.5D) <= 64D;
    }

    @Override
    public void openInventory() {
    }

    @Override
    public void closeInventory() {
    }
}