diff --git a/src/main/java/net/citizensnpcs/npc/CitizensNPC.java b/src/main/java/net/citizensnpcs/npc/CitizensNPC.java index 1e80fd535..521c50827 100644 --- a/src/main/java/net/citizensnpcs/npc/CitizensNPC.java +++ b/src/main/java/net/citizensnpcs/npc/CitizensNPC.java @@ -44,6 +44,7 @@ public abstract class CitizensNPC extends AbstractNPC { protected CitizensNPC(int id, String name) { super(id, name); + runnables.add(navigator); } protected abstract EntityLiving createHandle(Location loc); @@ -101,7 +102,7 @@ public abstract class CitizensNPC extends AbstractNPC { @Override public boolean isSpawned() { - return getHandle() != null; + return mcEntity != null; } public void load(final DataKey root) { @@ -229,10 +230,8 @@ public abstract class CitizensNPC extends AbstractNPC { public void update() { try { super.update(); - if (isSpawned()) { + if (isSpawned()) NMS.trySwim(getHandle()); - navigator.update(); - } } catch (Exception ex) { Messaging.logTr(Messages.EXCEPTION_UPDATING_NPC, getId(), ex.getMessage()); ex.printStackTrace(); diff --git a/src/main/java/net/citizensnpcs/npc/ai/CitizensNavigator.java b/src/main/java/net/citizensnpcs/npc/ai/CitizensNavigator.java index db5a02104..02546ce53 100644 --- a/src/main/java/net/citizensnpcs/npc/ai/CitizensNavigator.java +++ b/src/main/java/net/citizensnpcs/npc/ai/CitizensNavigator.java @@ -23,7 +23,7 @@ import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.LivingEntity; -public class CitizensNavigator implements Navigator { +public class CitizensNavigator implements Navigator, Runnable { private final NavigatorParameters defaultParams = new NavigatorParameters() .baseSpeed(UNINITIALISED_SPEED).range(Setting.DEFAULT_PATHFINDING_RANGE.asFloat()) .stationaryTicks(Setting.DEFAULT_STATIONARY_TICKS.asInt()) @@ -184,7 +184,8 @@ public class CitizensNavigator implements Navigator { Bukkit.getPluginManager().callEvent(new NavigationBeginEvent(this)); } - public void update() { + @Override + public void run() { if (!isNavigating()) return; if (!npc.isSpawned()) { diff --git a/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java b/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java index f888a8680..fb012530c 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java @@ -130,8 +130,8 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder { motX = motY = motZ = 0; NMS.updateSenses(this); - Navigation navigation = getNavigation(); if (npc.getNavigator().isNavigating()) { + Navigation navigation = getNavigation(); if (!navigation.f()) navigation.e(); moveOnCurrentHeading(); diff --git a/src/main/java/net/citizensnpcs/trait/Age.java b/src/main/java/net/citizensnpcs/trait/Age.java index 249ab3484..c7e59ab17 100644 --- a/src/main/java/net/citizensnpcs/trait/Age.java +++ b/src/main/java/net/citizensnpcs/trait/Age.java @@ -1,9 +1,7 @@ package net.citizensnpcs.trait; -import net.citizensnpcs.api.exception.NPCLoadException; import net.citizensnpcs.api.persistence.Persist; import net.citizensnpcs.api.trait.Trait; -import net.citizensnpcs.api.util.DataKey; import net.citizensnpcs.util.Messages; import net.citizensnpcs.util.Messaging; @@ -15,6 +13,7 @@ public class Age extends Trait implements Toggleable { private int age = 0; @Persist private boolean locked = true; + private Ageable ageable; public Age() { super("age"); @@ -25,41 +24,37 @@ public class Age extends Trait implements Toggleable { } private boolean isAgeable() { - return npc.getBukkitEntity() instanceof Ageable; - } - - @Override - public void load(DataKey key) throws NPCLoadException { - if (npc.isSpawned() && !(npc.getBukkitEntity() instanceof Ageable)) - throw new NPCLoadException("NPC must be ageable"); + return ageable != null; } @Override public void onSpawn() { - if (isAgeable()) { + if (npc.getBukkitEntity() instanceof Ageable) { Ageable entity = (Ageable) npc.getBukkitEntity(); entity.setAge(age); entity.setAgeLock(locked); - } + ageable = entity; + } else + ageable = null; } @Override public void run() { if (!locked && isAgeable()) - age = ((Ageable) npc.getBukkitEntity()).getAge(); + age = ageable.getAge(); } public void setAge(int age) { this.age = age; if (isAgeable()) - ((Ageable) npc.getBukkitEntity()).setAge(age); + ageable.setAge(age); } @Override public boolean toggle() { locked = !locked; if (isAgeable()) - ((Ageable) npc.getBukkitEntity()).setAgeLock(locked); + ageable.setAgeLock(locked); return locked; } diff --git a/src/main/java/net/citizensnpcs/trait/Gravity.java b/src/main/java/net/citizensnpcs/trait/Gravity.java index 72a25b735..26a440a14 100644 --- a/src/main/java/net/citizensnpcs/trait/Gravity.java +++ b/src/main/java/net/citizensnpcs/trait/Gravity.java @@ -3,7 +3,7 @@ package net.citizensnpcs.trait; import net.citizensnpcs.api.persistence.Persist; import net.citizensnpcs.api.trait.Trait; -import org.bukkit.util.Vector; +import org.bukkit.craftbukkit.entity.CraftEntity; public class Gravity extends Trait implements Toggleable { @Persist @@ -21,9 +21,8 @@ public class Gravity extends Trait implements Toggleable { public void run() { if (!npc.isSpawned() || !enabled) return; - Vector velocity = npc.getBukkitEntity().getVelocity(); - velocity.setY(Math.max(velocity.getY(), 0)); - npc.getBukkitEntity().setVelocity(velocity); + net.minecraft.server.Entity entity = ((CraftEntity) npc.getBukkitEntity()).getHandle(); + entity.motY = Math.max(0, entity.motY); } @Override diff --git a/src/main/java/net/citizensnpcs/trait/NPCSkeletonType.java b/src/main/java/net/citizensnpcs/trait/NPCSkeletonType.java index b7d1d13f1..831e6858c 100644 --- a/src/main/java/net/citizensnpcs/trait/NPCSkeletonType.java +++ b/src/main/java/net/citizensnpcs/trait/NPCSkeletonType.java @@ -6,7 +6,7 @@ import net.citizensnpcs.api.trait.Trait; import org.bukkit.entity.Skeleton; public class NPCSkeletonType extends Trait { - private boolean skeleton; + private Skeleton skeleton; @Persist private org.bukkit.entity.Skeleton.SkeletonType type = org.bukkit.entity.Skeleton.SkeletonType.NORMAL; @@ -16,13 +16,13 @@ public class NPCSkeletonType extends Trait { @Override public void onSpawn() { - skeleton = npc.getBukkitEntity() instanceof Skeleton; + skeleton = npc.getBukkitEntity() instanceof Skeleton ? (Skeleton) npc.getBukkitEntity() : null; } @Override public void run() { - if (skeleton) - ((Skeleton) npc.getBukkitEntity()).setSkeletonType(type); + if (skeleton != null) + skeleton.setSkeletonType(type); } public void setType(org.bukkit.entity.Skeleton.SkeletonType type) { diff --git a/src/main/java/net/citizensnpcs/trait/text/Text.java b/src/main/java/net/citizensnpcs/trait/text/Text.java index f050b57d2..c75f483f3 100644 --- a/src/main/java/net/citizensnpcs/trait/text/Text.java +++ b/src/main/java/net/citizensnpcs/trait/text/Text.java @@ -31,6 +31,7 @@ import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.plugin.Plugin; +import org.uncommons.maths.random.XORShiftRNG; public class Text extends Trait implements Runnable, Toggleable, Listener, ConversationAbandonedListener { private final Map cooldowns = new HashMap(); @@ -122,7 +123,7 @@ public class Text extends Trait implements Runnable, Toggleable, Listener, Conve @Override public void run() { - if (!npc.isSpawned() || !talkClose) + if (!talkClose || !npc.isSpawned()) return; List nearby = npc.getBukkitEntity().getNearbyEntities(range, range, range); for (Entity search : nearby) { @@ -140,7 +141,7 @@ public class Text extends Trait implements Runnable, Toggleable, Listener, Conve return; // Add a cooldown if the text was successfully sent Date wait = new Date(); - int secondsDelta = new Random().nextInt(Setting.TALK_CLOSE_MAXIMUM_COOLDOWN.asInt()) + int secondsDelta = RANDOM.nextInt(Setting.TALK_CLOSE_MAXIMUM_COOLDOWN.asInt()) + Setting.TALK_CLOSE_MINIMUM_COOLDOWN.asInt(); if (secondsDelta <= 0) return; @@ -150,6 +151,8 @@ public class Text extends Trait implements Runnable, Toggleable, Listener, Conve } } + private static final Random RANDOM = new XORShiftRNG(); + @Override public void save(DataKey key) { key.setBoolean("talk-close", talkClose); diff --git a/src/main/java/net/citizensnpcs/util/NMS.java b/src/main/java/net/citizensnpcs/util/NMS.java index cbc59c2ad..812d2463a 100644 --- a/src/main/java/net/citizensnpcs/util/NMS.java +++ b/src/main/java/net/citizensnpcs/util/NMS.java @@ -4,6 +4,7 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.util.List; import java.util.Map; +import java.util.Random; import java.util.Set; import java.util.WeakHashMap; @@ -34,6 +35,7 @@ import org.bukkit.entity.Player; import org.bukkit.material.Stairs; import org.bukkit.material.Step; import org.bukkit.util.Vector; +import org.uncommons.maths.random.XORShiftRNG; import com.google.common.collect.Maps; import com.google.common.collect.Sets; @@ -259,11 +261,13 @@ public class NMS { } public static void trySwim(EntityLiving handle, float power) { - if (inWater(handle) && Math.random() < 0.8F) { + if (RANDOM.nextFloat() < 0.8F && inWater(handle)) { handle.motY += power; } } + private static final Random RANDOM = new XORShiftRNG(); + public static void updateAI(EntityLiving entity) { updateSenses(entity); entity.getNavigation().e();