Skip to content

Commit

Permalink
Change navigation back to MC navigation and fix duplicate NPCs client…
Browse files Browse the repository at this point in the history
…side
  • Loading branch information
fullwall committed Jul 5, 2013
1 parent 836ae1e commit ea20318
Show file tree
Hide file tree
Showing 7 changed files with 466 additions and 45 deletions.
7 changes: 0 additions & 7 deletions src/main/java/net/citizensnpcs/npc/CitizensNPC.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@
import net.citizensnpcs.util.Messages;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.server.v1_6_R1.EntityHuman;
import net.minecraft.server.v1_6_R1.EntityLiving;
import net.minecraft.server.v1_6_R1.EntityPlayer;
import net.minecraft.server.v1_6_R1.Packet20NamedEntitySpawn;

import org.bukkit.Bukkit;
import org.bukkit.Location;
Expand Down Expand Up @@ -216,10 +213,6 @@ public boolean spawn(Location at) {
trait.onSpawn();
getBukkitEntity().setRemoveWhenFarAway(false);
getBukkitEntity().setCustomName(getFullName());
if (mcEntity instanceof EntityPlayer) {
Packet20NamedEntitySpawn packet = new Packet20NamedEntitySpawn((EntityHuman) mcEntity);
NMS.sendToOnline(packet);
}
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ public void setTarget(Location target) {
}
localParams = defaultParams.clone();
PathStrategy newStrategy;
if (Setting.USE_NEW_PATHFINDER.asBoolean() || NMS.isSentient(npc.getBukkitEntity())) {
if (Setting.USE_NEW_PATHFINDER.asBoolean()) {
newStrategy = new AStarNavigationStrategy(npc, target, localParams);
} else
newStrategy = new MCNavigationStrategy(npc, target, localParams);
Expand Down
13 changes: 7 additions & 6 deletions src/main/java/net/citizensnpcs/npc/ai/MCNavigationStrategy.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
import net.citizensnpcs.api.ai.TargetType;
import net.citizensnpcs.api.ai.event.CancelReason;
import net.citizensnpcs.api.npc.NPC;
import net.minecraft.server.v1_6_R1.EntityInsentient;
import net.citizensnpcs.util.NMS;
import net.minecraft.server.v1_6_R1.EntityLiving;
import net.minecraft.server.v1_6_R1.Navigation;

import org.bukkit.Location;
Expand All @@ -19,15 +20,15 @@ public class MCNavigationStrategy extends AbstractPathStrategy {
super(TargetType.LOCATION);
this.target = dest;
this.parameters = params;
EntityInsentient handle = (EntityInsentient) ((CraftLivingEntity) npc.getBukkitEntity()).getHandle();
EntityLiving handle = ((CraftLivingEntity) npc.getBukkitEntity()).getHandle();
handle.onGround = true;
// not sure of a better way around this - if onGround is false, then
// navigation won't execute, and calling entity.move doesn't
// entirely fix the problem.
navigation = handle.getNavigation();
navigation = NMS.getNavigation(handle);
navigation.a(parameters.avoidWater());
navigation.a(dest.getX(), dest.getY(), dest.getZ(), parameters.speed());
if (navigation.g())
if (NMS.isNavigationFinished(navigation))
setCancelReason(CancelReason.STUCK);
}

Expand All @@ -43,7 +44,7 @@ public TargetType getTargetType() {

@Override
public void stop() {
navigation.g();
NMS.stopNavigation(navigation);
}

@Override
Expand All @@ -57,6 +58,6 @@ public boolean update() {
return true;
navigation.a(parameters.avoidWater());
navigation.a(parameters.speed());
return navigation.g();
return NMS.isNavigationFinished(navigation);
}
}
42 changes: 28 additions & 14 deletions src/main/java/net/citizensnpcs/npc/ai/MCTargetStrategy.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.PlayerAnimation;
import net.citizensnpcs.util.nms.PlayerNavigation;
import net.minecraft.server.v1_6_R1.AttributeInstance;
import net.minecraft.server.v1_6_R1.Entity;
import net.minecraft.server.v1_6_R1.EntityInsentient;
import net.minecraft.server.v1_6_R1.EntityLiving;
import net.minecraft.server.v1_6_R1.EntityPlayer;
import net.minecraft.server.v1_6_R1.Navigation;
Expand All @@ -39,8 +39,9 @@ public MCTargetStrategy(NPC npc, org.bukkit.entity.Entity target, boolean aggro,
this.parameters = params;
this.handle = ((CraftLivingEntity) npc.getBukkitEntity()).getHandle();
this.target = ((CraftEntity) target).getHandle();
this.targetNavigator = this.handle instanceof EntityInsentient ? new NavigationFieldWrapper(
((EntityInsentient) this.handle).getNavigation()) : new AStarTargeter();
Navigation nav = NMS.getNavigation(this.handle);
this.targetNavigator = nav != null && !Setting.USE_NEW_PATHFINDER.asBoolean() ? new NavigationFieldWrapper(nav)
: new AStarTargeter();
this.aggro = aggro;
}

Expand Down Expand Up @@ -172,12 +173,21 @@ private NavigationFieldWrapper(Navigation navigation) {
this.k = navigation.c();
this.l = navigation.a();
try {
if (NAV_E != null)
speed = (float) ((AttributeInstance) NAV_E.get(navigation)).e();
if (NAV_J != null)
j = NAV_J.getBoolean(navigation);
if (NAV_M != null)
m = NAV_M.getBoolean(navigation);
if (navigation instanceof PlayerNavigation) {
if (P_NAV_E != null)
speed = (float) ((AttributeInstance) P_NAV_E.get(navigation)).e();
if (P_NAV_J != null)
j = P_NAV_J.getBoolean(navigation);
if (P_NAV_M != null)
m = P_NAV_M.getBoolean(navigation);
} else {
if (E_NAV_E != null)
speed = (float) ((AttributeInstance) E_NAV_E.get(navigation)).e();
if (E_NAV_J != null)
j = E_NAV_J.getBoolean(navigation);
if (E_NAV_M != null)
m = E_NAV_M.getBoolean(navigation);
}
} catch (Exception ex) {
speed = parameters.speed();
}
Expand All @@ -195,7 +205,7 @@ public void setPath() {

@Override
public void stop() {
navigation.g();
NMS.stopNavigation(navigation);
}
}

Expand All @@ -206,13 +216,17 @@ private static interface TargetNavigator {
}

private static final int ATTACK_DELAY_TICKS = 20;
private static Field E_NAV_E, E_NAV_J, E_NAV_M;
private static final Location HANDLE_LOCATION = new Location(null, 0, 0, 0);
private static Field NAV_E, NAV_J, NAV_M;
private static Field P_NAV_E, P_NAV_J, P_NAV_M;
private static final Location TARGET_LOCATION = new Location(null, 0, 0, 0);

static {
NAV_E = NMS.getField(Navigation.class, "e");
NAV_J = NMS.getField(Navigation.class, "j");
NAV_M = NMS.getField(Navigation.class, "m");
E_NAV_E = NMS.getField(Navigation.class, "e");
E_NAV_J = NMS.getField(Navigation.class, "j");
E_NAV_M = NMS.getField(Navigation.class, "m");
P_NAV_E = NMS.getField(PlayerNavigation.class, "e");
P_NAV_J = NMS.getField(PlayerNavigation.class, "j");
P_NAV_M = NMS.getField(PlayerNavigation.class, "m");
}
}
29 changes: 23 additions & 6 deletions src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
import net.citizensnpcs.util.nms.PlayerControllerLook;
import net.citizensnpcs.util.nms.PlayerControllerMove;
import net.citizensnpcs.util.nms.PlayerEntitySenses;
import net.citizensnpcs.util.nms.PlayerNavigation;
import net.minecraft.server.v1_6_R1.Connection;
import net.minecraft.server.v1_6_R1.Entity;
import net.minecraft.server.v1_6_R1.EntityPlayer;
import net.minecraft.server.v1_6_R1.EnumGamemode;
import net.minecraft.server.v1_6_R1.MathHelper;
import net.minecraft.server.v1_6_R1.MinecraftServer;
import net.minecraft.server.v1_6_R1.Navigation;
import net.minecraft.server.v1_6_R1.NetworkManager;
import net.minecraft.server.v1_6_R1.Packet;
import net.minecraft.server.v1_6_R1.Packet35EntityHeadRotation;
Expand All @@ -46,6 +48,7 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
private PlayerEntitySenses entitySenses;
private boolean gravity = true;
private int jumpTicks = 0;
private PlayerNavigation navigation;
private final CitizensNPC npc;
private final Location packetLocationCache = new Location(null, 0, 0, 0);
private int packetUpdateCount;
Expand All @@ -56,8 +59,9 @@ public EntityHumanNPC(MinecraftServer minecraftServer, World world, String strin
playerInteractManager.setGameMode(EnumGamemode.SURVIVAL);

this.npc = (CitizensNPC) npc;
if (npc != null)
if (npc != null) {
initialise(minecraftServer);
}
}

@Override
Expand Down Expand Up @@ -102,6 +106,10 @@ public PlayerControllerJump getControllerJump() {
return controllerJump;
}

public Navigation getNavigation() {
return navigation;
}

@Override
public NPC getNPC() {
return npc;
Expand Down Expand Up @@ -135,6 +143,7 @@ public boolean a() {
controllerLook = new PlayerControllerLook(this);
controllerMove = new PlayerControllerMove(this);
entitySenses = new PlayerEntitySenses(this);
navigation = new PlayerNavigation(this, world);
}

public boolean isNavigating() {
Expand All @@ -161,17 +170,18 @@ public void l_() {
motX = motY = motZ = 0;

if (navigating) {
// Navigation navigation = getNavigation();
// if (!navigation.g())
// navigation.e();
if (!NMS.isNavigationFinished(navigation)) {
NMS.updateNavigation(navigation);
}
moveOnCurrentHeading();
} else if (motX != 0 || motZ != 0 || motY != 0) {
e(0, 0); // is this necessary? it does controllable but sometimes
// players sink into the ground
}

if (noDamageTicks > 0)
if (noDamageTicks > 0) {
--noDamageTicks;
}
npc.update();
}

Expand All @@ -187,8 +197,9 @@ private void moveOnCurrentHeading() {
ba();
jumpTicks = 10;
}
} else
} else {
jumpTicks = 0;
}

be *= 0.98F;
bf *= 0.98F;
Expand All @@ -211,6 +222,7 @@ public void setTargetLook(Entity target, float yawOffset, float renderOffset) {
}

public void updateAI() {
navigation.f();
entitySenses.a();
controllerMove.c();
controllerLook.a();
Expand All @@ -233,6 +245,10 @@ private void updatePackets(boolean navigating) {
}
}

public void updatePathfindingRange(float pathfindingRange) {
this.navigation.a(pathfindingRange);
}

public static class PlayerNPC extends CraftPlayer implements NPCHolder {
private final CraftServer cserver;
private final CitizensNPC npc;
Expand Down Expand Up @@ -284,5 +300,6 @@ public void setMetadata(String metadataKey, MetadataValue newMetadataValue) {
}

private static final float EPSILON = 0.005F;

private static final Location LOADED_LOCATION = new Location(null, 0, 0, 0);
}
35 changes: 24 additions & 11 deletions src/main/java/net/citizensnpcs/util/NMS.java
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,11 @@ public static float getHeadYaw(EntityLiving handle) {
return handle.aP;
}

public static Navigation getNavigation(EntityLiving handle) {
return handle instanceof EntityInsentient ? ((EntityInsentient) handle).getNavigation()
: handle instanceof EntityHumanNPC ? ((EntityHumanNPC) handle).getNavigation() : null;
}

public static float getSpeedFor(NPC npc) {
if (!npc.isSpawned())
return DEFAULT_SPEED;
Expand All @@ -156,8 +161,8 @@ public static boolean inWater(LivingEntity entity) {
return mcEntity.G() || mcEntity.I();
}

public static boolean isSentient(LivingEntity entity) {
return !(((CraftLivingEntity) entity).getHandle() instanceof EntityInsentient);
public static boolean isNavigationFinished(Navigation navigation) {
return navigation.g();
}

public static void loadPlugins() {
Expand Down Expand Up @@ -308,6 +313,10 @@ public static org.bukkit.entity.Entity spawnCustomEntity(org.bukkit.World world,
return entity.getBukkitEntity();
}

public static void stopNavigation(Navigation navigation) {
navigation.h();
}

public static void stopNetworkThreads(NetworkManager manager) {
if (THREAD_STOPPER == null)
return;
Expand All @@ -333,7 +342,7 @@ public static void updateAI(EntityLiving entity) {
if (entity instanceof EntityInsentient) {
EntityInsentient handle = (EntityInsentient) entity;
handle.getEntitySenses().a();
handle.getNavigation().f();
NMS.updateNavigation(handle.getNavigation());
handle.getControllerMove().c();
handle.getControllerLook().a();
handle.getControllerJump().b();
Expand All @@ -342,6 +351,10 @@ public static void updateAI(EntityLiving entity) {
}
}

public static void updateNavigation(Navigation navigation) {
navigation.f();
}

public static void updateNavigationWorld(LivingEntity entity, org.bukkit.World world) {
if (NAVIGATION_WORLD_FIELD == null)
return;
Expand All @@ -358,18 +371,18 @@ public static void updateNavigationWorld(LivingEntity entity, org.bukkit.World w
}

public static void updatePathfindingRange(NPC npc, float pathfindingRange) {
if (PATHFINDING_RANGE == null || !npc.isSpawned())
if (!npc.isSpawned())
return;
EntityLiving en = ((CraftLivingEntity) npc.getBukkitEntity()).getHandle();
if (!(en instanceof EntityInsentient))
if (!(en instanceof EntityInsentient)) {
if (en instanceof EntityHumanNPC) {
((EntityHumanNPC) en).updatePathfindingRange(pathfindingRange);
}
return;
}
EntityInsentient handle = (EntityInsentient) en;
Navigation navigation = handle.getNavigation();
try {
PATHFINDING_RANGE.set(navigation, pathfindingRange);
} catch (Exception e) {
Messaging.logTr(Messages.ERROR_UPDATING_PATHFINDING_RANGE, e.getMessage());
}
navigation.a(pathfindingRange);
}

private static final float DEFAULT_SPEED = 1F;
Expand All @@ -380,8 +393,8 @@ public static void updatePathfindingRange(NPC npc, float pathfindingRange) {
private static final Field JUMP_FIELD = getField(EntityLiving.class, "bd");
private static Field NAVIGATION_WORLD_FIELD = getField(Navigation.class, "b");
private static final Location PACKET_CACHE_LOCATION = new Location(null, 0, 0, 0);
private static Field PATHFINDING_RANGE = getField(Navigation.class, "d");
private static final Random RANDOM = Util.getFastRandom();

private static Field THREAD_STOPPER = getField(NetworkManager.class, "n");
// true field above false and three synchronised lists

Expand Down
Loading

0 comments on commit ea20318

Please sign in to comment.