257 lines
		
	
	
	
		
			9.1 KiB
			
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			257 lines
		
	
	
	
		
			9.1 KiB
			
		
	
	
	
		
			Diff
		
	
	
	
	
	
From 0000000000000000000000000000000000000000 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.
 | 
						|
 | 
						|
You can use EntityPathfindEvent to cancel new pathfinds from overriding your current.
 | 
						|
 | 
						|
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
 | 
						|
--- /dev/null
 | 
						|
+++ b/src/main/java/com/destroystokyo/paper/entity/Pathfinder.java
 | 
						|
@@ -0,0 +0,0 @@
 | 
						|
+package com.destroystokyo.paper.entity;
 | 
						|
+
 | 
						|
+import org.bukkit.Location;
 | 
						|
+import org.bukkit.entity.LivingEntity;
 | 
						|
+import org.bukkit.entity.Mob;
 | 
						|
+
 | 
						|
+import java.util.List;
 | 
						|
+import org.jetbrains.annotations.NotNull;
 | 
						|
+import org.jetbrains.annotations.Nullable;
 | 
						|
+
 | 
						|
+/**
 | 
						|
+ * Handles pathfinding operations for an Entity
 | 
						|
+ */
 | 
						|
+public interface Pathfinder {
 | 
						|
+
 | 
						|
+    /**
 | 
						|
+     *
 | 
						|
+     * @return The entity that is controlled by this pathfinder
 | 
						|
+     */
 | 
						|
+    @NotNull
 | 
						|
+    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 hasPath();
 | 
						|
+
 | 
						|
+    /**
 | 
						|
+     * @return The location the entity is trying to navigate to, or null if there is no destination
 | 
						|
+     */
 | 
						|
+    @Nullable
 | 
						|
+    PathResult getCurrentPath();
 | 
						|
+
 | 
						|
+    /**
 | 
						|
+     * 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 findPath(@NotNull 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 findPath(@NotNull 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 moveTo(@NotNull Location loc) {
 | 
						|
+        return moveTo(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 moveTo(@NotNull Location loc, double speed) {
 | 
						|
+        PathResult path = findPath(loc);
 | 
						|
+        return path != null && moveTo(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 moveTo(@NotNull LivingEntity target) {
 | 
						|
+        return moveTo(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 moveTo(@NotNull LivingEntity target, double speed) {
 | 
						|
+        PathResult path = findPath(target);
 | 
						|
+        return path != null && moveTo(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 moveTo(@NotNull PathResult path) {
 | 
						|
+        return moveTo(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 moveTo(@NotNull PathResult path, double speed);
 | 
						|
+
 | 
						|
+    /**
 | 
						|
+     * Checks if this pathfinder allows passing through closed doors.
 | 
						|
+     *
 | 
						|
+     * @return if this pathfinder allows passing through closed doors
 | 
						|
+     */
 | 
						|
+    boolean canOpenDoors();
 | 
						|
+
 | 
						|
+    /**
 | 
						|
+     * Allows this pathfinder to pass through closed doors, or not
 | 
						|
+     *
 | 
						|
+     * @param canOpenDoors if the mob can pass through closed doors, or not
 | 
						|
+     */
 | 
						|
+    void setCanOpenDoors(boolean canOpenDoors);
 | 
						|
+
 | 
						|
+    /**
 | 
						|
+     * Checks if this pathfinder allows passing through open doors.
 | 
						|
+     *
 | 
						|
+     * @return if this pathfinder allows passing through open doors
 | 
						|
+     */
 | 
						|
+    boolean canPassDoors();
 | 
						|
+
 | 
						|
+    /**
 | 
						|
+     * Allows this pathfinder to pass through open doors, or not
 | 
						|
+     *
 | 
						|
+     * @param canPassDoors if the mob can pass through open doors, or not
 | 
						|
+     */
 | 
						|
+    void setCanPassDoors(boolean canPassDoors);
 | 
						|
+
 | 
						|
+    /**
 | 
						|
+     * Checks if this pathfinder assumes that the mob can float
 | 
						|
+     *
 | 
						|
+     * @return if this pathfinder assumes that the mob can float
 | 
						|
+     */
 | 
						|
+    boolean canFloat();
 | 
						|
+
 | 
						|
+    /**
 | 
						|
+     * Makes this pathfinder assume that the mob can float, or not
 | 
						|
+     *
 | 
						|
+     * @param canFloat if the mob can float, or not
 | 
						|
+     */
 | 
						|
+    void setCanFloat(boolean canFloat);
 | 
						|
+
 | 
						|
+    /**
 | 
						|
+     * Represents the result of a pathfinding calculation
 | 
						|
+     */
 | 
						|
+    interface PathResult {
 | 
						|
+
 | 
						|
+        /**
 | 
						|
+         * 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
 | 
						|
+         */
 | 
						|
+        @NotNull
 | 
						|
+        List<Location> getPoints();
 | 
						|
+
 | 
						|
+        /**
 | 
						|
+         * @return Returns the index of the current point along the points returned in {@link #getPoints()} the entity
 | 
						|
+         * is trying to reach. This value will be higher than the maximum index of {@link #getPoints()} if this path finding is done.
 | 
						|
+         */
 | 
						|
+        int 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 getNextPoint();
 | 
						|
+
 | 
						|
+        /**
 | 
						|
+         * @return The closest point the path can get to the target location
 | 
						|
+         */
 | 
						|
+        @Nullable Location getFinalPoint();
 | 
						|
+    }
 | 
						|
+}
 | 
						|
diff --git a/src/main/java/org/bukkit/entity/Mob.java b/src/main/java/org/bukkit/entity/Mob.java
 | 
						|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
						|
--- a/src/main/java/org/bukkit/entity/Mob.java
 | 
						|
+++ b/src/main/java/org/bukkit/entity/Mob.java
 | 
						|
@@ -0,0 +0,0 @@
 | 
						|
 package org.bukkit.entity;
 | 
						|
 
 | 
						|
 import org.bukkit.loot.Lootable;
 | 
						|
+import org.jetbrains.annotations.NotNull;
 | 
						|
 import org.jetbrains.annotations.Nullable;
 | 
						|
 
 | 
						|
 /**
 | 
						|
@@ -0,0 +0,0 @@ public interface Mob extends LivingEntity, Lootable {
 | 
						|
     // Paper start
 | 
						|
     @Override
 | 
						|
     org.bukkit.inventory.@org.jetbrains.annotations.NotNull EntityEquipment getEquipment();
 | 
						|
+
 | 
						|
+    /**
 | 
						|
+     * Enables access to control the pathing of an Entity
 | 
						|
+     * @return Pathfinding Manager for this entity
 | 
						|
+     */
 | 
						|
+    @NotNull
 | 
						|
+    com.destroystokyo.paper.entity.Pathfinder getPathfinder();
 | 
						|
     // Paper end
 | 
						|
     /**
 | 
						|
      * Instructs this Mob to set the specified LivingEntity as its target.
 |