summaryrefslogtreecommitdiff
path: root/src/main/java/ihl/flexible_cable
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/ihl/flexible_cable')
-rw-r--r--src/main/java/ihl/flexible_cable/AnchorBlock.java111
-rw-r--r--src/main/java/ihl/flexible_cable/AnchorTileEntity.java342
-rw-r--r--src/main/java/ihl/flexible_cable/BatterySwitchUnitModel.java48
-rw-r--r--src/main/java/ihl/flexible_cable/BatterySwitchUnitTileEntity.java295
-rw-r--r--src/main/java/ihl/flexible_cable/BlastEntityFX.java68
-rw-r--r--src/main/java/ihl/flexible_cable/FlexibleCableHolderBaseTileEntity.java237
-rw-r--r--src/main/java/ihl/flexible_cable/IHLCable.java111
-rw-r--r--src/main/java/ihl/flexible_cable/IHLENet.java168
-rw-r--r--src/main/java/ihl/flexible_cable/IHLGrid.java291
-rw-r--r--src/main/java/ihl/flexible_cable/InvSlotOutputInProgress.java93
-rw-r--r--src/main/java/ihl/flexible_cable/InvSlotProcessableIronWorkbench.java131
-rw-r--r--src/main/java/ihl/flexible_cable/InvSlotTool.java69
-rw-r--r--src/main/java/ihl/flexible_cable/InvSlotWorkspaceElement.java184
-rw-r--r--src/main/java/ihl/flexible_cable/IronWorkbenchContainer.java131
-rw-r--r--src/main/java/ihl/flexible_cable/IronWorkbenchGui.java185
-rw-r--r--src/main/java/ihl/flexible_cable/IronWorkbenchInvSlot.java30
-rw-r--r--src/main/java/ihl/flexible_cable/IronWorkbenchModel.java48
-rw-r--r--src/main/java/ihl/flexible_cable/IronWorkbenchRender.java36
-rw-r--r--src/main/java/ihl/flexible_cable/IronWorkbenchTileEntity.java351
-rw-r--r--src/main/java/ihl/flexible_cable/NodeEntity.java604
-rw-r--r--src/main/java/ihl/flexible_cable/NodeRender.java76
-rw-r--r--src/main/java/ihl/flexible_cable/PowerCableNodeEntity.java243
-rw-r--r--src/main/java/ihl/flexible_cable/RectifierTransformerUnitTileEntity.java336
-rw-r--r--src/main/java/ihl/flexible_cable/SetOfDiesMiniGUI.java81
-rw-r--r--src/main/java/ihl/flexible_cable/SubAnchorEnergyNetNode.java346
-rw-r--r--src/main/java/ihl/flexible_cable/SubRTUEnergyNetNode.java320
26 files changed, 4935 insertions, 0 deletions
diff --git a/src/main/java/ihl/flexible_cable/AnchorBlock.java b/src/main/java/ihl/flexible_cable/AnchorBlock.java
new file mode 100644
index 0000000..207173e
--- /dev/null
+++ b/src/main/java/ihl/flexible_cable/AnchorBlock.java
@@ -0,0 +1,111 @@
+package ihl.flexible_cable;
+
+import cpw.mods.fml.common.registry.GameRegistry;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import ihl.IHLModInfo;
+import net.minecraft.block.Block;
+import net.minecraft.block.ITileEntityProvider;
+import net.minecraft.block.material.Material;
+import net.minecraft.client.renderer.texture.IIconRegister;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.AxisAlignedBB;
+import net.minecraft.world.IBlockAccess;
+import net.minecraft.world.World;
+
+public class AnchorBlock extends Block implements ITileEntityProvider {
+
+ public AnchorBlock(String unlocalizedName1) {
+ super(Material.circuits);
+ this.setBlockName(unlocalizedName1);
+ GameRegistry.registerBlock(this, unlocalizedName1);
+ }
+
+ @Override
+ public boolean hasTileEntity(int metadata) {
+ return true;
+ }
+
+ @Override
+ public void onBlockPreDestroy(World world, int x, int y, int z, int meta) {
+ if (!world.isRemote) {
+ TileEntity te = world.getTileEntity(x, y, z);
+ if (te != null && te instanceof AnchorTileEntity) {
+ AnchorTileEntity ate = (AnchorTileEntity) te;
+ ate.invalidate();
+ for (short i = 0; i < 6; i++) {
+ ate.energyNetNodes[i].removeAttachedChains();
+ }
+ }
+ }
+ super.onBlockPreDestroy(world, x, y, z, meta);
+ }
+
+ @Override
+ public TileEntity createNewTileEntity(World arg0, int arg1) {
+ return new AnchorTileEntity();
+ }
+
+ @Override
+ public void dropBlockAsItemWithChance(World world, int x, int y, int z, int meta, float chance, int flag) {
+ }
+
+ @Override
+ public AxisAlignedBB getCollisionBoundingBoxFromPool(World p_149668_1_, int p_149668_2_, int p_149668_3_,
+ int p_149668_4_) {
+ return null;
+ }
+
+ @Override
+ public boolean isOpaqueCube() {
+ return false;
+ }
+
+ @Override
+ public boolean renderAsNormalBlock() {
+ return false;
+ }
+
+ @Override
+ public int getRenderType() {
+ return -2;
+ }
+
+ @Override
+ @SideOnly(Side.CLIENT)
+ public void registerBlockIcons(IIconRegister par1IconRegister) {
+ this.blockIcon = par1IconRegister.registerIcon(IHLModInfo.MODID + ":junctionBox");
+ }
+
+ @Override
+ public void setBlockBoundsBasedOnState(IBlockAccess iBlockAccess, int x, int y, int z) {
+ TileEntity te = iBlockAccess.getTileEntity(x, y, z);
+ if (te != null && te instanceof AnchorTileEntity) {
+ AnchorTileEntity ate = (AnchorTileEntity) te;
+ float portSize = 0.1f;
+ float bbMinX = 1f;
+ float bbMaxX = 0f;
+ float bbMinY = 1f;
+ float bbMaxY = 0f;
+ float bbMinZ = 1f;
+ float bbMaxZ = 0f;
+ for (short i = 0; i < 6; i++) {
+ if (ate.hasCableOnSide[i]) {
+ float pMinX = (float) (ate.energyNetNodes[i].getPortPos(null)[0] - portSize - x);
+ float pMaxX = (float) (ate.energyNetNodes[i].getPortPos(null)[0] + portSize - x);
+ float pMinY = (float) (ate.energyNetNodes[i].getPortPos(null)[1] - portSize - y);
+ float pMaxY = (float) (ate.energyNetNodes[i].getPortPos(null)[1] + portSize - y);
+ float pMinZ = (float) (ate.energyNetNodes[i].getPortPos(null)[2] - portSize - z);
+ float pMaxZ = (float) (ate.energyNetNodes[i].getPortPos(null)[2] + portSize - z);
+ bbMinX = Math.min(pMinX, bbMinX);
+ bbMaxX = Math.max(pMaxX, bbMaxX);
+ bbMinY = Math.min(pMinY, bbMinY);
+ bbMaxY = Math.max(pMaxY, bbMaxY);
+ bbMinZ = Math.min(pMinZ, bbMinZ);
+ bbMaxZ = Math.max(pMaxZ, bbMaxZ);
+ }
+ }
+ this.setBlockBounds(bbMinX, bbMinY, bbMinZ, bbMaxX, bbMaxY, bbMaxZ);
+ }
+ }
+}
diff --git a/src/main/java/ihl/flexible_cable/AnchorTileEntity.java b/src/main/java/ihl/flexible_cable/AnchorTileEntity.java
new file mode 100644
index 0000000..488e89b
--- /dev/null
+++ b/src/main/java/ihl/flexible_cable/AnchorTileEntity.java
@@ -0,0 +1,342 @@
+package ihl.flexible_cable;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import ic2.api.energy.EnergyNet;
+import ic2.api.energy.event.EnergyTileLoadEvent;
+import ic2.api.energy.event.EnergyTileUnloadEvent;
+import ic2.api.energy.tile.IEnergySink;
+import ic2.api.energy.tile.IEnergySource;
+import ic2.core.ExplosionIC2;
+import ic2.core.IC2;
+import ic2.core.block.TileEntityBlock;
+import ihl.interfaces.IEnergyNetNode;
+import ihl.interfaces.IMultiPowerCableHolder;
+import ihl.utils.IHLUtils;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTTagList;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.common.util.ForgeDirection;
+
+public class AnchorTileEntity extends TileEntityBlock implements IEnergySink, IEnergySource, IMultiPowerCableHolder {
+ public boolean addedToEnergyNet = false;
+ public final Set<TileEntity> sacrifices = new HashSet<TileEntity>();
+ public SubAnchorEnergyNetNode[] energyNetNodes = new SubAnchorEnergyNetNode[6];
+ public boolean[] hasCableOnSide = new boolean[] { false, false, false, false, false, false };
+ public int checksum = -1;
+ public boolean checkCables = true;
+
+ public AnchorTileEntity() {
+ super();
+ for (short i = 0; i < 6; i++) {
+ energyNetNodes[i] = new SubAnchorEnergyNetNode(this, i);
+ }
+ }
+
+ @Override
+ public List<String> getNetworkedFields() {
+ List<String> fields = super.getNetworkedFields();
+ fields.add("hasCableOnSide");
+ return fields;
+ }
+
+ @Override
+ public void onLoaded() {
+ super.onLoaded();
+ for (short i = 0; i < 6; i++) {
+ energyNetNodes[i].onLoaded();
+ }
+ if (IC2.platform.isSimulating() && !this.addedToEnergyNet) {
+ MinecraftForge.EVENT_BUS.post(new EnergyTileLoadEvent(this));
+ this.addedToEnergyNet = true;
+ }
+ }
+
+ @Override
+ public void onUnloaded() {
+ super.onUnloaded();
+ if (IC2.platform.isSimulating()) {
+ if (this.addedToEnergyNet) {
+ MinecraftForge.EVENT_BUS.post(new EnergyTileUnloadEvent(this));
+ this.addedToEnergyNet = false;
+ }
+ for (SubAnchorEnergyNetNode sen : energyNetNodes) {
+ sen.onUnloaded();
+ }
+
+ }
+ }
+
+ @Override
+ public boolean wrenchCanRemove(EntityPlayer var1) {
+ return false;
+ }
+
+ public boolean enableUpdateEntity() {
+ return IC2.platform.isSimulating();
+ }
+
+ @Override
+ public void updateEntityServer() {
+ if (!sacrifices.isEmpty()) {
+ Iterator<TileEntity> victimIterator = sacrifices.iterator();
+ while (victimIterator.hasNext()) {
+ TileEntity sacrifice = victimIterator.next();
+ ExplosionIC2 explosion = new ExplosionIC2(this.worldObj, null, sacrifice.xCoord + 0.5D,
+ sacrifice.yCoord + 0.5D, sacrifice.zCoord + 0.5D, 3F, 0.3F, ExplosionIC2.Type.Normal, null, 0);
+ explosion.doExplosion();
+ sacrifices.remove(sacrifice);
+ }
+
+ }
+ int newchecksum = 0;
+ for (short i = 0; i < 6; i++) {
+ if (this.hasCableOnSide[i]) {
+ newchecksum++;
+ }
+ }
+ if (newchecksum != checksum) {
+ IC2.network.get().updateTileEntityField(this, "hasCableOnSide");
+ checksum = newchecksum;
+ }
+ }
+
+ @Override
+ public void writeToNBT(NBTTagCompound nbt) {
+ super.writeToNBT(nbt);
+ NBTTagList energyNetNodeNBTList = new NBTTagList();
+ for (SubAnchorEnergyNetNode node : this.energyNetNodes) {
+ energyNetNodeNBTList.appendTag(node.writeToNBT());
+ }
+ nbt.setTag("energyNetNodes", energyNetNodeNBTList);
+ nbt.setBoolean("checkCables", this.checkCables);
+ }
+
+ @Override
+ public void readFromNBT(NBTTagCompound nbt) {
+ super.readFromNBT(nbt);
+ if (!nbt.hasKey("energyNetNodes")) {
+ short facing = nbt.getShort("facing");
+ int gridID = nbt.getInteger("gridID");
+ this.energyNetNodes[facing].setGrid(gridID);
+ NBTTagList cableNBTList = nbt.getTagList("cableList", 10);
+ for (int i = 0; i < cableNBTList.tagCount(); i++) {
+ this.energyNetNodes[facing].addCable(cableNBTList.getCompoundTagAt(i));
+ }
+ } else {
+ NBTTagList energyNetNodeNBTList = nbt.getTagList("energyNetNodes", 10);
+ for (int i = 0; i < 6; i++) {
+ this.energyNetNodes[i].readFromNBT(energyNetNodeNBTList.getCompoundTagAt(i));
+ }
+ }
+ this.checkCables = nbt.getBoolean("checkCables");
+ }
+
+ @Override
+ public void setFacing(short facing) {
+ this.energyNetNodes[facing].removeAttachedChains();
+ boolean removeTE = true;
+ for (short i = 0; i < 6; i++) {
+ if (!energyNetNodes[i].getCableList().isEmpty()) {
+ removeTE = false;
+ }
+ }
+ if (removeTE) {
+ worldObj.setBlockToAir(xCoord, yCoord, zCoord);
+ }
+ }
+
+ @Override
+ public boolean acceptsEnergyFrom(TileEntity emitter, ForgeDirection direction) {
+ if (direction != ForgeDirection.UNKNOWN) {
+ return this.energyNetNodes[direction.getOpposite().ordinal()].getGridID() != -1;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean emitsEnergyTo(TileEntity receiver, ForgeDirection direction) {
+ return this.acceptsEnergyFrom(receiver, direction);
+ }
+
+ @Override
+ public double getOfferedEnergy() {
+ double offeredEnergy = 0d;
+ for (short i = 0; i < 6; i++) {
+ offeredEnergy += energyNetNodes[i].getEnergyOfferedByGrid();
+ }
+ return offeredEnergy;
+ }
+
+ @Override
+ public void drawEnergy(double amount) {
+ for (short i = 0; i < 6; i++) {
+ amount -= energyNetNodes[i].drawEnergyFromGrid(amount);
+ double voltage = energyNetNodes[i].getVoltage();
+ if (voltage > 500D) {
+ Set<TileEntity> teset = new HashSet<TileEntity>();
+ ForgeDirection direction = ForgeDirection.getOrientation(i).getOpposite();
+ TileEntity te = EnergyNet.instance.getNeighbor(this, direction);
+ teset.add(te);
+ TileEntity te1 = this.getSink(te, teset);
+ if (te1 instanceof IEnergyNetNode) {
+ if (((IEnergyNetNode) te1).getMaxAllowableVoltage() >= voltage) {
+ return;
+ }
+ }
+ if (te1 != null) {
+ sacrifices.add(te1);
+ }
+ }
+ if (amount <= 0d) {
+ break;
+ }
+ }
+ }
+
+ @Override
+ public int getSourceTier() {
+ return 4;
+ }
+
+ @Override
+ public double getDemandedEnergy() {
+ double amount = 0d;
+ for (short i = 0; i < 6; i++) {
+ amount += energyNetNodes[i].getDemandedEnergy();
+ }
+ return amount;
+ }
+
+ @Override
+ public int getSinkTier() {
+ return 4;
+ }
+
+ @Override
+ public double injectEnergy(ForgeDirection directionFrom, double amount, double voltage) {
+ if (directionFrom != ForgeDirection.UNKNOWN) {
+ return this.energyNetNodes[directionFrom.getOpposite().ordinal()].injectEnergyToGrid(amount);
+ }
+ return amount;
+ }
+
+ @Override
+ public ItemStack getWrenchDrop(EntityPlayer entityPlayer) {
+ return null;
+ }
+
+ @Override
+ public boolean wrenchCanSetFacing(EntityPlayer entityPlayer, int side) {
+ return !this.wrenchCanRemove(entityPlayer);
+ }
+
+ public TileEntity getSink(TileEntity te, Set<TileEntity> teset) {
+ teset.add(te);
+ while (te != null && !(te instanceof IEnergySink)) {
+ TileEntity te1 = EnergyNet.instance.getNeighbor(te, ForgeDirection.NORTH);
+ if (te1 == null || teset.contains(te1)) {
+ te1 = EnergyNet.instance.getNeighbor(te, ForgeDirection.SOUTH);
+ } else {
+ TileEntity te2 = this.getSink(te1, teset);
+ if (te2 != null) {
+ return te2;
+ }
+ }
+ if (te1 == null || teset.contains(te1)) {
+ te1 = EnergyNet.instance.getNeighbor(te, ForgeDirection.UP);
+ } else {
+ TileEntity te2 = this.getSink(te1, teset);
+ if (te2 != null) {
+ return te2;
+ }
+ }
+ if (te1 == null || teset.contains(te1)) {
+ te1 = EnergyNet.instance.getNeighbor(te, ForgeDirection.DOWN);
+ } else {
+ TileEntity te2 = this.getSink(te1, teset);
+ if (te2 != null) {
+ return te2;
+ }
+ }
+ if (te1 == null || teset.contains(te1)) {
+ te1 = EnergyNet.instance.getNeighbor(te, ForgeDirection.WEST);
+ } else {
+ TileEntity te2 = this.getSink(te1, teset);
+ if (te2 != null) {
+ return te2;
+ }
+ }
+ if (te1 == null || teset.contains(te1)) {
+ te1 = EnergyNet.instance.getNeighbor(te, ForgeDirection.EAST);
+ } else {
+ TileEntity te2 = this.getSink(te1, teset);
+ if (te2 != null) {
+ return te2;
+ }
+ }
+ if (te1 != null) {
+ teset.add(te1);
+ }
+ te = te1;
+ }
+ if (te instanceof IEnergySink) {
+ return te;
+ } else {
+ return null;
+ }
+ }
+
+ public void checkIfNoCablesLeft() {
+ boolean noCables = true;
+ for (SubAnchorEnergyNetNode sen : energyNetNodes) {
+ if (!sen.getCableList().isEmpty()) {
+ noCables = false;
+ }
+ }
+ if (noCables) {
+ worldObj.setBlockToAir(xCoord, yCoord, zCoord);
+ }
+ }
+
+ @Override
+ public boolean isCableRemoved(int chainUniqueID) {
+ if (!checkCables) {
+ return false;
+ }
+ for (SubAnchorEnergyNetNode sen : energyNetNodes) {
+ if (!sen.isCableRemoved(chainUniqueID)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public IEnergyNetNode getEnergyNetNode(short facing) {
+ return energyNetNodes[facing];
+ }
+
+ @Override
+ public short getSide(EntityPlayer player) {
+ return IHLUtils.getFacingFromPlayerView(player, true);
+ }
+
+ @Override
+ public void removeAttachedChains() {
+ for (short i = 0; i < 6; i++) {
+ energyNetNodes[i].removeAttachedChains();
+ }
+
+ }
+
+ public boolean isTileEntityInvalid() {
+ return this.tileEntityInvalid;
+ }
+}
diff --git a/src/main/java/ihl/flexible_cable/BatterySwitchUnitModel.java b/src/main/java/ihl/flexible_cable/BatterySwitchUnitModel.java
new file mode 100644
index 0000000..2d16ed4
--- /dev/null
+++ b/src/main/java/ihl/flexible_cable/BatterySwitchUnitModel.java
@@ -0,0 +1,48 @@
+package ihl.flexible_cable;
+
+import ihl.model.IHLModelRenderer;
+import net.minecraft.client.model.ModelBase;
+import net.minecraftforge.common.util.ForgeDirection;
+
+// Date: 07.04.2015 18:24:15
+// Template version 1.1
+// Java generated by Techne
+// Keep in mind that you still need to fill in some blanks
+// - ZeuX
+
+public class BatterySwitchUnitModel extends ModelBase
+{
+ //fields
+ IHLModelRenderer Piece1;
+
+ public BatterySwitchUnitModel()
+ {
+ textureWidth = 64;
+ textureHeight = 32;
+ setTextureOffset("Piece1.Shape1", 0, 0);
+ setTextureOffset("Piece1.ConeUp01", 0, 0);
+ setTextureOffset("Piece1.PipeUp", 54, 0);
+ setTextureOffset("Piece1.ConeUp02", 0, 0);
+ setTextureOffset("Piece1.Shape27", 0, 0);
+ setTextureOffset("Piece1.ConeUp04", 0, 0);
+
+ Piece1 = new IHLModelRenderer(this, "Piece1");
+ Piece1.setRotationPoint(0F, 16F, 0F);
+ setRotation(Piece1, 0F, 0F, 0F);
+ Piece1.mirror = true;
+ Piece1.addBox("Shape1", -8F, -8F, -8F, 16, 16, 16);
+ Piece1.addTube("ConeUp01", -2F, -16F, -2F, 4, 2, 4, 0f, 0.5f, ForgeDirection.DOWN);
+ Piece1.addTube("PipeUp", -0.5F, -17F, -0.5F, 1, 1, 1, 0f, 1f, ForgeDirection.DOWN);
+ Piece1.addTube("ConeUp02", -2F, -14F, -2F, 4, 2, 4, 0f, 0.5f, ForgeDirection.DOWN);
+ Piece1.addTube("Shape27", -2F, -12F, -2F, 4, 2, 4, 0f, 0.5f, ForgeDirection.DOWN);
+ Piece1.addTube("ConeUp04", -2F, -10F, -2F, 4, 2, 4, 0f, 0.5f, ForgeDirection.DOWN);
+ }
+
+ private void setRotation(IHLModelRenderer model, float x, float y, float z)
+ {
+ model.rotateAngleX = x;
+ model.rotateAngleY = y;
+ model.rotateAngleZ = z;
+ }
+
+}
diff --git a/src/main/java/ihl/flexible_cable/BatterySwitchUnitTileEntity.java b/src/main/java/ihl/flexible_cable/BatterySwitchUnitTileEntity.java
new file mode 100644
index 0000000..f4fc6c1
--- /dev/null
+++ b/src/main/java/ihl/flexible_cable/BatterySwitchUnitTileEntity.java
@@ -0,0 +1,295 @@
+package ihl.flexible_cable;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import ic2.api.energy.event.EnergyTileLoadEvent;
+import ic2.api.energy.event.EnergyTileUnloadEvent;
+import ic2.api.energy.tile.IEnergySource;
+import ic2.api.network.INetworkClientTileEntityEventListener;
+import ic2.core.ExplosionIC2;
+import ic2.core.IC2;
+import ihl.utils.IHLUtils;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.common.util.ForgeDirection;
+
+public class BatterySwitchUnitTileEntity extends FlexibleCableHolderBaseTileEntity implements INetworkClientTileEntityEventListener, IEnergySource{
+
+ public short progress;
+ protected short operationLength=200;
+ public boolean isGuiScreenOpened=false;
+ protected final double energyConsume=128D;
+ public double energy;
+ public int maxStorage=65536;
+ private boolean addedToEnergyNet=false;
+ public byte mode = 0;
+ private Set<BatterySwitchUnitTileEntity> batteryChain = new HashSet<BatterySwitchUnitTileEntity>();
+ private BatterySwitchUnitTileEntity batteryChainMaster;
+ private boolean chargingMode=true;
+
+ public BatterySwitchUnitTileEntity()
+ {
+ super();
+ }
+
+ @Override
+ public void onLoaded()
+ {
+ super.onLoaded();
+ if (IC2.platform.isSimulating()&&!this.addedToEnergyNet)
+ {
+ MinecraftForge.EVENT_BUS.post(new EnergyTileLoadEvent(this));
+ this.addedToEnergyNet = true;
+ }
+ }
+
+ @Override
+ public void onUnloaded()
+ {
+ if (IC2.platform.isSimulating()&&this.addedToEnergyNet)
+ {
+ MinecraftForge.EVENT_BUS.post(new EnergyTileUnloadEvent(this));
+ this.addedToEnergyNet = false;
+ }
+ super.onUnloaded();
+ }
+
+ @Override
+ public ItemStack getWrenchDrop(EntityPlayer player)
+ {
+ return IHLUtils.getThisModItemStack("batterySwitchUnit");
+ }
+ @Override
+ public boolean wrenchCanSetFacing(EntityPlayer entityPlayer, int side)
+ {
+ return this.getFacing()!=(short)side;
+ }
+
+
+ @Override
+ public void writeToNBT(NBTTagCompound nbt) {
+ super.writeToNBT(nbt);
+ nbt.setShort("progress", this.progress);
+ nbt.setDouble("energy", this.energy);
+ }
+
+ @Override
+ public void readFromNBT(NBTTagCompound nbt) {
+ super.readFromNBT(nbt);
+ this.progress = nbt.getShort("progress");
+ this.energy=nbt.getDouble("energy");
+ }
+
+ @Override
+ public void onNetworkEvent(EntityPlayer player, int event)
+ {
+ switch(event)
+ {
+ case 0:
+ this.isGuiScreenOpened=false;
+ break;
+ }
+ }
+
+ @Override
+ public void updateEntityServer()
+ {
+ {
+ if(this.chargingMode && this.gridID!=-1 && this.energy<this.maxStorage && !this.batteryChain.isEmpty())
+ {
+ if(this.getGrid().energy>0D)
+ {
+ if(this.getGrid().getSinkVoltage(this)/this.batteryChain.size()>410D)
+ {
+ this.energy+=energyConsume;
+ this.getGrid().drawEnergy(energyConsume, this);
+ if(this.getGrid().getSinkVoltage(this)/this.batteryChain.size()>500D)
+ {
+ this.createChainOfExplosions();
+ }
+ }
+ }
+ }
+ if(this.chargingMode && this.batteryChainMaster!=null && this.gridID==-1)
+ {
+ if(this.batteryChainMaster.gridID!=-1 && this.batteryChainMaster.energy>0D && this.energy<this.maxStorage && !this.batteryChainMaster.batteryChain.isEmpty())
+ {
+ if(this.batteryChainMaster.getGrid().getSinkVoltage(this.batteryChainMaster)/this.batteryChainMaster.batteryChain.size()>410D)
+ {
+ this.energy+=energyConsume;
+ this.batteryChainMaster.drawEnergy(energyConsume);
+ }
+ }
+ }
+ if(this.chargingMode && this.gridID!=-1 && MinecraftServer.getServer().getTickCounter() % 40==0)
+ {
+ this.checkBatteryChain();
+ }
+ if(this.energy>=this.maxStorage)
+ {
+ this.chargingMode=false;
+ }
+ if(!this.chargingMode)
+ {
+ this.energy-=0.01D;
+ if(this.energy<energyConsume)
+ {
+ this.chargingMode=true;
+ }
+ }
+ }
+ }
+
+ private void createChainOfExplosions()
+ {
+ Iterator<BatterySwitchUnitTileEntity> batteryChainIterator = this.batteryChain.iterator();
+ while(batteryChainIterator.hasNext())
+ {
+ BatterySwitchUnitTileEntity bsu = batteryChainIterator.next();
+ ExplosionIC2 explosion = new ExplosionIC2(bsu.worldObj, null, bsu.xCoord+0.5D, bsu.yCoord+0.5D, bsu.zCoord+0.5D, 2F, 0.3F, ExplosionIC2.Type.Normal, null, 0);
+ explosion.doExplosion();
+ }
+ }
+
+ private boolean checkBatteryChain()
+ {
+ boolean allright=true;
+ if(!this.batteryChain.isEmpty())
+ {
+ Iterator<BatterySwitchUnitTileEntity> sectionsIterator = this.batteryChain.iterator();
+ while(sectionsIterator.hasNext())
+ {
+ BatterySwitchUnitTileEntity section = sectionsIterator.next();
+ if(section==null || section.isInvalid())
+ {
+ allright=false;
+ }
+ }
+ }
+ else
+ {
+ allright=false;
+ }
+ if(allright)
+ {
+ return true;
+ }
+ else
+ {
+ this.batteryChain.clear();
+ boolean checking = true;
+ int x=xCoord;
+ int z=zCoord;
+ List<Integer> xs = new ArrayList<Integer>();
+ List<Integer> zs = new ArrayList<Integer>();
+ xs.add(xCoord);
+ zs.add(zCoord);
+ this.batteryChain.add(this);
+ while(checking)
+ {
+ if(!xs.isEmpty() && !zs.isEmpty())
+ {
+ x=xs.remove(0);
+ z=zs.remove(0);
+ }
+ else
+ {
+ checking=false;
+ break;
+ }
+ int[] xz = new int[] {0,1,0,-1,0};
+ for(int i=0;i<xz.length-1;i++)
+ {
+ TileEntity te = worldObj.getTileEntity(x+xz[i], yCoord, z+xz[i+1]);
+ if(te instanceof BatterySwitchUnitTileEntity)
+ {
+ BatterySwitchUnitTileEntity section = (BatterySwitchUnitTileEntity)te;
+ if(this.batteryChain.add(section))
+ {
+ xs.add(section.xCoord);
+ zs.add(section.zCoord);
+ section.batteryChain.add(this);
+ section.batteryChainMaster=this;
+ }
+ }
+ }
+ }
+ return true;
+ }
+ }
+
+ @Override
+ public boolean emitsEnergyTo(TileEntity receiver, ForgeDirection direction) {
+ return true;
+ }
+
+ @Override
+ public double getOfferedEnergy()
+ {
+ return this.chargingMode? 0 : this.energy;
+ }
+
+ @Override
+ public void drawEnergy(double amount)
+ {
+ this.energy-=amount;
+ }
+
+ @Override
+ public double getEnergyAmountThisNodeWant()
+ {
+ return this.energy-this.maxStorage;
+ }
+
+ public double drawEnergyToGrid(double amount)
+ {
+ return 0d;
+ }
+
+ public double injectEnergy(double amount)
+ {
+ this.energy+=amount;
+ return 0d;
+ }
+
+ @Override
+ public int getSourceTier() {
+ return 4;
+ }
+
+ @Override
+ public double getMaxAllowableVoltage()
+ {
+ return 64000D;
+ }
+
+ @Override
+ public boolean shouldRenderInPass(int pass)
+ {
+ return pass==0;
+ }
+
+ @Override
+ public String getInventoryName() {
+ return null;
+ }
+
+ @Override
+ public void injectEnergyInThisNode(double amount, double voltage)
+ {
+ this.energy+=amount;
+ if(voltage/this.batteryChain.size()>500D)
+ {
+ this.createChainOfExplosions();
+ }
+ }
+
+}
diff --git a/src/main/java/ihl/flexible_cable/BlastEntityFX.java b/src/main/java/ihl/flexible_cable/BlastEntityFX.java
new file mode 100644
index 0000000..49e2a36
--- /dev/null
+++ b/src/main/java/ihl/flexible_cable/BlastEntityFX.java
@@ -0,0 +1,68 @@
+package ihl.flexible_cable;
+
+import net.minecraft.client.particle.EntityFX;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.world.World;
+
+public class BlastEntityFX extends EntityFX {
+
+ public BlastEntityFX(World world, double x, double y, double z)
+ {
+ super(world, x, y, z);
+ this.renderDistanceWeight = 5.0D;
+ }
+
+ public BlastEntityFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, float par14)
+ {
+ super(par1World, par2, par4, par6, 0.0D, 0.0D, 0.0D);
+ this.motionX *= 0.10000000149011612D;
+ this.motionY *= 0.10000000149011612D;
+ this.motionZ *= 0.10000000149011612D;
+ this.motionX += par8;
+ this.motionY += par10;
+ this.motionZ += par12;
+ this.particleScale *= par14;
+ this.particleMaxAge = 3;
+ this.particleAge=0;
+ this.noClip = false;
+ this.renderDistanceWeight = 6.0D;
+ }
+
+ @Override
+ public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7)
+ {
+ float var8 = this.particleTextureIndexX / 2.0F;
+ float var9 = var8 + 0.5f;
+ float var10 = this.particleTextureIndexY / 2.0F;
+ float var11 = var10 + 0.5f;
+ float var12 = 0.1F * this.particleScale;
+ float var13 = (float)(this.prevPosX + (this.posX - this.prevPosX) * par2 - interpPosX);
+ float var14 = (float)(this.prevPosY + (this.posY - this.prevPosY) * par2 - interpPosY);
+ float var15 = (float)(this.prevPosZ + (this.posZ - this.prevPosZ) * par2 - interpPosZ);
+ par1Tessellator.addVertexWithUV(var13 - par3 * var12 - par6 * var12, var14 - par4 * var12, var15 - par5 * var12 - par7 * var12, var9, var11);
+ par1Tessellator.addVertexWithUV(var13 - par3 * var12 + par6 * var12, var14 + par4 * var12, var15 - par5 * var12 + par7 * var12, var9, var10);
+ par1Tessellator.addVertexWithUV(var13 + par3 * var12 + par6 * var12, var14 + par4 * var12, var15 + par5 * var12 + par7 * var12, var8, var10);
+ par1Tessellator.addVertexWithUV(var13 + par3 * var12 - par6 * var12, var14 - par4 * var12, var15 + par5 * var12 - par7 * var12, var8, var11);
+ }
+
+ @Override
+ public void onUpdate()
+ {
+ this.prevPosX = this.posX;
+ this.prevPosY = this.posY;
+ this.prevPosZ = this.posZ;
+ if (this.particleAge++ >= this.particleMaxAge)
+ {
+ this.setDead();
+ }
+ this.setParticleTextureIndex(this.particleAge * 3 / this.particleMaxAge);
+ }
+
+ @Override
+ public void setParticleTextureIndex(int par1)
+ {
+ this.particleTextureIndexX = par1 % 2;
+ this.particleTextureIndexY = par1 / 2;
+ }
+
+}
diff --git a/src/main/java/ihl/flexible_cable/FlexibleCableHolderBaseTileEntity.java b/src/main/java/ihl/flexible_cable/FlexibleCableHolderBaseTileEntity.java
new file mode 100644
index 0000000..919e130
--- /dev/null
+++ b/src/main/java/ihl/flexible_cable/FlexibleCableHolderBaseTileEntity.java
@@ -0,0 +1,237 @@
+package ihl.flexible_cable;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import ic2.core.block.TileEntityInventory;
+import ihl.IHLMod;
+import ihl.interfaces.IEnergyNetNode;
+import ihl.utils.IHLUtils;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTTagList;
+import net.minecraft.util.AxisAlignedBB;
+
+public abstract class FlexibleCableHolderBaseTileEntity extends TileEntityInventory implements IEnergyNetNode{
+
+ protected double connectionX;
+ protected double connectionY;
+ protected double connectionZ;
+ protected int gridID=-1;
+ protected final Set<IHLCable> cableList;
+ public boolean checkCables=true;
+
+ public FlexibleCableHolderBaseTileEntity()
+ {
+ super();
+ cableList=new HashSet<IHLCable>();
+ }
+
+ @Override
+ public void onLoaded()
+ {
+ super.onLoaded();
+ if(gridID!=-1)
+ {
+ IHLGrid grid = IHLMod.enet.getGrid(gridID);
+ grid.add(this);
+ }
+ }
+
+ @Override
+ public void onUnloaded()
+ {
+ super.onUnloaded();
+ if(gridID!=-1)
+ {
+ IHLGrid grid = IHLMod.enet.getGrid(gridID);
+ grid.remove(this);
+ }
+ }
+
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void setFacing(short facing1)
+ {
+ short facing2 = (short) Math.max(facing1, 2);
+ double range = 2D;
+ AxisAlignedBB searchArea = AxisAlignedBB.getBoundingBox(connectionX-range,connectionY-range,connectionZ-range,connectionX+range,connectionY+range,connectionZ+range);
+ List<NodeEntity> nodeList = worldObj.getEntitiesWithinAABB(NodeEntity.class, searchArea);
+ super.setFacing(facing2);
+ setConnectionX(this.xCoord+0.5D);
+ setConnectionY(this.yCoord+1.5D);
+ setConnectionZ(this.zCoord+0.5D);
+ if(!nodeList.isEmpty())
+ {
+ Iterator<NodeEntity> ei = nodeList.iterator();
+ while(ei.hasNext())
+ {
+ NodeEntity ne=(NodeEntity) ei.next();
+ if((ne.prevAnchorEntity==null||ne.nextAnchorEntity==null) && this.cableListContains(ne.getChainUniqueID()))
+ {
+ ne.setVirtualNodePos(connectionX, connectionY, connectionZ);
+ }
+ }
+ }
+ }
+
+ protected boolean cableListContains(int chainUniqueID) {
+ Iterator<IHLCable> cli = this.getCableList().iterator();
+ while(cli.hasNext())
+ {
+ IHLCable c = cli.next();
+ if(c.chainUID==chainUniqueID)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean wrenchCanSetFacing(EntityPlayer entityPlayer, int side)
+ {
+ return this.getFacing()!=(short)side;
+ }
+
+
+ @Override
+ public void writeToNBT(NBTTagCompound nbt) {
+ super.writeToNBT(nbt);
+ NBTTagList cableNBTList = new NBTTagList();
+ for(IHLCable cable:this.cableList)
+ {
+ cableNBTList.appendTag(cable.toNBT());
+ }
+ nbt.setTag("cableList", cableNBTList);
+ nbt.setDouble("connectionX", this.connectionX);
+ nbt.setDouble("connectionY", this.connectionY);
+ nbt.setDouble("connectionZ", this.connectionZ);
+ nbt.setInteger("gridID", this.gridID);
+ nbt.setBoolean("checkCables", this.checkCables);
+ }
+
+ @Override
+ public void readFromNBT(NBTTagCompound nbt) {
+ super.readFromNBT(nbt);
+ NBTTagList cableNBTList=nbt.getTagList("cableList", 10);
+ for(int i=0;i<cableNBTList.tagCount();i++)
+ {
+ this.cableList.add(IHLCable.fromNBT(cableNBTList.getCompoundTagAt(i)));
+ }
+ this.setConnectionX(nbt.getDouble("connectionX"));
+ this.setConnectionY(nbt.getDouble("connectionY"));
+ this.setConnectionZ(nbt.getDouble("connectionZ"));
+ this.gridID=nbt.getInteger("gridID");
+ this.checkCables=nbt.getBoolean("checkCables");
+ }
+
+ @Override
+ public void removeAttachedChains()
+ {
+ IHLUtils.removeChains(this,this.worldObj);
+ }
+
+ public void setConnectionX(double connectionX) {
+ this.connectionX = connectionX;
+ }
+
+ public void setConnectionY(double connectionY) {
+ this.connectionY = connectionY;
+ }
+
+ public void setConnectionZ(double connectionZ) {
+ this.connectionZ = connectionZ;
+ }
+
+ @Override
+ public double[] getPortPos(EntityLivingBase player)
+ {
+ return new double[] {this.connectionX,this.connectionY,this.connectionZ};
+ }
+
+ @Override
+ public boolean addCable(NBTTagCompound cable)
+ {
+ return this.cableList.add(IHLCable.fromNBT(cable));
+ }
+
+ @Override
+ public Set<IHLCable> getCableList() {
+ return cableList;
+ }
+
+ @Override
+ public void setGrid(int newGridID)
+ {
+ if(newGridID!=-1)
+ {
+ this.gridID=newGridID;
+ IHLMod.enet.getGrid(newGridID).add(this);
+ }
+ else
+ {
+ this.gridID=-1;
+ }
+ }
+
+ @Override
+ public int getGridID()
+ {
+ return this.gridID;
+ }
+
+ @Override
+ public IHLGrid getGrid()
+ {
+ return IHLMod.enet.getGrid(gridID);
+ }
+
+ @Override
+ public boolean shouldRenderInPass(int pass)
+ {
+ return pass==0;
+ }
+
+ @Override
+ public void remove(IHLCable cable)
+ {
+ if(this.cableList.remove(cable))
+ {
+ IHLUtils.removeChain(cable, this);
+ }
+ }
+
+
+ @Override
+ public boolean isCableRemoved(int chainUniqueID)
+ {
+ if(!checkCables)
+ {
+ return false;
+ }
+ for(IHLCable cable:this.cableList)
+ {
+ if(cable.chainUID==chainUniqueID)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public void setCableCheck(boolean b)
+ {
+ this.checkCables=b;
+ }
+
+ @Override
+ public boolean isTileEntityBaseInvalid(){
+ return this.tileEntityInvalid;
+ }
+}
diff --git a/src/main/java/ihl/flexible_cable/IHLCable.java b/src/main/java/ihl/flexible_cable/IHLCable.java
new file mode 100644
index 0000000..e47621e
--- /dev/null
+++ b/src/main/java/ihl/flexible_cable/IHLCable.java
@@ -0,0 +1,111 @@
+package ihl.flexible_cable;
+
+import ihl.metallurgy.constants.ElectricConductor;
+import net.minecraft.nbt.NBTTagCompound;
+
+public class IHLCable {
+
+ public final int chainUID;
+ public final int fullLength;
+ public final int length;
+ public final String material;
+ public final int transverseSection;
+ public final String insulationMaterial;
+ public final int insulationThickness;
+ public final int maxVoltage;
+ public final int connectorX1;
+ public final int connectorY1;
+ public final int connectorZ1;
+ public final int connectorDimensionId1;
+ public final short connectorFacing1;
+ public final int connectorX;
+ public final int connectorY;
+ public final int connectorZ;
+ public final int connectorDimensionId;
+ public final short connectorFacing;
+
+ public IHLCable(int chainUIDIn, int fullLengthIn, int lengthIn, String materialIn, int transverseSectionIn,
+ String insulationMaterialIn, int insulationThicknessIn, int maxVoltageIn, int connectorX1In,
+ int connectorY1In, int connectorZ1In, int connectorDimensionId1In, short connectorFacing1In,
+ int connectorXIn, int connectorYIn, int connectorZIn, int connectorDimensionIdIn, short connectorFacingIn) {
+ chainUID = chainUIDIn;
+ fullLength = fullLengthIn;
+ length = lengthIn;
+ material = materialIn;
+ transverseSection = transverseSectionIn;
+ insulationMaterial = insulationMaterialIn;
+ insulationThickness = insulationThicknessIn;
+ maxVoltage = maxVoltageIn;
+ connectorX1 = connectorX1In;
+ connectorY1 = connectorY1In;
+ connectorZ1 = connectorZ1In;
+ connectorDimensionId1 = connectorDimensionId1In;
+ connectorFacing1 = connectorFacing1In;
+ connectorX = connectorXIn;
+ connectorY = connectorYIn;
+ connectorZ = connectorZIn;
+ connectorDimensionId = connectorDimensionIdIn;
+ connectorFacing = connectorFacingIn;
+ }
+
+ public static IHLCable fromNBT(NBTTagCompound tag) {
+ return new IHLCable(tag.getInteger("chainUID"),
+ tag.getInteger("fullLength"),
+ tag.getInteger("length"),
+ tag.getString("material"),
+ tag.getInteger("transverseSection"),
+ tag.getString("insulationMaterial"),
+ tag.getInteger("insulationThickness"),
+ tag.getInteger("maxVoltage"),
+ tag.getInteger("connectorX1"),
+ tag.getInteger("connectorY1"),
+ tag.getInteger("connectorZ1"),
+ tag.getInteger("connectorDimensionId1"),
+ tag.getShort("connectorFacing1"),
+ tag.getInteger("connectorX"),
+ tag.getInteger("connectorY"),
+ tag.getInteger("connectorZ"),
+ tag.getInteger("connectorDimensionId"),
+ tag.getShort("connectorFacing"));
+ }
+
+ public NBTTagCompound toNBT() {
+ NBTTagCompound tag = new NBTTagCompound();
+ tag.setInteger("fullLength", fullLength);
+ tag.setInteger("length", length);
+ tag.setString("material", material);
+ tag.setInteger("transverseSection", transverseSection);
+ tag.setString("insulationMaterial", insulationMaterial);
+ tag.setInteger("insulationThickness", insulationThickness);
+ tag.setInteger("maxVoltage", maxVoltage);
+ tag.setInteger("connectorX1",connectorX1);
+ tag.setInteger("connectorY1",connectorY1);
+ tag.setInteger("connectorZ1",connectorZ1);
+ tag.setInteger("connectorDimensionId1",connectorDimensionId1);
+ tag.setShort("connectorFacing1",connectorFacing1);
+ tag.setInteger("connectorX",connectorX);
+ tag.setInteger("connectorY",connectorY);
+ tag.setInteger("connectorZ",connectorZ);
+ tag.setInteger("connectorDimensionId",connectorDimensionId);
+ tag.setShort("connectorFacing",connectorFacing);
+ return tag;
+ }
+
+ @Override
+ public int hashCode() {
+ return chainUID;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof IHLCable))
+ return false;
+ IHLCable otherCable = (IHLCable) o;
+ return otherCable.chainUID == this.chainUID;
+ }
+
+ public long getResistance(){
+ return ElectricConductor.getResistivity(material) * 100L / transverseSection;
+ }
+
+}
diff --git a/src/main/java/ihl/flexible_cable/IHLENet.java b/src/main/java/ihl/flexible_cable/IHLENet.java
new file mode 100644
index 0000000..de08204
--- /dev/null
+++ b/src/main/java/ihl/flexible_cable/IHLENet.java
@@ -0,0 +1,168 @@
+package ihl.flexible_cable;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import ihl.IHLMod;
+import ihl.interfaces.IEnergyNetNode;
+
+public class IHLENet {
+
+ public Map<Integer, IHLGrid> grids = new HashMap<Integer, IHLGrid>();
+ public Map<Integer, IHLGrid> cablesToGrids = new HashMap<Integer, IHLGrid>();
+
+ private int griduid=0;
+
+ public IHLENet()
+ {
+ }
+
+ public int getNewUniqueGridID()
+ {
+ for(int i=0;i<Integer.MAX_VALUE;i++)
+ {
+ if(grids.get(++griduid)==null)
+ {
+ return griduid;
+ }
+ }
+ return -1;
+ }
+
+ public int mergeGrids(int gridID, int gridID2)
+ {
+ if(gridID==-1 && gridID2!=-1)
+ {
+ return gridID2;
+ }
+ else if(gridID!=-1 && gridID2==-1)
+ {
+ return gridID;
+ }
+ else if(gridID==-1 && gridID2==-1)
+ {
+ int newGridID=this.getNewUniqueGridID();
+ IHLGrid cgrid;
+ cgrid=new IHLGrid();
+ grids.put(newGridID, cgrid);
+ return newGridID;
+ }
+ else if(gridID!=gridID2)
+ {
+ Iterator<IEnergyNetNode> tei = grids.get(gridID2).telist.iterator();
+ while(tei.hasNext())
+ {
+ IEnergyNetNode te = tei.next();
+ te.setGrid(gridID);
+ }
+ grids.remove(gridID2);
+ return gridID;
+ }
+ return gridID2;
+ }
+
+
+ public IHLGrid getGrid(int gridID)
+ {
+ if(gridID==-1)
+ throw new IllegalArgumentException("Node should never ask grid with ID -1");
+ if(this.grids.get(gridID)==null)
+ {
+ IHLGrid cgrid;
+ cgrid=new IHLGrid();
+ grids.put(gridID, cgrid);
+ return cgrid;
+ }
+ else
+ {
+ return this.grids.get(gridID);
+ }
+ }
+
+ public void splitGrids(int gridID, IEnergyNetNode exclude)
+ {
+ Set<IEnergyNetNode> telist = this.grids.get(gridID).telist;
+ Set<IEnergyNetNode> telist2 = new HashSet<IEnergyNetNode>();
+ telist.remove(exclude);
+ Iterator<IEnergyNetNode> atei = telist.iterator();
+ while(atei.hasNext())
+ {
+ IEnergyNetNode cte = atei.next();
+ atei.remove();
+ telist2.add(cte);
+ cte.getCableList().removeAll(exclude.getCableList());
+ cte.setGrid(-1);
+ }
+ Iterator<IEnergyNetNode> atei2 = telist2.iterator();
+ while(atei2.hasNext())
+ {
+ IEnergyNetNode cte = atei2.next();
+ if(cte.getGridID()==-1)//Warning! Potential future bugs are hidden here!
+ {
+ Iterator<IEnergyNetNode> atei3 = telist2.iterator();
+ while(atei3.hasNext())
+ {
+ IEnergyNetNode cte2 = atei3.next();
+ if(cte2!=cte && hasSame(cte.getCableList(),cte2.getCableList()))
+ {
+ int result=this.mergeGrids(cte.getGridID(), cte2.getGridID());
+ cte.setGrid(result);
+ cte2.setGrid(result);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ public void removeCableAndSplitGrids(int gridID, IHLCable cable)
+ {
+ this.grids.get(gridID).removeCableAndSplitGrids(cable);
+ }
+
+ public boolean hasSame(Set<IHLCable> set, Set<IHLCable> set2)
+ {
+ Iterator<IHLCable> i1 = set.iterator();
+ while(i1.hasNext())
+ {
+ IHLCable num1=i1.next();
+ if(set2.contains(num1))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void setOnFire(IHLCable cable)
+ {
+ Set<NodeEntity> cs = IHLMod.proxy.nodeEntityRegistry.get(cable.chainUID);
+ if(cs!=null)
+ {
+ for(NodeEntity ne:cs)
+ {
+ ne.setFire(10);
+ }
+ }
+ }
+
+ public void removeCableEntities(IHLCable cable)
+ {
+ int uid = cable.chainUID;
+ Set<NodeEntity> cs = IHLMod.proxy.nodeEntityRegistry.get(uid);
+ if(cs!=null)
+ {
+ for(NodeEntity ne:cs)
+ {
+ if(ne!=null)
+ {
+ ne.setDead();
+ }
+ }
+ }
+ cablesToGrids.remove(uid);
+ }
+} \ No newline at end of file
diff --git a/src/main/java/ihl/flexible_cable/IHLGrid.java b/src/main/java/ihl/flexible_cable/IHLGrid.java
new file mode 100644
index 0000000..0a8178e
--- /dev/null
+++ b/src/main/java/ihl/flexible_cable/IHLGrid.java
@@ -0,0 +1,291 @@
+package ihl.flexible_cable;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import ihl.IHLMod;
+import ihl.interfaces.IEnergyNetNode;
+import ihl.utils.IHLUtils;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.server.MinecraftServer;
+
+public class IHLGrid {
+ private static final double powerLossLimitPerMeter = 1.6D;
+ public final Set<IEnergyNetNode> telist = new HashSet<IEnergyNetNode>();
+ public double energy = 0D;
+ private IEnergyNetNode sink;
+ private IEnergyNetNode source;
+ private double voltage = 400d;
+ private double lastVoltage;
+ public boolean isGridValid = true;
+ private double total20TicksEU;
+ private int lastTickCounter = 0;
+ private int tickCounterFireStart = 0;
+ public final List<IEnergyNetNode> calculatedSinks = new ArrayList<IEnergyNetNode>();
+ public final List<IEnergyNetNode> calculatedSources = new ArrayList<IEnergyNetNode>();
+ public final Set<IHLCable> cablesOnFire = new HashSet<IHLCable>();
+ private final Map<IEnergyNetNode, Double> energyLossSinkMap = new HashMap<IEnergyNetNode, Double>();
+ private final Map<IEnergyNetNode, Double> voltageSinkMap = new HashMap<IEnergyNetNode, Double>();
+ private double averageEUTransfered;
+ private double lastAverageEUTransfered = 0D;
+
+ public void drawEnergy(double amount, IEnergyNetNode sink1) {
+ this.energy -= amount;
+ if (energyLossSinkMap.get(sink1) != null) {
+ this.energy -= energyLossSinkMap.get(sink1) * amount * amount;
+ } else {
+ this.telist.add(sink1);
+ }
+ this.sink = sink1;
+ }
+
+ public void injectEnergy(double amount, double voltage1, IEnergyNetNode source1) {
+ this.energy += amount;
+ this.voltage = voltage1;
+ this.source = source1;
+ this.total20TicksEU += amount;
+ int tickCounter = MinecraftServer.getServer().getTickCounter();
+ if (tickCounter - lastTickCounter < 0) {
+ lastTickCounter = tickCounter;
+ this.total20TicksEU = 0D;
+ }
+ Iterator<IEnergyNetNode> i = telist.iterator();
+ while (this.energy > 1d && i.hasNext()) {
+ IEnergyNetNode eNode = i.next();
+ if (eNode.isTileEntityBaseInvalid()) {
+ if (!eNode.getCableList().isEmpty()) {
+ for (IHLCable cable : eNode.getCableList()) {
+ IHLMod.enet.cablesToGrids.remove(cable.chainUID);
+ }
+ }
+ IHLMod.log.error("Removing invalide TE " + eNode.getClass().getName());
+ i.remove();
+ continue;
+ }
+ else if(eNode.getGridID()==-1) {
+ eNode.removeAttachedChains();
+ IHLMod.log.error("Removing TE with grid ID==-1 " + eNode.getClass().getName()+ " If it happened more than a single time, report that to mod author.");
+ i.remove();
+ continue;
+ }
+ if (eNode.getEnergyAmountThisNodeWant() > 0d) {
+ double powerToInject = Math.min(energy, eNode.getEnergyAmountThisNodeWant());
+ eNode.injectEnergyInThisNode(powerToInject, this.getSinkVoltage(eNode));
+ this.energy -= powerToInject;
+ if (energyLossSinkMap.get(eNode) != null) {
+ this.energy -= energyLossSinkMap.get(eNode) * powerToInject * powerToInject;
+ } else {
+ this.sink = eNode;
+ }
+ }
+ }
+ int d = tickCounter - lastTickCounter;
+ if (d >= 40) {
+ this.averageEUTransfered = this.total20TicksEU / d;
+ lastTickCounter = tickCounter;
+ this.total20TicksEU = 0D;
+ if (IHLMod.config.enableFlexibleCablesGridPowerLossCalculations && isGridValid
+ && this.averageEUTransfered > 1D) {
+ this.telist.add(source1);
+ this.updateGrid();
+ }
+ }
+ d = tickCounter - tickCounterFireStart;
+ if (d >= 40 && !this.cablesOnFire.isEmpty()) {
+ for (IHLCable cable : this.cablesOnFire) {
+ this.removeCableAndSplitGrids(cable);
+ }
+ this.cablesOnFire.clear();
+ }
+
+ }
+
+ public void removeCableAndSplitGrids(IHLCable cable) {
+ IHLUtils.removeChain(cable, null);
+ Iterator<IEnergyNetNode> atei = this.telist.iterator();
+ Set<IEnergyNetNode> telist2 = new HashSet<IEnergyNetNode>();
+ while (atei.hasNext()) {
+ IEnergyNetNode cte = atei.next();
+ atei.remove();
+ telist2.add(cte);
+ cte.setGrid(-1);
+ }
+ IHLMod.enet.removeCableEntities(cable);
+ Iterator<IEnergyNetNode> atei2 = telist2.iterator();
+ while (atei2.hasNext()) {
+ IEnergyNetNode cte = atei2.next();
+ if (cte.getGridID() == -1) {
+ Iterator<IEnergyNetNode> atei3 = telist2.iterator();
+ while (atei3.hasNext()) {
+ IEnergyNetNode cte2 = atei3.next();
+ if (cte2 != cte && IHLMod.enet.hasSame(cte.getCableList(), cte2.getCableList())) {
+ int result = IHLMod.enet.mergeGrids(cte.getGridID(), cte2.getGridID());
+ cte.setGrid(result);
+ cte2.setGrid(result);
+ break;
+ }
+ }
+
+ }
+ }
+ }
+
+ private void updateGrid() {
+ Iterator<IEnergyNetNode> atei2 = telist.iterator();
+ while (atei2.hasNext()) {
+ IEnergyNetNode cte = atei2.next();
+ if (cte.isTileEntityBaseInvalid()) {
+ if (!cte.getCableList().isEmpty()) {
+ for (IHLCable cable : cte.getCableList()) {
+ IHLMod.enet.cablesToGrids.remove(cable.chainUID);
+ }
+ }
+ atei2.remove();
+ }
+ }
+ if (this.source != null && this.sink != null && this.source != this.sink && !this.sink.getCableList().isEmpty()
+ && !this.source.getCableList().isEmpty()
+ && (!this.calculatedSources.contains(this.source) || !this.calculatedSinks.contains(this.sink)
+ || this.averageEUTransfered > this.lastAverageEUTransfered
+ || this.voltage != this.lastVoltage)) {
+ IEnergyNetNode[] gridTEList = new IEnergyNetNode[this.telist.size()];
+ if (gridTEList.length > 100)
+ IHLMod.log.error("Grid has " + gridTEList.length
+ + " nodes. If there is no such complex grids in game, report that to mod author.");
+ gridTEList = this.telist.toArray(gridTEList);
+ Map<IEnergyNetNode, IHLCable> map = new HashMap<IEnergyNetNode, IHLCable>();
+ Set<IEnergyNetNode> templist = new HashSet<IEnergyNetNode>();
+ Set<IEnergyNetNode> processlist = new HashSet<IEnergyNetNode>();
+ Set<IEnergyNetNode> templist2 = new HashSet<IEnergyNetNode>();
+ templist.addAll(telist);
+ processlist.add(sink);
+ int threads = 0;
+ a: while (!templist.isEmpty()) {
+ if (threads++ > 1000) {
+ this.isGridValid = false;
+ return;
+ }
+ templist.removeAll(processlist);
+ templist2.clear();
+ Iterator<IEnergyNetNode> it1 = processlist.iterator();
+ while (it1.hasNext()) {
+ if (threads++ > 1000) {
+ this.isGridValid = false;
+ return;
+ }
+ IEnergyNetNode ate1 = it1.next();
+ Iterator<IEnergyNetNode> it2 = templist.iterator();
+ while (it2.hasNext()) {
+ if (threads++ > 1000) {
+ this.isGridValid = false;
+ return;
+ }
+ IEnergyNetNode ate2 = it2.next();
+ if (ate1 != ate2) {
+ IHLCable cable = this.getSame(ate1.getCableList(), ate2.getCableList());
+ if (cable != null) {
+ map.put(ate2, cable);
+ templist2.add(ate2);
+ if (ate2 == source) {
+ break a;
+ }
+ }
+ }
+ }
+ templist.removeAll(templist2);
+ }
+ processlist.clear();
+ processlist.addAll(templist2);
+ }
+ IEnergyNetNode cursor = source;
+ {
+ double voltage1 = this.voltage;
+ double euTransfered = this.averageEUTransfered;
+ double voltageLossPerMeter = 0D;
+ double powerLossPerMeter = 0D;
+ double powerLossPerSquaredEU = 0D;
+ this.energyLossSinkMap.remove(sink);
+ this.voltageSinkMap.remove(sink);
+ while (cursor != sink) {
+ // System.out.println("cycle 4");
+ IHLCable cable = map.get(cursor);
+ if (cable == null) {
+ IHLMod.log.error("One of a cables is null during grid update. Skipping update in this tick.");
+ return;
+ }
+ voltageLossPerMeter = cable.getResistance() / 1000D * euTransfered / voltage1;
+ powerLossPerMeter = voltageLossPerMeter * euTransfered / voltage1;
+ euTransfered -= powerLossPerMeter * cable.length;
+ voltage1 -= voltageLossPerMeter * cable.length;
+ powerLossPerSquaredEU += cable.getResistance() / 1000d * cable.length / voltage1 / voltage1;
+ if (!this.cablesOnFire.contains(cable) && (powerLossPerMeter > IHLGrid.powerLossLimitPerMeter)) {
+ IHLMod.enet.setOnFire(cable);
+ tickCounterFireStart = lastTickCounter;
+ this.cablesOnFire.add(cable);
+ }
+ cursor = this.getHasCable(cable, cursor, gridTEList);
+ }
+ this.energyLossSinkMap.put(sink, powerLossPerSquaredEU);
+ if (voltage1 < 1d)
+ voltage1 = 1d;
+ this.voltageSinkMap.put(sink, voltage1);
+ }
+ this.calculatedSources.add(this.source);
+ this.calculatedSinks.add(this.sink);
+ this.lastAverageEUTransfered = this.averageEUTransfered;
+ this.lastVoltage = this.voltage;
+ }
+ }
+
+ private IHLCable getSame(Set<IHLCable> set, Set<IHLCable> set2) {
+ Iterator<IHLCable> i1 = set.iterator();
+ while (i1.hasNext()) {
+ IHLCable cable = i1.next();
+ if (set2.contains(cable)) {
+ return cable;
+ }
+ }
+ return null;
+ }
+
+ public double getSinkVoltage(IEnergyNetNode node) {
+ if (this.voltageSinkMap.containsKey(node)) {
+ return this.voltageSinkMap.get(node);
+ } else {
+ return this.voltage;
+ }
+ }
+
+ private IEnergyNetNode getHasCable(IHLCable cable, IEnergyNetNode exclude, IEnergyNetNode[] gridTEList) {
+ for (IEnergyNetNode ate1 : gridTEList) {
+ if (ate1 != exclude && ate1.getCableList().contains(cable)) {
+ return ate1;
+ }
+ }
+ return null;
+ }
+
+ public void add(IEnergyNetNode e) {
+ this.telist.add(e);
+ this.isGridValid = true;
+ if (!e.getCableList().isEmpty()) {
+ for (IHLCable cable : e.getCableList()) {
+ IHLMod.enet.cablesToGrids.put(cable.chainUID, this);
+ }
+ }
+ }
+
+ public void remove(IEnergyNetNode e) {
+ this.telist.remove(e);
+ if (!e.getCableList().isEmpty()) {
+ for (IHLCable cable : e.getCableList()) {
+ IHLMod.enet.cablesToGrids.remove(cable.chainUID);
+ }
+ }
+ }
+}
diff --git a/src/main/java/ihl/flexible_cable/InvSlotOutputInProgress.java b/src/main/java/ihl/flexible_cable/InvSlotOutputInProgress.java
new file mode 100644
index 0000000..da17e0f
--- /dev/null
+++ b/src/main/java/ihl/flexible_cable/InvSlotOutputInProgress.java
@@ -0,0 +1,93 @@
+package ihl.flexible_cable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+
+public class InvSlotOutputInProgress extends IronWorkbenchInvSlot{
+ public short[] slotRecipe;
+ private int size;
+ public InvSlotOutputInProgress(IronWorkbenchTileEntity base1, String name1, int oldStartIndex1, int count) {
+ super(base1, name1, oldStartIndex1, Access.NONE, count);
+ slotRecipe = new short[count];
+ size=count;
+ for(int i=0;i<slotRecipe.length;i++)
+ {
+ slotRecipe[i]=-1;
+ }
+ }
+
+ @Override
+ public boolean accepts(ItemStack itemStack)
+ {
+ return false;
+ }
+
+ @Override
+ public boolean getCanTakeStack()
+ {
+ return false;
+ }
+
+ @Override
+ public void writeToNbt(NBTTagCompound nbtTagCompound){}
+
+ @Override
+ public void readFromNbt(NBTTagCompound nbtTagCompound){}
+
+ public short put(List<ItemStack> outputs)
+ {
+ short slot=this.getFirstEmptySlot();
+ if(slot!=-1 && outputs!=null && !outputs.isEmpty() && slot<=this.size()-outputs.size())
+ {
+ for(int i=0;i<outputs.size();i++)
+ {
+ ItemStack output = outputs.get(i);
+ this.put(slot+i,output.copy());
+ this.slotRecipe[slot+i]=slot;
+ }
+ }
+ return slot;
+ }
+
+
+
+ private short getFirstEmptySlot()
+ {
+ for(short i=0; i<this.size();i++)
+ {
+ if(this.get(i)==null)
+ {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public int getCheckSum()
+ {
+ int sum=0;
+ for(short i=0; i<this.size();i++)
+ {
+ sum+=this.slotRecipe[i];
+ }
+ return sum;
+ }
+
+ public List<ItemStack> getRecipeOutputs(int currentSlot)
+ {
+ int slotRecipeIndex=this.slotRecipe[currentSlot];
+ List<ItemStack> list = new ArrayList<ItemStack>();
+ for(int i=0;i<this.size;i++)
+ {
+ if(this.slotRecipe[i]==slotRecipeIndex && get(i)!=null)
+ {
+ list.add(get(i));
+ }
+ }
+ return list;
+ }
+
+}
diff --git a/src/main/java/ihl/flexible_cable/InvSlotProcessableIronWorkbench.java b/src/main/java/ihl/flexible_cable/InvSlotProcessableIronWorkbench.java
new file mode 100644
index 0000000..fa2cc73
--- /dev/null
+++ b/src/main/java/ihl/flexible_cable/InvSlotProcessableIronWorkbench.java
@@ -0,0 +1,131 @@
+package ihl.flexible_cable;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import ic2.api.recipe.IRecipeInput;
+import ic2.api.recipe.RecipeInputFluidContainer;
+import ic2.core.IC2;
+import ic2.core.item.ItemUpgradeModule;
+import ihl.interfaces.IWire;
+import ihl.utils.IHLUtils;
+import net.minecraft.item.ItemStack;
+import net.minecraftforge.fluids.FluidContainerRegistry;
+
+public class InvSlotProcessableIronWorkbench extends IronWorkbenchInvSlot {
+
+ public InvSlotProcessableIronWorkbench(IronWorkbenchTileEntity base1,
+ String name1, int oldStartIndex1, Access access1, int count) {
+ super(base1, name1, oldStartIndex1, access1, count);
+ }
+
+ @Override
+ public boolean accepts(ItemStack itemStack)
+ {
+ if (itemStack != null && itemStack.getItem() instanceof ItemUpgradeModule)
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+ }
+
+ @Override
+ public void put(int index, ItemStack content)
+ {
+ super.put(index, content);
+ if(IC2.platform.isSimulating() && ((IronWorkbenchTileEntity)this.base).container!=null)
+ {
+ ((IronWorkbenchTileEntity)this.base).resetOutput();
+ ((IronWorkbenchTileEntity)this.base).container.detectAndSendChanges();
+ }
+ }
+
+ public Set<ItemStack> substract(List<IRecipeInput> materials, int multiplier)
+ {
+ Set<ItemStack> output = new HashSet<ItemStack>();
+ Iterator<IRecipeInput> i1 = materials.iterator();
+ while(i1.hasNext())
+ {
+ IRecipeInput is1 = i1.next();
+ for(int i=0;i<this.size();i++)
+ {
+ ItemStack is = this.get(i);
+ if(is!=null && (is1.matches(is)))
+ {
+ if(is.getItem() instanceof IWire)
+ {
+ if(IHLUtils.adjustWireLength(is, -is1.getAmount()*multiplier))
+ {
+ is.stackSize=0;
+ }
+ }
+ else if(is1 instanceof RecipeInputFluidContainer)
+ {
+ if(is.stackSize==1)
+ {
+ output.add(FluidContainerRegistry.drainFluidContainer(is));
+ is.stackSize=0;
+ }
+ else
+ {
+ is.stackSize-=is1.getAmount()*multiplier;
+ ItemStack iscopy = is.copy();
+ iscopy.stackSize=1;
+ ItemStack emptyContainer = FluidContainerRegistry.drainFluidContainer(iscopy);
+ if(emptyContainer!=null)
+ {
+ output.add(emptyContainer);
+ }
+ }
+ }
+ else
+ {
+ is.stackSize-=is1.getAmount()*multiplier;
+ }
+ if(is.stackSize<=0)
+ {
+ this.put(i, null);
+ }
+ break;
+ }
+ }
+ }
+ return output;
+ }
+
+ public int getAmountOf(ItemStack rubber)
+ {
+ int amount = 0;
+ for(int i=0;i<this.size();i++)
+ {
+ ItemStack is = this.get(i);
+ if(is!=null && ((is.getItem() == rubber.getItem() && is.getItemDamage() == rubber.getItemDamage())||IHLUtils.isItemsHaveSameOreDictionaryEntry(is, rubber)))
+ {
+ amount+=is.stackSize;
+ }
+ }
+ return amount;
+ }
+
+ public int getMultiplier(List<IRecipeInput> materials)
+ {
+ int m = Integer.MAX_VALUE;
+ for(int i=0;i<this.size();i++)
+ {
+ ItemStack is = this.get(i);
+ for(IRecipeInput recipeInput:materials)
+ {
+ if(is!=null && recipeInput.matches(is))
+ {
+ m = Math.min(m, Math.max(IHLUtils.getAmountOf(is)/recipeInput.getAmount(),1));
+ }
+ }
+ }
+ return m;
+ }
+}
diff --git a/src/main/java/ihl/flexible_cable/InvSlotTool.java b/src/main/java/ihl/flexible_cable/InvSlotTool.java
new file mode 100644
index 0000000..0d5119e
--- /dev/null
+++ b/src/main/java/ihl/flexible_cable/InvSlotTool.java
@@ -0,0 +1,69 @@
+package ihl.flexible_cable;
+
+import java.util.Iterator;
+import java.util.List;
+
+import ic2.api.recipe.IRecipeInput;
+import ic2.core.IC2;
+import ihl.recipes.IronWorkbenchRecipe;
+import ihl.utils.IHLUtils;
+import net.minecraft.item.ItemStack;
+
+public class InvSlotTool extends IronWorkbenchInvSlot {
+
+ public InvSlotTool(IronWorkbenchTileEntity base1, String name1, int oldStartIndex1, Access access1, int count) {
+ super(base1, name1, oldStartIndex1, access1, count);
+ // TODO Auto-generated constructor stub
+ }
+
+ public void damage(List<IRecipeInput> tools) {
+ if (tools != null && !tools.isEmpty()) {
+ for (int i = 0; i < this.size(); i++) {
+ ItemStack is = this.get(i);
+ Iterator<IRecipeInput> i1 = tools.iterator();
+ while (i1.hasNext()) {
+ IRecipeInput is1 = i1.next();
+ if (is != null && (is1.matches(is))) {
+ if (!is.attemptDamageItem(1, IC2.random)) {
+ if (is.stackTagCompound != null && is.stackTagCompound.hasKey("GT.ToolStats")) {
+ IHLUtils.damageItemViaNBTTag(is, 1);
+ }
+ }
+ if (is.stackSize <= 0) {
+ this.put(i, null);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void put(int index, ItemStack content) {
+ super.put(index, content);
+ if (IC2.platform.isSimulating() && ((IronWorkbenchTileEntity) this.base).container != null) {
+ ((IronWorkbenchTileEntity) this.base).resetOutput();
+ ((IronWorkbenchTileEntity) this.base).container.detectAndSendChanges();
+ }
+ }
+
+ @Override
+ public boolean accepts(ItemStack itemStack) {
+ for (IronWorkbenchRecipe recipe : IronWorkbenchTileEntity.recipes) {
+ if (recipe.isTool(itemStack)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean contain(ItemStack is1) {
+ for (int i = 0; i < this.size(); i++) {
+ ItemStack is = this.get(i);
+ if (is != null && (is.getItem() == is1.getItem() || IHLUtils.isItemsHaveSameOreDictionaryEntry(is, is1))) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/ihl/flexible_cable/InvSlotWorkspaceElement.java b/src/main/java/ihl/flexible_cable/InvSlotWorkspaceElement.java
new file mode 100644
index 0000000..b9e65b2
--- /dev/null
+++ b/src/main/java/ihl/flexible_cable/InvSlotWorkspaceElement.java
@@ -0,0 +1,184 @@
+package ihl.flexible_cable;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import ihl.interfaces.IWorkspaceElement;
+import ihl.utils.IHLUtils;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.tileentity.TileEntity;
+
+public class InvSlotWorkspaceElement extends IronWorkbenchInvSlot {
+
+ private final IWorkspaceElement[] workspaceElements;
+ public final boolean[] ready;
+
+ public InvSlotWorkspaceElement(IronWorkbenchTileEntity base1, String name1, int oldStartIndex1, Access access1, int count)
+ {
+ super(base1, name1, oldStartIndex1, access1, count);
+ this.put(0, IHLUtils.getThisModItemStack("ironWorkbench"));
+ workspaceElements=new IWorkspaceElement[count];
+ ready=new boolean[count];
+ }
+
+ @Override
+ public boolean accepts(ItemStack itemStack)
+ {
+ return false;
+ }
+
+ @Override
+ public boolean getCanTakeStack()
+ {
+ return false;
+ }
+
+ public boolean containsAndCanUse(List<ItemStack> workspaceElements2)
+ {
+ Iterator<ItemStack> iterator = workspaceElements2.iterator();
+ while(iterator.hasNext())
+ {
+ ItemStack rWorkspaceElementItemStack = iterator.next();
+ boolean presence=false;
+ for(int i=1;i<workspaceElements.length;i++)
+ {
+ IWorkspaceElement cWorkspaceElement=workspaceElements[i];
+ if(cWorkspaceElement!=null && rWorkspaceElementItemStack.getItem() == cWorkspaceElement.getWrenchDrop(null).getItem() && cWorkspaceElement.canBeUsed())
+ {
+ presence=true;
+ break;
+ }
+ }
+ //System.out.println("Checking " + rWorkspaceElementItemStack.getDisplayName());
+ if(!presence)
+ {
+ //System.out.println("Return false");
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public void use(List<ItemStack> workspaceElements2)
+ {
+ Iterator<ItemStack> iterator = workspaceElements2.iterator();
+ while(iterator.hasNext())
+ {
+ ItemStack rWorkspaceElementItemStack = iterator.next();
+ for(int i=1;i<workspaceElements.length;i++)
+ {
+ IWorkspaceElement cWorkspaceElement=workspaceElements[i];
+ if(cWorkspaceElement==null)
+ {
+ continue;
+ }
+ if(rWorkspaceElementItemStack.getItem() == cWorkspaceElement.getWrenchDrop(null).getItem() && cWorkspaceElement.canBeUsed())
+ {
+ cWorkspaceElement.use();
+ break;
+ }
+ }
+ }
+ }
+
+ public void reset()
+ {
+ for(int i=1;i<workspaceElements.length;i++)
+ {
+ workspaceElements[i]=null;
+ ready[i]=true;
+ this.put(i,null);
+ }
+ for(int i=1;i<workspaceElements.length;i++)
+ {
+ boolean clear=true;
+ //int[] xz = new int [] {0,1,1,0,-1,-1,1,-1,0};
+ // -1:1; 0:1; 1:1
+ // -1:0; 0:0; 1:0
+ // -1:-1; 0:-1; 1;-1
+ // 0 1 -1 -1 1 1 0 -1 0
+ for(int iy=-1;iy<=1;iy++)
+ {
+ for(int ix=-2;ix<=2;ix++)
+ {
+ for(int iz=-2;iz<=2;iz++)
+ {
+ TileEntity te = this.base.getWorldObj().getTileEntity(this.base.xCoord+ix, this.base.yCoord+iy, this.base.zCoord+iz);
+ if(te instanceof IWorkspaceElement)
+ {
+ IWorkspaceElement wse = (IWorkspaceElement)te;
+ if(!wse.getIsInvalid() && !this.contains(wse))
+ {
+ workspaceElements[i]=wse;
+ ready[i]=wse.canBeUsed();
+ this.put(i,wse.getWrenchDrop(null));
+ clear=false;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if(clear)
+ {
+ workspaceElements[i]=null;
+ this.put(i,null);
+ }
+ }
+ }
+
+ @Override
+ public void writeToNbt(NBTTagCompound nbtTagCompound){}
+
+ @Override
+ public void readFromNbt(NBTTagCompound nbtTagCompound){}
+
+ private boolean contains(IWorkspaceElement wse)
+ {
+ for(int i=0;i<workspaceElements.length;i++)
+ {
+ if(workspaceElements[i]!=null && workspaceElements[i].getWrenchDrop(null).getItem() == wse.getWrenchDrop(null).getItem())
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public short encodeReadyStatus()
+ {
+ short result=0;
+ for(int i=0;i<ready.length;i++)
+ {
+ if(ready[i])
+ {
+ result+= 1 << i;
+ }
+ }
+ //System.out.println("Encoding result = "+ result);
+ return result;
+ }
+
+ public void decodeReadyStatus(short encodedShort)
+ {
+ for(int i=0;i<ready.length;i++)
+ {
+ ready[i]=((encodedShort >> i) & 1)==1;
+ //System.out.println("Decoding result = "+ ready[i]);
+ }
+ }
+
+ @Override
+ public List<ItemStack> getItemStackList()
+ {
+ List<ItemStack> list = new ArrayList<ItemStack>();
+ for(int i=1; i<this.size(); i++)
+ {
+ if(get(i)!=null)list.add(get(i));
+ }
+ return list;
+ }
+
+}
diff --git a/src/main/java/ihl/flexible_cable/IronWorkbenchContainer.java b/src/main/java/ihl/flexible_cable/IronWorkbenchContainer.java
new file mode 100644
index 0000000..ede2194
--- /dev/null
+++ b/src/main/java/ihl/flexible_cable/IronWorkbenchContainer.java
@@ -0,0 +1,131 @@
+package ihl.flexible_cable;
+
+import ic2.core.ContainerBase;
+import ihl.processing.invslots.SlotInvSlotIronWorkbench;
+import ihl.processing.invslots.SlotInvSlotOutputInProgress;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.inventory.ICrafting;
+import net.minecraft.inventory.Slot;
+
+public class IronWorkbenchContainer extends ContainerBase<IronWorkbenchTileEntity> {
+
+ protected IronWorkbenchTileEntity tileEntity;
+ private int lastProgress1 = -1;
+ private int conrolSum = -1;
+ private int currentSlot1 = -1;
+ private short workspaceReadyStatus1 = -1;
+ private static final short slotUpdateOffset=4;
+ public final static int height=202;//166
+
+ public IronWorkbenchContainer(EntityPlayer entityPlayer, IronWorkbenchTileEntity tileEntity1){
+ super(tileEntity1);
+ this.tileEntity = tileEntity1;
+ int col, row;
+
+ for (col = 0; col < 3; ++col)
+ {
+ for (int col1 = 0; col1 < 9; ++col1)
+ {
+ this.addSlotToContainer(new Slot(entityPlayer.inventory, col1 + col * 9 + 9, 8 + col1 * 18, height + -82 + col * 18));
+ }
+ }
+ for (col = 0; col < 9; ++col)
+ {
+ this.addSlotToContainer(new Slot(entityPlayer.inventory, col, 8 + col * 18, height + -24));
+ }
+ for(row=0;row<6;row++)
+ {
+ for(col=0;col<=1;col++)
+ {
+ this.addSlotToContainer(new SlotInvSlotIronWorkbench(tileEntity1.tools, row+col*6, 26+col*18, 8+row*18));
+ }
+ }
+ for(row=0;row<6;row++)
+ {
+ for(col=0;col<=1;col++)
+ {
+ this.addSlotToContainer(new SlotInvSlotIronWorkbench(tileEntity1.inputMaterial, row+col*6, 65+col*18, 8+row*18));
+ }
+ }
+ for (row = 0; row<6; ++row)
+ {
+ this.addSlotToContainer(new SlotInvSlotOutputInProgress(tileEntity1.workspaceElements, row, 8, 8+row*18));
+ }
+ for(row=0;row<6;row++)
+ {
+ for (col = 0; col<3; ++col)
+ {
+ this.addSlotToContainer(new SlotInvSlotOutputInProgress(tileEntity1.output, col+row*3, 116+col*18, 8+row*18));
+ }
+ }
+
+ }
+
+ @Override
+ public void detectAndSendChanges()
+ {
+ super.detectAndSendChanges();
+ for (int i = 0; i < this.crafters.size(); ++i)
+ {
+ ICrafting icrafting = (ICrafting)this.crafters.get(i);
+
+ if (this.tileEntity.progress != this.lastProgress1)
+ {
+ icrafting.sendProgressBarUpdate(this, 0, this.tileEntity.progress);
+
+ }
+ if (this.tileEntity.currentSlot != this.currentSlot1)
+ {
+ icrafting.sendProgressBarUpdate(this, 1, this.tileEntity.currentSlot);
+
+ }
+ if(this.tileEntity.workspaceElements.encodeReadyStatus()!=this.workspaceReadyStatus1)
+ {
+ icrafting.sendProgressBarUpdate(this, 2, this.tileEntity.workspaceElements.encodeReadyStatus());
+ }
+ if(this.tileEntity.output.getCheckSum()!=this.conrolSum)
+ {
+ for(int i1 = 0; i1<this.tileEntity.output.size();i1++)
+ {
+ icrafting.sendProgressBarUpdate(this, i1+slotUpdateOffset, this.tileEntity.output.slotRecipe[i1]);
+ }
+ }
+
+ }
+ this.currentSlot1=this.tileEntity.currentSlot;
+ this.conrolSum=this.tileEntity.output.getCheckSum();
+ this.lastProgress1 = this.tileEntity.progress;
+ this.workspaceReadyStatus1=this.tileEntity.workspaceElements.encodeReadyStatus();
+ }
+
+ @Override
+ public void updateProgressBar(int index, int value)
+ {
+ super.updateProgressBar(index, value);
+ if(index>=slotUpdateOffset)
+ {
+ this.tileEntity.output.slotRecipe[index-slotUpdateOffset]=(short) value;
+ }
+ switch (index)
+ {
+ case 0:
+ this.tileEntity.progress=value;
+ break;
+ case 1:
+ this.tileEntity.currentSlot=value;
+ break;
+ case 2:
+ this.tileEntity.workspaceElements.decodeReadyStatus((short) value);
+ break;
+ }
+ }
+
+ @Override
+ public boolean canInteractWith(EntityPlayer var1) {
+ return tileEntity.isUseableByPlayer(var1);
+ }
+
+ /**
+ * Called when a player shift-clicks on a slot. You must override this or you will crash when someone does that.
+ */
+}
diff --git a/src/main/java/ihl/flexible_cable/IronWorkbenchGui.java b/src/main/java/ihl/flexible_cable/IronWorkbenchGui.java
new file mode 100644
index 0000000..c395484
--- /dev/null
+++ b/src/main/java/ihl/flexible_cable/IronWorkbenchGui.java
@@ -0,0 +1,185 @@
+package ihl.flexible_cable;
+
+import org.lwjgl.opengl.GL11;
+
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import ic2.core.IC2;
+import ihl.interfaces.IItemHasMiniGUI;
+import ihl.interfaces.ItemMiniGUI;
+import ihl.utils.IHLRenderUtils;
+import net.minecraft.client.gui.inventory.GuiContainer;
+import net.minecraft.inventory.Slot;
+import net.minecraft.util.ResourceLocation;
+
+@SideOnly(Side.CLIENT)
+public class IronWorkbenchGui extends GuiContainer {
+ private static final ResourceLocation background = new ResourceLocation("ihl", "textures/gui/GUIIronWorkbench.png");
+ private IronWorkbenchContainer container;
+ private ItemMiniGUI miniGui;
+ private static final short outputslotoffset=66;
+
+ public IronWorkbenchGui (IronWorkbenchContainer container1) {
+ super(container1);
+ this.container=container1;
+ this.ySize=IronWorkbenchContainer.height;
+ }
+
+ @Override
+ protected void drawGuiContainerForegroundLayer(int par1, int par2)
+ {
+ int x = (width - xSize) / 2;
+ int y = (height - ySize) / 2;
+ for(int row = 1;row<6;row++)
+ {
+ if(!this.container.tileEntity.workspaceElements.ready[row] && this.container.tileEntity.workspaceElements.get(row)!=null)
+ {
+ IHLRenderUtils.instance.drawWorkspaceElementTooltip(par1, par2, 8+x, 8+y+row*18, this.container.tileEntity.workspaceElements.get(row));
+ }
+ }
+ if(miniGui!=null)
+ {
+ miniGui.displayGUI();
+ }
+ }
+
+ @Override
+ protected void keyTyped(char characterTyped, int keyIndex)
+ {
+ super.keyTyped(characterTyped, keyIndex);
+ if(miniGui!=null && miniGui.handleKeyTyped(characterTyped, keyIndex))
+ {
+ miniGui.onGUIClosed();
+ miniGui=null;
+ }
+ }
+
+ @Override
+ protected void mouseClicked(int mouseX, int mouseY, int mouseButton)
+ {
+ int x = (width - xSize) / 2;
+ int y = (height - ySize) / 2;
+ if(miniGui==null || !miniGui.handleMouseClick(mouseX-x, mouseY-y, mouseButton))
+ {
+ if(miniGui!=null)
+ {
+ miniGui.onGUIClosed();
+ miniGui=null;
+ }
+ super.mouseClicked(mouseX, mouseY, mouseButton);
+ }
+ }
+
+ @Override
+ protected void mouseMovedOrUp(int mouseX, int mouseY, int mouseButton)
+ {
+ super.mouseMovedOrUp(mouseX, mouseY, mouseButton);
+ int x = (width - xSize) / 2;
+ int y = (height - ySize) / 2;
+ if(miniGui!=null)
+ {
+ miniGui.handleMouseClick(mouseX-x, mouseY-y, mouseButton);
+ }
+ }
+
+ @Override
+ protected void drawGuiContainerBackgroundLayer(float par1, int par2,
+ int par3) {
+ GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
+ this.mc.renderEngine.bindTexture(background);
+ int x = (width - xSize) / 2;
+ int y = (height - ySize) / 2;
+ this.drawTexturedModalRect(x, y, 0, 0, xSize, ySize);
+ if (this.container.tileEntity.progress > 0)
+ {
+ int frameNum=0;
+ short slotRecipeNum=this.container.tileEntity.output.slotRecipe[0];
+ for(int row = 0;row<6;row++)
+ {
+ for (int col = 0; col<3; ++col)
+ {
+ if(slotRecipeNum!=this.container.tileEntity.output.slotRecipe[col+row*3])
+ {
+ frameNum++;
+ slotRecipeNum=this.container.tileEntity.output.slotRecipe[col+row*3];
+ }
+ if(this.container.tileEntity.currentSlot==slotRecipeNum)
+ {
+ int i1 = Math.min(this.container.tileEntity.gaugeProgressScaled(18),18);
+ this.drawTexturedModalRect(115+x+col*18, 7+y+row*18, 176, 72,i1,18);
+ this.drawTexturedModalRect(115+x+col*18, 7+y+row*18, 176+getFrameX(frameNum), getFrameY(frameNum),18,18);
+ }
+ }
+ }
+ }
+ else
+ {
+ int frameNum=0;
+ short slotRecipeNum=this.container.tileEntity.output.slotRecipe[0];
+ for(int row = 0;row<6;row++)
+ {
+ for (int col = 0;col<3; ++col)
+ {
+ if(slotRecipeNum!=this.container.tileEntity.output.slotRecipe[col+row*3])
+ {
+ frameNum++;
+ slotRecipeNum=this.container.tileEntity.output.slotRecipe[col+row*3];
+ }
+ if(this.container.tileEntity.output.get(col+row*3)!=null)
+ {
+ this.drawTexturedModalRect(115+x+col*18, 7+y+row*18, 176+getFrameX(frameNum), getFrameY(frameNum),18,18);
+ }
+ }
+ }
+ }
+ for(int row = 1;row<6;row++)
+ {
+ if(!this.container.tileEntity.workspaceElements.ready[row])
+ {
+ this.drawTexturedModalRect(20+x, 9+y+row*18, 194, 74,3,14);
+ }
+ }
+ }
+
+ @Override
+ public void onGuiClosed()
+ {
+ super.onGuiClosed();
+ this.container.tileEntity.isGuiScreenOpened=false;
+ IC2.network.get().initiateClientTileEntityEvent(this.container.tileEntity, 16);
+ }
+
+ @Override
+ public void handleMouseClick(Slot slot,int slotNumber,int mouseButton/*0=left 1=right*/,int arg3)
+ {
+ if(miniGui==null && slot!=null && slot.slotNumber>=outputslotoffset && slot.slotNumber<outputslotoffset+18)
+ {
+ if(mouseButton==0)
+ {
+ IC2.network.get().initiateClientTileEntityEvent(this.container.tileEntity, slot.slotNumber-outputslotoffset);
+ }
+ else if(mouseButton==1)
+ {
+ if(slot.getHasStack() && slot.getStack().getItem() instanceof IItemHasMiniGUI)
+ {
+ if(miniGui!=null)
+ {
+ miniGui.onGUIClosed();
+ }
+ miniGui = ((IItemHasMiniGUI)slot.getStack().getItem()).getMiniGUI(this, slot);
+ }
+ }
+ }
+ super.handleMouseClick(slot, slotNumber, mouseButton, arg3);
+ }
+
+ private int getFrameX(int number)
+ {
+ return (number % 4) * 18;
+ }
+ private int getFrameY(int number)
+ {
+ return ((number>>2) & 3)*18;
+ }
+
+} \ No newline at end of file
diff --git a/src/main/java/ihl/flexible_cable/IronWorkbenchInvSlot.java b/src/main/java/ihl/flexible_cable/IronWorkbenchInvSlot.java
new file mode 100644
index 0000000..33821da
--- /dev/null
+++ b/src/main/java/ihl/flexible_cable/IronWorkbenchInvSlot.java
@@ -0,0 +1,30 @@
+package ihl.flexible_cable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import ic2.core.block.invslot.InvSlot;
+import net.minecraft.item.ItemStack;
+
+public class IronWorkbenchInvSlot extends InvSlot {
+
+ public IronWorkbenchInvSlot(IronWorkbenchTileEntity base1, String name1,
+ int oldStartIndex1, Access access1, int count) {
+ super(base1, name1, oldStartIndex1, access1, count);
+ }
+
+ public List<ItemStack> getItemStackList()
+ {
+ List<ItemStack> list = new ArrayList<ItemStack>();
+ for(int i=0; i<this.size(); i++)
+ {
+ if(get(i)!=null)list.add(get(i));
+ }
+ return list;
+ }
+
+ public boolean getCanTakeStack()
+ {
+ return true;
+ }
+}
diff --git a/src/main/java/ihl/flexible_cable/IronWorkbenchModel.java b/src/main/java/ihl/flexible_cable/IronWorkbenchModel.java
new file mode 100644
index 0000000..1039692
--- /dev/null
+++ b/src/main/java/ihl/flexible_cable/IronWorkbenchModel.java
@@ -0,0 +1,48 @@
+package ihl.flexible_cable;
+
+import net.minecraft.client.model.ModelBase;
+import net.minecraft.client.model.ModelRenderer;
+
+public class IronWorkbenchModel extends ModelBase {
+ //fields
+ ModelRenderer Base;
+
+ public IronWorkbenchModel()
+ {
+ textureWidth = 64;
+ textureHeight = 32;
+ setTextureOffset("Base.Shape1", 20, 0);
+ setTextureOffset("Base.Shape2", 20, 0);
+ setTextureOffset("Base.Shape3", 23, 0);
+ setTextureOffset("Base.Shape4", 23, 0);
+ setTextureOffset("Base.Shape5", 0, 0);
+ setTextureOffset("Base.Shape6", 16, 0);
+ setTextureOffset("Base.Shape7", 1, 21);
+ setTextureOffset("Base.Shape8", 0, 17);
+ setTextureOffset("Base.Shape9", 0, 0);
+ setTextureOffset("Base.Shape10", 0, 0);
+ setTextureOffset("Base.Shape11", 0, 0);
+ setTextureOffset("Base.Shape12", 0, 0);
+ setTextureOffset("Base.Shape13", 0, 0);
+ setTextureOffset("Base.Shape14", 0, 0);
+
+ Base = new ModelRenderer(this, "Base");
+ Base.setRotationPoint(0F, 8F, 0F);
+ Base.mirror = true;
+ Base.addBox("Shape1", 5F, 1F, -7F, 2, 15, 2);
+ Base.addBox("Shape2", 5F, 1F, 5F, 2, 15, 2);
+ Base.addBox("Shape3", -7F, 1F, -7F, 2, 15, 2);
+ Base.addBox("Shape4", -7F, 1F, 5F, 2, 15, 2);
+ Base.addBox("Shape5", -8F, 0F, -8F, 16, 1, 16);
+ Base.addBox("Shape6", -6F, 10F, -6F, 12, 1, 12);
+ Base.addBox("Shape7", 5F, 2F, -8F, 2, 2, 1);
+ Base.addBox("Shape8", -1F, -7F, 4F, 8, 1, 3);
+ Base.addBox("Shape9", 5F, -1F, 4F, 3, 1, 3);
+ Base.addBox("Shape10", 7F, -7F, 5F, 1, 6, 1);
+ Base.addBox("Shape11", -5F, 1F, -6F, 10, 2, 1);
+ Base.addBox("Shape12", -5F, 1F, 5F, 10, 2, 1);
+ Base.addBox("Shape13", 5F, 1F, -5F, 1, 2, 10);
+ Base.addBox("Shape14", -6F, 1F, -5F, 1, 2, 10);
+ }
+
+}
diff --git a/src/main/java/ihl/flexible_cable/IronWorkbenchRender.java b/src/main/java/ihl/flexible_cable/IronWorkbenchRender.java
new file mode 100644
index 0000000..27b3835
--- /dev/null
+++ b/src/main/java/ihl/flexible_cable/IronWorkbenchRender.java
@@ -0,0 +1,36 @@
+package ihl.flexible_cable;
+import org.lwjgl.opengl.GL11;
+
+import ihl.utils.IHLItemRenderer;
+import net.minecraft.client.renderer.entity.RenderManager;
+import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
+import net.minecraft.tileentity.TileEntity;
+
+public class IronWorkbenchRender extends TileEntitySpecialRenderer{
+private IHLItemRenderer itemRenderer=new IHLItemRenderer(true);
+
+public IronWorkbenchRender(){}
+
+public void renderAModelAt(IronWorkbenchTileEntity tile, double x, double y, double z, float f) {
+ GL11.glPushMatrix();
+ GL11.glTranslatef((float)x + 0.5F, (float)y+0.5F, (float)z + 0.5F);
+ GL11.glRotatef(90f, 1F, 0F, 0F);
+ int index = 0;
+ for (int i = 0; i < tile.tools.size() && index < 8; i++) {
+ if (tile.tools.get(i)!=null) {
+ float iy = index >= 4 ? -0.5f : 0f;
+ float ix = (index % 2) * 0.4f-0.2f;
+ float iz = (index / 2) * 0.4f-0.2f + iy * 1.5f;
+ this.itemRenderer.doRender(RenderManager.instance,tile.tools.get(i),ix,iz,iy-0.002f*index);
+ index++;
+ }
+ }
+ GL11.glPopMatrix();
+}
+
+ @Override
+ public void renderTileEntityAt(TileEntity par1TileEntity, double par2, double par4, double par6, float par8)
+ {
+ this.renderAModelAt((IronWorkbenchTileEntity)par1TileEntity, par2, par4, par6, par8);
+ }
+}
diff --git a/src/main/java/ihl/flexible_cable/IronWorkbenchTileEntity.java b/src/main/java/ihl/flexible_cable/IronWorkbenchTileEntity.java
new file mode 100644
index 0000000..30f6fda
--- /dev/null
+++ b/src/main/java/ihl/flexible_cable/IronWorkbenchTileEntity.java
@@ -0,0 +1,351 @@
+package ihl.flexible_cable;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import ic2.api.network.INetworkClientTileEntityEventListener;
+import ic2.api.network.INetworkTileEntityEventListener;
+import ic2.api.recipe.IRecipeInput;
+import ic2.core.ContainerBase;
+import ic2.core.IHasGui;
+import ic2.core.block.TileEntityInventory;
+import ic2.core.block.invslot.InvSlot.Access;
+import ihl.IHLMod;
+import ihl.interfaces.IWire;
+import ihl.recipes.IronWorkbenchRecipe;
+import ihl.recipes.RecipeInputDetonator;
+import ihl.recipes.RecipeInputDie;
+import ihl.recipes.RecipeInputObjectInstance;
+import ihl.utils.IHLUtils;
+import net.minecraft.client.gui.GuiScreen;
+import net.minecraft.entity.item.EntityItem;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.network.NetworkManager;
+import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
+
+public class IronWorkbenchTileEntity extends TileEntityInventory
+ implements IHasGui, INetworkClientTileEntityEventListener, INetworkTileEntityEventListener {
+
+ public static List<IronWorkbenchRecipe> recipes = new ArrayList<IronWorkbenchRecipe>();
+ public int progress;
+ public int currentSlot = -1;
+ public final int maxProgress;
+ public final InvSlotTool tools;
+ public final InvSlotWorkspaceElement workspaceElements;
+ public final InvSlotProcessableIronWorkbench inputMaterial;
+ public final InvSlotOutputInProgress output;
+ public boolean isGuiScreenOpened = false;
+ private boolean startProcess = false;
+ private boolean outputDefined = false;
+ private EntityPlayer crafter;
+ public ContainerBase<?> container;
+ private Map<Integer, IronWorkbenchRecipe> slotRecipeMap = new HashMap<Integer, IronWorkbenchRecipe>();
+ private boolean firstTick = true;
+
+ public IronWorkbenchTileEntity() {
+ this.maxProgress = 80;
+ this.workspaceElements = new InvSlotWorkspaceElement(this, "workspaceElements", 3, Access.NONE, 6);
+ this.tools = new InvSlotTool(this, "tools", 0, Access.IO, 12);
+ this.inputMaterial = new InvSlotProcessableIronWorkbench(this, "input", 1, Access.IO, 12);
+ this.output = new InvSlotOutputInProgress(this, "output", 2, 18);
+ }
+
+ public static void addRecipe(IronWorkbenchRecipe recipe) {
+ IronWorkbenchTileEntity.recipes.add(recipe);
+ }
+
+ @Override
+ public String getInventoryName() {
+ return "ironWorkbench";
+ }
+
+ @Override
+ public ItemStack getWrenchDrop(EntityPlayer player) {
+ return IHLUtils.getThisModItemStack("ironWorkbench");
+ }
+
+ @Override
+ @SideOnly(Side.CLIENT)
+ public void updateEntityClient() {
+ if (firstTick) {
+ IHLMod.proxy.requestTileEntityInitdataFromClientToServer(xCoord, yCoord, zCoord);
+ this.firstTick = false;
+ }
+ }
+
+ @Override
+ public void updateEntityServer() {
+ if (this.isGuiScreenOpened) {
+ if (this.output.isEmpty() && !outputDefined) {
+ this.workspaceElements.reset();
+ Iterator<IronWorkbenchRecipe> iwri = IronWorkbenchTileEntity.recipes.iterator();
+ while (iwri.hasNext()) {
+ IronWorkbenchRecipe recipe = iwri.next();
+ if (recipe.isCanBeCrafted(this.tools.getItemStackList(), this.inputMaterial.getItemStackList(),
+ this.workspaceElements.getItemStackList())) {
+ if (recipe.workspaceElements == null || recipe.workspaceElements.isEmpty()
+ || this.workspaceElements.containsAndCanUse(recipe.workspaceElements)) {
+ List<ItemStack> newOutputs = recipe.outputs;
+ for (IRecipeInput rinput : recipe.tools) {
+ if (rinput instanceof RecipeInputDie) {
+ newOutputs = ((RecipeInputDie) rinput)
+ .transformOutput(this.getMatchedItemStack(rinput), recipe.outputs);
+ }
+ }
+ for (IRecipeInput rinput : recipe.materials) {
+ if (rinput instanceof RecipeInputDetonator) {
+ newOutputs = ((RecipeInputDetonator) rinput)
+ .transformOutput(this.getMatchedItemStack(rinput), recipe.outputs);
+ }
+ }
+ int slot = this.output.put(newOutputs);
+ if (slot < 0)
+ break;
+ slotRecipeMap.put(slot, recipe);
+ this.startProcess = false;
+ }
+ }
+ }
+ for (int i = 0; i < this.inputMaterial.size(); i++) {
+ ItemStack stack = this.inputMaterial.get(i);
+ if (stack != null && stack.getItem() instanceof IWire) {
+ if (stack.stackTagCompound == null) {
+ stack.stackTagCompound = new NBTTagCompound();
+ }
+ int fullLength = this.getFullLengthOfSameWires(stack);
+ List<RecipeInputObjectInstance> list = this.getListOfSameWires(stack);
+ ItemStack result = stack.copy();
+ result.stackTagCompound.setInteger("length", fullLength);
+ result.stackTagCompound.setInteger("fullLength", fullLength);
+ IronWorkbenchRecipe recipe = new IronWorkbenchRecipe(null, list,
+ Arrays.asList(new ItemStack[] { result }));
+ int slot = this.output.put(recipe.outputs);
+ if (slot < 0)
+ break;
+ slotRecipeMap.put(slot, recipe);
+ this.startProcess = false;
+ break;
+ }
+ }
+ outputDefined = true;
+ } else if (!this.output.isEmpty()) {
+ Set<Integer> crafterEmptyInventorySlotsList = getCrafterEmptyInventorySlotsList();
+ if (startProcess && crafterEmptyInventorySlotsList.size() >= this.slotRecipeMap.get(currentSlot).outputs
+ .size()) {
+ if (++this.progress >= this.maxProgress) {
+ IronWorkbenchRecipe crecipe = this.slotRecipeMap.get(currentSlot);
+ List<ItemStack> opts = this.output.getRecipeOutputs(currentSlot);
+ int multiplier = this.inputMaterial.getMultiplier(crecipe.materials);
+ Iterator<ItemStack> optsi = opts.iterator();
+ Iterator<Integer> emptySlotsIterator = crafterEmptyInventorySlotsList.iterator();
+ while (optsi.hasNext()) {
+ int slot = emptySlotsIterator.next();
+ ItemStack stack = optsi.next();
+ if (stack.getItem() instanceof IWire) {
+ this.crafter.inventory.mainInventory[slot] = IHLUtils
+ .getWireItemStackCopyWithLengthMultiplied(stack, multiplier);
+ } else {
+ this.crafter.inventory.mainInventory[slot] = stack.copy();
+ this.crafter.inventory.mainInventory[slot].stackSize *= multiplier;
+ }
+ }
+ Iterator<ItemStack> emptyContainers = this.inputMaterial
+ .substract(crecipe.materials, multiplier).iterator();
+ while (emptyContainers.hasNext()) {
+ if (emptySlotsIterator.hasNext()) {
+ int slot = emptySlotsIterator.next();
+ ItemStack stack = emptyContainers.next();
+ this.crafter.inventory.mainInventory[slot] = stack.copy();
+ this.crafter.inventory.mainInventory[slot].stackSize *= multiplier;
+ } else {
+ EntityItem eistack = new EntityItem(this.worldObj, this.xCoord, this.yCoord + 1,
+ this.zCoord, emptyContainers.next());
+ this.worldObj.spawnEntityInWorld(eistack);
+ }
+ }
+ this.crafter.inventoryContainer.detectAndSendChanges();
+ this.tools.damage(crecipe.tools);
+ if (!crecipe.workspaceElements.isEmpty()) {
+ this.workspaceElements.use(crecipe.workspaceElements);
+ }
+ this.resetOutput();
+ }
+ }
+ }
+ }
+ }
+
+ private ItemStack getMatchedItemStack(IRecipeInput rinput) {
+ for (ItemStack tool : this.tools.getItemStackList()) {
+ if (rinput.matches(tool)) {
+ return tool;
+ }
+ }
+ for (ItemStack material : this.inputMaterial.getItemStackList()) {
+ if (rinput.matches(material)) {
+ return material;
+ }
+ }
+
+ return null;
+ }
+
+ private Set<Integer> getCrafterEmptyInventorySlotsList() {
+ Set<Integer> list = new HashSet<Integer>(4);
+ if (this.crafter != null) {
+ for (int var1 = 0; var1 < this.crafter.inventory.mainInventory.length; ++var1) {
+ if (this.crafter.inventory.mainInventory[var1] == null) {
+ list.add(var1);
+ }
+ }
+ }
+ return list;
+ }
+
+ private List<RecipeInputObjectInstance> getListOfSameWires(ItemStack stack1) {
+ List<RecipeInputObjectInstance> list = new ArrayList<RecipeInputObjectInstance>();
+ for (int i = 0; i < this.inputMaterial.size(); i++) {
+ ItemStack stack = this.inputMaterial.get(i);
+ if (stack != null && ((IWire) stack1.getItem()).isSameWire(stack1, stack)) {
+ list.add(new RecipeInputObjectInstance(stack));
+ }
+ }
+ return list;
+ }
+
+ private int getFullLengthOfSameWires(ItemStack stack1) {
+ int fullLength = 0;
+ for (int i = 0; i < this.inputMaterial.size(); i++) {
+ ItemStack stack = this.inputMaterial.get(i);
+ if (stack != null && ((IWire) stack1.getItem()).isSameWire(stack1, stack)) {
+ fullLength += IHLUtils.getWireLength(stack);
+ }
+ }
+ return fullLength;
+ }
+
+ @Override
+ @SideOnly(Side.CLIENT)
+ public GuiScreen getGui(EntityPlayer player, boolean arg1) {
+ return new IronWorkbenchGui(new IronWorkbenchContainer(player, this));
+ }
+
+ @Override
+ public ContainerBase<?> getGuiContainer(EntityPlayer player) {
+ resetOutput();
+ this.isGuiScreenOpened = true;
+ this.crafter = player;
+ container = new IronWorkbenchContainer(player, this);
+ return container;
+ }
+
+ @Override
+ public void onGuiClosed(EntityPlayer arg0) {
+ this.isGuiScreenOpened = false;
+ }
+
+ @Override
+ public void onNetworkEvent(EntityPlayer player, int event) {
+ if (event == 16) {
+ this.isGuiScreenOpened = false;
+ this.crafter = null;
+ this.container = null;
+ return;
+ }
+ for (int i = event; i >= 0; i--) {
+ if (this.slotRecipeMap.containsKey(i)) {
+ if (!this.slotRecipeMap.get(i).isCanBeCrafted(this.tools.getItemStackList(),
+ this.inputMaterial.getItemStackList(), this.workspaceElements.getItemStackList())) {
+ resetOutput();
+ } else {
+ this.currentSlot = i;
+ this.startProcess = true;
+ return;
+ }
+ }
+ }
+ }
+
+ public void resetOutput() {
+ this.output.clear();
+ this.slotRecipeMap.clear();
+ this.progress = 0;
+ this.startProcess = false;
+ this.currentSlot = -1;
+ this.outputDefined = false;
+ }
+
+ public void dropContents() {
+ for (int i = 0; i < this.tools.size(); i++) {
+ if (this.tools.get(i) != null)
+ this.worldObj.spawnEntityInWorld(
+ new EntityItem(this.worldObj, this.xCoord, this.yCoord + 1, this.zCoord, this.tools.get(i)));
+ }
+ for (int i = 0; i < this.inputMaterial.size(); i++) {
+ if (this.inputMaterial.get(i) != null)
+ this.worldObj.spawnEntityInWorld(new EntityItem(this.worldObj, this.xCoord, this.yCoord + 1,
+ this.zCoord, this.inputMaterial.get(i)));
+ }
+ }
+
+ @Override
+ public void onNetworkEvent(int event) {
+
+ }
+
+ public int gaugeProgressScaled(int i) {
+ return this.progress * i / this.maxProgress;
+ }
+
+ @Override
+ public boolean shouldRenderInPass(int pass) {
+ return pass == 0;
+ }
+
+ public static void removeRecipeByOutput(List<ItemStack> recipeOutputsItems) {
+ Iterator<IronWorkbenchRecipe> ri = recipes.iterator();
+ while (ri.hasNext()) {
+ IronWorkbenchRecipe recipe = ri.next();
+ boolean removeEntry = false;
+ Iterator<ItemStack> roi = recipe.outputs.iterator();
+ while (roi.hasNext()) {
+ if (IHLUtils.isItemStacksIsEqual(recipeOutputsItems.get(0), roi.next(), true)) {
+ removeEntry = true;
+ }
+ }
+ if (removeEntry) {
+ ri.remove();
+ }
+ }
+
+ }
+
+ public static void removeRecipeByInput(List<IRecipeInput> recipeInputsTools1, List<IRecipeInput> recipeInputsItems1,
+ List<ItemStack> recipeInputsMachines) {
+ List<ItemStack> recipeInputsTools = IHLUtils.convertRecipeInputToItemStackList(recipeInputsTools1);
+ List<ItemStack> recipeInputsItems = IHLUtils.convertRecipeInputToItemStackList(recipeInputsItems1);
+ Iterator<IronWorkbenchRecipe> ri = recipes.iterator();
+ while (ri.hasNext()) {
+ IronWorkbenchRecipe recipe = ri.next();
+ if (recipe.isCanBeCrafted(recipeInputsTools, recipeInputsItems, recipeInputsMachines)) {
+ ri.remove();
+ }
+ }
+ }
+
+ @Override
+ public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) {
+ this.readFromNBT(pkt.func_148857_g());
+ }
+
+}
diff --git a/src/main/java/ihl/flexible_cable/NodeEntity.java b/src/main/java/ihl/flexible_cable/NodeEntity.java
new file mode 100644
index 0000000..b734cd1
--- /dev/null
+++ b/src/main/java/ihl/flexible_cable/NodeEntity.java
@@ -0,0 +1,604 @@
+package ihl.flexible_cable;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import cpw.mods.fml.common.network.internal.FMLProxyPacket;
+import ihl.IHLMod;
+import ihl.IHLModInfo;
+import ihl.interfaces.ICableHolder;
+import ihl.interfaces.IMultiPowerCableHolder;
+import ihl.interfaces.INetworkListener;
+import ihl.items_blocks.FlexibleCableItem;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufInputStream;
+import io.netty.buffer.ByteBufOutputStream;
+import io.netty.buffer.Unpooled;
+import net.minecraft.block.Block;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.item.EntityItem;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.init.Blocks;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.AxisAlignedBB;
+import net.minecraft.util.MathHelper;
+import net.minecraft.world.World;
+import net.minecraft.world.WorldServer;
+
+public class NodeEntity extends Entity implements INetworkListener{
+
+ public NodeEntity prevAnchorEntity;
+ public Entity nextAnchorEntity;
+ private int anchorX;
+ private int anchorY;
+ private int anchorZ;
+ private short anchorFacing;
+ private int anchorDimensionId;
+ public boolean shouldFollowPlayer=false;
+ protected int chainUniqueID=-2;
+ public int chainArrangeNumber=-2;
+ protected int checkTimer=201;
+ public int colorIndex=16777215;
+ public int renderEvery=1;
+ public int type=1;//0 - uninsulated wire; 1 - insulated cable; 2 - data cable
+ public float dx0=0;
+ public float dy0=0;
+ public float dz0=0;
+ public final int n=48;
+ public final float[] rotationPitchArray = new float[n+1];
+ public final float[] rotationYawArray = new float[n+1];
+ public final float[] translationX = new float[n+1];
+ public final float[] translationY = new float[n+1];
+ public final float[] translationZ = new float[n+1];
+ public double virtualNodePosX;
+ public double virtualNodePosY;
+ public double virtualNodePosZ;
+ public double renderPosX;
+ public double renderPosY;
+ public double renderPosZ;
+ public double lastTickRenderPosX;
+ public double lastTickRenderPosY;
+ public double lastTickRenderPosZ;
+ private boolean alreadyRegistered=false;
+ private boolean shouldUpdateRender=true;
+
+ public NodeEntity(World world)
+ {
+ super(world);
+ if(world.isRemote)
+ {
+ IHLMod.proxy.addEntityToList(this);
+ this.setSize(2f, 0.2f);
+ }
+ else
+ {
+ IHLMod.proxy.addEntityToServerList(this);
+ this.setSize(0.5F, 0.1F);
+ }
+ this.renderDistanceWeight = 5.0D;
+ this.yOffset+=0.15F;
+ this.virtualNodePosX=this.posX;
+ this.virtualNodePosY=this.posY;
+ this.virtualNodePosZ=this.posZ;
+ this.motionX=0D;
+ this.motionY=0D;
+ this.motionZ=0D;
+ }
+
+ @Override
+ public void setInPortal(){}
+
+ @Override
+ public void travelToDimension(int dimensionId){}
+
+ @Override
+ public void setSize(float width, float heigth)
+ {
+ super.setSize(width, heigth);
+ }
+
+ public void setVirtualNodePos(double d,double e, double f)
+ {
+ virtualNodePosX=d;
+ virtualNodePosY=e;
+ virtualNodePosZ=f;
+ this.registerAndSendData(null);
+ }
+
+ @Override
+ public void registerAndSendData(EntityPlayerMP player)
+ {
+ if(!worldObj.isRemote)
+ {
+ if(!alreadyRegistered)
+ {
+ Set<NodeEntity> nes;
+ if(IHLMod.proxy.nodeEntityRegistry.containsKey(this.getChainUniqueID()))
+ {
+ nes=IHLMod.proxy.nodeEntityRegistry.get(this.getChainUniqueID());
+ }
+ else
+ {
+ nes=new HashSet<NodeEntity>();
+ IHLMod.proxy.nodeEntityRegistry.put(this.getChainUniqueID(),nes);
+ }
+ nes.add(this);
+ alreadyRegistered=true;
+ }
+ ByteBuf bb = Unpooled.buffer(30);
+ ByteBufOutputStream byteBufOutputStream = new ByteBufOutputStream(bb);
+ try
+ {
+ byteBufOutputStream.write(1);
+ byteBufOutputStream.writeInt(this.getEntityId());
+ byteBufOutputStream.writeInt(this.getChainUniqueID());
+ byteBufOutputStream.writeInt(this.chainArrangeNumber);
+ byteBufOutputStream.writeByte(this.type);
+ byteBufOutputStream.writeInt(this.colorIndex);
+ byteBufOutputStream.writeDouble(this.virtualNodePosX);
+ byteBufOutputStream.writeDouble(this.virtualNodePosY);
+ byteBufOutputStream.writeDouble(this.virtualNodePosZ);
+ byteBufOutputStream.writeBoolean(this.shouldFollowPlayer);
+ if(player==null)
+ {
+ IHLMod.proxy.sendFromServerToAll(new FMLProxyPacket(byteBufOutputStream.buffer(), IHLModInfo.MODID));
+ }
+ else
+ {
+ IHLMod.proxy.sendFromServerToPlayer(new FMLProxyPacket(byteBufOutputStream.buffer(), IHLModInfo.MODID),player);
+ }
+ byteBufOutputStream.close();
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void onUpdate()
+ {
+ super.onUpdate();
+ if(this.checkTimer==201)
+ {
+ if(worldObj.isRemote)
+ {
+ IHLMod.proxy.recieveDelayedDataPacket(this);
+ }
+ else
+ {
+ this.registerAndSendData(null);
+ }
+ }
+ if(prevAnchorEntity==null||(nextAnchorEntity==null || nextAnchorEntity instanceof EntityPlayer || nextAnchorEntity instanceof EntityItem))
+ {
+ double range = 16D;
+ AxisAlignedBB searchArea = AxisAlignedBB.getBoundingBox(this.posX-range,this.posY-range,this.posZ-range,this.posX+range,this.posY+range,this.posZ+range);
+ List<NodeEntity> eItemsList = this.worldObj.getEntitiesWithinAABB(NodeEntity.class, searchArea);
+ if(!eItemsList.isEmpty())
+ {
+ Iterator<NodeEntity> ei = eItemsList.iterator();
+ while(ei.hasNext())
+ {
+ NodeEntity node=(NodeEntity) ei.next();
+ if(node.getChainUniqueID()==this.getChainUniqueID())
+ {
+ if(node.chainArrangeNumber==this.chainArrangeNumber-1)
+ {
+ this.prevAnchorEntity=node;
+ node.nextAnchorEntity=this;
+ node.shouldFollowPlayer=false;
+ }
+ else if(node.chainArrangeNumber==this.chainArrangeNumber+1)
+ {
+ this.nextAnchorEntity=node;
+ this.shouldFollowPlayer=false;
+ node.prevAnchorEntity=this;
+ }
+ }
+ if(prevAnchorEntity!=null && nextAnchorEntity!=null)
+ {
+ break;
+ }
+ }
+ }
+ }
+ if(this.shouldFollowPlayer && (this.nextAnchorEntity == null || this.nextAnchorEntity.isDead))
+ {
+ double range = 16D;
+ AxisAlignedBB searchArea = AxisAlignedBB.getBoundingBox(this.posX-range,this.posY-range,this.posZ-range,this.posX+range,this.posY+range,this.posZ+range);
+ List<EntityPlayer> eItemsList = this.worldObj.getEntitiesWithinAABB(EntityPlayer.class, searchArea);
+ if(!eItemsList.isEmpty())
+ {
+ Iterator<EntityPlayer> ei = eItemsList.iterator();
+ while(ei.hasNext())
+ {
+ EntityPlayer player=(EntityPlayer) ei.next();
+ if(this.playerHasItemStack(player))
+ {
+ this.nextAnchorEntity=player;
+ }
+
+ }
+ }
+ }
+ if(this.shouldFollowPlayer && this.nextAnchorEntity instanceof EntityPlayer)
+ {
+ EntityPlayer player = (EntityPlayer) this.nextAnchorEntity;
+ if(!this.playerHasItemStack(player))
+ {
+ double range = 16D;
+ AxisAlignedBB searchArea = AxisAlignedBB.getBoundingBox(this.posX-range,this.posY-range,this.posZ-range,this.posX+range,this.posY+range,this.posZ+range);
+ List<EntityItem> eItemsList = this.worldObj.getEntitiesWithinAABB(EntityItem.class, searchArea);
+ if(!eItemsList.isEmpty())
+ {
+ Iterator<EntityItem> ei = eItemsList.iterator();
+ while(ei.hasNext())
+ {
+ EntityItem eitem = ei.next();
+ if(this.isItemHasSameChainId(eitem.getEntityItem()))
+ {
+ this.nextAnchorEntity=eitem;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if(nextAnchorEntity!=null && this.getDistanceSqToEntity(nextAnchorEntity)>2D)
+ {
+ this.nextAnchorEntity.addVelocity((this.posX-this.nextAnchorEntity.posX)*0.02D, (this.posY-this.nextAnchorEntity.posY)*0.02D, (this.posZ-this.nextAnchorEntity.posZ)*0.02D);
+ }
+ if(!worldObj.isRemote)
+ {
+ double x0,x2,y0,y2,z0,z2;
+ x2=x0=this.virtualNodePosX;
+ y2=y0=this.virtualNodePosY;
+ z2=z0=this.virtualNodePosZ;
+ if(nextAnchorEntity!=null)
+ {
+ x2=nextAnchorEntity.posX;
+ y2=nextAnchorEntity.posY;
+ z2=nextAnchorEntity.posZ;
+ }
+ if(prevAnchorEntity!=null)
+ {
+ x0=prevAnchorEntity.posX;
+ y0=prevAnchorEntity.posY;
+ z0=prevAnchorEntity.posZ;
+ }
+ double d1 = (x0-x2)*(x0-x2)+(y0-y2)*(y0-y2)+(z0-z2)*(z0-z2);
+ if(d1>4D)
+ {
+ this.motionX+=(x0+x2)*0.05D-this.posX*0.1D;
+ this.motionY+=(y0+y2)*0.05D-this.posY*0.1D;
+ this.motionZ+=(z0+z2)*0.05D-this.posZ*0.1D;
+ }
+ else
+ {
+ double d2 = this.getDistanceSq(x2,y2,z2);
+ if(d2>1D)
+ {
+ this.motionX+=(x2-this.posX)*0.01D;
+ this.motionY+=(y2-this.posY)*0.01D;
+ this.motionZ+=(z2-this.posZ)*0.01D;
+ }
+ double d3 = this.getDistanceSq(x0,y0,z0);
+ if(d3>1D)
+ {
+ this.motionX+=(x0-this.posX)*0.01D;
+ this.motionY+=(y0-this.posY)*0.01D;
+ this.motionZ+=(z0-this.posZ)*0.01D;
+ }
+ }
+ this.motionY-=0.005D;
+ this.motionX*=0.8D;
+ this.motionY*=0.8D;
+ this.motionZ*=0.8D;
+ this.moveEntity(this.motionX, this.motionY, this.motionZ);
+ }
+ if(this.onGround)
+ {
+ this.motionY *= -0.5D;
+ }
+ if(worldObj.isRemote)
+ {
+ this.lastTickRenderPosX=this.renderPosX;
+ this.lastTickRenderPosY=this.renderPosY;
+ this.lastTickRenderPosZ=this.renderPosZ;
+ this.renderPosX=(float) this.prevPosX;
+ this.renderPosY=(float) this.prevPosY;
+ this.renderPosZ=(float) this.prevPosZ;
+ shouldUpdateRender=
+ Math.abs(this.lastTickRenderPosX-this.renderPosX)+
+ Math.abs(this.lastTickRenderPosY-this.renderPosY)+
+ Math.abs(this.lastTickRenderPosZ-this.renderPosZ)>0.01f;
+
+ float xi,yi,zi;
+ float x0=xi=(float)this.prevPosX;
+ float y0=yi=(float)this.prevPosY;
+ float z0=zi=(float)this.prevPosZ;
+ float dx0=this.dx0;
+ float dy0=this.dy0;
+ float dz0=this.dz0;
+ float dx1=(float) (this.virtualNodePosX-xi);
+ float dy1=(float) (this.virtualNodePosY-yi);
+ float dz1=(float) (this.virtualNodePosZ-zi);
+ if(this.nextAnchorEntity!=null)
+ {
+ dx1=(float) (this.nextAnchorEntity.prevPosX-xi);
+ dy1=(float) (this.nextAnchorEntity.prevPosY-yi);
+ dz1=(float) (this.nextAnchorEntity.prevPosZ-zi);
+ }
+ if(this.prevAnchorEntity==null)
+ {
+ this.renderPosX=this.virtualNodePosX;
+ this.renderPosY=this.virtualNodePosY;
+ this.renderPosZ=this.virtualNodePosZ;
+ x0=xi=(float) this.virtualNodePosX;
+ y0=yi=(float) this.virtualNodePosY;
+ z0=zi=(float) this.virtualNodePosZ;
+ }
+ if(this.nextAnchorEntity instanceof NodeEntity)
+ {
+ shouldUpdateRender=this.shouldUpdateRender || ((NodeEntity)this.nextAnchorEntity).shouldUpdateRender;
+ if(((NodeEntity)this.nextAnchorEntity).nextAnchorEntity!=null)
+ {
+ Entity nne = ((NodeEntity)this.nextAnchorEntity).nextAnchorEntity;
+ dx1=(float) (nne.prevPosX-xi);
+ dy1=(float) (nne.prevPosY-yi);
+ dz1=(float) (nne.prevPosZ-zi);
+ }
+ else
+ {
+ dx1=(float) (((NodeEntity) this.nextAnchorEntity).virtualNodePosX-xi);
+ dy1=(float) (((NodeEntity) this.nextAnchorEntity).virtualNodePosY-yi);
+ dz1=(float) (((NodeEntity) this.nextAnchorEntity).virtualNodePosZ-zi);
+ }
+ }
+ if(shouldUpdateRender)
+ {
+ float x1=(float) this.virtualNodePosX;
+ float y1=(float) this.virtualNodePosY;
+ float z1=(float) this.virtualNodePosZ;
+ if(this.nextAnchorEntity!=null)
+ {
+ if(nextAnchorEntity instanceof NodeEntity)
+ {
+ x1=(float) ((NodeEntity) nextAnchorEntity).renderPosX;
+ y1=(float) ((NodeEntity) nextAnchorEntity).renderPosY;
+ z1=(float) ((NodeEntity) nextAnchorEntity).renderPosZ;
+ }
+ else
+ {
+ x1=(float) nextAnchorEntity.posX;
+ y1=(float) nextAnchorEntity.posY;
+ z1=(float) nextAnchorEntity.posZ;
+ }
+ }
+ float d = (x0-x1)*(x0-x1)+(y0-y1)*(y0-y1)+(z0-z1)*(z0-z1);
+ if(d>2f)
+ {
+ renderEvery=1;
+ }/*
+ else if(d>0.5f)
+ {
+ renderEvery=2;
+ }
+ else
+ {
+ renderEvery=4;
+ }*/
+ int i1=0;
+ for(float i=1f/n;i<=1f+1f/n;i+=((float)renderEvery)/n,i1+=renderEvery)
+ {
+ float dxi = xi;
+ float dyi = yi;
+ float dzi = zi;
+ xi=(dx1-2*x1+2*dx0+2*x0-dx0)*i*i*i+(3*x1-dx1-3*dx0-3*x0+dx0)*i*i+dx0*i+x0;
+ yi=(dy1-2*y1+2*dy0+2*y0-dy0)*i*i*i+(3*y1-dy1-3*dy0-3*y0+dy0)*i*i+dy0*i+y0;
+ zi=(dz1-2*z1+2*dz0+2*z0-dz0)*i*i*i+(3*z1-dz1-3*dz0-3*z0+dz0)*i*i+dz0*i+z0;
+ dxi-=xi;
+ dyi-=yi;
+ dzi-=zi;
+ double var7 = MathHelper.sqrt_double(dxi * dxi + dzi * dzi);
+ float rotationPitch = (float) Math.atan2(dxi, dzi);
+ float rotationYaw = (float) (-Math.atan2(dyi, var7));
+ rotationPitchArray[i1]=rotationPitch;
+ rotationYawArray[i1]=rotationYaw;
+ translationX[i1]=dxi;
+ translationY[i1]=dyi;
+ translationZ[i1]=dzi;
+ }
+ if(this.nextAnchorEntity instanceof NodeEntity)
+ {
+ NodeEntity next = (NodeEntity) this.nextAnchorEntity;
+ next.dx0=dx1;
+ next.dy0=dy1;
+ next.dz0=dz1;
+ }
+ }
+ }
+ if(--this.checkTimer<=0)
+ {
+ if(!worldObj.isRemote)
+ {
+ WorldServer world = MinecraftServer.getServer().worldServerForDimension(this.anchorDimensionId);
+ TileEntity te = world.getTileEntity(this.anchorX, this.anchorY, this.anchorZ);
+ if(te==null || !(te instanceof ICableHolder || te instanceof IMultiPowerCableHolder))
+ {
+ this.setDead();
+ }
+ else
+ {
+ if(te instanceof ICableHolder)
+ {
+ if(((ICableHolder)te).isCableRemoved(this.chainUniqueID))
+ {
+ this.setDead();
+ }
+ }
+ if(te instanceof IMultiPowerCableHolder)
+ {
+ if(((IMultiPowerCableHolder)te).isCableRemoved(this.chainUniqueID))
+ {
+ this.setDead();
+ }
+ }
+ }
+ }
+ this.checkTimer=200;
+ }
+ }
+
+ @Override
+ protected void readEntityFromNBT(NBTTagCompound nbt)
+ {
+ this.setChainUniqueID(nbt.getInteger("chainUniqueID"));
+ this.chainArrangeNumber=nbt.getInteger("chainArrangeNumber");
+ this.anchorX=nbt.getInteger("anchorX");
+ this.anchorY=nbt.getInteger("anchorY");
+ this.anchorZ=nbt.getInteger("anchorZ");
+ this.anchorFacing=nbt.getShort("anchorFacing");
+ this.anchorDimensionId=nbt.getInteger("anchorDimensionId");
+ this.type=nbt.getInteger("type");
+ this.colorIndex=nbt.getInteger("colorIndex");
+ this.shouldFollowPlayer=nbt.getBoolean("shouldFollowPlayer");
+ if(nbt.hasKey("width"))
+ {
+ this.setSize(nbt.getFloat("width"), nbt.getFloat("height"));
+ }
+ this.virtualNodePosX=nbt.getDouble("virtualNodePosX");
+ this.virtualNodePosY=nbt.getDouble("virtualNodePosY");
+ this.virtualNodePosZ=nbt.getDouble("virtualNodePosZ");
+ }
+
+ @Override
+ protected void writeEntityToNBT(NBTTagCompound nbt)
+ {
+ nbt.setFloat("width", this.width);
+ nbt.setFloat("height", this.height);
+ nbt.setInteger("chainUniqueID", this.getChainUniqueID());
+ nbt.setInteger("chainArrangeNumber", this.chainArrangeNumber);
+ nbt.setInteger("anchorX", this.anchorX);
+ nbt.setInteger("anchorY", this.anchorY);
+ nbt.setInteger("anchorZ", this.anchorZ);
+ nbt.setShort("anchorFacing",this.anchorFacing);
+ nbt.setInteger("anchorDimensionId",this.anchorDimensionId);
+ nbt.setInteger("type", this.type);
+ nbt.setInteger("colorIndex", this.colorIndex);
+ nbt.setBoolean("shouldFollowPlayer",this.shouldFollowPlayer);
+ nbt.setDouble("virtualNodePosX",this.virtualNodePosX);
+ nbt.setDouble("virtualNodePosY",this.virtualNodePosY);
+ nbt.setDouble("virtualNodePosZ",this.virtualNodePosZ);
+ }
+
+ public void setAnchor(int x, int y, int z, short facing, int dimensionId)
+ {
+ this.anchorX=x;
+ this.anchorY=y;
+ this.anchorZ=z;
+ this.anchorFacing=facing;
+ this.anchorDimensionId=dimensionId;
+ }
+
+ public boolean playerHasItemStack(EntityPlayer player)
+ {
+ int var2;
+ for (var2 = 0; var2 < player.inventory.mainInventory.length; ++var2)
+ {
+ if(this.isItemHasSameChainId(player.inventory.mainInventory[var2]))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean isItemHasSameChainId(ItemStack itemStack)
+ {
+ if(itemStack!=null)
+ {
+ if(itemStack.getItem() instanceof FlexibleCableItem)
+ {
+ return itemStack.stackTagCompound.getInteger("chainUID") == this.chainUniqueID;
+ }
+ }
+ return false;
+ }
+
+ public int getChainUniqueID() {
+ return chainUniqueID;
+ }
+
+ public void setChainUniqueID(int chainUniqueID) {
+ this.chainUniqueID = chainUniqueID;
+ }
+
+ @Override
+ public int getId()
+ {
+ return this.getEntityId();
+ }
+
+ @Override
+ public void recieveData(ByteBufInputStream byteBufInputStream)
+ {
+ try
+ {
+ this.setChainUniqueID(byteBufInputStream.readInt());
+ this.chainArrangeNumber=byteBufInputStream.readInt();
+ this.type=byteBufInputStream.readByte();
+ this.colorIndex=byteBufInputStream.readInt();
+ this.virtualNodePosX=byteBufInputStream.readDouble();
+ this.virtualNodePosY=byteBufInputStream.readDouble();
+ this.virtualNodePosZ=byteBufInputStream.readDouble();
+ this.shouldFollowPlayer=byteBufInputStream.readBoolean();
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ protected void entityInit() {}
+
+ @Override
+ public boolean isInvalid()
+ {
+ return this.isDead;
+ }
+
+ public void setVirtualNodePosToNearestPortal()
+ {
+ int x0 = (int)this.posX;
+ int y0 = (int)this.posY;
+ int z0 = (int)this.posZ;
+ for(int xi=x0-2;xi<=x0+2;xi++)
+ {
+ for(int yi=y0-2;yi<=y0+2;yi++)
+ {
+ for(int zi=z0-2;zi<=z0+2;zi++)
+ {
+ Block block = worldObj.getBlock(xi, yi, zi);
+ if(block==Blocks.portal||block==Blocks.end_portal)
+ {
+ this.setVirtualNodePos(xi+0.5d, yi+0.5d, zi+0.5d);
+ return;
+ }
+ }
+ }
+ }
+
+ }
+}
diff --git a/src/main/java/ihl/flexible_cable/NodeRender.java b/src/main/java/ihl/flexible_cable/NodeRender.java
new file mode 100644
index 0000000..c27f11a
--- /dev/null
+++ b/src/main/java/ihl/flexible_cable/NodeRender.java
@@ -0,0 +1,76 @@
+package ihl.flexible_cable;
+
+import org.lwjgl.opengl.GL11;
+
+import ihl.IHLModInfo;
+import ihl.model.ModelTube;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.client.renderer.entity.Render;
+import net.minecraft.client.renderer.entity.RenderManager;
+import net.minecraft.entity.Entity;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.common.util.ForgeDirection;
+
+public class NodeRender extends Render
+{
+
+ private ModelTube model;
+ private ModelTube modelThin;
+ private ResourceLocation tex;
+ private float scale;
+
+ public NodeRender()
+ {
+ super();
+ scale = 1F/16F;
+ model=new ModelTube(null, 0, 0, -4F, -4F, -3F, 8, 8, 6,0f, 0.5f,0.99f, ForgeDirection.NORTH);
+ modelThin=new ModelTube(null, 0, 0, -1F, -1F, -3F, 2, 2, 6,0f, 0f,0.99f, ForgeDirection.NORTH);
+ tex = new ResourceLocation(IHLModInfo.MODID+":textures/blocks/junctionBox.png");
+ }
+
+ @Override
+ public void doRender(Entity entity, double x1, double y1, double z1, float rotationYaw, float iFrame)
+ {
+ bindTexture(tex);
+ GL11.glPushMatrix();
+ NodeEntity ne = (NodeEntity) entity;
+ float x = (float) (ne.lastTickRenderPosX + (ne.renderPosX-ne.lastTickRenderPosX)*iFrame-RenderManager.renderPosX);
+ float y = (float) (ne.lastTickRenderPosY + (ne.renderPosY-ne.lastTickRenderPosY)*iFrame-RenderManager.renderPosY);
+ float z = (float) (ne.lastTickRenderPosZ + (ne.renderPosZ-ne.lastTickRenderPosZ)*iFrame-RenderManager.renderPosZ);
+ GL11.glTranslatef(x, y, z);
+ GL11.glScalef(0.25F, -0.25F, -0.25F);
+ int red = ne.colorIndex>>16;
+ int green = (ne.colorIndex>>8) & 255;
+ int blue = ne.colorIndex & 255;
+ for(int i=0;i<ne.n;i+=ne.renderEvery)
+ {
+ GL11.glRotatef(-ne.rotationPitchArray[i] * (180F / (float)Math.PI), 0.0F, 1.0F, 0.0F);
+ GL11.glRotatef(ne.rotationYawArray[i] * (180F / (float)Math.PI), 1.0F, 0.0F, 0.0F);
+ float cc=ne.rotationYawArray[i]*0.25f;
+ float red1 = Math.min(Math.max(red/255f+cc,red/511f),1f);
+ float green1 = Math.min(Math.max(green/255f+cc,green/511f),1f);
+ float blue1 = Math.min(Math.max(blue/255f+cc,blue/511f),1f);
+ GL11.glColor3f(red1, green1, blue1);
+ if(ne.type==0)
+ {
+ modelThin.renderCached(Tessellator.instance, scale);
+ }
+ else
+ {
+ model.renderCached(Tessellator.instance, scale);
+ }
+ GL11.glRotatef(-ne.rotationYawArray[i] * (180F / (float)Math.PI), 1.0F, 0.0F, 0.0F);
+ GL11.glRotatef(ne.rotationPitchArray[i] * (180F / (float)Math.PI), 0.0F, 1.0F, 0.0F);
+ GL11.glTranslatef(-ne.translationX[i]*4f, ne.translationY[i]*4f, ne.translationZ[i]*4f);
+ }
+
+ GL11.glPopMatrix(); //end
+ }
+
+ @Override
+ protected ResourceLocation getEntityTexture(Entity arg0)
+ {
+ return this.tex;
+ }
+}
+ \ No newline at end of file
diff --git a/src/main/java/ihl/flexible_cable/PowerCableNodeEntity.java b/src/main/java/ihl/flexible_cable/PowerCableNodeEntity.java
new file mode 100644
index 0000000..346b86c
--- /dev/null
+++ b/src/main/java/ihl/flexible_cable/PowerCableNodeEntity.java
@@ -0,0 +1,243 @@
+package ihl.flexible_cable;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import ic2.core.IC2DamageSource;
+import ic2.core.item.armor.ItemArmorHazmat;
+import ihl.IHLMod;
+import ihl.IHLModInfo;
+import ihl.interfaces.IEnergyNetNode;
+import ihl.utils.IHLUtils;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.network.play.server.S29PacketSoundEffect;
+import net.minecraft.network.play.server.S2APacketParticles;
+import net.minecraft.util.AxisAlignedBB;
+import net.minecraft.world.World;
+
+public class PowerCableNodeEntity extends NodeEntity implements IEnergyNetNode{
+
+ private Set<IHLCable> cableList;
+ private IHLCable cable;
+ private double soundRange=10d;
+ private final static float groundConductivity=0.005f;
+ private int lastCheckTimer=0;
+
+ public PowerCableNodeEntity(World world)
+ {
+ super(world);
+ }
+
+ @Override
+ public boolean canBeCollidedWith()
+ {
+ return !worldObj.isRemote && !this.noClip;
+ }
+
+ @Override
+ public boolean canBePushed()
+ {
+ return !worldObj.isRemote && !this.noClip;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void onUpdate()
+ {
+ super.onUpdate();
+ if(!worldObj.isRemote)
+ {
+ IHLGrid grid = IHLMod.enet.cablesToGrids.get(this.chainUniqueID);
+ if(grid!=null && grid.energy>0d)
+ {
+ double voltage = grid.getSinkVoltage(this);
+ if(this.onGround && voltage>=10d && this.getMaxAllowableVoltage()<voltage)
+ {
+ grid.drawEnergy(voltage*voltage*groundConductivity, this);
+ if(Math.abs(lastCheckTimer-checkTimer) > 10)
+ {
+ for(Object player:worldObj.getEntitiesWithinAABB(EntityPlayerMP.class, AxisAlignedBB.getBoundingBox(this.posX-soundRange,this.posY-soundRange,this.posZ-soundRange, this.posX+soundRange,this.posY+soundRange,this.posZ+soundRange)))
+ {
+ if(player instanceof EntityPlayerMP)
+ {
+ EntityPlayerMP playerMP = (EntityPlayerMP)player;
+ playerMP.playerNetServerHandler.sendPacket(new S2APacketParticles("largesmoke",(float)this.posX,(float)this.posY,(float)this.posZ,worldObj.rand.nextFloat()*0.1f-0.05f,0.1f,worldObj.rand.nextFloat()*0.1f-0.05f,0.1f,4));
+ }
+ }
+ lastCheckTimer=checkTimer;
+ }
+ }
+ if(this.nextAnchorEntity!=null)
+ {
+ List<EntityLivingBase> entityList = worldObj.getEntitiesWithinAABB(EntityLivingBase.class, this.boundingBox.expand(4d, 4d,4d));
+ for(EntityLivingBase elb:entityList)
+ {
+ if(elb.boundingBox!=null)
+ {
+ if(IHLUtils.isSegmentInsideAABB(elb.boundingBox,this.posX,this.posY,this.posZ,this.nextAnchorEntity.posX,this.nextAnchorEntity.posY,this.nextAnchorEntity.posZ))
+ {
+ this.applyEntityCollision(elb);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public AxisAlignedBB getCollisionBox(Entity entity)
+ {
+ return boundingBox;
+ }
+
+
+ @Override
+ public void applyEntityCollision(Entity entity)
+ {
+ super.applyEntityCollision(entity);
+ IHLGrid grid = IHLMod.enet.cablesToGrids.get(this.chainUniqueID);
+ if(entity instanceof EntityLivingBase && grid!=null && grid.energy>=1d)
+ {
+ double voltage = grid.getSinkVoltage(this);
+ if(this.getMaxAllowableVoltage()<voltage)
+ {
+ EntityLivingBase victim=(EntityLivingBase) entity;
+ if (!ItemArmorHazmat.hasCompleteHazmat(victim))
+ {
+ float damage=(float)Math.min(voltage*groundConductivity,grid.energy*1000d/voltage);
+ victim.attackEntityFrom(IC2DamageSource.electricity, damage);
+ grid.drawEnergy(damage*voltage/1000d, this);
+ if(voltage>1000)
+ {
+ sendSound();
+ IHLMod.proxy.spawnParticleFromServer(3,worldObj, (float)this.posX,(float)this.posY,(float)this.posZ,0f,0f,0f,10f);
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ protected void readEntityFromNBT(NBTTagCompound nbt)
+ {
+ super.readEntityFromNBT(nbt);
+ if(nbt.hasKey("cable"))
+ {
+ this.addCable(nbt.getCompoundTag("cable"));
+ }
+ }
+
+ @Override
+ protected void writeEntityToNBT(NBTTagCompound nbt)
+ {
+ super.writeEntityToNBT(nbt);
+ if(this.cable!=null)
+ {
+ nbt.setTag("cable",this.cable.toNBT());
+ }
+ }
+
+ @Override
+ public IHLGrid getGrid()
+ {
+ return IHLMod.enet.cablesToGrids.get(this.chainUniqueID);
+ }
+
+ @Override
+ public int getGridID()
+ {
+ return 0;
+ }
+
+ @Override
+ public void setGrid(int newGridID) {}
+
+ @Override
+ public double getMaxAllowableVoltage()
+ {
+ if(this.cable!=null)
+ {
+ return this.cable.maxVoltage;
+ }
+ else
+ {
+ return Integer.MAX_VALUE;
+ }
+ }
+
+ @Override
+ public boolean addCable(NBTTagCompound cable1)
+ {
+ this.cable=IHLCable.fromNBT(cable1);
+ return true;
+ }
+
+ @Override
+ public Set<IHLCable> getCableList() {
+ if(cableList==null)
+ {
+ cableList=new HashSet<IHLCable>(1);
+ if(this.cable!=null)
+ {
+ cableList.add(this.cable);
+ }
+ }
+ return cableList;
+ }
+
+ @Override
+ public void removeAttachedChains() {}
+
+ public void sendSound()
+ {
+ for(Object player:worldObj.getEntitiesWithinAABB(EntityPlayerMP.class, AxisAlignedBB.getBoundingBox(this.posX-soundRange,this.posY-soundRange,this.posZ-soundRange, this.posX+soundRange,this.posY+soundRange,this.posZ+soundRange)))
+ {
+ if(player instanceof EntityPlayerMP)
+ {
+ EntityPlayerMP playerMP = (EntityPlayerMP)player;
+ playerMP.playerNetServerHandler.sendPacket(new S29PacketSoundEffect(IHLModInfo.MODID+":electrocution",this.posX,this.posY,this.posZ,1f,1f));
+ }
+ }
+ }
+
+ @Override
+ public double[] getPortPos(EntityLivingBase player)
+ {
+ return new double[3];
+ }
+
+ @Override
+ public void remove(IHLCable cable)
+ {
+ this.cableList.remove(cable);
+ }
+
+ @Override
+ public boolean isCableRemoved(int chainUniqueID)
+ {
+ return false;
+ }
+
+ @Override
+ public void setCableCheck(boolean b) {}
+
+ @Override
+ public double getEnergyAmountThisNodeWant()
+ {
+ return 0;
+ }
+
+ @Override
+ public void injectEnergyInThisNode(double amount, double voltage) {}
+
+ @Override
+ public boolean isTileEntityBaseInvalid() {
+ return this.isDead;
+ }
+
+}
diff --git a/src/main/java/ihl/flexible_cable/RectifierTransformerUnitTileEntity.java b/src/main/java/ihl/flexible_cable/RectifierTransformerUnitTileEntity.java
new file mode 100644
index 0000000..60a5a76
--- /dev/null
+++ b/src/main/java/ihl/flexible_cable/RectifierTransformerUnitTileEntity.java
@@ -0,0 +1,336 @@
+package ihl.flexible_cable;
+
+import java.util.List;
+
+import ic2.api.energy.event.EnergyTileLoadEvent;
+import ic2.api.energy.event.EnergyTileUnloadEvent;
+import ic2.api.energy.tile.IEnergySink;
+import ic2.api.network.INetworkClientTileEntityEventListener;
+import ic2.core.IC2;
+import ic2.core.block.TileEntityInventory;
+import ihl.interfaces.IEnergyNetNode;
+import ihl.interfaces.IMultiPowerCableHolder;
+import ihl.utils.IHLUtils;
+import net.minecraft.entity.player.EntityPlayer;
+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.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.common.util.ForgeDirection;
+
+public class RectifierTransformerUnitTileEntity extends TileEntityInventory implements INetworkClientTileEntityEventListener, IEnergySink, IMultiPowerCableHolder {
+
+ public boolean addedToEnergyNet=false;
+ public SubRTUEnergyNetNode[] energyNetNodes = new SubRTUEnergyNetNode[2];
+ public float mode = 1f;
+ public static float modeMultiplier = 2f;
+ public static float modeMax = 128f;
+ public static float modeMin = 1/modeMax;
+ public AxisAlignedBB aabb1;// Input zone "0"
+ public AxisAlignedBB aabb2;// Output zone "1"
+ public AxisAlignedBB aabb1_1;
+ public AxisAlignedBB aabb2_1;
+ public boolean checkCables=true;
+
+ public RectifierTransformerUnitTileEntity()
+ {
+ super();
+ for(short i=0;i<2;i++)
+ {
+ energyNetNodes[i] = new SubRTUEnergyNetNode(this, i);
+ }
+ aabb1 = AxisAlignedBB.getBoundingBox(this.xCoord, this.yCoord+1d, this.zCoord, this.xCoord+0.5d, this.yCoord+1.1d, this.zCoord+1d);
+ aabb2 = AxisAlignedBB.getBoundingBox(this.xCoord+0.5d, this.yCoord+1d, this.zCoord, this.xCoord+1d, this.yCoord+1.1d, this.zCoord+1d);
+ aabb1_1 = AxisAlignedBB.getBoundingBox(this.xCoord+0.2d, this.yCoord+1.4d, this.zCoord+0.45d, this.xCoord+0.3d, this.yCoord+1.5d, this.zCoord+0.55d);
+ aabb2_1 = AxisAlignedBB.getBoundingBox(this.xCoord+0.7d, this.yCoord+1.4d, this.zCoord+0.45d, this.xCoord+0.8d, this.yCoord+1.5d, this.zCoord+0.55d);
+ }
+
+ @Override
+ public void onLoaded()
+ {
+ super.onLoaded();
+ for(short i=0;i<2;i++)
+ {
+ energyNetNodes[i].onLoaded();
+ }
+ if (IC2.platform.isSimulating()&&!this.addedToEnergyNet)
+ {
+ MinecraftForge.EVENT_BUS.post(new EnergyTileLoadEvent(this));
+ this.addedToEnergyNet = true;
+ }
+ this.setupInteractingSpots(this.getFacing());
+ }
+
+ @Override
+ public void onUnloaded()
+ {
+ for(short i=0;i<2;i++)
+ {
+ energyNetNodes[i].onUnloaded();
+ }
+ if (IC2.platform.isSimulating() && this.addedToEnergyNet)
+ {
+ MinecraftForge.EVENT_BUS.post(new EnergyTileUnloadEvent(this));
+ this.addedToEnergyNet = false;
+ }
+ super.onUnloaded();
+ }
+
+ @Override
+ public List<String> getNetworkedFields()
+ {
+ List<String> fields = super.getNetworkedFields();
+ fields.add("mode");
+ return fields;
+ }
+
+ @Override
+ public void setFacing(short facing1)
+ {
+ this.removeAttachedChains();
+ short facing2 = (short) Math.max(facing1, 2);
+ super.setFacing(facing2);
+ this.setupInteractingSpots(facing2);
+ }
+
+ public void setupInteractingSpots(short facing2)
+ {
+ double yStart=this.yCoord+0.98d;
+ switch (facing2)
+ {
+ case 2:
+ aabb1 = AxisAlignedBB.getBoundingBox(this.xCoord, yStart, this.zCoord, this.xCoord+0.5d, this.yCoord+1.1d, this.zCoord+1d);
+ aabb2 = AxisAlignedBB.getBoundingBox(this.xCoord+0.5d, yStart, this.zCoord, this.xCoord+1d, this.yCoord+1.1d, this.zCoord+1d);
+ aabb1_1 = AxisAlignedBB.getBoundingBox(this.xCoord+0.2d, this.yCoord+1.4d, this.zCoord+0.45d, this.xCoord+0.3d, this.yCoord+1.5d, this.zCoord+0.55d);
+ aabb2_1 = AxisAlignedBB.getBoundingBox(this.xCoord+0.7d, this.yCoord+1.4d, this.zCoord+0.45d, this.xCoord+0.8d, this.yCoord+1.5d, this.zCoord+0.55d);
+ break;
+ case 5:
+ aabb1 = AxisAlignedBB.getBoundingBox(this.xCoord, yStart, this.zCoord, this.xCoord+1d, this.yCoord+1.1d, this.zCoord+0.5d);
+ aabb2 = AxisAlignedBB.getBoundingBox(this.xCoord, yStart, this.zCoord+0.5d, this.xCoord+1d, this.yCoord+1.1d, this.zCoord+1d);
+ aabb1_1 = AxisAlignedBB.getBoundingBox(this.xCoord+0.45d, this.yCoord+1.4d, this.zCoord+0.2d, this.xCoord+0.55d, this.yCoord+1.5d, this.zCoord+0.3d);
+ aabb2_1 = AxisAlignedBB.getBoundingBox(this.xCoord+0.45d, this.yCoord+1.4d, this.zCoord+0.7d, this.xCoord+0.55d, this.yCoord+1.5d, this.zCoord+0.8d);
+ break;
+ case 3:
+ aabb2 = AxisAlignedBB.getBoundingBox(this.xCoord, yStart, this.zCoord, this.xCoord+0.5d, this.yCoord+1.1d, this.zCoord+1d);
+ aabb1 = AxisAlignedBB.getBoundingBox(this.xCoord+0.5d, yStart, this.zCoord, this.xCoord+1d, this.yCoord+1.1d, this.zCoord+1d);
+ aabb2_1 = AxisAlignedBB.getBoundingBox(this.xCoord+0.2d, this.yCoord+1.4d, this.zCoord+0.45d, this.xCoord+0.3d, this.yCoord+1.5d, this.zCoord+0.55d);
+ aabb1_1 = AxisAlignedBB.getBoundingBox(this.xCoord+0.7d, this.yCoord+1.4d, this.zCoord+0.45d, this.xCoord+0.8d, this.yCoord+1.5d, this.zCoord+0.55d);
+ break;
+ case 4:
+ aabb2 = AxisAlignedBB.getBoundingBox(this.xCoord, yStart, this.zCoord, this.xCoord+1d, this.yCoord+1.1d, this.zCoord+0.5d);
+ aabb1 = AxisAlignedBB.getBoundingBox(this.xCoord, yStart, this.zCoord+0.5d, this.xCoord+1d, this.yCoord+1.1d, this.zCoord+1d);
+ aabb2_1 = AxisAlignedBB.getBoundingBox(this.xCoord+0.45d, this.yCoord+1.4d, this.zCoord+0.2d, this.xCoord+0.55d, this.yCoord+1.5d, this.zCoord+0.3d);
+ aabb1_1 = AxisAlignedBB.getBoundingBox(this.xCoord+0.45d, this.yCoord+1.4d, this.zCoord+0.7d, this.xCoord+0.55d, this.yCoord+1.5d, this.zCoord+0.8d);
+ break;
+ default:
+ aabb1 = AxisAlignedBB.getBoundingBox(this.xCoord, yStart, this.zCoord, this.xCoord+0.5d, this.yCoord+1.1d, this.zCoord+1d);
+ aabb2 = AxisAlignedBB.getBoundingBox(this.xCoord+0.5d, yStart, this.zCoord, this.xCoord+1d, this.yCoord+1.1d, this.zCoord+1d);
+ aabb1_1 = AxisAlignedBB.getBoundingBox(this.xCoord+0.2d, this.yCoord+1.4d, this.zCoord+0.45d, this.xCoord+0.3d, this.yCoord+1.5d, this.zCoord+0.55d);
+ aabb2_1 = AxisAlignedBB.getBoundingBox(this.xCoord+0.7d, this.yCoord+1.4d, this.zCoord+0.45d, this.xCoord+0.8d, this.yCoord+1.5d, this.zCoord+0.55d);
+ break;
+ }
+ }
+
+ @Override
+ public ItemStack getWrenchDrop(EntityPlayer player)
+ {
+ return IHLUtils.getThisModItemStack("rectifierTransformerUnit");
+ }
+ @Override
+ public boolean wrenchCanSetFacing(EntityPlayer entityPlayer, int side)
+ {
+ return this.getFacing()!=(short)side;
+ }
+
+
+ @Override
+ public void writeToNBT(NBTTagCompound nbt) {
+ super.writeToNBT(nbt);
+ NBTTagList energyNetNodeNBTList = new NBTTagList();
+ for(SubRTUEnergyNetNode node:this.energyNetNodes)
+ {
+ energyNetNodeNBTList.appendTag(node.writeToNBT());
+ }
+ nbt.setTag("energyNetNodes", energyNetNodeNBTList);
+ nbt.setFloat("mode",this.mode);
+ }
+
+ @Override
+ public void readFromNBT(NBTTagCompound nbt) {
+ super.readFromNBT(nbt);
+ NBTTagList energyNetNodeNBTList=nbt.getTagList("energyNetNodes", 10);
+ for(int i=0;i<2;i++)
+ {
+ this.energyNetNodes[i].readFromNBT(energyNetNodeNBTList.getCompoundTagAt(i));
+ }
+ this.mode=nbt.getFloat("mode");
+ this.mode=this.mode==0f?1f:this.mode;
+ }
+
+ @Override
+ public void onNetworkEvent(EntityPlayer player, int event)
+ {
+ switch(event)
+ {
+ case 0:
+ break;
+ }
+ }
+
+ public void switchModeUp()
+ {
+ if(this.mode<modeMax)
+ {
+ this.mode*=modeMultiplier;
+ if(this.energyNetNodes[1].getGridID()!=-1)
+ {
+ if(this.energyNetNodes[0].getGridID()!=-1)
+ {
+ this.energyNetNodes[1].getGrid().injectEnergy(0, this.energyNetNodes[0].getGrid().getSinkVoltage(this.energyNetNodes[0])*this.mode, this.energyNetNodes[1]);
+ }
+ else if(this.energyNetNodes[1].getGrid().energy>=1d)
+ {
+ this.energyNetNodes[1].getGrid().injectEnergy(0, 400d*this.mode, this.energyNetNodes[1]);
+ }
+ }
+ IC2.network.get().updateTileEntityField(this, "mode");
+ }
+ }
+
+ public void switchModeDown()
+ {
+ if(this.mode>modeMin)
+ {
+ this.mode/=modeMultiplier;;
+ if(this.energyNetNodes[1].getGridID()!=-1)
+ {
+ if(this.energyNetNodes[0].getGridID()!=-1)
+ {
+ this.energyNetNodes[1].getGrid().injectEnergy(0, this.energyNetNodes[0].getGrid().getSinkVoltage(this.energyNetNodes[0])*this.mode, this.energyNetNodes[1]);
+ }
+ else if(this.energyNetNodes[1].getGrid().energy>=1d)
+ {
+ this.energyNetNodes[1].getGrid().injectEnergy(0, 400d*this.mode, this.energyNetNodes[1]);
+ }
+ }
+ IC2.network.get().updateTileEntityField(this, "mode");
+ }
+ }
+
+ @Override
+ public void onNetworkUpdate(String field)
+ {
+ if (field.equals("facing") && this.prevFacing != this.getFacing())
+ {
+ this.setupInteractingSpots(this.getFacing());
+ }
+ super.onNetworkUpdate(field);
+ }
+
+
+ @Override
+ public void updateEntityServer()
+ {
+
+ }
+
+ @Override
+ public String getInventoryName()
+ {
+ return "RTU";
+ }
+
+ @Override
+ public boolean acceptsEnergyFrom(TileEntity emitter,ForgeDirection direction)
+ {
+ return !direction.equals(ForgeDirection.UP);
+ }
+
+ @Override
+ public double getDemandedEnergy()
+ {
+ if(this.energyNetNodes[1].getGridID()!=-1 && this.energyNetNodes[1].getGrid().energy<1D)
+ {
+ return Integer.MAX_VALUE;
+ }
+ else
+ {
+ return 0d;
+ }
+ }
+
+ @Override
+ public int getSinkTier()
+ {
+ return 4;
+ }
+
+ @Override
+ public double injectEnergy(ForgeDirection directionFrom, double amount, double voltage)
+ {
+ if(getDemandedEnergy()>0d)
+ {
+ this.energyNetNodes[1].getGrid().injectEnergy(amount, 400d*this.mode, this.energyNetNodes[1]);
+ return 0d;
+ }
+ return amount;
+ }
+
+ @Override
+ public boolean isCableRemoved(int chainUniqueID)
+ {
+ if(!checkCables)
+ {
+ return false;
+ }
+ for(SubRTUEnergyNetNode sen:energyNetNodes)
+ {
+ if(!sen.isCableRemoved(chainUniqueID))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public IEnergyNetNode getEnergyNetNode(short facing)
+ {
+ return this.energyNetNodes[facing];
+ }
+
+ @Override
+ public short getSide(EntityPlayer player)
+ {
+ if(IHLUtils.isPlayerLookingAt(player, aabb1))
+ {
+ return 0;
+ }
+ else if(IHLUtils.isPlayerLookingAt(player, aabb2))
+ {
+ return 1;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+
+ @Override
+ public void removeAttachedChains()
+ {
+ for(short i=0;i<2;i++)
+ {
+ energyNetNodes[i].removeAttachedChains();
+ }
+
+ }
+
+ public boolean isTileEntityInvalid() {
+ return this.tileEntityInvalid;
+ }
+
+
+}
diff --git a/src/main/java/ihl/flexible_cable/SetOfDiesMiniGUI.java b/src/main/java/ihl/flexible_cable/SetOfDiesMiniGUI.java
new file mode 100644
index 0000000..c708da7
--- /dev/null
+++ b/src/main/java/ihl/flexible_cable/SetOfDiesMiniGUI.java
@@ -0,0 +1,81 @@
+package ihl.flexible_cable;
+
+import java.awt.event.KeyEvent;
+
+import org.lwjgl.opengl.GL11;
+
+import ihl.IHLMod;
+import ihl.interfaces.ItemMiniGUI;
+import ihl.utils.IHLUtils;
+import net.minecraft.client.gui.GuiTextField;
+import net.minecraft.client.gui.inventory.GuiContainer;
+import net.minecraft.inventory.Slot;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.StatCollector;
+
+public class SetOfDiesMiniGUI extends ItemMiniGUI {
+ private static final ResourceLocation background = new ResourceLocation("ihl", "textures/gui/GUIIronWorkbench.png");
+ private int transverseSectionValue;
+ private GuiTextField transverseSectionTextField;
+ private int xPos;
+ private int yPos;
+
+ public SetOfDiesMiniGUI(GuiContainer gui, Slot slot) {
+ super(gui, slot);
+ transverseSectionValue = slot.getStack().stackTagCompound.getInteger("transverseSection");
+ xPos = this.slotBase.xDisplayPosition - 18;
+ yPos = this.slotBase.yDisplayPosition + 18;
+ transverseSectionTextField = new GuiTextField(this.guiBase.mc.fontRenderer, xPos + TEXT_BOX_POSX, yPos + TEXT_BOX_POSY, TEXT_BOX_WIDTH,
+ 11);
+ transverseSectionTextField.setText(Float.toString(transverseSectionValue / 10f));
+ transverseSectionTextField.setFocused(true);
+ }
+
+ @Override
+ public void displayGUI() {
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ this.guiBase.mc.renderEngine.bindTexture(background);
+ this.guiBase.drawTexturedModalRect(xPos, yPos, 0, 202, 126, HEIGHT);
+ int runnerXPos = xPos + 5 + 114 * transverseSectionValue / 1350;
+ this.guiBase.drawTexturedModalRect(runnerXPos, yPos + RUNNER_POSY, 126, 202, 3, 5);
+ this.guiBase.mc.fontRenderer.drawStringWithShadow(StatCollector.translateToLocal("ihl.transversesection"),
+ xPos + 3, yPos + 4, 0xFFCC00);
+ this.transverseSectionTextField.drawTextBox();
+ this.guiBase.mc.fontRenderer.drawStringWithShadow(StatCollector.translateToLocal("mm\u00B2"), xPos + UNITS_LABEL_POSX,
+ yPos + 18, 0xFFCC00);
+ }
+
+ @Override
+ public boolean handleMouseClick(int mouseX, int mouseY, int mouseButton) {
+ if (mouseX >= xPos + 5 && mouseX <= xPos + 119 && mouseY >= yPos + RUNNER_POSY - 1 && mouseY <= yPos + HEIGHT) {
+ this.transverseSectionValue = Math.max(1, Math.min(1350, (mouseX - xPos - 5) * 1350 / 114));
+ this.transverseSectionTextField.setText(Float.toString(transverseSectionValue / 10f));
+ }
+ if (mouseX >= xPos + TEXT_BOX_POSX && mouseX <= xPos + TEXT_BOX_POSX + TEXT_BOX_WIDTH && mouseY >= yPos + TEXT_BOX_POSY && mouseY <= yPos + TEXT_BOX_POSY + 11) {
+ this.transverseSectionTextField.setFocused(true);
+ }
+ return mouseX >= xPos && mouseX <= xPos + 202 && mouseY >= yPos && mouseY <= yPos + HEIGHT;
+ }
+
+ @Override
+ public boolean handleKeyTyped(char characterTyped, int keyIndex) {
+ this.transverseSectionTextField.textboxKeyTyped(characterTyped, keyIndex);
+ // 28 - enter; 156 - numpad enter
+ if (keyIndex == KeyEvent.VK_ACCEPT || keyIndex == KeyEvent.VK_ENTER || keyIndex == 28 || keyIndex == 156) {
+ this.transverseSectionValue = Math.max(1, Math.min(1350, (int) (IHLUtils
+ .parseFloatSafe(this.transverseSectionTextField.getText(), this.transverseSectionValue) * 10f)));
+ this.transverseSectionTextField.setText(Float.toString(transverseSectionValue / 10f));
+ this.transverseSectionTextField.setFocused(false);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void onGUIClosed() {
+ IHLMod.proxy.sendItemStackNBTTagFromClientToServerPlayer(this.guiBase.mc.thePlayer, this.slotBase.slotNumber,
+ "transverseSection", this.transverseSectionValue);
+ }
+
+}
diff --git a/src/main/java/ihl/flexible_cable/SubAnchorEnergyNetNode.java b/src/main/java/ihl/flexible_cable/SubAnchorEnergyNetNode.java
new file mode 100644
index 0000000..daada72
--- /dev/null
+++ b/src/main/java/ihl/flexible_cable/SubAnchorEnergyNetNode.java
@@ -0,0 +1,346 @@
+package ihl.flexible_cable;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import ic2.api.energy.EnergyNet;
+import ic2.api.energy.event.EnergyTileLoadEvent;
+import ic2.api.energy.event.EnergyTileUnloadEvent;
+import ic2.api.energy.tile.IEnergySink;
+import ic2.api.energy.tile.IEnergySource;
+import ic2.core.IC2;
+import ihl.IHLMod;
+import ihl.interfaces.IEnergyNetNode;
+import ihl.utils.IHLUtils;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTTagList;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.common.util.ForgeDirection;
+
+public class SubAnchorEnergyNetNode implements IEnergyNetNode{
+
+ private AnchorTileEntity base;
+ private short facing;
+ private int gridID=-1;
+ private Set<IHLCable> cableList = new HashSet<IHLCable>();
+
+ public SubAnchorEnergyNetNode(AnchorTileEntity base1, short facing1)
+ {
+ base=base1;
+ facing=facing1;
+ }
+
+ @Override
+ public double[] getPortPos(EntityLivingBase player)
+ {
+ double d=0.5D;
+ double f=-0.05D;
+ switch(facing)
+ {
+ case 0:
+ return new double[]{
+ (base.xCoord+d),
+ (base.yCoord+1D-f),
+ (base.zCoord+0.5D)};
+ case 1:
+ return new double[]{
+ (base.xCoord+d),
+ (base.yCoord+f),
+ (base.zCoord+0.5D)};
+ case 2:
+ return new double[]{
+ (base.xCoord+0.5D),
+ (base.yCoord+d),
+ (base.zCoord+1D-f)};
+ case 3:
+ return new double[]{
+ (base.xCoord+0.5D),
+ (base.yCoord+d),
+ (base.zCoord+f)};
+ case 4:
+ return new double[]{
+ (base.xCoord+1D-f),
+ (base.yCoord+d),
+ (base.zCoord+0.5D)};
+ case 5:
+ return new double[]{
+ (base.xCoord+f),
+ (base.yCoord+d),
+ (base.zCoord+0.5D)};
+ default:
+ return new double[]{
+ (base.xCoord+f),
+ (base.yCoord+d),
+ (base.zCoord+0.5D)};
+ }
+ }
+
+ @Override
+ public IHLGrid getGrid()
+ {
+ if(gridID!=-1)
+ {
+ return IHLMod.enet.getGrid(gridID);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ @Override
+ public int getGridID()
+ {
+ return gridID;
+ }
+
+ @Override
+ public void setGrid(int newgridID)
+ {
+ if(IC2.platform.isSimulating()&& base.addedToEnergyNet && base.getWorldObj()!=null)
+ {
+ MinecraftForge.EVENT_BUS.post(new EnergyTileUnloadEvent(base));
+ base.addedToEnergyNet = false;
+ }
+ if(newgridID!=-1)
+ {
+ this.gridID=newgridID;
+ IHLMod.enet.getGrid(newgridID).add(this);
+ }
+ else
+ {
+ this.gridID=-1;
+ }
+ if (IC2.platform.isSimulating()&& !base.addedToEnergyNet && base.getWorldObj()!=null)
+ {
+ MinecraftForge.EVENT_BUS.post(new EnergyTileLoadEvent(base));
+ base.addedToEnergyNet = true;
+ }
+ }
+
+ @Override
+ public double getMaxAllowableVoltage()
+ {
+ return 64000d;
+ }
+
+ @Override
+ public boolean addCable(NBTTagCompound cable)
+ {
+ base.hasCableOnSide[this.facing]=true;
+ return this.cableList.add(IHLCable.fromNBT(cable));
+ }
+
+ @Override
+ public Set<IHLCable> getCableList() {
+ return cableList;
+ }
+
+ @Override
+ public void removeAttachedChains()
+ {
+ IHLUtils.removeChains(this,this.base.getWorldObj());
+ }
+
+ public void onLoaded()
+ {
+ if(gridID!=-1)
+ {
+ IHLGrid grid = IHLMod.enet.getGrid(gridID);
+ grid.add(this);
+ }
+ }
+
+ public void onUnloaded()
+ {
+ if(gridID!=-1)
+ {
+ IHLGrid grid = IHLMod.enet.getGrid(gridID);
+ grid.remove(this);
+ }
+ }
+
+ public NBTTagCompound writeToNBT()
+ {
+ NBTTagCompound nbt = new NBTTagCompound();
+ NBTTagList cableNBTList = new NBTTagList();
+ for(IHLCable cable:this.cableList)
+ {
+ cableNBTList.appendTag(cable.toNBT());
+ }
+ nbt.setTag("cableList", cableNBTList);
+ nbt.setInteger("gridID", this.gridID);
+ return nbt;
+ }
+
+ public void readFromNBT(NBTTagCompound nbt) {
+ NBTTagList cableNBTList=nbt.getTagList("cableList", 10);
+ for(int i=0;i<cableNBTList.tagCount();i++)
+ {
+ this.cableList.add(IHLCable.fromNBT(cableNBTList.getCompoundTagAt(i)));
+ }
+ this.gridID=nbt.getInteger("gridID");
+ if(this.gridID!=-1)
+ {
+ base.hasCableOnSide[this.facing]=true;
+ }
+ }
+
+ public double getDemandedEnergy()
+ {
+ if(this.gridID==-1)
+ {
+ return 0D;
+ }
+ else
+ {
+ if(this.getGrid().energy<=1d)
+ {
+ return 65536d;
+ }
+ else
+ {
+ return 0D;
+ }
+ }
+ }
+
+ public double drawEnergyFromGrid(double amount)
+ {
+ if(this.gridID!=-1 && this.getGrid().energy>0d)
+ {
+ double drainedEnergy = Math.min(amount, this.getGrid().energy);
+ this.getGrid().drawEnergy(drainedEnergy, this);
+ return drainedEnergy;
+ }
+ return 0D;
+ }
+
+ public double getVoltage()
+ {
+ if(this.gridID==-1)
+ {
+ return 0D;
+ }
+ else
+ {
+ return this.getGrid().getSinkVoltage(this);
+ }
+ }
+
+ @Override
+ public void remove(IHLCable cable)
+ {
+ if(this.cableList.remove(cable))
+ {
+ IHLUtils.removeChain(cable, this);
+ }
+ if(this.cableList.isEmpty())
+ {
+ base.hasCableOnSide[this.facing]=false;
+ base.checkIfNoCablesLeft();
+ }
+ }
+
+ public double injectEnergyToGrid(double amount)
+ {
+ if(this.gridID==-1)
+ {
+ return amount;
+ }
+ else
+ {
+ this.getGrid().injectEnergy(amount, 400d, this);
+ return 0d;
+ }
+ }
+
+ @Override
+ public boolean isCableRemoved(int chainUniqueID) {
+ for(IHLCable cable:this.cableList)
+ {
+ if(cable.chainUID==chainUniqueID)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public void setCableCheck(boolean b)
+ {
+ base.checkCables=b;
+ }
+
+ @Override
+ public double getEnergyAmountThisNodeWant()
+ {
+ Set<TileEntity> teset = new HashSet<TileEntity>();
+ ForgeDirection direction = ForgeDirection.getOrientation(this.facing).getOpposite();
+ TileEntity te = EnergyNet.instance.getNeighbor(this.base, direction);
+ teset.add(te);
+ TileEntity te1 = this.base.getSink(te, teset);
+ if(te1==this.base)
+ {
+ return 0d;
+ }
+ if(te instanceof IEnergySink)
+ {
+ return ((IEnergySink)te).acceptsEnergyFrom(this.base, ForgeDirection.getOrientation(this.facing))?((IEnergySink)te).getDemandedEnergy():0d;
+ }
+ return 0d;
+ }
+
+ public double getEnergyOfferedByGrid()
+ {
+ if(this.gridID==-1)
+ {
+ return 0D;
+ }
+ else
+ {
+ return Math.max(this.getGrid().energy,0d);
+ }
+ }
+
+ @Override
+ public void injectEnergyInThisNode(double amount, double voltage)
+ {
+ Set<TileEntity> teset = new HashSet<TileEntity>();
+ ForgeDirection direction = ForgeDirection.getOrientation(this.facing).getOpposite();
+ TileEntity te = EnergyNet.instance.getNeighbor(this.base, direction);
+ teset.add(te);
+ TileEntity te1 = this.base.getSink(te, teset);
+ if(te1==this.base)
+ {
+ return;
+ }
+ if(te1!=null && voltage>500D)
+ {
+ if(te1 instanceof IEnergyNetNode)
+ {
+ if(((IEnergyNetNode)te1).getMaxAllowableVoltage()<voltage)
+ {
+ base.sacrifices.add(te1);
+ }
+ }
+ else if(te1 instanceof IEnergySink)
+ {
+ base.sacrifices.add(te1);
+ }
+ }
+ if(te1 instanceof IEnergySink)
+ {
+ amount=((IEnergySink)te1).injectEnergy(direction, amount, voltage);
+ }
+ }
+
+ @Override
+ public boolean isTileEntityBaseInvalid() {
+ return base.isTileEntityInvalid();
+ }
+
+}
diff --git a/src/main/java/ihl/flexible_cable/SubRTUEnergyNetNode.java b/src/main/java/ihl/flexible_cable/SubRTUEnergyNetNode.java
new file mode 100644
index 0000000..06fc964
--- /dev/null
+++ b/src/main/java/ihl/flexible_cable/SubRTUEnergyNetNode.java
@@ -0,0 +1,320 @@
+package ihl.flexible_cable;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import ic2.api.energy.event.EnergyTileLoadEvent;
+import ic2.api.energy.event.EnergyTileUnloadEvent;
+import ic2.core.IC2;
+import ihl.IHLMod;
+import ihl.interfaces.IEnergyNetNode;
+import ihl.utils.IHLUtils;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTTagList;
+import net.minecraftforge.common.MinecraftForge;
+
+public class SubRTUEnergyNetNode implements IEnergyNetNode{
+
+ private RectifierTransformerUnitTileEntity base;
+ private short side;
+ private int gridID=-1;
+ private Set<IHLCable> cableList = new HashSet<IHLCable>();
+
+ public SubRTUEnergyNetNode(RectifierTransformerUnitTileEntity base1, short facing1)
+ {
+ base=base1;
+ side=facing1;
+ }
+
+ @Override
+ public double[] getPortPos(EntityLivingBase player)
+ {
+ double d=0.5D;
+ double f=0.25D;
+ double h=1.45d;
+ switch(base.getFacing())
+ {
+ case 0:
+ case 1:
+ case 2:
+ switch(side)
+ {
+ case 0:
+ return new double[]{
+ (base.xCoord+f),
+ (base.yCoord+h),
+ (base.zCoord+d)};
+ case 1:
+ return new double[]{
+ (base.xCoord+1d-f),
+ (base.yCoord+h),
+ (base.zCoord+d)};
+ }
+ case 3:
+ switch(side)
+ {
+ case 1:
+ return new double[]{
+ (base.xCoord+f),
+ (base.yCoord+h),
+ (base.zCoord+d)};
+ case 0:
+ return new double[]{
+ (base.xCoord+1d-f),
+ (base.yCoord+h),
+ (base.zCoord+d)};
+ }
+ case 4:
+ switch(side)
+ {
+ case 1:
+ return new double[]{
+ (base.xCoord+d),
+ (base.yCoord+h),
+ (base.zCoord+f)};
+ case 0:
+ return new double[]{
+ (base.xCoord+d),
+ (base.yCoord+h),
+ (base.zCoord+1d-f)};
+ }
+ case 5:
+ switch(side)
+ {
+ case 0:
+ return new double[]{
+ (base.xCoord+d),
+ (base.yCoord+h),
+ (base.zCoord+f)};
+ case 1:
+ return new double[]{
+ (base.xCoord+d),
+ (base.yCoord+h),
+ (base.zCoord+1d-f)};
+ }
+ default:
+ return new double[]{
+ (base.xCoord+1d-f),
+ (base.yCoord+h),
+ (base.zCoord+d)};
+ }
+ }
+
+ @Override
+ public IHLGrid getGrid()
+ {
+ if(gridID!=-1)
+ {
+ return IHLMod.enet.getGrid(gridID);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ @Override
+ public int getGridID()
+ {
+ return gridID;
+ }
+
+ @Override
+ public void setGrid(int newgridID)
+ {
+ if(IC2.platform.isSimulating()&& base.addedToEnergyNet && base.getWorldObj()!=null)
+ {
+ MinecraftForge.EVENT_BUS.post(new EnergyTileUnloadEvent(base));
+ base.addedToEnergyNet = false;
+ }
+ if(newgridID!=-1)
+ {
+ this.gridID=newgridID;
+ IHLMod.enet.getGrid(newgridID).add(this);
+ }
+ else
+ {
+ this.gridID=-1;
+ }
+ if (IC2.platform.isSimulating()&& !base.addedToEnergyNet && base.getWorldObj()!=null)
+ {
+ MinecraftForge.EVENT_BUS.post(new EnergyTileLoadEvent(base));
+ base.addedToEnergyNet = true;
+ }
+ }
+
+ @Override
+ public double getMaxAllowableVoltage()
+ {
+ return 64000d;
+ }
+
+ @Override
+ public boolean addCable(NBTTagCompound cable)
+ {
+ return this.cableList.add(IHLCable.fromNBT(cable));
+ }
+
+ @Override
+ public Set<IHLCable> getCableList() {
+ return cableList;
+ }
+
+ @Override
+ public void removeAttachedChains()
+ {
+ IHLUtils.removeChains(this,this.base.getWorldObj());
+ }
+
+ public void onLoaded()
+ {
+ if(gridID!=-1)
+ {
+ IHLGrid grid = IHLMod.enet.getGrid(gridID);
+ grid.add(this);
+ }
+ }
+
+ public void onUnloaded()
+ {
+ if(gridID!=-1)
+ {
+ IHLGrid grid = IHLMod.enet.getGrid(gridID);
+ grid.remove(this);
+ }
+ }
+
+ public NBTTagCompound writeToNBT()
+ {
+ NBTTagCompound nbt = new NBTTagCompound();
+ NBTTagList cableNBTList = new NBTTagList();
+ for(IHLCable cable:this.cableList)
+ {
+ cableNBTList.appendTag(cable.toNBT());
+ }
+ nbt.setTag("cableList", cableNBTList);
+ nbt.setInteger("gridID", this.gridID);
+ return nbt;
+ }
+
+ public void readFromNBT(NBTTagCompound nbt) {
+ NBTTagList cableNBTList=nbt.getTagList("cableList", 10);
+ for(int i=0;i<cableNBTList.tagCount();i++)
+ {
+ this.cableList.add(IHLCable.fromNBT(cableNBTList.getCompoundTagAt(i)));
+ }
+ this.gridID=nbt.getInteger("gridID");
+ }
+
+ public double getOfferedEnergy()
+ {
+ if(this.gridID==-1)
+ {
+ return 0D;
+ }
+ else
+ {
+ return Math.max(this.getGrid().energy, 0D);
+ }
+ }
+
+ public double drawEnergy(double amount)
+ {
+ if(this.gridID==-1)
+ {
+ return 0D;
+ }
+ else
+ {
+ double dEnergy = Math.min(this.getGrid().energy, amount);
+ this.getGrid().energy-=dEnergy;
+ return dEnergy;
+ }
+ }
+
+ public double getVoltage()
+ {
+ if(this.gridID==-1)
+ {
+ return 0D;
+ }
+ else
+ {
+ return this.getGrid().getSinkVoltage(this);
+ }
+ }
+
+ @Override
+ public void remove(IHLCable cable)
+ {
+ if(this.cableList.remove(cable))
+ {
+ IHLUtils.removeChain(cable, this);
+ }
+ }
+
+ public double injectEnergyToGrid(double amount)
+ {
+ if(this.gridID==-1)
+ {
+ return amount;
+ }
+ else
+ {
+ this.getGrid().injectEnergy(amount, 400d, this);
+ return 0d;
+ }
+ }
+
+ @Override
+ public boolean isCableRemoved(int chainUniqueID) {
+ for(IHLCable cable:this.cableList)
+ {
+ if(cable.chainUID==chainUniqueID)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public void setCableCheck(boolean b)
+ {
+ base.checkCables=b;
+ }
+
+ @Override
+ public double getEnergyAmountThisNodeWant()
+ {
+ if(this.side==0)
+ {
+ IEnergyNetNode eNode1 = this.base.getEnergyNetNode((short)1);
+ if(eNode1.getGridID()!=-1 && eNode1.getGrid().energy<1d)
+ {
+ return Integer.MAX_VALUE;
+ }
+ }
+ return 0;
+ }
+
+ @Override
+ public void injectEnergyInThisNode(double amount, double voltage)
+ {
+ if(this.side==0)
+ {
+ IEnergyNetNode eNode1 = this.base.getEnergyNetNode((short)1);
+ if(eNode1.getGridID()!=-1)
+ {
+ eNode1.getGrid().injectEnergy(amount, voltage*this.base.mode, eNode1);
+ }
+ }
+ }
+
+ @Override
+ public boolean isTileEntityBaseInvalid() {
+ return this.base.isTileEntityInvalid();
+ }
+
+}