diff --git a/src/main/java/com/simibubi/create/content/trains/entity/CarriageContraptionEntity.java b/src/main/java/com/simibubi/create/content/trains/entity/CarriageContraptionEntity.java index eeb5d679e..dc750775d 100644 --- a/src/main/java/com/simibubi/create/content/trains/entity/CarriageContraptionEntity.java +++ b/src/main/java/com/simibubi/create/content/trains/entity/CarriageContraptionEntity.java @@ -640,7 +640,7 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity { if (lookAhead != null) { if (spaceDown) { carriage.train.manualTick = true; - nav.startNavigation(lookAhead, -1, false); + nav.startNavigation(nav.findPathTo(lookAhead, -1)); carriage.train.manualTick = false; navDistanceTotal = nav.distanceToDestination; return true; diff --git a/src/main/java/com/simibubi/create/content/trains/entity/Navigation.java b/src/main/java/com/simibubi/create/content/trains/entity/Navigation.java index b8fdd98d4..31253d612 100644 --- a/src/main/java/com/simibubi/create/content/trains/entity/Navigation.java +++ b/src/main/java/com/simibubi/create/content/trains/entity/Navigation.java @@ -15,6 +15,9 @@ import java.util.UUID; import javax.annotation.Nullable; +import com.mojang.logging.LogUtils; +import com.simibubi.create.content.trains.graph.DiscoveredPath; + import org.apache.commons.lang3.mutable.MutableDouble; import org.apache.commons.lang3.mutable.MutableObject; @@ -380,15 +383,11 @@ public class Navigation { train.reservedSignalBlocks.clear(); } - public double startNavigation(GlobalStation destination, double maxCost, boolean simulate) { - DiscoveredPath pathTo = findPathTo(destination, maxCost); + public double startNavigation(DiscoveredPath pathTo) { boolean noneFound = pathTo == null; double distance = noneFound ? -1 : Math.abs(pathTo.distance); double cost = noneFound ? -1 : pathTo.cost; - if (simulate) - return cost; - distanceToDestination = distance; if (noneFound) { @@ -407,10 +406,10 @@ public class Navigation { train.reservedSignalBlocks.clear(); train.navigation.waitingForSignal = null; - if (this.destination == null && !simulate) + if (this.destination == null) distanceStartedAt = distance; - if (this.destination == destination) + if (this.destination == pathTo.destination) return 0; if (!train.runtime.paused) { @@ -435,16 +434,16 @@ public class Navigation { train.status.foundConductor(); } - this.destination = destination; + this.destination = pathTo.destination; return cost; } @Nullable - private DiscoveredPath findPathTo(GlobalStation destination, double maxCost) { + public DiscoveredPath findPathTo(GlobalStation destination, double maxCost) { TrackGraph graph = train.graph; if (graph == null) return null; - + LogUtils.getLogger().info("finding path"); Couple results = Couple.create(null, null); for (boolean forward : Iterate.trueAndFalse) { @@ -486,7 +485,7 @@ public class Navigation { double position = edge.getLength() - destination.getLocationOn(edge); double distanceToDestination = distance - position; - results.set(forward, new DiscoveredPath((forward ? 1 : -1) * distanceToDestination, cost, currentPath)); + results.set(forward, new DiscoveredPath((forward ? 1 : -1) * distanceToDestination, cost, currentPath, destination)); return true; }); } @@ -508,18 +507,6 @@ public class Navigation { return frontBetter ? front : back; } - public class DiscoveredPath { - List> path; - double distance; - double cost; - - public DiscoveredPath(double distance, double cost, List> path) { - this.distance = distance; - this.cost = cost; - this.path = path; - } - } - public GlobalStation findNearestApproachable(boolean forward) { TrackGraph graph = train.graph; if (graph == null) @@ -776,9 +763,9 @@ public class Navigation { c -> currentPath.add(Couple .deserializeEach(c.getList("Nodes", Tag.TAG_COMPOUND), c2 -> TrackNodeLocation.read(c2, dimensions)) .map(graph::locateNode))); - + removeBrokenPathEntries(); - + waitingForSignal = tag.contains("BlockingSignal") ? Pair.of(tag.getUUID("BlockingSignal"), tag.getBoolean("BlockingSignalSide")) : null; @@ -793,7 +780,7 @@ public class Navigation { * Trains might load or save with null entries in their path, this method avoids * that anomaly from causing NPEs. The underlying issue has not been found. */ - + boolean nullEntriesPresent = false; for (Iterator> iterator = currentPath.iterator(); iterator.hasNext();) { diff --git a/src/main/java/com/simibubi/create/content/trains/entity/Train.java b/src/main/java/com/simibubi/create/content/trains/entity/Train.java index 612c8fd7c..48acf59e2 100644 --- a/src/main/java/com/simibubi/create/content/trains/entity/Train.java +++ b/src/main/java/com/simibubi/create/content/trains/entity/Train.java @@ -17,6 +17,8 @@ import java.util.function.Consumer; import javax.annotation.Nullable; +import com.simibubi.create.content.trains.graph.DiscoveredPath; + import org.apache.commons.lang3.mutable.MutableBoolean; import org.apache.commons.lang3.mutable.MutableObject; @@ -541,12 +543,12 @@ public class Train { GlobalStation destination = navigation.destination; if (!navigatingManually && fullRefresh) { - GlobalStation preferredDestination = runtime.startCurrentInstruction(); - if (preferredDestination != null) - destination = preferredDestination; + DiscoveredPath preferredPath = runtime.startCurrentInstruction(); + if (preferredPath != null) + destination = preferredPath.destination; } - navigation.startNavigation(destination, navigatingManually ? -1 : Double.MAX_VALUE, false); + navigation.startNavigation(navigation.findPathTo(destination, navigatingManually ? -1 : Double.MAX_VALUE)); } private void tickDerailedSlowdown() { diff --git a/src/main/java/com/simibubi/create/content/trains/graph/DiscoveredPath.java b/src/main/java/com/simibubi/create/content/trains/graph/DiscoveredPath.java new file mode 100644 index 000000000..9b2be0aaa --- /dev/null +++ b/src/main/java/com/simibubi/create/content/trains/graph/DiscoveredPath.java @@ -0,0 +1,22 @@ +package com.simibubi.create.content.trains.graph; + +import com.simibubi.create.content.trains.station.GlobalStation; +import com.simibubi.create.foundation.utility.Couple; + +import org.openjdk.nashorn.internal.objects.Global; + +import java.util.List; + +public class DiscoveredPath { + public List> path; + public GlobalStation destination; + public double distance; + public double cost; + + public DiscoveredPath(double distance, double cost, List> path, GlobalStation destination) { + this.distance = distance; + this.cost = cost; + this.path = path; + this.destination = destination; + } +} diff --git a/src/main/java/com/simibubi/create/content/trains/schedule/ScheduleRuntime.java b/src/main/java/com/simibubi/create/content/trains/schedule/ScheduleRuntime.java index 5147edf96..c78056d7a 100644 --- a/src/main/java/com/simibubi/create/content/trains/schedule/ScheduleRuntime.java +++ b/src/main/java/com/simibubi/create/content/trains/schedule/ScheduleRuntime.java @@ -8,7 +8,9 @@ import java.util.Objects; import com.simibubi.create.AllItems; import com.simibubi.create.content.trains.display.GlobalTrainDisplayData.TrainDeparturePrediction; import com.simibubi.create.content.trains.entity.Carriage; +import com.simibubi.create.content.trains.entity.Navigation; import com.simibubi.create.content.trains.entity.Train; +import com.simibubi.create.content.trains.graph.DiscoveredPath; import com.simibubi.create.content.trains.graph.EdgePointType; import com.simibubi.create.content.trains.schedule.condition.ScheduleWaitCondition; import com.simibubi.create.content.trains.schedule.condition.ScheduledDelay; @@ -122,17 +124,17 @@ public class ScheduleRuntime { return; } - GlobalStation nextStation = startCurrentInstruction(); - if (nextStation == null) + DiscoveredPath nextPath = startCurrentInstruction(); + if (nextPath == null) return; train.status.successfulNavigation(); - if (nextStation == train.getCurrentStation()) { + if (nextPath.destination == train.getCurrentStation()) { state = State.IN_TRANSIT; destinationReached(); return; } - if (train.navigation.startNavigation(nextStation, Double.MAX_VALUE, false) != TBD) { + if (train.navigation.startNavigation(nextPath) != TBD) { state = State.IN_TRANSIT; ticksInTransit = 0; } @@ -167,13 +169,13 @@ public class ScheduleRuntime { carriage.storage.tickIdleCargoTracker(); } - public GlobalStation startCurrentInstruction() { + public DiscoveredPath startCurrentInstruction() { ScheduleEntry entry = schedule.entries.get(currentEntry); ScheduleInstruction instruction = entry.instruction; if (instruction instanceof DestinationInstruction destination) { String regex = destination.getFilterForRegex(); - GlobalStation best = null; + DiscoveredPath best = null; double bestCost = Double.MAX_VALUE; boolean anyMatch = false; @@ -188,12 +190,19 @@ public class ScheduleRuntime { continue; anyMatch = true; boolean matchesCurrent = train.currentStation != null && train.currentStation.equals(globalStation.id); - double cost = matchesCurrent ? 0 : train.navigation.startNavigation(globalStation, bestCost, true); + double cost; + DiscoveredPath path = train.navigation.findPathTo(globalStation, bestCost); + if (matchesCurrent) { + cost = 0; + } else { + cost = path == null ? -1 : path.cost; + } + if (cost < 0) continue; if (cost > bestCost) continue; - best = globalStation; + best = path; bestCost = cost; } @@ -332,9 +341,9 @@ public class ScheduleRuntime { return accumulatedTime; if (predictionTicks.size() <= currentEntry) return accumulatedTime; - + int departureTime = estimateStayDuration(index); - + if (accumulatedTime < 0) { predictions.add(createPrediction(index, filter.getFilter(), currentTitle, accumulatedTime)); return Math.min(accumulatedTime, departureTime); @@ -348,12 +357,12 @@ public class ScheduleRuntime { predictions.add(createPrediction(index, filter.getFilter(), currentTitle, accumulatedTime)); - if (accumulatedTime != TBD) + if (accumulatedTime != TBD) accumulatedTime += departureTime; - + if (departureTime == INVALID) accumulatedTime = INVALID; - + return accumulatedTime; } @@ -381,7 +390,7 @@ public class ScheduleRuntime { private TrainDeparturePrediction createPrediction(int index, String destination, String currentTitle, int time) { if (time == INVALID) return null; - + int size = schedule.entries.size(); if (index >= size) { if (!schedule.cyclic) diff --git a/src/main/java/com/simibubi/create/content/trains/station/StationBlockEntity.java b/src/main/java/com/simibubi/create/content/trains/station/StationBlockEntity.java index 44657b81f..596873cd1 100644 --- a/src/main/java/com/simibubi/create/content/trains/station/StationBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/trains/station/StationBlockEntity.java @@ -13,6 +13,8 @@ import java.util.function.Consumer; import javax.annotation.Nullable; +import com.simibubi.create.content.trains.graph.DiscoveredPath; + import org.jetbrains.annotations.NotNull; import com.simibubi.create.AllBlocks; @@ -286,7 +288,7 @@ public class StationBlockEntity extends SmartBlockEntity implements ITransformab BlockPos up = new BlockPos(track.getUpNormal(level, pos, state)); BlockPos down = new BlockPos(track.getUpNormal(level, pos, state).scale(-1)); int bogeyOffset = pos.distManhattan(edgePoint.getGlobalPosition()) - 1; - + if (!isValidBogeyOffset(bogeyOffset)) { for (boolean upsideDown : Iterate.falseAndTrue) { for (int i = -1; i <= 1; i++) { @@ -374,8 +376,8 @@ public class StationBlockEntity extends SmartBlockEntity implements ITransformab if (train.navigation.destination != station) continue; - GlobalStation preferredDestination = train.runtime.startCurrentInstruction(); - train.navigation.startNavigation(preferredDestination != null ? preferredDestination : station, Double.MAX_VALUE, false); + DiscoveredPath preferredPath = train.runtime.startCurrentInstruction(); + train.navigation.startNavigation(preferredPath != null ? preferredPath : train.navigation.findPathTo(station, Double.MAX_VALUE)); } }