mirror of
https://github.com/CitizensDev/Citizens2.git
synced 2024-11-30 14:43:54 +01:00
Change navigation back to MC navigation and fix duplicate NPCs clientside
This commit is contained in:
parent
1ebbe6fe64
commit
c98162c20d
@ -22,10 +22,7 @@ import net.citizensnpcs.trait.CurrentLocation;
|
|||||||
import net.citizensnpcs.util.Messages;
|
import net.citizensnpcs.util.Messages;
|
||||||
import net.citizensnpcs.util.NMS;
|
import net.citizensnpcs.util.NMS;
|
||||||
import net.citizensnpcs.util.Util;
|
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.EntityLiving;
|
||||||
import net.minecraft.server.v1_6_R1.EntityPlayer;
|
|
||||||
import net.minecraft.server.v1_6_R1.Packet20NamedEntitySpawn;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@ -216,10 +213,6 @@ public class CitizensNPC extends AbstractNPC {
|
|||||||
trait.onSpawn();
|
trait.onSpawn();
|
||||||
getBukkitEntity().setRemoveWhenFarAway(false);
|
getBukkitEntity().setRemoveWhenFarAway(false);
|
||||||
getBukkitEntity().setCustomName(getFullName());
|
getBukkitEntity().setCustomName(getFullName());
|
||||||
if (mcEntity instanceof EntityPlayer) {
|
|
||||||
Packet20NamedEntitySpawn packet = new Packet20NamedEntitySpawn((EntityHuman) mcEntity);
|
|
||||||
NMS.sendToOnline(packet);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ public class CitizensNavigator implements Navigator, Runnable {
|
|||||||
}
|
}
|
||||||
localParams = defaultParams.clone();
|
localParams = defaultParams.clone();
|
||||||
PathStrategy newStrategy;
|
PathStrategy newStrategy;
|
||||||
if (Setting.USE_NEW_PATHFINDER.asBoolean() || NMS.isSentient(npc.getBukkitEntity())) {
|
if (Setting.USE_NEW_PATHFINDER.asBoolean()) {
|
||||||
newStrategy = new AStarNavigationStrategy(npc, target, localParams);
|
newStrategy = new AStarNavigationStrategy(npc, target, localParams);
|
||||||
} else
|
} else
|
||||||
newStrategy = new MCNavigationStrategy(npc, target, localParams);
|
newStrategy = new MCNavigationStrategy(npc, target, localParams);
|
||||||
|
@ -4,7 +4,8 @@ import net.citizensnpcs.api.ai.NavigatorParameters;
|
|||||||
import net.citizensnpcs.api.ai.TargetType;
|
import net.citizensnpcs.api.ai.TargetType;
|
||||||
import net.citizensnpcs.api.ai.event.CancelReason;
|
import net.citizensnpcs.api.ai.event.CancelReason;
|
||||||
import net.citizensnpcs.api.npc.NPC;
|
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 net.minecraft.server.v1_6_R1.Navigation;
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@ -19,15 +20,15 @@ public class MCNavigationStrategy extends AbstractPathStrategy {
|
|||||||
super(TargetType.LOCATION);
|
super(TargetType.LOCATION);
|
||||||
this.target = dest;
|
this.target = dest;
|
||||||
this.parameters = params;
|
this.parameters = params;
|
||||||
EntityInsentient handle = (EntityInsentient) ((CraftLivingEntity) npc.getBukkitEntity()).getHandle();
|
EntityLiving handle = ((CraftLivingEntity) npc.getBukkitEntity()).getHandle();
|
||||||
handle.onGround = true;
|
handle.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
|
||||||
// navigation won't execute, and calling entity.move doesn't
|
// navigation won't execute, and calling entity.move doesn't
|
||||||
// entirely fix the problem.
|
// entirely fix the problem.
|
||||||
navigation = handle.getNavigation();
|
navigation = NMS.getNavigation(handle);
|
||||||
navigation.a(parameters.avoidWater());
|
navigation.a(parameters.avoidWater());
|
||||||
navigation.a(dest.getX(), dest.getY(), dest.getZ(), parameters.speed());
|
navigation.a(dest.getX(), dest.getY(), dest.getZ(), parameters.speed());
|
||||||
if (navigation.g())
|
if (NMS.isNavigationFinished(navigation))
|
||||||
setCancelReason(CancelReason.STUCK);
|
setCancelReason(CancelReason.STUCK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +44,7 @@ public class MCNavigationStrategy extends AbstractPathStrategy {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stop() {
|
public void stop() {
|
||||||
navigation.g();
|
NMS.stopNavigation(navigation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -57,6 +58,6 @@ public class MCNavigationStrategy extends AbstractPathStrategy {
|
|||||||
return true;
|
return true;
|
||||||
navigation.a(parameters.avoidWater());
|
navigation.a(parameters.avoidWater());
|
||||||
navigation.a(parameters.speed());
|
navigation.a(parameters.speed());
|
||||||
return navigation.g();
|
return NMS.isNavigationFinished(navigation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,9 @@ import net.citizensnpcs.api.ai.event.CancelReason;
|
|||||||
import net.citizensnpcs.api.npc.NPC;
|
import net.citizensnpcs.api.npc.NPC;
|
||||||
import net.citizensnpcs.util.NMS;
|
import net.citizensnpcs.util.NMS;
|
||||||
import net.citizensnpcs.util.PlayerAnimation;
|
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.AttributeInstance;
|
||||||
import net.minecraft.server.v1_6_R1.Entity;
|
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.EntityLiving;
|
||||||
import net.minecraft.server.v1_6_R1.EntityPlayer;
|
import net.minecraft.server.v1_6_R1.EntityPlayer;
|
||||||
import net.minecraft.server.v1_6_R1.Navigation;
|
import net.minecraft.server.v1_6_R1.Navigation;
|
||||||
@ -39,8 +39,9 @@ public class MCTargetStrategy implements PathStrategy, EntityTarget {
|
|||||||
this.parameters = params;
|
this.parameters = params;
|
||||||
this.handle = ((CraftLivingEntity) npc.getBukkitEntity()).getHandle();
|
this.handle = ((CraftLivingEntity) npc.getBukkitEntity()).getHandle();
|
||||||
this.target = ((CraftEntity) target).getHandle();
|
this.target = ((CraftEntity) target).getHandle();
|
||||||
this.targetNavigator = this.handle instanceof EntityInsentient ? new NavigationFieldWrapper(
|
Navigation nav = NMS.getNavigation(this.handle);
|
||||||
((EntityInsentient) this.handle).getNavigation()) : new AStarTargeter();
|
this.targetNavigator = nav != null && !Setting.USE_NEW_PATHFINDER.asBoolean() ? new NavigationFieldWrapper(nav)
|
||||||
|
: new AStarTargeter();
|
||||||
this.aggro = aggro;
|
this.aggro = aggro;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,12 +173,21 @@ public class MCTargetStrategy implements PathStrategy, EntityTarget {
|
|||||||
this.k = navigation.c();
|
this.k = navigation.c();
|
||||||
this.l = navigation.a();
|
this.l = navigation.a();
|
||||||
try {
|
try {
|
||||||
if (NAV_E != null)
|
if (navigation instanceof PlayerNavigation) {
|
||||||
speed = (float) ((AttributeInstance) NAV_E.get(navigation)).e();
|
if (P_NAV_E != null)
|
||||||
if (NAV_J != null)
|
speed = (float) ((AttributeInstance) P_NAV_E.get(navigation)).e();
|
||||||
j = NAV_J.getBoolean(navigation);
|
if (P_NAV_J != null)
|
||||||
if (NAV_M != null)
|
j = P_NAV_J.getBoolean(navigation);
|
||||||
m = NAV_M.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) {
|
} catch (Exception ex) {
|
||||||
speed = parameters.speed();
|
speed = parameters.speed();
|
||||||
}
|
}
|
||||||
@ -195,7 +205,7 @@ public class MCTargetStrategy implements PathStrategy, EntityTarget {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stop() {
|
public void stop() {
|
||||||
navigation.g();
|
NMS.stopNavigation(navigation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,13 +216,17 @@ public class MCTargetStrategy implements PathStrategy, EntityTarget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static final int ATTACK_DELAY_TICKS = 20;
|
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 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);
|
private static final Location TARGET_LOCATION = new Location(null, 0, 0, 0);
|
||||||
|
|
||||||
static {
|
static {
|
||||||
NAV_E = NMS.getField(Navigation.class, "e");
|
E_NAV_E = NMS.getField(Navigation.class, "e");
|
||||||
NAV_J = NMS.getField(Navigation.class, "j");
|
E_NAV_J = NMS.getField(Navigation.class, "j");
|
||||||
NAV_M = NMS.getField(Navigation.class, "m");
|
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");
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -17,12 +17,16 @@ import net.citizensnpcs.util.nms.PlayerControllerJump;
|
|||||||
import net.citizensnpcs.util.nms.PlayerControllerLook;
|
import net.citizensnpcs.util.nms.PlayerControllerLook;
|
||||||
import net.citizensnpcs.util.nms.PlayerControllerMove;
|
import net.citizensnpcs.util.nms.PlayerControllerMove;
|
||||||
import net.citizensnpcs.util.nms.PlayerEntitySenses;
|
import net.citizensnpcs.util.nms.PlayerEntitySenses;
|
||||||
|
import net.citizensnpcs.util.nms.PlayerNavigation;
|
||||||
|
import net.minecraft.server.v1_6_R1.AttributeInstance;
|
||||||
import net.minecraft.server.v1_6_R1.Connection;
|
import net.minecraft.server.v1_6_R1.Connection;
|
||||||
import net.minecraft.server.v1_6_R1.Entity;
|
import net.minecraft.server.v1_6_R1.Entity;
|
||||||
import net.minecraft.server.v1_6_R1.EntityPlayer;
|
import net.minecraft.server.v1_6_R1.EntityPlayer;
|
||||||
import net.minecraft.server.v1_6_R1.EnumGamemode;
|
import net.minecraft.server.v1_6_R1.EnumGamemode;
|
||||||
|
import net.minecraft.server.v1_6_R1.GenericAttributes;
|
||||||
import net.minecraft.server.v1_6_R1.MathHelper;
|
import net.minecraft.server.v1_6_R1.MathHelper;
|
||||||
import net.minecraft.server.v1_6_R1.MinecraftServer;
|
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.NetworkManager;
|
||||||
import net.minecraft.server.v1_6_R1.Packet;
|
import net.minecraft.server.v1_6_R1.Packet;
|
||||||
import net.minecraft.server.v1_6_R1.Packet35EntityHeadRotation;
|
import net.minecraft.server.v1_6_R1.Packet35EntityHeadRotation;
|
||||||
@ -46,6 +50,7 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
|
|||||||
private PlayerEntitySenses entitySenses;
|
private PlayerEntitySenses entitySenses;
|
||||||
private boolean gravity = true;
|
private boolean gravity = true;
|
||||||
private int jumpTicks = 0;
|
private int jumpTicks = 0;
|
||||||
|
private PlayerNavigation navigation;
|
||||||
private final CitizensNPC npc;
|
private final CitizensNPC npc;
|
||||||
private final Location packetLocationCache = new Location(null, 0, 0, 0);
|
private final Location packetLocationCache = new Location(null, 0, 0, 0);
|
||||||
private int packetUpdateCount;
|
private int packetUpdateCount;
|
||||||
@ -56,9 +61,10 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
|
|||||||
playerInteractManager.setGameMode(EnumGamemode.SURVIVAL);
|
playerInteractManager.setGameMode(EnumGamemode.SURVIVAL);
|
||||||
|
|
||||||
this.npc = (CitizensNPC) npc;
|
this.npc = (CitizensNPC) npc;
|
||||||
if (npc != null)
|
if (npc != null) {
|
||||||
initialise(minecraftServer);
|
initialise(minecraftServer);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void collide(net.minecraft.server.v1_6_R1.Entity entity) {
|
public void collide(net.minecraft.server.v1_6_R1.Entity entity) {
|
||||||
@ -102,6 +108,10 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
|
|||||||
return controllerJump;
|
return controllerJump;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Navigation getNavigation() {
|
||||||
|
return navigation;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NPC getNPC() {
|
public NPC getNPC() {
|
||||||
return npc;
|
return npc;
|
||||||
@ -131,10 +141,16 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
|
|||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
// swallow
|
// swallow
|
||||||
}
|
}
|
||||||
|
AttributeInstance range = this.aT().a(GenericAttributes.b);
|
||||||
|
if (range == null) {
|
||||||
|
range = this.aT().b(GenericAttributes.b);
|
||||||
|
range.a(16D);
|
||||||
|
}
|
||||||
controllerJump = new PlayerControllerJump(this);
|
controllerJump = new PlayerControllerJump(this);
|
||||||
controllerLook = new PlayerControllerLook(this);
|
controllerLook = new PlayerControllerLook(this);
|
||||||
controllerMove = new PlayerControllerMove(this);
|
controllerMove = new PlayerControllerMove(this);
|
||||||
entitySenses = new PlayerEntitySenses(this);
|
entitySenses = new PlayerEntitySenses(this);
|
||||||
|
navigation = new PlayerNavigation(this, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isNavigating() {
|
public boolean isNavigating() {
|
||||||
@ -161,17 +177,18 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
|
|||||||
motX = motY = motZ = 0;
|
motX = motY = motZ = 0;
|
||||||
|
|
||||||
if (navigating) {
|
if (navigating) {
|
||||||
// Navigation navigation = getNavigation();
|
if (!NMS.isNavigationFinished(navigation)) {
|
||||||
// if (!navigation.g())
|
NMS.updateNavigation(navigation);
|
||||||
// navigation.e();
|
}
|
||||||
moveOnCurrentHeading();
|
moveOnCurrentHeading();
|
||||||
} else if (motX != 0 || motZ != 0 || motY != 0) {
|
} else if (motX != 0 || motZ != 0 || motY != 0) {
|
||||||
e(0, 0); // is this necessary? it does controllable but sometimes
|
e(0, 0); // is this necessary? it does controllable but sometimes
|
||||||
// players sink into the ground
|
// players sink into the ground
|
||||||
}
|
}
|
||||||
|
|
||||||
if (noDamageTicks > 0)
|
if (noDamageTicks > 0) {
|
||||||
--noDamageTicks;
|
--noDamageTicks;
|
||||||
|
}
|
||||||
npc.update();
|
npc.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,8 +204,9 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
|
|||||||
ba();
|
ba();
|
||||||
jumpTicks = 10;
|
jumpTicks = 10;
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
jumpTicks = 0;
|
jumpTicks = 0;
|
||||||
|
}
|
||||||
|
|
||||||
be *= 0.98F;
|
be *= 0.98F;
|
||||||
bf *= 0.98F;
|
bf *= 0.98F;
|
||||||
@ -211,6 +229,7 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void updateAI() {
|
public void updateAI() {
|
||||||
|
navigation.f();
|
||||||
entitySenses.a();
|
entitySenses.a();
|
||||||
controllerMove.c();
|
controllerMove.c();
|
||||||
controllerLook.a();
|
controllerLook.a();
|
||||||
@ -233,6 +252,10 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updatePathfindingRange(float pathfindingRange) {
|
||||||
|
this.navigation.a(pathfindingRange);
|
||||||
|
}
|
||||||
|
|
||||||
public static class PlayerNPC extends CraftPlayer implements NPCHolder {
|
public static class PlayerNPC extends CraftPlayer implements NPCHolder {
|
||||||
private final CraftServer cserver;
|
private final CraftServer cserver;
|
||||||
private final CitizensNPC npc;
|
private final CitizensNPC npc;
|
||||||
@ -284,5 +307,6 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static final float EPSILON = 0.005F;
|
private static final float EPSILON = 0.005F;
|
||||||
|
|
||||||
private static final Location LOADED_LOCATION = new Location(null, 0, 0, 0);
|
private static final Location LOADED_LOCATION = new Location(null, 0, 0, 0);
|
||||||
}
|
}
|
@ -142,6 +142,11 @@ public class NMS {
|
|||||||
return handle.aP;
|
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) {
|
public static float getSpeedFor(NPC npc) {
|
||||||
if (!npc.isSpawned())
|
if (!npc.isSpawned())
|
||||||
return DEFAULT_SPEED;
|
return DEFAULT_SPEED;
|
||||||
@ -156,8 +161,8 @@ public class NMS {
|
|||||||
return mcEntity.G() || mcEntity.I();
|
return mcEntity.G() || mcEntity.I();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSentient(LivingEntity entity) {
|
public static boolean isNavigationFinished(Navigation navigation) {
|
||||||
return !(((CraftLivingEntity) entity).getHandle() instanceof EntityInsentient);
|
return navigation.g();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void loadPlugins() {
|
public static void loadPlugins() {
|
||||||
@ -308,6 +313,10 @@ public class NMS {
|
|||||||
return entity.getBukkitEntity();
|
return entity.getBukkitEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void stopNavigation(Navigation navigation) {
|
||||||
|
navigation.h();
|
||||||
|
}
|
||||||
|
|
||||||
public static void stopNetworkThreads(NetworkManager manager) {
|
public static void stopNetworkThreads(NetworkManager manager) {
|
||||||
if (THREAD_STOPPER == null)
|
if (THREAD_STOPPER == null)
|
||||||
return;
|
return;
|
||||||
@ -333,7 +342,7 @@ public class NMS {
|
|||||||
if (entity instanceof EntityInsentient) {
|
if (entity instanceof EntityInsentient) {
|
||||||
EntityInsentient handle = (EntityInsentient) entity;
|
EntityInsentient handle = (EntityInsentient) entity;
|
||||||
handle.getEntitySenses().a();
|
handle.getEntitySenses().a();
|
||||||
handle.getNavigation().f();
|
NMS.updateNavigation(handle.getNavigation());
|
||||||
handle.getControllerMove().c();
|
handle.getControllerMove().c();
|
||||||
handle.getControllerLook().a();
|
handle.getControllerLook().a();
|
||||||
handle.getControllerJump().b();
|
handle.getControllerJump().b();
|
||||||
@ -342,6 +351,10 @@ public class NMS {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void updateNavigation(Navigation navigation) {
|
||||||
|
navigation.f();
|
||||||
|
}
|
||||||
|
|
||||||
public static void updateNavigationWorld(LivingEntity entity, org.bukkit.World world) {
|
public static void updateNavigationWorld(LivingEntity entity, org.bukkit.World world) {
|
||||||
if (NAVIGATION_WORLD_FIELD == null)
|
if (NAVIGATION_WORLD_FIELD == null)
|
||||||
return;
|
return;
|
||||||
@ -358,18 +371,18 @@ public class NMS {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void updatePathfindingRange(NPC npc, float pathfindingRange) {
|
public static void updatePathfindingRange(NPC npc, float pathfindingRange) {
|
||||||
if (PATHFINDING_RANGE == null || !npc.isSpawned())
|
if (!npc.isSpawned())
|
||||||
return;
|
return;
|
||||||
EntityLiving en = ((CraftLivingEntity) npc.getBukkitEntity()).getHandle();
|
EntityLiving en = ((CraftLivingEntity) npc.getBukkitEntity()).getHandle();
|
||||||
if (!(en instanceof EntityInsentient))
|
if (!(en instanceof EntityInsentient)) {
|
||||||
|
if (en instanceof EntityHumanNPC) {
|
||||||
|
((EntityHumanNPC) en).updatePathfindingRange(pathfindingRange);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
EntityInsentient handle = (EntityInsentient) en;
|
EntityInsentient handle = (EntityInsentient) en;
|
||||||
Navigation navigation = handle.getNavigation();
|
Navigation navigation = handle.getNavigation();
|
||||||
try {
|
navigation.a(pathfindingRange);
|
||||||
PATHFINDING_RANGE.set(navigation, pathfindingRange);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Messaging.logTr(Messages.ERROR_UPDATING_PATHFINDING_RANGE, e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final float DEFAULT_SPEED = 1F;
|
private static final float DEFAULT_SPEED = 1F;
|
||||||
@ -380,8 +393,8 @@ public class NMS {
|
|||||||
private static final Field JUMP_FIELD = getField(EntityLiving.class, "bd");
|
private static final Field JUMP_FIELD = getField(EntityLiving.class, "bd");
|
||||||
private static Field NAVIGATION_WORLD_FIELD = getField(Navigation.class, "b");
|
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 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 final Random RANDOM = Util.getFastRandom();
|
||||||
|
|
||||||
private static Field THREAD_STOPPER = getField(NetworkManager.class, "n");
|
private static Field THREAD_STOPPER = getField(NetworkManager.class, "n");
|
||||||
// true field above false and three synchronised lists
|
// true field above false and three synchronised lists
|
||||||
|
|
||||||
|
389
src/main/java/net/citizensnpcs/util/nms/PlayerNavigation.java
Normal file
389
src/main/java/net/citizensnpcs/util/nms/PlayerNavigation.java
Normal file
@ -0,0 +1,389 @@
|
|||||||
|
package net.citizensnpcs.util.nms;
|
||||||
|
|
||||||
|
import net.citizensnpcs.npc.entity.EntityHumanNPC;
|
||||||
|
import net.minecraft.server.v1_6_R1.AttributeInstance;
|
||||||
|
import net.minecraft.server.v1_6_R1.Block;
|
||||||
|
import net.minecraft.server.v1_6_R1.Entity;
|
||||||
|
import net.minecraft.server.v1_6_R1.EntityInsentient;
|
||||||
|
import net.minecraft.server.v1_6_R1.GenericAttributes;
|
||||||
|
import net.minecraft.server.v1_6_R1.IBlockAccess;
|
||||||
|
import net.minecraft.server.v1_6_R1.Material;
|
||||||
|
import net.minecraft.server.v1_6_R1.MathHelper;
|
||||||
|
import net.minecraft.server.v1_6_R1.Navigation;
|
||||||
|
import net.minecraft.server.v1_6_R1.PathEntity;
|
||||||
|
import net.minecraft.server.v1_6_R1.PathPoint;
|
||||||
|
import net.minecraft.server.v1_6_R1.Vec3D;
|
||||||
|
import net.minecraft.server.v1_6_R1.World;
|
||||||
|
|
||||||
|
public class PlayerNavigation extends Navigation {
|
||||||
|
private final EntityHumanNPC a;
|
||||||
|
private final World b;
|
||||||
|
private PathEntity c;
|
||||||
|
private double d;
|
||||||
|
private final AttributeInstance e;
|
||||||
|
private boolean f;
|
||||||
|
private int g;
|
||||||
|
private int h;
|
||||||
|
private final Vec3D i = Vec3D.a(0.0D, 0.0D, 0.0D);
|
||||||
|
private boolean j = true;
|
||||||
|
private boolean k;
|
||||||
|
private boolean l;
|
||||||
|
private boolean m;
|
||||||
|
|
||||||
|
public PlayerNavigation(EntityHumanNPC entityinsentient, World world) {
|
||||||
|
super(getDummyInsentient(entityinsentient), world);
|
||||||
|
this.a = entityinsentient;
|
||||||
|
this.b = world;
|
||||||
|
this.e = entityinsentient.a(GenericAttributes.b);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean a() {
|
||||||
|
return this.l;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void a(boolean flag) {
|
||||||
|
this.l = flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void a(double d0) {
|
||||||
|
this.d = d0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PathEntity a(double d0, double d1, double d2) {
|
||||||
|
return !this.l() ? null : this.b.a(this.a, MathHelper.floor(d0), (int) d1, MathHelper.floor(d2), this.d(),
|
||||||
|
this.j, this.k, this.l, this.m);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean a(double d0, double d1, double d2, double d3) {
|
||||||
|
PathEntity pathentity = this.a(MathHelper.floor(d0), ((int) d1), MathHelper.floor(d2));
|
||||||
|
|
||||||
|
return this.a(pathentity, d3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PathEntity a(Entity entity) {
|
||||||
|
return !this.l() ? null : this.b.findPath(this.a, entity, this.d(), this.j, this.k, this.l, this.m);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean a(Entity entity, double d0) {
|
||||||
|
PathEntity pathentity = this.a(entity);
|
||||||
|
|
||||||
|
return pathentity != null ? this.a(pathentity, d0) : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean a(int i, int j, int k, int l, int i1, int j1, Vec3D vec3d, double d0, double d1) {
|
||||||
|
int k1 = i - l / 2;
|
||||||
|
int l1 = k - j1 / 2;
|
||||||
|
|
||||||
|
if (!this.b(k1, j, l1, l, i1, j1, vec3d, d0, d1)) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
for (int i2 = k1; i2 < k1 + l; ++i2) {
|
||||||
|
for (int j2 = l1; j2 < l1 + j1; ++j2) {
|
||||||
|
double d2 = i2 + 0.5D - vec3d.c;
|
||||||
|
double d3 = j2 + 0.5D - vec3d.e;
|
||||||
|
|
||||||
|
if (d2 * d0 + d3 * d1 >= 0.0D) {
|
||||||
|
int k2 = this.b.getTypeId(i2, j - 1, j2);
|
||||||
|
|
||||||
|
if (k2 <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Material material = Block.byId[k2].material;
|
||||||
|
|
||||||
|
if (material == Material.WATER && !this.a.G()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (material == Material.LAVA) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean a(PathEntity pathentity, double d0) {
|
||||||
|
if (pathentity == null) {
|
||||||
|
this.c = null;
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
if (!pathentity.a(this.c)) {
|
||||||
|
this.c = pathentity;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.f) {
|
||||||
|
this.n();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.c.d() == 0) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
this.d = d0;
|
||||||
|
Vec3D vec3d = this.j();
|
||||||
|
|
||||||
|
this.h = this.g;
|
||||||
|
this.i.c = vec3d.c;
|
||||||
|
this.i.d = vec3d.d;
|
||||||
|
this.i.e = vec3d.e;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean a(Vec3D vec3d, Vec3D vec3d1, int i, int j, int k) {
|
||||||
|
int l = MathHelper.floor(vec3d.c);
|
||||||
|
int i1 = MathHelper.floor(vec3d.e);
|
||||||
|
double d0 = vec3d1.c - vec3d.c;
|
||||||
|
double d1 = vec3d1.e - vec3d.e;
|
||||||
|
double d2 = d0 * d0 + d1 * d1;
|
||||||
|
|
||||||
|
if (d2 < 1.0E-8D) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
double d3 = 1.0D / Math.sqrt(d2);
|
||||||
|
|
||||||
|
d0 *= d3;
|
||||||
|
d1 *= d3;
|
||||||
|
i += 2;
|
||||||
|
k += 2;
|
||||||
|
if (!this.a(l, (int) vec3d.d, i1, i, j, k, vec3d, d0, d1)) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
i -= 2;
|
||||||
|
k -= 2;
|
||||||
|
double d4 = 1.0D / Math.abs(d0);
|
||||||
|
double d5 = 1.0D / Math.abs(d1);
|
||||||
|
double d6 = l * 1 - vec3d.c;
|
||||||
|
double d7 = i1 * 1 - vec3d.e;
|
||||||
|
|
||||||
|
if (d0 >= 0.0D) {
|
||||||
|
++d6;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d1 >= 0.0D) {
|
||||||
|
++d7;
|
||||||
|
}
|
||||||
|
|
||||||
|
d6 /= d0;
|
||||||
|
d7 /= d1;
|
||||||
|
int j1 = d0 < 0.0D ? -1 : 1;
|
||||||
|
int k1 = d1 < 0.0D ? -1 : 1;
|
||||||
|
int l1 = MathHelper.floor(vec3d1.c);
|
||||||
|
int i2 = MathHelper.floor(vec3d1.e);
|
||||||
|
int j2 = l1 - l;
|
||||||
|
int k2 = i2 - i1;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (j2 * j1 <= 0 && k2 * k1 <= 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d6 < d7) {
|
||||||
|
d6 += d4;
|
||||||
|
l += j1;
|
||||||
|
j2 = l1 - l;
|
||||||
|
} else {
|
||||||
|
d7 += d5;
|
||||||
|
i1 += k1;
|
||||||
|
k2 = i2 - i1;
|
||||||
|
}
|
||||||
|
} while (this.a(l, (int) vec3d.d, i1, i, j, k, vec3d, d0, d1));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void b(boolean flag) {
|
||||||
|
this.k = flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean b(int i, int j, int k, int l, int i1, int j1, Vec3D vec3d, double d0, double d1) {
|
||||||
|
for (int k1 = i; k1 < i + l; ++k1) {
|
||||||
|
for (int l1 = j; l1 < j + i1; ++l1) {
|
||||||
|
for (int i2 = k; i2 < k + j1; ++i2) {
|
||||||
|
double d2 = k1 + 0.5D - vec3d.c;
|
||||||
|
double d3 = i2 + 0.5D - vec3d.e;
|
||||||
|
|
||||||
|
if (d2 * d0 + d3 * d1 >= 0.0D) {
|
||||||
|
int j2 = this.b.getTypeId(k1, l1, i2);
|
||||||
|
|
||||||
|
if (j2 > 0 && !Block.byId[j2].b((IBlockAccess) this.b, k1, l1, i2)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean c() {
|
||||||
|
return this.k;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void c(boolean flag) {
|
||||||
|
this.j = flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float d() {
|
||||||
|
return (float) this.e.e();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void d(boolean flag) {
|
||||||
|
this.f = flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PathEntity e() {
|
||||||
|
return this.c;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void e(boolean flag) {
|
||||||
|
this.m = flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void f() {
|
||||||
|
++this.g;
|
||||||
|
if (!this.g()) {
|
||||||
|
if (this.l()) {
|
||||||
|
this.i();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.g()) {
|
||||||
|
Vec3D vec3d = this.c.a(this.a);
|
||||||
|
|
||||||
|
if (vec3d != null) {
|
||||||
|
this.a.setMoveDestination(vec3d.c, vec3d.d, vec3d.e, (float) this.d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean g() {
|
||||||
|
return this.c == null || this.c.b();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void h() {
|
||||||
|
this.c = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void i() {
|
||||||
|
Vec3D vec3d = this.j();
|
||||||
|
int i = this.c.d();
|
||||||
|
|
||||||
|
for (int j = this.c.e(); j < this.c.d(); ++j) {
|
||||||
|
if (this.c.a(j).b != (int) vec3d.d) {
|
||||||
|
i = j;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float f = this.a.width * this.a.width;
|
||||||
|
|
||||||
|
int k;
|
||||||
|
|
||||||
|
for (k = this.c.e(); k < i; ++k) {
|
||||||
|
if (vec3d.distanceSquared(this.c.a(this.a, k)) < f) {
|
||||||
|
this.c.c(k + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
k = MathHelper.f(this.a.width);
|
||||||
|
int l = (int) this.a.length + 1;
|
||||||
|
int i1 = k;
|
||||||
|
|
||||||
|
for (int j1 = i - 1; j1 >= this.c.e(); --j1) {
|
||||||
|
if (this.a(vec3d, this.c.a(this.a, j1), k, l, i1)) {
|
||||||
|
this.c.c(j1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.g - this.h > 100) {
|
||||||
|
if (vec3d.distanceSquared(this.i) < 2.25D) {
|
||||||
|
this.h();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.h = this.g;
|
||||||
|
this.i.c = vec3d.c;
|
||||||
|
this.i.d = vec3d.d;
|
||||||
|
this.i.e = vec3d.e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Vec3D j() {
|
||||||
|
return this.b.getVec3DPool().create(this.a.locX, this.k(), this.a.locZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int k() {
|
||||||
|
if (this.a.G() && this.m) {
|
||||||
|
int i = (int) this.a.boundingBox.b;
|
||||||
|
int j = this.b.getTypeId(MathHelper.floor(this.a.locX), i, MathHelper.floor(this.a.locZ));
|
||||||
|
int k = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (j != Block.WATER.id && j != Block.STATIONARY_WATER.id) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
++i;
|
||||||
|
j = this.b.getTypeId(MathHelper.floor(this.a.locX), i, MathHelper.floor(this.a.locZ));
|
||||||
|
++k;
|
||||||
|
} while (k <= 16);
|
||||||
|
|
||||||
|
return (int) this.a.boundingBox.b;
|
||||||
|
} else {
|
||||||
|
return (int) (this.a.boundingBox.b + 0.5D);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean l() {
|
||||||
|
return this.a.onGround || this.m && this.m();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean m() {
|
||||||
|
return this.a.G() || this.a.I();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void n() {
|
||||||
|
if (!this.b
|
||||||
|
.l(MathHelper.floor(this.a.locX), (int) (this.a.boundingBox.b + 0.5D), MathHelper.floor(this.a.locZ))) {
|
||||||
|
for (int i = 0; i < this.c.d(); ++i) {
|
||||||
|
PathPoint pathpoint = this.c.a(i);
|
||||||
|
|
||||||
|
if (this.b.l(pathpoint.a, pathpoint.b, pathpoint.c)) {
|
||||||
|
this.c.b(i - 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static EntityInsentient getDummyInsentient(EntityHumanNPC from) {
|
||||||
|
return new EntityInsentient(null) {
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user