Revert "Removed modular battery in favor of new design"

This reverts commit e7cc2c07f3.
This commit is contained in:
Calclavia 2013-12-23 17:50:23 +08:00
parent bbf1ade144
commit 2d8af00e89
8 changed files with 1628 additions and 0 deletions

View file

@ -0,0 +1,39 @@
package resonantinduction.battery;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import universalelectricity.core.item.IElectricalItem;
public class BatteryManager
{
public static final int CELLS_PER_BATTERY = 16;
public static class SlotOut extends Slot
{
public SlotOut(IInventory inventory, int index, int x, int y)
{
super(inventory, index, x, y);
}
@Override
public boolean isItemValid(ItemStack itemstack)
{
return false;
}
}
public static class SlotBattery extends Slot
{
public SlotBattery(IInventory inventory, int index, int x, int y)
{
super(inventory, index, x, y);
}
@Override
public boolean isItemValid(ItemStack itemstack)
{
return itemstack.getItem() instanceof IElectricalItem;
}
}
}

View file

@ -0,0 +1,298 @@
package resonantinduction.battery;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
import resonantinduction.base.ListUtil;
import universalelectricity.api.vector.Vector3;
public class BatteryUpdateProtocol
{
/** The battery nodes that have already been iterated over. */
public Set<TileEntityBattery> iteratedNodes = new HashSet<TileEntityBattery>();
/** The structures found, all connected by some nodes to the pointer. */
public SynchronizedBatteryData structureFound = null;
/** The original block the calculation is getting run from. */
public TileEntity pointer;
public BatteryUpdateProtocol(TileEntity tileEntity)
{
pointer = tileEntity;
}
private void loopThrough(TileEntity tile)
{
if (structureFound == null)
{
World worldObj = tile.worldObj;
int origX = tile.xCoord, origY = tile.yCoord, origZ = tile.zCoord;
boolean isCorner = true;
boolean rightBlocks = true;
Set<Vector3> locations = new HashSet<Vector3>();
int xmin = 0, xmax = 0, ymin = 0, ymax = 0, zmin = 0, zmax = 0;
int x = 0, y = 0, z = 0;
if ((isBattery(origX + 1, origY, origZ) && isBattery(origX - 1, origY, origZ)) || (isBattery(origX, origY + 1, origZ) && isBattery(origX, origY - 1, origZ)) || (isBattery(origX, origY, origZ + 1) && isBattery(origX, origY, origZ - 1)))
{
isCorner = false;
}
if (isCorner)
{
if (isBattery(origX + 1, origY, origZ))
{
xmin = 0;
while (isBattery(origX + x + 1, origY, origZ))
{
x++;
}
xmax = x;
}
else
{
xmax = 0;
while (isBattery(origX + x - 1, origY, origZ))
{
x--;
}
xmin = x;
}
if (isBattery(origX, origY + 1, origZ))
{
ymin = 0;
while (isBattery(origX, origY + y + 1, origZ))
{
y++;
}
ymax = y;
}
else
{
ymax = 0;
while (isBattery(origX, origY + y - 1, origZ))
{
y--;
}
ymin = y;
}
if (isBattery(origX, origY, origZ + 1))
{
zmin = 0;
while (isBattery(origX, origY, origZ + z + 1))
{
z++;
}
zmax = z;
}
else
{
zmax = 0;
while (isBattery(origX, origY, origZ + z - 1))
{
z--;
}
zmin = z;
}
for (x = xmin; x <= xmax; x++)
{
for (y = ymin; y <= ymax; y++)
{
for (z = zmin; z <= zmax; z++)
{
if (!isBattery(origX + x, origY + y, origZ + z))
{
rightBlocks = false;
break;
}
else
{
locations.add(new Vector3(tile).translate(new Vector3(x, y, z)));
}
}
if (!rightBlocks)
{
break;
}
}
if (!rightBlocks)
{
break;
}
}
}
if (locations.size() >= 1 && locations.size() < 512)
{
if (rightBlocks && isCorner)
{
SynchronizedBatteryData structure = new SynchronizedBatteryData();
structure.locations = locations;
structure.length = Math.abs(xmax - xmin) + 1;
structure.height = Math.abs(ymax - ymin) + 1;
structure.width = Math.abs(zmax - zmin) + 1;
if (structure.getVolume() > 1)
{
structure.isMultiblock = true;
}
if (structure.locations.contains(new Vector3(pointer)))
{
structureFound = structure;
}
}
}
}
iteratedNodes.add((TileEntityBattery) tile);
for (ForgeDirection side : ForgeDirection.VALID_DIRECTIONS)
{
TileEntity tileEntity = new Vector3(tile).modifyPositionFromSide(side).getTileEntity(tile.worldObj);
if (tileEntity instanceof TileEntityBattery)
{
if (!iteratedNodes.contains(tileEntity))
{
loopThrough(tileEntity);
}
}
}
}
private boolean isBattery(int x, int y, int z)
{
if (pointer.worldObj.getBlockTileEntity(x, y, z) instanceof TileEntityBattery)
{
return true;
}
return false;
}
private void disperseCells()
{
SynchronizedBatteryData oldStructure = null;
for (TileEntityBattery tile : iteratedNodes)
{
if (tile.structure.isMultiblock)
{
oldStructure = tile.structure;
break;
}
}
if (oldStructure != null)
{
int maxCells = iteratedNodes.size() * BatteryManager.CELLS_PER_BATTERY;
List<ItemStack> rejected = ListUtil.capRemains(oldStructure.inventory, maxCells);
ejectItems(rejected, new Vector3(pointer));
ArrayList<List<ItemStack>> inventories = ListUtil.split(ListUtil.cap(oldStructure.inventory, maxCells), iteratedNodes.size());
List<TileEntityBattery> iterList = ListUtil.asList(iteratedNodes);
boolean didVisibleInventory = false;
for (int i = 0; i < iterList.size(); i++)
{
TileEntityBattery tile = iterList.get(i);
tile.structure = SynchronizedBatteryData.getBase(tile, inventories.get(i));
if (!didVisibleInventory)
{
tile.structure.visibleInventory = oldStructure.visibleInventory;
didVisibleInventory = true;
}
}
}
}
private void ejectItems(List<ItemStack> items, Vector3 vec)
{
for (ItemStack itemStack : items)
{
float motion = 0.7F;
double motionX = (pointer.worldObj.rand.nextFloat() * motion) + (1.0F - motion) * 0.5D;
double motionY = (pointer.worldObj.rand.nextFloat() * motion) + (1.0F - motion) * 0.5D;
double motionZ = (pointer.worldObj.rand.nextFloat() * motion) + (1.0F - motion) * 0.5D;
EntityItem entityItem = new EntityItem(pointer.worldObj, vec.x + motionX, vec.y + motionY, vec.z + motionZ, itemStack);
pointer.worldObj.spawnEntityInWorld(entityItem);
}
}
public void updateBatteries()
{
loopThrough(pointer);
if (structureFound != null)
{
for (TileEntityBattery tileEntity : iteratedNodes)
{
if (!structureFound.locations.contains(new Vector3(tileEntity)))
{
disperseCells();
return;
}
}
for (Vector3 obj : structureFound.locations)
{
TileEntityBattery tileEntity = (TileEntityBattery) obj.getTileEntity(pointer.worldObj);
structureFound.inventory = ListUtil.merge(structureFound.inventory, tileEntity.structure.inventory);
if (tileEntity.structure.hasVisibleInventory())
{
structureFound.visibleInventory = tileEntity.structure.visibleInventory;
}
tileEntity.structure = structureFound;
}
List<ItemStack> rejected = ListUtil.capRemains(structureFound.inventory, structureFound.getMaxCells());
ejectItems(rejected, new Vector3(pointer));
structureFound.inventory = ListUtil.cap(structureFound.inventory, structureFound.getMaxCells());
}
else
{
disperseCells();
}
}
}

