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.Preconditions;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.mojang.authlib.GameProfile;
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.PacketPlayOutEntityTeleport;
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.PathfinderGoalSelector;
import net.minecraft.server.v1_10_R1.ReportedException;
@ -381,9 +383,39 @@ public class NMSImpl implements NMSBridge {
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
public MCNavigator getTargetNavigator(final org.bukkit.entity.Entity entity, final Location dest,
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);
raw.onGround = true;
// 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) {
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
// prefer to make it just fit on 1 so hack around it a bit.
final CancelReason initial;
@ -426,7 +458,7 @@ public class NMSImpl implements NMSBridge {
public boolean update() {
if (params.speed() != lastSpeed) {
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();
}
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 final Field RABBIT_FIELD = NMS.getField(EntityRabbit.class, "bx");
private static final Random RANDOM = Util.getFastRandom();
private static Field SKULL_PROFILE_FIELD;
private static Field TRACKED_ENTITY_SET = NMS.getField(EntityTracker.class, "c");

View File

@ -1,9 +1,13 @@
package net.citizensnpcs.npc.ai;
import java.util.List;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.util.Vector;
import com.google.common.collect.Lists;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.ai.AbstractPathStrategy;
import net.citizensnpcs.api.ai.NavigatorParameters;
@ -24,6 +28,15 @@ public class AStarNavigationStrategy extends AbstractPathStrategy {
private Path plan;
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) {
super(TargetType.LOCATION);
this.params = params;
@ -31,17 +44,9 @@ public class AStarNavigationStrategy extends AbstractPathStrategy {
this.npc = npc;
Location location = npc.getEntity().getLocation();
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()),
50000);
if (plan == null || plan.isComplete()) {
setCancelReason(CancelReason.STUCK);
} else {
vector = plan.getCurrentVector();
if (Setting.DEBUG_PATHFINDING.asBoolean()) {
plan.debug();
}
}
50000));
}
@Override
@ -54,6 +59,18 @@ public class AStarNavigationStrategy extends AbstractPathStrategy {
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
public void stop() {
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 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.util.Vector;
import com.google.common.collect.Iterables;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.ai.EntityTarget;
import net.citizensnpcs.api.ai.Navigator;
@ -199,6 +201,27 @@ public class CitizensNavigator implements Navigator, Runnable {
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
public void setTarget(Location target) {
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 int UNINITIALISED_SPEED = Integer.MIN_VALUE;
}

View File

@ -1,10 +1,14 @@
package net.citizensnpcs.npc.ai;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.entity.EntityType;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.util.Vector;
import com.google.common.collect.Lists;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.ai.AbstractPathStrategy;
import net.citizensnpcs.api.ai.NavigatorParameters;
@ -27,6 +31,15 @@ public class FlyingAStarNavigationStrategy extends AbstractPathStrategy {
private final Location target;
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) {
super(TargetType.LOCATION);
this.target = dest;
@ -44,17 +57,9 @@ public class FlyingAStarNavigationStrategy extends AbstractPathStrategy {
if (!found) {
params.examiner(new FlyingBlockExaminer());
}
plan = ASTAR.runFully(goal,
setPlan(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();
}
}
50000));
}
@Override
@ -67,6 +72,18 @@ public class FlyingAStarNavigationStrategy extends AbstractPathStrategy {
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
public void stop() {
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 Location NPC_LOCATION = new Location(null, 0, 0, 0);
}

View File

@ -1,9 +1,13 @@
package net.citizensnpcs.npc.ai;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.util.Vector;
import com.google.common.collect.Lists;
import net.citizensnpcs.api.ai.AbstractPathStrategy;
import net.citizensnpcs.api.ai.NavigatorParameters;
import net.citizensnpcs.api.ai.TargetType;
@ -17,6 +21,15 @@ public class MCNavigationStrategy extends AbstractPathStrategy {
private final NavigatorParameters parameters;
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) {
super(TargetType.LOCATION);
this.target = dest;

View File

@ -15,6 +15,7 @@ import org.bukkit.entity.Tameable;
import org.bukkit.entity.Wither;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.util.Vector;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.GameProfileRepository;
@ -106,6 +107,10 @@ public class NMS {
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) {
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.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.util.Vector;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.GameProfileRepository;
@ -58,6 +59,8 @@ public interface NMSBridge {
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 Entity getVehicle(Entity entity);