aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/api/graphs/GenerateNodeMap.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/gregtech/api/graphs/GenerateNodeMap.java')
-rw-r--r--src/main/java/gregtech/api/graphs/GenerateNodeMap.java202
1 files changed, 202 insertions, 0 deletions
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..7289f0faad
--- /dev/null
+++ b/src/main/java/gregtech/api/graphs/GenerateNodeMap.java
@@ -0,0 +1,202 @@
+package gregtech.api.graphs;
+
+import static gregtech.api.enums.GT_Values.ALL_VALID_SIDES;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+
+import net.minecraft.tileentity.TileEntity;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import gregtech.api.graphs.consumers.ConsumerNode;
+import gregtech.api.graphs.paths.NodePath;
+import gregtech.api.metatileentity.BaseMetaPipeEntity;
+import gregtech.api.metatileentity.MetaPipeEntity;
+
+// generates the node map
+public abstract 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 tPipe) {
+ tPipe.setNode(null);
+ tPipe.setNodePath(null);
+ if (aNode.mSelfPath != null) {
+ aNode.mSelfPath.clearPath();
+ aNode.mSelfPath = null;
+ }
+ }
+ for (byte side : ALL_VALID_SIDES) {
+ final NodePath tPath = aNode.mNodePaths[side];
+ if (tPath != null) {
+ tPath.clearPath();
+ aNode.mNodePaths[side] = null;
+ }
+ final Node tNextNode = aNode.mNeighbourNodes[side];
+ if (tNextNode == null) continue;
+ if (tNextNode.mNodeValue != aReturnNodeValue) clearNodeMap(tNextNode, aNode.mNodeValue);
+ aNode.mNeighbourNodes[side] = null;
+ }
+ }
+
+ // get how many connections the pipe have
+ private static int getNumberOfConnections(MetaPipeEntity aPipe) {
+ int tCons = 0;
+ for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) {
+ if (aPipe.isConnectedAtSide(side)) tCons++;
+ }
+ return tCons;
+ }
+
+ // gets the next node
+ protected void generateNextNode(BaseMetaPipeEntity aPipe, Node aPipeNode, ForgeDirection aInvalidSide,
+ int aNextNodeValue, ArrayList<ConsumerNode> tConsumers, HashSet<Node> tNodeMap) {
+ final MetaPipeEntity tMetaPipe = (MetaPipeEntity) aPipe.getMetaTileEntity();
+ for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) {
+ if (side == aInvalidSide) {
+ continue;
+ }
+ final TileEntity tNextTileEntity = aPipe.getTileEntityAtSide(side);
+ if (tNextTileEntity == null || (tMetaPipe != null && !tMetaPipe.isConnectedAtSide(side))) continue;
+ final ArrayList<MetaPipeEntity> tNewPipes = new ArrayList<>();
+ final Pair nextTileEntity = getNextValidTileEntity(tNextTileEntity, tNewPipes, side, tNodeMap);
+ if (nextTileEntity != null) {
+ final Node tNextNode = generateNode(
+ nextTileEntity.mTileEntity,
+ aPipeNode,
+ aNextNodeValue + 1,
+ tNewPipes,
+ nextTileEntity.mSide,
+ tConsumers,
+ tNodeMap);
+ if (tNextNode != null) {
+ final int i = side.ordinal();
+ aNextNodeValue = tNextNode.mHighestNodeValue;
+ aPipeNode.mHighestNodeValue = tNextNode.mHighestNodeValue;
+ aPipeNode.mNeighbourNodes[i] = tNextNode;
+ aPipeNode.mNodePaths[i] = aPipeNode.returnValues.mReturnPath;
+ aPipeNode.locks[i] = aPipeNode.returnValues.returnLock;
+ aPipeNode.mNodePaths[i].reloadLocks();
+ }
+ }
+ }
+ aPipe.reloadLocks();
+ }
+
+ // on a valid tile entity create a new node
+ protected Node generateNode(TileEntity aTileEntity, Node aPreviousNode, int aNextNodeValue,
+ ArrayList<MetaPipeEntity> aPipes, ForgeDirection side, ArrayList<ConsumerNode> aConsumers,
+ HashSet<Node> aNodeMap) {
+ if (aTileEntity.isInvalid()) return null;
+ final ForgeDirection oppositeSide = side.getOpposite();
+ final ForgeDirection tInvalidSide = aPreviousNode == null ? ForgeDirection.UNKNOWN : oppositeSide;
+ Node tThisNode = null;
+ if (isPipe(aTileEntity)) {
+ final BaseMetaPipeEntity tPipe = (BaseMetaPipeEntity) aTileEntity;
+ final MetaPipeEntity tMetaPipe = (MetaPipeEntity) tPipe.getMetaTileEntity();
+ final int tConnections = getNumberOfConnections(tMetaPipe);
+ final Node tPipeNode;
+ if (tConnections == 1) {
+ tPipeNode = getEmptyNode(aNextNodeValue, oppositeSide, aTileEntity, aConsumers);
+ if (tPipeNode == null) return null;
+ } else {
+ tPipeNode = getPipeNode(aNextNodeValue, oppositeSide, aTileEntity, aConsumers);
+ }
+ tPipe.setNode(tPipeNode);
+ aNodeMap.add(tPipeNode);
+ tPipeNode.mSelfPath = getNewPath(new MetaPipeEntity[] { tMetaPipe });
+ tThisNode = tPipeNode;
+ if (tInvalidSide != ForgeDirection.UNKNOWN) {
+ final int iInvalid = tInvalidSide.ordinal();
+ tPipeNode.mNeighbourNodes[iInvalid] = aPreviousNode;
+ tPipeNode.mNodePaths[iInvalid] = getNewPath(aPipes.toArray(new MetaPipeEntity[0]));
+ final Lock lock = new Lock();
+ tPipeNode.mNodePaths[oppositeSide.ordinal()].lock = lock;
+ tPipeNode.locks[iInvalid] = lock;
+ aPreviousNode.returnValues.mReturnPath = tPipeNode.mNodePaths[iInvalid];
+ aPreviousNode.returnValues.returnLock = lock;
+ }
+ if (tConnections > 1)
+ generateNextNode(tPipe, tPipeNode, tInvalidSide, aNextNodeValue, aConsumers, aNodeMap);
+ } else if (addConsumer(aTileEntity, oppositeSide, aNextNodeValue, aConsumers)) {
+ final int oppositeSideOrdinal = oppositeSide.ordinal();
+ final ConsumerNode tConsumeNode = aConsumers.get(aConsumers.size() - 1);
+ tConsumeNode.mNeighbourNodes[oppositeSideOrdinal] = aPreviousNode;
+ tConsumeNode.mNodePaths[oppositeSideOrdinal] = getNewPath(aPipes.toArray(new MetaPipeEntity[0]));
+ final Lock lock = new Lock();
+ tConsumeNode.mNodePaths[oppositeSideOrdinal].lock = lock;
+ aPreviousNode.returnValues.mReturnPath = tConsumeNode.mNodePaths[oppositeSideOrdinal];
+ aPreviousNode.returnValues.returnLock = lock;
+ 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, ForgeDirection side,
+ HashSet<Node> aNodeMap) {
+ if (isPipe(aTileEntity)) {
+ final BaseMetaPipeEntity tPipe = (BaseMetaPipeEntity) aTileEntity;
+ final MetaPipeEntity tMetaPipe = (MetaPipeEntity) tPipe.getMetaTileEntity();
+ final Node tNode = tPipe.getNode();
+ if (tNode != null) {
+ if (aNodeMap.contains(tNode)) return null;
+ }
+ final int tConnections = getNumberOfConnections(tMetaPipe);
+ if (tConnections == 2) {
+ final ForgeDirection tSideOp = side.getOpposite();
+ for (final ForgeDirection s : ForgeDirection.VALID_DIRECTIONS) {
+ if (s == tSideOp || !(tMetaPipe.isConnectedAtSide(s))) continue;
+ final TileEntity tNewTileEntity = tPipe.getTileEntityAtSide(s);
+ if (tNewTileEntity == null) continue;
+ if (isPipe(tNewTileEntity)) {
+ aPipes.add(tMetaPipe);
+ return getNextValidTileEntity(tNewTileEntity, aPipes, s, aNodeMap);
+ } else {
+ return new Pair(aTileEntity, s);
+ }
+ }
+ } else {
+ return new Pair(aTileEntity, side);
+ }
+ } else {
+ return new Pair(aTileEntity, side);
+ }
+ return null;
+ }
+
+ // 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
+ protected abstract boolean addConsumer(TileEntity aTileEntity, ForgeDirection side, 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 dead ends for something can be null
+ protected Node getEmptyNode(int aNodeValue, ForgeDirection side, TileEntity aTileEntity,
+ ArrayList<ConsumerNode> aConsumers) {
+ return null;
+ }
+
+ // get correct node type you need for your network
+ protected Node getPipeNode(int aNodeValue, ForgeDirection side, TileEntity aTileEntity,
+ ArrayList<ConsumerNode> aConsumers) {
+ return new Node(aNodeValue, aTileEntity, aConsumers);
+ }
+
+ private static class Pair {
+
+ public ForgeDirection mSide;
+ public TileEntity mTileEntity;
+
+ public Pair(TileEntity aTileEntity, ForgeDirection side) {
+ this.mTileEntity = aTileEntity;
+ this.mSide = side;
+ }
+ }
+}