Search in sources :

Example 66 with DoubleCoordinates

use of network.rs485.logisticspipes.world.DoubleCoordinates 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)

Example 67 with DoubleCoordinates

use of network.rs485.logisticspipes.world.DoubleCoordinates in project LogisticsPipes by RS485.

the class PathFinder method paintAndgetConnectedRoutingPipes.

/**
	 * Recurse through all exists of a pipe to find instances of
	 * PipeItemsRouting. maxVisited and maxLength are safeguards for recursion
	 * runaways.
	 * 
	 * @param startPipe
	 *            - The TileEntity to start the search from
	 * @param maxVisited
	 *            - The maximum number of pipes to visit, regardless of
	 *            recursion level
	 * @param maxLength
	 *            - The maximum recurse depth, i.e. the maximum length pipe that
	 *            is supported
	 * @return
	 */
public static HashMap<CoreRoutedPipe, ExitRoute> paintAndgetConnectedRoutingPipes(TileEntity startPipe, ForgeDirection startOrientation, int maxVisited, int maxLength, IPaintPath pathPainter, EnumSet<PipeRoutingConnectionType> connectionType) {
    IPipeInformationProvider startProvider = SimpleServiceLocator.pipeInformationManager.getInformationProviderFor(startPipe);
    if (startProvider == null) {
        return new HashMap<>();
    }
    PathFinder newSearch = new PathFinder(maxVisited, maxLength, pathPainter);
    DoubleCoordinates p = new DoubleCoordinates(startProvider);
    newSearch.setVisited.add(p);
    CoordinateUtils.add(p, startOrientation);
    TileEntity entity = p.getTileEntity(startProvider.getWorld());
    IPipeInformationProvider provider = SimpleServiceLocator.pipeInformationManager.getInformationProviderFor(entity);
    if (provider == null) {
        return new HashMap<>();
    }
    return newSearch.getConnectedRoutingPipes(provider, connectionType, startOrientation);
}
Also used : TileEntity(net.minecraft.tileentity.TileEntity) HashMap(java.util.HashMap) DoubleCoordinates(network.rs485.logisticspipes.world.DoubleCoordinates)

Example 68 with DoubleCoordinates

use of network.rs485.logisticspipes.world.DoubleCoordinates in project LogisticsPipes by RS485.

the class ExitRoute method readRouter.

@SideOnly(Side.CLIENT)
private IRouter readRouter(LPDataInput input) {
    DoubleCoordinates pos = new DoubleCoordinates(input);
    TileEntity tile = pos.getTileEntity(MainProxy.getClientMainWorld());
    if (tile instanceof LogisticsTileGenericPipe && ((LogisticsTileGenericPipe) tile).pipe instanceof CoreRoutedPipe) {
        return ((CoreRoutedPipe) ((LogisticsTileGenericPipe) tile).pipe).getRouter();
    }
    return null;
}
Also used : TileEntity(net.minecraft.tileentity.TileEntity) LogisticsTileGenericPipe(logisticspipes.pipes.basic.LogisticsTileGenericPipe) CoreRoutedPipe(logisticspipes.pipes.basic.CoreRoutedPipe) DoubleCoordinates(network.rs485.logisticspipes.world.DoubleCoordinates) SideOnly(cpw.mods.fml.relauncher.SideOnly)

Example 69 with DoubleCoordinates

use of network.rs485.logisticspipes.world.DoubleCoordinates in project LogisticsPipes by RS485.

the class ClientViewController method handlePacket.

public void handlePacket(RoutingUpdateCanidatePipe routingUpdateCanidatePipe) {
    DoubleCoordinates pos = routingUpdateCanidatePipe.getExitRoute().destination.getLPPosition();
    canidates.add(routingUpdateCanidatePipe.getExitRoute().destination.getLPPosition());
    //listHUD.add(new HUDRoutingTableDebugProvider(new HUDRoutingTableNewCandateUntrace(routingUpdateCanidatePipe.getExitRoute()), pos));
    getDebugInformation(pos).isNew = true;
    getDebugInformation(pos).newIndex = routingUpdateCanidatePipe.getExitRoute().debug.index;
}
Also used : DoubleCoordinates(network.rs485.logisticspipes.world.DoubleCoordinates)

Example 70 with DoubleCoordinates

use of network.rs485.logisticspipes.world.DoubleCoordinates in project LogisticsPipes by RS485.

the class SideConfigDisplay method doWorldRenderPass.

private void doWorldRenderPass(Vector3d trans, List<DoubleCoordinates> blocks, int pass) {
    RenderPassHelper.setBlockRenderPass(pass);
    Tessellator.instance.startDrawingQuads();
    Tessellator.instance.setTranslation(trans.x, trans.y, trans.z);
    Tessellator.instance.setBrightness(15 << 20 | 15 << 4);
    for (DoubleCoordinates bc : blocks) {
        Block block = world.getBlock(bc.getXInt(), bc.getYInt(), bc.getZInt());
        if (block != null) {
            if (block.canRenderInPass(pass)) {
                RB.renderAllFaces = true;
                RB.setRenderAllFaces(true);
                RB.setRenderBounds(0, 0, 0, 1, 1, 1);
                try {
                    RB.renderBlockByRenderType(block, bc.getXInt(), bc.getYInt(), bc.getZInt());
                } catch (Exception e) {
                //Ignore, things might blow up in rendering due to the modified block access
                //but this is about as good as we can do
                }
            }
        }
    }
    Tessellator.instance.draw();
    Tessellator.instance.setTranslation(0, 0, 0);
    RenderPassHelper.clearBlockRenderPass();
}
Also used : Block(net.minecraft.block.Block) DoubleCoordinates(network.rs485.logisticspipes.world.DoubleCoordinates)

Aggregations

DoubleCoordinates (network.rs485.logisticspipes.world.DoubleCoordinates)70 TileEntity (net.minecraft.tileentity.TileEntity)44 ForgeDirection (net.minecraftforge.common.util.ForgeDirection)21 LogisticsTileGenericPipe (logisticspipes.pipes.basic.LogisticsTileGenericPipe)15 ArrayList (java.util.ArrayList)14 LPPositionSet (logisticspipes.utils.LPPositionSet)10 Block (net.minecraft.block.Block)10 SideOnly (cpw.mods.fml.relauncher.SideOnly)8 CoreRoutedPipe (logisticspipes.pipes.basic.CoreRoutedPipe)8 ItemStack (net.minecraft.item.ItemStack)8 World (net.minecraft.world.World)8 LogisticsTileGenericSubMultiBlock (logisticspipes.pipes.basic.LogisticsTileGenericSubMultiBlock)6 AxisAlignedBB (net.minecraft.util.AxisAlignedBB)6 IIcon (net.minecraft.util.IIcon)6 DockingStation (buildcraft.api.robots.DockingStation)5 MovingObjectPosition (net.minecraft.util.MovingObjectPosition)5 DoubleCoordinatesType (network.rs485.logisticspipes.world.DoubleCoordinatesType)5 EntityRobotBase (buildcraft.api.robots.EntityRobotBase)4 PipePluggable (buildcraft.api.transport.pluggable.PipePluggable)4 RobotStationPluggable (buildcraft.robotics.RobotStationPluggable)4