Search in sources :

Example 1 with PipeRoutingConnectionType

use of logisticspipes.routing.PipeRoutingConnectionType in project LogisticsPipes by RS485.

the class HUDRoutingTableGeneralInfo method renderHeadUpDisplay.

@Override
public void renderHeadUpDisplay(double distance, boolean day, boolean shifted, Minecraft mc, IHUDConfig config) {
    if (route.isNew) {
        line = -65;
    } else {
        line = -75;
    }
    GL11.glColor4b((byte) 127, (byte) 127, (byte) 127, (byte) 64);
    GuiGraphics.drawGuiBackGround(mc, -70, -80, 70, 80, 0, false);
    GL11.glTranslatef(0.0F, 0.0F, -0.0005F);
    super.renderHeadUpDisplay(distance, day, shifted, mc, config);
    GL11.glTranslatef(0.0F, 0.0F, -0.0005F);
    write("Routing Update in: ", mc);
    write(route.positions.toString(), mc);
    if (route.closedSet != null) {
        int left = -55;
        for (PipeRoutingConnectionType flag : PipeRoutingConnectionType.values) {
            if (route.closedSet.contains(flag)) {
                mc.fontRenderer.drawString("+", left, line, getColorForFlag(flag));
                left += mc.fontRenderer.getStringWidth("+");
            } else {
                mc.fontRenderer.drawString("-", left, line, getColorForFlag(flag));
                left += mc.fontRenderer.getStringWidth("-");
            }
        }
        line += 10;
    }
    if (route.routes != null) {
        for (ExitRoute exit : route.routes) {
            mc.fontRenderer.drawString("Possible: ", -55, line, 0xffffff);
            int left = -55 + mc.fontRenderer.getStringWidth("Possible: ");
            for (PipeRoutingConnectionType flag : PipeRoutingConnectionType.values) {
                if (exit.containsFlag(flag)) {
                    mc.fontRenderer.drawString("+", left, line, getColorForFlag(flag));
                    left += mc.fontRenderer.getStringWidth("+");
                } else {
                    mc.fontRenderer.drawString("-", left, line, getColorForFlag(flag));
                    left += mc.fontRenderer.getStringWidth("-");
                }
            }
            line += 10;
            write("  " + exit.debug.filterPosition, mc);
        }
    }
    GL11.glTranslatef(0.0F, 0.0F, 0.0010F);
}
Also used : PipeRoutingConnectionType(logisticspipes.routing.PipeRoutingConnectionType) ExitRoute(logisticspipes.routing.ExitRoute)

Example 2 with PipeRoutingConnectionType

use of logisticspipes.routing.PipeRoutingConnectionType in project LogisticsPipes by RS485.

the class RoutingUpdateDebugFilters method readData.

@Override
public void readData(LPDataInput input) {
    pos = new DoubleCoordinates(input);
    filterPositions = new EnumMap<>(PipeRoutingConnectionType.class);
    short id;
    while ((id = input.readShort()) != -1) {
        PipeRoutingConnectionType type = PipeRoutingConnectionType.values[id];
        List<List<DoubleCoordinates>> typeFilters = new ArrayList<>();
        int length;
        while ((length = input.readShort()) != -1) {
            List<DoubleCoordinates> linkedFilter = new ArrayList<>();
            for (int i = 0; i < length; i++) {
                linkedFilter.add(new DoubleCoordinates(input));
            }
            typeFilters.add(linkedFilter);
        }
        filterPositions.put(type, typeFilters);
    }
}
Also used : PipeRoutingConnectionType(logisticspipes.routing.PipeRoutingConnectionType) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) DoubleCoordinates(network.rs485.logisticspipes.world.DoubleCoordinates)

Example 3 with PipeRoutingConnectionType

