use of logisticspipes.routing.LaserData in project LogisticsPipes by RS485.
the class LogisticsHUDRenderer method renderWorldRelative.
@SideOnly(Side.CLIENT)
public void renderWorldRelative(long renderTicks, float partialTick) {
if (!displayRenderer()) {
return;
}
Minecraft mc = FMLClientHandler.instance().getClient();
EntityPlayer player = mc.player;
if (list.size() == 0 || Math.hypot(lastXPos - player.posX, Math.hypot(lastYPos - player.posY, lastZPos - player.posZ)) > 0.5 || (renderTicks % 10 == 0 && (lastXPos != player.posX || lastYPos != player.posY || lastZPos != player.posZ)) || renderTicks % 600 == 0) {
refreshList(player.posX, player.posY, player.posZ);
lastXPos = player.posX;
lastYPos = player.posY;
lastZPos = player.posZ;
}
boolean cursorHandled = false;
displayCross = false;
IHUDConfig config;
if (debugHUD == null) {
config = new HUDConfig(mc.player.inventory.armorInventory.get(3));
} else {
config = new IHUDConfig() {
@Override
public boolean isHUDSatellite() {
return false;
}
@Override
public boolean isHUDProvider() {
return false;
}
@Override
public boolean isHUDPowerLevel() {
return false;
}
@Override
public boolean isHUDInvSysCon() {
return false;
}
@Override
public boolean isHUDCrafting() {
return false;
}
@Override
public boolean isChassisHUD() {
return false;
}
@Override
public void setChassisHUD(boolean state) {
}
@Override
public void setHUDCrafting(boolean state) {
}
@Override
public void setHUDInvSysCon(boolean state) {
}
@Override
public void setHUDPowerJunction(boolean state) {
}
@Override
public void setHUDProvider(boolean state) {
}
@Override
public void setHUDSatellite(boolean state) {
}
};
}
IHeadUpDisplayRendererProvider thisIsLast = null;
List<IHeadUpDisplayRendererProvider> toUse = list;
if (debugHUD != null) {
toUse = debugHUD.getHUDs();
}
for (IHeadUpDisplayRendererProvider renderer : toUse) {
if (renderer.getRenderer() == null) {
continue;
}
if (renderer.getRenderer().display(config)) {
GL11.glPushMatrix();
if (!cursorHandled) {
double x = renderer.getX() + 0.5 - player.posX;
double y = renderer.getY() + 0.5 - player.posY;
double z = renderer.getZ() + 0.5 - player.posZ;
if (Math.hypot(x, Math.hypot(y, z)) < 0.75 || (renderer instanceof IHeadUpDisplayBlockRendererProvider && (((IHeadUpDisplayBlockRendererProvider) renderer).isHUDInvalid() || !((IHeadUpDisplayBlockRendererProvider) renderer).isHUDExistent()))) {
refreshList(player.posX, player.posY, player.posZ);
GL11.glPopMatrix();
break;
}
int[] pos = getCursor(renderer);
if (pos.length == 2) {
if (renderer.getRenderer().cursorOnWindow(pos[0], pos[1])) {
renderer.getRenderer().handleCursor(pos[0], pos[1]);
if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) {
// if(FMLClientHandler.instance().getClient().player.isSneaking()) {
thisIsLast = renderer;
displayCross = true;
}
cursorHandled = true;
}
}
}
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
if (thisIsLast != renderer) {
displayOneView(renderer, config, partialTick, false);
}
GL11.glPopMatrix();
}
}
if (thisIsLast != null) {
GL11.glPushMatrix();
GL11.glDisable(GL11.GL_BLEND);
GL11.glDisable(GL11.GL_DEPTH_TEST);
displayOneView(thisIsLast, config, partialTick, true);
GL11.glEnable(GL11.GL_BLEND);
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glPopMatrix();
}
GL11.glPushMatrix();
RayTraceResult box = mc.objectMouseOver;
if (box != null && box.typeOfHit == RayTraceResult.Type.BLOCK) {
if (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL)) {
progress = Math.min(progress + (2 * Math.max(1, (int) Math.floor((System.currentTimeMillis() - last) / 50.0D))), 100);
} else {
progress = Math.max(progress - (2 * Math.max(1, (int) Math.floor((System.currentTimeMillis() - last) / 50.0D))), 0);
}
if (progress != 0) {
List<String> textData = SimpleServiceLocator.neiProxy.getInfoForPosition(player.world, player, box);
if (!textData.isEmpty()) {
double xCoord = box.getBlockPos().getX() + 0.5D;
double yCoord = box.getBlockPos().getY() + 0.5D;
double zCoord = box.getBlockPos().getZ() + 0.5D;
double x = xCoord - player.prevPosX - ((player.posX - player.prevPosX) * partialTick);
double y = yCoord - player.prevPosY - ((player.posY - player.prevPosY) * partialTick);
double z = zCoord - player.prevPosZ - ((player.posZ - player.prevPosZ) * partialTick);
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glTranslatef((float) x, (float) y, (float) z);
GL11.glRotatef(90.0F, 1.0F, 0.0F, 0.0F);
GL11.glRotatef(getAngle(z, x) + 110F, 0.0F, 0.0F, 1.0F);
GL11.glRotatef((-1) * getAngle(Math.hypot(x + 0.8, z + 0.8), y + 0.5) + 180, 1.0F, 0.0F, 0.0F);
double dProgress = progress / 100D;
GL11.glTranslated(0.4D * dProgress + 0.6D, -0.2D * dProgress - 0.6D, -0.0D);
GL11.glScalef(0.01F, 0.01F, 1F);
int heigth = Math.max(32, 10 * textData.size() + 15);
int width = 0;
for (String s : textData) {
width = Math.max(width, mc.fontRenderer.getStringWidth(s) + 22);
}
width = Math.max(32, width + 15);
GL11.glColor4b((byte) 127, (byte) 127, (byte) 127, (byte) 96);
GuiGraphics.drawGuiBackGround(mc, (int) ((-0.5 * (width - 32)) * dProgress) - 16, (int) ((-0.5 * (heigth - 32)) * dProgress) - 16, (int) ((0.5 * (width - 32)) * dProgress) + 16, (int) ((0.5 * (heigth - 32)) * dProgress) + 16, 0, false);
GL11.glColor4b((byte) 127, (byte) 127, (byte) 127, (byte) 127);
if (progress == 100) {
GL11.glTranslated((int) ((-0.5 * (width - 32)) * dProgress) - 16, (int) ((-0.5 * (heigth - 32)) * dProgress) - 16, -0.0001D);
for (int i = 0; i < textData.size(); i++) {
mc.fontRenderer.drawString(textData.get(i), 28, 8 + i * 10, 0x000000);
}
ItemStack stack = SimpleServiceLocator.neiProxy.getItemForPosition(player.world, player, box);
if (!stack.isEmpty()) {
float scaleX = 1.5F * 0.8F;
float scaleY = 1.5F * 0.8F;
float scaleZ = -0.0001F;
GL11.glScalef(scaleX, scaleY, scaleZ);
ItemStackRenderer itemStackRenderer = new ItemStackRenderer(5, 6, 0.0F, true, true);
itemStackRenderer.setItemstack(stack).setDisplayAmount(DisplayAmount.NEVER);
itemStackRenderer.setScaleX(scaleX).setScaleY(scaleY).setScaleZ(scaleZ);
itemStackRenderer.renderInGui();
}
}
GL11.glEnable(GL11.GL_DEPTH_TEST);
}
}
} else if (!Keyboard.isKeyDown(Keyboard.KEY_LCONTROL)) {
progress = 0;
}
GL11.glPopMatrix();
// Render Laser
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
// GL11.glEnable(GL11.GL_LIGHTING);
for (LaserData data : lasers) {
GL11.glPushMatrix();
double x = data.getPosX() + 0.5 - player.prevPosX - ((player.posX - player.prevPosX) * partialTick);
double y = data.getPosY() + 0.5 - player.prevPosY - ((player.posY - player.prevPosY) * partialTick);
double z = data.getPosZ() + 0.5 - player.prevPosZ - ((player.posZ - player.prevPosZ) * partialTick);
GL11.glTranslatef((float) x, (float) y, (float) z);
switch(data.getDir()) {
case NORTH:
GL11.glRotatef(90.0F, 0.0F, 1.0F, 0.0F);
break;
case SOUTH:
GL11.glRotatef(-90.0F, 0.0F, 1.0F, 0.0F);
break;
case EAST:
break;
case WEST:
GL11.glRotatef(180.0F, 0.0F, 1.0F, 0.0F);
break;
case UP:
GL11.glRotatef(90.0F, 0.0F, 0.0F, 1.0F);
break;
case DOWN:
GL11.glRotatef(-90.0F, 0.0F, 0.0F, 1.0F);
break;
default:
break;
}
GL11.glScalef(0.01F, 0.01F, 0.01F);
Tessellator tessellator = Tessellator.getInstance();
for (float i = 0; i < 6 * data.getLength(); i++) {
setColor(i, data.getConnectionType());
float shift = 100f * i / 6f;
float start = 0.0f;
if (data.isStartPipe() && i == 0) {
start = -6.0f;
}
BufferBuilder buffer = tessellator.getBuffer();
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR);
buffer.pos(19.7f + shift, 3.0f, -3.0f);
buffer.pos(3.0f + shift + start, 3.0f, -3.0f);
buffer.pos(3.0f + shift + start, 3.0f, 3.0f);
buffer.pos(19.7f + shift, 3.0f, 3.0f);
tessellator.draw();
buffer = tessellator.getBuffer();
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR);
buffer.pos(19.7f + shift, -3.0f, 3.0f);
buffer.pos(3.0f + shift + start, -3.0f, 3.0f);
buffer.pos(3.0f + shift + start, -3.0f, -3.0f);
buffer.pos(19.7f + shift, -3.0f, -3.0f);
tessellator.draw();
buffer = tessellator.getBuffer();
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR);
buffer.pos(19.7f + shift, 3.0f, 3.0f);
buffer.pos(3.0f + shift + start, 3.0f, 3.0f);
buffer.pos(3.0f + shift + start, -3.0f, 3.0f);
buffer.pos(19.7f + shift, -3.0f, 3.0f);
tessellator.draw();
buffer = tessellator.getBuffer();
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR);
buffer.pos(19.7f + shift, -3.0f, -3.0f);
buffer.pos(3.0f + shift + start, -3.0f, -3.0f);
buffer.pos(3.0f + shift + start, 3.0f, -3.0f);
buffer.pos(19.7f + shift, 3.0f, -3.0f);
tessellator.draw();
}
if (data.isStartPipe()) {
setColor(0, data.getConnectionType());
BufferBuilder buffer = tessellator.getBuffer();
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR);
buffer.pos(-3.0f, 3.0f, 3.0f);
buffer.pos(-3.0f, 3.0f, -3.0f);
buffer.pos(-3.0f, -3.0f, -3.0f);
buffer.pos(-3.0f, -3.0f, 3.0f);
tessellator.draw();
}
if (data.isFinalPipe()) {
setColor(6 * data.getLength() - 1, data.getConnectionType());
BufferBuilder buffer = tessellator.getBuffer();
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR);
buffer.pos(100.0f * data.getLength() + 3f, 3.0f, -3.0f);
buffer.pos(100.0f * data.getLength() + 3f, 3.0f, 3.0f);
buffer.pos(100.0f * data.getLength() + 3f, -3.0f, 3.0f);
buffer.pos(100.0f * data.getLength() + 3f, -3.0f, -3.0f);
tessellator.draw();
}
GL11.glPopMatrix();
}
GL11.glEnable(GL11.GL_TEXTURE_2D);
last = System.currentTimeMillis();
}
use of logisticspipes.routing.LaserData in project LogisticsPipes by RS485.
the class RequestRoutingLasersPacket method processPacket.
@Override
public void processPacket(EntityPlayer player) {
LogisticsTileGenericPipe tile = this.getPipe(player.world);
if (tile == null) {
return;
}
if (tile.pipe instanceof CoreRoutedPipe) {
IRouter router = ((CoreRoutedPipe) tile.pipe).getRouter();
// this is here to allow players to manually trigger a network-wide LSA update
router.forceLsaUpdate();
List<List<ExitRoute>> exits = router.getRouteTable();
HashMap<EnumFacing, ArrayList<ExitRoute>> routers = new HashMap<>();
for (List<ExitRoute> exit : exits) {
if (exit == null) {
continue;
}
for (ExitRoute e : exit) {
if (!routers.containsKey(e.exitOrientation)) {
routers.put(e.exitOrientation, new ArrayList<>());
}
if (!routers.get(e.exitOrientation).contains(e)) {
routers.get(e.exitOrientation).add(e);
}
}
}
ArrayList<LaserData> lasers = new ArrayList<>();
firstPipe = true;
for (final EnumFacing dir : routers.keySet()) {
if (dir == null) {
continue;
}
handleRouteInDirection(tile, dir, routers.get(dir), lasers, EnumSet.allOf(PipeRoutingConnectionType.class), new Log() {
@Override
void log(String log) {
if (LogisticsPipes.isDEBUG()) {
System.out.println(dir.name() + ": " + log);
}
}
});
}
lasers = compressLasers(lasers);
MainProxy.sendPacketToPlayer(PacketHandler.getPacket(RoutingLaserPacket.class).setLasers(lasers), player);
}
}
use of logisticspipes.routing.LaserData in project LogisticsPipes by RS485.
the class RequestRoutingLasersPacket method handleRouteInDirection.
private void handleRouteInDirection(final LogisticsTileGenericPipe pipeIn, ForgeDirection dirIn, ArrayList<ExitRoute> connectedRoutersIn, final List<LaserData> lasersIn, EnumSet<PipeRoutingConnectionType> connectionTypeIn, final Log logIn) {
List<DataEntry> worklist = new LinkedList<>();
worklist.add(new DataEntry(pipeIn, dirIn, connectedRoutersIn, lasersIn, connectionTypeIn, logIn));
while (!worklist.isEmpty()) {
final DataEntry entry = worklist.remove(0);
final LogisticsTileGenericPipe pipe = entry.pipe;
final ForgeDirection dir = entry.dir;
final ArrayList<ExitRoute> connectedRouters = entry.connectedRouters;
final List<LaserData> lasers = entry.lasers;
final EnumSet<PipeRoutingConnectionType> connectionType = entry.connectionType;
final Log log = entry.log;
if (LPConstants.DEBUG) {
log.log("Size: " + connectedRouters.size());
}
lasers.add(new LaserData(pipe.xCoord, pipe.yCoord, pipe.zCoord, dir, connectionType).setStartPipe(firstPipe));
firstPipe = false;
HashMap<CoreRoutedPipe, ExitRoute> map = PathFinder.paintAndgetConnectedRoutingPipes(pipe, dir, Configs.LOGISTICS_DETECTION_COUNT, Configs.LOGISTICS_DETECTION_LENGTH, (worldObj, laser) -> {
if (pipe.getWorld() == worldObj) {
lasers.add(laser);
}
}, connectionType);
for (CoreRoutedPipe connectedPipe : map.keySet()) {
IRouter newRouter = connectedPipe.getRouter();
Iterator<ExitRoute> iRoutes = connectedRouters.iterator();
while (iRoutes.hasNext()) {
ExitRoute route = iRoutes.next();
if (route.destination == newRouter) {
iRoutes.remove();
}
}
}
Map<CoreRoutedPipe, ArrayList<ExitRoute>> sort = new HashMap<>();
for (ExitRoute routeTo : connectedRouters) {
ExitRoute result = null;
CoreRoutedPipe resultPipe = null;
for (Entry<CoreRoutedPipe, ExitRoute> routeCanidate : map.entrySet()) {
List<ExitRoute> distances = routeCanidate.getValue().destination.getDistanceTo(routeTo.destination);
for (ExitRoute distance : distances) {
if (distance.isSameWay(routeTo)) {
if (result == null || result.distanceToDestination > distance.distanceToDestination) {
result = distance;
resultPipe = routeCanidate.getKey();
}
}
}
}
if (result == null) {
continue;
}
if (!sort.containsKey(resultPipe)) {
sort.put(resultPipe, new ArrayList<>());
}
if (!sort.get(resultPipe).contains(result)) {
sort.get(resultPipe).add(result);
}
}
for (Entry<CoreRoutedPipe, ArrayList<ExitRoute>> connectedPipe : sort.entrySet()) {
HashMap<ForgeDirection, ArrayList<ExitRoute>> routers = new HashMap<>();
for (ExitRoute exit : connectedPipe.getValue()) {
if (!routers.containsKey(exit.exitOrientation)) {
routers.put(exit.exitOrientation, new ArrayList<>());
}
if (!routers.get(exit.exitOrientation).contains(exit)) {
routers.get(exit.exitOrientation).add(exit);
}
}
for (final ForgeDirection exitDir : routers.keySet()) {
if (exitDir == ForgeDirection.UNKNOWN) {
continue;
}
worklist.add(new DataEntry(connectedPipe.getKey().container, exitDir, routers.get(exitDir), lasers, map.get(connectedPipe.getKey()).connectionDetails, new Log() {
@Override
void log(String logString) {
if (LPConstants.DEBUG) {
log.log(exitDir.name() + ": " + logString);
}
}
}));
}
}
}
}
use of logisticspipes.routing.LaserData in project LogisticsPipes by RS485.
the class PathFinder method getConnectedRoutingPipes.
private HashMap<CoreRoutedPipe, ExitRoute> getConnectedRoutingPipes(IPipeInformationProvider startPipe, EnumSet<PipeRoutingConnectionType> connectionFlags, ForgeDirection side) {
HashMap<CoreRoutedPipe, ExitRoute> foundPipes = new HashMap<>();
boolean root = setVisited.size() == 0;
//Reset visited count at top level
if (setVisited.size() == 1) {
pipesVisited = 0;
}
//Break recursion if we have visited a set number of pipes, to prevent client hang if pipes are weirdly configured
if (++pipesVisited > maxVisited) {
return foundPipes;
}
//Break recursion after certain amount of nodes visited
if (setVisited.size() > maxLength) {
return foundPipes;
}
if (!startPipe.isRouterInitialized()) {
return foundPipes;
}
//Break recursion if we end up on a routing pipe, unless its the first one. Will break if matches the first call
if (startPipe.isRoutingPipe() && setVisited.size() != 0) {
CoreRoutedPipe rp = startPipe.getRoutingPipe();
if (rp.stillNeedReplace()) {
return foundPipes;
}
double size = 0;
for (Double dis : distances.values()) {
size += dis;
}
if (!rp.getUpgradeManager().hasPowerPassUpgrade()) {
connectionFlags.remove(PipeRoutingConnectionType.canPowerSubSystemFrom);
}
foundPipes.put(rp, new ExitRoute(null, rp.getRouter(), ForgeDirection.UNKNOWN, side.getOpposite(), Math.max(1, size), connectionFlags, distances.size()));
return foundPipes;
}
//Visited is checked after, so we can reach the same target twice to allow to keep the shortest path
setVisited.add(new DoubleCoordinates(startPipe));
distances.put(new DoubleCoordinates(startPipe), startPipe.getDistance());
// first check specialPipeConnections (tesseracts, teleports, other connectors)
List<ConnectionInformation> pipez = SimpleServiceLocator.specialpipeconnection.getConnectedPipes(startPipe, connectionFlags, side);
for (ConnectionInformation specialConnection : pipez) {
if (setVisited.contains(new DoubleCoordinates(specialConnection.getConnectedPipe()))) {
//Don't go where we have been before
continue;
}
distances.put(new DoubleCoordinates(startPipe).center(), specialConnection.getDistance());
HashMap<CoreRoutedPipe, ExitRoute> result = getConnectedRoutingPipes(specialConnection.getConnectedPipe(), specialConnection.getConnectionFlags(), specialConnection.getInsertOrientation());
distances.remove(new DoubleCoordinates(startPipe).center());
for (Entry<CoreRoutedPipe, ExitRoute> pipe : result.entrySet()) {
pipe.getValue().exitOrientation = specialConnection.getExitOrientation();
ExitRoute foundPipe = foundPipes.get(pipe.getKey());
if (foundPipe == null || (pipe.getValue().distanceToDestination < foundPipe.distanceToDestination)) {
// New path OR If new path is better, replace old path
foundPipes.put(pipe.getKey(), pipe.getValue());
}
}
}
ArrayDeque<Pair<TileEntity, ForgeDirection>> connections = new ArrayDeque<>();
//Recurse in all directions
for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS) {
if (root && !ForgeDirection.UNKNOWN.equals(side) && !direction.equals(side)) {
continue;
}
// tile may be up to 1 second old, but any neighbour pipe change will cause an immidiate update here, so we know that if it has changed, it isn't a pipe that has done so.
TileEntity tile = startPipe.getNextConnectedTile(direction);
if (tile == null) {
continue;
}
if (OrientationsUtil.isSide(direction)) {
if (root && tile instanceof ILogisticsPowerProvider) {
if (powerNodes == null) {
powerNodes = new ArrayList<>();
}
//If we are a FireWall pipe add our filter to the pipes
if (startPipe.isFirewallPipe()) {
powerNodes.add(new Pair<>((ILogisticsPowerProvider) tile, new OneList<>(startPipe.getFirewallFilter())));
} else {
powerNodes.add(new Pair<>((ILogisticsPowerProvider) tile, Collections.unmodifiableList(new ArrayList<>(0))));
}
}
if (root && tile instanceof ISubSystemPowerProvider) {
if (subPowerProvider == null) {
subPowerProvider = new ArrayList<>();
}
//If we are a FireWall pipe add our filter to the pipes
if (startPipe.isFirewallPipe()) {
subPowerProvider.add(new Pair<>((ISubSystemPowerProvider) tile, new OneList<>(startPipe.getFirewallFilter())));
} else {
subPowerProvider.add(new Pair<>((ISubSystemPowerProvider) tile, Collections.unmodifiableList(new ArrayList<>(0))));
}
}
}
connections.add(new Pair<>(tile, direction));
}
while (!connections.isEmpty()) {
Pair<TileEntity, ForgeDirection> pair = connections.pollFirst();
TileEntity tile = pair.getValue1();
ForgeDirection direction = pair.getValue2();
EnumSet<PipeRoutingConnectionType> nextConnectionFlags = EnumSet.copyOf(connectionFlags);
boolean isDirectConnection = false;
int resistance = 0;
if (root) {
Collection<TileEntity> list = SimpleServiceLocator.specialtileconnection.getConnectedPipes(tile);
if (!list.isEmpty()) {
connections.addAll(list.stream().map(pipe -> new Pair<>(pipe, direction)).collect(Collectors.toList()));
listTileEntity(tile);
continue;
}
if (!startPipe.getRoutingPipe().getUpgradeManager().hasPowerPassUpgrade()) {
nextConnectionFlags.remove(PipeRoutingConnectionType.canPowerSubSystemFrom);
}
}
if (tile instanceof IInventory && startPipe.isRoutingPipe() && startPipe.getRoutingPipe() instanceof IDirectRoutingConnection && startPipe.canConnect(tile, direction, false)) {
if (SimpleServiceLocator.connectionManager.hasDirectConnection(startPipe.getRoutingPipe().getRouter())) {
CoreRoutedPipe CRP = SimpleServiceLocator.connectionManager.getConnectedPipe(startPipe.getRoutingPipe().getRouter());
if (CRP != null) {
tile = CRP.container;
isDirectConnection = true;
resistance = ((IDirectRoutingConnection) startPipe.getRoutingPipe()).getConnectionResistance();
}
}
}
if (tile == null) {
continue;
}
IPipeInformationProvider currentPipe = SimpleServiceLocator.pipeInformationManager.getInformationProviderFor(tile);
if (currentPipe != null && currentPipe.isRouterInitialized() && (isDirectConnection || SimpleServiceLocator.pipeInformationManager.canConnect(startPipe, currentPipe, direction, true))) {
listTileEntity(tile);
// DON'T USE THIS ANYMORE CAN CAUSE TROUBLE WITH MULTIBLOCKS
tile = null;
if (currentPipe.isMultiBlock()) {
currentPipe.getPartsOfPipe().forEach(this::listTileEntity);
}
if (setVisited.contains(new DoubleCoordinates(currentPipe))) {
//Don't go where we have been before
continue;
}
if (side != pair.getValue2() && !root) {
//Only straight connections for subsystem power
nextConnectionFlags.remove(PipeRoutingConnectionType.canPowerSubSystemFrom);
}
if (isDirectConnection) {
//ISC doesn't pass power
nextConnectionFlags.remove(PipeRoutingConnectionType.canPowerFrom);
nextConnectionFlags.remove(PipeRoutingConnectionType.canPowerSubSystemFrom);
}
//Iron, obsidean and liquid pipes will separate networks
if (currentPipe.divideNetwork()) {
continue;
}
if (currentPipe.powerOnly()) {
nextConnectionFlags.remove(PipeRoutingConnectionType.canRouteTo);
nextConnectionFlags.remove(PipeRoutingConnectionType.canRequestFrom);
}
if (startPipe.isOnewayPipe()) {
if (!startPipe.isOutputOpen(direction)) {
nextConnectionFlags.remove(PipeRoutingConnectionType.canRouteTo);
}
}
if (currentPipe.isOnewayPipe()) {
nextConnectionFlags.remove(PipeRoutingConnectionType.canPowerSubSystemFrom);
if (!currentPipe.isOutputOpen(direction.getOpposite())) {
nextConnectionFlags.remove(PipeRoutingConnectionType.canRequestFrom);
nextConnectionFlags.remove(PipeRoutingConnectionType.canPowerFrom);
}
}
if (nextConnectionFlags.isEmpty()) {
//don't bother going somewhere we can't do anything with
continue;
}
int beforeRecurseCount = foundPipes.size();
HashMap<CoreRoutedPipe, ExitRoute> result = null;
if (currentPipe instanceof IRouteProvider) {
List<RouteInfo> list = ((IRouteProvider) currentPipe).getConnectedPipes(direction.getOpposite());
if (list != null) {
result = new HashMap<>();
DoubleCoordinates pos = new DoubleCoordinates(currentPipe);
for (RouteInfo info : list) {
if (info.getPipe() == startPipe)
continue;
if (setVisited.contains(new DoubleCoordinates(info.getPipe()))) {
//Don't go where we have been before
continue;
}
distances.put(pos, currentPipe.getDistance() + info.getLength());
result.putAll(getConnectedRoutingPipes(info.getPipe(), nextConnectionFlags, direction));
distances.remove(pos);
}
}
}
if (result == null) {
result = getConnectedRoutingPipes(currentPipe, nextConnectionFlags, direction);
}
for (Entry<CoreRoutedPipe, ExitRoute> pipeEntry : result.entrySet()) {
//Update Result with the direction we took
pipeEntry.getValue().exitOrientation = direction;
ExitRoute foundPipe = foundPipes.get(pipeEntry.getKey());
if (foundPipe == null) {
// New path
foundPipes.put(pipeEntry.getKey(), pipeEntry.getValue());
//Add resistance
pipeEntry.getValue().distanceToDestination += resistance;
} else if (pipeEntry.getValue().distanceToDestination + resistance < foundPipe.distanceToDestination) {
//If new path is better, replace old path, otherwise do nothing
foundPipes.put(pipeEntry.getKey(), pipeEntry.getValue());
//Add resistance
pipeEntry.getValue().distanceToDestination += resistance;
}
}
if (foundPipes.size() > beforeRecurseCount && pathPainter != null) {
pathPainter.addLaser(startPipe.getWorld(), new LaserData(startPipe.getX(), startPipe.getY(), startPipe.getZ(), direction, connectionFlags));
}
}
}
setVisited.remove(new DoubleCoordinates(startPipe));
distances.remove(new DoubleCoordinates(startPipe));
if (startPipe.isRoutingPipe()) {
// ie, has the recursion returned to the pipe it started from?
for (ExitRoute e : foundPipes.values()) {
e.root = (startPipe.getRoutingPipe()).getRouter();
}
}
//If we are a FireWall pipe add our filter to the pipes
if (startPipe.isFirewallPipe() && root) {
for (ExitRoute e : foundPipes.values()) {
e.filters = new OneList<>(startPipe.getFirewallFilter());
}
}
return foundPipes;
}
use of logisticspipes.routing.LaserData in project LogisticsPipes by RS485.
the class PathFinder method getConnectedRoutingPipes.
private HashMap<CoreRoutedPipe, ExitRoute> getConnectedRoutingPipes(IPipeInformationProvider startPipe, EnumSet<PipeRoutingConnectionType> connectionFlags, EnumFacing side) {
HashMap<CoreRoutedPipe, ExitRoute> foundPipes = new HashMap<>();
final int setVisitedSize = setVisited.size();
boolean root = setVisitedSize == 0;
// Reset visited count at top level
if (setVisitedSize == 1) {
pipesVisited = 0;
}
// Break recursion if we have visited a set number of pipes, to prevent client hang if pipes are weirdly configured
pipesVisited += startPipe.getDistanceWeight() > 0 ? startPipe.getDistanceWeight() : 1;
if (pipesVisited > maxVisited) {
return foundPipes;
}
// Break recursion after certain amount of nodes visited
if (setVisitedSize > maxLength * 10) {
return foundPipes;
}
// Check size of setVisited first to speed up the process, so we don't sum the distances all the time
if (setVisitedSize > maxLength && distances.values().stream().mapToDouble(i -> Math.max(Math.min(i, 1), 0)).sum() > maxLength) {
return foundPipes;
}
if (!startPipe.isRouterInitialized()) {
return foundPipes;
}
// Break recursion if we end up on a routing pipe, unless its the first one. Will break if matches the first call
if (startPipe.isRoutingPipe() && setVisitedSize != 0) {
CoreRoutedPipe rp = startPipe.getRoutingPipe();
if (rp.stillNeedReplace()) {
return foundPipes;
}
double size = 0;
for (Double dis : distances.values()) {
size += dis;
}
if (!rp.getUpgradeManager().hasPowerPassUpgrade()) {
connectionFlags.remove(PipeRoutingConnectionType.canPowerSubSystemFrom);
}
foundPipes.put(rp, new ExitRoute(null, rp.getRouter(), null, side.getOpposite(), Math.max(1, size), connectionFlags, distances.size()));
return foundPipes;
}
// Visited is checked after, so we can reach the same target twice to allow to keep the shortest path
setVisited.add(new DoubleCoordinates(startPipe));
distances.put(new DoubleCoordinates(startPipe), startPipe.getDistance() * startPipe.getDistanceWeight());
// first check specialPipeConnections (tesseracts, teleports, other connectors)
List<ConnectionInformation> pipez = SimpleServiceLocator.specialpipeconnection.getConnectedPipes(startPipe, connectionFlags, side);
for (ConnectionInformation specialConnection : pipez) {
if (setVisited.contains(new DoubleCoordinates(specialConnection.getConnectedPipe()))) {
// Don't go where we have been before
continue;
}
distances.put(new DoubleCoordinates(startPipe).center(), specialConnection.getDistance());
HashMap<CoreRoutedPipe, ExitRoute> result = getConnectedRoutingPipes(specialConnection.getConnectedPipe(), specialConnection.getConnectionFlags(), specialConnection.getInsertOrientation());
distances.remove(new DoubleCoordinates(startPipe).center());
for (Entry<CoreRoutedPipe, ExitRoute> pipe : result.entrySet()) {
pipe.getValue().exitOrientation = specialConnection.getExitOrientation();
ExitRoute foundPipe = foundPipes.get(pipe.getKey());
if (foundPipe == null || (pipe.getValue().distanceToDestination < foundPipe.distanceToDestination)) {
// New path OR If new path is better, replace old path
foundPipes.put(pipe.getKey(), pipe.getValue());
}
}
}
ArrayDeque<Quartet<TileEntity, EnumFacing, Integer, Boolean>> connections = new ArrayDeque<>();
// Recurse in all directions
for (EnumFacing direction : EnumFacing.VALUES) {
if (root && side != null && !direction.equals(side)) {
continue;
}
// tile may be up to 1 second old, but any neighbour pipe change will cause an immidiate update here, so we know that if it has changed, it isn't a pipe that has done so.
TileEntity tile = startPipe.getNextConnectedTile(direction);
if (tile == null) {
continue;
}
if (root && (direction.getAxis() == EnumFacing.Axis.X || direction.getAxis() == EnumFacing.Axis.Z)) {
if (tile instanceof ILogisticsPowerProvider) {
if (powerNodes == null) {
powerNodes = new ArrayList<>();
}
// If we are a FireWall pipe add our filter to the pipes
if (startPipe.isFirewallPipe()) {
powerNodes.add(new Pair<>((ILogisticsPowerProvider) tile, new OneList<>(startPipe.getFirewallFilter())));
} else {
powerNodes.add(new Pair<>((ILogisticsPowerProvider) tile, Collections.unmodifiableList(new ArrayList<>(0))));
}
} else if (tile instanceof ISubSystemPowerProvider) {
if (subPowerProvider == null) {
subPowerProvider = new ArrayList<>();
}
// If we are a FireWall pipe add our filter to the pipes
if (startPipe.isFirewallPipe()) {
subPowerProvider.add(new Pair<>((ISubSystemPowerProvider) tile, new OneList<>(startPipe.getFirewallFilter())));
} else {
subPowerProvider.add(new Pair<>((ISubSystemPowerProvider) tile, Collections.unmodifiableList(new ArrayList<>(0))));
}
}
}
connections.add(new Quartet<>(tile, direction, 0, false));
}
while (!connections.isEmpty()) {
Quartet<TileEntity, EnumFacing, Integer, Boolean> quartet = connections.pollFirst();
TileEntity tile = quartet.getValue1();
EnumFacing direction = quartet.getValue2();
int resistance = quartet.getValue3();
boolean isDirectConnection = quartet.getValue4();
EnumSet<PipeRoutingConnectionType> nextConnectionFlags = EnumSet.copyOf(connectionFlags);
if (root) {
Collection<TileEntity> list = SimpleServiceLocator.specialtileconnection.getConnectedPipes(tile);
if (!list.isEmpty()) {
connections.addAll(list.stream().map(pipe -> new Quartet<>(pipe, direction, 0, false)).collect(Collectors.toList()));
listTileEntity(tile);
continue;
}
if (!startPipe.getRoutingPipe().getUpgradeManager().hasPowerPassUpgrade()) {
nextConnectionFlags.remove(PipeRoutingConnectionType.canPowerSubSystemFrom);
}
}
if (!SimpleServiceLocator.pipeInformationManager.isPipe(tile) && tile.hasCapability(LogisticsPipes.ITEM_HANDLER_CAPABILITY, direction.getOpposite()) && startPipe.isRoutingPipe() && startPipe.getRoutingPipe() instanceof IChannelRoutingConnection && startPipe.canConnect(tile, direction, false)) {
if (SimpleServiceLocator.connectionManager.hasChannelConnection(startPipe.getRoutingPipe().getRouter())) {
List<CoreRoutedPipe> connectedPipes = SimpleServiceLocator.connectionManager.getConnectedPipes(startPipe.getRoutingPipe().getRouter());
connections.addAll(connectedPipes.stream().map(pipe -> new Quartet<>((TileEntity) pipe.container, direction, ((IChannelRoutingConnection) startPipe.getRoutingPipe()).getConnectionResistance(), true)).collect(Collectors.toList()));
if (!connectedPipes.isEmpty()) {
continue;
}
}
}
if (tile == null) {
continue;
}
IPipeInformationProvider currentPipe = SimpleServiceLocator.pipeInformationManager.getInformationProviderFor(tile);
if (currentPipe != null && currentPipe.isRouterInitialized() && (isDirectConnection || SimpleServiceLocator.pipeInformationManager.canConnect(startPipe, currentPipe, direction, true))) {
listTileEntity(tile);
if (currentPipe.isMultiBlock()) {
currentPipe.getPartsOfPipe().forEach(this::listTileEntity);
}
if (setVisited.contains(new DoubleCoordinates(currentPipe))) {
// Don't go where we have been before
continue;
}
if (side != direction && !root) {
// Only straight connections for subsystem power
nextConnectionFlags.remove(PipeRoutingConnectionType.canPowerSubSystemFrom);
}
if (isDirectConnection) {
// ISC doesn't pass power
nextConnectionFlags.remove(PipeRoutingConnectionType.canPowerFrom);
nextConnectionFlags.remove(PipeRoutingConnectionType.canPowerSubSystemFrom);
}
// Iron, obsidean and liquid pipes will separate networks
if (currentPipe.divideNetwork()) {
continue;
}
if (currentPipe.powerOnly()) {
nextConnectionFlags.remove(PipeRoutingConnectionType.canRouteTo);
nextConnectionFlags.remove(PipeRoutingConnectionType.canRequestFrom);
}
if (startPipe.isOnewayPipe()) {
if (startPipe.isOutputClosed(direction)) {
nextConnectionFlags.remove(PipeRoutingConnectionType.canRouteTo);
}
}
if (currentPipe.isOnewayPipe()) {
nextConnectionFlags.remove(PipeRoutingConnectionType.canPowerSubSystemFrom);
if (currentPipe.isOutputClosed(direction.getOpposite())) {
nextConnectionFlags.remove(PipeRoutingConnectionType.canRequestFrom);
nextConnectionFlags.remove(PipeRoutingConnectionType.canPowerFrom);
}
}
if (nextConnectionFlags.isEmpty()) {
// don't bother going somewhere we can't do anything with
continue;
}
int beforeRecurseCount = foundPipes.size();
HashMap<CoreRoutedPipe, ExitRoute> result = null;
if (currentPipe instanceof IRouteProvider) {
List<RouteInfo> list = ((IRouteProvider) currentPipe).getConnectedPipes(direction.getOpposite());
if (list != null) {
result = new HashMap<>();
DoubleCoordinates pos = new DoubleCoordinates(currentPipe);
for (RouteInfo info : list) {
if (info.getPipe() == startPipe)
continue;
if (setVisited.contains(new DoubleCoordinates(info.getPipe()))) {
// Don't go where we have been before
continue;
}
distances.put(pos, (currentPipe.getDistance() * currentPipe.getDistanceWeight()) + info.getLength());
result.putAll(getConnectedRoutingPipes(info.getPipe(), nextConnectionFlags, direction));
distances.remove(pos);
}
}
}
if (result == null) {
result = getConnectedRoutingPipes(currentPipe, nextConnectionFlags, direction);
}
for (Entry<CoreRoutedPipe, ExitRoute> pipeEntry : result.entrySet()) {
// Update Result with the direction we took
pipeEntry.getValue().exitOrientation = direction;
ExitRoute foundPipe = foundPipes.get(pipeEntry.getKey());
if (foundPipe == null) {
// New path
foundPipes.put(pipeEntry.getKey(), pipeEntry.getValue());
// Add resistance
pipeEntry.getValue().distanceToDestination += resistance;
} else if (pipeEntry.getValue().distanceToDestination + resistance < foundPipe.distanceToDestination) {
// If new path is better, replace old path, otherwise do nothing
foundPipes.put(pipeEntry.getKey(), pipeEntry.getValue());
// Add resistance
pipeEntry.getValue().distanceToDestination += resistance;
}
}
if (foundPipes.size() > beforeRecurseCount && pathPainter != null) {
pathPainter.addLaser(startPipe.getWorld(), new LaserData(startPipe.getX(), startPipe.getY(), startPipe.getZ(), direction, connectionFlags));
}
}
}
setVisited.remove(new DoubleCoordinates(startPipe));
distances.remove(new DoubleCoordinates(startPipe));
if (startPipe.isRoutingPipe()) {
// ie, has the recursion returned to the pipe it started from?
for (ExitRoute e : foundPipes.values()) {
e.root = (startPipe.getRoutingPipe()).getRouter();
}
}
// If we are a FireWall pipe add our filter to the pipes
if (startPipe.isFirewallPipe() && root) {
for (ExitRoute e : foundPipes.values()) {
e.filters = new OneList<>(startPipe.getFirewallFilter());
}
}
return foundPipes;
}
Aggregations