diff options
Diffstat (limited to 'src/main/java/gregtech/api/graphs/GenerateNodeMap.java')
-rw-r--r-- | src/main/java/gregtech/api/graphs/GenerateNodeMap.java | 202 |
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; + } + } +} |