208 Zeilen
7.6 KiB
Diff
208 Zeilen
7.6 KiB
Diff
|
From a9c06c0f1eecb397249a9e0c8881bf848e9168f3 Mon Sep 17 00:00:00 2001
|
||
|
From: Aikar <aikar@aikar.co>
|
||
|
Date: Sun, 9 Sep 2018 12:39:06 -0400
|
||
|
Subject: [PATCH] Mob Pathfinding API
|
||
|
|
||
|
Adds an API to allow plugins to instruct a Mob to Pathfind to a Location or Entity
|
||
|
|
||
|
This does not do anything to stop other AI rules from changing the location, so
|
||
|
it is still up to the plugin to control that or override after another goal changed
|
||
|
the location.
|
||
|
|
||
|
diff --git a/src/main/java/com/destroystokyo/paper/entity/Pathfinder.java b/src/main/java/com/destroystokyo/paper/entity/Pathfinder.java
|
||
|
new file mode 100644
|
||
|
index 000000000..27b6bb696
|
||
|
--- /dev/null
|
||
|
+++ b/src/main/java/com/destroystokyo/paper/entity/Pathfinder.java
|
||
|
@@ -0,0 +1,168 @@
|
||
|
+package com.destroystokyo.paper.entity;
|
||
|
+
|
||
|
+import org.apache.commons.lang.Validate;
|
||
|
+import org.bukkit.Location;
|
||
|
+import org.bukkit.entity.LivingEntity;
|
||
|
+import org.bukkit.entity.Mob;
|
||
|
+
|
||
|
+import javax.annotation.Nonnull;
|
||
|
+import javax.annotation.Nullable;
|
||
|
+import java.util.List;
|
||
|
+
|
||
|
+/**
|
||
|
+ * Handles pathfinding operations for an Entity
|
||
|
+ */
|
||
|
+public interface Pathfinder {
|
||
|
+
|
||
|
+ /**
|
||
|
+ *
|
||
|
+ * @return The entity that is controlled by this pathfinder
|
||
|
+ */
|
||
|
+ Mob getEntity();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Instructs the Entity to stop trying to navigate to its current desired location
|
||
|
+ */
|
||
|
+ void stopPathfinding();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * If the entity is currently trying to navigate to a destination, this will return true
|
||
|
+ * @return true if the entity is navigating to a destination
|
||
|
+ */
|
||
|
+ boolean hasDestination();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * @return The location the entity is trying to navigate to, or null if there is no destination
|
||
|
+ */
|
||
|
+ @Nullable PathResult getCurrentDestination();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Calculates a destination for the Entity to navigate to, but does not set it
|
||
|
+ * as the current target. Useful for calculating what would happen before setting it.
|
||
|
+ * @param loc Location to navigate to
|
||
|
+ * @return The closest Location the Entity can get to for this navigation, or null if no path could be calculated
|
||
|
+ */
|
||
|
+ @Nullable PathResult calculateDestination(Location loc);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Calculates a destination for the Entity to navigate to to reach the target entity,
|
||
|
+ * but does not set it as the current target.
|
||
|
+ * Useful for calculating what would happen before setting it.
|
||
|
+ *
|
||
|
+ * The behavior of this PathResult is subject to the games pathfinding rules, and may
|
||
|
+ * result in the pathfinding automatically updating to follow the target Entity.
|
||
|
+ *
|
||
|
+ * However, this behavior is not guaranteed, and is subject to the games behavior.
|
||
|
+ *
|
||
|
+ * @param target the Entity to navigate to
|
||
|
+ * @return The closest Location the Entity can get to for this navigation, or null if no path could be calculated
|
||
|
+ */
|
||
|
+ @Nullable PathResult calculateDestination(LivingEntity target);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Calculates a destination for the Entity to navigate to, and sets it with default speed
|
||
|
+ * as the current target.
|
||
|
+ * @param loc Location to navigate to
|
||
|
+ * @return If the pathfinding was successfully started
|
||
|
+ */
|
||
|
+ default boolean setDestination(@Nonnull Location loc) {
|
||
|
+ return setDestination(loc, 1);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Calculates a destination for the Entity to navigate to, with desired speed
|
||
|
+ * as the current target.
|
||
|
+ * @param loc Location to navigate to
|
||
|
+ * @param speed Speed multiplier to navigate at, where 1 is 'normal'
|
||
|
+ * @return If the pathfinding was successfully started
|
||
|
+ */
|
||
|
+ default boolean setDestination(@Nonnull Location loc, double speed) {
|
||
|
+ PathResult path = calculateDestination(loc);
|
||
|
+ return path != null && setDestination(path, speed);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Calculates a destination for the Entity to navigate to to reach the target entity,
|
||
|
+ * and sets it with default speed.
|
||
|
+ *
|
||
|
+ * The behavior of this PathResult is subject to the games pathfinding rules, and may
|
||
|
+ * result in the pathfinding automatically updating to follow the target Entity.
|
||
|
+ *
|
||
|
+ * However, this behavior is not guaranteed, and is subject to the games behavior.
|
||
|
+ *
|
||
|
+ * @param target the Entity to navigate to
|
||
|
+ * @return If the pathfinding was successfully started
|
||
|
+ */
|
||
|
+ default boolean setDestination(@Nonnull LivingEntity target) {
|
||
|
+ return setDestination(target, 1);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Calculates a destination for the Entity to navigate to to reach the target entity,
|
||
|
+ * and sets it with specified speed.
|
||
|
+ *
|
||
|
+ * The behavior of this PathResult is subject to the games pathfinding rules, and may
|
||
|
+ * result in the pathfinding automatically updating to follow the target Entity.
|
||
|
+ *
|
||
|
+ * However, this behavior is not guaranteed, and is subject to the games behavior.
|
||
|
+ *
|
||
|
+ * @param target the Entity to navigate to
|
||
|
+ * @param speed Speed multiplier to navigate at, where 1 is 'normal'
|
||
|
+ * @return If the pathfinding was successfully started
|
||
|
+ */
|
||
|
+ default boolean setDestination(@Nonnull LivingEntity target, double speed) {
|
||
|
+ PathResult path = calculateDestination(target);
|
||
|
+ return path != null && setDestination(path, speed);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Takes the result of a previous pathfinding calculation and sets it
|
||
|
+ * as the active pathfinding with default speed.
|
||
|
+ *
|
||
|
+ * @param path The Path to start following
|
||
|
+ * @return If the pathfinding was successfully started
|
||
|
+ */
|
||
|
+ default boolean setDestination(@Nonnull PathResult path) {
|
||
|
+ return setDestination(path, 1);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Takes the result of a previous pathfinding calculation and sets it
|
||
|
+ * as the active pathfinding,
|
||
|
+ *
|
||
|
+ * @param path The Path to start following
|
||
|
+ * @param speed Speed multiplier to navigate at, where 1 is 'normal'
|
||
|
+ * @return If the pathfinding was successfully started
|
||
|
+ */
|
||
|
+ boolean setDestination(@Nonnull PathResult path, double speed);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Represents the result of a pathfinding calculation
|
||
|
+ */
|
||
|
+ interface PathResult {
|
||
|
+
|
||
|
+ /**
|
||
|
+ * @return The closest point the path can get to the target location
|
||
|
+ */
|
||
|
+ @Nullable Location getLocation();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * All currently calculated points to follow along the path to reach the destination location
|
||
|
+ *
|
||
|
+ * Will return points the entity has already moved past, see {@link #getNextPointIndex()}
|
||
|
+ * @return List of points
|
||
|
+ */
|
||
|
+ List<Location> getPoints();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * @return Returns the index of the current point along the points returned in {@link #getPoints()} the entity
|
||
|
+ * is trying to reach, or null if we are done with this pathfinding.
|
||
|
+ */
|
||
|
+ @Nullable Integer getNextPointIndex();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * @return The next location in the path points the entity is trying to reach, or null if there is no next point
|
||
|
+ */
|
||
|
+ @Nullable Location getNextPointLocation();
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/src/main/java/org/bukkit/entity/Mob.java b/src/main/java/org/bukkit/entity/Mob.java
|
||
|
index d029d34ea..48eddcd30 100644
|
||
|
--- a/src/main/java/org/bukkit/entity/Mob.java
|
||
|
+++ b/src/main/java/org/bukkit/entity/Mob.java
|
||
|
@@ -7,6 +7,14 @@ import org.bukkit.loot.Lootable;
|
||
|
*/
|
||
|
public interface Mob extends LivingEntity, Lootable {
|
||
|
|
||
|
+ // Paper start
|
||
|
+ /**
|
||
|
+ * Enables access to control the pathing of an Entity
|
||
|
+ * @return Pathfinding Manager for this entity
|
||
|
+ */
|
||
|
+ com.destroystokyo.paper.entity.Pathfinder getPathfinder();
|
||
|
+ // Paper end
|
||
|
+
|
||
|
/**
|
||
|
* Instructs this Mob to set the specified LivingEntity as its target.
|
||
|
* <p>
|
||
|
--
|
||
|
2.18.0
|
||
|
|