| 
									
										
										
										
											2018-09-09 14:36:51 -04:00
										 |  |  | From ff4b1d675da0e4955bae805d7ed579f3e8fb9238 Mon Sep 17 00:00:00 2001 | 
					
						
							| 
									
										
										
										
											2018-09-09 12:58:47 -04:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											2018-09-09 14:36:51 -04:00
										 |  |  | index 000000000..78230bd28
 | 
					
						
							| 
									
										
										
										
											2018-09-09 12:58:47 -04:00
										 |  |  | --- /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.
 | 
					
						
							|  |  |  | +         */
 | 
					
						
							| 
									
										
										
										
											2018-09-09 14:36:51 -04:00
										 |  |  | +        int getNextPointIndex();
 | 
					
						
							| 
									
										
										
										
											2018-09-09 12:58:47 -04:00
										 |  |  | +
 | 
					
						
							|  |  |  | +        /**
 | 
					
						
							|  |  |  | +         * @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 | 
					
						
							|  |  |  | 
 |