aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/api/graphs/PowerNodes.java
diff options
context:
space:
mode:
authorKiwi <42833050+Kiwi233@users.noreply.github.com>2021-07-05 22:06:44 +0800
committerGitHub <noreply@github.com>2021-07-05 22:06:44 +0800
commit4eaefbb5455dc3402b43dcbf6cba208cea4e301a (patch)
treeb7e34b2e20af663cdd72c616fd7424301304e3e4 /src/main/java/gregtech/api/graphs/PowerNodes.java
parent36406947fc5c0de1ee71da2644ec057b5fbc8d25 (diff)
parent703a8930bee25b1f908e9c4ea4f52cef24337d03 (diff)
downloadGT5-Unofficial-4eaefbb5455dc3402b43dcbf6cba208cea4e301a.tar.gz
GT5-Unofficial-4eaefbb5455dc3402b43dcbf6cba208cea4e301a.tar.bz2
GT5-Unofficial-4eaefbb5455dc3402b43dcbf6cba208cea4e301a.zip
Merge pull request #3 from GTNewHorizons/experimental
gregtech-5.09.35.00
Diffstat (limited to 'src/main/java/gregtech/api/graphs/PowerNodes.java')
-rw-r--r--src/main/java/gregtech/api/graphs/PowerNodes.java162
1 files changed, 162 insertions, 0 deletions
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;
+ }
+}