aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0247-Mob-Pathfinding-API.patch
blob: ec6e875e5d585f7928382e67ea69882f487b6a49 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sun, 9 Sep 2018 13:30:00 -0400
Subject: [PATCH] Mob Pathfinding API

Implements Pathfinding API for mobs

== AT ==
public net.minecraft.world.entity.ai.navigation.PathNavigation pathFinder
public net.minecraft.world.level.pathfinder.PathFinder nodeEvaluator
public net.minecraft.world.level.pathfinder.Path nodes

diff --git a/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java b/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java
new file mode 100644
index 0000000000000000000000000000000000000000..064712e7b27a200b29c72076a82f4f5611fa507f
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java
@@ -0,0 +1,143 @@
+package com.destroystokyo.paper.entity;
+
+import org.apache.commons.lang.Validate;
+import org.bukkit.Location;
+import org.bukkit.craftbukkit.entity.CraftLivingEntity;
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.entity.Mob;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import net.minecraft.world.level.pathfinder.Node;
+import net.minecraft.world.level.pathfinder.Path;
+import java.util.ArrayList;
+import java.util.List;
+
+public class PaperPathfinder implements com.destroystokyo.paper.entity.Pathfinder {
+
+    private net.minecraft.world.entity.Mob entity;
+
+    public PaperPathfinder(net.minecraft.world.entity.Mob entity) {
+        this.entity = entity;
+    }
+
+    @Override
+    public Mob getEntity() {
+        return entity.getBukkitMob();
+    }
+
+    public void setHandle(net.minecraft.world.entity.Mob entity) {
+        this.entity = entity;
+    }
+
+    @Override
+    public void stopPathfinding() {
+        entity.getNavigation().stop();
+    }
+
+    @Override
+    public boolean hasPath() {
+        return entity.getNavigation().getPath() != null && !entity.getNavigation().getPath().isDone();
+    }
+
+    @Nullable
+    @Override
+    public PathResult getCurrentPath() {
+        Path path = entity.getNavigation().getPath();
+        return path != null && !path.isDone() ? new PaperPathResult(path) : null;
+    }
+
+    @Nullable
+    @Override
+    public PathResult findPath(Location loc) {
+        Validate.notNull(loc, "Location can not be null");
+        Path path = entity.getNavigation().createPath(loc.getX(), loc.getY(), loc.getZ(), 0);
+        return path != null ? new PaperPathResult(path) : null;
+    }
+
+    @Nullable
+    @Override
+    public PathResult findPath(LivingEntity target) {
+        Validate.notNull(target, "Target can not be null");
+        Path path = entity.getNavigation().createPath(((CraftLivingEntity) target).getHandle(), 0);
+        return path != null ? new PaperPathResult(path) : null;
+    }
+
+    @Override
+    public boolean moveTo(@Nonnull PathResult path, double speed) {
+        Validate.notNull(path, "PathResult can not be null");
+        Path pathEntity = ((PaperPathResult) path).path;
+        return entity.getNavigation().moveTo(pathEntity, speed);
+    }
+
+    @Override
+    public boolean canOpenDoors() {
+        return entity.getNavigation().pathFinder.nodeEvaluator.canOpenDoors();
+    }
+
+    @Override
+    public void setCanOpenDoors(boolean canOpenDoors) {
+        entity.getNavigation().pathFinder.nodeEvaluator.setCanOpenDoors(canOpenDoors);
+    }
+
+    @Override
+    public boolean canPassDoors() {
+        return entity.getNavigation().pathFinder.nodeEvaluator.canPassDoors();
+    }
+
+    @Override
+    public void setCanPassDoors(boolean canPassDoors) {
+        entity.getNavigation().pathFinder.nodeEvaluator.setCanPassDoors(canPassDoors);
+    }
+
+    @Override
+    public boolean canFloat() {
+        return entity.getNavigation().pathFinder.nodeEvaluator.canFloat();
+    }
+
+    @Override
+    public void setCanFloat(boolean canFloat) {
+        entity.getNavigation().pathFinder.nodeEvaluator.setCanFloat(canFloat);
+    }
+
+    public class PaperPathResult implements com.destroystokyo.paper.entity.PaperPathfinder.PathResult {
+
+        private final Path path;
+        PaperPathResult(Path path) {
+            this.path = path;
+        }
+
+        @Nullable
+        @Override
+        public Location getFinalPoint() {
+            Node point = path.getEndNode();
+            return point != null ? toLoc(point) : null;
+        }
+
+        @Override
+        public List<Location> getPoints() {
+            List<Location> points = new ArrayList<>();
+            for (Node point : path.nodes) {
+                points.add(toLoc(point));
+            }
+            return points;
+        }
+
+        @Override
+        public int getNextPointIndex() {
+            return path.getNextNodeIndex();
+        }
+
+        @Nullable
+        @Override
+        public Location getNextPoint() {
+            if (!path.hasNext()) {
+                return null;
+            }
+            return toLoc(path.nodes.get(path.getNextNodeIndex()));
+        }
+    }
+
+    private Location toLoc(Node point) {
+        return new Location(entity.level().getWorld(), point.x, point.y, point.z);
+    }
+}
diff --git a/src/main/java/net/minecraft/world/level/pathfinder/Path.java b/src/main/java/net/minecraft/world/level/pathfinder/Path.java
index 539dc45c3c7ffc60cf3fb47ae4df65e604e8627b..3049edb5a8b5967e5242a3896b23665888eb3472 100644
--- a/src/main/java/net/minecraft/world/level/pathfinder/Path.java
+++ b/src/main/java/net/minecraft/world/level/pathfinder/Path.java
@@ -18,6 +18,7 @@ public class Path {
     private final BlockPos target;
     private final float distToTarget;
     private final boolean reached;
+    public boolean hasNext() { return getNextNodeIndex() < this.nodes.size(); } // Paper - Mob Pathfinding API
 
     public Path(List<Node> nodes, BlockPos target, boolean reachesTarget) {
         this.nodes = nodes;
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
index a75623fd1b2d36530c55c7a380e68b8dc7e58021..018884ced888fcd03d2fb17b3620f8e6125e67da 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
@@ -15,8 +15,11 @@ import org.bukkit.loot.LootTable;
 public abstract class CraftMob extends CraftLivingEntity implements Mob {
     public CraftMob(CraftServer server, net.minecraft.world.entity.Mob entity) {
         super(server, entity);
+         paperPathfinder = new com.destroystokyo.paper.entity.PaperPathfinder(entity); // Paper - Mob Pathfinding API
     }
 
+    private final com.destroystokyo.paper.entity.PaperPathfinder paperPathfinder; // Paper - Mob Pathfinding API
+    @Override public com.destroystokyo.paper.entity.Pathfinder getPathfinder() { return paperPathfinder; } // Paper - Mob Pathfinding API
     @Override
     public void setTarget(LivingEntity target) {
         Preconditions.checkState(!this.getHandle().generation, "Cannot set target during world generation");
@@ -57,6 +60,14 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob {
         return (net.minecraft.world.entity.Mob) this.entity;
     }
 
+    // Paper start - Mob Pathfinding API
+    @Override
+    public void setHandle(net.minecraft.world.entity.Entity entity) {
+        super.setHandle(entity);
+        paperPathfinder.setHandle(getHandle());
+    }
+    // Paper end - Mob Pathfinding API
+
     @Override
     public String toString() {
         return "CraftMob";