package crazypants.enderio.machine.capbank;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import cofh.api.energy.IEnergyContainerItem;
import com.enderio.core.common.util.BlockCoord;
import com.enderio.core.common.util.EntityUtil;
import com.enderio.core.common.util.Util;
import com.enderio.core.common.vecmath.Vector3d;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import crazypants.enderio.EnderIO;
import crazypants.enderio.TileEntityEio;
import crazypants.enderio.conduit.IConduitBundle;
import crazypants.enderio.machine.IIoConfigurable;
import crazypants.enderio.machine.IoMode;
import crazypants.enderio.machine.RedstoneControlMode;
import crazypants.enderio.machine.capbank.network.CapBankClientNetwork;
import crazypants.enderio.machine.capbank.network.ClientNetworkManager;
import crazypants.enderio.machine.capbank.network.EnergyReceptor;
import crazypants.enderio.machine.capbank.network.ICapBankNetwork;
import crazypants.enderio.machine.capbank.network.InventoryImpl;
import crazypants.enderio.machine.capbank.network.NetworkUtil;
import crazypants.enderio.machine.capbank.packet.PacketNetworkIdRequest;
import crazypants.enderio.network.PacketHandler;
import crazypants.enderio.power.IInternalPowerReceiver;
import crazypants.enderio.power.IPowerInterface;
import crazypants.enderio.power.IPowerStorage;
import crazypants.enderio.power.PowerHandlerUtil;
public class TileCapBank extends TileEntityEio implements IInternalPowerReceiver, IInventory, IIoConfigurable, IPowerStorage {
private Map<ForgeDirection, IoMode> faceModes;
private Map<ForgeDirection, InfoDisplayType> faceDisplayTypes;
private CapBankType type;
private int energyStored;
private int maxInput = -1;
private int maxOutput = -1;
private RedstoneControlMode inputControlMode = RedstoneControlMode.IGNORE;
private RedstoneControlMode outputControlMode = RedstoneControlMode.IGNORE;
private boolean redstoneStateDirty = true;
private boolean isRecievingRedstoneSignal;
private final List<EnergyReceptor> receptors = new ArrayList<EnergyReceptor>();
private boolean receptorsDirty = true;
private ICapBankNetwork network;
private final ItemStack[] inventory;
public TileCapBank() {
inventory = new ItemStack[4];
}
//Client side refernce to look up network state
private int networkId = -1;
private int idRequestTimer = 0;
private boolean dropItems;
private boolean displayTypesDirty;
private boolean revalidateDisplayTypes;
private int lastComparatorState;
public CapBankType getType() {
if(type == null) {
type = CapBankType.getTypeFromMeta(getBlockMetadata());
}
return type;
}
public void onNeighborBlockChange(Block blockId) {
redstoneStateDirty = true;
revalidateDisplayTypes = true;
// directly call updateReceptors() to work around issue #1433
updateReceptors();
}
//---------- Multiblock
@SideOnly(Side.CLIENT)
public void setNetworkId(int networkId) {
this.networkId = networkId;
if(networkId != -1) {
ClientNetworkManager.getInstance().addToNetwork(networkId, this);
}
}
@SideOnly(Side.CLIENT)
public int getNetworkId() {
return networkId;
}
public ICapBankNetwork getNetwork() {
return network;
}
public boolean setNetwork(ICapBankNetwork network) {
this.network = network;
return true;
}
public boolean canConnectTo(TileCapBank cap) {
CapBankType t = getType();
return t.isMultiblock() && t.getUid().equals(cap.getType().getUid());
}
@Override
public void onChunkUnload() {
if(network != null) {
network.destroyNetwork();
}
}
@Override
public void invalidate() {
super.invalidate();
if(network != null) {
network.destroyNetwork();
}
}
public void moveInventoryToNetwork() {
if(network == null) {
return;
}
if(network.getInventory().getCapBank() == this && !InventoryImpl.isInventoryEmtpy(inventory)) {
for (TileCapBank cb : network.getMembers()) {
if(cb != this) {
for (int i = 0; i < inventory.length; i++) {
cb.inventory[i] = inventory[i];
inventory[i] = null;
}
network.getInventory().setCapBank(cb);
break;
}
}
}
}
public void onBreakBlock() {
//If we are holding the networks inventory when we care broken, tranfer it to another member of the network
moveInventoryToNetwork();
}
@Override
public void doUpdate() {
if(worldObj.isRemote) {
if(networkId == -1) {
if(idRequestTimer <= 0) {
PacketHandler.INSTANCE.sendToServer(new PacketNetworkIdRequest(this));
idRequestTimer = 5;
} else {
--idRequestTimer;
}
}
return;
}
updateNetwork(worldObj);
if(network == null) {
return;
}
if(redstoneStateDirty) {
int sig = worldObj.getStrongestIndirectPower(xCoord, yCoord, zCoord);
boolean recievingSignal = sig > 0;
network.updateRedstoneSignal(this, recievingSignal);
redstoneStateDirty = false;
}
if(receptorsDirty) {
updateReceptors();
}
if(revalidateDisplayTypes) {
validateDisplayTypes();
revalidateDisplayTypes = false;
}
if(displayTypesDirty) {
displayTypesDirty = false;
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
}
// update any comparators, since they don't check themselves
int comparatorState = getComparatorOutput();
if(lastComparatorState != comparatorState) {
worldObj.func_147453_f(xCoord, yCoord, zCoord, getBlockType());
lastComparatorState = comparatorState;
}
doDropItems();
}
private void updateNetwork(World world) {
if(getNetwork() == null) {
NetworkUtil.ensureValidNetwork(this);
}
if(getNetwork() != null) {
getNetwork().onUpdateEntity(this);
}
}
//---------- IO
@Override
public IoMode toggleIoModeForFace(ForgeDirection faceHit) {
IPowerInterface rec = getReceptorForFace(faceHit);
IoMode curMode = getIoMode(faceHit);
if(curMode == IoMode.PULL) {
setIoMode(faceHit, IoMode.PUSH, true);
return IoMode.PUSH;
}
if(curMode == IoMode.PUSH) {
setIoMode(faceHit, IoMode.DISABLED, true);
return IoMode.DISABLED;
}
if(curMode == IoMode.DISABLED) {
if(rec == null || rec.getDelegate() instanceof IConduitBundle) {
setIoMode(faceHit, IoMode.NONE, true);
return IoMode.NONE;
}
}
setIoMode(faceHit, IoMode.PULL, true);
return IoMode.PULL;
}
@Override
public boolean supportsMode(ForgeDirection faceHit, IoMode mode) {
IPowerInterface rec = getReceptorForFace(faceHit);
if(mode == IoMode.NONE) {
return rec == null || rec.getDelegate() instanceof IConduitBundle;
}
return true;
}
@Override
public void setIoMode(ForgeDirection faceHit, IoMode mode) {
setIoMode(faceHit, mode, true);
}
public void setIoMode(ForgeDirection faceHit, IoMode mode, boolean updateReceptors) {
if(mode == IoMode.NONE) {
if(faceModes == null) {
return;
}
faceModes.remove(faceHit);
if(faceModes.isEmpty()) {
faceModes = null;
}
} else {
if(faceModes == null) {
faceModes = new EnumMap<ForgeDirection, IoMode>(ForgeDirection.class);
}
faceModes.put(faceHit, mode);
}
if(updateReceptors) {
validateModeForReceptor(faceHit);
receptorsDirty = true;
}
if(worldObj != null) {
worldObj.markBlockForUpdate(xCoord, yCoord, zCoord);
worldObj.notifyBlocksOfNeighborChange(xCoord, yCoord, zCoord, getBlockType());
}
}
public void setDefaultIoMode(ForgeDirection faceHit) {
EnergyReceptor er = getEnergyReceptorForFace(faceHit);
if(er == null || er.getConduit() != null) {
setIoMode(faceHit, IoMode.NONE);
} else if(er.getReceptor().isInputOnly()) {
setIoMode(faceHit, IoMode.PUSH);
} else if(er.getReceptor().isOutputOnly()) {
setIoMode(faceHit, IoMode.PULL);
} else {
setIoMode(faceHit, IoMode.PUSH);
}
}
@Override
public void clearAllIoModes() {
if(network != null) {
for(TileCapBank cb : network.getMembers()) {
cb.doClearAllIoModes();
}
} else {
doClearAllIoModes();
}
}
private void doClearAllIoModes() {
for(ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
setDefaultIoMode(dir);
}
}
@Override
public IoMode getIoMode(ForgeDirection face) {
if(faceModes == null) {
return IoMode.NONE;
}
IoMode res = faceModes.get(face);
if(res == null) {
return IoMode.NONE;
}
return res;
}
//----- Info Display
public boolean hasDisplayTypes() {
return faceDisplayTypes != null;
}
public InfoDisplayType getDisplayType(ForgeDirection face) {
if(faceDisplayTypes == null) {
return InfoDisplayType.NONE;
}
InfoDisplayType res = faceDisplayTypes.get(face);
return res == null ? InfoDisplayType.NONE : res;
}
public void setDisplayType(ForgeDirection face, InfoDisplayType type) {
setDisplayType(face, type, true);
}
public void setDisplayType(ForgeDirection face, InfoDisplayType type, boolean markDirty) {
if(type == null) {
type = InfoDisplayType.NONE;
}
if(faceDisplayTypes == null && type == InfoDisplayType.NONE) {
return;
}
InfoDisplayType cur = getDisplayType(face);
if(cur == type) {
return;
}
if(faceDisplayTypes == null) {
faceDisplayTypes = new EnumMap<ForgeDirection, InfoDisplayType>(ForgeDirection.class);
}
if(type == InfoDisplayType.NONE) {
faceDisplayTypes.remove(face);
} else {
faceDisplayTypes.put(face, type);
}
if(faceDisplayTypes.isEmpty()) {
faceDisplayTypes = null;
}
displayTypesDirty = markDirty;
invalidateDisplayInfoCache();
}
public void validateDisplayTypes() {
if(faceDisplayTypes == null) {
return;
}
List<ForgeDirection> reset = new ArrayList<ForgeDirection>();
for (Entry<ForgeDirection, InfoDisplayType> entry : faceDisplayTypes.entrySet()) {
BlockCoord bc = getLocation().getLocation(entry.getKey());
Block block = worldObj.getBlock(bc.x, bc.y, bc.z);
if(block != null && (block.isOpaqueCube() || block == EnderIO.blockCapBank)) {
reset.add(entry.getKey());
}
}
for (ForgeDirection dir : reset) {
setDisplayType(dir, InfoDisplayType.NONE);
setDefaultIoMode(dir);
}
}
private void invalidateDisplayInfoCache() {
if(network != null) {
network.invalidateDisplayInfoCache();
}
}
//----------- rendering
@Override
public boolean shouldRenderInPass(int pass) {
if(faceDisplayTypes == null) {
return false;
}
return pass == 0;
}
@Override
@SideOnly(Side.CLIENT)
public AxisAlignedBB getRenderBoundingBox() {
if(!type.isMultiblock() || !(network instanceof CapBankClientNetwork)) {
return super.getRenderBoundingBox();
}
int minX = xCoord;
int minY = yCoord;
int minZ = zCoord;
int maxX = xCoord+1;
int maxY = yCoord+1;
int maxZ = zCoord+1;
if(faceDisplayTypes != null) {
CapBankClientNetwork cn = (CapBankClientNetwork)network;
if(faceDisplayTypes.get(ForgeDirection.NORTH) == InfoDisplayType.IO) {
CapBankClientNetwork.IOInfo info = cn.getIODisplayInfo(xCoord, yCoord, zCoord, ForgeDirection.NORTH);
maxX = Math.max(maxX, xCoord + info.width);
minY = Math.min(minY, yCoord + 1 - info.height);
}
if(faceDisplayTypes.get(ForgeDirection.SOUTH) == InfoDisplayType.IO) {
CapBankClientNetwork.IOInfo info = cn.getIODisplayInfo(xCoord, yCoord, zCoord, ForgeDirection.SOUTH);
minX = Math.min(minX, xCoord + 1 - info.width);
minY = Math.min(minY, yCoord + 1 - info.height);
}
if(faceDisplayTypes.get(ForgeDirection.EAST) == InfoDisplayType.IO) {
CapBankClientNetwork.IOInfo info = cn.getIODisplayInfo(xCoord, yCoord, zCoord, ForgeDirection.EAST);
maxZ = Math.max(maxZ, zCoord + info.width);
minY = Math.min(minY, yCoord + 1 - info.height);
}
if(faceDisplayTypes.get(ForgeDirection.WEST) == InfoDisplayType.IO) {
CapBankClientNetwork.IOInfo info = cn.getIODisplayInfo(xCoord, yCoord, zCoord, ForgeDirection.WEST);
minZ = Math.min(minZ, zCoord + 1 - info.width);
minY = Math.min(minY, yCoord + 1 - info.height);
}
}
return AxisAlignedBB.getBoundingBox(minX, minY, minZ, maxX, maxY, maxZ);
}
//----------- Redstone
public RedstoneControlMode getInputControlMode() {
return inputControlMode;
}
public void setInputControlMode(RedstoneControlMode inputControlMode) {
this.inputControlMode = inputControlMode;
}
public RedstoneControlMode getOutputControlMode() {
return outputControlMode;
}
public void setOutputControlMode(RedstoneControlMode outputControlMode) {
this.outputControlMode = outputControlMode;
}
//----------- Power
@Override
public IPowerStorage getController() {
return network;
}
@Override
public long getEnergyStoredL() {
if(network == null) {
return getEnergyStored();
}
return network.getEnergyStoredL();
}
@Override
public long getMaxEnergyStoredL() {
if (network == null) {
return getMaxEnergyStored();
}
return network.getMaxEnergyStoredL();
}
@Override
public boolean isOutputEnabled(ForgeDirection direction) {
IoMode mode = getIoMode(direction);
return mode == IoMode.PUSH || mode == IoMode.NONE && isOutputEnabled();
}
private boolean isOutputEnabled() {
if(network == null) {
return true;
}
return network.isOutputEnabled();
}
@Override
public boolean isInputEnabled(ForgeDirection direction) {
IoMode mode = getIoMode(direction);
return mode == IoMode.PULL || mode == IoMode.NONE && isInputEnabled();
}
private boolean isInputEnabled() {
if(network == null) {
return true;
}
return network.isInputEnabled();
}
@Override
public boolean isNetworkControlledIo(ForgeDirection direction) {
IoMode mode = getIoMode(direction);
return mode == IoMode.NONE || mode == IoMode.PULL;
}
@Override
public boolean isCreative() {
return getType().isCreative();
}
public List<EnergyReceptor> getReceptors() {
if(receptorsDirty) {
updateReceptors();
}
return receptors;
}
private void updateReceptors() {
if(network == null) {
return;
}
network.removeReceptors(receptors);
receptors.clear();
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
IPowerInterface pi = getReceptorForFace(dir);
if(pi != null) {
EnergyReceptor er = new EnergyReceptor(this, pi, dir);
validateModeForReceptor(er);
IoMode ioMode = getIoMode(dir);
if(ioMode != IoMode.DISABLED && ioMode != IoMode.PULL) {
receptors.add(er);
}
}
}
network.addReceptors(receptors);
receptorsDirty = false;
}
private IPowerInterface getReceptorForFace(ForgeDirection faceHit) {
BlockCoord checkLoc = new BlockCoord(this).getLocation(faceHit);
TileEntity te = worldObj.getTileEntity(checkLoc.x, checkLoc.y, checkLoc.z);
if(!(te instanceof TileCapBank)) {
return PowerHandlerUtil.create(te);
} else {
TileCapBank other = (TileCapBank) te;
if(other.getType() != getType()) {
return PowerHandlerUtil.create(te);
}
}
return null;
}
private EnergyReceptor getEnergyReceptorForFace(ForgeDirection dir) {
IPowerInterface pi = getReceptorForFace(dir);
if(pi == null || pi.getDelegate() instanceof TileCapBank) {
return null;
}
return new EnergyReceptor(this, pi, dir);
}
private void validateModeForReceptor(ForgeDirection dir) {
validateModeForReceptor(getEnergyReceptorForFace(dir));
}
private void validateModeForReceptor(EnergyReceptor er) {
if (er == null) return;
IoMode ioMode = getIoMode(er.getDir());
if((ioMode == IoMode.PUSH_PULL || ioMode == IoMode.NONE) && er.getConduit() == null) {
if(er.getReceptor().isOutputOnly()) {
setIoMode(er.getDir(), IoMode.PULL, false);
} else if (er.getReceptor().isInputOnly()) {
setIoMode(er.getDir(), IoMode.PUSH, false);
}
}
if(ioMode == IoMode.PULL && er.getReceptor().isInputOnly()) {
setIoMode(er.getDir(), IoMode.PUSH, false);
} else if(ioMode == IoMode.PUSH && er.getReceptor().isOutputOnly()) {
setIoMode(er.getDir(), IoMode.DISABLED, false);
}
}
@Override
public void addEnergy(int energy) {
if(network == null) {
setEnergyStored(getEnergyStored() + energy);
} else {
network.addEnergy(energy);
}
}
@Override
public void setEnergyStored(int stored) {
energyStored = MathHelper.clamp_int(stored, 0, getMaxEnergyStored());
}
@Override
public int getEnergyStored() {
return energyStored;
}
@Override
public int getEnergyStored(ForgeDirection from) {
return getEnergyStored();
}
@Override
public int getMaxEnergyStored() {
return getType().getMaxEnergyStored();
}
@Override
public int getMaxEnergyRecieved(ForgeDirection dir) {
return getMaxInput();
}
@Override
public int getMaxInput() {
if(network == null) {
return getType().getMaxIO();
}
return network.getMaxInput();
}
public void setMaxInput(int maxInput) {
this.maxInput = maxInput;
}
public int getMaxInputOverride() {
return maxInput;
}
@Override
public int getMaxOutput() {
if(network == null) {
return getType().getMaxIO();
}
return network.getMaxOutput();
}
public void setMaxOutput(int maxOutput) {
this.maxOutput = maxOutput;
}
public int getMaxOutputOverride() {
return maxOutput;
}
@Override
public int receiveEnergy(ForgeDirection from, int maxReceive, boolean simulate) {
if(network == null) {
return 0;
}
IoMode mode = getIoMode(from);
if(mode == IoMode.DISABLED || mode == IoMode.PUSH) {
return 0;
}
return network.receiveEnergy(maxReceive, simulate);
}
// @Override
// public int extractEnergy(ForgeDirection from, int maxExtract, boolean simulate) {
// return 0;
// }
@Override
public int getMaxEnergyStored(ForgeDirection from) {
return getType().getMaxEnergyStored();
}
@Override
public boolean canConnectEnergy(ForgeDirection from) {
return getIoMode(from) != IoMode.DISABLED;
}
public int getComparatorOutput() {
double stored = getEnergyStored();
return stored == 0 ? 0 : (int) (1 + stored / getMaxEnergyStored() * 14);
}
@Override
public boolean displayPower() {
return true;
}
//------------------- Inventory
@Override
public boolean isUseableByPlayer(EntityPlayer player) {
return canPlayerAccess(player);
}
@Override
public ItemStack getStackInSlot(int slot) {
if(network == null) {
return null;
}
return network.getInventory().getStackInSlot(slot);
}
@Override
public ItemStack decrStackSize(int fromSlot, int amount) {
if(network == null) {
return null;
}
return network.getInventory().decrStackSize(fromSlot, amount);
}
@Override
public void setInventorySlotContents(int slot, ItemStack itemstack) {
if(network == null) {
return;
}
network.getInventory().setInventorySlotContents(slot, itemstack);
}
@Override
public ItemStack getStackInSlotOnClosing(int p_70304_1_) {
return null;
}
@Override
public int getSizeInventory() {
return 4;
}
@Override
public String getInventoryName() {
return EnderIO.blockCapacitorBank.getUnlocalizedName() + ".name";
}
@Override
public boolean hasCustomInventoryName() {
return false;
}
@Override
public int getInventoryStackLimit() {
return 1;
}
@Override
public void openInventory() {
}
@Override
public void closeInventory() {
}
@Override
public boolean isItemValidForSlot(int slot, ItemStack itemstack) {
if(itemstack == null) {
return false;
}
return itemstack.getItem() instanceof IEnergyContainerItem;
}
public ItemStack[] getInventory() {
return inventory;
}
public void dropItems() {
dropItems = true;
}
public void doDropItems() {
if(!dropItems) {
return;
}
Vector3d dropLocation;
EntityPlayer player = worldObj.getClosestPlayer(xCoord, yCoord, zCoord, 32);
if(player != null) {
dropLocation = EntityUtil.getEntityPosition(player);
} else {
dropLocation = new Vector3d(xCoord, yCoord, zCoord);
}
Util.dropItems(worldObj, inventory, (int) dropLocation.x, (int) dropLocation.y, (int) dropLocation.z, false);
for (int i = 0; i < inventory.length; i++) {
inventory[i] = null;
}
dropItems = false;
}
//---------------- NBT
@Override
protected void writeCustomNBT(NBTTagCompound nbtRoot) {
writeCommonNBT(nbtRoot);
}
//Values common to both item and block form
public void writeCommonNBT(NBTTagCompound nbtRoot) {
getType().writeTypeToNBT(nbtRoot);
nbtRoot.setInteger(PowerHandlerUtil.STORED_ENERGY_NBT_KEY, energyStored);
if(maxInput != -1) {
nbtRoot.setInteger("maxInput", maxInput);
}
if(maxOutput != -1) {
nbtRoot.setInteger("maxOutput", maxOutput);
}
if(inputControlMode != RedstoneControlMode.IGNORE) {
nbtRoot.setShort("inputControlMode", (short) inputControlMode.ordinal());
}
if(outputControlMode != RedstoneControlMode.IGNORE) {
nbtRoot.setShort("outputControlMode", (short) outputControlMode.ordinal());
}
//face modes
if(faceModes != null) {
nbtRoot.setByte("hasFaces", (byte) 1);
for (Entry<ForgeDirection, IoMode> e : faceModes.entrySet()) {
nbtRoot.setShort("face" + e.getKey().ordinal(), (short) e.getValue().ordinal());
}
}
//display type
if(faceDisplayTypes != null) {
nbtRoot.setByte("hasDisplayTypes", (byte) 1);
for (Entry<ForgeDirection, InfoDisplayType> e : faceDisplayTypes.entrySet()) {
if(e.getValue() != InfoDisplayType.NONE) {
nbtRoot.setShort("faceDisplay" + e.getKey().ordinal(), (short) e.getValue().ordinal());
}
}
}
boolean hasItems = false;
NBTTagList itemList = new NBTTagList();
for (int i = 0; i < inventory.length; i++) {
if(inventory[i] != null) {
hasItems = true;
NBTTagCompound itemStackNBT = new NBTTagCompound();
itemStackNBT.setByte("Slot", (byte) i);
inventory[i].writeToNBT(itemStackNBT);
itemList.appendTag(itemStackNBT);
}
}
if(hasItems) {
nbtRoot.setTag("Items", itemList);
}
}
@Override
protected void readCustomNBT(NBTTagCompound nbtRoot) {
readCommonNBT(nbtRoot);
}
//Values common to both item and block form
public void readCommonNBT(NBTTagCompound nbtRoot) {
type = CapBankType.readTypeFromNBT(nbtRoot);
energyStored = nbtRoot.getInteger(PowerHandlerUtil.STORED_ENERGY_NBT_KEY);
setEnergyStored(energyStored); //Call this to clamp values in case config changed
if(nbtRoot.hasKey("maxInput")) {
maxInput = nbtRoot.getInteger("maxInput");
} else {
maxInput = -1;
}
if(nbtRoot.hasKey("maxOutput")) {
maxOutput = nbtRoot.getInteger("maxOutput");
} else {
maxOutput = -1;
}
if(nbtRoot.hasKey("inputControlMode")) {
inputControlMode = RedstoneControlMode.values()[nbtRoot.getShort("inputControlMode")];
} else {
inputControlMode = RedstoneControlMode.IGNORE;
}
if(nbtRoot.hasKey("outputControlMode")) {
outputControlMode = RedstoneControlMode.values()[nbtRoot.getShort("outputControlMode")];
} else {
outputControlMode = RedstoneControlMode.IGNORE;
}
if(nbtRoot.hasKey("hasFaces")) {
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
String key = "face" + dir.ordinal();
if(nbtRoot.hasKey(key)) {
setIoMode(dir, IoMode.values()[nbtRoot.getShort(key)], false);
}
}
} else {
faceModes = null;
}
if(nbtRoot.hasKey("hasDisplayTypes")) {
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
String key = "faceDisplay" + dir.ordinal();
if(nbtRoot.hasKey(key)) {
setDisplayType(dir, InfoDisplayType.values()[nbtRoot.getShort(key)], false);
}
}
} else {
faceDisplayTypes = null;
}
for (int i = 0; i < inventory.length; i++) {
inventory[i] = null;
}
if(nbtRoot.hasKey("Items")) {
NBTTagList itemList = (NBTTagList) nbtRoot.getTag("Items");
for (int i = 0; i < itemList.tagCount(); i++) {
NBTTagCompound itemStack = itemList.getCompoundTagAt(i);
byte slot = itemStack.getByte("Slot");
if(slot >= 0 && slot < inventory.length) {
inventory[slot] = ItemStack.loadItemStackFromNBT(itemStack);
}
}
}
}
}