use of logisticspipes.routing.PipeRoutingConnectionType 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);
                        }
                    }
                }));
            }
        }
    }
}
Also used : PipeRoutingConnectionType(logisticspipes.routing.PipeRoutingConnectionType) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) CoreRoutedPipe(logisticspipes.pipes.basic.CoreRoutedPipe) IRouter(logisticspipes.routing.IRouter) LogisticsTileGenericPipe(logisticspipes.pipes.basic.LogisticsTileGenericPipe) ForgeDirection(net.minecraftforge.common.util.ForgeDirection) LinkedList(java.util.LinkedList) LaserData(logisticspipes.routing.LaserData) ExitRoute(logisticspipes.routing.ExitRoute)

Example 4 with PipeRoutingConnectionType

use of logisticspipes.routing.PipeRoutingConnectionType in project LogisticsPipes by RS485.

the class LPRobotConnectionControl method getConnections.

@Override
public List<ConnectionInformation> getConnections(IPipeInformationProvider startPipe, EnumSet<PipeRoutingConnectionType> connection, ForgeDirection side) {
    List<ConnectionInformation> list = new ArrayList<>();
    LogisticsTileGenericPipe pipe = (LogisticsTileGenericPipe) startPipe;
    if (pipe == null || pipe.tilePart.getOriginal() == null) {
        // Proxy got disabled
        return list;
    }
    DoubleCoordinates pos = new DoubleCoordinates(startPipe);
    pos.center();
    for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
        PipePluggable pluggable = ((TileGenericPipe) pipe.tilePart.getOriginal()).getPipePluggable(dir);
        if (!(pluggable instanceof RobotStationPluggable)) {
            continue;
        }
        DockingStation station = ((RobotStationPluggable) pluggable).getStation();
        if (!station.isTaken()) {
            continue;
        }
        EntityRobotBase robot = station.robotTaking();
        if (robot == null) {
            continue;
        }
        if (!(robot.getBoard() instanceof LogisticsRoutingBoardRobot)) {
            continue;
        }
        if (robot.isDead) {
            continue;
        }
        if (!((LogisticsRoutingBoardRobot) robot.getBoard()).isAcceptsItems()) {
            continue;
        }
        DoubleCoordinates robotPos = new DoubleCoordinates(robot);
        if (((LogisticsRoutingBoardRobot) robot.getBoard()).getCurrentTarget() != null) {
            Pair<Double, LogisticsRoutingBoardRobot> currentTarget = ((LogisticsRoutingBoardRobot) robot.getBoard()).getCurrentTarget();
            DoubleCoordinates pipePos = currentTarget.getValue2().getLinkedStationPosition();
            TileEntity connectedPipeTile = pipePos.getTileEntity(pipe.getWorldObj());
            if (!(connectedPipeTile instanceof LogisticsTileGenericPipe)) {
                continue;
            }
            LogisticsTileGenericPipe connectedPipe = (LogisticsTileGenericPipe) connectedPipeTile;
            if (!connectedPipe.isRoutingPipe()) {
                continue;
            }
            IPipeInformationProvider connectedInfo = SimpleServiceLocator.pipeInformationManager.getInformationProviderFor(connectedPipe);
            EntityRobotBase connectedRobot = currentTarget.getValue2().robot;
            if (connectedRobot == null) {
                continue;
            }
            if (!(connectedRobot.getBoard() instanceof LogisticsRoutingBoardRobot)) {
                continue;
            }
            if (connectedRobot.isDead) {
                continue;
            }
            if (connectedRobot.getZoneToWork() != null && !connectedRobot.getZoneToWork().contains(robotPos.getXCoord(), robotPos.getYCoord(), robotPos.getZCoord())) {
                continue;
            }
            if (!((LogisticsRoutingBoardRobot) connectedRobot.getBoard()).isAcceptsItems()) {
                continue;
            }
            DoubleCoordinates connectedRobotPos = new DoubleCoordinates(connectedRobot);
            if (CoordinateUtils.add(new DoubleCoordinates(pipePos).center(), currentTarget.getValue2().robot.getLinkedStation().side(), 0.5).distanceTo(connectedRobotPos) > 0.05) {
                // Not at station
                continue;
            }
            EnumSet<PipeRoutingConnectionType> newCon = connection.clone();
            newCon.removeAll(EnumSet.of(PipeRoutingConnectionType.canPowerFrom, PipeRoutingConnectionType.canPowerSubSystemFrom));
            double distance = CoordinateUtils.add(new DoubleCoordinates(currentTarget.getValue2().getLinkedStationPosition()).center(), currentTarget.getValue2().robot.getLinkedStation().side(), 0.5).distanceTo(robotPos);
            list.add(new ConnectionInformation(connectedInfo, newCon, currentTarget.getValue2().robot.getLinkedStation().side().getOpposite(), dir, (distance * 3) + 21));
        } else {
            if (CoordinateUtils.add(new DoubleCoordinates(pos), dir, 0.5).distanceTo(robotPos) > 0.05) {
                // Not at station
                continue;
            }
            for (Pair<DoubleCoordinates, ForgeDirection> canidatePos : ((LogisticsRoutingBoardRobot) robot.getBoard()).getConnectionDetails().localConnectedRobots) {
                if (canidatePos.getValue1().equals(new DoubleCoordinates(startPipe))) {
                    continue;
                }
                double distance = CoordinateUtils.add(new DoubleCoordinates(canidatePos.getValue1()).center(), canidatePos.getValue2(), 0.5).distanceTo(robotPos);
                TileEntity connectedPipeTile = canidatePos.getValue1().getTileEntity(pipe.getWorldObj());
                if (!(connectedPipeTile instanceof LogisticsTileGenericPipe)) {
                    continue;
                }
                LogisticsTileGenericPipe connectedPipe = (LogisticsTileGenericPipe) connectedPipeTile;
                if (!connectedPipe.isRoutingPipe()) {
                    continue;
                }
                IPipeInformationProvider connectedInfo = SimpleServiceLocator.pipeInformationManager.getInformationProviderFor(connectedPipe);
                PipePluggable connectedPluggable = ((TileGenericPipe) connectedPipe.tilePart.getOriginal()).getPipePluggable(canidatePos.getValue2());
                if (!(connectedPluggable instanceof RobotStationPluggable)) {
                    continue;
                }
                DockingStation connectedStation = ((RobotStationPluggable) connectedPluggable).getStation();
                if (!connectedStation.isTaken()) {
                    continue;
                }
                EntityRobotBase connectedRobot = connectedStation.robotTaking();
                if (connectedRobot == null) {
                    continue;
                }
                if (!(connectedRobot.getBoard() instanceof LogisticsRoutingBoardRobot)) {
                    continue;
                }
                if (connectedRobot.isDead) {
                    continue;
                }
                if (connectedRobot.getZoneToWork() != null && !connectedRobot.getZoneToWork().contains(robotPos.getXCoord(), robotPos.getYCoord(), robotPos.getZCoord())) {
                    continue;
                }
                if (!((LogisticsRoutingBoardRobot) connectedRobot.getBoard()).isAcceptsItems()) {
                    continue;
                }
                if (((LogisticsRoutingBoardRobot) connectedRobot.getBoard()).getCurrentTarget() != null && ((LogisticsRoutingBoardRobot) connectedRobot.getBoard()).getCurrentTarget().getValue2() != robot.getBoard()) {
                    continue;
                }
                DoubleCoordinates connectedRobotPos = new DoubleCoordinates(connectedRobot);
                if (CoordinateUtils.add(new DoubleCoordinates(canidatePos.getValue1()).center(), canidatePos.getValue2(), 0.5).distanceTo(connectedRobotPos) > 0.05) {
                    // Not at station
                    continue;
                }
                EnumSet<PipeRoutingConnectionType> newCon = connection.clone();
                newCon.removeAll(EnumSet.of(PipeRoutingConnectionType.canPowerFrom, PipeRoutingConnectionType.canPowerSubSystemFrom));
                list.add(new ConnectionInformation(connectedInfo, newCon, canidatePos.getValue2().getOpposite(), dir, (distance * 3) + 21));
            }
        }
    }
    return list;
}
Also used : ConnectionInformation(logisticspipes.proxy.specialconnection.SpecialPipeConnection.ConnectionInformation) RobotStationPluggable(buildcraft.robotics.RobotStationPluggable) DockingStation(buildcraft.api.robots.DockingStation) PipeRoutingConnectionType(logisticspipes.routing.PipeRoutingConnectionType) LogisticsRoutingBoardRobot(logisticspipes.proxy.buildcraft.robots.boards.LogisticsRoutingBoardRobot) ArrayList(java.util.ArrayList) PipePluggable(buildcraft.api.transport.pluggable.PipePluggable) DoubleCoordinates(network.rs485.logisticspipes.world.DoubleCoordinates) TileEntity(net.minecraft.tileentity.TileEntity) IPipeInformationProvider(logisticspipes.routing.pathfinder.IPipeInformationProvider) LogisticsTileGenericPipe(logisticspipes.pipes.basic.LogisticsTileGenericPipe) TileGenericPipe(buildcraft.transport.TileGenericPipe) LogisticsTileGenericPipe(logisticspipes.pipes.basic.LogisticsTileGenericPipe) ForgeDirection(net.minecraftforge.common.util.ForgeDirection) EntityRobotBase(buildcraft.api.robots.EntityRobotBase)

