diff options
author | Kiwi <42833050+Kiwi233@users.noreply.github.com> | 2021-07-05 22:06:44 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-05 22:06:44 +0800 |
commit | 4eaefbb5455dc3402b43dcbf6cba208cea4e301a (patch) | |
tree | b7e34b2e20af663cdd72c616fd7424301304e3e4 /src/main/java/gregtech/api/graphs/PowerNodes.java | |
parent | 36406947fc5c0de1ee71da2644ec057b5fbc8d25 (diff) | |
parent | 703a8930bee25b1f908e9c4ea4f52cef24337d03 (diff) | |
download | GT5-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.java | 162 |
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; + } +} |