View file

@ -0,0 +1,225 @@
/**
*
*/
package resonantinduction.battery;
import net.minecraft.block.ITileEntityProvider;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
import resonantinduction.ResonantInduction;
import resonantinduction.api.ICapacitor;
import resonantinduction.base.BlockBase;
import resonantinduction.base.ListUtil;
import resonantinduction.render.BlockRenderingHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
/**
* A block that detects power.
*
* @author Calclavia
*
*/
public class BlockBattery extends BlockBase implements ITileEntityProvider
{
public BlockBattery(int id)
{
super("battery", id);
this.setTextureName(ResonantInduction.PREFIX + "machine");
}
@Override
public void onBlockClicked(World world, int x, int y, int z, EntityPlayer entityPlayer)
{
if (!world.isRemote)
{
if (!entityPlayer.capabilities.isCreativeMode)
{
TileEntityBattery tileEntity = (TileEntityBattery) world.getBlockTileEntity(x, y, z);
ItemStack itemStack = ListUtil.getTop(tileEntity.structure.inventory);
if (tileEntity.structure.inventory.remove(itemStack))
{
entityPlayer.dropPlayerItem(itemStack);
tileEntity.updateAllClients();
}
}
}
}
@Override
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer entityPlayer, int side, float xClick, float yClick, float zClick)
{
TileEntityBattery tileEntity = (TileEntityBattery) world.getBlockTileEntity(x, y, z);
if (entityPlayer.isSneaking())
{
boolean result = tileEntity.toggleSide(ForgeDirection.getOrientation(side));
if (!world.isRemote)
{
entityPlayer.addChatMessage("Toggled side to: " + (result ? "input" : "output"));
}
return true;
}
else
{
if (entityPlayer.getCurrentEquippedItem() != null)
{
if (entityPlayer.getCurrentEquippedItem().getItem() instanceof ICapacitor)
{
if (side != 0 && side != 1)
{
if (!world.isRemote)
{
if (tileEntity.structure.addCell(entityPlayer.getCurrentEquippedItem()))
{
entityPlayer.inventory.setInventorySlotContents(entityPlayer.inventory.currentItem, null);
tileEntity.updateAllClients();
}
}
/**
* Place cells into block. 2 Dimensional Click Zone.
*
* TODO: In the future.
*/
float xHit = 0;
float yHit = yClick;
if (side == 2 || side == 3)
{
xHit = xClick;
if (side == 2)
{
xHit = 1 - xHit;
}
}
else if (side == 4 || side == 5)
{
xHit = zClick;
if (side == 5)
{
xHit = 1 - xHit;
}
}
// Convert to quadrant coords.
xHit -= 0.5f;
yHit -= 0.5f;
// Quadrant 1
if (xHit > 0 && yHit > 0)
{
}// Quadrant 2
if (xHit > 0 && yHit < 0)
{
}// Quadrant 3
if (xHit < 0 && yHit < 0)
{
}// Quadrant 4
if (xHit < 0 && yHit > 0)
{
}
return true;
}
}
}
}
if (!world.isRemote)
{
entityPlayer.openGui(ResonantInduction.INSTANCE, 0, world, x, y, z);
}
return true;
}
@Override
public void onNeighborBlockChange(World world, int x, int y, int z, int id)
{
if (!world.isRemote)
{
if (id == blockID)
{
TileEntityBattery battery = (TileEntityBattery) world.getBlockTileEntity(x, y, z);
battery.update();
}
}
}
@Override
public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase entityliving, ItemStack itemstack)
{
if (!world.isRemote)
{
TileEntityBattery battery = (TileEntityBattery) world.getBlockTileEntity(x, y, z);
battery.update();
}
}
@Override
public boolean renderAsNormalBlock()
{
return false;
}
@Override
public boolean isOpaqueCube()
{
return false;
}
@Override
public boolean removeBlockByPlayer(World world, EntityPlayer player, int x, int y, int z)
{
if (!world.isRemote && canHarvestBlock(player, world.getBlockMetadata(x, y, z)))
{
TileEntityBattery tileEntity = (TileEntityBattery) world.getBlockTileEntity(x, y, z);
if (!tileEntity.structure.isMultiblock)
{
for (ItemStack itemStack : tileEntity.structure.inventory)
{
float motion = 0.7F;
double motionX = (world.rand.nextFloat() * motion) + (1.0F - motion) * 0.5D;
double motionY = (world.rand.nextFloat() * motion) + (1.0F - motion) * 0.5D;
double motionZ = (world.rand.nextFloat() * motion) + (1.0F - motion) * 0.5D;
EntityItem entityItem = new EntityItem(world, x + motionX, y + motionY, z + motionZ, itemStack);
world.spawnEntityInWorld(entityItem);
}
}
}
return super.removeBlockByPlayer(world, player, x, y, z);
}
@Override
@SideOnly(Side.CLIENT)
public int getRenderType()
{
return BlockRenderingHandler.INSTANCE.getRenderId();
}
@Override
public TileEntity createNewTileEntity(World world)
{
return new TileEntityBattery();
}
}