Example 5 with PipeRoutingConnectionType

use of logisticspipes.routing.PipeRoutingConnectionType 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;
}
Also used : ConnectionInformation(logisticspipes.proxy.specialconnection.SpecialPipeConnection.ConnectionInformation) PipeRoutingConnectionType(logisticspipes.routing.PipeRoutingConnectionType) HashMap(java.util.HashMap) CoreRoutedPipe(logisticspipes.pipes.basic.CoreRoutedPipe) TileEntity(net.minecraft.tileentity.TileEntity) ForgeDirection(net.minecraftforge.common.util.ForgeDirection) ILogisticsPowerProvider(logisticspipes.api.ILogisticsPowerProvider) IDirectRoutingConnection(logisticspipes.interfaces.routing.IDirectRoutingConnection) RouteInfo(logisticspipes.routing.pathfinder.IRouteProvider.RouteInfo) ISubSystemPowerProvider(logisticspipes.interfaces.ISubSystemPowerProvider) Pair(logisticspipes.utils.tuples.Pair) IInventory(net.minecraft.inventory.IInventory) DoubleCoordinates(network.rs485.logisticspipes.world.DoubleCoordinates) ArrayDeque(java.util.ArrayDeque) OneList(logisticspipes.utils.OneList) LaserData(logisticspipes.routing.LaserData) ExitRoute(logisticspipes.routing.ExitRoute)

