596 lines
15 KiB
Java
Executable file
596 lines
15 KiB
Java
Executable file
/*******************************************************************************
|
|
* 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() {}
|
|
}
|