View file

@ -0,0 +1,87 @@
package resonantinduction.battery;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.ICrafting;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import resonantinduction.battery.BatteryManager.SlotBattery;
import resonantinduction.battery.BatteryManager.SlotOut;
import calclavia.lib.gui.ContainerBase;
public class ContainerBattery extends ContainerBase
{
private TileEntityBattery tileEntity;
public ContainerBattery(InventoryPlayer inventory, TileEntityBattery unit)
{
super(unit);
tileEntity = unit;
addSlotToContainer(new SlotBattery(unit, 0, 8, 22));
addSlotToContainer(new SlotOut(unit, 1, 8, 58));
addSlotToContainer(new SlotBattery(unit, 2, 31, 22));
addSlotToContainer(new SlotBattery(unit, 3, 31, 58));
int slotX;
for (slotX = 0; slotX < 3; ++slotX)
{
for (int slotY = 0; slotY < 9; ++slotY)
{
addSlotToContainer(new Slot(inventory, slotY + slotX * 9 + 9, 8 + slotY * 18, 125 + slotX * 18));
}
}
for (slotX = 0; slotX < 9; ++slotX)
{
addSlotToContainer(new Slot(inventory, slotX, 8 + slotX * 18, 183));
}
tileEntity.openChest();
tileEntity.playersUsing.add(inventory.player);
}
@Override
public ItemStack slotClick(int slotID, int par2, int par3, EntityPlayer par4EntityPlayer)
{
ItemStack stack = super.slotClick(slotID, par2, par3, par4EntityPlayer);
if (slotID == 1)
{
ItemStack itemstack = ((Slot) inventorySlots.get(slotID)).getStack();
ItemStack itemstack1 = itemstack == null ? null : itemstack.copy();
inventoryItemStacks.set(slotID, itemstack1);
for (int j = 0; j < crafters.size(); ++j)
{
((ICrafting) crafters.get(j)).sendSlotContents(this, slotID, itemstack1);
}
}
return stack;
}
@Override
public void onContainerClosed(EntityPlayer entityplayer)
{
super.onContainerClosed(entityplayer);
tileEntity.closeChest();
tileEntity.playersUsing.remove(entityplayer);
}
@Override
public boolean canInteractWith(EntityPlayer entityplayer)
{
return tileEntity.isUseableByPlayer(entityplayer);
}
@Override
public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int slotID)
{
if (slotID != 1)
{
return super.transferStackInSlot(par1EntityPlayer, slotID);
}
return null;
}
}

