aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0255-Mob-Pathfinding-API.patch
blob: f08afb6752459a96ad1036b222c6b588bd4cc65a (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..7ba7add6475ff8d238897398c26de24de52c4cfd
--- /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;
+    }
+
+    @Nullable
+    @Override
+    public PathResult getCurrentPath() {
+        Path path = entity.getNavigation().getPath();
+        return path != null ? 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 4ad2ac8d1e9111933fa58c47442fa1f5e8173fd3..2a335f277bd0e4b8ad0f60d8226eb8aaa80a871f 100644
--- a/src/main/java/net/minecraft/world/level/pathfinder/Path.java
+++ b/src/main/java/net/minecraft/world/level/pathfinder/Path.java
@@ -21,6 +21,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
 
     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 659ccb6532506b2a8c9feb55dc5aee962f6da795..f36713771598ac5afdae5d94db10a5790949611d 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
     }
 
+    private final com.destroystokyo.paper.entity.PaperPathfinder paperPathfinder; // Paper
+    @Override public com.destroystokyo.paper.entity.Pathfinder getPathfinder() { return paperPathfinder; } // Paper
     @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) entity;
     }
 
+    // Paper start
+    @Override
+    public void setHandle(net.minecraft.world.entity.Entity entity) {
+        super.setHandle(entity);
+        paperPathfinder.setHandle(getHandle());
+    }
+    // Paper end
+
     @Override
     public String toString() {
         return "CraftMob";