Implement new API

This commit is contained in:
fullwall 2016-08-03 00:13:21 +08:00
parent 7d11994b3d
commit 9d0b0aaef1
7 changed files with 134 additions and 24 deletions

View File

@ -43,6 +43,7 @@ import org.bukkit.util.Vector;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import com.mojang.authlib.GameProfileRepository; import com.mojang.authlib.GameProfileRepository;
@ -177,6 +178,7 @@ import net.minecraft.server.v1_10_R1.NetworkManager;
import net.minecraft.server.v1_10_R1.Packet; import net.minecraft.server.v1_10_R1.Packet;
import net.minecraft.server.v1_10_R1.PacketPlayOutEntityTeleport; import net.minecraft.server.v1_10_R1.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_10_R1.PacketPlayOutPlayerInfo; import net.minecraft.server.v1_10_R1.PacketPlayOutPlayerInfo;
import net.minecraft.server.v1_10_R1.PathEntity;
import net.minecraft.server.v1_10_R1.PathPoint; import net.minecraft.server.v1_10_R1.PathPoint;
import net.minecraft.server.v1_10_R1.PathfinderGoalSelector; import net.minecraft.server.v1_10_R1.PathfinderGoalSelector;
import net.minecraft.server.v1_10_R1.ReportedException; import net.minecraft.server.v1_10_R1.ReportedException;
@ -381,9 +383,39 @@ public class NMSImpl implements NMSBridge {
return NMSImpl.getHandle(entity).P; return NMSImpl.getHandle(entity).P;
} }
@Override
public MCNavigator getTargetNavigator(org.bukkit.entity.Entity entity, Iterable<Vector> dest,
final NavigatorParameters params) {
final PathEntity path = new PathEntity(
Iterables.toArray(Iterables.transform(dest, new Function<Vector, PathPoint>() {
@Override
public PathPoint apply(Vector input) {
return new PathPoint(input.getBlockX(), input.getBlockY(), input.getBlockZ());
}
}), PathPoint.class));
return getTargetNavigator(entity, params, new Function<NavigationAbstract, Void>() {
@Override
public Void apply(NavigationAbstract input) {
input.a(path, params.speed());
return null;
}
});
}
@Override @Override
public MCNavigator getTargetNavigator(final org.bukkit.entity.Entity entity, final Location dest, public MCNavigator getTargetNavigator(final org.bukkit.entity.Entity entity, final Location dest,
final NavigatorParameters params) { final NavigatorParameters params) {
return getTargetNavigator(entity, params, new Function<NavigationAbstract, Void>() {
@Override
public Void apply(NavigationAbstract input) {
input.a(dest.getX(), dest.getY(), dest.getZ(), params.speed());
return null;
}
});
}
private MCNavigator getTargetNavigator(final org.bukkit.entity.Entity entity, final NavigatorParameters params,
final Function<NavigationAbstract, Void> function) {
net.minecraft.server.v1_10_R1.Entity raw = getHandle(entity); net.minecraft.server.v1_10_R1.Entity raw = getHandle(entity);
raw.onGround = true; raw.onGround = true;
// not sure of a better way around this - if onGround is false, then // not sure of a better way around this - if onGround is false, then
@ -394,7 +426,7 @@ public class NMSImpl implements NMSBridge {
if (raw instanceof EntityHorse) { if (raw instanceof EntityHorse) {
raw.width = Math.min(0.99f, oldWidth); raw.width = Math.min(0.99f, oldWidth);
} }
navigation.a(dest.getX(), dest.getY(), dest.getZ(), params.speed()); function.apply(navigation);
raw.width = oldWidth; // minecraft requires that an entity fit onto both blocks if width >= 1f, but we'd raw.width = oldWidth; // minecraft requires that an entity fit onto both blocks if width >= 1f, but we'd
// prefer to make it just fit on 1 so hack around it a bit. // prefer to make it just fit on 1 so hack around it a bit.
final CancelReason initial; final CancelReason initial;
@ -426,7 +458,7 @@ public class NMSImpl implements NMSBridge {
public boolean update() { public boolean update() {
if (params.speed() != lastSpeed) { if (params.speed() != lastSpeed) {
Messaging.debug("Repathfinding " + ((NPCHolder) entity).getNPC().getId() + " due to speed change"); Messaging.debug("Repathfinding " + ((NPCHolder) entity).getNPC().getId() + " due to speed change");
navigation.a(dest.getX(), dest.getY(), dest.getZ(), params.speed()); function.apply(navigation);
lastSpeed = params.speed(); lastSpeed = params.speed();
} }
navigation.a(params.speed()); navigation.a(params.speed());
@ -1295,6 +1327,7 @@ public class NMSImpl implements NMSBridge {
private static Field PATHFINDING_RANGE = NMS.getField(NavigationAbstract.class, "f"); private static Field PATHFINDING_RANGE = NMS.getField(NavigationAbstract.class, "f");
private static final Field RABBIT_FIELD = NMS.getField(EntityRabbit.class, "bx"); private static final Field RABBIT_FIELD = NMS.getField(EntityRabbit.class, "bx");
private static final Random RANDOM = Util.getFastRandom(); private static final Random RANDOM = Util.getFastRandom();
private static Field SKULL_PROFILE_FIELD; private static Field SKULL_PROFILE_FIELD;
private static Field TRACKED_ENTITY_SET = NMS.getField(EntityTracker.class, "c"); private static Field TRACKED_ENTITY_SET = NMS.getField(EntityTracker.class, "c");

View File

@ -1,9 +1,13 @@
package net.citizensnpcs.npc.ai; package net.citizensnpcs.npc.ai;
import java.util.List;
import org.bukkit.Effect; import org.bukkit.Effect;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import com.google.common.collect.Lists;
import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.ai.AbstractPathStrategy; import net.citizensnpcs.api.ai.AbstractPathStrategy;
import net.citizensnpcs.api.ai.NavigatorParameters; import net.citizensnpcs.api.ai.NavigatorParameters;
@ -24,6 +28,15 @@ public class AStarNavigationStrategy extends AbstractPathStrategy {
private Path plan; private Path plan;
private Vector vector; private Vector vector;
public AStarNavigationStrategy(NPC npc, Iterable<Vector> path, NavigatorParameters params) {
super(TargetType.LOCATION);
List<Vector> list = Lists.newArrayList(path);
this.params = params;
this.destination = list.get(list.size() - 1).toLocation(npc.getStoredLocation().getWorld());
this.npc = npc;
setPlan(new Path(list));
}
public AStarNavigationStrategy(NPC npc, Location dest, NavigatorParameters params) { public AStarNavigationStrategy(NPC npc, Location dest, NavigatorParameters params) {
super(TargetType.LOCATION); super(TargetType.LOCATION);
this.params = params; this.params = params;
@ -31,17 +44,9 @@ public class AStarNavigationStrategy extends AbstractPathStrategy {
this.npc = npc; this.npc = npc;
Location location = npc.getEntity().getLocation(); Location location = npc.getEntity().getLocation();
VectorGoal goal = new VectorGoal(dest, (float) params.pathDistanceMargin()); VectorGoal goal = new VectorGoal(dest, (float) params.pathDistanceMargin());
plan = ASTAR.runFully(goal, setPlan(ASTAR.runFully(goal,
new VectorNode(goal, location, new ChunkBlockSource(location, params.range()), params.examiners()), new VectorNode(goal, location, new ChunkBlockSource(location, params.range()), params.examiners()),
50000); 50000));
if (plan == null || plan.isComplete()) {
setCancelReason(CancelReason.STUCK);
} else {
vector = plan.getCurrentVector();
if (Setting.DEBUG_PATHFINDING.asBoolean()) {
plan.debug();
}
}
} }
@Override @Override
@ -54,6 +59,18 @@ public class AStarNavigationStrategy extends AbstractPathStrategy {
return destination; return destination;
} }
public void setPlan(Path path) {
this.plan = path;
if (plan == null || plan.isComplete()) {
setCancelReason(CancelReason.STUCK);
} else {
vector = plan.getCurrentVector();
if (Setting.DEBUG_PATHFINDING.asBoolean()) {
plan.debug();
}
}
}
@Override @Override
public void stop() { public void stop() {
if (plan != null && Setting.DEBUG_PATHFINDING.asBoolean()) { if (plan != null && Setting.DEBUG_PATHFINDING.asBoolean()) {
@ -95,6 +112,5 @@ public class AStarNavigationStrategy extends AbstractPathStrategy {
} }
private static final AStarMachine<VectorNode, Path> ASTAR = AStarMachine.createWithDefaultStorage(); private static final AStarMachine<VectorNode, Path> ASTAR = AStarMachine.createWithDefaultStorage();
private static final Location NPC_LOCATION = new Location(null, 0, 0, 0); private static final Location NPC_LOCATION = new Location(null, 0, 0, 0);
} }

View File

@ -12,6 +12,8 @@ import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import com.google.common.collect.Iterables;
import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.ai.EntityTarget; import net.citizensnpcs.api.ai.EntityTarget;
import net.citizensnpcs.api.ai.Navigator; import net.citizensnpcs.api.ai.Navigator;
@ -199,6 +201,27 @@ public class CitizensNavigator implements Navigator, Runnable {
switchStrategyTo(newStrategy); switchStrategyTo(newStrategy);
} }
@Override
public void setTarget(Iterable<Vector> path) {
if (!npc.isSpawned())
throw new IllegalStateException("npc is not spawned");
if (path == null || Iterables.size(path) == 0) {
cancelNavigation();
return;
}
switchParams();
updatePathfindingRange();
PathStrategy newStrategy;
if (npc.isFlyable()) {
newStrategy = new FlyingAStarNavigationStrategy(npc, path, localParams);
} else if (localParams.useNewPathfinder() || !(npc.getEntity() instanceof LivingEntity)) {
newStrategy = new AStarNavigationStrategy(npc, path, localParams);
} else {
newStrategy = new MCNavigationStrategy(npc, path, localParams);
}
switchStrategyTo(newStrategy);
}
@Override @Override
public void setTarget(Location target) { public void setTarget(Location target) {
if (!npc.isSpawned()) if (!npc.isSpawned())
@ -357,5 +380,6 @@ public class CitizensNavigator implements Navigator, Runnable {
} }
private static final Location STATIONARY_LOCATION = new Location(null, 0, 0, 0); private static final Location STATIONARY_LOCATION = new Location(null, 0, 0, 0);
private static int UNINITIALISED_SPEED = Integer.MIN_VALUE; private static int UNINITIALISED_SPEED = Integer.MIN_VALUE;
} }

View File

@ -1,10 +1,14 @@
package net.citizensnpcs.npc.ai; package net.citizensnpcs.npc.ai;
import java.util.List;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import com.google.common.collect.Lists;
import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.ai.AbstractPathStrategy; import net.citizensnpcs.api.ai.AbstractPathStrategy;
import net.citizensnpcs.api.ai.NavigatorParameters; import net.citizensnpcs.api.ai.NavigatorParameters;
@ -27,6 +31,15 @@ public class FlyingAStarNavigationStrategy extends AbstractPathStrategy {
private final Location target; private final Location target;
private Vector vector; private Vector vector;
public FlyingAStarNavigationStrategy(NPC npc, Iterable<Vector> path, NavigatorParameters params) {
super(TargetType.LOCATION);
List<Vector> list = Lists.newArrayList(path);
this.target = list.get(list.size() - 1).toLocation(npc.getStoredLocation().getWorld());
this.parameters = params;
this.npc = npc;
setPlan(new Path(list));
}
public FlyingAStarNavigationStrategy(final NPC npc, Location dest, NavigatorParameters params) { public FlyingAStarNavigationStrategy(final NPC npc, Location dest, NavigatorParameters params) {
super(TargetType.LOCATION); super(TargetType.LOCATION);
this.target = dest; this.target = dest;
@ -44,17 +57,9 @@ public class FlyingAStarNavigationStrategy extends AbstractPathStrategy {
if (!found) { if (!found) {
params.examiner(new FlyingBlockExaminer()); params.examiner(new FlyingBlockExaminer());
} }
plan = ASTAR.runFully(goal, setPlan(ASTAR.runFully(goal,
new VectorNode(goal, location, new ChunkBlockSource(location, params.range()), params.examiners()), new VectorNode(goal, location, new ChunkBlockSource(location, params.range()), params.examiners()),
50000); 50000));
if (plan == null || plan.isComplete()) {
setCancelReason(CancelReason.STUCK);
} else {
vector = plan.getCurrentVector();
if (Setting.DEBUG_PATHFINDING.asBoolean()) {
plan.debug();
}
}
} }
@Override @Override
@ -67,6 +72,18 @@ public class FlyingAStarNavigationStrategy extends AbstractPathStrategy {
return target; return target;
} }
public void setPlan(Path path) {
this.plan = path;
if (plan == null || plan.isComplete()) {
setCancelReason(CancelReason.STUCK);
} else {
vector = plan.getCurrentVector();
if (Setting.DEBUG_PATHFINDING.asBoolean()) {
plan.debug();
}
}
}
@Override @Override
public void stop() { public void stop() {
if (plan != null && Setting.DEBUG_PATHFINDING.asBoolean()) { if (plan != null && Setting.DEBUG_PATHFINDING.asBoolean()) {
@ -124,6 +141,5 @@ public class FlyingAStarNavigationStrategy extends AbstractPathStrategy {
} }
private static final AStarMachine<VectorNode, Path> ASTAR = AStarMachine.createWithDefaultStorage(); private static final AStarMachine<VectorNode, Path> ASTAR = AStarMachine.createWithDefaultStorage();
private static final Location NPC_LOCATION = new Location(null, 0, 0, 0); private static final Location NPC_LOCATION = new Location(null, 0, 0, 0);
} }

View File

@ -1,9 +1,13 @@
package net.citizensnpcs.npc.ai; package net.citizensnpcs.npc.ai;
import java.util.List;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import com.google.common.collect.Lists;
import net.citizensnpcs.api.ai.AbstractPathStrategy; import net.citizensnpcs.api.ai.AbstractPathStrategy;
import net.citizensnpcs.api.ai.NavigatorParameters; import net.citizensnpcs.api.ai.NavigatorParameters;
import net.citizensnpcs.api.ai.TargetType; import net.citizensnpcs.api.ai.TargetType;
@ -17,6 +21,15 @@ public class MCNavigationStrategy extends AbstractPathStrategy {
private final NavigatorParameters parameters; private final NavigatorParameters parameters;
private final Location target; private final Location target;
MCNavigationStrategy(final NPC npc, Iterable<Vector> path, NavigatorParameters params) {
super(TargetType.LOCATION);
List<Vector> list = Lists.newArrayList(path);
this.target = list.get(list.size() - 1).toLocation(npc.getStoredLocation().getWorld());
this.parameters = params;
handle = npc.getEntity();
this.navigator = NMS.getTargetNavigator(npc.getEntity(), list, params);
}
MCNavigationStrategy(final NPC npc, Location dest, NavigatorParameters params) { MCNavigationStrategy(final NPC npc, Location dest, NavigatorParameters params) {
super(TargetType.LOCATION); super(TargetType.LOCATION);
this.target = dest; this.target = dest;

View File

@ -15,6 +15,7 @@ import org.bukkit.entity.Tameable;
import org.bukkit.entity.Wither; import org.bukkit.entity.Wither;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.inventory.meta.SkullMeta; import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.util.Vector;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import com.mojang.authlib.GameProfileRepository; import com.mojang.authlib.GameProfileRepository;
@ -106,6 +107,10 @@ public class NMS {
return BRIDGE.getStepHeight(entity); return BRIDGE.getStepHeight(entity);
} }
public static MCNavigator getTargetNavigator(Entity entity, Iterable<Vector> dest, NavigatorParameters params) {
return BRIDGE.getTargetNavigator(entity, dest, params);
}
public static MCNavigator getTargetNavigator(Entity entity, Location dest, NavigatorParameters params) { public static MCNavigator getTargetNavigator(Entity entity, Location dest, NavigatorParameters params) {
return BRIDGE.getTargetNavigator(entity, dest, params); return BRIDGE.getTargetNavigator(entity, dest, params);
} }

View File

@ -15,6 +15,7 @@ import org.bukkit.entity.Tameable;
import org.bukkit.entity.Wither; import org.bukkit.entity.Wither;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.inventory.meta.SkullMeta; import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.util.Vector;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import com.mojang.authlib.GameProfileRepository; import com.mojang.authlib.GameProfileRepository;
@ -58,6 +59,8 @@ public interface NMSBridge {
public TargetNavigator getTargetNavigator(Entity handle, Entity target, NavigatorParameters parameters); public TargetNavigator getTargetNavigator(Entity handle, Entity target, NavigatorParameters parameters);
public MCNavigator getTargetNavigator(Entity entity, Iterable<Vector> dest, NavigatorParameters params);
public MCNavigator getTargetNavigator(Entity entity, Location dest, NavigatorParameters params); public MCNavigator getTargetNavigator(Entity entity, Location dest, NavigatorParameters params);
public Entity getVehicle(Entity entity); public Entity getVehicle(Entity entity);