View file

@ -0,0 +1,43 @@
/**
*
*/
package resonantinduction.battery;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.Configuration;
import resonantinduction.ResonantInduction;
import resonantinduction.TabRI;
import resonantinduction.api.ICapacitor;
import universalelectricity.compatibility.ItemUniversalElectric;
/**
* Stores power.
*
* @author Calclavia
*
*/
public class ItemCapacitor extends ItemUniversalElectric implements ICapacitor
{
public ItemCapacitor(int id)
{
super(ResonantInduction.CONFIGURATION.get(Configuration.CATEGORY_ITEM, "capacitor", id).getInt(id));
this.setCreativeTab(TabRI.INSTANCE);
this.setUnlocalizedName(ResonantInduction.PREFIX + "capacitor");
this.setTextureName(ResonantInduction.PREFIX + "capacitor");
this.setMaxStackSize(1);
this.setMaxDamage(100);
}
@Override
public float getTransfer(ItemStack itemStack)
{
return this.getMaxEnergyStored(itemStack) * 0.05F;
}
@Override
public float getElectricityCapacity(ItemStack theItem)
{
return 500;
}
}

View file

@ -0,0 +1,81 @@
/**
*
*/
package resonantinduction.battery;
import java.util.List;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.Configuration;
import resonantinduction.ResonantInduction;
import resonantinduction.TabRI;
import universalelectricity.compatibility.ItemUniversalElectric;
/**
* Stores power.
*
* @author Calclavia
*
*/
public class ItemInfiniteCapacitor extends ItemUniversalElectric
{
public ItemInfiniteCapacitor(int id)
{
super(ResonantInduction.CONFIGURATION.get(Configuration.CATEGORY_ITEM, "infiniteCapacitor", id).getInt(id));
this.setCreativeTab(TabRI.INSTANCE);
this.setUnlocalizedName(ResonantInduction.PREFIX + "infiniteCapacitor");
this.setTextureName(ResonantInduction.PREFIX + "capacitor");
this.setMaxStackSize(1);
this.setMaxDamage(100);
}
@Override
public void addInformation(ItemStack itemStack, EntityPlayer entityPlayer, List list, boolean par4)
{
list.add("Infinite");
}
@Override
public float recharge(ItemStack itemStack, float energy, boolean doReceive)
{
return energy;
}
@Override
public float discharge(ItemStack itemStack, float energy, boolean doTransfer)
{
return energy;
}
@Override
public void setElectricity(ItemStack itemStack, float joules)
{
}
@Override
public float getTransfer(ItemStack itemStack)
{
return Float.POSITIVE_INFINITY;
}
@Override
public float getElectricityStored(ItemStack itemStack)
{
return Float.POSITIVE_INFINITY;
}
@Override
public float getElectricityCapacity(ItemStack theItem)
{
return Float.POSITIVE_INFINITY;
}
@Override
public void getSubItems(int par1, CreativeTabs par2CreativeTabs, List par3List)
{
par3List.add(new ItemStack(this));
}
}

View file

