aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Robertz <dream-master@gmx.net>2021-07-02 20:52:49 +0200
committerGitHub <noreply@github.com>2021-07-02 20:52:49 +0200
commit2a5b42343509d9684affa6be27da32e9eef89851 (patch)
treec1542a71bf37ed7611aa4cecb6d633556798d01d /src
parent77c57a97b7286863f9239de806ac9659013d6852 (diff)
parent6f80c03736d6d9ea9c72d19f0af72fc727714370 (diff)
downloadGT5-Unofficial-2a5b42343509d9684affa6be27da32e9eef89851.tar.gz
GT5-Unofficial-2a5b42343509d9684affa6be27da32e9eef89851.tar.bz2
GT5-Unofficial-2a5b42343509d9684affa6be27da32e9eef89851.zip
Merge pull request #572 from GTNewHorizons/beter-power-net
Better power net
Diffstat (limited to 'src')
-rw-r--r--src/main/java/gregtech/api/GregTech_API.java10
-rw-r--r--src/main/java/gregtech/api/graphs/GenerateNodeMap.java174
-rw-r--r--src/main/java/gregtech/api/graphs/GenerateNodeMapPower.java81
-rw-r--r--src/main/java/gregtech/api/graphs/Node.java30
-rw-r--r--src/main/java/gregtech/api/graphs/NodeList.java24
-rw-r--r--src/main/java/gregtech/api/graphs/PowerNode.java14
-rw-r--r--src/main/java/gregtech/api/graphs/PowerNodes.java162
-rw-r--r--src/main/java/gregtech/api/graphs/consumers/ConsumerNode.java23
-rw-r--r--src/main/java/gregtech/api/graphs/consumers/EmptyPowerConsumer.java27
-rw-r--r--src/main/java/gregtech/api/graphs/consumers/NodeEnergyReceiver.java79
-rw-r--r--src/main/java/gregtech/api/graphs/consumers/NodeEnergySink.java28
-rw-r--r--src/main/java/gregtech/api/graphs/consumers/NodeGTBaseMetaTile.java23
-rw-r--r--src/main/java/gregtech/api/graphs/paths/NodePath.java29
-rw-r--r--src/main/java/gregtech/api/graphs/paths/PowerNodePath.java111
-rw-r--r--src/main/java/gregtech/api/interfaces/tileentity/IEnergyConnected.java4
-rw-r--r--src/main/java/gregtech/api/metatileentity/BaseMetaPipeEntity.java26
-rw-r--r--src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java37
-rw-r--r--src/main/java/gregtech/api/metatileentity/MetaTileEntity.java1
-rw-r--r--src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Cable.java218
-rw-r--r--src/main/java/gregtech/api/threads/GT_Runnable_Cable_Update.java69
-rw-r--r--src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java16
21 files changed, 993 insertions, 193 deletions
diff --git a/src/main/java/gregtech/api/GregTech_API.java b/src/main/java/gregtech/api/GregTech_API.java
index e24297c48c..ba7e3ab43e 100644
--- a/src/main/java/gregtech/api/GregTech_API.java
+++ b/src/main/java/gregtech/api/GregTech_API.java
@@ -17,6 +17,7 @@ import gregtech.api.objects.GT_Cover_Default;
import gregtech.api.objects.GT_Cover_None;
import gregtech.api.objects.GT_HashSet;
import gregtech.api.objects.GT_ItemStack;
+import gregtech.api.threads.GT_Runnable_Cable_Update;
import gregtech.api.threads.GT_Runnable_MachineBlockUpdate;
import gregtech.api.util.*;
import gregtech.api.world.GT_Worldgen;
@@ -407,6 +408,15 @@ public class GregTech_API {
return false;
}
+ public static boolean causeCableUpdate(World aWorld, int aX, int aY, int aZ) {
+ if (aWorld != null && !aWorld.isRemote) { // World might be null during Worldgen
+ GT_Runnable_Cable_Update.setCableUpdateValues(aWorld, new ChunkCoordinates(aX, aY, aZ));
+ return true;
+ }
+ return false;
+
+ }
+
/**
* Adds a Multi-Machine Block, like my Machine Casings for example.
* You should call @causeMachineUpdate in @Block.breakBlock and in @Block.onBlockAdded of your registered Block.
diff --git a/src/main/java/gregtech/api/graphs/GenerateNodeMap.java b/src/main/java/gregtech/api/graphs/GenerateNodeMap.java
new file mode 100644
index 0000000000..98c8215fc7
--- /dev/null
+++ b/src/main/java/gregtech/api/graphs/GenerateNodeMap.java
@@ -0,0 +1,174 @@
+package gregtech.api.graphs;
+
+import gregtech.api.graphs.consumers.ConsumerNode;
+import gregtech.api.graphs.paths.NodePath;
+import gregtech.api.metatileentity.*;
+import net.minecraft.tileentity.TileEntity;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+
+import static gregtech.api.util.GT_Utility.getOppositeSide;
+
+
+//generates the node map
+abstract public class GenerateNodeMap {
+ //clearing the node map to make sure it is gone on reset
+ public static void clearNodeMap(Node aNode,int aReturnNodeValue) {
+ if (aNode.mTileEntity instanceof BaseMetaPipeEntity) {
+ BaseMetaPipeEntity tPipe = (BaseMetaPipeEntity) aNode.mTileEntity;
+ tPipe.setNode(null);
+ tPipe.setNodePath(null);
+ if (aNode.mSelfPath != null) {
+ aNode.mSelfPath.clearPath();
+ aNode.mSelfPath = null;
+ }
+ }
+ for (int i = 0;i<6;i++) {
+ NodePath tPath = aNode.mNodePaths[i];
+ if (tPath != null) {
+ tPath.clearPath();
+ aNode.mNodePaths[i] = null;
+ }
+ Node tNextNode = aNode.mNeighbourNodes[i];
+ if (tNextNode == null) continue;
+ if (tNextNode.mNodeValue != aReturnNodeValue)
+ clearNodeMap(tNextNode,aNode.mNodeValue);
+ aNode.mNeighbourNodes[i] = null;
+ }
+ }
+
+ //gets the next node
+ protected void generateNextNode(BaseMetaPipeEntity aPipe, Node aPipeNode, byte aInvalidSide, int aNextNodeValue,
+ ArrayList<ConsumerNode> tConsumers, HashSet<Node> tNodeMap) {
+ MetaPipeEntity tMetaPipe = (MetaPipeEntity) aPipe.getMetaTileEntity();
+ for (byte i = 0;i<6;i++) {
+ if (i==aInvalidSide) {
+ continue;
+ }
+ TileEntity tNextTileEntity = aPipe.getTileEntityAtSide(i);
+ if (tNextTileEntity == null || (tMetaPipe != null && !tMetaPipe.isConnectedAtSide(i))) continue;
+ ArrayList<MetaPipeEntity> tNewPipes = new ArrayList<MetaPipeEntity>();
+ Pair nextTileEntity = getNextValidTileEntity(tNextTileEntity,tNewPipes,i,tNodeMap);
+ if (nextTileEntity != null) {
+ Node tNextNode = generateNode(nextTileEntity.mTileEntity,aPipeNode,aNextNodeValue+1,tNewPipes,
+ nextTileEntity.mSide,tConsumers,tNodeMap);
+ if (tNextNode != null) {
+ aNextNodeValue = tNextNode.mHighestNodeValue;
+ aPipeNode.mHighestNodeValue = tNextNode.mHighestNodeValue;
+ aPipeNode.mNeighbourNodes[i] = tNextNode;
+ aPipeNode.mNodePaths[i] = aPipeNode.mReturnPath;
+ }
+ }
+ }
+ }
+
+ //on a valid tile entity create a new node
+ protected Node generateNode(TileEntity aTileEntity, Node aPreviousNode, int aNextNodeValue, ArrayList<MetaPipeEntity> aPipes,
+ int aSide, ArrayList<ConsumerNode> aConsumers, HashSet<Node> aNodeMap) {
+ if (aTileEntity.isInvalid()) return null;
+ byte tSideOp = getOppositeSide(aSide);
+ byte tInvalidSide = aPreviousNode == null ? -1 : tSideOp;
+ Node tThisNode = null;
+ if (isPipe(aTileEntity)){
+ BaseMetaPipeEntity tPipe = (BaseMetaPipeEntity) aTileEntity;
+ MetaPipeEntity tMetaPipe = (MetaPipeEntity) tPipe.getMetaTileEntity();
+ int tConnections = getNumberOfConnections(tMetaPipe);
+ Node tPipeNode;
+ if (tConnections == 1) {
+ tPipeNode = getEmptyNode(aNextNodeValue,tSideOp,aTileEntity,aConsumers);
+ if (tPipeNode == null) return null;
+ } else {
+ tPipeNode = getPipeNode(aNextNodeValue,tSideOp,aTileEntity,aConsumers);
+ }
+ tPipe.setNode(tPipeNode);
+ aNodeMap.add(tPipeNode);
+ tPipeNode.mSelfPath = getNewPath(new MetaPipeEntity[]{tMetaPipe});
+ tThisNode = tPipeNode;
+ if (tInvalidSide>-1) {
+ tPipeNode.mNeighbourNodes[tInvalidSide] = aPreviousNode;
+ tPipeNode.mNodePaths[tInvalidSide] = getNewPath(aPipes.toArray(new MetaPipeEntity[0]));
+ aPreviousNode.mReturnPath = tPipeNode.mNodePaths[tInvalidSide];
+ }
+ if (tConnections > 1)
+ generateNextNode(tPipe,tPipeNode,tInvalidSide,aNextNodeValue,aConsumers,aNodeMap);
+ } else if (addConsumer(aTileEntity,tSideOp,aNextNodeValue,aConsumers)) {
+ ConsumerNode tConsumeNode = aConsumers.get(aConsumers.size()-1);
+ tConsumeNode.mNeighbourNodes[tSideOp] = aPreviousNode;
+ tConsumeNode.mNodePaths[tSideOp] = getNewPath(aPipes.toArray(new MetaPipeEntity[0]));
+ aPreviousNode.mReturnPath = tConsumeNode.mNodePaths[tSideOp];
+ tThisNode = tConsumeNode;
+ }
+ return tThisNode;
+ }
+
+ //go over the pipes until we see a valid tile entity that needs a node
+ protected Pair getNextValidTileEntity(TileEntity aTileEntity, ArrayList<MetaPipeEntity> aPipes, byte aSide, HashSet<Node> aNodeMap) {
+ if (isPipe(aTileEntity)) {
+ BaseMetaPipeEntity tPipe = (BaseMetaPipeEntity) aTileEntity;
+ MetaPipeEntity tMetaPipe = (MetaPipeEntity) tPipe.getMetaTileEntity();
+ Node tNode = tPipe.getNode();
+ if (tNode != null) {
+ if (aNodeMap.contains(tNode))
+ return null;
+ }
+ int tConnections = getNumberOfConnections(tMetaPipe);
+ if (tConnections == 2) {
+ byte tSideOp = getOppositeSide(aSide);
+ for (byte i = 0;i<6;i++) {
+ if (i == tSideOp || !(tMetaPipe.isConnectedAtSide(i))) continue;
+ TileEntity tNewTileEntity = tPipe.getTileEntityAtSide(i);
+ if (tNewTileEntity == null) continue;
+ if (isPipe(tNewTileEntity)) {
+ aPipes.add(tMetaPipe);
+ return getNextValidTileEntity(tNewTileEntity,aPipes,i,aNodeMap);
+ } else {
+ return new Pair(aTileEntity,i);
+ }
+ }
+ } else {
+ return new Pair(aTileEntity,aSide);
+ }
+ } else {
+ return new Pair(aTileEntity,aSide);
+ }
+ return null;
+ }
+
+ private static class Pair {
+ public byte mSide;
+ public TileEntity mTileEntity;
+ public Pair(TileEntity aTileEntity, byte aSide) {
+ this.mTileEntity = aTileEntity;
+ this.mSide = aSide;
+ }
+ }
+
+ //if check if the tile entity is the correct pipe
+ protected boolean isPipe(TileEntity aTileEntity) {
+ return aTileEntity instanceof BaseMetaPipeEntity;
+ }
+ //checks if the tile entity is a consumer and add to the list
+ abstract protected boolean addConsumer(TileEntity aTileEntity, byte aSide, int aNodeValue, ArrayList<ConsumerNode> aConsumers);
+ //get correct pathClass that you need for your node network
+ protected abstract NodePath getNewPath(MetaPipeEntity[] aPipes);
+
+ //used for if you need to use death ends for something
+ //can be null
+ protected Node getEmptyNode(int aNodeValue, byte aSide, TileEntity aTileEntity, ArrayList<ConsumerNode> aConsumers) {
+ return null;
+ }
+ //get correct node type you need for your network
+ protected Node getPipeNode(int aNodeValue, byte aSide, TileEntity aTileEntity, ArrayList<ConsumerNode> aConsumers) {
+ return new Node(aNodeValue,aTileEntity,aConsumers);
+ }
+
+ //get how many connections the pipe have
+ private static int getNumberOfConnections(MetaPipeEntity aPipe) {
+ int tCons = 0;
+ for (int i = 0; i < 6; i++) {
+ if (aPipe.isConnectedAtSide(i)) tCons++;
+ }
+ return tCons;
+ }
+}
diff --git a/src/main/java/gregtech/api/graphs/GenerateNodeMapPower.java b/src/main/java/gregtech/api/graphs/GenerateNodeMapPower.java
new file mode 100644
index 0000000000..547da44050
--- /dev/null
+++ b/src/main/java/gregtech/api/graphs/GenerateNodeMapPower.java
@@ -0,0 +1,81 @@
+package gregtech.api.graphs;
+
+import cofh.api.energy.IEnergyReceiver;
+import gregtech.api.GregTech_API;
+import gregtech.api.graphs.consumers.*;
+import gregtech.api.graphs.paths.NodePath;
+import gregtech.api.graphs.paths.PowerNodePath;
+import gregtech.api.metatileentity.BaseMetaPipeEntity;
+import gregtech.api.metatileentity.BaseMetaTileEntity;
+import gregtech.api.metatileentity.MetaPipeEntity;
+import gregtech.api.metatileentity.implementations.GT_MetaPipeEntity_Cable;
+import ic2.api.energy.tile.IEnergySink;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+
+//node map generator for power distribution
+public class GenerateNodeMapPower extends GenerateNodeMap {
+ public GenerateNodeMapPower(BaseMetaPipeEntity aTileEntity) {
+ generateNode(aTileEntity,null,1,null,
+ -1,new ArrayList<>(),new HashSet<>());
+ }
+
+ @Override
+ protected boolean isPipe(TileEntity aTileEntity) {
+ return super.isPipe(aTileEntity) && ((BaseMetaPipeEntity) aTileEntity).getMetaTileEntity() instanceof GT_MetaPipeEntity_Cable;
+ }
+
+ @Override
+ protected NodePath getNewPath(MetaPipeEntity[] aPipes) {
+ return new PowerNodePath(aPipes);
+ }
+
+ //used to apply voltage on death ends
+ @Override
+ protected Node getEmptyNode(int aNodeValue, byte aSide, TileEntity aTileEntity, ArrayList<ConsumerNode> aConsumers) {
+ Node tNode = new EmptyPowerConsumer(aNodeValue, aTileEntity, aSide, aConsumers);
+ aConsumers.add((ConsumerNode) tNode);
+ return tNode;
+ }
+
+ @Override
+ protected Node getPipeNode(int aNodeValue, byte aSide, TileEntity aTileEntity, ArrayList<ConsumerNode> aConsumers) {
+ return new PowerNode(aNodeValue, aTileEntity, aConsumers);
+ }
+
+ @Override
+ protected boolean addConsumer(TileEntity aTileEntity, byte aSide, int aNodeValue, ArrayList<ConsumerNode> aConsumers) {
+ if (aTileEntity instanceof BaseMetaTileEntity) {
+ BaseMetaTileEntity tBaseTileEntity = (BaseMetaTileEntity) aTileEntity;
+ if (tBaseTileEntity.inputEnergyFrom(aSide,false)) {
+ ConsumerNode tConsumerNode = new NodeGTBaseMetaTile(aNodeValue,tBaseTileEntity, aSide, aConsumers);
+ aConsumers.add(tConsumerNode);
+ return true;
+ }
+ } else if (aTileEntity instanceof IEnergySink) {
+ //ic2 wants the tilentitty next to it of that side not going to add a bunch of arguments just for ic2
+ //crossborder checks to not not load chuncks just to make sure
+ int dX = aTileEntity.xCoord + ForgeDirection.getOrientation(aSide).offsetX;
+ int dY = aTileEntity.yCoord + ForgeDirection.getOrientation(aSide).offsetY;
+ int dZ = aTileEntity.zCoord + ForgeDirection.getOrientation(aSide).offsetZ;
+ boolean crossesChuncks = dX >> 4 != aTileEntity.xCoord >> 4 || dZ >> 4 != aTileEntity.zCoord >> 4;
+ TileEntity tNextTo = null;
+ if (!crossesChuncks || !aTileEntity.getWorldObj().blockExists(dX, dY, dZ))
+ tNextTo = aTileEntity.getWorldObj().getTileEntity(dX, dY, dZ);
+
+ if (((IEnergySink) aTileEntity).acceptsEnergyFrom(tNextTo, ForgeDirection.getOrientation(aSide))) {
+ ConsumerNode tConsumerNode = new NodeEnergySink(aNodeValue,(IEnergySink) aTileEntity, aSide, aConsumers);
+ aConsumers.add(tConsumerNode);
+ return true;
+ }
+ } else if (GregTech_API.mOutputRF && aTileEntity instanceof IEnergyReceiver) {
+ ConsumerNode tConsumerNode = new NodeEnergyReceiver(aNodeValue,(IEnergyReceiver) aTileEntity, aSide, aConsumers);
+ aConsumers.add(tConsumerNode);
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/gregtech/api/graphs/Node.java b/src/main/java/gregtech/api/graphs/Node.java
new file mode 100644
index 0000000000..258915e473
--- /dev/null
+++ b/src/main/java/gregtech/api/graphs/Node.java
@@ -0,0 +1,30 @@
+package gregtech.api.graphs;
+
+import gregtech.api.graphs.consumers.ConsumerNode;
+import gregtech.api.graphs.paths.NodePath;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.tileentity.TileEntity;
+import java.util.ArrayList;
+
+//base Node class
+public class Node {
+ public Node(int aNodeValue,TileEntity aTileEntity,ArrayList<ConsumerNode> aConsumers){
+ this.mNodeValue = aNodeValue;
+ this.mTileEntity = aTileEntity;
+ this.mConsumers = aConsumers;
+ mHighestNodeValue = aNodeValue;
+ //you don't want to generate map multiple times in the same tick
+ mCreationTime = MinecraftServer.getServer().getTickCounter();
+ }
+
+
+ public int mCreationTime;
+ public NodePath mSelfPath;
+ public ArrayList<ConsumerNode> mConsumers;
+ public int mNodeValue;
+ public final TileEntity mTileEntity;
+ public Node[] mNeighbourNodes = new Node[6];
+ public NodePath[] mNodePaths = new NodePath[6];
+ public NodePath mReturnPath;
+ public int mHighestNodeValue;
+}
diff --git a/src/main/java/gregtech/api/graphs/NodeList.java b/src/main/java/gregtech/api/graphs/NodeList.java
new file mode 100644
index 0000000000..36ebbc4f6f
--- /dev/null
+++ b/src/main/java/gregtech/api/graphs/NodeList.java
@@ -0,0 +1,24 @@
+package gregtech.api.graphs;
+
+//keep track on which node is being looked for across the recursive functions
+public class NodeList {
+ Node[] mNodes;
+ int mCounter = 0;
+ public NodeList(Node[] mNodes) {
+ this.mNodes = mNodes;
+ }
+
+ Node getNextNode() {
+ if (++mCounter < mNodes.length)
+ return mNodes[mCounter];
+ else
+ return null;
+ }
+
+ Node getNode() {
+ if (mCounter < mNodes.length)
+ return mNodes[mCounter];
+ else
+ return null;
+ }
+}
diff --git a/src/main/java/gregtech/api/graphs/PowerNode.java b/src/main/java/gregtech/api/graphs/PowerNode.java
new file mode 100644
index 0000000000..a92e3ea0ca
--- /dev/null
+++ b/src/main/java/gregtech/api/graphs/PowerNode.java
@@ -0,0 +1,14 @@
+package gregtech.api.graphs;
+
+import gregtech.api.graphs.consumers.ConsumerNode;
+import net.minecraft.tileentity.TileEntity;
+
+import java.util.ArrayList;
+
+//base node for power networks
+public class PowerNode extends Node{
+ public boolean mHadVoltage = false;
+ public PowerNode(int aNodeValue, TileEntity aTileEntity, ArrayList<ConsumerNode> aConsumers) {
+ super(aNodeValue, aTileEntity, aConsumers);
+ }
+}
diff --git a/src/main/java/gregtech/api/graphs/PowerNodes.java b/src/main/java/gregtech/api/graphs/PowerNodes.java
new file mode 100644
index 0000000000..411d690cca
--- /dev/null
+++ b/src/main/java/gregtech/api/graphs/PowerNodes.java
@@ -0,0 +1,162 @@
+package gregtech.api.graphs;
+
+import gregtech.api.graphs.consumers.ConsumerNode;
+import gregtech.api.graphs.paths.PowerNodePath;
+
+/* look for and power node that need power
+ *
+ * how this works
+ *
+ * a node only contains nodes that has a higher value then it self except for 1 which is the return node
+ * this node also contains the highest known node value of its network
+ * this network only includes nodes that have a higher value then it self so it does not know the highest known value that
+ * the return node knows
+ *
+ * with these rules we can know for the target node to be in the network of a node, the target node must have a value no
+ * less than the node we are looking and no greater than the highest value that node knows
+ * this way we don't have to go over the entire network to look for it
+ *
+ * we also hold a list of all consumers so we can check before looking if that consumer actually needs power
+ * and only look for nodes that actually need power
+ *
+ */
+public class PowerNodes {
+ //check if the looked for node is next to or get the next node that is closer to it
+ static public int powerNode(Node aCurrentNode, Node aPreviousNode, NodeList aConsumers, int aVoltage, int aMaxAmps) {
+ int tAmpsUsed = 0;
+ ConsumerNode tConsumer =(ConsumerNode) aConsumers.getNode();
+ int tLoopProtection = 0;
+ while (tConsumer != null) {
+ int tTargetNodeValue = tConsumer.mNodeValue;
+ //if the target node has a value less then the current node
+ if (tTargetNodeValue < aCurrentNode.mNodeValue || tTargetNodeValue > aCurrentNode.mHighestNodeValue) {
+ for (int j = 0;j<6;j++) {
+ Node tNextNode = aCurrentNode.mNeighbourNodes[j];
+ if (tNextNode != null && tNextNode.mNodeValue < aCurrentNode.mNodeValue) {
+ if (tNextNode.mNodeValue == tConsumer.mNodeValue) {
+ tAmpsUsed += processNodeInject(aCurrentNode,tConsumer,j,aMaxAmps-tAmpsUsed,aVoltage,false);
+ tConsumer =(ConsumerNode) aConsumers.getNextNode();
+ break;
+ } else {
+ if (aPreviousNode == tNextNode) return tAmpsUsed;
+ tAmpsUsed += processNextNode(aCurrentNode,tNextNode,aConsumers,j,aMaxAmps-tAmpsUsed,aVoltage);
+ tConsumer =(ConsumerNode) aConsumers.getNode();
+ break;
+ }
+ }
+ }
+ } else {
+ //if the target node has a node value greater then current node value
+ for (int side = 5;side>-1;side--) {
+ Node tNextNode = aCurrentNode.mNeighbourNodes[side];
+ if (tNextNode == null) continue;
+ if (tNextNode.mNodeValue > aCurrentNode.mNodeValue && tNextNode.mNodeValue < tTargetNodeValue) {
+ if (tNextNode == aPreviousNode) return tAmpsUsed;
+ tAmpsUsed += processNextNodeAbove(aCurrentNode,tNextNode,aConsumers,side,aMaxAmps-tAmpsUsed,aVoltage);
+ tConsumer =(ConsumerNode) aConsumers.getNode();
+ break;
+ } else if (tNextNode.mNodeValue == tTargetNodeValue) {
+ tAmpsUsed += processNodeInject(aCurrentNode,tConsumer,side,aMaxAmps-tAmpsUsed,aVoltage,true);
+ tConsumer =(ConsumerNode) aConsumers.getNextNode();
+ break;
+ }
+ }
+ }
+ if (aMaxAmps - tAmpsUsed <= 0) {
+ return tAmpsUsed;
+ }
+ if (tLoopProtection++ > 20) {
+ throw new NullPointerException("infinite loop in powering nodes ");
+ }
+ }
+ return tAmpsUsed;
+ }
+
+ //checking if target node is next to it or has a higher value then current node value
+ //these functions are different to either go down or up the stack
+ protected static int powerNodeAbove(Node aCurrentNode, Node aPreviousNode, NodeList aConsumers, int aVoltage, int aMaxAmps) {
+ int tAmpsUsed = 0;
+ int tLoopProtection = 0;
+ ConsumerNode tConsumer =(ConsumerNode) aConsumers.getNode();
+ while (tConsumer != null) {
+ int tTargetNodeValue = tConsumer.mNodeValue;
+ if (tTargetNodeValue > aCurrentNode.mHighestNodeValue || tTargetNodeValue < aCurrentNode.mNodeValue) {
+ return tAmpsUsed;
+ } else {
+ for (int side = 5;side>-1;side--) {
+ Node tNextNode = aCurrentNode.mNeighbourNodes[side];
+ if (tNextNode == null) continue;
+ if (tNextNode.mNodeValue > aCurrentNode.mNodeValue && tNextNode.mNodeValue < tTargetNodeValue) {
+ if (tNextNode == aPreviousNode) return tAmpsUsed;
+ tAmpsUsed += processNextNodeAbove(aCurrentNode,tNextNode,aConsumers,side,aMaxAmps-tAmpsUsed,aVoltage);
+ tConsumer =(ConsumerNode) aConsumers.getNode();
+ break;
+ } else if (tNextNode.mNodeValue == tTargetNodeValue) {
+ tAmpsUsed += processNodeInject(aCurrentNode,tConsumer,side,aMaxAmps-tAmpsUsed,aVoltage,true);
+ tConsumer =(ConsumerNode) aConsumers.getNextNode();
+ break;
+ }
+ }
+ }
+ if (aMaxAmps - tAmpsUsed <= 0) {
+ return tAmpsUsed;
+ }
+ if (tLoopProtection++ > 20) {
+ throw new NullPointerException("infinite loop in powering nodes ");
+ }
+ }
+ return tAmpsUsed;
+ }
+
+ protected static int processNextNode(Node aCurrentNode, Node aNextNode, NodeList aConsumers, int aSide, int aMaxAmps, int aVoltage) {
+ PowerNodePath tPath = (PowerNodePath)aCurrentNode.mNodePaths[aSide];
+ PowerNodePath tSelfPath = (PowerNodePath) aCurrentNode.mSelfPath;
+ int tVoltLoss = 0;
+ if (tSelfPath != null) {
+ tVoltLoss += tSelfPath.getLoss();
+ tSelfPath.applyVoltage(aVoltage,false);
+ }
+ tPath.applyVoltage(aVoltage - tVoltLoss,true);
+ tVoltLoss += tPath.getLoss();
+ int tAmps = powerNode(aNextNode,aCurrentNode,aConsumers,aVoltage - tVoltLoss,aMaxAmps );
+ tPath.addAmps(tAmps);
+ if (tSelfPath != null)
+ tSelfPath.addAmps(tAmps);
+ return tAmps;
+ }
+
+ protected static int processNextNodeAbove(Node aCurrentNode, Node aNextNode, NodeList aConsumers, int aSide, int aMaxAmps, int aVoltage) {
+ PowerNodePath tPath = (PowerNodePath)aCurrentNode.mNodePaths[aSide];
+ PowerNodePath tSelfPath = (PowerNodePath) aCurrentNode.mSelfPath;
+ int tVoltLoss = 0;
+ if (tSelfPath != null) {
+ tVoltLoss += tSelfPath.getLoss();
+ tSelfPath.applyVoltage(aVoltage,false);
+ }
+ tPath.applyVoltage(aVoltage - tVoltLoss,true);
+ tVoltLoss += tPath.getLoss();
+ int tAmps = powerNodeAbove(aNextNode,aCurrentNode,aConsumers,aVoltage - tVoltLoss,aMaxAmps );
+ tPath.addAmps(tAmps);
+ if (tSelfPath != null)
+ tSelfPath.addAmps(tAmps);
+ return tAmps;
+ }
+
+ protected static int processNodeInject(Node aCurrentNode, ConsumerNode aConsumer, int aSide,int aMaxAmps, int aVoltage,
+ boolean isUp) {
+ PowerNodePath tPath = (PowerNodePath)aCurrentNode.mNodePaths[aSide];
+ PowerNodePath tSelfPath = (PowerNodePath) aCurrentNode.mSelfPath;
+ int tVoltLoss = 0;
+ if (tSelfPath != null) {
+ tVoltLoss += tSelfPath.getLoss();
+ tSelfPath.applyVoltage(aVoltage,false);
+ }
+ tPath.applyVoltage(aVoltage - tVoltLoss,true);
+ tVoltLoss += tPath.getLoss();
+ int tAmps = aConsumer.injectEnergy(aVoltage - tVoltLoss,aMaxAmps);
+ tPath.addAmps(tAmps);
+ if (tSelfPath != null)
+ tSelfPath.addAmps(tAmps);
+ return tAmps;
+ }
+}
diff --git a/src/main/java/gregtech/api/graphs/consumers/ConsumerNode.java b/src/main/java/gregtech/api/graphs/consumers/ConsumerNode.java
new file mode 100644
index 0000000000..87376008c4
--- /dev/null
+++ b/src/main/java/gregtech/api/graphs/consumers/ConsumerNode.java
@@ -0,0 +1,23 @@
+package gregtech.api.graphs.consumers;
+
+import gregtech.api.graphs.Node;
+import net.minecraft.tileentity.TileEntity;
+
+import java.util.ArrayList;
+
+//node attached to a tile entity that can consume stuff from the network
+public class ConsumerNode extends Node {
+ public byte mSide;
+ public ConsumerNode(int aNodeValue, TileEntity aTileEntity, byte aSide, ArrayList<ConsumerNode> aConsumers) {
+ super(aNodeValue,aTileEntity,aConsumers);
+ this.mSide = aSide;
+ }
+
+ public boolean needsEnergy() {
+ return !mTileEntity.isInvalid();
+ }
+
+ public int injectEnergy(int aVoltage, int aMaxAmps) {
+ return 0;
+ }
+}
diff --git a/src/main/java/gregtech/api/graphs/consumers/EmptyPowerConsumer.java b/src/main/java/gregtech/api/graphs/consumers/EmptyPowerConsumer.java
new file mode 100644
index 0000000000..da3d0a757b
--- /dev/null
+++ b/src/main/java/gregtech/api/graphs/consumers/EmptyPowerConsumer.java
@@ -0,0 +1,27 @@
+package gregtech.api.graphs.consumers;
+
+import gregtech.api.graphs.paths.PowerNodePath;
+import gregtech.api.metatileentity.BaseMetaPipeEntity;
+import net.minecraft.tileentity.TileEntity;
+
+import java.util.ArrayList;
+
+//this is here to apply voltage to death ends
+public class EmptyPowerConsumer extends ConsumerNode{
+ public EmptyPowerConsumer(int aNodeValue, TileEntity aTileEntity, byte aSide, ArrayList<ConsumerNode> aConsumers) {
+ super(aNodeValue, aTileEntity, aSide, aConsumers);
+ }
+
+ @Override
+ public boolean needsEnergy() {
+ return false;
+ }
+
+ @Override
+ public int injectEnergy(int aVoltage, int aMaxAmps) {
+ BaseMetaPipeEntity tPipe = (BaseMetaPipeEntity) mTileEntity;
+ PowerNodePath tPath =(PowerNodePath) tPipe.getNodePath();
+ tPath.applyVoltage(aVoltage,true);
+ return 0;
+ }
+}
diff --git a/src/main/java/gregtech/api/graphs/consumers/NodeEnergyReceiver.java b/src/main/java/gregtech/api/graphs/consumers/NodeEnergyReceiver.java
new file mode 100644
index 0000000000..c8c4c64211
--- /dev/null
+++ b/src/main/java/gregtech/api/graphs/consumers/NodeEnergyReceiver.java
@@ -0,0 +1,79 @@
+package gregtech.api.graphs.consumers;
+
+import cofh.api.energy.IEnergyReceiver;
+import gregtech.GT_Mod;
+import gregtech.api.GregTech_API;
+import gregtech.api.util.GT_Utility;
+import gregtech.api.util.WorldSpawnedEventBuilder;
+import gregtech.common.GT_Pollution;
+import net.minecraft.init.Blocks;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.World;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import java.util.ArrayList;
+
+import static gregtech.api.enums.GT_Values.V;
+
+//consumer for RF machines
+public class NodeEnergyReceiver extends ConsumerNode {
+ public NodeEnergyReceiver(int aNodeValue, IEnergyReceiver aTileEntity, byte aSide, ArrayList<ConsumerNode> aConsumers) {
+ super(aNodeValue, (TileEntity) aTileEntity, aSide, aConsumers);
+ }
+
+ @Override
+ public int injectEnergy(int aVoltage, int aMaxAmps) {
+ ForgeDirection tDirection = ForgeDirection.getOrientation(mSide);
+ int rfOut = GT_Utility.safeInt(aVoltage * GregTech_API.mEUtoRF / 100);
+ if (((IEnergyReceiver) mTileEntity).receiveEnergy(tDirection, rfOut, true) == rfOut) {
+ ((IEnergyReceiver) mTileEntity).receiveEnergy(tDirection, rfOut, false);
+ return 1;
+ }
+ if (GregTech_API.mRFExplosions && GregTech_API.sMachineExplosions &&
+ ((IEnergyReceiver) mTileEntity).getMaxEnergyStored(tDirection) < rfOut * 600L) {
+ explode(rfOut);
+ }
+ return 0;
+ }
+
+ //copied from IEnergyConnected
+ private void explode(int aRfOut) {
+ if (aRfOut > 32L * GregTech_API.mEUtoRF / 100L) {
+ int aExplosionPower = aRfOut;
+ float tStrength =
+ aExplosionPower < V[0] ? 1.0F :
+ aExplosionPower < V[1] ? 2.0F :
+ aExplosionPower < V[2] ? 3.0F :
+ aExplosionPower < V[3] ? 4.0F :
+ aExplosionPower < V[4] ? 5.0F :
+ aExplosionPower < V[4] * 2 ? 6.0F :
+ aExplosionPower < V[5] ? 7.0F :
+ aExplosionPower < V[6] ? 8.0F :
+ aExplosionPower < V[7] ? 9.0F :
+ aExplosionPower < V[8] ? 10.0F :
+ aExplosionPower < V[8] * 2 ? 11.0F :
+ aExplosionPower < V[9] ? 12.0F :
+ aExplosionPower < V[10] ? 13.0F :
+ aExplosionPower < V[11] ? 14.0F :
+ aExplosionPower < V[12] ? 15.0F :
+ aExplosionPower < V[12] * 2 ? 16.0F :
+ aExplosionPower < V[13] ? 17.0F :
+ aExplosionPower < V[14] ? 18.0F :
+ aExplosionPower < V[15] ? 19.0F : 20.0F;
+ int tX = mTileEntity.xCoord, tY = mTileEntity.yCoord, tZ = mTileEntity.zCoord;
+ World tWorld = mTileEntity.getWorldObj();
+ GT_Utility.sendSoundToPlayers(tWorld, GregTech_API.sSoundList.get(209), 1.0F, -1, tX, tY, tZ);
+ tWorld.setBlock(tX, tY, tZ, Blocks.air);
+ if (GregTech_API.sMachineExplosions)
+ if (GT_Mod.gregtechproxy.mPollution)
+ GT_Pollution.addPollution(tWorld.getChunkFromBlockCoords(tX, tZ), 100000);
+
+ new WorldSpawnedEventBuilder.ExplosionEffectEventBuilder()
+ .setStrength(tStrength)
+ .setSmoking(true)
+ .setPosition(tX + 0.5, tY + 0.5, tZ + 0.5)
+ .setWorld(tWorld)
+ .run();
+ }
+ }
+}
diff --git a/src/main/java/gregtech/api/graphs/consumers/NodeEnergySink.java b/src/main/java/gregtech/api/graphs/consumers/NodeEnergySink.java
new file mode 100644
index 0000000000..3f93c62010
--- /dev/null
+++ b/src/main/java/gregtech/api/graphs/consumers/NodeEnergySink.java
@@ -0,0 +1,28 @@
+package gregtech.api.graphs.consumers;
+
+import ic2.api.energy.tile.IEnergySink;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import java.util.ArrayList;
+
+//consumer for IC2 machines
+public class NodeEnergySink extends ConsumerNode {
+ public NodeEnergySink(int nodeValue, IEnergySink tileEntity, byte side, ArrayList<ConsumerNode> consumers) {
+ super(nodeValue, (TileEntity) tileEntity, side, consumers);
+ }
+
+ @Override
+ public boolean needsEnergy() {
+ return super.needsEnergy() && ((IEnergySink) mTileEntity).getDemandedEnergy() > 0;
+ }
+
+ @Override
+ public int injectEnergy(int aVoltage, int aMaxAmps) {
+ int tUsedAmps = 0;
+ while (aMaxAmps > tUsedAmps && ((IEnergySink) mTileEntity).getDemandedEnergy() > 0 &&
+ ((IEnergySink) mTileEntity).injectEnergy(ForgeDirection.getOrientation(mSide), aVoltage, aVoltage) < aVoltage)
+ tUsedAmps++;
+ return tUsedAmps;
+ }
+}
diff --git a/src/main/java/gregtech/api/graphs/consumers/NodeGTBaseMetaTile.java b/src/main/java/gregtech/api/graphs/consumers/NodeGTBaseMetaTile.java
new file mode 100644
index 0000000000..5c54ee16f9
--- /dev/null
+++ b/src/main/java/gregtech/api/graphs/consumers/NodeGTBaseMetaTile.java
@@ -0,0 +1,23 @@
+package gregtech.api.graphs.consumers;
+
+import gregtech.api.interfaces.tileentity.IEnergyConnected;
+import gregtech.api.metatileentity.BaseMetaTileEntity;
+import java.util.ArrayList;
+
+//consumer for gt machines
+public class NodeGTBaseMetaTile extends ConsumerNode {
+ public NodeGTBaseMetaTile(int aNodeValue, BaseMetaTileEntity aTileEntity, byte aSide, ArrayList<ConsumerNode> aConsumers) {
+ super(aNodeValue, aTileEntity, aSide, aConsumers);
+ }
+
+ @Override
+ public int injectEnergy(int aVoltage, int aMaxAmps) {
+ return (int)((IEnergyConnected) mTileEntity).injectEnergyUnits(mSide,aVoltage, aMaxAmps);
+ }
+
+ @Override
+ public boolean needsEnergy() {
+ BaseMetaTileEntity tTileEntity = (BaseMetaTileEntity) mTileEntity;
+ return super.needsEnergy() && tTileEntity.getStoredEU() < tTileEntity.getEUCapacity();
+ }
+}
diff --git a/src/main/java/gregtech/api/graphs/paths/NodePath.java b/src/main/java/gregtech/api/graphs/paths/NodePath.java
new file mode 100644
index 0000000000..ddbd570af3
--- /dev/null
+++ b/src/main/java/gregtech/api/graphs/paths/NodePath.java
@@ -0,0 +1,29 @@
+package gregtech.api.graphs.paths;
+
+import gregtech.api.metatileentity.BaseMetaPipeEntity;
+import gregtech.api.metatileentity.MetaPipeEntity;
+
+//to contain all info about the path between nodes
+public class NodePath {
+ protected MetaPipeEntity[] mPipes;
+
+ public NodePath(MetaPipeEntity[] aCables) {
+ this.mPipes = aCables;
+ processPipes();
+ }
+
+ public void clearPath() {
+ for (int i = 0; i< mPipes.length; i++) {
+ BaseMetaPipeEntity tBasePipe = (BaseMetaPipeEntity) mPipes[i].getBaseMetaTileEntity();
+ if (tBasePipe != null) {
+ tBasePipe.setNodePath(null);
+ }
+ }
+ }
+ protected void processPipes() {
+ for (MetaPipeEntity tPipe : mPipes) {
+ BaseMetaPipeEntity basePipe = (BaseMetaPipeEntity) tPipe.getBaseMetaTileEntity();
+ basePipe.setNodePath(this);
+ }
+ }
+}
diff --git a/src/main/java/gregtech/api/graphs/paths/PowerNodePath.java b/src/main/java/gregtech/api/graphs/paths/PowerNodePath.java
new file mode 100644
index 0000000000..736373a9ca
--- /dev/null
+++ b/src/main/java/gregtech/api/graphs/paths/PowerNodePath.java
@@ -0,0 +1,111 @@
+package gregtech.api.graphs.paths;
+
+import gregtech.api.metatileentity.BaseMetaPipeEntity;
+import gregtech.api.metatileentity.MetaPipeEntity;
+import gregtech.api.metatileentity.implementations.GT_MetaPipeEntity_Cable;
+import net.minecraft.server.MinecraftServer;
+
+//path for cables
+//all calculations like amp and voltage happens here
+public class PowerNodePath extends NodePath {
+ int mMaxAmps;
+ int mAmps = 0;
+ int mLoss;
+ int mVoltage = 0;
+ int mMaxVoltage;
+ int mTick = 0;
+ boolean mCountUp = true;
+
+
+ public PowerNodePath(MetaPipeEntity[] aCables) {
+ super(aCables);
+ }
+
+ public int getLoss() {
+ return mLoss;
+ }
+
+ public void applyVoltage(int aVoltage, boolean aCountUp) {
+ int tNewTime = MinecraftServer.getServer().getTickCounter();
+ if (mTick != tNewTime) {
+ reset(tNewTime - mTick);
+ mTick = tNewTime;
+ this.mVoltage = aVoltage;
+ this.mCountUp = aCountUp;
+ } else if (this.mCountUp != aCountUp && (aVoltage - mLoss)> this.mVoltage || aVoltage > this.mVoltage){
+ this.mCountUp = aCountUp;
+ this.mVoltage = aVoltage;
+ }
+ if (aVoltage > mMaxVoltage) {
+ for (MetaPipeEntity tCable : mPipes) {
+ if (((GT_MetaPipeEntity_Cable)tCable).mVoltage < this.mVoltage) {
+ BaseMetaPipeEntity tBaseCable = (BaseMetaPipeEntity) tCable.getBaseMetaTileEntity();
+ tBaseCable.setToFire();
+ }
+ }
+ }
+ }
+
+ public void addAmps(int aAmps) {
+ this.mAmps += aAmps;
+ if (this.mAmps > mMaxAmps * 40) {
+ for (MetaPipeEntity tCable : mPipes) {
+ if (((GT_MetaPipeEntity_Cable)tCable).mAmperage*40 < this.mAmps) {
+ BaseMetaPipeEntity tBaseCable = (BaseMetaPipeEntity) tCable.getBaseMetaTileEntity();
+ tBaseCable.setToFire();
+ }
+ }
+ }
+ }
+
+ //if no amps pass trough for more then 0.5 second reduce them to minimize wrong results
+ //but still allow the player to see if activity is happening
+ public int getAmps() {
+ int tTime = MinecraftServer.getServer().getTickCounter() - 10;
+ if (mTick < tTime) {
+ reset(tTime - mTick);
+ mTick = tTime;
+ }
+ return mAmps;
+ }
+
+ public int getVoltage(MetaPipeEntity aCable) {
+ int tLoss = 0;
+ if (mCountUp) {
+ for (int i = 0; i < mPipes.length; i++) {
+ GT_MetaPipeEntity_Cable tCable = (GT_MetaPipeEntity_Cable) mPipes[i];
+ tLoss += tCable.mCableLossPerMeter;
+ if (aCable == tCable) {
+ return Math.max(mVoltage - tLoss, 0);
+ }
+ }
+ } else {
+ for (int i = mPipes.length - 1; i >= 0; i--) {
+ GT_MetaPipeEntity_Cable tCable = (GT_MetaPipeEntity_Cable) mPipes[i];
+ tLoss += tCable.mCableLossPerMeter;
+ if (aCable == tCable) {
+ return Math.max(mVoltage - tLoss, 0);
+ }
+ }
+ }
+ return -1;
+ }
+
+ private void reset(int aTimePassed) {
+ mAmps = Math.max(0, mAmps - (mMaxAmps * aTimePassed));
+ }
+
+ @Override
+ protected void processPipes() {
+ super.processPipes();
+ mMaxAmps = Integer.MAX_VALUE;
+ mMaxVoltage = Integer.MAX_VALUE;
+ for (MetaPipeEntity tCable : mPipes) {
+ if (tCable instanceof GT_MetaPipeEntity_Cable) {
+ mMaxAmps = Math.min((int)((GT_MetaPipeEntity_Cable) tCable).mAmperage, mMaxAmps);
+ mLoss += (int)((GT_MetaPipeEntity_Cable) tCable).mCableLossPerMeter;
+ mMaxVoltage = Math.min((int)((GT_MetaPipeEntity_Cable) tCable).mVoltage, mMaxVoltage);
+ }
+ }
+ }
+}
diff --git a/src/main/java/gregtech/api/interfaces/tileentity/IEnergyConnected.java b/src/main/java/gregtech/api/interfaces/tileentity/IEnergyConnected.java
index 158b53068d..24d0576864 100644
--- a/src/main/java/gregtech/api/interfaces/tileentity/IEnergyConnected.java
+++ b/src/main/java/gregtech/api/interfaces/tileentity/IEnergyConnected.java
@@ -61,7 +61,7 @@ public interface IEnergyConnected extends IColoredTileEntity, IHasWorldObjectAnd
*/
public static final long emitEnergyToNetwork(long aVoltage, long aAmperage, IEnergyConnected aEmitter) {
long rUsedAmperes = 0;
- for (byte i = 0, j = 0; i < 6 && aAmperage > rUsedAmperes; i++)
+ for (byte i = 0, j = 0; i < 6 && aAmperage > rUsedAmperes; i++) {
if (aEmitter.outputsEnergyTo(i)) {
j = GT_Utility.getOppositeSide(i);
TileEntity tTileEntity = aEmitter.getTileEntityAtSide(i);
@@ -71,6 +71,7 @@ public interface IEnergyConnected extends IColoredTileEntity, IHasWorldObjectAnd
if (tColor >= 0 && tColor != aEmitter.getColorization()) continue;
}
rUsedAmperes += ((IEnergyConnected) tTileEntity).injectEnergyUnits(j, aVoltage, aAmperage - rUsedAmperes);
+
} else if (tTileEntity instanceof IEnergySink) {
if (((IEnergySink) tTileEntity).acceptsEnergyFrom((TileEntity) aEmitter, ForgeDirection.getOrientation(j))) {
while (aAmperage > rUsedAmperes && ((IEnergySink) tTileEntity).getDemandedEnergy() > 0 && ((IEnergySink) tTileEntity).injectEnergy(ForgeDirection.getOrientation(j), aVoltage, aVoltage) < aVoltage)
@@ -124,6 +125,7 @@ public interface IEnergyConnected extends IColoredTileEntity, IHasWorldObjectAnd
}
}
}
+ }
return rUsedAmperes;
}
}
diff --git a/src/main/java/gregtech/api/metatileentity/BaseMetaPipeEntity.java b/src/main/java/gregtech/api/metatileentity/BaseMetaPipeEntity.java
index 0fd8779244..b51377550b 100644
--- a/src/main/java/gregtech/api/metatileentity/BaseMetaPipeEntity.java
+++ b/src/main/java/gregtech/api/metatileentity/BaseMetaPipeEntity.java
@@ -12,6 +12,8 @@ import gregtech.GT_Mod;
import gregtech.api.GregTech_API;
import gregtech.api.enums.Textures;
import gregtech.api.enums.Textures.BlockIcons;
+import gregtech.api.graphs.Node;
+import gregtech.api.graphs.paths.NodePath;
import gregtech.api.interfaces.ITexture;
import gregtech.api.interfaces.metatileentity.IConnectable;
import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
@@ -62,6 +64,25 @@ public class BaseMetaPipeEntity extends BaseTileEntity implements IGregTechTileE
private int oX = 0, oY = 0, oZ = 0, mTimeStatisticsIndex = 0;
private short mID = 0;
private long mTickTimer = 0;
+ protected Node node;
+ protected NodePath nodePath;
+
+ public Node getNode() {
+ return node;
+ }
+
+ public void setNode(Node node) {
+ this.node = node;
+ }
+
+ public NodePath getNodePath() {
+ return nodePath;
+ }
+
+ public void setNodePath(NodePath nodePath) {
+ this.nodePath = nodePath;
+ }
+
public BaseMetaPipeEntity() {
}
@@ -262,12 +283,15 @@ public class BaseMetaPipeEntity extends BaseTileEntity implements IGregTechTileE
if (!hasValidMetaTileEntity()) return;
}
}
- // Mask-out Connection direction bits to keep only Foam related connections
+ byte oldConnections = mConnections;
+ // Mask-out connection direction bits to keep only Foam related connections
mConnections = (byte) (mMetaTileEntity.mConnections | (mConnections & ~IConnectable.CONNECTED_ALL));
// If foam not hardened, tries roll chance to harden
if ((mConnections & IConnectable.HAS_FOAM) == IConnectable.HAS_FRESHFOAM && getRandomNumber(1000) == 0) {
mConnections = (byte) ((mConnections & ~IConnectable.HAS_FRESHFOAM) | IConnectable.HAS_HARDENEDFOAM);
}
+ if (mTickTimer > 12 && oldConnections != mConnections)
+ GregTech_API.causeCableUpdate(worldObj,xCoord,yCoord,zCoord);
}
case 8:
tCode = 9;
diff --git a/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java
index f1a15aca40..341e7d5714 100644
--- a/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java
+++ b/src/main/java/gregtech/api/metatileentity/BaseMetaTileEntity.java
@@ -14,6 +14,9 @@ import gregtech.api.GregTech_API;
import gregtech.api.enums.ItemList;
import gregtech.api.enums.Textures;
import gregtech.api.enums.Textures.BlockIcons;
+import gregtech.api.graphs.GenerateNodeMap;
+import gregtech.api.graphs.GenerateNodeMapPower;
+import gregtech.api.graphs.Node;
import gregtech.api.interfaces.ITexture;
import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
import gregtech.api.interfaces.tileentity.IEnergyConnected;
@@ -40,6 +43,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.network.Packet;
+import net.minecraft.server.MinecraftServer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.EnumChatFormatting;
@@ -90,6 +94,7 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE
private String mOwnerName = "";
private UUID mOwnerUuid = GT_Utility.defaultUuid;
private NBTTagCompound mRecipeStuff = new NBTTagCompound();
+ private int cableUpdateDelay = 30;
public boolean mWasShutdown = false;
@@ -568,6 +573,12 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE
case 15:
tCode++;
if (aSideServer) {
+ if (mTickTimer > 20 && cableUpdateDelay == 0) {
+ generatePowerNodes();
+ cableUpdateDelay--;
+ } else {
+ cableUpdateDelay--;
+ }
if (mTickTimer % 10 == 0) {
if (mSendClientData) {
NW.sendPacketToAllPlayersInRange(worldObj,
@@ -869,6 +880,7 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE
mMetaTileEntity.onFacingChange();
doEnetUpdate();
+ cableUpdateDelay = 10;
if (mMetaTileEntity.shouldTriggerBlockUpdate()) {
// If we're triggering a block update this will call onMachineBlockUpdate()
@@ -971,6 +983,7 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE
@Override
public void onMachineBlockUpdate() {
if (canAccessData()) mMetaTileEntity.onMachineBlockUpdate();
+ cableUpdateDelay = 10;
}
/**
@@ -1098,6 +1111,26 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE
return isEnergyOutputSide(aSide);
}
+ public void generatePowerNodes() {
+ if (isServerSide() && mMetaTileEntity != null && (mMetaTileEntity.isEnetInput() || mMetaTileEntity.isEnetOutput())) {
+ int time = MinecraftServer.getServer().getTickCounter();
+ for (byte i = 0;i<6;i++) {
+ if (outputsEnergyTo(i,false) || inputEnergyFrom(i,false)) {
+ IGregTechTileEntity TE = getIGregTechTileEntityAtSide(i);
+ if (TE instanceof BaseMetaPipeEntity) {
+ Node node = ((BaseMetaPipeEntity) TE).getNode();
+ if (node == null) {
+ new GenerateNodeMapPower((BaseMetaPipeEntity) TE);
+ } else if (node.mCreationTime != time) {
+ GenerateNodeMap.clearNodeMap(node,-1);
+ new GenerateNodeMapPower((BaseMetaPipeEntity) TE);
+ }
+ }
+ }
+ }
+ }
+ }
+
@Override
public long getOutputAmperage() {
if (canAccessData() && mMetaTileEntity.isElectric()) return mMetaTileEntity.maxAmperesOut();
@@ -1399,9 +1432,11 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE
if(aPlayer.isSneaking() && mMetaTileEntity instanceof GT_MetaTileEntity_BasicMachine && ((GT_MetaTileEntity_BasicMachine)mMetaTileEntity).setMainFacing(GT_Utility.determineWrenchingSide(aSide, aX, aY, aZ))){
GT_ModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer);
GT_Utility.sendSoundToPlayers(worldObj, GregTech_API.sSoundList.get(100), 1.0F, -1, xCoord, yCoord, zCoord);
+ cableUpdateDelay = 10;
}else if (mMetaTileEntity.onWrenchRightClick(aSide, GT_Utility.determineWrenchingSide(aSide, aX, aY, aZ), aPlayer, aX, aY, aZ)) {
GT_ModHandler.damageOrDechargeItem(tCurrentItem, 1, 1000, aPlayer);
GT_Utility.sendSoundToPlayers(worldObj, GregTech_API.sSoundList.get(100), 1.0F, -1, xCoord, yCoord, zCoord);
+ cableUpdateDelay = 10;
}
return true;
}
@@ -1452,6 +1487,7 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE
issueBlockUpdate();
}
doEnetUpdate();
+ cableUpdateDelay = 10;
return true;
}
@@ -1462,6 +1498,7 @@ public class BaseMetaTileEntity extends BaseTileEntity implements IGregTechTileE
GT_Utility.sendSoundToPlayers(worldObj, GregTech_API.sSoundList.get(100), 1.0F, -1, xCoord, yCoord, zCoord);
}
doEnetUpdate();
+ cableUpdateDelay = 10;
return true;
}
diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java
index 84790ce958..87eee3e6ac 100644
--- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java
+++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java
@@ -63,6 +63,7 @@ public abstract class MetaTileEntity implements IMetaTileEntity {
public final ItemStack[] mInventory;
public boolean doTickProfilingInThisTick = true;
+
/**
* accessibility to this Field is no longer given, see below
*/
diff --git a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Cable.java b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Cable.java
index 93d947b9d0..b15e520da7 100644
--- a/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Cable.java
+++ b/src/main/java/gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Cable.java
@@ -9,6 +9,12 @@ import gregtech.api.enums.Dyes;
import gregtech.api.enums.Materials;
import gregtech.api.enums.TextureSet;
import gregtech.api.enums.Textures;
+import gregtech.api.graphs.PowerNode;
+import gregtech.api.graphs.PowerNodes;
+import gregtech.api.graphs.consumers.ConsumerNode;
+import gregtech.api.graphs.Node;
+import gregtech.api.graphs.NodeList;
+import gregtech.api.graphs.paths.PowerNodePath;
import gregtech.api.interfaces.ITexture;
import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
import gregtech.api.interfaces.metatileentity.IMetaTileEntityCable;
@@ -18,10 +24,7 @@ import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
import gregtech.api.metatileentity.BaseMetaPipeEntity;
import gregtech.api.metatileentity.MetaPipeEntity;
import gregtech.api.render.TextureFactory;
-import gregtech.api.util.GT_CoverBehavior;
-import gregtech.api.util.GT_GC_Compat;
-import gregtech.api.util.GT_ModHandler;
-import gregtech.api.util.GT_Utility;
+import gregtech.api.util.*;
import gregtech.common.GT_Client;
import gregtech.common.covers.GT_Cover_SolarPanel;
import ic2.api.energy.EnergyNet;
@@ -158,7 +161,8 @@ public class GT_MetaPipeEntity_Cable extends MetaPipeEntity implements IMetaTile
return 0;
if (!getBaseMetaTileEntity().getCoverBehaviorAtSide(aSide).letsEnergyIn(aSide, getBaseMetaTileEntity().getCoverIDAtSide(aSide), getBaseMetaTileEntity().getCoverDataAtSide(aSide), getBaseMetaTileEntity()))
return 0;
- return transferElectricity(aSide, aVoltage, aAmperage, Sets.newHashSet((TileEntity) getBaseMetaTileEntity()));
+ HashSet<TileEntity> nul = null;
+ return transferElectricity(aSide, aVoltage, aAmperage,nul);
}
@Override
@@ -169,118 +173,30 @@ public class GT_MetaPipeEntity_Cable extends MetaPipeEntity implements IMetaTile
@Override
public long transferElectricity(byte aSide, long aVoltage, long aAmperage, HashSet<TileEntity> aAlreadyPassedSet) {
- if (!isConnectedAtSide(aSide) && aSide != 6) return 0;
-
- long rUsedAmperes = 0;
- final IGregTechTileEntity baseMetaTile = getBaseMetaTileEntity();
- byte i = (byte)((((aSide/2)*2)+2)%6); //this bit of trickery makes sure a direction goes to the next cardinal pair. IE, NS goes to E, EW goes to U, UD goes to N. It's a lame way to make sure locally connected machines on a wire get EU first.
- aVoltage -= mCableLossPerMeter;
-
- if (aVoltage > 0) for (byte j = 0; j < 6 && aAmperage > rUsedAmperes; j++, i=(byte)((i+1)%6) )
- if (i != aSide && isConnectedAtSide(i) && baseMetaTile.getCoverBehaviorAtSide(i).letsEnergyOut(i, baseMetaTile.getCoverIDAtSide(i), baseMetaTile.getCoverDataAtSide(i), baseMetaTile)) {
- final TileEntity tTileEntity = baseMetaTile.getTileEntityAtSide(i);
-
- if (tTileEntity != null && aAlreadyPassedSet.add(tTileEntity)) {
- final byte tSide = GT_Utility.getOppositeSide(i);
- final IGregTechTileEntity tBaseMetaTile = tTileEntity instanceof IGregTechTileEntity ? ((IGregTechTileEntity) tTileEntity) : null;
- final IMetaTileEntity tMeta = tBaseMetaTile != null ? tBaseMetaTile.getMetaTileEntity() : null;
-
- if (tMeta instanceof IMetaTileEntityCable) {
- if (tBaseMetaTile.getCoverBehaviorAtSide(tSide).letsEnergyIn(tSide, tBaseMetaTile.getCoverIDAtSide(tSide), tBaseMetaTile.getCoverDataAtSide(tSide), tBaseMetaTile) && ((IGregTechTileEntity) tTileEntity).getTimer() > 50) {
- rUsedAmperes += ((IMetaTileEntityCable) ((IGregTechTileEntity) tTileEntity).getMetaTileEntity()).transferElectricity(tSide, aVoltage, aAmperage - rUsedAmperes, aAlreadyPassedSet);
- }
- } else {
- rUsedAmperes += insertEnergyInto(tTileEntity, tSide, aVoltage, aAmperage - rUsedAmperes);
- }
-
- }
- }
- mTransferredVoltage = Math.max(mTransferredVoltage, aVoltage);
- mTransferredAmperage += rUsedAmperes;
- mTransferredVoltageLast20 = Math.max(mTransferredVoltageLast20, aVoltage);
- mTransferredAmperageLast20 = Math.max(mTransferredAmperageLast20, mTransferredAmperage);
- if (aVoltage > mVoltage) {
- mOverheat += Math.max(100, 100 * GT_Utility.getTier(aVoltage) - GT_Utility.getTier(mVoltage));
- }
- if (mTransferredAmperage > mAmperage) return aAmperage;
-
- // Always return amount of used amperes, used on overheat
- return rUsedAmperes;
- }
-
-
-
- private long insertEnergyInto(TileEntity tTileEntity, byte tSide, long aVoltage, long aAmperage) {
- if (aAmperage == 0 || tTileEntity == null) return 0;
-
- final IGregTechTileEntity baseMetaTile = getBaseMetaTileEntity();
- final ForgeDirection tDirection = ForgeDirection.getOrientation(tSide);
-
- if (tTileEntity instanceof IEnergyConnected) {
- return ((IEnergyConnected) tTileEntity).injectEnergyUnits(tSide, aVoltage, aAmperage);
- }
-
- // AE2 Compat
- if (GT_Mod.gregtechproxy.mAE2Integration && tTileEntity instanceof appeng.tile.powersink.IC2) {
- if (((appeng.tile.powersink.IC2) tTileEntity).acceptsEnergyFrom((TileEntity) baseMetaTile, tDirection)) {
- long rUsedAmperes = 0;
- while (aAmperage > rUsedAmperes && ((appeng.tile.powersink.IC2)tTileEntity).getDemandedEnergy() > 0 && ((appeng.tile.powersink.IC2)tTileEntity).injectEnergy(tDirection, aVoltage, aVoltage) <= aVoltage)
- rUsedAmperes++;
-
- return rUsedAmperes;
- }
+ if (!getBaseMetaTileEntity().isServerSide() || !isConnectedAtSide(aSide) && aSide != 6) return 0;
+ BaseMetaPipeEntity tBase =(BaseMetaPipeEntity) getBaseMetaTileEntity();
+ if (!(tBase.getNode() instanceof PowerNode))
return 0;
- }
-
- if (Loader.isModLoaded("GalacticraftCore")) {
- long gc = GT_GC_Compat.insertEnergyInto(tTileEntity, aVoltage, tDirection);
- if (gc != 2)
- return gc;
- }
-
- // IC2 Compat
- {
- final TileEntity tIc2Acceptor = (tTileEntity instanceof IEnergyTile || EnergyNet.instance == null) ? tTileEntity :
- EnergyNet.instance.getTileEntity(tTileEntity.getWorldObj(), tTileEntity.xCoord, tTileEntity.yCoord, tTileEntity.zCoord);
-
- if (tIc2Acceptor instanceof IEnergySink && ((IEnergySink) tIc2Acceptor).acceptsEnergyFrom((TileEntity) baseMetaTile, tDirection)) {
- long rUsedAmperes = 0;
- while (aAmperage > rUsedAmperes && ((IEnergySink) tIc2Acceptor).getDemandedEnergy() > 0 && ((IEnergySink) tIc2Acceptor).injectEnergy(tDirection, aVoltage, aVoltage) <= aVoltage)
- rUsedAmperes++;
- return rUsedAmperes;
- }
- }
-
- // RF Compat
- if (GregTech_API.mOutputRF && tTileEntity instanceof IEnergyReceiver) {
- final IEnergyReceiver rfReceiver = (IEnergyReceiver) tTileEntity;
- long rfOUT = aVoltage * GregTech_API.mEUtoRF / 100, rUsedAmperes = 0;
- int rfOut = rfOUT > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) rfOUT;
-
- if (rfReceiver.receiveEnergy(tDirection, rfOut, true) == rfOut) {
- rfReceiver.receiveEnergy(tDirection, rfOut, false);
- rUsedAmperes++;
- }
- else if (rfReceiver.receiveEnergy(tDirection, rfOut, true) > 0) {
- if (mRestRF == 0) {
- int RFtrans = rfReceiver.receiveEnergy(tDirection, rfOut, false);
- rUsedAmperes++;
- mRestRF = rfOut - RFtrans;
- } else {
- int RFtrans = rfReceiver.receiveEnergy(tDirection, (int) mRestRF, false);
- mRestRF = mRestRF - RFtrans;
+ PowerNode tNode =(PowerNode) tBase.getNode();
+ if (tNode != null) {
+ int tPlace = 0;
+ Node[] tToPower = new Node[tNode.mConsumers.size()];
+ if (tNode.mHadVoltage) {
+ for (ConsumerNode consumer : tNode.mConsumers) {
+ if (consumer.needsEnergy())
+ tToPower[tPlace++] = consumer;
+ }
+ } else {
+ tNode.mHadVoltage = true;
+ for (ConsumerNode consumer : tNode.mConsumers) {
+ tToPower[tPlace++] = consumer;
}
}
- if (GregTech_API.mRFExplosions && rfReceiver.getMaxEnergyStored(tDirection) < rfOut * 600) {
- if (rfOut > 32 * GregTech_API.mEUtoRF / 100) this.doExplosion(rfOut);
- }
- return rUsedAmperes;
+ return PowerNodes.powerNode(tNode,null,new NodeList(tToPower),(int)aVoltage,(int)aAmperage);
}
-
return 0;
}
-
@Override
public void onFirstTick(IGregTechTileEntity aBaseMetaTileEntity) {
if(aBaseMetaTileEntity.isServerSide()) {
@@ -290,76 +206,6 @@ public class GT_MetaPipeEntity_Cable extends MetaPipeEntity implements IMetaTile
}
@Override
- public void onPostTick(IGregTechTileEntity aBaseMetaTileEntity, long aTick) {
- super.onPostTick(aBaseMetaTileEntity, aTick);
- if (aBaseMetaTileEntity.isServerSide()) {
-
- { //amp handler
- long worldTick = aBaseMetaTileEntity.getWorld().getTotalWorldTime();
- int tickDiff = (int) (worldTick - lastWorldTick);
- lastWorldTick = worldTick;
-
- if (tickDiff >= 16) for (int i = 0; i <= 14; i++) lastAmperage[i] = 0;
- else {
- System.arraycopy(lastAmperage, tickDiff, lastAmperage, 0, 16 - tickDiff);
- for (int i = 14; i >= 0; i--) {
- if (--tickDiff > 0) lastAmperage[i] = 0;
- else break;
- }
- }
-
- lastAmperage[15] = mTransferredAmperage;
-
- if (lastAmperage[15] > mAmperage) {
- int i = 0;
- for (; i <= 14; i++) {
- if (lastAmperage[i] < mAmperage) {
- lastAmperage[15] -= (int) mAmperage - lastAmperage[i];
- lastAmperage[i] = (int)mAmperage;
- if (lastAmperage[15] <= mAmperage) break;
- }
- }
- if (lastAmperage[15] > mAmperage) {
- mOverheat += 100 * (lastAmperage[15] - mAmperage);
- lastAmperage[15] = (int) mAmperage;
- } else if (lastAmperage[15] < mAmperage) {
- lastAmperage[i] = lastAmperage[15];
- lastAmperage[15] = (int) mAmperage;
- }
- }
- }
-
- if(mOverheat>=mMaxOverheat) {
- //TODO someday
- //int newMeta=aBaseMetaTileEntity.getMetaTileID()-6;
- //if(mInsulated &&
- // GregTech_API.METATILEENTITIES[newMeta] instanceof GT_MetaPipeEntity_Cable &&
- // ((GT_MetaPipeEntity_Cable)GregTech_API.METATILEENTITIES[newMeta]).mMaterial==mMaterial &&
- // ((GT_MetaPipeEntity_Cable)GregTech_API.METATILEENTITIES[newMeta]).mAmperage<=mAmperage){
- // aBaseMetaTileEntity.setOnFire();
- // aBaseMetaTileEntity.setMetaTileEntity(GregTech_API.METATILEENTITIES[newMeta]);
- // return;
- //}else{
- aBaseMetaTileEntity.setToFire();
- //}
- }else if (mOverheat>0) mOverheat--;
-
- mTransferredVoltageOK=mTransferredVoltage;
- mTransferredVoltage=0;
- mTransferredAmperageOK=mTransferredAmperage;
- mTransferredAmperage = 0;
-
- if (aTick % 20 == 0) {
- mTransferredVoltageLast20OK=mTransferredVoltageLast20;
- mTransferredVoltageLast20 = 0;
- mTransferredAmperageLast20OK=mTransferredAmperageLast20;
- mTransferredAmperageLast20 = 0;
- if (!GT_Mod.gregtechproxy.gt6Cable || mCheckConnections) checkConnections();
- }
- }
- }
-
- @Override
public boolean onWireCutterRightClick(byte aSide, byte aWrenchingSide, EntityPlayer aPlayer, float aX, float aY, float aZ) {
if (GT_Mod.gregtechproxy.gt6Cable && GT_ModHandler.damageOrDechargeItem(aPlayer.inventory.getCurrentItem(), 1, 500, aPlayer)) {
if(isConnectedAtSide(aWrenchingSide)) {
@@ -506,15 +352,23 @@ public class GT_MetaPipeEntity_Cable extends MetaPipeEntity implements IMetaTile
@Override
public String[] getInfoData() {
+ BaseMetaPipeEntity base = (BaseMetaPipeEntity) getBaseMetaTileEntity();
+ PowerNodePath path =(PowerNodePath) base.getNodePath();
+ int amps = 0;
+ int volts = 0;
+ if (path != null) {
+ amps = path.getAmps();
+ volts = path.getVoltage(this);
+ }
return new String[]{
//EnumChatFormatting.BLUE + mName + EnumChatFormatting.RESET,
"Heat: "+
EnumChatFormatting.RED+ mOverheat +EnumChatFormatting.RESET+" / "+EnumChatFormatting.YELLOW+ mMaxOverheat + EnumChatFormatting.RESET,
"Max Load (1t):",
- EnumChatFormatting.GREEN + Integer.toString(mTransferredAmperageOK) + EnumChatFormatting.RESET +" A / "+
+ EnumChatFormatting.GREEN + Integer.toString(amps) + EnumChatFormatting.RESET +" A / "+
EnumChatFormatting.YELLOW + mAmperage + EnumChatFormatting.RESET +" A",
"Max EU/p (1t):",
- EnumChatFormatting.GREEN + Long.toString(mTransferredVoltageOK) + EnumChatFormatting.RESET +" EU / "+
+ EnumChatFormatting.GREEN + Long.toString(volts) + EnumChatFormatting.RESET +" EU / "+
EnumChatFormatting.YELLOW + mVoltage + EnumChatFormatting.RESET +" EU",
"Max Load (20t): "+
EnumChatFormatting.GREEN + mTransferredAmperageLast20OK + EnumChatFormatting.RESET +" A",
diff --git a/src/main/java/gregtech/api/threads/GT_Runnable_Cable_Update.java b/src/main/java/gregtech/api/threads/GT_Runnable_Cable_Update.java
new file mode 100644
index 0000000000..7093184533
--- /dev/null
+++ b/src/main/java/gregtech/api/threads/GT_Runnable_Cable_Update.java
@@ -0,0 +1,69 @@
+package gregtech.api.threads;
+
+import gregtech.GT_Mod;
+import gregtech.api.interfaces.tileentity.IMachineBlockUpdateable;
+import gregtech.api.metatileentity.BaseMetaPipeEntity;
+import gregtech.api.metatileentity.implementations.GT_MetaPipeEntity_Cable;
+import gregtech.common.GT_Proxy;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.ChunkCoordinates;
+import net.minecraft.world.World;
+import net.minecraftforge.common.util.ForgeDirection;
+
+public class GT_Runnable_Cable_Update extends GT_Runnable_MachineBlockUpdate {
+ protected GT_Runnable_Cable_Update(World aWorld, ChunkCoordinates aCoords) {
+ super(aWorld, aCoords);
+ }
+
+ public static void setCableUpdateValues(World aWorld, ChunkCoordinates aCoords) {
+ if (isEnabled) {
+ EXECUTOR_SERVICE.submit(new GT_Runnable_Cable_Update(aWorld, aCoords));
+ }
+ }
+
+ @Override
+ public void run() {
+ try {
+ while (!tQueue.isEmpty()) {
+ final ChunkCoordinates aCoords = tQueue.poll();
+ final TileEntity tTileEntity;
+
+ GT_Proxy.TICK_LOCK.lock();
+ try {
+ //we dont want to go over cables that are in unloaded chunks
+ //keeping the lock just to make sure no CME happens
+ if (world.blockExists(aCoords.posX, aCoords.posY, aCoords.posZ)) {
+ tTileEntity = world.getTileEntity(aCoords.posX, aCoords.posY, aCoords.posZ);
+ } else {
+ tTileEntity = null;
+ }
+ } finally {
+ GT_Proxy.TICK_LOCK.unlock();
+ }
+
+ // See if the block itself needs an update
+ if (tTileEntity instanceof IMachineBlockUpdateable)
+ ((IMachineBlockUpdateable) tTileEntity).onMachineBlockUpdate();
+
+ // Now see if we should add the nearby blocks to the queue:
+ // only add blocks the cable is connected to
+ if (tTileEntity instanceof BaseMetaPipeEntity &&
+ ((BaseMetaPipeEntity) tTileEntity).getMetaTileEntity() instanceof GT_MetaPipeEntity_Cable)
+ {
+ ChunkCoordinates tCoords;
+ for (byte i = 0;i<6;i++) {
+ if (((GT_MetaPipeEntity_Cable) ((BaseMetaPipeEntity) tTileEntity).getMetaTileEntity()).isConnectedAtSide(i)) {
+ ForgeDirection offset = ForgeDirection.getOrientation(i);
+ if (visited.add(tCoords = new ChunkCoordinates(aCoords.posX + offset.offsetX,
+ aCoords.posY + offset.offsetY, aCoords.posZ + offset.offsetZ)))
+ tQueue.add(tCoords);
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ GT_Mod.GT_FML_LOGGER.error(
+ "Well this update was broken... " + mCoords + ", mWorld={" + world.getProviderName() + " @dimId " + world.provider.dimensionId + "}", e);
+ }
+ }
+}
diff --git a/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java b/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java
index 3ce1daf9b2..cc224b977d 100644
--- a/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java
+++ b/src/main/java/gregtech/api/threads/GT_Runnable_MachineBlockUpdate.java
@@ -19,10 +19,10 @@ import java.util.concurrent.TimeUnit;
public class GT_Runnable_MachineBlockUpdate implements Runnable {
// used by runner thread
- private final ChunkCoordinates mCoords;
- private final World world;
- private final Set<ChunkCoordinates> visited = new HashSet<>(80);
- private final Queue<ChunkCoordinates> tQueue = new LinkedList<>();
+ protected final ChunkCoordinates mCoords;
+ protected final World world;
+ protected final Set<ChunkCoordinates> visited = new HashSet<>(80);
+ protected final Queue<ChunkCoordinates> tQueue = new LinkedList<>();
// Threading
private static final ThreadFactory THREAD_FACTORY = r -> {
@@ -30,15 +30,14 @@ public class GT_Runnable_MachineBlockUpdate implements Runnable {
thread.setName("GT_MachineBlockUpdate");
return thread;
};
- private static ExecutorService EXECUTOR_SERVICE;
+ protected static ExecutorService EXECUTOR_SERVICE;
// This class should never be initiated outside of this class!
- private GT_Runnable_MachineBlockUpdate(World aWorld, ChunkCoordinates aCoords) {
+ protected GT_Runnable_MachineBlockUpdate(World aWorld, ChunkCoordinates aCoords) {
this.world = aWorld;
this.mCoords = aCoords;
visited.add(aCoords);
tQueue.add(aCoords);
-
}
public static boolean isEnabled() {
@@ -57,11 +56,10 @@ public class GT_Runnable_MachineBlockUpdate implements Runnable {
GT_Runnable_MachineBlockUpdate.isEnabled = isEnabled;
}
- private static boolean isEnabled = true;
+ protected static boolean isEnabled = true;
public static void setMachineUpdateValues(World aWorld, ChunkCoordinates aCoords) {
if (isEnabled) {
- aWorld.getTileEntity(aCoords.posX, aCoords.posY, aCoords.posZ);
EXECUTOR_SERVICE.submit(new GT_Runnable_MachineBlockUpdate(aWorld, aCoords));
}
}