Skip to content

Commit

Permalink
Forge direction (#1895)
Browse files Browse the repository at this point in the history
* ForgeDirection

Also refactor the clusterfuck that was `getCoordinateScan`

Co-authored by: Jason Mitchell <mitchej@gmail.com>

* Fix rendering of Frame Boxes

Frame boxes needed their own implementation of getTexture with int connexion mask,
which is returning an error texture for the MetaTileEntity, because pipes (FrameBox
**is** a pipe) do use this method to return different textures based on connexion
status.

---------

Co-authored-by: Léa Gris <lea.gris@noiraude.net>
  • Loading branch information
mitchej123 and leagris authored Apr 23, 2023
1 parent ac0b7a7 commit 56f2269
Show file tree
Hide file tree
Showing 285 changed files with 5,390 additions and 5,259 deletions.
10 changes: 6 additions & 4 deletions src/main/java/gregtech/api/events/BlockScanningEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.event.world.WorldEvent;

import cpw.mods.fml.common.eventhandler.Cancelable;
Expand All @@ -16,7 +17,7 @@ public class BlockScanningEvent extends WorldEvent {
public final EntityPlayer mPlayer;
public final int mX, mY, mZ, mScanLevel;
public final ArrayList<String> mList;
public final byte mSide;
public final ForgeDirection mSide;
public final float mClickX, mClickY, mClickZ;
public final TileEntity mTileEntity;
public final Block mBlock;
Expand All @@ -26,15 +27,16 @@ public class BlockScanningEvent extends WorldEvent {
*/
public int mEUCost = 0;

public BlockScanningEvent(World aWorld, EntityPlayer aPlayer, int aX, int aY, int aZ, byte aSide, int aScanLevel,
Block aBlock, TileEntity aTileEntity, ArrayList<String> aList, float aClickX, float aClickY, float aClickZ) {
public BlockScanningEvent(World aWorld, EntityPlayer aPlayer, int aX, int aY, int aZ, ForgeDirection side,
int aScanLevel, Block aBlock, TileEntity aTileEntity, ArrayList<String> aList, float aClickX, float aClickY,
float aClickZ) {
super(aWorld);
mPlayer = aPlayer;
mScanLevel = aScanLevel;
mTileEntity = aTileEntity;
mBlock = aBlock;
mList = aList;
mSide = aSide;
mSide = side;
mX = aX;
mY = aY;
mZ = aZ;
Expand Down
85 changes: 45 additions & 40 deletions src/main/java/gregtech/api/graphs/GenerateNodeMap.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package gregtech.api.graphs;

import static gregtech.api.enums.GT_Values.ALL_VALID_SIDES;
import static gregtech.api.util.GT_Utility.getOppositeSide;

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;
Expand Down Expand Up @@ -42,17 +42,17 @@ public static void clearNodeMap(Node aNode, int aReturnNodeValue) {
// get how many connections the pipe have
private static int getNumberOfConnections(MetaPipeEntity aPipe) {
int tCons = 0;
for (byte side : ALL_VALID_SIDES) {
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, byte aInvalidSide, int aNextNodeValue,
ArrayList<ConsumerNode> tConsumers, HashSet<Node> tNodeMap) {
protected void generateNextNode(BaseMetaPipeEntity aPipe, Node aPipeNode, ForgeDirection aInvalidSide,
int aNextNodeValue, ArrayList<ConsumerNode> tConsumers, HashSet<Node> tNodeMap) {
final MetaPipeEntity tMetaPipe = (MetaPipeEntity) aPipe.getMetaTileEntity();
for (byte side : ALL_VALID_SIDES) {
for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) {
if (side == aInvalidSide) {
continue;
}
Expand All @@ -70,12 +70,13 @@ protected void generateNextNode(BaseMetaPipeEntity aPipe, Node aPipeNode, byte a
tConsumers,
tNodeMap);
if (tNextNode != null) {
final int i = side.ordinal();
aNextNodeValue = tNextNode.mHighestNodeValue;
aPipeNode.mHighestNodeValue = tNextNode.mHighestNodeValue;
aPipeNode.mNeighbourNodes[side] = tNextNode;
aPipeNode.mNodePaths[side] = aPipeNode.returnValues.mReturnPath;
aPipeNode.locks[side] = aPipeNode.returnValues.returnLock;
aPipeNode.mNodePaths[side].reloadLocks();
aPipeNode.mNeighbourNodes[i] = tNextNode;
aPipeNode.mNodePaths[i] = aPipeNode.returnValues.mReturnPath;
aPipeNode.locks[i] = aPipeNode.returnValues.returnLock;
aPipeNode.mNodePaths[i].reloadLocks();
}
}
}
Expand All @@ -84,52 +85,55 @@ protected void generateNextNode(BaseMetaPipeEntity aPipe, Node aPipeNode, byte a

// 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) {
ArrayList<MetaPipeEntity> aPipes, ForgeDirection side, ArrayList<ConsumerNode> aConsumers,
HashSet<Node> aNodeMap) {
if (aTileEntity.isInvalid()) return null;
final byte tSideOp = getOppositeSide(aSide);
final byte tInvalidSide = aPreviousNode == null ? -1 : tSideOp;
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, tSideOp, aTileEntity, aConsumers);
tPipeNode = getEmptyNode(aNextNodeValue, oppositeSide, aTileEntity, aConsumers);
if (tPipeNode == null) return null;
} else {
tPipeNode = getPipeNode(aNextNodeValue, tSideOp, aTileEntity, aConsumers);
tPipeNode = getPipeNode(aNextNodeValue, oppositeSide, 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]));
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[tSideOp].lock = lock;
tPipeNode.locks[tInvalidSide] = lock;
aPreviousNode.returnValues.mReturnPath = tPipeNode.mNodePaths[tInvalidSide];
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, tSideOp, aNextNodeValue, aConsumers)) {
} else if (addConsumer(aTileEntity, oppositeSide, aNextNodeValue, aConsumers)) {
final int oppositeSideOrdinal = oppositeSide.ordinal();
final ConsumerNode tConsumeNode = aConsumers.get(aConsumers.size() - 1);
tConsumeNode.mNeighbourNodes[tSideOp] = aPreviousNode;
tConsumeNode.mNodePaths[tSideOp] = getNewPath(aPipes.toArray(new MetaPipeEntity[0]));
tConsumeNode.mNeighbourNodes[oppositeSideOrdinal] = aPreviousNode;
tConsumeNode.mNodePaths[oppositeSideOrdinal] = getNewPath(aPipes.toArray(new MetaPipeEntity[0]));
final Lock lock = new Lock();
tConsumeNode.mNodePaths[tSideOp].lock = lock;
aPreviousNode.returnValues.mReturnPath = tConsumeNode.mNodePaths[tSideOp];
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, byte aSide,
protected Pair getNextValidTileEntity(TileEntity aTileEntity, ArrayList<MetaPipeEntity> aPipes, ForgeDirection side,
HashSet<Node> aNodeMap) {
if (isPipe(aTileEntity)) {
final BaseMetaPipeEntity tPipe = (BaseMetaPipeEntity) aTileEntity;
Expand All @@ -140,23 +144,23 @@ protected Pair getNextValidTileEntity(TileEntity aTileEntity, ArrayList<MetaPipe
}
final int tConnections = getNumberOfConnections(tMetaPipe);
if (tConnections == 2) {
final byte tSideOp = getOppositeSide(aSide);
for (byte i : ALL_VALID_SIDES) {
if (i == tSideOp || !(tMetaPipe.isConnectedAtSide(i))) continue;
final TileEntity tNewTileEntity = tPipe.getTileEntityAtSide(i);
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, i, aNodeMap);
return getNextValidTileEntity(tNewTileEntity, aPipes, s, aNodeMap);
} else {
return new Pair(aTileEntity, i);
return new Pair(aTileEntity, s);
}
}
} else {
return new Pair(aTileEntity, aSide);
return new Pair(aTileEntity, side);
}
} else {
return new Pair(aTileEntity, aSide);
return new Pair(aTileEntity, side);
}
return null;
}
Expand All @@ -167,31 +171,32 @@ protected boolean isPipe(TileEntity aTileEntity) {
}

// checks if the tile entity is a consumer and add to the list
protected abstract boolean addConsumer(TileEntity aTileEntity, byte aSide, int aNodeValue,
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, byte aSide, TileEntity aTileEntity,
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, byte aSide, TileEntity aTileEntity, ArrayList<ConsumerNode> aConsumers) {
protected Node getPipeNode(int aNodeValue, ForgeDirection side, TileEntity aTileEntity,
ArrayList<ConsumerNode> aConsumers) {
return new Node(aNodeValue, aTileEntity, aConsumers);
}

private static class Pair {

public byte mSide;
public ForgeDirection mSide;
public TileEntity mTileEntity;

public Pair(TileEntity aTileEntity, byte aSide) {
public Pair(TileEntity aTileEntity, ForgeDirection side) {
this.mTileEntity = aTileEntity;
this.mSide = aSide;
this.mSide = side;
}
}
}
39 changes: 18 additions & 21 deletions src/main/java/gregtech/api/graphs/GenerateNodeMapPower.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
public class GenerateNodeMapPower extends GenerateNodeMap {

public GenerateNodeMapPower(BaseMetaPipeEntity aTileEntity) {
generateNode(aTileEntity, null, 1, null, -1, new ArrayList<>(), new HashSet<>());
generateNode(aTileEntity, null, 1, null, ForgeDirection.UNKNOWN, new ArrayList<>(), new HashSet<>());
}

@Override
Expand All @@ -37,49 +37,45 @@ protected boolean isPipe(TileEntity aTileEntity) {
}

@Override
protected boolean addConsumer(TileEntity aTileEntity, byte aSide, int aNodeValue,
protected boolean addConsumer(TileEntity aTileEntity, ForgeDirection side, int aNodeValue,
ArrayList<ConsumerNode> aConsumers) {
if (aTileEntity instanceof BaseMetaTileEntity tBaseTileEntity) {
if (tBaseTileEntity.inputEnergyFrom(aSide, false)) {
ConsumerNode tConsumerNode = new NodeGTBaseMetaTile(aNodeValue, tBaseTileEntity, aSide, aConsumers);
if (tBaseTileEntity.inputEnergyFrom(side, false)) {
ConsumerNode tConsumerNode = new NodeGTBaseMetaTile(aNodeValue, tBaseTileEntity, side, aConsumers);
aConsumers.add(tConsumerNode);
return true;
}

} else if (aTileEntity instanceof IEnergyConnected tTileEntity) {
if (tTileEntity.inputEnergyFrom(aSide, false)) {
ConsumerNode tConsumerNode = new NodeEnergyConnected(aNodeValue, tTileEntity, aSide, aConsumers);
if (tTileEntity.inputEnergyFrom(side, false)) {
ConsumerNode tConsumerNode = new NodeEnergyConnected(aNodeValue, tTileEntity, side, aConsumers);
aConsumers.add(tConsumerNode);
return true;
}
} else if (aTileEntity instanceof IEnergySink) {
} else if (aTileEntity instanceof IEnergySink sink) {
// ic2 wants the tilentity next to it of that side not going to add a bunch of arguments just for ic2
// crossborder checks to 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;
int dX = aTileEntity.xCoord + side.offsetX;
int dY = aTileEntity.yCoord + side.offsetY;
int dZ = aTileEntity.zCoord + side.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))) {
if (sink.acceptsEnergyFrom(tNextTo, side)) {
ConsumerNode tConsumerNode = new NodeEnergySink(
aNodeValue,
(IEnergySink) aTileEntity,
aSide,
side,
aConsumers);
aConsumers.add(tConsumerNode);
return true;
}
} else if (GregTech_API.mOutputRF && aTileEntity instanceof IEnergyReceiver) {
ConsumerNode tConsumerNode = new NodeEnergyReceiver(
aNodeValue,
(IEnergyReceiver) aTileEntity,
aSide,
aConsumers);
} else if (GregTech_API.mOutputRF && aTileEntity instanceof IEnergyReceiver receiver) {
ConsumerNode tConsumerNode = new NodeEnergyReceiver(aNodeValue, receiver, side, aConsumers);
aConsumers.add(tConsumerNode);
return true;
}
Expand All @@ -93,15 +89,16 @@ protected NodePath getNewPath(MetaPipeEntity[] aPipes) {

// used to apply voltage on dead ends
@Override
protected Node getEmptyNode(int aNodeValue, byte aSide, TileEntity aTileEntity,
protected Node getEmptyNode(int aNodeValue, ForgeDirection side, TileEntity aTileEntity,
ArrayList<ConsumerNode> aConsumers) {
ConsumerNode tNode = new EmptyPowerConsumer(aNodeValue, aTileEntity, aSide, aConsumers);
ConsumerNode tNode = new EmptyPowerConsumer(aNodeValue, aTileEntity, side, aConsumers);
aConsumers.add(tNode);
return tNode;
}

@Override
protected Node getPipeNode(int aNodeValue, byte aSide, TileEntity aTileEntity, ArrayList<ConsumerNode> aConsumers) {
protected Node getPipeNode(int aNodeValue, ForgeDirection side, TileEntity aTileEntity,
ArrayList<ConsumerNode> aConsumers) {
return new PowerNode(aNodeValue, aTileEntity, aConsumers);
}
}
18 changes: 9 additions & 9 deletions src/main/java/gregtech/api/graphs/PowerNodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,13 @@ protected static long powerNodeAbove(Node aCurrentNode, Node aPreviousNode, Node
return tAmpsUsed;
}

protected static long processNextNode(Node aCurrentNode, Node aNextNode, NodeList aConsumers, int aSide,
protected static long processNextNode(Node aCurrentNode, Node aNextNode, NodeList aConsumers, int ordinalSide,
long aMaxAmps, long aVoltage) {
if (aCurrentNode.locks[aSide].isLocked()) {
if (aCurrentNode.locks[ordinalSide].isLocked()) {
aConsumers.getNextNode();
return 0;
}
final PowerNodePath tPath = (PowerNodePath) aCurrentNode.mNodePaths[aSide];
final PowerNodePath tPath = (PowerNodePath) aCurrentNode.mNodePaths[ordinalSide];
final PowerNodePath tSelfPath = (PowerNodePath) aCurrentNode.mSelfPath;
long tVoltLoss = 0;
if (tSelfPath != null) {
Expand All @@ -141,13 +141,13 @@ protected static long processNextNode(Node aCurrentNode, Node aNextNode, NodeLis
return tAmps;
}

protected static long processNextNodeAbove(Node aCurrentNode, Node aNextNode, NodeList aConsumers, int aSide,
protected static long processNextNodeAbove(Node aCurrentNode, Node aNextNode, NodeList aConsumers, int ordinalSide,
long aMaxAmps, long aVoltage) {
if (aCurrentNode.locks[aSide].isLocked()) {
if (aCurrentNode.locks[ordinalSide].isLocked()) {
aConsumers.getNextNode();
return 0;
}
final PowerNodePath tPath = (PowerNodePath) aCurrentNode.mNodePaths[aSide];
final PowerNodePath tPath = (PowerNodePath) aCurrentNode.mNodePaths[ordinalSide];
final PowerNodePath tSelfPath = (PowerNodePath) aCurrentNode.mSelfPath;
long tVoltLoss = 0;
if (tSelfPath != null) {
Expand All @@ -162,10 +162,10 @@ protected static long processNextNodeAbove(Node aCurrentNode, Node aNextNode, No
return tAmps;
}

protected static long processNodeInject(Node aCurrentNode, ConsumerNode aConsumer, int aSide, long aMaxAmps,
protected static long processNodeInject(Node aCurrentNode, ConsumerNode aConsumer, int ordinalSide, long aMaxAmps,
long aVoltage) {
if (aCurrentNode.locks[aSide].isLocked()) return 0;
final PowerNodePath tPath = (PowerNodePath) aCurrentNode.mNodePaths[aSide];
if (aCurrentNode.locks[ordinalSide].isLocked()) return 0;
final PowerNodePath tPath = (PowerNodePath) aCurrentNode.mNodePaths[ordinalSide];
final PowerNodePath tSelfPath = (PowerNodePath) aCurrentNode.mSelfPath;
long tVoltLoss = 0;
if (tSelfPath != null) {
Expand Down
Loading

0 comments on commit 56f2269

Please sign in to comment.