diff --git a/pom.xml b/pom.xml
index 82acff50e..82676af7b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -11,7 +11,7 @@
UTF-8
- 1.2.5-R1.2-SNAPSHOT
+ 1.2.5-R4.1-SNAPSHOT
2.0-SNAPSHOT
Unknown
diff --git a/src/main/java/net/citizensnpcs/Citizens.java b/src/main/java/net/citizensnpcs/Citizens.java
index ee0212885..bbf7b733e 100644
--- a/src/main/java/net/citizensnpcs/Citizens.java
+++ b/src/main/java/net/citizensnpcs/Citizens.java
@@ -15,7 +15,7 @@ import net.citizensnpcs.api.npc.NPCRegistry;
import net.citizensnpcs.api.scripting.EventRegistrar;
import net.citizensnpcs.api.scripting.ObjectProvider;
import net.citizensnpcs.api.scripting.ScriptCompiler;
-import net.citizensnpcs.api.trait.TraitManager;
+import net.citizensnpcs.api.trait.TraitFactory;
import net.citizensnpcs.api.util.DataKey;
import net.citizensnpcs.api.util.DatabaseStorage;
import net.citizensnpcs.api.util.NBTStorage;
@@ -36,7 +36,7 @@ import net.citizensnpcs.command.exception.WrappedCommandException;
import net.citizensnpcs.editor.Editor;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.CitizensNPCRegistry;
-import net.citizensnpcs.npc.CitizensTraitManager;
+import net.citizensnpcs.npc.CitizensTraitFactory;
import net.citizensnpcs.npc.NPCSelector;
import net.citizensnpcs.util.Messaging;
import net.citizensnpcs.util.StringHelper;
@@ -48,6 +48,7 @@ import org.bukkit.command.CommandSender;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
+import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import com.google.common.collect.Iterables;
@@ -60,7 +61,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
private CitizensNPCRegistry npcRegistry;
private Storage saves; // TODO: refactor this, it's used in too many places
private NPCSelector selector;
- private CitizensTraitManager traitManager;
+ private CitizensTraitFactory traitFactory;
private void despawnNPCs() {
Iterator itr = npcRegistry.iterator();
@@ -90,8 +91,8 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
}
@Override
- public TraitManager getTraitManager() {
- return traitManager;
+ public TraitFactory getTraitFactory() {
+ return traitFactory;
}
@Override
@@ -171,7 +172,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
setupStorage();
npcRegistry = new CitizensNPCRegistry(saves);
- traitManager = new CitizensTraitManager();
+ traitFactory = new CitizensTraitFactory();
selector = new NPCSelector(this);
CitizensAPI.setImplementation(this);
@@ -188,31 +189,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
public void run() {
setupNPCs();
startMetrics();
- }
-
- private void startMetrics() {
- new Thread() {
- @Override
- public void run() {
- try {
- Metrics metrics = new Metrics(Citizens.this);
- if (metrics.isOptOut())
- return;
- metrics.addCustomData(new Metrics.Plotter("Total NPCs") {
- @Override
- public int getValue() {
- return Iterables.size(npcRegistry);
- }
- });
-
- traitManager.addPlotters(metrics.createGraph("traits"));
- metrics.start();
- Messaging.log("Metrics started.");
- } catch (IOException e) {
- Messaging.logF("Unable to start metrics: %s.", e.getMessage());
- }
- }
- }.start();
+ enableSubPlugins();
}
}) == -1) {
Messaging.severe("Issue enabling plugin. Disabling.");
@@ -226,6 +203,48 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
Bukkit.getPluginManager().disablePlugin(this);
}
+ private void enableSubPlugins() {
+ File root = new File(getDataFolder(), Setting.SUBPLUGIN_FOLDER.asString());
+ if (!root.exists() || !root.isDirectory())
+ return;
+ Plugin[] plugins = Bukkit.getPluginManager().loadPlugins(root);
+ // code beneath modified from CraftServer
+ for (Plugin plugin : plugins) {
+ try {
+ Messaging.logF("Loading %s", plugin.getDescription().getFullName());
+ plugin.onLoad();
+ } catch (Throwable ex) {
+ Messaging.severe(ex.getMessage() + " initializing " + plugin.getDescription().getFullName());
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ private void startMetrics() {
+ new Thread() {
+ @Override
+ public void run() {
+ try {
+ Metrics metrics = new Metrics(Citizens.this);
+ if (metrics.isOptOut())
+ return;
+ metrics.addCustomData(new Metrics.Plotter("Total NPCs") {
+ @Override
+ public int getValue() {
+ return Iterables.size(npcRegistry);
+ }
+ });
+
+ traitFactory.addPlotters(metrics.createGraph("traits"));
+ metrics.start();
+ Messaging.log("Metrics started.");
+ } catch (IOException e) {
+ Messaging.logF("Unable to start metrics: %s.", e.getMessage());
+ }
+ }
+ }.start();
+ }
+
private void registerCommands() {
commands.setInjector(new Injector(this));
@@ -293,7 +312,11 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
private void setupScripting() {
contextClassLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(getClassLoader());
- // workaround to fix scripts not loading plugin classes properly
+ // Workaround to fix scripts not loading plugin classes properly.
+ // The built in Sun Rhino Javascript engine uses the context classloader
+ // to search for class imports. Since the context classloader only has
+ // CraftBukkit classes, we replace it with a PluginClassLoader, which
+ // allows all plugin classes to be imported.
}
private void setupStorage() {
diff --git a/src/main/java/net/citizensnpcs/Settings.java b/src/main/java/net/citizensnpcs/Settings.java
index 95911b474..225764757 100644
--- a/src/main/java/net/citizensnpcs/Settings.java
+++ b/src/main/java/net/citizensnpcs/Settings.java
@@ -71,7 +71,8 @@ public class Settings {
STORAGE_TYPE("storage.type", "yaml"),
TALK_CLOSE_MAXIMUM_COOLDOWN("npc.text.max-talk-cooldown", 60),
TALK_CLOSE_MINIMUM_COOLDOWN("npc.text.min-talk-cooldown", 30),
- TALK_ITEM("npc.text.talk-item", "340");
+ TALK_ITEM("npc.text.talk-item", "340"),
+ SUBPLUGIN_FOLDER("subplugins.folder", "plugins");
protected String path;
protected Object value;
diff --git a/src/main/java/net/citizensnpcs/command/command/NPCCommands.java b/src/main/java/net/citizensnpcs/command/command/NPCCommands.java
index 7b8f1cc5e..ca54d08d7 100644
--- a/src/main/java/net/citizensnpcs/command/command/NPCCommands.java
+++ b/src/main/java/net/citizensnpcs/command/command/NPCCommands.java
@@ -61,8 +61,8 @@ public class NPCCommands {
min = 1,
max = 2,
permission = "npc.age")
- @Requirements(selected = true, ownership = true, types = { EntityType.CHICKEN, EntityType.COW, EntityType.OCELOT,
- EntityType.PIG, EntityType.SHEEP, EntityType.VILLAGER, EntityType.WOLF })
+ @Requirements(selected = true, ownership = true, types = { EntityType.CHICKEN, EntityType.COW,
+ EntityType.OCELOT, EntityType.PIG, EntityType.SHEEP, EntityType.VILLAGER, EntityType.WOLF })
public void age(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
Age trait = npc.getTrait(Age.class);
@@ -90,8 +90,13 @@ public class NPCCommands {
Messaging.send(sender, "Age " + (trait.toggle() ? "locked" : "unlocked") + ".");
}
- @Command(aliases = { "npc" }, usage = "behaviour [scripts]", desc = "Sets the behaviour of a NPC", modifiers = {
- "behaviour", "ai" }, min = 2, max = -1)
+ @Command(
+ aliases = { "npc" },
+ usage = "behaviour [scripts]",
+ desc = "Sets the behaviour of a NPC",
+ modifiers = { "behaviour", "ai" },
+ min = 2,
+ max = -1)
public void behaviour(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
Iterable files = Splitter.on(',').split(args.getJoinedStrings(1, ','));
npc.getTrait(Behaviour.class).addScripts(files);
@@ -128,7 +133,8 @@ public class NPCCommands {
public void create(CommandContext args, final Player player, NPC npc) {
String name = args.getString(1);
if (name.length() > 16) {
- Messaging.sendError(player, "NPC names cannot be longer than 16 characters. The name has been shortened.");
+ Messaging.sendError(player,
+ "NPC names cannot be longer than 16 characters. The name has been shortened.");
name = name.substring(0, 15);
}
EntityType type = EntityType.PLAYER;
@@ -141,7 +147,8 @@ public class NPCCommands {
}
}
npc = npcRegistry.createNPC(type, name);
- String msg = ChatColor.GREEN + "You created " + StringHelper.wrap(npc.getName()) + " at your location";
+ String msg = ChatColor.GREEN + "You created " + StringHelper.wrap(npc.getName())
+ + " at your location";
int age = 0;
if (args.hasFlag('b')) {
@@ -177,13 +184,21 @@ public class NPCCommands {
@Command(
aliases = { "npc" },
- usage = "despawn",
+ usage = "despawn (id)",
desc = "Despawn a NPC",
modifiers = { "despawn" },
min = 1,
- max = 1,
+ max = 2,
permission = "npc.despawn")
- public void despawn(CommandContext args, CommandSender sender, NPC npc) {
+ @Requirements
+ public void despawn(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
+ if (npc == null || args.argsLength() == 2) {
+ if (args.argsLength() < 2)
+ throw new CommandException("No NPC selected.");
+ npc = CitizensAPI.getNPCRegistry().getById(args.getInteger(2));
+ if (npc == null)
+ throw new CommandException("No NPC found with that ID.");
+ }
npc.getTrait(Spawned.class).setSpawned(false);
npc.despawn();
Messaging.send(sender, ChatColor.GREEN + "You despawned " + StringHelper.wrap(npc.getName()) + ".");
@@ -351,11 +366,10 @@ public class NPCCommands {
public void profession(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
String profession = args.getString(1);
try {
- npc.getTrait(VillagerProfession.class).setProfession(Profession.valueOf(profession.toUpperCase()));
- Messaging.send(
- sender,
- StringHelper.wrap(npc.getName()) + " is now the profession "
- + StringHelper.wrap(profession.toUpperCase()) + ".");
+ npc.getTrait(VillagerProfession.class)
+ .setProfession(Profession.valueOf(profession.toUpperCase()));
+ Messaging.send(sender, StringHelper.wrap(npc.getName()) + " is now the profession "
+ + StringHelper.wrap(profession.toUpperCase()) + ".");
} catch (IllegalArgumentException ex) {
throw new CommandException("'" + profession + "' is not a valid profession.");
}
@@ -404,11 +418,13 @@ public class NPCCommands {
String oldName = npc.getName();
String newName = args.getString(1);
if (newName.length() > 16) {
- Messaging.sendError(sender, "NPC names cannot be longer than 16 characters. The name has been shortened.");
+ Messaging.sendError(sender,
+ "NPC names cannot be longer than 16 characters. The name has been shortened.");
newName = newName.substring(0, 15);
}
npc.setName(newName);
- String msg = String.format("You renamed %s to %s.", StringHelper.wrap(oldName), StringHelper.wrap(newName));
+ String msg = String.format("You renamed %s to %s.", StringHelper.wrap(oldName),
+ StringHelper.wrap(newName));
Messaging.send(sender, ChatColor.GREEN + msg);
}
@@ -439,22 +455,25 @@ public class NPCCommands {
min = 2,
max = 2,
permission = "npc.spawn")
- @Requirements
- public void spawn(CommandContext args, Player player, NPC npc) throws CommandException {
+ @Requirements(ownership = true)
+ public void spawn(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
NPC respawn = npcRegistry.getById(args.getInteger(1));
if (respawn == null)
throw new CommandException("No NPC with the ID '" + args.getInteger(1) + "' exists.");
-
- if (!respawn.getTrait(Owner.class).isOwnedBy(player))
- throw new CommandException("You must be the owner of this NPC to execute that command.");
-
- if (respawn.spawn(player.getLocation())) {
- selector.select(player, respawn);
- Messaging.send(player, ChatColor.GREEN + "You respawned " + StringHelper.wrap(respawn.getName())
- + " at your location.");
- } else
+ if (respawn.isSpawned())
throw new CommandException(respawn.getName() + " is already spawned at another location."
+ " Use '/npc tphere' to teleport the NPC to your location.");
+
+ Location location = respawn.getTrait(CurrentLocation.class).getLocation();
+ if (location == null && sender instanceof Player)
+ location = ((Player) sender).getLocation();
+ else
+ throw new CommandException("No stored location available - command must be used ingame.");
+ if (respawn.spawn(location)) {
+ selector.select(sender, respawn);
+ Messaging.send(sender, ChatColor.GREEN + "You respawned " + StringHelper.wrap(respawn.getName())
+ + " at your location.");
+ }
}
@Command(
@@ -470,11 +489,12 @@ public class NPCCommands {
if (!npc.isSpawned())
npc.spawn(npc.getTrait(CurrentLocation.class).getLocation());
player.teleport(npc.getBukkitEntity(), TeleportCause.COMMAND);
- Messaging.send(player, ChatColor.GREEN + "You teleported to " + StringHelper.wrap(npc.getName()) + ".");
+ Messaging.send(player, ChatColor.GREEN + "You teleported to " + StringHelper.wrap(npc.getName())
+ + ".");
}
- @Command(aliases = { "npc" }, usage = "tphere", desc = "Teleport a NPC to your location", modifiers = { "tphere",
- "move" }, min = 1, max = 1, permission = "npc.tphere")
+ @Command(aliases = { "npc" }, usage = "tphere", desc = "Teleport a NPC to your location", modifiers = {
+ "tphere", "move" }, min = 1, max = 1, permission = "npc.tphere")
public void tphere(CommandContext args, Player player, NPC npc) {
// Spawn the NPC if it isn't spawned to prevent NPEs
if (!npc.isSpawned())
@@ -492,10 +512,11 @@ public class NPCCommands {
max = 2,
permission = "npc.trait")
public void trait(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
- Trait trait = CitizensAPI.getTraitManager().getTrait(args.getString(1), npc);
+ Trait trait = CitizensAPI.getTraitFactory().getTrait(args.getString(1));
if (trait == null)
throw new CommandException("Trait not found.");
npc.addTrait(trait);
- Messaging.sendF(sender, ChatColor.GREEN + "Trait %s added successfully.", StringHelper.wrap(trait.getName()));
+ Messaging.sendF(sender, ChatColor.GREEN + "Trait %s added successfully.",
+ StringHelper.wrap(trait.getName()));
}
}
\ 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 dab1b1847..820a86f94 100644
--- a/src/main/java/net/citizensnpcs/npc/CitizensNPC.java
+++ b/src/main/java/net/citizensnpcs/npc/CitizensNPC.java
@@ -1,6 +1,7 @@
package net.citizensnpcs.npc;
import net.citizensnpcs.api.CitizensAPI;
+import net.citizensnpcs.api.ai.Navigator;
import net.citizensnpcs.api.event.NPCDespawnEvent;
import net.citizensnpcs.api.event.NPCSpawnEvent;
import net.citizensnpcs.api.exception.NPCLoadException;
@@ -8,21 +9,20 @@ import net.citizensnpcs.api.npc.AbstractNPC;
import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.trait.trait.Spawned;
import net.citizensnpcs.api.util.DataKey;
-import net.citizensnpcs.npc.ai.CitizensAI;
+import net.citizensnpcs.npc.ai.CitizensNavigator;
import net.citizensnpcs.trait.CurrentLocation;
import net.citizensnpcs.util.Messaging;
-import net.citizensnpcs.util.StringHelper;
import net.minecraft.server.EntityLiving;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.LivingEntity;
-import org.bukkit.inventory.Inventory;
+import org.bukkit.metadata.FixedMetadataValue;
public abstract class CitizensNPC extends AbstractNPC {
- private final CitizensAI ai = new CitizensAI(this);
protected EntityLiving mcEntity;
+ private final CitizensNavigator navigator = new CitizensNavigator(this);
protected CitizensNPC(int id, String name) {
super(id, name);
@@ -47,17 +47,6 @@ public abstract class CitizensNPC extends AbstractNPC {
return true;
}
- @Override
- public void destroy() {
- super.destroy();
- CitizensAPI.getNPCRegistry().deregister(this);
- }
-
- @Override
- public CitizensAI getAI() {
- return ai;
- }
-
@Override
public LivingEntity getBukkitEntity() {
return (LivingEntity) getHandle().getBukkitEntity();
@@ -68,15 +57,13 @@ public abstract class CitizensNPC extends AbstractNPC {
}
@Override
- public org.bukkit.inventory.Inventory getInventory() {
- Inventory inventory = Bukkit.getServer().createInventory(this, 36, StringHelper.parseColors(getFullName()));
- inventory.setContents(getTrait(net.citizensnpcs.api.trait.trait.Inventory.class).getContents());
- return inventory;
+ public Navigator getNavigator() {
+ return navigator;
}
@Override
public Trait getTraitFor(Class extends Trait> clazz) {
- return CitizensAPI.getTraitManager().getTrait(clazz, this);
+ return CitizensAPI.getTraitFactory().getTrait(clazz);
}
@Override
@@ -87,9 +74,10 @@ public abstract class CitizensNPC extends AbstractNPC {
public void load(DataKey root) {
// Load traits
for (DataKey traitKey : root.getRelative("traits").getSubKeys()) {
- Trait trait = CitizensAPI.getTraitManager().getTrait(traitKey.name(), this);
+ Trait trait = CitizensAPI.getTraitFactory().getTrait(traitKey.name());
if (trait == null) {
- Messaging.severeF("Skipped missing trait '%s' while loading NPC ID: '%d'. Has the name changed?",
+ Messaging.severeF(
+ "Skipped missing trait '%s' while loading NPC ID: '%d'. Has the name changed?",
traitKey.name(), getId());
continue;
}
@@ -135,6 +123,8 @@ public abstract class CitizensNPC extends AbstractNPC {
mcEntity.world.addEntity(mcEntity);
mcEntity.world.players.remove(mcEntity);
+ getBukkitEntity().setMetadata(NPC_METADATA_MARKER,
+ new FixedMetadataValue(CitizensAPI.getPlugin(), true));
// Set the spawned state
getTrait(CurrentLocation.class).setLocation(loc);
@@ -142,7 +132,7 @@ public abstract class CitizensNPC extends AbstractNPC {
// Modify NPC using traits after the entity has been created
for (Trait trait : traits.values())
- trait.onNPCSpawn();
+ trait.onSpawn();
return true;
}
@@ -150,10 +140,12 @@ public abstract class CitizensNPC extends AbstractNPC {
public void update() {
try {
super.update();
- ai.update();
+ navigator.update();
} catch (Exception ex) {
Messaging.logF("Exception while updating %d: %s.", getId(), ex.getMessage());
ex.printStackTrace();
}
}
+
+ private static final String NPC_METADATA_MARKER = "NPC";
}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/npc/CitizensTraitManager.java b/src/main/java/net/citizensnpcs/npc/CitizensTraitFactory.java
similarity index 90%
rename from src/main/java/net/citizensnpcs/npc/CitizensTraitManager.java
rename to src/main/java/net/citizensnpcs/npc/CitizensTraitFactory.java
index cb4df88fc..dfc48bce5 100644
--- a/src/main/java/net/citizensnpcs/npc/CitizensTraitManager.java
+++ b/src/main/java/net/citizensnpcs/npc/CitizensTraitFactory.java
@@ -8,7 +8,7 @@ import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.trait.TraitInfo;
-import net.citizensnpcs.api.trait.TraitManager;
+import net.citizensnpcs.api.trait.TraitFactory;
import net.citizensnpcs.api.trait.trait.Equipment;
import net.citizensnpcs.api.trait.trait.Inventory;
import net.citizensnpcs.api.trait.trait.MobType;
@@ -30,11 +30,11 @@ import net.citizensnpcs.trait.waypoint.Waypoints;
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
-public class CitizensTraitManager implements TraitManager {
+public class CitizensTraitFactory implements TraitFactory {
private final Map> registered = Maps.newHashMap();
// TODO: find a way to avoid naming conflicts
- public CitizensTraitManager() {
+ public CitizensTraitFactory() {
registerTrait(TraitInfo.create(Age.class).withName("age"));
registerTrait(TraitInfo.create(CurrentLocation.class).withName("location"));
registerTrait(TraitInfo.create(Equipment.class).withName("equipment"));
@@ -71,7 +71,7 @@ public class CitizensTraitManager implements TraitManager {
}
}
- private T create(Class trait, NPC npc) {
+ private T create(Class trait) {
try {
return trait.newInstance();
} catch (Exception ex) {
@@ -81,19 +81,19 @@ public class CitizensTraitManager implements TraitManager {
}
@Override
- public T getTrait(Class clazz, NPC npc) {
+ public T getTrait(Class clazz) {
if (!registered.containsValue(clazz))
return null;
- return create(clazz, npc);
+ return create(clazz);
}
@Override
@SuppressWarnings("unchecked")
- public T getTrait(String name, NPC npc) {
+ public T getTrait(String name) {
Class extends Trait> clazz = registered.get(name);
if (clazz == null)
return null;
- return (T) create(clazz, npc);
+ return (T) create(clazz);
}
@Override
diff --git a/src/main/java/net/citizensnpcs/npc/ai/CitizensAI.java b/src/main/java/net/citizensnpcs/npc/ai/CitizensAI.java
deleted file mode 100644
index 57c10f238..000000000
--- a/src/main/java/net/citizensnpcs/npc/ai/CitizensAI.java
+++ /dev/null
@@ -1,236 +0,0 @@
-package net.citizensnpcs.npc.ai;
-
-import java.lang.ref.WeakReference;
-import java.util.Iterator;
-import java.util.List;
-
-import net.citizensnpcs.api.ai.AI;
-import net.citizensnpcs.api.ai.Goal;
-import net.citizensnpcs.api.ai.NavigationCallback;
-import net.citizensnpcs.api.ai.NavigationCallback.CancelReason;
-import net.citizensnpcs.npc.CitizensNPC;
-
-import org.bukkit.Location;
-import org.bukkit.entity.LivingEntity;
-
-import com.google.common.collect.Lists;
-
-public class CitizensAI implements AI {
- private final List> callbacks = Lists.newArrayList();
- private PathStrategy executing;
- private final List executingGoals = Lists.newArrayList();
- private final List goals = Lists.newArrayList();
- private final CitizensNPC npc;
- private boolean paused;
- private List toRemove = null;
-
- public CitizensAI(CitizensNPC npc) {
- this.npc = npc;
- }
-
- @Override
- public void addGoal(int priority, Goal goal) {
- if (goals.contains(goal))
- return;
- goals.add(new GoalEntry(priority, goal));
- }
-
- @Override
- public void cancelDestination() {
- if (executing == null)
- return;
- executing = null;
- for (int i = 0; i < callbacks.size(); ++i) {
- NavigationCallback next = callbacks.get(i).get();
- if (next == null || next.onCancel(this, CancelReason.CANCEL)) {
- callbacks.remove(i);
- }
- }
- }
-
- @Override
- public boolean hasDestination() {
- return executing != null;
- }
-
- private boolean isGoalAllowable(GoalEntry test) {
- for (int i = 0; i < goals.size(); ++i) {
- GoalEntry item = goals.get(i);
- if (item == test)
- continue;
- if (test.getPriority() >= item.getPriority()) {
- if (!test.getGoal().isCompatibleWith(item.getGoal()) && executingGoals.contains(item)) {
- return false;
- }
- } /*else if (executingGoals.contains(item) && !item.goal.requiresUpdates()) {
- return false;
- }*/
- }
-
- return true;
- }
-
- public void pause() {
- paused = true;
- }
-
- @Override
- public void registerNavigationCallback(NavigationCallback callback) {
- if (!callbacks.contains(callback)) {
- callbacks.add(new WeakReference(callback));
- callback.onAttach(this);
- }
- }
-
- @Override
- public void removeGoal(Goal goal) {
- if (toRemove == null)
- toRemove = Lists.newArrayList();
- toRemove.add(goal);
- }
-
- private void removeGoals() {
- if (toRemove == null)
- return;
- for (Goal goal : toRemove) {
- Iterator itr = executingGoals.iterator();
- while (itr.hasNext()) {
- GoalEntry entry = itr.next();
- if (entry.getGoal().equals(goal)) {
- entry.getGoal().reset();
- itr.remove();
- }
- }
- itr = goals.iterator();
- while (itr.hasNext()) {
- GoalEntry entry = itr.next();
- if (entry.getGoal().equals(goal))
- itr.remove();
- }
- }
-
- toRemove = null;
- }
-
- public void resume() {
- paused = false;
- }
-
- @Override
- public void setDestination(Location destination) {
- if (destination == null)
- throw new IllegalArgumentException("destination cannot be null");
- if (!npc.isSpawned())
- throw new IllegalStateException("npc is not spawned");
- if (destination.getWorld() != npc.getBukkitEntity().getWorld())
- throw new IllegalArgumentException("location is not in the same world");
-
- boolean replaced = executing != null;
- executing = new MCNavigationStrategy(npc, destination);
-
- for (int i = 0; i < callbacks.size(); ++i) {
- NavigationCallback next = callbacks.get(i).get();
- if (next == null || (replaced && next.onCancel(this, CancelReason.REPLACE)) || next.onBegin(this)) {
- callbacks.remove(i);
- }
- }
- }
-
- @Override
- public void setTarget(LivingEntity target, boolean aggressive) {
- if (target == null)
- throw new IllegalArgumentException("target cannot be null");
-
- boolean replaced = executing != null;
- executing = new MCTargetStrategy(npc, target, aggressive);
-
- for (int i = 0; i < callbacks.size(); ++i) {
- NavigationCallback next = callbacks.get(i).get();
- if (next == null || (replaced && next.onCancel(this, CancelReason.REPLACE)) || next.onBegin(this)) {
- callbacks.remove(i);
- }
- }
- }
-
- public void update() {
- if (paused || !npc.isSpawned()) {
- return;
- }
-
- if (executing != null && executing.update()) {
- executing = null;
- for (int i = 0; i < callbacks.size(); ++i) {
- NavigationCallback next = callbacks.get(i).get();
- if (next == null || next.onCompletion(this)) {
- callbacks.remove(i);
- }
- }
- }
- removeGoals();
- for (int i = 0; i < goals.size(); ++i) {
- GoalEntry entry = goals.get(i);
- boolean executing = executingGoals.contains(entry);
-
- if (executing) {
- if (!entry.getGoal().continueExecuting() || !isGoalAllowable(entry)) {
- entry.getGoal().reset();
- executingGoals.remove(entry);
- }
- } else if (entry.getGoal().shouldExecute() && isGoalAllowable(entry)) {
- entry.getGoal().start();
- executingGoals.add(entry);
- }
- }
-
- for (int i = 0; i < executingGoals.size(); ++i) {
- executingGoals.get(i).getGoal().update();
- }
- }
-
- public static class GoalEntry implements Comparable {
- private final Goal goal;
- private final int priority;
-
- public GoalEntry(int priority, Goal goal) {
- this.priority = priority;
- this.goal = goal;
- }
-
- @Override
- public int compareTo(GoalEntry o) {
- return o.priority > priority ? 1 : o.priority < priority ? -1 : 0;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null || getClass() != obj.getClass()) {
- return false;
- }
- GoalEntry other = (GoalEntry) obj;
- if (goal == null) {
- if (other.goal != null) {
- return false;
- }
- } else if (!goal.equals(other.goal)) {
- return false;
- }
- return true;
- }
-
- public Goal getGoal() {
- return goal;
- }
-
- public int getPriority() {
- return priority;
- }
-
- @Override
- public int hashCode() {
- return 31 + ((goal == null) ? 0 : goal.hashCode());
- }
- }
-}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/npc/ai/CitizensNavigator.java b/src/main/java/net/citizensnpcs/npc/ai/CitizensNavigator.java
new file mode 100644
index 000000000..90c9c7b1b
--- /dev/null
+++ b/src/main/java/net/citizensnpcs/npc/ai/CitizensNavigator.java
@@ -0,0 +1,137 @@
+package net.citizensnpcs.npc.ai;
+
+import java.lang.reflect.Field;
+import java.util.Map;
+
+import net.citizensnpcs.api.ai.EntityTarget;
+import net.citizensnpcs.api.ai.Navigator;
+import net.citizensnpcs.api.ai.TargetType;
+import net.citizensnpcs.api.ai.event.NavigationBeginEvent;
+import net.citizensnpcs.api.ai.event.NavigationCancelEvent;
+import net.citizensnpcs.api.ai.event.NavigationReplaceEvent;
+import net.citizensnpcs.npc.CitizensNPC;
+import net.minecraft.server.EntityLiving;
+
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.entity.EntityType;
+import org.bukkit.entity.LivingEntity;
+
+import com.google.common.collect.Maps;
+
+public class CitizensNavigator implements Navigator {
+ private final CitizensNPC npc;
+ private float speed;
+ private PathStrategy executing;
+
+ public CitizensNavigator(CitizensNPC npc) {
+ this.npc = npc;
+ this.speed = getSpeedFor(npc.getHandle());
+ }
+
+ public void update() {
+ if (executing == null)
+ return;
+ boolean finished = executing.update();
+ if (finished) {
+ Bukkit.getPluginManager().callEvent(new NavigationCompleteEvent(this));
+ executing = null;
+ }
+ }
+
+ @Override
+ public void cancelNavigation() {
+ if (executing != null) {
+ Bukkit.getPluginManager().callEvent(new NavigationCancelEvent(this));
+ }
+ executing = null;
+ }
+
+ @Override
+ public float getSpeed() {
+ return speed;
+ }
+
+ @Override
+ public EntityTarget getEntityTarget() {
+ return executing instanceof EntityTarget ? (EntityTarget) executing : null;
+ }
+
+ @Override
+ public Location getTargetAsLocation() {
+ return executing.getTargetAsLocation();
+ }
+
+ @Override
+ public TargetType getTargetType() {
+ return executing.getTargetType();
+ }
+
+ @Override
+ public boolean isNavigating() {
+ return executing != null;
+ }
+
+ @Override
+ public void setSpeed(float speed) {
+ this.speed = speed;
+ }
+
+ @Override
+ public void setTarget(LivingEntity target, boolean aggressive) {
+ PathStrategy newStrategy = new MCTargetStrategy(npc, target, aggressive, speed);
+ switchStrategyTo(newStrategy);
+ }
+
+ private void switchStrategyTo(PathStrategy newStrategy) {
+ if (executing != null)
+ Bukkit.getPluginManager().callEvent(new NavigationReplaceEvent(this));
+
+ executing = newStrategy;
+
+ Bukkit.getPluginManager().callEvent(new NavigationBeginEvent(this));
+ }
+
+ @Override
+ public void setTarget(Location target) {
+ PathStrategy newStrategy = new MCNavigationStrategy(npc, target, speed);
+ switchStrategyTo(newStrategy);
+ }
+
+ private float getSpeedFor(EntityLiving from) {
+ EntityType entityType = from.getBukkitEntity().getType();
+ Float cached = MOVEMENT_SPEEDS.get(entityType);
+ if (cached != null)
+ return cached;
+ if (SPEED_FIELD == null) {
+ MOVEMENT_SPEEDS.put(entityType, DEFAULT_SPEED);
+ return DEFAULT_SPEED;
+ }
+ try {
+ float speed = SPEED_FIELD.getFloat(from);
+ MOVEMENT_SPEEDS.put(entityType, speed);
+ return speed;
+ } catch (IllegalAccessException ex) {
+ ex.printStackTrace();
+ return DEFAULT_SPEED;
+ }
+ }
+
+ private static final float DEFAULT_SPEED = 0.3F;
+ private static final Map MOVEMENT_SPEEDS = Maps.newEnumMap(EntityType.class);
+ private static Field SPEED_FIELD;
+ static {
+ MOVEMENT_SPEEDS.put(EntityType.IRON_GOLEM, 0.15F);
+ MOVEMENT_SPEEDS.put(EntityType.CHICKEN, 0.25F);
+ MOVEMENT_SPEEDS.put(EntityType.COW, 0.2F);
+ MOVEMENT_SPEEDS.put(EntityType.SHEEP, 0.25F);
+ MOVEMENT_SPEEDS.put(EntityType.VILLAGER, 0.3F);
+ MOVEMENT_SPEEDS.put(EntityType.SNOWMAN, 0.25F);
+ try {
+ SPEED_FIELD = EntityLiving.class.getDeclaredField("bb");
+ SPEED_FIELD.setAccessible(true);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+}
diff --git a/src/main/java/net/citizensnpcs/npc/ai/MCNavigationStrategy.java b/src/main/java/net/citizensnpcs/npc/ai/MCNavigationStrategy.java
index 214a490a1..e2e9fa698 100644
--- a/src/main/java/net/citizensnpcs/npc/ai/MCNavigationStrategy.java
+++ b/src/main/java/net/citizensnpcs/npc/ai/MCNavigationStrategy.java
@@ -1,60 +1,37 @@
package net.citizensnpcs.npc.ai;
-import java.lang.reflect.Field;
-import java.util.Map;
-
+import net.citizensnpcs.api.ai.TargetType;
import net.citizensnpcs.npc.CitizensNPC;
import net.minecraft.server.EntityLiving;
import net.minecraft.server.Navigation;
import org.bukkit.Location;
-import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
-import com.google.common.collect.Maps;
-
public class MCNavigationStrategy implements PathStrategy {
- private final EntityLiving entity;
private final Navigation navigation;
+ private final Location target;
- MCNavigationStrategy(final CitizensNPC npc, final Location dest) {
- entity = npc.getHandle();
- if (npc.getBukkitEntity() instanceof Player) {
+ MCNavigationStrategy(final CitizensNPC npc, Location dest, float speed) {
+ this(npc.getHandle(), dest);
+ navigation.a(dest.getX(), dest.getY(), dest.getZ(), speed);
+
+ }
+
+ MCNavigationStrategy(EntityLiving entity, EntityLiving target, float speed) {
+ this(entity, target.getBukkitEntity().getLocation());
+ navigation.a(target, speed);
+ }
+
+ private MCNavigationStrategy(EntityLiving entity, Location target) {
+ this.target = target;
+ if (entity.getBukkitEntity() instanceof Player) {
entity.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 = entity.al();
- navigation.a(dest.getX(), dest.getY(), dest.getZ(), getSpeed(npc.getHandle()));
-
- }
-
- MCNavigationStrategy(EntityLiving entity, EntityLiving target) {
- this.entity = entity;
- if (entity.getBukkitEntity() instanceof Player) {
- entity.onGround = true; // see above
- }
- navigation = entity.al();
- navigation.a(target, getSpeed(entity));
- }
-
- private float getSpeed(EntityLiving from) {
- Float cached = MOVEMENT_SPEEDS.get(from.getBukkitEntity().getType());
- if (cached != null)
- return cached;
- if (SPEED_FIELD == null) {
- MOVEMENT_SPEEDS.put(from.getBukkitEntity().getType(), DEFAULT_SPEED);
- return DEFAULT_SPEED;
- }
- try {
- float speed = SPEED_FIELD.getFloat(from);
- MOVEMENT_SPEEDS.put(from.getBukkitEntity().getType(), speed);
- return speed;
- } catch (IllegalAccessException ex) {
- ex.printStackTrace();
- return DEFAULT_SPEED;
- }
}
@Override
@@ -62,21 +39,13 @@ public class MCNavigationStrategy implements PathStrategy {
return navigation.e();
}
- private static final float DEFAULT_SPEED = 0.3F;
- private static final Map MOVEMENT_SPEEDS = Maps.newEnumMap(EntityType.class);
- private static Field SPEED_FIELD;
- static {
- MOVEMENT_SPEEDS.put(EntityType.IRON_GOLEM, 0.15F);
- MOVEMENT_SPEEDS.put(EntityType.CHICKEN, 0.25F);
- MOVEMENT_SPEEDS.put(EntityType.COW, 0.2F);
- MOVEMENT_SPEEDS.put(EntityType.SHEEP, 0.25F);
- MOVEMENT_SPEEDS.put(EntityType.VILLAGER, 0.3F);
- MOVEMENT_SPEEDS.put(EntityType.SNOWMAN, 0.25F);
- try {
- SPEED_FIELD = EntityLiving.class.getDeclaredField("bb");
- SPEED_FIELD.setAccessible(true);
- } catch (Exception ex) {
- ex.printStackTrace();
- }
+ @Override
+ public Location getTargetAsLocation() {
+ return target;
+ }
+
+ @Override
+ public TargetType getTargetType() {
+ return TargetType.LOCATION;
}
}
diff --git a/src/main/java/net/citizensnpcs/npc/ai/MCTargetStrategy.java b/src/main/java/net/citizensnpcs/npc/ai/MCTargetStrategy.java
index 9f6e0860e..924c7f9ef 100644
--- a/src/main/java/net/citizensnpcs/npc/ai/MCTargetStrategy.java
+++ b/src/main/java/net/citizensnpcs/npc/ai/MCTargetStrategy.java
@@ -1,5 +1,7 @@
package net.citizensnpcs.npc.ai;
+import net.citizensnpcs.api.ai.EntityTarget;
+import net.citizensnpcs.api.ai.TargetType;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.util.Util;
import net.minecraft.server.EntityLiving;
@@ -7,17 +9,20 @@ import net.minecraft.server.EntityMonster;
import net.minecraft.server.EntityPlayer;
import net.minecraft.server.Packet18ArmAnimation;
+import org.bukkit.Location;
import org.bukkit.craftbukkit.entity.CraftLivingEntity;
import org.bukkit.entity.LivingEntity;
-public class MCTargetStrategy implements PathStrategy {
+public class MCTargetStrategy implements PathStrategy, EntityTarget {
private final boolean aggro;
private final EntityLiving handle, target;
+ private final float speed;
- public MCTargetStrategy(CitizensNPC handle, LivingEntity target, boolean aggro) {
+ public MCTargetStrategy(CitizensNPC handle, LivingEntity target, boolean aggro, float speed) {
this.handle = handle.getHandle();
this.target = ((CraftLivingEntity) target).getHandle();
this.aggro = aggro;
+ this.speed = speed;
}
private boolean canAttack() {
@@ -34,7 +39,7 @@ public class MCTargetStrategy implements PathStrategy {
public boolean update() {
if (target == null || target.dead)
return true;
- new MCNavigationStrategy(handle, target).update();
+ new MCNavigationStrategy(handle, target, speed).update();
handle.getControllerLook().a(target, 10.0F, handle.D());
if (aggro && canAttack()) {
if (handle instanceof EntityMonster) {
@@ -43,8 +48,8 @@ public class MCTargetStrategy implements PathStrategy {
} else if (handle instanceof EntityPlayer) {
EntityPlayer humanHandle = (EntityPlayer) handle;
humanHandle.attack(target);
- Util.sendPacketNearby(handle.getBukkitEntity().getLocation(), new Packet18ArmAnimation(humanHandle, 1),
- 64);
+ Util.sendPacketNearby(handle.getBukkitEntity().getLocation(), new Packet18ArmAnimation(
+ humanHandle, 1), 64);
}
}
@@ -52,4 +57,24 @@ public class MCTargetStrategy implements PathStrategy {
}
private static final double ATTACK_DISTANCE = 1.75 * 1.75;
+
+ @Override
+ public LivingEntity getTarget() {
+ return (LivingEntity) target.getBukkitEntity();
+ }
+
+ @Override
+ public boolean isAggressive() {
+ return aggro;
+ }
+
+ @Override
+ public Location getTargetAsLocation() {
+ return getTarget().getLocation();
+ }
+
+ @Override
+ public TargetType getTargetType() {
+ return TargetType.ENTITY;
+ }
}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/npc/ai/NavigationCompleteEvent.java b/src/main/java/net/citizensnpcs/npc/ai/NavigationCompleteEvent.java
new file mode 100644
index 000000000..2deacc008
--- /dev/null
+++ b/src/main/java/net/citizensnpcs/npc/ai/NavigationCompleteEvent.java
@@ -0,0 +1,23 @@
+package net.citizensnpcs.npc.ai;
+
+import net.citizensnpcs.api.ai.Navigator;
+import net.citizensnpcs.api.ai.event.NavigationEvent;
+
+import org.bukkit.event.HandlerList;
+
+public class NavigationCompleteEvent extends NavigationEvent {
+ public NavigationCompleteEvent(Navigator navigator) {
+ super(navigator);
+ }
+
+ @Override
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+
+ private static final HandlerList handlers = new HandlerList();
+
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+}
diff --git a/src/main/java/net/citizensnpcs/npc/ai/PathStrategy.java b/src/main/java/net/citizensnpcs/npc/ai/PathStrategy.java
index 3af3fbe6e..3d4144848 100644
--- a/src/main/java/net/citizensnpcs/npc/ai/PathStrategy.java
+++ b/src/main/java/net/citizensnpcs/npc/ai/PathStrategy.java
@@ -1,6 +1,13 @@
package net.citizensnpcs.npc.ai;
-public interface PathStrategy {
+import net.citizensnpcs.api.ai.TargetType;
+import org.bukkit.Location;
+
+public interface PathStrategy {
boolean update();
+
+ Location getTargetAsLocation();
+
+ TargetType getTargetType();
}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensBlazeNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensBlazeNPC.java
index eca788a48..98b5d639d 100644
--- a/src/main/java/net/citizensnpcs/npc/entity/CitizensBlazeNPC.java
+++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensBlazeNPC.java
@@ -31,8 +31,10 @@ public class CitizensBlazeNPC extends CitizensMobNPC {
public EntityBlazeNPC(World world, NPC npc) {
super(world);
this.npc = (CitizensNPC) npc;
- goalSelector = new PathfinderGoalSelector();
- targetSelector = new PathfinderGoalSelector();
+ if (npc != null) {
+ goalSelector = new PathfinderGoalSelector();
+ targetSelector = new PathfinderGoalSelector();
+ }
}
@Override
@@ -47,5 +49,11 @@ public class CitizensBlazeNPC extends CitizensMobNPC {
public NPC getNPC() {
return npc;
}
+
+ @Override
+ public void b_(double x, double y, double z) {
+ // when another entity collides, b_ is called to push the NPC
+ // so we prevent b_ from doing anything.
+ }
}
}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensCaveSpiderNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensCaveSpiderNPC.java
index c38049555..f4e42add5 100644
--- a/src/main/java/net/citizensnpcs/npc/entity/CitizensCaveSpiderNPC.java
+++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensCaveSpiderNPC.java
@@ -27,8 +27,10 @@ public class CitizensCaveSpiderNPC extends CitizensMobNPC {
public EntityCaveSpiderNPC(World world, NPC npc) {
super(world);
this.npc = (CitizensNPC) npc;
- goalSelector = new PathfinderGoalSelector();
- targetSelector = new PathfinderGoalSelector();
+ if (npc != null) {
+ goalSelector = new PathfinderGoalSelector();
+ targetSelector = new PathfinderGoalSelector();
+ }
}
@Override
@@ -41,5 +43,11 @@ public class CitizensCaveSpiderNPC extends CitizensMobNPC {
super.z_();
npc.update();
}
+
+ @Override
+ public void b_(double x, double y, double z) {
+ // when another entity collides, b_ is called to push the NPC
+ // so we prevent b_ from doing anything.
+ }
}
}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensChickenNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensChickenNPC.java
index 822d94351..4e8c37b54 100644
--- a/src/main/java/net/citizensnpcs/npc/entity/CitizensChickenNPC.java
+++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensChickenNPC.java
@@ -31,8 +31,10 @@ public class CitizensChickenNPC extends CitizensMobNPC {
public EntityChickenNPC(World world, NPC npc) {
super(world);
this.npc = (CitizensNPC) npc;
- goalSelector = new PathfinderGoalSelector();
- targetSelector = new PathfinderGoalSelector();
+ if (npc != null) {
+ goalSelector = new PathfinderGoalSelector();
+ targetSelector = new PathfinderGoalSelector();
+ }
}
@Override
@@ -46,5 +48,11 @@ public class CitizensChickenNPC extends CitizensMobNPC {
if (npc != null)
npc.update();
}
+
+ @Override
+ public void b_(double x, double y, double z) {
+ // when another entity collides, b_ is called to push the NPC
+ // so we prevent b_ from doing anything.
+ }
}
}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensCowNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensCowNPC.java
index 472671225..387c12be3 100644
--- a/src/main/java/net/citizensnpcs/npc/entity/CitizensCowNPC.java
+++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensCowNPC.java
@@ -31,8 +31,10 @@ public class CitizensCowNPC extends CitizensMobNPC {
public EntityCowNPC(World world, NPC npc) {
super(world);
this.npc = (CitizensNPC) npc;
- goalSelector = new PathfinderGoalSelector();
- targetSelector = new PathfinderGoalSelector();
+ if (npc != null) {
+ goalSelector = new PathfinderGoalSelector();
+ targetSelector = new PathfinderGoalSelector();
+ }
}
@Override
@@ -46,5 +48,11 @@ public class CitizensCowNPC extends CitizensMobNPC {
if (npc != null)
npc.update();
}
+
+ @Override
+ public void b_(double x, double y, double z) {
+ // when another entity collides, b_ is called to push the NPC
+ // so we prevent b_ from doing anything.
+ }
}
}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensCreeperNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensCreeperNPC.java
index ca495576c..98f4db3ab 100644
--- a/src/main/java/net/citizensnpcs/npc/entity/CitizensCreeperNPC.java
+++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensCreeperNPC.java
@@ -32,12 +32,16 @@ public class CitizensCreeperNPC extends CitizensMobNPC {
public EntityCreeperNPC(World world, NPC npc) {
super(world);
this.npc = (CitizensNPC) npc;
- goalSelector = new PathfinderGoalSelector();
- targetSelector = new PathfinderGoalSelector();
+ if (npc != null) {
+ goalSelector = new PathfinderGoalSelector();
+ targetSelector = new PathfinderGoalSelector();
+ }
}
@Override
public void a(EntityWeatherLighting entityweatherlighting) {
+ if (npc == null)
+ super.a(entityweatherlighting);
}
@Override
@@ -51,5 +55,11 @@ public class CitizensCreeperNPC extends CitizensMobNPC {
if (npc != null)
npc.update();
}
+
+ @Override
+ public void b_(double x, double y, double z) {
+ // when another entity collides, b_ is called to push the NPC
+ // so we prevent b_ from doing anything.
+ }
}
}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensEnderDragonNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensEnderDragonNPC.java
index c4a034054..21ee64e25 100644
--- a/src/main/java/net/citizensnpcs/npc/entity/CitizensEnderDragonNPC.java
+++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensEnderDragonNPC.java
@@ -27,22 +27,35 @@ public class CitizensEnderDragonNPC extends CitizensMobNPC {
public EntityEnderDragonNPC(World world, NPC npc) {
super(world);
this.npc = (CitizensNPC) npc;
- goalSelector = new PathfinderGoalSelector();
- targetSelector = new PathfinderGoalSelector();
+ if (npc != null) {
+ goalSelector = new PathfinderGoalSelector();
+ targetSelector = new PathfinderGoalSelector();
+ }
}
@Override
public void d_() {
+ if (npc == null)
+ super.d_();
}
@Override
public void e() {
- npc.update();
+ if (npc != null)
+ npc.update();
+ else
+ super.e();
}
@Override
public NPC getNPC() {
return npc;
}
+
+ @Override
+ public void b_(double x, double y, double z) {
+ // when another entity collides, b_ is called to push the NPC
+ // so we prevent b_ from doing anything.
+ }
}
}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensEndermanNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensEndermanNPC.java
index dbe100ba7..310890f31 100644
--- a/src/main/java/net/citizensnpcs/npc/entity/CitizensEndermanNPC.java
+++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensEndermanNPC.java
@@ -69,12 +69,16 @@ public class CitizensEndermanNPC extends CitizensMobNPC implements Equipable {
public EntityEndermanNPC(World world, NPC npc) {
super(world);
this.npc = (CitizensNPC) npc;
- goalSelector = new PathfinderGoalSelector();
- targetSelector = new PathfinderGoalSelector();
+ if (npc != null) {
+ goalSelector = new PathfinderGoalSelector();
+ targetSelector = new PathfinderGoalSelector();
+ }
}
@Override
public void d_() {
+ if (npc == null)
+ super.d_();
}
@Override
@@ -89,5 +93,11 @@ public class CitizensEndermanNPC extends CitizensMobNPC implements Equipable {
public NPC getNPC() {
return npc;
}
+
+ @Override
+ public void b_(double x, double y, double z) {
+ // when another entity collides, b_ is called to push the NPC
+ // so we prevent b_ from doing anything.
+ }
}
}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensGhastNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensGhastNPC.java
index d522d2be3..62526d27f 100644
--- a/src/main/java/net/citizensnpcs/npc/entity/CitizensGhastNPC.java
+++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensGhastNPC.java
@@ -31,8 +31,10 @@ public class CitizensGhastNPC extends CitizensMobNPC {
public EntityGhastNPC(World world, NPC npc) {
super(world);
this.npc = (CitizensNPC) npc;
- goalSelector = new PathfinderGoalSelector();
- targetSelector = new PathfinderGoalSelector();
+ if (npc != null) {
+ goalSelector = new PathfinderGoalSelector();
+ targetSelector = new PathfinderGoalSelector();
+ }
}
@Override
@@ -47,5 +49,11 @@ public class CitizensGhastNPC extends CitizensMobNPC {
public NPC getNPC() {
return npc;
}
+
+ @Override
+ public void b_(double x, double y, double z) {
+ // when another entity collides, b_ is called to push the NPC
+ // so we prevent b_ from doing anything.
+ }
}
}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensGiantNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensGiantNPC.java
index a6ea42179..0c5050f39 100644
--- a/src/main/java/net/citizensnpcs/npc/entity/CitizensGiantNPC.java
+++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensGiantNPC.java
@@ -27,8 +27,10 @@ public class CitizensGiantNPC extends CitizensMobNPC {
public EntityGiantNPC(World world, NPC npc) {
super(world);
this.npc = (CitizensNPC) npc;
- goalSelector = new PathfinderGoalSelector();
- targetSelector = new PathfinderGoalSelector();
+ if (npc != null) {
+ goalSelector = new PathfinderGoalSelector();
+ targetSelector = new PathfinderGoalSelector();
+ }
}
@Override
@@ -40,5 +42,11 @@ public class CitizensGiantNPC extends CitizensMobNPC {
public NPC getNPC() {
return npc;
}
+
+ @Override
+ public void b_(double x, double y, double z) {
+ // when another entity collides, b_ is called to push the NPC
+ // so we prevent b_ from doing anything.
+ }
}
}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensHumanNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensHumanNPC.java
index 0d59da5b1..bb0e01076 100644
--- a/src/main/java/net/citizensnpcs/npc/entity/CitizensHumanNPC.java
+++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensHumanNPC.java
@@ -48,48 +48,50 @@ public class CitizensHumanNPC extends CitizensNPC implements Equipable {
Material type = hand == null ? Material.AIR : hand.getType();
// First, determine the slot to edit
switch (type) {
- case PUMPKIN:
- case JACK_O_LANTERN:
- case LEATHER_HELMET:
- case CHAINMAIL_HELMET:
- case GOLD_HELMET:
- case IRON_HELMET:
- case DIAMOND_HELMET:
- if (!equipper.isSneaking())
- slot = 1;
- break;
- case LEATHER_CHESTPLATE:
- case CHAINMAIL_CHESTPLATE:
- case GOLD_CHESTPLATE:
- case IRON_CHESTPLATE:
- case DIAMOND_CHESTPLATE:
- if (!equipper.isSneaking())
- slot = 2;
- break;
- case LEATHER_LEGGINGS:
- case CHAINMAIL_LEGGINGS:
- case GOLD_LEGGINGS:
- case IRON_LEGGINGS:
- case DIAMOND_LEGGINGS:
- if (!equipper.isSneaking())
- slot = 3;
- break;
- case LEATHER_BOOTS:
- case CHAINMAIL_BOOTS:
- case GOLD_BOOTS:
- case IRON_BOOTS:
- case DIAMOND_BOOTS:
- if (!equipper.isSneaking())
- slot = 4;
- break;
- case AIR:
- for (int i = 0; i < 5; i++) {
- if (trait.get(i) != null && trait.get(i).getType() != Material.AIR) {
- equipper.getWorld().dropItemNaturally(getBukkitEntity().getLocation(), trait.get(i));
- trait.set(i, null);
+ case PUMPKIN:
+ case JACK_O_LANTERN:
+ case LEATHER_HELMET:
+ case CHAINMAIL_HELMET:
+ case GOLD_HELMET:
+ case IRON_HELMET:
+ case DIAMOND_HELMET:
+ if (!equipper.isSneaking())
+ slot = 1;
+ break;
+ case LEATHER_CHESTPLATE:
+ case CHAINMAIL_CHESTPLATE:
+ case GOLD_CHESTPLATE:
+ case IRON_CHESTPLATE:
+ case DIAMOND_CHESTPLATE:
+ if (!equipper.isSneaking())
+ slot = 2;
+ break;
+ case LEATHER_LEGGINGS:
+ case CHAINMAIL_LEGGINGS:
+ case GOLD_LEGGINGS:
+ case IRON_LEGGINGS:
+ case DIAMOND_LEGGINGS:
+ if (!equipper.isSneaking())
+ slot = 3;
+ break;
+ case LEATHER_BOOTS:
+ case CHAINMAIL_BOOTS:
+ case GOLD_BOOTS:
+ case IRON_BOOTS:
+ case DIAMOND_BOOTS:
+ if (!equipper.isSneaking())
+ slot = 4;
+ break;
+ case AIR:
+ for (int i = 0; i < 5; i++) {
+ if (trait.get(i) != null && trait.get(i).getType() != Material.AIR) {
+ equipper.getWorld().dropItemNaturally(getBukkitEntity().getLocation(), trait.get(i));
+ trait.set(i, null);
+ }
}
- }
- Messaging.sendF(equipper, "%shad all of its items removed.", getName());
+ Messaging.sendF(equipper, "%shad all of its items removed.", getName());
+ default:
+ break;
}
// Drop any previous equipment on the ground
if (trait.get(slot) != null && trait.get(slot).getType() != Material.AIR)
diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensIronGolemNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensIronGolemNPC.java
index d5d4c33c9..f3ace3910 100644
--- a/src/main/java/net/citizensnpcs/npc/entity/CitizensIronGolemNPC.java
+++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensIronGolemNPC.java
@@ -27,8 +27,10 @@ public class CitizensIronGolemNPC extends CitizensMobNPC {
public EntityIronGolemNPC(World world, NPC npc) {
super(world);
this.npc = (CitizensNPC) npc;
- goalSelector = new PathfinderGoalSelector();
- targetSelector = new PathfinderGoalSelector();
+ if (npc != null) {
+ goalSelector = new PathfinderGoalSelector();
+ targetSelector = new PathfinderGoalSelector();
+ }
}
@Override
@@ -39,7 +41,14 @@ public class CitizensIronGolemNPC extends CitizensMobNPC {
@Override
public void z_() {
super.z_();
- npc.update();
+ if (npc != null)
+ npc.update();
+ }
+
+ @Override
+ public void b_(double x, double y, double z) {
+ // when another entity collides, b_ is called to push the NPC
+ // so we prevent b_ from doing anything.
}
}
}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensMagmaCubeNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensMagmaCubeNPC.java
index f6543b380..c4ce98771 100644
--- a/src/main/java/net/citizensnpcs/npc/entity/CitizensMagmaCubeNPC.java
+++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensMagmaCubeNPC.java
@@ -31,9 +31,11 @@ public class CitizensMagmaCubeNPC extends CitizensMobNPC {
public EntityMagmaCubeNPC(World world, NPC npc) {
super(world);
this.npc = (CitizensNPC) npc;
- setSize(3);
- goalSelector = new PathfinderGoalSelector();
- targetSelector = new PathfinderGoalSelector();
+ if (npc != null) {
+ setSize(3);
+ goalSelector = new PathfinderGoalSelector();
+ targetSelector = new PathfinderGoalSelector();
+ }
}
@Override
@@ -48,5 +50,11 @@ public class CitizensMagmaCubeNPC extends CitizensMobNPC {
public NPC getNPC() {
return npc;
}
+
+ @Override
+ public void b_(double x, double y, double z) {
+ // when another entity collides, b_ is called to push the NPC
+ // so we prevent b_ from doing anything.
+ }
}
}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensMushroomCowNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensMushroomCowNPC.java
index e240ed7ca..1de97fc46 100644
--- a/src/main/java/net/citizensnpcs/npc/entity/CitizensMushroomCowNPC.java
+++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensMushroomCowNPC.java
@@ -31,8 +31,10 @@ public class CitizensMushroomCowNPC extends CitizensMobNPC {
public EntityMushroomCowNPC(World world, NPC npc) {
super(world);
this.npc = (CitizensNPC) npc;
- goalSelector = new PathfinderGoalSelector();
- targetSelector = new PathfinderGoalSelector();
+ if (npc != null) {
+ goalSelector = new PathfinderGoalSelector();
+ targetSelector = new PathfinderGoalSelector();
+ }
}
@Override
@@ -46,5 +48,11 @@ public class CitizensMushroomCowNPC extends CitizensMobNPC {
if (npc != null)
npc.update();
}
+
+ @Override
+ public void b_(double x, double y, double z) {
+ // when another entity collides, b_ is called to push the NPC
+ // so we prevent b_ from doing anything.
+ }
}
}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensOcelotNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensOcelotNPC.java
index ad7f3b015..a620ddeab 100644
--- a/src/main/java/net/citizensnpcs/npc/entity/CitizensOcelotNPC.java
+++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensOcelotNPC.java
@@ -31,8 +31,10 @@ public class CitizensOcelotNPC extends CitizensMobNPC {
public EntityOcelotNPC(World world, NPC npc) {
super(world);
this.npc = (CitizensNPC) npc;
- goalSelector = new PathfinderGoalSelector();
- targetSelector = new PathfinderGoalSelector();
+ if (npc != null) {
+ goalSelector = new PathfinderGoalSelector();
+ targetSelector = new PathfinderGoalSelector();
+ }
}
@Override
@@ -46,5 +48,11 @@ public class CitizensOcelotNPC extends CitizensMobNPC {
if (npc != null)
npc.update();
}
+
+ @Override
+ public void b_(double x, double y, double z) {
+ // when another entity collides, b_ is called to push the NPC
+ // so we prevent b_ from doing anything.
+ }
}
}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensPigNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensPigNPC.java
index b607dd935..bb7ac7b77 100644
--- a/src/main/java/net/citizensnpcs/npc/entity/CitizensPigNPC.java
+++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensPigNPC.java
@@ -58,12 +58,16 @@ public class CitizensPigNPC extends CitizensMobNPC implements Equipable {
public EntityPigNPC(World world, NPC npc) {
super(world);
this.npc = (CitizensNPC) npc;
- goalSelector = new PathfinderGoalSelector();
- targetSelector = new PathfinderGoalSelector();
+ if (npc != null) {
+ goalSelector = new PathfinderGoalSelector();
+ targetSelector = new PathfinderGoalSelector();
+ }
}
@Override
public void a(EntityWeatherLighting entityweatherlighting) {
+ if (npc == null)
+ super.a(entityweatherlighting);
}
@Override
@@ -77,5 +81,11 @@ public class CitizensPigNPC extends CitizensMobNPC implements Equipable {
if (npc != null)
npc.update();
}
+
+ @Override
+ public void b_(double x, double y, double z) {
+ // when another entity collides, b_ is called to push the NPC
+ // so we prevent b_ from doing anything.
+ }
}
}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensPigZombieNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensPigZombieNPC.java
index c30865538..435433822 100644
--- a/src/main/java/net/citizensnpcs/npc/entity/CitizensPigZombieNPC.java
+++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensPigZombieNPC.java
@@ -31,8 +31,10 @@ public class CitizensPigZombieNPC extends CitizensMobNPC {
public EntityPigZombieNPC(World world, NPC npc) {
super(world);
this.npc = (CitizensNPC) npc;
- goalSelector = new PathfinderGoalSelector();
- targetSelector = new PathfinderGoalSelector();
+ if (npc != null) {
+ goalSelector = new PathfinderGoalSelector();
+ targetSelector = new PathfinderGoalSelector();
+ }
}
@Override
@@ -47,5 +49,11 @@ public class CitizensPigZombieNPC extends CitizensMobNPC {
public NPC getNPC() {
return npc;
}
+
+ @Override
+ public void b_(double x, double y, double z) {
+ // when another entity collides, b_ is called to push the NPC
+ // so we prevent b_ from doing anything.
+ }
}
}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensSheepNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensSheepNPC.java
index f6a593277..167779da4 100644
--- a/src/main/java/net/citizensnpcs/npc/entity/CitizensSheepNPC.java
+++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensSheepNPC.java
@@ -49,7 +49,8 @@ public class CitizensSheepNPC extends CitizensMobNPC implements Equipable {
equipper.setItemInHand(hand);
} else {
getTrait(WoolColor.class).setColor(DyeColor.WHITE);
- Messaging.send(equipper, StringHelper.wrap(getName()) + " is now " + StringHelper.wrap("white") + ".");
+ Messaging.send(equipper, StringHelper.wrap(getName()) + " is now " + StringHelper.wrap("white")
+ + ".");
}
}
@@ -68,8 +69,10 @@ public class CitizensSheepNPC extends CitizensMobNPC implements Equipable {
public EntitySheepNPC(World world, NPC npc) {
super(world);
this.npc = (CitizensNPC) npc;
- goalSelector = new PathfinderGoalSelector();
- targetSelector = new PathfinderGoalSelector();
+ if (npc != null) {
+ goalSelector = new PathfinderGoalSelector();
+ targetSelector = new PathfinderGoalSelector();
+ }
}
@Override
@@ -83,5 +86,11 @@ public class CitizensSheepNPC extends CitizensMobNPC implements Equipable {
if (npc != null)
npc.update();
}
+
+ @Override
+ public void b_(double x, double y, double z) {
+ // when another entity collides, b_ is called to push the NPC
+ // so we prevent b_ from doing anything.
+ }
}
}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensSilverfishNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensSilverfishNPC.java
index 8d4784345..2139cda36 100644
--- a/src/main/java/net/citizensnpcs/npc/entity/CitizensSilverfishNPC.java
+++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensSilverfishNPC.java
@@ -31,8 +31,10 @@ public class CitizensSilverfishNPC extends CitizensMobNPC {
public EntitySilverfishNPC(World world, NPC npc) {
super(world);
this.npc = (CitizensNPC) npc;
- goalSelector = new PathfinderGoalSelector();
- targetSelector = new PathfinderGoalSelector();
+ if (npc != null) {
+ goalSelector = new PathfinderGoalSelector();
+ targetSelector = new PathfinderGoalSelector();
+ }
}
@Override
@@ -46,5 +48,11 @@ public class CitizensSilverfishNPC extends CitizensMobNPC {
if (npc != null)
npc.update();
}
+
+ @Override
+ public void b_(double x, double y, double z) {
+ // when another entity collides, b_ is called to push the NPC
+ // so we prevent b_ from doing anything.
+ }
}
}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensSkeletonNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensSkeletonNPC.java
index 9a246d7c8..d1c44b8cf 100644
--- a/src/main/java/net/citizensnpcs/npc/entity/CitizensSkeletonNPC.java
+++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensSkeletonNPC.java
@@ -31,8 +31,10 @@ public class CitizensSkeletonNPC extends CitizensMobNPC {
public EntitySkeletonNPC(World world, NPC npc) {
super(world);
this.npc = (CitizensNPC) npc;
- goalSelector = new PathfinderGoalSelector();
- targetSelector = new PathfinderGoalSelector();
+ if (npc != null) {
+ goalSelector = new PathfinderGoalSelector();
+ targetSelector = new PathfinderGoalSelector();
+ }
}
@Override
@@ -46,5 +48,11 @@ public class CitizensSkeletonNPC extends CitizensMobNPC {
if (npc != null)
npc.update();
}
+
+ @Override
+ public void b_(double x, double y, double z) {
+ // when another entity collides, b_ is called to push the NPC
+ // so we prevent b_ from doing anything.
+ }
}
}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensSlimeNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensSlimeNPC.java
index 75d2b9405..133b44077 100644
--- a/src/main/java/net/citizensnpcs/npc/entity/CitizensSlimeNPC.java
+++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensSlimeNPC.java
@@ -31,9 +31,11 @@ public class CitizensSlimeNPC extends CitizensMobNPC {
public EntitySlimeNPC(World world, NPC npc) {
super(world);
this.npc = (CitizensNPC) npc;
- setSize(3);
- goalSelector = new PathfinderGoalSelector();
- targetSelector = new PathfinderGoalSelector();
+ if (npc != null) {
+ setSize(3);
+ goalSelector = new PathfinderGoalSelector();
+ targetSelector = new PathfinderGoalSelector();
+ }
}
@Override
@@ -47,5 +49,11 @@ public class CitizensSlimeNPC extends CitizensMobNPC {
if (npc != null)
npc.update();
}
+
+ @Override
+ public void b_(double x, double y, double z) {
+ // when another entity collides, b_ is called to push the NPC
+ // so we prevent b_ from doing anything.
+ }
}
}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensSnowmanNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensSnowmanNPC.java
index 98b5f10b4..75c764b0b 100644
--- a/src/main/java/net/citizensnpcs/npc/entity/CitizensSnowmanNPC.java
+++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensSnowmanNPC.java
@@ -27,8 +27,10 @@ public class CitizensSnowmanNPC extends CitizensMobNPC {
public EntitySnowmanNPC(World world, NPC npc) {
super(world);
this.npc = (CitizensNPC) npc;
- goalSelector = new PathfinderGoalSelector();
- targetSelector = new PathfinderGoalSelector();
+ if (npc != null) {
+ goalSelector = new PathfinderGoalSelector();
+ targetSelector = new PathfinderGoalSelector();
+ }
}
@Override
@@ -41,5 +43,11 @@ public class CitizensSnowmanNPC extends CitizensMobNPC {
super.z_();
npc.update();
}
+
+ @Override
+ public void b_(double x, double y, double z) {
+ // when another entity collides, b_ is called to push the NPC
+ // so we prevent b_ from doing anything.
+ }
}
}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensSpiderNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensSpiderNPC.java
index 654cf5a3d..fce102fbe 100644
--- a/src/main/java/net/citizensnpcs/npc/entity/CitizensSpiderNPC.java
+++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensSpiderNPC.java
@@ -31,8 +31,10 @@ public class CitizensSpiderNPC extends CitizensMobNPC {
public EntitySpiderNPC(World world, NPC npc) {
super(world);
this.npc = (CitizensNPC) npc;
- goalSelector = new PathfinderGoalSelector();
- targetSelector = new PathfinderGoalSelector();
+ if (npc != null) {
+ goalSelector = new PathfinderGoalSelector();
+ targetSelector = new PathfinderGoalSelector();
+ }
}
@Override
@@ -46,5 +48,11 @@ public class CitizensSpiderNPC extends CitizensMobNPC {
if (npc != null)
npc.update();
}
+
+ @Override
+ public void b_(double x, double y, double z) {
+ // when another entity collides, b_ is called to push the NPC
+ // so we prevent b_ from doing anything.
+ }
}
}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensSquidNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensSquidNPC.java
index 74fe80ffd..47cf51c21 100644
--- a/src/main/java/net/citizensnpcs/npc/entity/CitizensSquidNPC.java
+++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensSquidNPC.java
@@ -31,8 +31,10 @@ public class CitizensSquidNPC extends CitizensMobNPC {
public EntitySquidNPC(World world, NPC npc) {
super(world);
this.npc = (CitizensNPC) npc;
- goalSelector = new PathfinderGoalSelector();
- targetSelector = new PathfinderGoalSelector();
+ if (npc != null) {
+ goalSelector = new PathfinderGoalSelector();
+ targetSelector = new PathfinderGoalSelector();
+ }
}
@Override
@@ -47,5 +49,11 @@ public class CitizensSquidNPC extends CitizensMobNPC {
public NPC getNPC() {
return npc;
}
+
+ @Override
+ public void b_(double x, double y, double z) {
+ // when another entity collides, b_ is called to push the NPC
+ // so we prevent b_ from doing anything.
+ }
}
}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensVillagerNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensVillagerNPC.java
index eea34b8bb..02c88c347 100644
--- a/src/main/java/net/citizensnpcs/npc/entity/CitizensVillagerNPC.java
+++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensVillagerNPC.java
@@ -31,8 +31,10 @@ public class CitizensVillagerNPC extends CitizensMobNPC {
public EntityVillagerNPC(World world, NPC npc) {
super(world);
this.npc = (CitizensNPC) npc;
- goalSelector = new PathfinderGoalSelector();
- targetSelector = new PathfinderGoalSelector();
+ if (npc != null) {
+ goalSelector = new PathfinderGoalSelector();
+ targetSelector = new PathfinderGoalSelector();
+ }
}
@Override
@@ -46,5 +48,11 @@ public class CitizensVillagerNPC extends CitizensMobNPC {
if (npc != null)
npc.update();
}
+
+ @Override
+ public void b_(double x, double y, double z) {
+ // when another entity collides, b_ is called to push the NPC
+ // so we prevent b_ from doing anything.
+ }
}
}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensWolfNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensWolfNPC.java
index 1b58b8b34..0a7e9e09f 100644
--- a/src/main/java/net/citizensnpcs/npc/entity/CitizensWolfNPC.java
+++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensWolfNPC.java
@@ -31,8 +31,10 @@ public class CitizensWolfNPC extends CitizensMobNPC {
public EntityWolfNPC(World world, NPC npc) {
super(world);
this.npc = (CitizensNPC) npc;
- goalSelector = new PathfinderGoalSelector();
- targetSelector = new PathfinderGoalSelector();
+ if (npc != null) {
+ goalSelector = new PathfinderGoalSelector();
+ targetSelector = new PathfinderGoalSelector();
+ }
}
@Override
@@ -46,5 +48,11 @@ public class CitizensWolfNPC extends CitizensMobNPC {
if (npc != null)
npc.update();
}
+
+ @Override
+ public void b_(double x, double y, double z) {
+ // when another entity collides, b_ is called to push the NPC
+ // so we prevent b_ from doing anything.
+ }
}
}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensZombieNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensZombieNPC.java
index ab6bda757..ef1ddcc11 100644
--- a/src/main/java/net/citizensnpcs/npc/entity/CitizensZombieNPC.java
+++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensZombieNPC.java
@@ -31,8 +31,10 @@ public class CitizensZombieNPC extends CitizensMobNPC {
public EntityZombieNPC(World world, NPC npc) {
super(world);
this.npc = (CitizensNPC) npc;
- goalSelector = new PathfinderGoalSelector();
- targetSelector = new PathfinderGoalSelector();
+ if (npc != null) {
+ goalSelector = new PathfinderGoalSelector();
+ targetSelector = new PathfinderGoalSelector();
+ }
}
@Override
@@ -46,5 +48,11 @@ public class CitizensZombieNPC extends CitizensMobNPC {
if (npc != null)
npc.update();
}
+
+ @Override
+ public void b_(double x, double y, double z) {
+ // when another entity collides, b_ is called to push the NPC
+ // so we prevent b_ from doing anything.
+ }
}
}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java b/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java
index aa83e7677..a49358b50 100644
--- a/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java
+++ b/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java
@@ -81,4 +81,10 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
a(aW, aX);
X = yaw; // TODO: this looks jerky
}
+
+ @Override
+ public void b_(double x, double y, double z) {
+ // when another entity collides, b_ is called to push the NPC
+ // so we prevent b_ from doing anything.
+ }
}
\ No newline at end of file
diff --git a/src/main/java/net/citizensnpcs/trait/Age.java b/src/main/java/net/citizensnpcs/trait/Age.java
index d3991bd96..36930889b 100644
--- a/src/main/java/net/citizensnpcs/trait/Age.java
+++ b/src/main/java/net/citizensnpcs/trait/Age.java
@@ -6,7 +6,7 @@ import net.citizensnpcs.api.util.DataKey;
import org.bukkit.entity.Ageable;
-public class Age extends Trait implements Runnable, Toggleable {
+public class Age extends Trait implements Toggleable {
private int age = 0;
private boolean ageable = false;
private boolean locked = true;
@@ -24,7 +24,7 @@ public class Age extends Trait implements Runnable, Toggleable {
}
@Override
- public void onNPCSpawn() {
+ public void onSpawn() {
if (npc instanceof Ageable) {
Ageable entity = (Ageable) npc.getBukkitEntity();
entity.setAge(age);
diff --git a/src/main/java/net/citizensnpcs/trait/Behaviour.java b/src/main/java/net/citizensnpcs/trait/Behaviour.java
index c1316d790..4b22d02b6 100644
--- a/src/main/java/net/citizensnpcs/trait/Behaviour.java
+++ b/src/main/java/net/citizensnpcs/trait/Behaviour.java
@@ -57,9 +57,9 @@ public class Behaviour extends Trait {
}
@Override
- public void onNPCSpawn() {
+ public void onSpawn() {
for (Entry entry : addedGoals.entrySet()) {
- npc.getAI().addGoal(entry.getValue(), entry.getKey());
+ npc.getDefaultGoalController().addGoal(entry.getKey(), entry.getValue());
}
}
@@ -70,7 +70,7 @@ public class Behaviour extends Trait {
private void removeGoals() {
for (Goal entry : addedGoals.keySet()) {
- npc.getAI().removeGoal(entry);
+ npc.getDefaultGoalController().removeGoal(entry);
}
}
@@ -98,7 +98,7 @@ public class Behaviour extends Trait {
if (!npc.isSpawned())
return;
for (Entry entry : goals.goals.entrySet()) {
- npc.getAI().addGoal(entry.getValue(), entry.getKey());
+ npc.getDefaultGoalController().addGoal(entry.getKey(), entry.getValue());
}
}
@@ -111,7 +111,7 @@ public class Behaviour extends Trait {
public static class Goals {
private final Map goals = Maps.newHashMap();
- public void addGoal(int priority, Goal goal) {
+ public void addGoal(Goal goal, int priority) {
Validate.notNull(goal);
goals.put(goal, priority);
}
diff --git a/src/main/java/net/citizensnpcs/trait/Controllable.java b/src/main/java/net/citizensnpcs/trait/Controllable.java
index 30657b165..11e77c988 100644
--- a/src/main/java/net/citizensnpcs/trait/Controllable.java
+++ b/src/main/java/net/citizensnpcs/trait/Controllable.java
@@ -11,12 +11,11 @@ import net.minecraft.server.EntityPlayer;
import org.bukkit.craftbukkit.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.event.EventHandler;
-import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
//TODO: reduce reliance on CitizensNPC
-public class Controllable extends Trait implements Runnable, Listener, Toggleable {
+public class Controllable extends Trait implements Toggleable {
private boolean enabled;
public Controllable(NPC npc) {
@@ -86,6 +85,7 @@ public class Controllable extends Trait implements Runnable, Listener, Toggleabl
public boolean toggle() {
return (enabled = !enabled);
}
+
private static final double AIR_SPEED = 1.5;
private static final double GROUND_SPEED = 4;
diff --git a/src/main/java/net/citizensnpcs/trait/CurrentLocation.java b/src/main/java/net/citizensnpcs/trait/CurrentLocation.java
index 4614c52d9..0cb55c0cd 100644
--- a/src/main/java/net/citizensnpcs/trait/CurrentLocation.java
+++ b/src/main/java/net/citizensnpcs/trait/CurrentLocation.java
@@ -7,7 +7,7 @@ import net.citizensnpcs.api.util.DataKey;
import org.bukkit.Bukkit;
import org.bukkit.Location;
-public class CurrentLocation extends Trait implements Runnable {
+public class CurrentLocation extends Trait {
private Location loc;
public CurrentLocation() {
diff --git a/src/main/java/net/citizensnpcs/trait/LookClose.java b/src/main/java/net/citizensnpcs/trait/LookClose.java
index 1c8c635d5..2d8de7572 100644
--- a/src/main/java/net/citizensnpcs/trait/LookClose.java
+++ b/src/main/java/net/citizensnpcs/trait/LookClose.java
@@ -15,7 +15,7 @@ import org.bukkit.craftbukkit.entity.CraftLivingEntity;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
-public class LookClose extends Trait implements Runnable, Toggleable {
+public class LookClose extends Trait implements Toggleable {
private boolean enabled = Setting.DEFAULT_LOOK_CLOSE.asBoolean();
private Player lookingAt;
@@ -84,7 +84,7 @@ public class LookClose extends Trait implements Runnable, Toggleable {
@Override
public void run() {
- if (!enabled || npc.getAI().hasDestination())
+ if (!enabled || npc.getNavigator().isNavigating())
return;
if (hasInvalidTarget()) {
findNewTarget();
diff --git a/src/main/java/net/citizensnpcs/trait/Powered.java b/src/main/java/net/citizensnpcs/trait/Powered.java
index b41d7445e..5a976e668 100644
--- a/src/main/java/net/citizensnpcs/trait/Powered.java
+++ b/src/main/java/net/citizensnpcs/trait/Powered.java
@@ -19,7 +19,7 @@ public class Powered extends Trait implements Toggleable {
}
@Override
- public void onNPCSpawn() {
+ public void onSpawn() {
if (npc.getBukkitEntity() instanceof Creeper)
((Creeper) npc.getBukkitEntity()).setPowered(powered);
}
diff --git a/src/main/java/net/citizensnpcs/trait/Saddle.java b/src/main/java/net/citizensnpcs/trait/Saddle.java
index 5a32fb700..86c22bc29 100644
--- a/src/main/java/net/citizensnpcs/trait/Saddle.java
+++ b/src/main/java/net/citizensnpcs/trait/Saddle.java
@@ -7,10 +7,9 @@ import net.citizensnpcs.api.util.DataKey;
import org.bukkit.entity.Pig;
import org.bukkit.event.EventHandler;
-import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEntityEvent;
-public class Saddle extends Trait implements Toggleable, Listener {
+public class Saddle extends Trait implements Toggleable {
private boolean pig;
private boolean saddle;
@@ -24,7 +23,7 @@ public class Saddle extends Trait implements Toggleable, Listener {
}
@Override
- public void onNPCSpawn() {
+ public void onSpawn() {
if (npc.getBukkitEntity() instanceof Pig) {
((Pig) npc.getBukkitEntity()).setSaddle(saddle);
pig = true;
diff --git a/src/main/java/net/citizensnpcs/trait/Sheared.java b/src/main/java/net/citizensnpcs/trait/Sheared.java
index 05e33de8a..e116c979a 100644
--- a/src/main/java/net/citizensnpcs/trait/Sheared.java
+++ b/src/main/java/net/citizensnpcs/trait/Sheared.java
@@ -7,10 +7,9 @@ import net.citizensnpcs.api.util.DataKey;
import org.bukkit.entity.Sheep;
import org.bukkit.event.EventHandler;
-import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerShearEntityEvent;
-public class Sheared extends Trait implements Toggleable, Listener {
+public class Sheared extends Trait implements Toggleable {
private boolean sheared;
public Sheared() {
@@ -23,7 +22,7 @@ public class Sheared extends Trait implements Toggleable, Listener {
}
@Override
- public void onNPCSpawn() {
+ public void onSpawn() {
((Sheep) npc.getBukkitEntity()).setSheared(sheared);
}
diff --git a/src/main/java/net/citizensnpcs/trait/VillagerProfession.java b/src/main/java/net/citizensnpcs/trait/VillagerProfession.java
index 8638ad6a0..b89cab228 100644
--- a/src/main/java/net/citizensnpcs/trait/VillagerProfession.java
+++ b/src/main/java/net/citizensnpcs/trait/VillagerProfession.java
@@ -24,7 +24,7 @@ public class VillagerProfession extends Trait {
}
@Override
- public void onNPCSpawn() {
+ public void onSpawn() {
if (npc.getBukkitEntity() instanceof Villager)
((Villager) npc.getBukkitEntity()).setProfession(profession);
}
diff --git a/src/main/java/net/citizensnpcs/trait/WoolColor.java b/src/main/java/net/citizensnpcs/trait/WoolColor.java
index 354480d29..e3006428c 100644
--- a/src/main/java/net/citizensnpcs/trait/WoolColor.java
+++ b/src/main/java/net/citizensnpcs/trait/WoolColor.java
@@ -8,10 +8,9 @@ import net.citizensnpcs.api.util.DataKey;
import org.bukkit.DyeColor;
import org.bukkit.entity.Sheep;
import org.bukkit.event.EventHandler;
-import org.bukkit.event.Listener;
import org.bukkit.event.entity.SheepDyeWoolEvent;
-public class WoolColor extends Trait implements Listener {
+public class WoolColor extends Trait {
private DyeColor color = DyeColor.WHITE;
boolean sheep = false;
@@ -29,7 +28,7 @@ public class WoolColor extends Trait implements Listener {
}
@Override
- public void onNPCSpawn() {
+ public void onSpawn() {
if (npc.getBukkitEntity() instanceof Sheep) {
((Sheep) npc.getBukkitEntity()).setColor(color);
sheep = true;
diff --git a/src/main/java/net/citizensnpcs/trait/text/Text.java b/src/main/java/net/citizensnpcs/trait/text/Text.java
index 015d90381..44dc9bf68 100644
--- a/src/main/java/net/citizensnpcs/trait/text/Text.java
+++ b/src/main/java/net/citizensnpcs/trait/text/Text.java
@@ -96,7 +96,7 @@ public class Text extends Trait implements Runnable, Toggleable, Listener, Conve
}
@Override
- public void onNPCSpawn() {
+ public void onSpawn() {
if (text.isEmpty())
populateDefaultText();
}
diff --git a/src/main/java/net/citizensnpcs/trait/waypoint/LinearWaypointProvider.java b/src/main/java/net/citizensnpcs/trait/waypoint/LinearWaypointProvider.java
index c675591d6..f467325ea 100644
--- a/src/main/java/net/citizensnpcs/trait/waypoint/LinearWaypointProvider.java
+++ b/src/main/java/net/citizensnpcs/trait/waypoint/LinearWaypointProvider.java
@@ -3,7 +3,6 @@ package net.citizensnpcs.trait.waypoint;
import java.util.Iterator;
import java.util.List;
-import net.citizensnpcs.api.ai.NavigationCallback;
import net.citizensnpcs.api.util.DataKey;
import net.citizensnpcs.editor.Editor;
import net.citizensnpcs.util.Messaging;
@@ -21,7 +20,7 @@ import org.bukkit.event.player.PlayerItemHeldEvent;
import com.google.common.collect.Lists;
public class LinearWaypointProvider implements WaypointProvider, Iterable {
- private final GenericWaypointCallback callback = new GenericWaypointCallback(this);
+ private final PassiveWaypointCycler cycler = new PassiveWaypointCycler(this);
private final List waypoints = Lists.newArrayList();
@Override
@@ -41,35 +40,37 @@ public class LinearWaypointProvider implements WaypointProvider, Iterable%d, %d, %d", location.getBlockX(), location.getBlockY(),
- location.getBlockZ());
+ return String.format("%d, %d, %d", location.getBlockX(),
+ location.getBlockY(), location.getBlockZ());
}
@EventHandler
- @SuppressWarnings("unused")
public void onPlayerInteract(PlayerInteractEvent event) {
if (!event.getPlayer().equals(player) || event.getAction() == Action.PHYSICAL)
return;
- if (event.getAction() == Action.LEFT_CLICK_BLOCK || event.getAction() == Action.LEFT_CLICK_AIR) {
+ if (event.getAction() == Action.LEFT_CLICK_BLOCK
+ || event.getAction() == Action.LEFT_CLICK_AIR) {
if (event.getClickedBlock() == null)
return;
Location at = event.getClickedBlock().getLocation();
waypoints.add(Math.max(0, editingSlot), new Waypoint(at));
editingSlot = Math.min(editingSlot + 1, waypoints.size());
- Messaging.send(player, String.format("Added a waypoint at (" + formatLoc(at)
- + ") (%d, %d)", editingSlot + 1, waypoints.size()));
+ Messaging.send(
+ player,
+ String.format("Added a waypoint at (" + formatLoc(at)
+ + ") (%d, %d)", editingSlot + 1, waypoints.size()));
} else if (waypoints.size() > 0) {
editingSlot = Math.min(0, Math.max(waypoints.size() - 1, editingSlot));
waypoints.remove(editingSlot);
editingSlot = Math.max(0, editingSlot - 1);
- Messaging.send(player, String.format("Removed a waypoint (%d remaining) (%d)",
- waypoints.size(), editingSlot + 1));
+ Messaging.send(player, String.format(
+ "Removed a waypoint (%d remaining) (%d)", waypoints.size(),
+ editingSlot + 1));
}
- callback.onProviderChanged();
+ cycler.onProviderChanged();
}
@EventHandler
- @SuppressWarnings("unused")
public void onPlayerItemHeldChange(PlayerItemHeldEvent event) {
if (!event.getPlayer().equals(player) || waypoints.size() == 0)
return;
@@ -97,11 +98,6 @@ public class LinearWaypointProvider implements WaypointProvider, Iterable iterator() {
return waypoints.iterator();
@@ -111,15 +107,15 @@ public class LinearWaypointProvider implements WaypointProvider, Iterable itr;
private final Iterable provider;
- public GenericWaypointCallback(Iterable provider) {
+ public PassiveWaypointCycler(Iterable provider) {
this.provider = provider;
}
@@ -26,24 +21,7 @@ public class GenericWaypointCallback extends NavigationCallback {
}
}
- @Override
- public void onAttach(AI ai) {
- this.ai = ai;
- executing |= !ai.hasDestination();
- if (!executing)
- return;
- if (dest == null) {
- ensureItr();
- if (itr.hasNext()) {
- dest = itr.next().getLocation();
- }
- }
- if (dest != null) {
- ai.setDestination(dest);
- }
- }
-
- @Override
+ /*@Override
public boolean onCancel(AI ai, CancelReason reason) {
if (hackfix) {
hackfix = false;
@@ -90,5 +68,8 @@ public class GenericWaypointCallback extends NavigationCallback {
if (dest != null) {
ai.setDestination(dest);
}
+ }*/
+
+ public void onProviderChanged() {
}
}
diff --git a/src/main/java/net/citizensnpcs/trait/waypoint/WaypointProvider.java b/src/main/java/net/citizensnpcs/trait/waypoint/WaypointProvider.java
index 720cd6a27..ed48f1c66 100644
--- a/src/main/java/net/citizensnpcs/trait/waypoint/WaypointProvider.java
+++ b/src/main/java/net/citizensnpcs/trait/waypoint/WaypointProvider.java
@@ -1,7 +1,5 @@
package net.citizensnpcs.trait.waypoint;
-import net.citizensnpcs.api.ai.AI;
-import net.citizensnpcs.api.ai.NavigationCallback;
import net.citizensnpcs.api.util.DataKey;
import net.citizensnpcs.editor.Editor;
@@ -18,14 +16,6 @@ public interface WaypointProvider {
*/
public Editor createEditor(Player player);
- /**
- * Returns the {@link NavigationCallback} linked to this provider. This will
- * be linked to the NPC's {@link AI}.
- *
- * @return The callback in use
- */
- public NavigationCallback getCallback();
-
/**
* Loads from the specified {@link DataKey}.
*
@@ -34,7 +24,11 @@ public interface WaypointProvider {
*/
public void load(DataKey key);
- public void onAttach();
+ /**
+ * Called when the NPC attached to this provider's {@link Waypoints} is
+ * spawned.
+ */
+ public void onSpawn();
/**
* Saves to the specified {@link DataKey}.
diff --git a/src/main/java/net/citizensnpcs/trait/waypoint/Waypoints.java b/src/main/java/net/citizensnpcs/trait/waypoint/Waypoints.java
index 6f738a725..10ec896e7 100644
--- a/src/main/java/net/citizensnpcs/trait/waypoint/Waypoints.java
+++ b/src/main/java/net/citizensnpcs/trait/waypoint/Waypoints.java
@@ -49,8 +49,9 @@ public class Waypoints extends Trait {
}
@Override
- public void onNPCSpawn() {
- npc.getAI().registerNavigationCallback(provider.getCallback());
+ public void onSpawn() {
+ if (provider != null)
+ provider.onSpawn();
}
@Override