@ -0,0 +1,163 @@
package resonantinduction.battery;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import net.minecraft.item.ItemStack;
import resonantinduction.base.ListUtil;
import universalelectricity.api.vector.Vector3;
import universalelectricity.core.item.IElectricalItem;
public class SynchronizedBatteryData
{
public Set<Vector3> locations = new HashSet<Vector3>();
public List<ItemStack> inventory = new ArrayList<ItemStack>();
/**
* Slot 0: Cell input slot Slot 1: Battery charge slot Slot 2: Battery discharge slot
*/
public ItemStack[] visibleInventory = new ItemStack[3];
public int length;
public int width;
public int height;
public ItemStack tempStack;
public boolean isMultiblock;
public boolean didTick;
public boolean wroteInventory;
public int getVolume()
{
return length * width * height;
}
public int getMaxCells()
{
return getVolume() * BatteryManager.CELLS_PER_BATTERY;
}
public boolean addCell(ItemStack cell)
{
if (this.inventory.size() < this.getMaxCells())
{
this.inventory.add(cell);
this.sortInventory();
return true;
}
return false;
}
public void sortInventory()
{
Object[] array = ListUtil.copy(inventory).toArray();
ItemStack[] toSort = new ItemStack[array.length];
for (int i = 0; i < array.length; i++)
{
toSort[i] = (ItemStack) array[i];
}
boolean cont = true;
ItemStack temp;
while (cont)
{
cont = false;
for (int i = 0; i < toSort.length - 1; i++)
{
if (((IElectricalItem) toSort[i].getItem()).getElectricityStored(toSort[i]) < ((IElectricalItem) toSort[i + 1].getItem()).getElectricityStored(toSort[i + 1]))
{
temp = toSort[i];
toSort[i] = toSort[i + 1];
toSort[i + 1] = temp;
cont = true;
}
}
}
inventory = new ArrayList<ItemStack>();
for (ItemStack itemStack : toSort)
{
inventory.add(itemStack);
}
}
public boolean hasVisibleInventory()
{
for (ItemStack itemStack : visibleInventory)
{
if (itemStack != null)
{
return true;
}
}
return false;
}
public static SynchronizedBatteryData getBase(TileEntityBattery tileEntity, List<ItemStack> inventory)
{
SynchronizedBatteryData structure = getBase(tileEntity);
structure.inventory = inventory;
return structure;
}
public static SynchronizedBatteryData getBase(TileEntityBattery tileEntity)
{
SynchronizedBatteryData structure = new SynchronizedBatteryData();
structure.length = 1;
structure.width = 1;
structure.height = 1;
structure.locations.add(new Vector3(tileEntity));
return structure;
}
@Override
public int hashCode()
{
int code = 1;
code = 31 * locations.hashCode();
code = 31 * length;
code = 31 * width;
code = 31 * height;
return code;
}
@Override
public boolean equals(Object obj)
{
if (!(obj instanceof SynchronizedBatteryData))
{
return false;
}
SynchronizedBatteryData data = (SynchronizedBatteryData) obj;
if (!data.locations.equals(locations))
{
return false;
}
if (data.length != length || data.width != width || data.height != height)
{
return false;
}
return true;
}
}

View file