Aggregations

PipeRoutingConnectionType (logisticspipes.routing.PipeRoutingConnectionType)9 ArrayList (java.util.ArrayList)6 ExitRoute (logisticspipes.routing.ExitRoute)6 HashMap (java.util.HashMap)4 CoreRoutedPipe (logisticspipes.pipes.basic.CoreRoutedPipe)4 LogisticsTileGenericPipe (logisticspipes.pipes.basic.LogisticsTileGenericPipe)4 LaserData (logisticspipes.routing.LaserData)4 DoubleCoordinates (network.rs485.logisticspipes.world.DoubleCoordinates)4 LinkedList (java.util.LinkedList)3 List (java.util.List)3 IFilter (logisticspipes.interfaces.routing.IFilter)3 ConnectionInformation (logisticspipes.proxy.specialconnection.SpecialPipeConnection.ConnectionInformation)3 IRouter (logisticspipes.routing.IRouter)3 TileEntity (net.minecraft.tileentity.TileEntity)3 ForgeDirection (net.minecraftforge.common.util.ForgeDirection)3 ArrayDeque (java.util.ArrayDeque)2 ILogisticsPowerProvider (logisticspipes.api.ILogisticsPowerProvider)2 ISubSystemPowerProvider (logisticspipes.interfaces.ISubSystemPowerProvider)2 RouteInfo (logisticspipes.routing.pathfinder.IRouteProvider.RouteInfo)2 OneList (logisticspipes.utils.OneList)2