diff --git a/src/main/java/net/citizensnpcs/Citizens.java b/src/main/java/net/citizensnpcs/Citizens.java index 794909a86..a9431cacf 100644 --- a/src/main/java/net/citizensnpcs/Citizens.java +++ b/src/main/java/net/citizensnpcs/Citizens.java @@ -210,17 +210,9 @@ public class Citizens extends JavaPlugin implements CitizensPlugin { CitizensAPI.setImplementation(this); getServer().getPluginManager().registerEvents(new EventListen(), this); + if (Setting.NPC_COST.asDouble() > 0) { - try { - RegisteredServiceProvider provider = Bukkit.getServicesManager().getRegistration( - Economy.class); - if (provider != null && provider.getProvider() != null) { - Economy economy = provider.getProvider(); - Bukkit.getPluginManager().registerEvents(new PaymentListener(economy), this); - } - } catch (NoClassDefFoundError e) { - Messaging.log("Unable to use economy handling. Has Vault been enabled?"); - } + setupEconomy(); } registerCommands(); @@ -244,6 +236,19 @@ public class Citizens extends JavaPlugin implements CitizensPlugin { } } + private void setupEconomy() { + try { + RegisteredServiceProvider provider = Bukkit.getServicesManager().getRegistration( + Economy.class); + if (provider != null && provider.getProvider() != null) { + Economy economy = provider.getProvider(); + Bukkit.getPluginManager().registerEvents(new PaymentListener(economy), this); + } + } catch (NoClassDefFoundError e) { + Messaging.log("Unable to use economy handling. Has Vault been enabled?"); + } + } + @Override public void onImplementationChanged() { Messaging.severe("Citizens implementation changed, disabling plugin."); diff --git a/src/main/java/net/citizensnpcs/EventListen.java b/src/main/java/net/citizensnpcs/EventListen.java index d32519d77..dfe40b5a8 100644 --- a/src/main/java/net/citizensnpcs/EventListen.java +++ b/src/main/java/net/citizensnpcs/EventListen.java @@ -55,6 +55,10 @@ public class EventListen implements Listener { private final NPCRegistry npcRegistry = CitizensAPI.getNPCRegistry(); private final ListMultimap toRespawn = ArrayListMultimap.create(); + public EventListen() { + instance = this; + } + /* * Chunk events */ @@ -283,4 +287,12 @@ public class EventListen implements Listener { return prime * (prime + x) + z; } } + + public static void add(Location loc, int id) { + if (instance == null) + return; + instance.toRespawn.put(instance.toCoord(loc.getChunk()), id); + } + + private static EventListen instance; } \ No newline at end of file diff --git a/src/main/java/net/citizensnpcs/npc/CitizensNPC.java b/src/main/java/net/citizensnpcs/npc/CitizensNPC.java index b3b5a61b0..1283bcb0c 100644 --- a/src/main/java/net/citizensnpcs/npc/CitizensNPC.java +++ b/src/main/java/net/citizensnpcs/npc/CitizensNPC.java @@ -1,5 +1,6 @@ package net.citizensnpcs.npc; +import net.citizensnpcs.EventListen; import net.citizensnpcs.api.CitizensAPI; import net.citizensnpcs.api.ai.Navigator; import net.citizensnpcs.api.event.NPCDespawnEvent; @@ -132,15 +133,25 @@ public abstract class CitizensNPC extends AbstractNPC { Messaging.debug("NPC (ID: " + getId() + ") is already spawned."); return false; } - NPCSpawnEvent spawnEvent = new NPCSpawnEvent(this, loc); - Bukkit.getPluginManager().callEvent(spawnEvent); - if (spawnEvent.isCancelled()) - return false; mcEntity = createHandle(loc); - mcEntity.world.addEntity(mcEntity, SpawnReason.CUSTOM); + boolean couldSpawn = mcEntity.world.addEntity(mcEntity, SpawnReason.CUSTOM); + if (!couldSpawn) { + // we need to wait for a chunk load before trying to spawn + mcEntity = null; + EventListen.add(loc, getId()); + return true; + } mcEntity.world.players.remove(mcEntity); + + NPCSpawnEvent spawnEvent = new NPCSpawnEvent(this, loc); + Bukkit.getPluginManager().callEvent(spawnEvent); + if (spawnEvent.isCancelled()) { + mcEntity = null; + return false; + } + getBukkitEntity().setMetadata(NPC_METADATA_MARKER, new FixedMetadataValue(CitizensAPI.getPlugin(), true)); diff --git a/src/main/java/net/citizensnpcs/npc/ai/MCTargetStrategy.java b/src/main/java/net/citizensnpcs/npc/ai/MCTargetStrategy.java index 8fcba133f..b2e5b4773 100644 --- a/src/main/java/net/citizensnpcs/npc/ai/MCTargetStrategy.java +++ b/src/main/java/net/citizensnpcs/npc/ai/MCTargetStrategy.java @@ -5,6 +5,7 @@ import net.citizensnpcs.api.ai.NavigatorParameters; import net.citizensnpcs.api.ai.TargetType; import net.citizensnpcs.api.ai.event.CancelReason; import net.citizensnpcs.npc.CitizensNPC; +import net.citizensnpcs.util.NMS; import net.citizensnpcs.util.Util; import net.minecraft.server.EntityLiving; import net.minecraft.server.EntityMonster; @@ -90,12 +91,12 @@ public class MCTargetStrategy implements PathStrategy, EntityTarget { } if (cancelReason != null) return true; + navigation.a(parameters.avoidWater()); navigation.a(target, parameters.speed()); - handle.getControllerLook().a(target, 10.0F, handle.bf()); + NMS.look(handle.getControllerLook(), handle, target); if (aggro && canAttack()) { if (handle instanceof EntityMonster) { - ((EntityMonster) handle).k(target); - // the cast is necessary to resolve overloaded method a + NMS.attack(handle, target); } else if (handle instanceof EntityPlayer) { EntityPlayer humanHandle = (EntityPlayer) handle; humanHandle.attack(target); diff --git a/src/main/java/net/citizensnpcs/util/NMS.java b/src/main/java/net/citizensnpcs/util/NMS.java index 3b11c1bc1..09168a5e9 100644 --- a/src/main/java/net/citizensnpcs/util/NMS.java +++ b/src/main/java/net/citizensnpcs/util/NMS.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.Map; import net.citizensnpcs.npc.CitizensNPC; +import net.minecraft.server.ControllerLook; import net.minecraft.server.Entity; import net.minecraft.server.EntityLiving; import net.minecraft.server.EntityTypes; @@ -159,4 +160,12 @@ public class NMS { } catch (Exception e) { } } + + public static void attack(EntityLiving handle, EntityLiving target) { + handle.k(target); + } + + public static void look(ControllerLook controllerLook, EntityLiving handle, EntityLiving target) { + controllerLook.a(target, 10.0F, handle.bf()); + } }