@ -0,0 +1,692 @@
/**
*
*/
package resonantinduction.battery;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityItem;
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.util.AxisAlignedBB;
import net.minecraftforge.common.ForgeDirection;
import resonantinduction.ResonantInduction;
import resonantinduction.api.ICapacitor;
import resonantinduction.base.ListUtil;
import universalelectricity.api.electricity.ElectricityPack;
import universalelectricity.api.vector.Vector3;
import universalelectricity.core.item.IElectricalItem;
import calclavia.lib.network.IPacketReceiver;
import calclavia.lib.network.IPacketSender;
import calclavia.lib.tile.TileEntityElectrical;
import com.google.common.io.ByteArrayDataInput;
import cpw.mods.fml.common.network.PacketDispatcher;
import cpw.mods.fml.common.network.Player;
/**
* A modular battery with no GUI.
*
* @author AidanBrady
*/
public class TileEntityBattery extends TileEntityElectrical implements IPacketSender, IPacketReceiver, IInventory
{
public Set<EntityPlayer> playersUsing = new HashSet<EntityPlayer>();
public SynchronizedBatteryData structure = SynchronizedBatteryData.getBase(this);
public SynchronizedBatteryData prevStructure;
public float clientEnergy;
public int clientCells;
public float clientMaxEnergy;
private EnumSet inputSides = EnumSet.allOf(ForgeDirection.class);
@Override
public void updateEntity()
{
super.updateEntity();
if (!this.worldObj.isRemote)
{
if (this.ticks == 5 && !this.structure.isMultiblock)
{
this.update();
}
if (this.structure.visibleInventory[0] != null)
{
if (structure.inventory.size() < structure.getMaxCells())
{
if (structure.visibleInventory[0].getItem() instanceof ICapacitor)
{
structure.inventory.add(structure.visibleInventory[0]);
structure.visibleInventory[0] = null;
structure.sortInventory();
updateAllClients();
}
}
}
/**
* Attempt to charge entities above it.
*/
ItemStack chargeItem = null;
if (this.worldObj.isBlockIndirectlyGettingPowered(this.xCoord, this.yCoord, this.zCoord))
{
List<Entity> entities = this.worldObj.getEntitiesWithinAABB(Entity.class, AxisAlignedBB.getBoundingBox(this.xCoord, this.yCoord + 1, this.zCoord, this.xCoord + 1, this.yCoord + 2, this.zCoord + 1));
electricItemLoop:
for (Entity entity : entities)
{
if (entity instanceof EntityPlayer)
{
IInventory inventory = ((EntityPlayer) entity).inventory;
for (int i = 0; i < inventory.getSizeInventory(); i++)
{
ItemStack checkStack = inventory.getStackInSlot(i);
if (checkStack != null)
{
if (checkStack.getItem() instanceof IElectricalItem)
{
if (((IElectricalItem) checkStack.getItem()).recharge(checkStack, provideElectricity(this.getTransferThreshhold(), false).getWatts(), false) > 0)
{
chargeItem = checkStack;
break electricItemLoop;
}
}
}
}
}
else if (entity instanceof EntityItem)
{
ItemStack checkStack = ((EntityItem) entity).getEntityItem();
if (checkStack != null)
{
if (checkStack.getItem() instanceof IElectricalItem)
{
if (((IElectricalItem) checkStack.getItem()).recharge(checkStack, provideElectricity(this.getTransferThreshhold(), false).getWatts(), false) > 0)
{
chargeItem = checkStack;
break electricItemLoop;
}
}
}
}
}
}
if (chargeItem == null)
{
chargeItem = this.structure.visibleInventory[1];
}
if (chargeItem != null)
{
ItemStack itemStack = chargeItem;
IElectricalItem battery = (IElectricalItem) itemStack.getItem();
float energyStored = getMaxEnergyStored();
float batteryNeeded = battery.recharge(itemStack, provideElectricity(this.getTransferThreshhold(), false).getWatts(), false);
float toGive = Math.min(energyStored, Math.min(battery.getTransfer(itemStack), batteryNeeded));
battery.recharge(itemStack, provideElectricity(toGive, true).getWatts(), true);
}
if (structure.visibleInventory[2] != null)
{
ItemStack itemStack = structure.visibleInventory[2];
IElectricalItem battery = (IElectricalItem) itemStack.getItem();
float energyNeeded = getMaxEnergyStored() - getEnergyStored();
float batteryStored = battery.getElectricityStored(itemStack);
float toReceive = Math.min(energyNeeded, Math.min(this.getTransferThreshhold(), Math.min(battery.getTransfer(itemStack), batteryStored)));
battery.discharge(itemStack, receiveElectricity(toReceive, true), true);
}
if (prevStructure != structure)
{
for (EntityPlayer player : playersUsing)
{
player.closeScreen();
}
updateClient();
}
this.prevStructure = structure;
this.structure.wroteInventory = false;
this.structure.didTick = false;
if (this.playersUsing.size() > 0)
{
updateClient();
}
for (EntityPlayer player : this.playersUsing)
{
PacketDispatcher.sendPacketToPlayer(ResonantInduction.PACKET_TILE.getPacket(this, this.getPacketData(0).toArray()), (Player) player);
}
this.produce();
}
}
public float getTransferThreshhold()
{
return this.structure.getVolume() * 50;
}
public void updateClient()
{
PacketDispatcher.sendPacketToAllPlayers(ResonantInduction.PACKET_TILE.getPacket(this, getPacketData(0).toArray()));
}
public void updateAllClients()
{
for (Vector3 vec : structure.locations)
{
TileEntityBattery battery = (TileEntityBattery) vec.getTileEntity(worldObj);
PacketDispatcher.sendPacketToAllPlayers(ResonantInduction.PACKET_TILE.getPacket(battery, battery.getPacketData(0).toArray()));
}
}
@Override
public void readFromNBT(NBTTagCompound nbtTags)
{
super.readFromNBT(nbtTags);
// Main inventory
if (nbtTags.hasKey("Items"))
{
NBTTagList tagList = nbtTags.getTagList("Items");
structure.inventory = new ArrayList<ItemStack>();
for (int tagCount = 0; tagCount < tagList.tagCount(); tagCount++)
{
NBTTagCompound tagCompound = (NBTTagCompound) tagList.tagAt(tagCount);
int slotID = tagCompound.getInteger("Slot");
structure.inventory.add(slotID, ItemStack.loadItemStackFromNBT(tagCompound));
}
}
// Visible inventory
if (nbtTags.hasKey("VisibleItems"))
{
NBTTagList tagList = nbtTags.getTagList("VisibleItems");
structure.visibleInventory = new ItemStack[3];
for (int tagCount = 0; tagCount < tagList.tagCount(); tagCount++)
{
NBTTagCompound tagCompound = (NBTTagCompound) tagList.tagAt(tagCount);
byte slotID = tagCompound.getByte("Slot");
if (slotID >= 0 && slotID < structure.visibleInventory.length)
{
if (slotID == 0)
{
setInventorySlotContents(slotID, ItemStack.loadItemStackFromNBT(tagCompound));
}
else
{
setInventorySlotContents(slotID + 1, ItemStack.loadItemStackFromNBT(tagCompound));
}
}
}
}
this.inputSides = EnumSet.noneOf(ForgeDirection.class);
NBTTagList tagList = nbtTags.getTagList("inputSides");
for (int tagCount = 0; tagCount < tagList.tagCount(); tagCount++)
{
NBTTagCompound tagCompound = (NBTTagCompound) tagList.tagAt(tagCount);
byte side = tagCompound.getByte("side");
this.inputSides.add(ForgeDirection.getOrientation(side));
}
this.inputSides.remove(ForgeDirection.UNKNOWN);
}
@Override
public void writeToNBT(NBTTagCompound nbt)
{
super.writeToNBT(nbt);
if (!structure.wroteInventory)
{
// Inventory
if (structure.inventory != null)
{
NBTTagList tagList = new NBTTagList();
for (int slotCount = 0; slotCount < structure.inventory.size(); slotCount++)
{
if (structure.inventory.get(slotCount) != null)
{
NBTTagCompound tagCompound = new NBTTagCompound();
tagCompound.setInteger("Slot", slotCount);
structure.inventory.get(slotCount).writeToNBT(tagCompound);
tagList.appendTag(tagCompound);
}
}
nbt.setTag("Items", tagList);
}
// Visible inventory
if (structure.visibleInventory != null)
{
NBTTagList tagList = new NBTTagList();
for (int slotCount = 0; slotCount < structure.visibleInventory.length; slotCount++)
{
if (slotCount > 0)
{
slotCount++;
}
if (getStackInSlot(slotCount) != null)
{
NBTTagCompound tagCompound = new NBTTagCompound();
tagCompound.setByte("Slot", (byte) slotCount);
getStackInSlot(slotCount).writeToNBT(tagCompound);
tagList.appendTag(tagCompound);
}
}
nbt.setTag("VisibleItems", tagList);
}
structure.wroteInventory = true;
/**
* Save the input sides.
*/
NBTTagList tagList = new NBTTagList();
Iterator<ForgeDirection> it = this.inputSides.iterator();
while (it.hasNext())
{
ForgeDirection dir = it.next();
if (dir != ForgeDirection.UNKNOWN)
{
NBTTagCompound tagCompound = new NBTTagCompound();
tagCompound.setByte("side", (byte) dir.ordinal());
tagList.appendTag(tagCompound);
}
}
nbt.setTag("inputSides", tagList);
}
}
public void update()
{
if (!worldObj.isRemote && (structure == null || !structure.didTick))
{
new BatteryUpdateProtocol(this).updateBatteries();
if (structure != null)
{
structure.didTick = true;
}
}
}
@Override
public float receiveElectricity(ElectricityPack receive, boolean doAdd)
{
float amount = receive.getWatts();
float added = 0;
for (ItemStack itemStack : structure.inventory)
{
if (itemStack.getItem() instanceof IElectricalItem)
{
IElectricalItem battery = (IElectricalItem) itemStack.getItem();
float needed = amount - added;
float itemAdd = Math.min(battery.getElectricityCapacity(itemStack) - battery.getElectricityStored(itemStack), needed);
if (doAdd)
{
battery.setElectricity(itemStack, battery.getElectricityStored(itemStack) + itemAdd);
}
added += itemAdd;
if (amount == added)
{
break;
}
}
}
return added;
}
@Override
public ElectricityPack provideElectricity(ElectricityPack pack, boolean doRemove)
{
float amount = pack.getWatts();
List<ItemStack> inverse = ListUtil.inverse(structure.inventory);
float removed = 0;
for (ItemStack itemStack : inverse)
{
if (itemStack.getItem() instanceof IElectricalItem)
{
IElectricalItem battery = (IElectricalItem) itemStack.getItem();
float needed = amount - removed;
float itemRemove = Math.min(battery.getElectricityStored(itemStack), needed);
if (doRemove)
{
battery.setElectricity(itemStack, battery.getElectricityStored(itemStack) - itemRemove);
}
removed += itemRemove;
if (amount == removed)
{
break;
}
}
}
return ElectricityPack.getFromWatts(removed, this.getVoltage());
}
@Override
public float getMaxEnergyStored()
{
if (!this.worldObj.isRemote)
{
float max = 0;
for (ItemStack itemStack : this.structure.inventory)
{
if (itemStack != null)
{
if (itemStack.getItem() instanceof IElectricalItem)
{
max += ((IElectricalItem) itemStack.getItem()).getElectricityCapacity(itemStack);
}
}
}
return max;
}
else
{
return this.clientMaxEnergy;
}
}
@Override
public float getEnergyStored()
{
if (!this.worldObj.isRemote)
{
float energy = 0;
for (ItemStack itemStack : this.structure.inventory)
{
if (itemStack != null)
{
if (itemStack.getItem() instanceof IElectricalItem)
{
energy += ((IElectricalItem) itemStack.getItem()).getElectricityStored(itemStack);
}
}
}
return energy;
}
else
{
return clientEnergy;
}
}
@Override
public void onReceivePacket(ByteArrayDataInput data, EntityPlayer player)
{
structure.isMultiblock = data.readBoolean();
clientEnergy = data.readFloat();
clientCells = data.readInt();
clientMaxEnergy = data.readFloat();
structure.height = data.readInt();
structure.length = data.readInt();
structure.width = data.readInt();
}
@Override
public ArrayList getPacketData(int type)
{
ArrayList data = new ArrayList();
data.add(structure.isMultiblock);
data.add(getEnergyStored());
data.add(structure.inventory.size());
data.add(getMaxEnergyStored());
data.add(structure.height);
data.add(structure.length);
data.add(structure.width);
return data;
}
@Override
public int getSizeInventory()
{
return 4;
}
@Override
public ItemStack getStackInSlot(int i)
{
if (i == 0)
{
return structure.visibleInventory[0];
}
else if (i == 1)
{
if (!worldObj.isRemote)
{
return ListUtil.getTop(structure.inventory);
}
else
{
return structure.tempStack;
}
}
else
{
return structure.visibleInventory[i - 1];
}
}
@Override
public ItemStack decrStackSize(int slotID, int amount)
{
if (getStackInSlot(slotID) != null)
{
ItemStack tempStack;
if (getStackInSlot(slotID).stackSize <= amount)
{
tempStack = getStackInSlot(slotID);
setInventorySlotContents(slotID, null);
return tempStack;
}
else
{
tempStack = getStackInSlot(slotID).splitStack(amount);
if (getStackInSlot(slotID).stackSize == 0)
{
setInventorySlotContents(slotID, null);
}
return tempStack;
}
}
else
{
return null;
}
}
@Override
public ItemStack getStackInSlotOnClosing(int i)
{
return getStackInSlot(i);
}
@Override
public void setInventorySlotContents(int i, ItemStack itemstack)
{
if (i == 0)
{
structure.visibleInventory[0] = itemstack;
}
else if (i == 1)
{
if (itemstack == null)
{
if (!worldObj.isRemote)
{
structure.inventory.remove(ListUtil.getTop(structure.inventory));
}
else
{
structure.tempStack = null;
}
}
else
{
if (worldObj.isRemote)
{
structure.tempStack = itemstack;
}
}
}
else
{
structure.visibleInventory[i - 1] = itemstack;
}
}
@Override
public String getInvName()
{
return "Battery";
}
@Override
public boolean isInvNameLocalized()
{
return false;
}
@Override
public int getInventoryStackLimit()
{
return 64;
}
@Override
public boolean isUseableByPlayer(EntityPlayer entityplayer)
{
return true;
}
@Override
public void openChest()
{
}
@Override
public void closeChest()
{
}
@Override
public boolean isItemValidForSlot(int i, ItemStack itemsSack)
{
return itemsSack.getItem() instanceof IElectricalItem;
}
@Override
public float getRequest(ForgeDirection direction)
{
if (this.getInputDirections().contains(direction))
{
return Math.min(this.getMaxEnergyStored() - this.getEnergyStored(), this.getTransferThreshhold());
}
return 0;
}
@Override
public float getProvide(ForgeDirection direction)
{
if (this.getOutputDirections().contains(direction))
{
return Math.min(this.getEnergyStored(), this.getTransferThreshhold());
}
return 0;
}
@Override
public EnumSet<ForgeDirection> getInputDirections()
{
return this.inputSides;
}
@Override
public EnumSet<ForgeDirection> getOutputDirections()
{
return EnumSet.complementOf(this.inputSides);
}
/**
* Toggles the input/output sides of the battery.
*/
public boolean toggleSide(ForgeDirection orientation)
{
if (this.inputSides.contains(orientation))
{
this.inputSides.remove(orientation);
return false;
}
else
{
this.inputSides.add(orientation);
return true;
}
}
}