diff --git a/pathfinder-api/src/main/java/de/cubbossa/pathapi/navigation/NavigationHandler.java b/pathfinder-api/src/main/java/de/cubbossa/pathapi/navigation/NavigationHandler.java index 8fec0324..462b8b13 100644 --- a/pathfinder-api/src/main/java/de/cubbossa/pathapi/navigation/NavigationHandler.java +++ b/pathfinder-api/src/main/java/de/cubbossa/pathapi/navigation/NavigationHandler.java @@ -6,16 +6,17 @@ import de.cubbossa.pathapi.node.Node; import de.cubbossa.pathapi.visualizer.VisualizerPath; import de.cubbossa.pathfinder.graph.PathSolver; -import java.util.Collection; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.function.Function; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import org.jetbrains.annotations.Nullable; +import java.util.Collection; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.function.Function; + /** * The core element to manage path visualizations on an existing graph. * @@ -107,7 +108,13 @@ record NavigationRequestContext(UUID playerId, Collection nodes) { */ interface NavigateLocation { Node getNode(); + + boolean isExternal(); + + void setExternal(boolean external); + boolean isAgile(); + void setAgile(boolean agile); } diff --git a/pathfinder-core/src/main/java/de/cubbossa/pathfinder/AbstractNavigationHandler.java b/pathfinder-core/src/main/java/de/cubbossa/pathfinder/AbstractNavigationHandler.java index bc9a9aaf..db32986a 100644 --- a/pathfinder-core/src/main/java/de/cubbossa/pathfinder/AbstractNavigationHandler.java +++ b/pathfinder-core/src/main/java/de/cubbossa/pathfinder/AbstractNavigationHandler.java @@ -78,6 +78,7 @@ public static void printResult(NavigateResult result, PathPlayer Messages.CMD_FIND_BLOCKED; case FAIL_EMPTY -> Messages.CMD_FIND_EMPTY; case FAIL_TOO_FAR_AWAY -> Messages.CMD_FIND_TOO_FAR; + case FAIL_UNKNOWN -> Messages.CMD_FIND_UNKNOWN; default -> null; }; if (message != null) { @@ -119,8 +120,7 @@ public CompletableFuture findPathToNodes(PathPlayer pla NavigateLocation location = new CommonNavigateLocation(new PlayerNode(player)); location.setAgile(true); return findPath(player, location, targets.stream() - .map(Node::getLocation) - .map(CommonNavigateLocation::staticLocation) + .map(CommonNavigateLocation::staticNode) .collect(Collectors.toList())); } @@ -154,7 +154,7 @@ public CompletableFuture findPath(PathPlayer viewer, Na navigateLocations.addAll(target); // graph becomes static, so this step and all following must be repeated for each path update. - return getGraph(Collections.singleton(start), target).thenCompose(graph -> findPath(graph, start, target)).thenApply(path -> { + return getGraph(Collections.singleton(start), target).thenCompose(graph -> findPath(graph, start, target)).thenApply((path) -> { NodeGroup highest = path.get(path.size() - 1).groups().stream() .filter(g -> g.hasModifier(FindDistanceModifier.KEY)) @@ -168,9 +168,11 @@ public CompletableFuture findPath(PathPlayer viewer, Na return setPath(viewer, path, path.get(path.size() - 1).node().getLocation(), (float) findDist, !updating ? null : () -> { return getGraph(Collections.singleton(start), target).thenCompose(graph -> findPath(graph, start, target)).join(); }); - - }).exceptionally(throwable -> { - throwable.printStackTrace(); + }).exceptionally(t -> { + if (t.getCause().getCause() instanceof NoPathFoundException) { + return NavigateResult.FAIL_BLOCKED; + } + t.printStackTrace(); return NavigateResult.FAIL_UNKNOWN; }); } @@ -340,6 +342,7 @@ private CompletableFuture> getGraph(Colle Collection locations = new HashSet<>(entries); locations.addAll(exits); + // TODO // check if any agile location has changed. If not, just return the last graph. if (false && cachedGraphWithTargets != null && locations.stream().filter(NavigateLocation::isAgile).map(NavigateLocation::getNode) .map(Node::getLocation).toList().equals(cachedAgileLocations)) { @@ -351,12 +354,16 @@ private CompletableFuture> getGraph(Colle GraphEntrySolver solver = new EdgeBasedGraphEntrySolver(); for (NavigateLocation location : entries) { + if (!location.isExternal()) continue; + GroupedNode g = new SimpleGroupedNode(location.getNode(), new HashSet<>()); graph.addNode(g); graph = solver.solveEntry(g, graph); graph.successors(g).forEach((groupedNode) -> g.groups().addAll(groupedNode.groups())); } for (NavigateLocation location : exits) { + if (!location.isExternal()) continue; + GroupedNode g = new SimpleGroupedNode(location.getNode(), new HashSet<>()); graph.addNode(g); graph = solver.solveExit(g, graph); @@ -437,6 +444,7 @@ private CompletableFuture> createGraph() static class CommonNavigateLocation implements NavigateLocation { private final Node node; + private boolean external = true; private boolean agile; public static NavigateLocation agileNode(Node node) { @@ -456,6 +464,12 @@ public Location getLocation() { return navloc; } + public static NavigateLocation staticNode(Node node) { + var n = new CommonNavigateLocation(node); + n.setExternal(false); + return n; + } + public static NavigateLocation staticLocation(Location location) { Node n = new Waypoint(UUID.randomUUID()); n.setLocation(location); diff --git a/pathfinder-core/src/main/java/de/cubbossa/pathfinder/StateMachine.java b/pathfinder-core/src/main/java/de/cubbossa/pathfinder/StateMachine.java new file mode 100644 index 00000000..df6a3633 --- /dev/null +++ b/pathfinder-core/src/main/java/de/cubbossa/pathfinder/StateMachine.java @@ -0,0 +1,11 @@ +package de.cubbossa.pathfinder; + +public class StateMachine { + + public enum State { + STARTUP, + RUNNING, + DUMPING, + SHUTDOWN + } +} diff --git a/pathfinder-core/src/main/java/de/cubbossa/pathfinder/messages/Messages.java b/pathfinder-core/src/main/java/de/cubbossa/pathfinder/messages/Messages.java index a66f2265..e5fb0ae3 100644 --- a/pathfinder-core/src/main/java/de/cubbossa/pathfinder/messages/Messages.java +++ b/pathfinder-core/src/main/java/de/cubbossa/pathfinder/messages/Messages.java @@ -320,25 +320,28 @@ public static MessageFormatter formatter() { public static final Message CMD_DISCOVERIES_FOOTER = new MessageBuilder("commands.discoveries.list.footer") .withDefault("------------- >← / >→ --------------") .withPlaceholders("page", "next-page", "prev-page", "pages") - .build(); + .build(); public static final Message CMD_FIND_EMPTY = new MessageBuilder("commands.find.no_nodes_found") - .withDefault("No matching waypoints could be found.") - .build(); + .withDefault("No matching waypoints could be found.") + .build(); public static final Message CMD_FIND_TOO_FAR = new MessageBuilder("commands.find.too_far_away") - .withDefault("The given location is too far away from any waypoint.") - .build(); + .withDefault("The given location is too far away from any waypoint.") + .build(); public static final Message CMD_FIND_BLOCKED = new MessageBuilder("commands.find.no_path_found") - .withDefault("No possible way could be found to reach that target.") - .build(); + .withDefault("No possible way could be found to reach that target.") + .build(); + public static final Message CMD_FIND_UNKNOWN = new MessageBuilder("commands.find.unknown_error") + .withDefault("An unknown error occurred.") + .build(); public static final Message CMD_CANCEL = new MessageBuilder("commands.cancel_path") - .withDefault("Navigation cancelled.") - .build(); + .withDefault("Navigation cancelled.") + .build(); public static final Message CMD_FINDP_OFFLINE = new MessageBuilder("commands.find_player.target_offline") - .withDefault("Player not found.") - .build(); + .withDefault("Player not found.") + .build(); public static final Message CMD_FINDP_NO_SELF = new MessageBuilder("commands.find_player.no_requests_to_self") - .withDefault("You cannot make requests to yourself.") - .build(); + .withDefault("You cannot make requests to yourself.") + .build(); public static final Message CMD_FINDP_NO_REQ = new MessageBuilder("commands.find_player.no_requests") .withDefault("No requests found.") .build();