Minor optimisations and changes

This commit is contained in:
fullwall 2012-03-27 22:42:15 +08:00
parent fd4b07f7e3
commit 5c0b32e8a3
55 changed files with 831 additions and 771 deletions

View File

@ -46,16 +46,15 @@ import org.bukkit.plugin.java.JavaPlugin;
import com.google.common.collect.Iterators;
public class Citizens extends JavaPlugin {
private static final String COMPATIBLE_MC_VERSION = "1.2.4";
private final CitizensCharacterManager characterManager = new CitizensCharacterManager();
private final CommandManager commands = new CommandManager();
private Settings config;
private boolean compatible;
private final CitizensCharacterManager characterManager = new CitizensCharacterManager();
private CitizensTraitManager traitManager;
private Settings config;
private CitizensNPCManager npcManager;
private Storage saves; // TODO: refactor this into an NPCStore (remove
// dependency on Storage).
private CitizensTraitManager traitManager;
public CommandManager getCommandManager() {
return commands;
@ -149,7 +148,10 @@ public class Citizens extends JavaPlugin {
try {
saves = new DatabaseStorage(Setting.DATABASE_DRIVER.asString(), Setting.DATABASE_URL.asString(),
Setting.DATABASE_USERNAME.asString(), Setting.DATABASE_PASSWORD.asString());
saves.getKey("test.one").setString("two", "empty");
Messaging.log(saves.getKey("test.one").getString("two"));
} catch (SQLException e) {
e.printStackTrace();
Messaging.log("Unable to connect to database, falling back to YAML");
saves = new YamlStorage(getDataFolder() + File.separator + "saves.yml", "Citizens NPC Storage");
}
@ -157,6 +159,8 @@ public class Citizens extends JavaPlugin {
saves = new YamlStorage(getDataFolder() + File.separator + "saves.yml", "Citizens NPC Storage");
}
Messaging.log("Save method set to", saves.toString());
// Register API managers
npcManager = new CitizensNPCManager(this, saves);
traitManager = new CitizensTraitManager(this);
@ -249,8 +253,15 @@ public class Citizens extends JavaPlugin {
if (!key.keyExists("name"))
throw new NPCLoadException("Could not find a name for the NPC with ID '" + id + "'.");
NPC npc = npcManager.createNPC(EntityType.valueOf(key.getString("traits.type").toUpperCase()), id,
key.getString("name"), null);
EntityType type = EntityType.fromName(key.getString("traits.type"));
if (type == null) {
try {
type = EntityType.valueOf(key.getString("traits.type"));
} catch (IllegalArgumentException ex) {
throw new NPCLoadException("type not recognised");
}
}
NPC npc = npcManager.createNPC(type, id, key.getString("name"), null);
try {
((CitizensNPC) npc).load(key);
} catch (NPCException ex) {
@ -281,4 +292,6 @@ public class Citizens extends JavaPlugin {
}
return false;
}
private static final String COMPATIBLE_MC_VERSION = "1.2.4";
}

View File

@ -47,6 +47,18 @@ public class EventListen implements Listener {
this.npcManager = npcManager;
}
private boolean isSettingFulfilled(Player player, Setting setting) {
String parts = setting.asString();
if (parts.contains("*"))
return true;
for (String part : Splitter.on(',').split(parts)) {
if (Material.matchMaterial(part) == player.getItemInHand().getType()) {
return true;
}
}
return false;
}
/*
* Chunk events
*/
@ -107,6 +119,14 @@ public class EventListen implements Listener {
}
}
@EventHandler
public void onEntityDeath(EntityDeathEvent event) {
if (!npcManager.isNPC(event.getEntity()))
return;
NPC npc = npcManager.getNPC(event.getEntity());
npc.despawn();
}
@EventHandler
public void onEntityTarget(EntityTargetEvent event) {
if (event.isCancelled() || !npcManager.isNPC(event.getEntity()) || !(event.getTarget() instanceof Player))
@ -139,14 +159,6 @@ public class EventListen implements Listener {
npc.getCharacter().onRightClick(npc, player);
}
@EventHandler
public void onEntityDeath(EntityDeathEvent event) {
if (!npcManager.isNPC(event.getEntity()))
return;
NPC npc = npcManager.getNPC(event.getEntity());
npc.despawn();
}
/*
* Player events
*/
@ -206,16 +218,4 @@ public class EventListen implements Listener {
private Pair<Integer, Integer> toIntPair(Chunk chunk) {
return new Pair<Integer, Integer>(chunk.getX(), chunk.getZ());
}
private boolean isSettingFulfilled(Player player, Setting setting) {
String parts = setting.asString();
if (parts.contains("*"))
return true;
for (String part : Splitter.on(',').split(parts)) {
if (Material.matchMaterial(part) == player.getItemInHand().getType()) {
return true;
}
}
return false;
}
}

View File

@ -10,8 +10,6 @@ import net.citizensnpcs.api.util.YamlStorage;
import net.citizensnpcs.util.Messaging;
public class Settings {
private static Storage config;
public Settings(File folder) {
config = new YamlStorage(folder + File.separator + "config.yml", "Citizens Configuration");
}
@ -26,6 +24,7 @@ public class Settings {
} else
setting.set(root.getRaw(setting.path));
}
config.save();
}
public void save() {
@ -50,7 +49,7 @@ public class Settings {
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"),
USE_DATABASE("use-database", false);
USE_DATABASE("database.use", false);
private String path;
private Object value;
@ -60,13 +59,6 @@ public class Settings {
this.value = value;
}
public List<String> asList(String path) {
List<String> list = new ArrayList<String>();
for (DataKey key : config.getKey(path).getIntegerSubKeys())
list.add(key.getString(""));
return list;
}
public boolean asBoolean() {
return (Boolean) value;
}
@ -79,6 +71,14 @@ public class Settings {
return Integer.parseInt(value.toString());
}
// TODO: single values only in a field, remove this
public List<String> asList(String path) {
List<String> list = new ArrayList<String>();
for (DataKey key : config.getKey(path).getIntegerSubKeys())
list.add(key.getString(""));
return list;
}
public long asLong() {
return (Long) value;
}
@ -95,4 +95,6 @@ public class Settings {
this.value = value;
}
}
private static Storage config;
}

View File

@ -1,8 +1,5 @@
package net.citizensnpcs.command.command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import net.citizensnpcs.Citizens;
import net.citizensnpcs.api.exception.NPCLoadException;
import net.citizensnpcs.api.npc.NPC;
@ -14,6 +11,9 @@ import net.citizensnpcs.command.exception.CommandException;
import net.citizensnpcs.util.Messaging;
import net.citizensnpcs.util.StringHelper;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@Requirements
public class AdminCommands {
private final Citizens plugin;

View File

@ -44,6 +44,24 @@ public class HelpCommands {
throw new CommandException("The page '" + page + "' does not exist.");
}
private List<String> getLines(CommandSender sender, String baseCommand) {
// Ensures that commands with multiple modifiers are only added once
Set<Command> cmds = new HashSet<Command>();
List<String> lines = new ArrayList<String>();
for (Command cmd : cmdManager.getCommands(baseCommand)) {
if (cmds.contains(cmd)
|| (!sender.hasPermission("citizens.admin") && !sender
.hasPermission("citizens." + cmd.permission())))
continue;
lines.add("<7>/<c>" + cmd.aliases()[0] + (cmd.usage().isEmpty() ? "" : " " + cmd.usage()) + " <7>- <e>"
+ cmd.desc());
if (cmd.modifiers().length > 1)
cmds.add(cmd);
}
return lines;
}
@Command(
aliases = { "npc" },
usage = "help (page)",
@ -62,22 +80,4 @@ public class HelpCommands {
if (!paginator.sendPage(sender, page))
throw new CommandException("The page '" + page + "' does not exist.");
}
private List<String> getLines(CommandSender sender, String baseCommand) {
// Ensures that commands with multiple modifiers are only added once
Set<Command> cmds = new HashSet<Command>();
List<String> lines = new ArrayList<String>();
for (Command cmd : cmdManager.getCommands(baseCommand)) {
if (cmds.contains(cmd)
|| (!sender.hasPermission("citizens.admin") && !sender
.hasPermission("citizens." + cmd.permission())))
continue;
lines.add("<7>/<c>" + cmd.aliases()[0] + (cmd.usage().isEmpty() ? "" : " " + cmd.usage()) + " <7>- <e>"
+ cmd.desc());
if (cmd.modifiers().length > 1)
cmds.add(cmd);
}
return lines;
}
}

View File

@ -47,6 +47,44 @@ public class NPCCommands {
npcManager = plugin.getNPCManager();
}
@Command(
aliases = { "npc" },
usage = "age [age] (-l)",
desc = "Set the age of a NPC",
flags = "l",
modifiers = { "age" },
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 })
public void age(CommandContext args, Player player, NPC npc) throws CommandException {
Age trait = npc.getTrait(Age.class);
if (args.argsLength() > 1) {
int age = 0;
String ageStr = "an adult";
try {
age = args.getInteger(1);
if (age < -24000 || age > 0)
throw new CommandException("Invalid age. Valid: adult, baby, number between -24000 and 0");
ageStr = "age " + age;
} catch (NumberFormatException ex) {
if (args.getString(1).equalsIgnoreCase("baby")) {
age = -24000;
ageStr = "a baby";
} else if (!args.getString(1).equalsIgnoreCase("adult"))
throw new CommandException("Invalid age. Valid: adult, baby, number between -24000 and 0");
}
trait.setAge(age);
Messaging.send(player, StringHelper.wrap(npc.getName()) + " is now " + ageStr + ".");
}
if (args.hasFlag('l'))
Messaging.send(player, "<a>Age " + (trait.toggle() ? "locked" : "unlocked") + ".");
}
@Command(
aliases = { "npc" },
usage = "character [character]",
@ -93,12 +131,13 @@ public class NPCCommands {
name = name.substring(0, 15);
}
EntityType type = EntityType.PLAYER;
if (args.hasValueFlag("type"))
try {
type = EntityType.valueOf(args.getFlag("type").toUpperCase().replace('-', '_'));
} catch (IllegalArgumentException ex) {
if (args.hasValueFlag("type")) {
type = EntityType.fromName(args.getFlag("type"));
if (type == null) {
Messaging.sendError(player, "'" + args.getFlag("type")
+ "' is not a valid mob type. Using default NPC.");
type = EntityType.PLAYER;
}
}
npc = npcManager.createNPC(type, name);
String msg = ChatColor.GREEN + "You created " + StringHelper.wrap(npc.getName());
@ -279,6 +318,43 @@ public class NPCCommands {
+ " is now the owner of " + StringHelper.wrap(npc.getName()) + ".");
}
@Command(
aliases = { "npc" },
usage = "power",
desc = "Toggle a creeper NPC as powered",
modifiers = { "power" },
min = 1,
max = 1,
permission = "npc.power")
@Requirements(selected = true, ownership = true, types = { EntityType.CREEPER })
public void power(CommandContext args, Player player, NPC npc) {
String msg = StringHelper.wrap(npc.getName()) + " will "
+ (npc.getTrait(Powered.class).toggle() ? "now" : "no longer");
Messaging.send(player, msg += " be powered.");
}
@Command(
aliases = { "npc" },
usage = "profession [profession]",
desc = "Set a NPC's profession",
modifiers = { "profession" },
min = 2,
max = 2,
permission = "npc.profession")
@Requirements(selected = true, ownership = true, types = { EntityType.VILLAGER })
public void profession(CommandContext args, Player player, NPC npc) throws CommandException {
String profession = args.getString(1);
try {
npc.getTrait(VillagerProfession.class).setProfession(Profession.valueOf(profession.toUpperCase()));
Messaging.send(
player,
StringHelper.wrap(npc.getName()) + " is now the profession "
+ StringHelper.wrap(profession.toUpperCase()) + ".");
} catch (IllegalArgumentException ex) {
throw new CommandException("'" + profession + "' is not a valid profession.");
}
}
@Command(
aliases = { "npc" },
usage = "remove (all)",
@ -404,79 +480,4 @@ public class NPCCommands {
npc.getBukkitEntity().teleport(player, TeleportCause.COMMAND);
Messaging.send(player, StringHelper.wrap(npc.getName()) + " was teleported to your location.");
}
@Command(
aliases = { "npc" },
usage = "power",
desc = "Toggle a creeper NPC as powered",
modifiers = { "power" },
min = 1,
max = 1,
permission = "npc.power")
@Requirements(selected = true, ownership = true, types = { EntityType.CREEPER })
public void power(CommandContext args, Player player, NPC npc) {
String msg = StringHelper.wrap(npc.getName()) + " will "
+ (npc.getTrait(Powered.class).toggle() ? "now" : "no longer");
Messaging.send(player, msg += " be powered.");
}
@Command(
aliases = { "npc" },
usage = "profession [profession]",
desc = "Set a NPC's profession",
modifiers = { "profession" },
min = 2,
max = 2,
permission = "npc.profession")
@Requirements(selected = true, ownership = true, types = { EntityType.VILLAGER })
public void profession(CommandContext args, Player player, NPC npc) throws CommandException {
String profession = args.getString(1);
try {
npc.getTrait(VillagerProfession.class).setProfession(Profession.valueOf(profession.toUpperCase()));
Messaging.send(
player,
StringHelper.wrap(npc.getName()) + " is now the profession "
+ StringHelper.wrap(profession.toUpperCase()) + ".");
} catch (IllegalArgumentException ex) {
throw new CommandException("'" + profession + "' is not a valid profession.");
}
}
@Command(
aliases = { "npc" },
usage = "age [age] (-l)",
desc = "Set the age of a NPC",
flags = "l",
modifiers = { "age" },
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 })
public void age(CommandContext args, Player player, NPC npc) throws CommandException {
Age trait = npc.getTrait(Age.class);
if (args.argsLength() > 1) {
int age = 0;
String ageStr = "an adult";
try {
age = args.getInteger(1);
if (age < -24000 || age > 0)
throw new CommandException("Invalid age. Valid: adult, baby, number between -24000 and 0");
ageStr = "age " + age;
} catch (NumberFormatException ex) {
if (args.getString(1).equalsIgnoreCase("baby")) {
age = -24000;
ageStr = "a baby";
} else if (!args.getString(1).equalsIgnoreCase("adult"))
throw new CommandException("Invalid age. Valid: adult, baby, number between -24000 and 0");
}
trait.setAge(age);
Messaging.send(player, StringHelper.wrap(npc.getName()) + " is now " + ageStr + ".");
}
if (args.hasFlag('l'))
Messaging.send(player, "<a>Age " + (trait.toggle() ? "locked" : "unlocked") + ".");
}
}

View File

@ -10,12 +10,12 @@ import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
public abstract class Editor implements Listener {
private static final Map<String, Editor> editing = new HashMap<String, Editor>();
public abstract void begin();
public abstract void end();
private static final Map<String, Editor> editing = new HashMap<String, Editor>();
private static void enter(Player player, Editor editor) {
editor.begin();
player.getServer().getPluginManager()

View File

@ -11,6 +11,11 @@ import net.citizensnpcs.api.npc.character.CharacterManager;
public class CitizensCharacterManager implements CharacterManager {
private final Map<String, Character> registered = new HashMap<String, Character>();
@Override
public Character getCharacter(String name) {
return registered.get(name);
}
@Override
public void registerCharacter(CharacterFactory factory) {
try {
@ -20,9 +25,4 @@ public class CitizensCharacterManager implements CharacterManager {
ex.printStackTrace();
}
}
@Override
public Character getCharacter(String name) {
return registered.get(name);
}
}

View File

@ -31,8 +31,8 @@ import org.bukkit.plugin.Plugin;
public abstract class CitizensNPC extends AbstractNPC {
private final CitizensAI ai = new CitizensAI(this);
private final CitizensNPCManager manager;
private final CitizensTraitManager traitManager;
protected EntityLiving mcEntity;
private final CitizensTraitManager traitManager;
protected CitizensNPC(CitizensNPCManager manager, int id, String name) {
super(id, name);
@ -129,6 +129,39 @@ public abstract class CitizensNPC extends AbstractNPC {
return getHandle() != null;
}
public void load(DataKey root) throws NPCLoadException {
Character character = CitizensAPI.getCharacterManager().getCharacter(root.getString("character"));
// Load the character if it exists
if (character != null) {
character.load(root.getRelative("characters." + character.getName()));
setCharacter(character);
}
// Load traits
for (DataKey traitKey : root.getRelative("traits").getSubKeys()) {
Trait trait = traitManager.getTrait(traitKey.name(), this);
if (trait == null)
throw new NPCLoadException("No trait with the name '" + traitKey.name()
+ "' exists. Was it registered properly?");
addTrait(trait);
try {
getTrait(trait.getClass()).load(traitKey);
} catch (Exception ex) {
Bukkit.getLogger().log(
Level.SEVERE,
"[Citizens] The trait '" + traitKey.name()
+ "' failed to load properly for the NPC with the ID '" + getId() + "'. "
+ ex.getMessage());
ex.printStackTrace();
}
}
// Spawn the NPC
if (getTrait(Spawned.class).shouldSpawn())
spawn(getTrait(CurrentLocation.class).getLocation());
}
@Override
public void remove() {
super.remove();
@ -137,6 +170,23 @@ public abstract class CitizensNPC extends AbstractNPC {
despawn();
}
public void save(DataKey root) {
root.setString("name", getFullName());
// Save the character if it exists
if (getCharacter() != null) {
root.setString("character", getCharacter().getName());
getCharacter().save(root.getRelative("characters." + getCharacter().getName()));
}
// Save all existing traits
for (Map<Class<? extends Trait>, Trait> map : traits.values()) {
for (Trait trait : map.values()) {
trait.save(root.getRelative("traits." + trait.getName()));
}
}
}
@Override
public void setName(String name) {
super.setName(name);
@ -176,52 +226,4 @@ public abstract class CitizensNPC extends AbstractNPC {
super.update();
ai.update();
}
public void load(DataKey root) throws NPCLoadException {
Character character = CitizensAPI.getCharacterManager().getCharacter(root.getString("character"));
// Load the character if it exists
if (character != null) {
character.load(root.getRelative("characters." + character.getName()));
setCharacter(character);
}
// Load traits
for (DataKey traitKey : root.getRelative("traits").getSubKeys()) {
Trait trait = traitManager.getTrait(traitKey.name(), this);
if (trait == null)
throw new NPCLoadException("No trait with the name '" + traitKey.name()
+ "' exists. Was it registered properly?");
addTrait(trait);
try {
getTrait(trait.getClass()).load(traitKey);
} catch (Exception ex) {
Bukkit.getLogger().log(
Level.SEVERE,
"[Citizens] The trait '" + traitKey.name()
+ "' failed to load properly for the NPC with the ID '" + getId() + "'. "
+ ex.getMessage());
ex.printStackTrace();
}
}
// Spawn the NPC
if (getTrait(Spawned.class).shouldSpawn())
spawn(getTrait(CurrentLocation.class).getLocation());
}
public void save(DataKey root) {
root.setString("name", getFullName());
// Save the character if it exists
if (getCharacter() != null) {
root.setString("character", getCharacter().getName());
getCharacter().save(root.getRelative("characters." + getCharacter().getName()));
}
// Save all existing traits
for (Plugin plugin : traits.keySet())
for (Trait trait : getTraits(plugin))
trait.save(root.getRelative("traits." + trait.getName()));
}
}

View File

@ -38,6 +38,7 @@ public class CitizensNPCManager implements NPCManager {
public NPC createNPC(EntityType type, int id, String name, Character character) {
CitizensNPC npc = npcBuilder.getByType(type, this, id, name);
if (character != null)
npc.setCharacter(character);
npcs.put(npc.getId(), npc);
return npc;
@ -110,6 +111,21 @@ public class CitizensNPCManager implements NPCManager {
removeMetadata(npc);
}
public void removeAll() {
while (iterator().hasNext())
iterator().next().remove();
}
private void removeMetadata(NPC npc) {
// Remove metadata from selectors
if (npc.hasMetadata("selectors")) {
for (MetadataValue value : npc.getMetadata("selectors"))
if (Bukkit.getPlayer(value.asString()) != null)
Bukkit.getPlayer(value.asString()).removeMetadata("selected", plugin);
npc.removeMetadata("selectors", plugin);
}
}
public void safeRemove() throws NPCLoadException {
// Destroy all NPCs everywhere besides storage
while (iterator().hasNext()) {
@ -120,11 +136,6 @@ public class CitizensNPCManager implements NPCManager {
}
}
public void removeAll() {
while (iterator().hasNext())
iterator().next().remove();
}
public void selectNPC(Player player, NPC npc) {
// Remove existing selection if any
if (player.hasMetadata("selected"))
@ -139,14 +150,4 @@ public class CitizensNPCManager implements NPCManager {
// Call selection event
player.getServer().getPluginManager().callEvent(new NPCSelectEvent(npc, player));
}
private void removeMetadata(NPC npc) {
// Remove metadata from selectors
if (npc.hasMetadata("selectors")) {
for (MetadataValue value : npc.getMetadata("selectors"))
if (Bukkit.getPlayer(value.asString()) != null)
Bukkit.getPlayer(value.asString()).removeMetadata("selected", plugin);
npc.removeMetadata("selectors", plugin);
}
}
}

View File

@ -29,8 +29,8 @@ import net.citizensnpcs.trait.text.Text;
import net.citizensnpcs.trait.waypoint.Waypoints;
public class CitizensTraitManager implements TraitManager {
private final Map<Plugin, Map<String, Class<? extends Trait>>> registered = new HashMap<Plugin, Map<String, Class<? extends Trait>>>();
private final Map<Class<? extends Trait>, Constructor<? extends Trait>> CACHED_CTORS = new HashMap<Class<? extends Trait>, Constructor<? extends Trait>>();
private final Map<Plugin, Map<String, Class<? extends Trait>>> registered = new HashMap<Plugin, Map<String, Class<? extends Trait>>>();
public CitizensTraitManager(Citizens plugin) {
// Register Citizens traits
@ -51,57 +51,6 @@ public class CitizensTraitManager implements TraitManager {
registerTrait(new TraitFactory(WoolColor.class).withName("wool-color").withPlugin(plugin));
}
@Override
public <T extends Trait> T getTrait(Class<T> clazz) {
return getTrait(clazz, null);
}
@SuppressWarnings("unchecked")
@Override
public <T extends Trait> T getTrait(String name) {
for (Plugin plugin : registered.keySet()) {
if (!registered.get(plugin).containsKey(name))
return null;
return (T) create(registered.get(plugin).get(name), null);
}
return null;
}
@Override
public void registerTrait(TraitFactory factory) {
Map<String, Class<? extends Trait>> map = registered.get(factory.getTraitPlugin());
if (map == null)
map = new HashMap<String, Class<? extends Trait>>();
map.put(factory.getTraitName(), factory.getTraitClass());
registered.put(factory.getTraitPlugin(), map);
}
@SuppressWarnings("unchecked")
public <T extends Trait> T getTrait(Class<T> clazz, NPC npc) {
for (Entry<Plugin, Map<String, Class<? extends Trait>>> entry : registered.entrySet()) {
for (Entry<String, Class<? extends Trait>> subEntry : entry.getValue().entrySet()) {
if (!subEntry.getValue().equals(clazz))
continue;
Trait trait = create(subEntry.getValue(), npc);
trait.setName(subEntry.getKey());
trait.setPlugin(entry.getKey());
return (T) trait;
}
}
return null;
}
@SuppressWarnings("unchecked")
public <T extends Trait> T getTrait(String name, NPC npc) {
for (Plugin plugin : registered.keySet()) {
Class<? extends Trait> clazz = registered.get(plugin).get(name);
if (clazz == null)
continue;
return (T) getTrait(clazz, npc);
}
return null;
}
@SuppressWarnings("unchecked")
private <T extends Trait> T create(Class<T> trait, NPC npc) {
Constructor<? extends Trait> constructor;
@ -126,4 +75,55 @@ public class CitizensTraitManager implements TraitManager {
return null;
}
}
@Override
public <T extends Trait> T getTrait(Class<T> clazz) {
return getTrait(clazz, null);
}
@SuppressWarnings("unchecked")
public <T extends Trait> T getTrait(Class<T> clazz, NPC npc) {
for (Entry<Plugin, Map<String, Class<? extends Trait>>> entry : registered.entrySet()) {
for (Entry<String, Class<? extends Trait>> subEntry : entry.getValue().entrySet()) {
if (!subEntry.getValue().equals(clazz))
continue;
Trait trait = create(subEntry.getValue(), npc);
trait.setName(subEntry.getKey());
trait.setPlugin(entry.getKey());
return (T) trait;
}
}
return null;
}
@SuppressWarnings("unchecked")
@Override
public <T extends Trait> T getTrait(String name) {
for (Plugin plugin : registered.keySet()) {
if (!registered.get(plugin).containsKey(name))
return null;
return (T) create(registered.get(plugin).get(name), null);
}
return null;
}
@SuppressWarnings("unchecked")
public <T extends Trait> T getTrait(String name, NPC npc) {
for (Plugin plugin : registered.keySet()) {
Class<? extends Trait> clazz = registered.get(plugin).get(name);
if (clazz == null)
continue;
return (T) getTrait(clazz, npc);
}
return null;
}
@Override
public void registerTrait(TraitFactory factory) {
Map<String, Class<? extends Trait>> map = registered.get(factory.getTraitPlugin());
if (map == null)
map = new HashMap<String, Class<? extends Trait>>();
map.put(factory.getTraitName(), factory.getTraitClass());
registered.put(factory.getTraitPlugin(), map);
}
}

View File

@ -1,6 +1,7 @@
package net.citizensnpcs.npc.ai;
import java.lang.reflect.Field;
import java.util.Map;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.entity.EntityHumanNPC;
@ -8,11 +9,14 @@ 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 Navigation navigation;
private EntityHumanNPC entity = null;
private final Navigation navigation;
MCNavigationStrategy(CitizensNPC npc, Location dest) {
if (npc.getBukkitEntity() instanceof Player) {
@ -37,13 +41,20 @@ public class MCNavigationStrategy implements PathStrategy {
}
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 {
Field field = EntityLiving.class.getDeclaredField("bb");
field.setAccessible(true);
return field.getFloat(from);
} catch (Exception ex) {
float speed = SPEED_FIELD.getFloat(from);
MOVEMENT_SPEEDS.put(from.getBukkitEntity().getType(), speed);
return speed;
} catch (IllegalAccessException ex) {
ex.printStackTrace();
return 0.7F;
return DEFAULT_SPEED;
}
}
@ -58,4 +69,22 @@ public class MCNavigationStrategy implements PathStrategy {
}
return navigation.e();
}
private static final float DEFAULT_SPEED = 0.3F;
private static final Map<EntityType, Float> 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();
}
}
}

View File

@ -24,11 +24,6 @@ public class CitizensBlazeNPC extends CitizensMobNPC {
public static class EntityBlazeNPC extends EntityBlaze implements NPCHandle {
private final NPC npc;
@Override
public NPC getNPC() {
return npc;
}
public EntityBlazeNPC(World world, NPC npc) {
super(world);
this.npc = npc;
@ -39,5 +34,10 @@ public class CitizensBlazeNPC extends CitizensMobNPC {
@Override
public void d_() {
}
@Override
public NPC getNPC() {
return npc;
}
}
}

View File

@ -24,11 +24,6 @@ public class CitizensCaveSpiderNPC extends CitizensMobNPC {
public static class EntityCaveSpiderNPC extends EntityCaveSpider implements NPCHandle {
private final NPC npc;
@Override
public NPC getNPC() {
return npc;
}
public EntityCaveSpiderNPC(World world, NPC npc) {
super(world);
this.npc = npc;
@ -39,5 +34,10 @@ public class CitizensCaveSpiderNPC extends CitizensMobNPC {
@Override
public void d_() {
}
@Override
public NPC getNPC() {
return npc;
}
}
}

View File

@ -24,11 +24,6 @@ public class CitizensChickenNPC extends CitizensMobNPC {
public static class EntityChickenNPC extends EntityChicken implements NPCHandle {
private final NPC npc;
@Override
public NPC getNPC() {
return npc;
}
public EntityChickenNPC(World world, NPC npc) {
super(world);
this.npc = npc;
@ -39,5 +34,10 @@ public class CitizensChickenNPC extends CitizensMobNPC {
@Override
public void d_() {
}
@Override
public NPC getNPC() {
return npc;
}
}
}

View File

@ -24,11 +24,6 @@ public class CitizensCowNPC extends CitizensMobNPC {
public static class EntityCowNPC extends EntityCow implements NPCHandle {
private final NPC npc;
@Override
public NPC getNPC() {
return npc;
}
public EntityCowNPC(World world, NPC npc) {
super(world);
this.npc = npc;
@ -39,5 +34,10 @@ public class CitizensCowNPC extends CitizensMobNPC {
@Override
public void d_() {
}
@Override
public NPC getNPC() {
return npc;
}
}
}

View File

@ -25,11 +25,6 @@ public class CitizensCreeperNPC extends CitizensMobNPC {
public static class EntityCreeperNPC extends EntityCreeper implements NPCHandle {
private final NPC npc;
@Override
public NPC getNPC() {
return npc;
}
public EntityCreeperNPC(World world, NPC npc) {
super(world);
this.npc = npc;
@ -37,12 +32,17 @@ public class CitizensCreeperNPC extends CitizensMobNPC {
targetSelector = new PathfinderGoalSelector();
}
@Override
public void a(EntityWeatherLighting entityweatherlighting) {
}
@Override
public void d_() {
}
@Override
public void a(EntityWeatherLighting entityweatherlighting) {
public NPC getNPC() {
return npc;
}
}
}

View File

@ -24,11 +24,6 @@ public class CitizensEnderDragonNPC extends CitizensMobNPC {
public static class EntityEnderDragonNPC extends EntityEnderDragon implements NPCHandle {
private final NPC npc;
@Override
public NPC getNPC() {
return npc;
}
public EntityEnderDragonNPC(World world, NPC npc) {
super(world);
this.npc = npc;
@ -43,5 +38,10 @@ public class CitizensEnderDragonNPC extends CitizensMobNPC {
@Override
public void e() {
}
@Override
public NPC getNPC() {
return npc;
}
}
}

View File

@ -23,11 +23,6 @@ public class CitizensEndermanNPC extends CitizensMobNPC implements Equipable {
super(manager, id, name, EntityEndermanNPC.class);
}
@Override
public Enderman getBukkitEntity() {
return (Enderman) getHandle().getBukkitEntity();
}
@Override
public void equip(Player equipper) {
ItemStack hand = equipper.getItemInHand();
@ -59,14 +54,14 @@ public class CitizensEndermanNPC extends CitizensMobNPC implements Equipable {
getTrait(Equipment.class).set(0, set);
}
@Override
public Enderman getBukkitEntity() {
return (Enderman) getHandle().getBukkitEntity();
}
public static class EntityEndermanNPC extends EntityEnderman implements NPCHandle {
private final NPC npc;
@Override
public NPC getNPC() {
return npc;
}
public EntityEndermanNPC(World world, NPC npc) {
super(world);
this.npc = npc;
@ -81,5 +76,10 @@ public class CitizensEndermanNPC extends CitizensMobNPC implements Equipable {
@Override
public void e() {
}
@Override
public NPC getNPC() {
return npc;
}
}
}

View File

@ -24,11 +24,6 @@ public class CitizensGhastNPC extends CitizensMobNPC {
public static class EntityGhastNPC extends EntityGhast implements NPCHandle {
private final NPC npc;
@Override
public NPC getNPC() {
return npc;
}
public EntityGhastNPC(World world, NPC npc) {
super(world);
this.npc = npc;
@ -39,5 +34,10 @@ public class CitizensGhastNPC extends CitizensMobNPC {
@Override
public void d_() {
}
@Override
public NPC getNPC() {
return npc;
}
}
}

View File

@ -24,11 +24,6 @@ public class CitizensGiantNPC extends CitizensMobNPC {
public static class EntityGiantNPC extends EntityGiantZombie implements NPCHandle {
private final NPC npc;
@Override
public NPC getNPC() {
return npc;
}
public EntityGiantNPC(World world, NPC npc) {
super(world);
this.npc = npc;
@ -39,5 +34,10 @@ public class CitizensGiantNPC extends CitizensMobNPC {
@Override
public void d_() {
}
@Override
public NPC getNPC() {
return npc;
}
}
}

View File

@ -34,39 +34,6 @@ public class CitizensHumanNPC extends CitizensNPC implements Equipable {
return handle;
}
@Override
public Player getBukkitEntity() {
return getHandle().getBukkitEntity();
}
@Override
public EntityHumanNPC getHandle() {
return (EntityHumanNPC) mcEntity;
}
@Override
public void load(DataKey key) throws NPCLoadException {
super.load(key);
}
@Override
public void setName(String name) {
super.setName(name);
Location prev = getBukkitEntity().getLocation();
despawn();
spawn(prev);
}
@Override
public void update() {
super.update();
if (isSpawned() && getBukkitEntity().getLocation().getChunk().isLoaded()) {
mcEntity.move(0, -0.1, 0);
// gravity! also works around an entity.onGround not updating issue
// (onGround is normally updated by the client)
}
}
@Override
public void equip(Player equipper) {
ItemStack hand = equipper.getItemInHand();
@ -132,4 +99,37 @@ public class CitizensHumanNPC extends CitizensNPC implements Equipable {
}
trait.set(slot, set);
}
@Override
public Player getBukkitEntity() {
return getHandle().getBukkitEntity();
}
@Override
public EntityHumanNPC getHandle() {
return (EntityHumanNPC) mcEntity;
}
@Override
public void load(DataKey key) throws NPCLoadException {
super.load(key);
}
@Override
public void setName(String name) {
super.setName(name);
Location prev = getBukkitEntity().getLocation();
despawn();
spawn(prev);
}
@Override
public void update() {
super.update();
if (isSpawned() && getBukkitEntity().getLocation().getChunk().isLoaded()) {
mcEntity.move(0, -0.1, 0);
// gravity! also works around an entity.onGround not updating issue
// (onGround is normally updated by the client)
}
}
}

View File

@ -24,11 +24,6 @@ public class CitizensIronGolemNPC extends CitizensMobNPC {
public static class EntityIronGolemNPC extends EntityIronGolem implements NPCHandle {
private final NPC npc;
@Override
public NPC getNPC() {
return npc;
}
public EntityIronGolemNPC(World world, NPC npc) {
super(world);
this.npc = npc;
@ -39,5 +34,10 @@ public class CitizensIronGolemNPC extends CitizensMobNPC {
@Override
public void d_() {
}
@Override
public NPC getNPC() {
return npc;
}
}
}

View File

@ -24,11 +24,6 @@ public class CitizensMagmaCubeNPC extends CitizensMobNPC {
public static class EntityMagmaCubeNPC extends EntityMagmaCube implements NPCHandle {
private final NPC npc;
@Override
public NPC getNPC() {
return npc;
}
public EntityMagmaCubeNPC(World world, NPC npc) {
super(world);
this.npc = npc;
@ -40,5 +35,10 @@ public class CitizensMagmaCubeNPC extends CitizensMobNPC {
@Override
public void d_() {
}
@Override
public NPC getNPC() {
return npc;
}
}
}

View File

@ -24,11 +24,6 @@ public class CitizensMushroomCowNPC extends CitizensMobNPC {
public static class EntityMushroomCowNPC extends EntityMushroomCow implements NPCHandle {
private final NPC npc;
@Override
public NPC getNPC() {
return npc;
}
public EntityMushroomCowNPC(World world, NPC npc) {
super(world);
this.npc = npc;
@ -39,5 +34,10 @@ public class CitizensMushroomCowNPC extends CitizensMobNPC {
@Override
public void d_() {
}
@Override
public NPC getNPC() {
return npc;
}
}
}

View File

@ -24,11 +24,6 @@ public class CitizensOcelotNPC extends CitizensMobNPC {
public static class EntityOcelotNPC extends EntityOcelot implements NPCHandle {
private final NPC npc;
@Override
public NPC getNPC() {
return npc;
}
public EntityOcelotNPC(World world, NPC npc) {
super(world);
this.npc = npc;
@ -39,5 +34,10 @@ public class CitizensOcelotNPC extends CitizensMobNPC {
@Override
public void d_() {
}
@Override
public NPC getNPC() {
return npc;
}
}
}

View File

@ -24,11 +24,6 @@ public class CitizensPigNPC extends CitizensMobNPC implements Equipable {
super(manager, id, name, EntityPigNPC.class);
}
@Override
public Pig getBukkitEntity() {
return (Pig) getHandle().getBukkitEntity();
}
@Override
public void equip(Player equipper) {
ItemStack hand = equipper.getItemInHand();
@ -48,14 +43,14 @@ public class CitizensPigNPC extends CitizensMobNPC implements Equipable {
}
}
@Override
public Pig getBukkitEntity() {
return (Pig) getHandle().getBukkitEntity();
}
public static class EntityPigNPC extends EntityPig implements NPCHandle {
private final NPC npc;
@Override
public NPC getNPC() {
return npc;
}
public EntityPigNPC(World world, NPC npc) {
super(world);
this.npc = npc;
@ -63,12 +58,17 @@ public class CitizensPigNPC extends CitizensMobNPC implements Equipable {
targetSelector = new PathfinderGoalSelector();
}
@Override
public void a(EntityWeatherLighting entityweatherlighting) {
}
@Override
public void d_() {
}
@Override
public void a(EntityWeatherLighting entityweatherlighting) {
public NPC getNPC() {
return npc;
}
}
}

View File

@ -24,11 +24,6 @@ public class CitizensPigZombieNPC extends CitizensMobNPC {
public static class EntityPigZombieNPC extends EntityPigZombie implements NPCHandle {
private final NPC npc;
@Override
public NPC getNPC() {
return npc;
}
public EntityPigZombieNPC(World world, NPC npc) {
super(world);
this.npc = npc;
@ -39,5 +34,10 @@ public class CitizensPigZombieNPC extends CitizensMobNPC {
@Override
public void d_() {
}
@Override
public NPC getNPC() {
return npc;
}
}
}

View File

@ -25,11 +25,6 @@ public class CitizensSheepNPC extends CitizensMobNPC implements Equipable {
super(manager, id, name, EntitySheepNPC.class);
}
@Override
public Sheep getBukkitEntity() {
return (Sheep) getHandle().getBukkitEntity();
}
@Override
public void equip(Player equipper) {
ItemStack hand = equipper.getItemInHand();
@ -58,14 +53,14 @@ public class CitizensSheepNPC extends CitizensMobNPC implements Equipable {
}
}
@Override
public Sheep getBukkitEntity() {
return (Sheep) getHandle().getBukkitEntity();
}
public static class EntitySheepNPC extends EntitySheep implements NPCHandle {
private final NPC npc;
@Override
public NPC getNPC() {
return npc;
}
public EntitySheepNPC(World world, NPC npc) {
super(world);
this.npc = npc;
@ -76,5 +71,10 @@ public class CitizensSheepNPC extends CitizensMobNPC implements Equipable {
@Override
public void d_() {
}
@Override
public NPC getNPC() {
return npc;
}
}
}

View File

@ -24,11 +24,6 @@ public class CitizensSilverfishNPC extends CitizensMobNPC {
public static class EntitySilverfishNPC extends EntitySilverfish implements NPCHandle {
private final NPC npc;
@Override
public NPC getNPC() {
return npc;
}
public EntitySilverfishNPC(World world, NPC npc) {
super(world);
this.npc = npc;
@ -39,5 +34,10 @@ public class CitizensSilverfishNPC extends CitizensMobNPC {
@Override
public void d_() {
}
@Override
public NPC getNPC() {
return npc;
}
}
}

View File

@ -24,11 +24,6 @@ public class CitizensSkeletonNPC extends CitizensMobNPC {
public static class EntitySkeletonNPC extends EntitySkeleton implements NPCHandle {
private final NPC npc;
@Override
public NPC getNPC() {
return npc;
}
public EntitySkeletonNPC(World world, NPC npc) {
super(world);
this.npc = npc;
@ -39,5 +34,10 @@ public class CitizensSkeletonNPC extends CitizensMobNPC {
@Override
public void d_() {
}
@Override
public NPC getNPC() {
return npc;
}
}
}

View File

@ -24,11 +24,6 @@ public class CitizensSlimeNPC extends CitizensMobNPC {
public static class EntitySlimeNPC extends EntitySlime implements NPCHandle {
private final NPC npc;
@Override
public NPC getNPC() {
return npc;
}
public EntitySlimeNPC(World world, NPC npc) {
super(world);
this.npc = npc;
@ -40,5 +35,10 @@ public class CitizensSlimeNPC extends CitizensMobNPC {
@Override
public void d_() {
}
@Override
public NPC getNPC() {
return npc;
}
}
}

View File

@ -24,11 +24,6 @@ public class CitizensSnowmanNPC extends CitizensMobNPC {
public static class EntitySnowmanNPC extends EntitySnowman implements NPCHandle {
private final NPC npc;
@Override
public NPC getNPC() {
return npc;
}
public EntitySnowmanNPC(World world, NPC npc) {
super(world);
this.npc = npc;
@ -39,5 +34,10 @@ public class CitizensSnowmanNPC extends CitizensMobNPC {
@Override
public void d_() {
}
@Override
public NPC getNPC() {
return npc;
}
}
}

View File

@ -24,11 +24,6 @@ public class CitizensSpiderNPC extends CitizensMobNPC {
public static class EntitySpiderNPC extends EntitySpider implements NPCHandle {
private final NPC npc;
@Override
public NPC getNPC() {
return npc;
}
public EntitySpiderNPC(World world, NPC npc) {
super(world);
this.npc = npc;
@ -39,5 +34,10 @@ public class CitizensSpiderNPC extends CitizensMobNPC {
@Override
public void d_() {
}
@Override
public NPC getNPC() {
return npc;
}
}
}

View File

@ -24,11 +24,6 @@ public class CitizensSquidNPC extends CitizensMobNPC {
public static class EntitySquidNPC extends EntitySquid implements NPCHandle {
private final NPC npc;
@Override
public NPC getNPC() {
return npc;
}
public EntitySquidNPC(World world, NPC npc) {
super(world);
this.npc = npc;
@ -39,5 +34,10 @@ public class CitizensSquidNPC extends CitizensMobNPC {
@Override
public void d_() {
}
@Override
public NPC getNPC() {
return npc;
}
}
}

View File

@ -24,11 +24,6 @@ public class CitizensVillagerNPC extends CitizensMobNPC {
public static class EntityVillagerNPC extends EntityVillager implements NPCHandle {
private final NPC npc;
@Override
public NPC getNPC() {
return npc;
}
public EntityVillagerNPC(World world, NPC npc) {
super(world);
this.npc = npc;
@ -39,5 +34,10 @@ public class CitizensVillagerNPC extends CitizensMobNPC {
@Override
public void d_() {
}
@Override
public NPC getNPC() {
return npc;
}
}
}

View File

@ -24,11 +24,6 @@ public class CitizensWolfNPC extends CitizensMobNPC {
public static class EntityWolfNPC extends EntityWolf implements NPCHandle {
private final NPC npc;
@Override
public NPC getNPC() {
return npc;
}
public EntityWolfNPC(World world, NPC npc) {
super(world);
this.npc = npc;
@ -39,5 +34,10 @@ public class CitizensWolfNPC extends CitizensMobNPC {
@Override
public void d_() {
}
@Override
public NPC getNPC() {
return npc;
}
}
}

View File

@ -24,11 +24,6 @@ public class CitizensZombieNPC extends CitizensMobNPC {
public static class EntityZombieNPC extends EntityZombie implements NPCHandle {
private final NPC npc;
@Override
public NPC getNPC() {
return npc;
}
public EntityZombieNPC(World world, NPC npc) {
super(world);
this.npc = npc;
@ -39,5 +34,10 @@ public class CitizensZombieNPC extends CitizensMobNPC {
@Override
public void d_() {
}
@Override
public NPC getNPC() {
return npc;
}
}
}

View File

@ -22,12 +22,6 @@ public class Age extends Trait implements Runnable, Toggleable {
locked = key.getBoolean("locked");
}
@Override
public void save(DataKey key) {
key.setInt("age", age);
key.setBoolean("locked", locked);
}
@Override
public void onNPCSpawn() {
if (npc.getBukkitEntity() instanceof Ageable) {
@ -44,10 +38,9 @@ public class Age extends Trait implements Runnable, Toggleable {
}
@Override
public boolean toggle() {
locked = !locked;
((Ageable) npc.getBukkitEntity()).setAgeLock(locked);
return locked;
public void save(DataKey key) {
key.setInt("age", age);
key.setBoolean("locked", locked);
}
public void setAge(int age) {
@ -56,6 +49,13 @@ public class Age extends Trait implements Runnable, Toggleable {
((Ageable) npc.getBukkitEntity()).setAge(age);
}
@Override
public boolean toggle() {
locked = !locked;
((Ageable) npc.getBukkitEntity()).setAgeLock(locked);
return locked;
}
@Override
public String toString() {
return "Age{age=" + age + ",locked=" + locked + "}";

View File

@ -16,12 +16,8 @@ public class CurrentLocation extends Trait implements Runnable {
this.npc = npc;
}
@Override
public void run() {
if (npc.getBukkitEntity() == null)
return;
loc = npc.getBukkitEntity().getLocation();
public Location getLocation() {
return loc;
}
@Override
@ -29,8 +25,16 @@ public class CurrentLocation extends Trait implements Runnable {
if (Bukkit.getWorld(key.getString("world")) == null)
throw new NPCLoadException("'" + key.getString("world") + "' is not a valid world.");
loc = new Location(Bukkit.getWorld(key.getString("world")), key.getDouble("x"), key.getDouble("y"), key
.getDouble("z"), (float) key.getDouble("yaw"), (float) key.getDouble("pitch"));
loc = new Location(Bukkit.getWorld(key.getString("world")), key.getDouble("x"), key.getDouble("y"),
key.getDouble("z"), (float) key.getDouble("yaw"), (float) key.getDouble("pitch"));
}
@Override
public void run() {
if (npc.getBukkitEntity() == null)
return;
loc = npc.getBukkitEntity().getLocation();
}
@Override
@ -43,10 +47,6 @@ public class CurrentLocation extends Trait implements Runnable {
key.setDouble("pitch", loc.getPitch());
}
public Location getLocation() {
return loc;
}
public void spawn(Location loc) {
this.loc = loc;
}

View File

@ -13,37 +13,13 @@ import org.bukkit.Location;
import org.bukkit.entity.Entity;
public class LookClose extends Trait implements Runnable, Toggleable {
private final NPC npc;
private boolean lookClose = Setting.DEFAULT_LOOK_CLOSE.asBoolean();
private final NPC npc;
public LookClose(NPC npc) {
this.npc = npc;
}
@Override
public void load(DataKey key) throws NPCLoadException {
lookClose = key.getBoolean("");
}
@Override
public void run() {
EntityLiving search = null;
CitizensNPC handle = (CitizensNPC) npc;
if (!npc.getAI().hasDestination() && (search = handle.getHandle().world.findNearbyPlayer(handle.getHandle(), 5)) != null && lookClose)
faceEntity(handle, search.getBukkitEntity());
}
@Override
public void save(DataKey key) {
key.setBoolean("", lookClose);
}
@Override
public boolean toggle() {
lookClose = !lookClose;
return lookClose;
}
private void faceEntity(CitizensNPC npc, Entity target) {
if (npc.getBukkitEntity().getWorld() != target.getWorld())
return;
@ -67,6 +43,31 @@ public class LookClose extends Trait implements Runnable, Toggleable {
npc.getHandle().X = npc.getHandle().yaw;
}
@Override
public void load(DataKey key) throws NPCLoadException {
lookClose = key.getBoolean("");
}
@Override
public void run() {
EntityLiving search = null;
CitizensNPC handle = (CitizensNPC) npc;
if (!npc.getAI().hasDestination()
&& (search = handle.getHandle().world.findNearbyPlayer(handle.getHandle(), 5)) != null && lookClose)
faceEntity(handle, search.getBukkitEntity());
}
@Override
public void save(DataKey key) {
key.setBoolean("", lookClose);
}
@Override
public boolean toggle() {
lookClose = !lookClose;
return lookClose;
}
@Override
public String toString() {
return "LookClose{" + lookClose + "}";

View File

@ -7,8 +7,8 @@ import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.util.DataKey;
public class Powered extends Trait implements Toggleable {
private boolean powered;
private final NPC npc;
private boolean powered;
public Powered(NPC npc) {
this.npc = npc;
@ -19,17 +19,17 @@ public class Powered extends Trait implements Toggleable {
powered = key.getBoolean("");
}
@Override
public void save(DataKey key) {
key.setBoolean("", powered);
}
@Override
public void onNPCSpawn() {
if (npc.getBukkitEntity() instanceof Creeper)
((Creeper) npc.getBukkitEntity()).setPowered(powered);
}
@Override
public void save(DataKey key) {
key.setBoolean("", powered);
}
@Override
public boolean toggle() {
powered = !powered;

View File

@ -12,8 +12,8 @@ import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.util.DataKey;
public class Saddle extends Trait implements Toggleable, Listener {
private boolean saddle;
private final NPC npc;
private boolean saddle;
public Saddle(NPC npc) {
this.npc = npc;
@ -24,30 +24,30 @@ public class Saddle extends Trait implements Toggleable, Listener {
saddle = key.getBoolean("");
}
@Override
public void save(DataKey key) {
key.setBoolean("", saddle);
}
@Override
public void onNPCSpawn() {
if (npc.getBukkitEntity() instanceof Pig)
((Pig) npc.getBukkitEntity()).setSaddle(saddle);
}
@Override
public boolean toggle() {
saddle = !saddle;
((Pig) npc.getBukkitEntity()).setSaddle(saddle);
return saddle;
}
@EventHandler
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
if (CitizensAPI.getNPCManager().isNPC(event.getRightClicked()))
event.setCancelled(true);
}
@Override
public void save(DataKey key) {
key.setBoolean("", saddle);
}
@Override
public boolean toggle() {
saddle = !saddle;
((Pig) npc.getBukkitEntity()).setSaddle(saddle);
return saddle;
}
@Override
public String toString() {
return "Saddle{" + saddle + "}";

View File

@ -12,8 +12,8 @@ import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.util.DataKey;
public class Sheared extends Trait implements Toggleable, Listener {
private boolean sheared;
private final NPC npc;
private boolean sheared;
public Sheared(NPC npc) {
this.npc = npc;
@ -24,30 +24,30 @@ public class Sheared extends Trait implements Toggleable, Listener {
sheared = key.getBoolean("");
}
@Override
public void save(DataKey key) {
key.setBoolean("", sheared);
}
@Override
public void onNPCSpawn() {
if (npc.getBukkitEntity() instanceof Sheep)
((Sheep) npc.getBukkitEntity()).setSheared(sheared);
}
@Override
public boolean toggle() {
sheared = !sheared;
((Sheep) npc.getBukkitEntity()).setSheared(sheared);
return sheared;
}
@EventHandler
public void onPlayerShearEntityEvent(PlayerShearEntityEvent event) {
if (CitizensAPI.getNPCManager().isNPC(event.getEntity()))
event.setCancelled(true);
}
@Override
public void save(DataKey key) {
key.setBoolean("", sheared);
}
@Override
public boolean toggle() {
sheared = !sheared;
((Sheep) npc.getBukkitEntity()).setSheared(sheared);
return sheared;
}
@Override
public String toString() {
return "Sheared{" + sheared + "}";

View File

@ -9,8 +9,8 @@ import org.bukkit.entity.Villager;
import org.bukkit.entity.Villager.Profession;
public class VillagerProfession extends Trait {
private Profession profession = Profession.FARMER;
private final NPC npc;
private Profession profession = Profession.FARMER;
public VillagerProfession(NPC npc) {
this.npc = npc;
@ -25,17 +25,17 @@ public class VillagerProfession extends Trait {
}
}
@Override
public void save(DataKey key) {
key.setString("", profession.name());
}
@Override
public void onNPCSpawn() {
if (npc.getBukkitEntity() instanceof Villager)
((Villager) npc.getBukkitEntity()).setProfession(profession);
}
@Override
public void save(DataKey key) {
key.setString("", profession.name());
}
public void setProfession(Profession profession) {
this.profession = profession;
((Villager) npc.getBukkitEntity()).setProfession(profession);

View File

@ -35,17 +35,17 @@ public class WoolColor extends Trait implements Listener {
((Sheep) npc.getBukkitEntity()).setColor(color);
}
@Override
public void save(DataKey key) {
key.setString("", color.name());
}
@EventHandler
public void onSheepDyeWool(SheepDyeWoolEvent event) {
if (CitizensAPI.getNPCManager().isNPC(event.getEntity()))
event.setCancelled(true);
}
@Override
public void save(DataKey key) {
key.setString("", color.name());
}
public void setColor(DyeColor color) {
this.color = color;
((Sheep) npc.getBukkitEntity()).setColor(color);

View File

@ -30,19 +30,56 @@ import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
public class Text extends Trait implements Runnable, Toggleable, ConversationAbandonedListener {
private final Plugin plugin;
private final NPC npc;
private final List<String> text = new ArrayList<String>();
private final Map<String, Calendar> cooldowns = new HashMap<String, Calendar>();
private boolean talkClose = Setting.DEFAULT_TALK_CLOSE.asBoolean();
private boolean randomTalker = Setting.DEFAULT_RANDOM_TALKER.asBoolean();
private int currentIndex;
private final NPC npc;
private final Plugin plugin;
private boolean randomTalker = Setting.DEFAULT_RANDOM_TALKER.asBoolean();
private boolean talkClose = Setting.DEFAULT_TALK_CLOSE.asBoolean();
private final List<String> text = new ArrayList<String>();
public Text(NPC npc) {
this.npc = npc;
this.plugin = Bukkit.getPluginManager().getPlugin("Citizens");
}
public void add(String string) {
text.add(string);
}
@Override
public void conversationAbandoned(ConversationAbandonedEvent event) {
Bukkit.dispatchCommand((Player) event.getContext().getForWhom(), "npc text");
}
public void edit(int index, String newText) {
text.set(index, newText);
}
public Editor getEditor(final Player player) {
final Conversation conversation = new ConversationFactory(plugin).addConversationAbandonedListener(this)
.withLocalEcho(false).withEscapeSequence("/npc text").withModality(false)
.withFirstPrompt(new StartPrompt(this)).buildConversation(player);
return new Editor() {
@Override
public void begin() {
Messaging.send(player, "<b>Entered the text editor!");
conversation.begin();
}
@Override
public void end() {
Messaging.send(player, "<a>Exited the text editor.");
}
};
}
public boolean hasIndex(int index) {
return text.size() > index;
}
@Override
public void load(DataKey key) throws NPCLoadException {
for (DataKey sub : key.getIntegerSubKeys())
@ -57,17 +94,18 @@ public class Text extends Trait implements Runnable, Toggleable, ConversationAba
}
@Override
public void save(DataKey key) {
key.setBoolean("talk-close", talkClose);
key.setBoolean("random-talker", randomTalker);
for (int i = 0; i < text.size(); i++)
key.setString(String.valueOf(i), text.get(i));
public void onNPCSpawn() {
if (text.isEmpty())
populateDefaultText();
}
@Override
public boolean toggle() {
talkClose = !talkClose;
return talkClose;
private void populateDefaultText() {
for (String line : Setting.DEFAULT_TEXT.asList("npc.default.text"))
text.add(line);
}
public void remove(int index) {
text.remove(index);
}
@Override
@ -97,54 +135,11 @@ public class Text extends Trait implements Runnable, Toggleable, ConversationAba
}
@Override
public void onNPCSpawn() {
if (text.isEmpty())
populateDefaultText();
}
@Override
public void conversationAbandoned(ConversationAbandonedEvent event) {
Bukkit.dispatchCommand((Player) event.getContext().getForWhom(), "npc text");
}
public boolean shouldTalkClose() {
return talkClose;
}
public Editor getEditor(final Player player) {
final Conversation conversation = new ConversationFactory(plugin).addConversationAbandonedListener(this)
.withLocalEcho(false).withEscapeSequence("/npc text").withModality(false)
.withFirstPrompt(new StartPrompt(this)).buildConversation(player);
return new Editor() {
@Override
public void begin() {
Messaging.send(player, "<b>Entered the text editor!");
conversation.begin();
}
@Override
public void end() {
Messaging.send(player, "<a>Exited the text editor.");
}
};
}
public void add(String string) {
text.add(string);
}
public void remove(int index) {
text.remove(index);
}
public void edit(int index, String newText) {
text.set(index, newText);
}
public boolean hasIndex(int index) {
return text.size() > index;
public void save(DataKey key) {
key.setBoolean("talk-close", talkClose);
key.setBoolean("random-talker", randomTalker);
for (int i = 0; i < text.size(); i++)
key.setString(String.valueOf(i), text.get(i));
}
public boolean sendPage(Player player, int page) {
@ -173,16 +168,21 @@ public class Text extends Trait implements Runnable, Toggleable, ConversationAba
return true;
}
public boolean shouldTalkClose() {
return talkClose;
}
@Override
public boolean toggle() {
talkClose = !talkClose;
return talkClose;
}
public boolean toggleRandomTalker() {
randomTalker = !randomTalker;
return randomTalker;
}
private void populateDefaultText() {
for (String line : Setting.DEFAULT_TEXT.asList("npc.default.text"))
text.add(line);
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();

View File

@ -26,8 +26,8 @@ public class StartPrompt extends StringPrompt {
return new TextRemovePrompt(text);
else {
if (input.equalsIgnoreCase("random"))
Messaging.send((Player) context.getForWhom(), "<e>Random talker <a>set to <e>"
+ text.toggleRandomTalker() + "<a>.");
Messaging.send((Player) context.getForWhom(),
"<e>Random talker <a>set to <e>" + text.toggleRandomTalker() + "<a>.");
else if (input.equalsIgnoreCase("close")) {
Messaging.send((Player) context.getForWhom(), "<e>Close talker <a>set to <e>" + text.toggle() + "<a>.");
} else

View File

@ -20,8 +20,8 @@ public class TextAddPrompt extends StringPrompt {
@Override
public Prompt acceptInput(ConversationContext context, String input) {
text.add(input);
Messaging.send((Player) context.getForWhom(), StringHelper.parseColors("<e>Added <a>the entry <e>" + input
+ "."));
Messaging.send((Player) context.getForWhom(),
StringHelper.parseColors("<e>Added <a>the entry <e>" + input + "."));
return new StartPrompt(text);
}

View File

@ -22,6 +22,16 @@ public class Waypoints extends Trait {
npc.getAI().registerNavigationCallback(provider.getCallback());
}
private WaypointProvider create(Class<? extends WaypointProvider> clazz) {
if (!providers.containsKey(clazz))
return null;
try {
return clazz.newInstance();
} catch (Exception ex) {
return null;
}
}
public Editor getEditor(Player player) {
return provider.createEditor(player);
}
@ -51,7 +61,8 @@ public class Waypoints extends Trait {
}
/**
* Sets the current {@link WaypointProvider} by using the given class. The class should have been registered using
* Sets the current {@link WaypointProvider} by using the given class. The
* class should have been registered using
* {@link Waypoints#registerWaypointProvider(Class, String)}.
*
* @param provider
@ -64,20 +75,11 @@ public class Waypoints extends Trait {
}
}
private WaypointProvider create(Class<? extends WaypointProvider> clazz) {
if (!providers.containsKey(clazz))
return null;
try {
return clazz.newInstance();
} catch (Exception ex) {
return null;
}
}
private static final Map<Class<? extends WaypointProvider>, String> providers = new HashMap<Class<? extends WaypointProvider>, String>();
/**
* Registers a {@link WaypointProvider}, which can be subsequently used by NPCs.
* Registers a {@link WaypointProvider}, which can be subsequently used by
* NPCs.
*
* @param clazz
* The class of the waypoint provider

View File

@ -49,12 +49,6 @@ import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.Plugin;
public class Metrics {
private static final String BASE_URL = "http://metrics.griefcraft.com";
private static final String CONFIG_FILE = "plugins/PluginMetrics/config.yml";
private final static int PING_INTERVAL = 10;
private static final String REPORT_URL = "/report/%s";
private final static int REVISION = 4;
private final YamlConfiguration configuration;
private final Map<Plugin, Set<Plotter>> customData = Collections
.synchronizedMap(new HashMap<Plugin, Set<Plotter>>());
@ -205,14 +199,24 @@ public class Metrics {
public abstract int getValue();
public void reset() {
}
@Override
public int hashCode() {
return getColumnName().hashCode() + getValue();
}
public void reset() {
}
}
private static final String BASE_URL = "http://metrics.griefcraft.com";
private static final String CONFIG_FILE = "plugins/PluginMetrics/config.yml";
private final static int PING_INTERVAL = 10;
private static final String REPORT_URL = "/report/%s";
private final static int REVISION = 4;
private static String encode(String text) throws UnsupportedEncodingException {
return URLEncoder.encode(text, "UTF-8");

View File

@ -1,6 +1,6 @@
package net.citizensnpcs.util;
import java.util.HashMap;
import java.util.EnumMap;
import java.util.Map;
import net.citizensnpcs.npc.CitizensNPC;
@ -35,7 +35,22 @@ import net.citizensnpcs.npc.entity.CitizensZombieNPC;
import org.bukkit.entity.EntityType;
public class NPCBuilder {
private static final Map<EntityType, Class<? extends CitizensNPC>> types = new HashMap<EntityType, Class<? extends CitizensNPC>>();
// TODO: convert this into solely a lookup class.
public CitizensNPC getByType(EntityType type, CitizensNPCManager npcManager, int id, String name) {
Class<? extends CitizensNPC> npcClass = types.get(type);
if (npcClass == null)
return null;
try {
return npcClass.getConstructor(CitizensNPCManager.class, int.class, String.class).newInstance(npcManager,
id, name);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
private static final Map<EntityType, Class<? extends CitizensNPC>> types = new EnumMap<EntityType, Class<? extends CitizensNPC>>(
EntityType.class);
static {
types.put(EntityType.BLAZE, CitizensBlazeNPC.class);
@ -65,15 +80,4 @@ public class NPCBuilder {
types.put(EntityType.WOLF, CitizensWolfNPC.class);
types.put(EntityType.ZOMBIE, CitizensZombieNPC.class);
}
public CitizensNPC getByType(EntityType type, CitizensNPCManager npcManager, int id, String name) {
Class<? extends CitizensNPC> npcClass = types.get(type);
try {
return npcClass.getConstructor(CitizensNPCManager.class, int.class, String.class).newInstance(npcManager,
id, name);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
}

View File

@ -6,15 +6,19 @@ import java.util.List;
import org.bukkit.command.CommandSender;
public class Paginator {
private static final int LINES_PER_PAGE = 9;
private String header;
private final List<String> lines = new ArrayList<String>();
public void addLine(String line) {
lines.add(line);
}
public Paginator header(String header) {
this.header = header;
return this;
}
public boolean sendPage(CommandSender sender, int page) {
int pages = (int) ((lines.size() / LINES_PER_PAGE == 0) ? 1 : Math.ceil((double) lines.size() / LINES_PER_PAGE));
if (page < 0 || page > pages)
@ -32,8 +36,5 @@ public class Paginator {
return true;
}
public Paginator header(String header) {
this.header = header;
return this;
}
private static final int LINES_PER_PAGE = 9;
}

View File

@ -6,8 +6,8 @@ public class StringHelper {
public static String capitalize(Object string) {
String capitalize = string.toString();
return capitalize.replaceFirst(String.valueOf(capitalize.charAt(0)), String.valueOf(Character
.toUpperCase(capitalize.charAt(0))));
return capitalize.replaceFirst(String.valueOf(capitalize.charAt(0)),
String.valueOf(Character.toUpperCase(capitalize.charAt(0))));
}
public static int getLevenshteinDistance(String s, String t) {