Change Navigation world when the entity changes world

This commit is contained in:
fullwall 2012-09-22 16:09:40 +08:00
parent 87063e9e60
commit 3d4387b119
2 changed files with 30 additions and 4 deletions

View File

@ -20,6 +20,7 @@ import net.citizensnpcs.api.trait.trait.Owner;
import net.citizensnpcs.editor.Editor;
import net.citizensnpcs.npc.entity.EntityHumanNPC;
import net.citizensnpcs.trait.CurrentLocation;
import net.citizensnpcs.util.NMS;
import net.minecraft.server.EntityPlayer;
import org.bukkit.Bukkit;
@ -40,6 +41,7 @@ import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.entity.EntityTargetEvent;
import org.bukkit.event.entity.EntityTeleportEvent;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerQuitEvent;
@ -90,6 +92,15 @@ public class EventListen implements Listener {
}
}
@EventHandler(ignoreCancelled = true)
public void onEntityChangedWorld(EntityTeleportEvent event) {
if (event.getFrom() == null || event.getTo() == null)
return;
if (event.getFrom().getWorld() == event.getTo().getWorld() || !npcRegistry.isNPC(event.getEntity()))
return;
NMS.updateNavigationWorld(event.getEntity(), event.getTo().getWorld());
}
/*
* Entity events
*/
@ -170,8 +181,8 @@ public class EventListen implements Listener {
EntityPlayer handle = ((CraftPlayer) event.getPlayer()).getHandle();
if (!(handle instanceof EntityHumanNPC))
return;
((CraftServer) Bukkit.getServer()).getHandle().players.remove(handle);
if (Setting.REMOVE_PLAYERS_FROM_PLAYER_LIST.asBoolean())
((CraftServer) Bukkit.getServer()).getHandle().players.remove(handle);
// on teleport, player NPCs are added to the server player list. this is
// undesirable as player NPCs are not real players and confuse plugins.
}

View File

@ -12,8 +12,12 @@ import net.minecraft.server.EntityTypes;
import net.minecraft.server.Navigation;
import net.minecraft.server.NetworkManager;
import net.minecraft.server.PathfinderGoalSelector;
import net.minecraft.server.World;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.entity.CraftLivingEntity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import com.google.common.collect.Maps;
@ -29,10 +33,9 @@ public class NMS {
private static Field GOAL_FIELD;
private static Field LAND_SPEED_MODIFIER_FIELD;
private static final Map<EntityType, Float> MOVEMENT_SPEEDS = Maps.newEnumMap(EntityType.class);
private static Field NAVIGATION_WORLD_FIELD;
private static Field PATHFINDING_RANGE;
private static Field SPEED_FIELD;
private static Field THREAD_STOPPER;
public static void attack(EntityLiving handle, EntityLiving target) {
@ -125,6 +128,17 @@ public class NMS {
entity.getControllerJump().b();
}
public static void updateNavigationWorld(org.bukkit.entity.Entity entity, org.bukkit.World world) {
if (NAVIGATION_WORLD_FIELD == null || !(entity instanceof LivingEntity))
return;
EntityLiving handle = ((CraftLivingEntity) entity).getHandle();
World worldHandle = ((CraftWorld) world).getHandle();
try {
NAVIGATION_WORLD_FIELD.set(handle.getNavigation(), worldHandle);
} catch (Exception e) {
}
}
public static void updatePathfindingRange(CitizensNPC npc, float pathfindingRange) {
if (PATHFINDING_RANGE == null)
return;
@ -155,6 +169,7 @@ public class NMS {
LAND_SPEED_MODIFIER_FIELD = getField(EntityLiving.class, "bB");
SPEED_FIELD = getField(EntityLiving.class, "bw");
NAVIGATION_WORLD_FIELD = getField(Navigation.class, "b");
PATHFINDING_RANGE = getField(Navigation.class, "e");
GOAL_FIELD = getField(PathfinderGoalSelector.class, "a");