-
-
Notifications
You must be signed in to change notification settings - Fork 302
/
FlyingAStarNavigationStrategy.java
129 lines (114 loc) · 4.62 KB
/
FlyingAStarNavigationStrategy.java
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
package net.citizensnpcs.npc.ai;
import org.bukkit.Location;
import org.bukkit.entity.EntityType;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.util.Vector;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.ai.AbstractPathStrategy;
import net.citizensnpcs.api.ai.NavigatorParameters;
import net.citizensnpcs.api.ai.TargetType;
import net.citizensnpcs.api.ai.event.CancelReason;
import net.citizensnpcs.api.astar.AStarMachine;
import net.citizensnpcs.api.astar.pathfinder.BlockExaminer;
import net.citizensnpcs.api.astar.pathfinder.ChunkBlockSource;
import net.citizensnpcs.api.astar.pathfinder.FlyingBlockExaminer;
import net.citizensnpcs.api.astar.pathfinder.Path;
import net.citizensnpcs.api.astar.pathfinder.VectorGoal;
import net.citizensnpcs.api.astar.pathfinder.VectorNode;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.util.NMS;
public class FlyingAStarNavigationStrategy extends AbstractPathStrategy {
private final NPC npc;
private final NavigatorParameters parameters;
private Path plan;
private final Location target;
private Vector vector;
public FlyingAStarNavigationStrategy(final NPC npc, Location dest, NavigatorParameters params) {
super(TargetType.LOCATION);
this.target = dest;
this.parameters = params;
this.npc = npc;
Location location = npc.getEntity().getLocation();
VectorGoal goal = new VectorGoal(dest, (float) params.pathDistanceMargin());
boolean found = false;
for (BlockExaminer examiner : params.examiners()) {
if (examiner instanceof FlyingBlockExaminer) {
found = true;
break;
}
}
if (!found) {
params.examiner(new FlyingBlockExaminer());
}
plan = ASTAR.runFully(goal,
new VectorNode(goal, location, new ChunkBlockSource(location, params.range()), params.examiners()),
50000);
if (plan == null || plan.isComplete()) {
setCancelReason(CancelReason.STUCK);
} else {
vector = plan.getCurrentVector();
if (Setting.DEBUG_PATHFINDING.asBoolean()) {
plan.debug();
}
}
}
@Override
public Iterable<Vector> getPath() {
return plan == null ? null : plan.getPath();
}
@Override
public Location getTargetAsLocation() {
return target;
}
@Override
public void stop() {
if (plan != null && Setting.DEBUG_PATHFINDING.asBoolean()) {
plan.debugEnd();
}
plan = null;
}
@Override
public boolean update() {
if (getCancelReason() != null || plan == null || plan.isComplete()) {
return true;
}
Location current = npc.getEntity().getLocation(NPC_LOCATION);
if (current.toVector().distanceSquared(vector) <= parameters.distanceMargin()) {
plan.update(npc);
if (plan.isComplete()) {
return true;
}
vector = plan.getCurrentVector();
}
double d0 = vector.getX() + 0.5D - current.getX();
double d1 = vector.getY() + 0.1D - current.getY();
double d2 = vector.getZ() + 0.5D - current.getZ();
Vector velocity = npc.getEntity().getVelocity();
double motX = velocity.getX(), motY = velocity.getY(), motZ = velocity.getZ();
motX += (Math.signum(d0) * 0.5D - motX) * 0.1;
motY += (Math.signum(d1) * 0.7D - motY) * 0.1;
motZ += (Math.signum(d2) * 0.5D - motZ) * 0.1;
float targetYaw = (float) (Math.atan2(motZ, motX) * 180.0D / Math.PI) - 90.0F;
float normalisedTargetYaw = (targetYaw - current.getYaw()) % 360;
if (normalisedTargetYaw >= 180.0F) {
normalisedTargetYaw -= 360.0F;
}
if (normalisedTargetYaw < -180.0F) {
normalisedTargetYaw += 360.0F;
}
velocity.setX(motX).setY(motY).setZ(motZ).multiply(parameters.speed());
npc.getEntity().setVelocity(velocity);
NMS.setVerticalMovement(npc.getEntity(), 0.5);
if (npc.getEntity().getType() != EntityType.ENDER_DRAGON) {
float newYaw = current.getYaw() + normalisedTargetYaw;
current.setYaw(newYaw);
NMS.setHeadYaw(npc.getEntity(), newYaw);
npc.teleport(current, TeleportCause.PLUGIN);
}
parameters.run();
plan.run(npc);
return false;
}
private static final AStarMachine<VectorNode, Path> ASTAR = AStarMachine.createWithDefaultStorage();
private static final Location NPC_LOCATION = new Location(null, 0, 0, 0);
}