major character and trait refactor

This commit is contained in:
aPunch 2012-03-07 19:03:32 -06:00
parent 5886289eeb
commit c45c7d919d
10 changed files with 197 additions and 54 deletions

Binary file not shown.

View File

@ -7,19 +7,10 @@ import java.util.logging.Level;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.event.CitizensReloadEvent;
import net.citizensnpcs.api.exception.NPCException;
import net.citizensnpcs.api.exception.NPCLoadException;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.trait.Character;
import net.citizensnpcs.api.trait.DefaultInstanceFactory;
import net.citizensnpcs.api.trait.InstanceFactory;
import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.trait.trait.Equipment;
import net.citizensnpcs.api.trait.trait.Inventory;
import net.citizensnpcs.api.trait.trait.MobType;
import net.citizensnpcs.api.trait.trait.Owner;
import net.citizensnpcs.api.trait.trait.SpawnLocation;
import net.citizensnpcs.api.trait.trait.Spawned;
import net.citizensnpcs.api.util.DataKey;
import net.citizensnpcs.api.util.DatabaseStorage;
import net.citizensnpcs.api.util.Storage;
@ -36,10 +27,9 @@ import net.citizensnpcs.command.exception.ServerCommandException;
import net.citizensnpcs.command.exception.UnhandledCommandException;
import net.citizensnpcs.command.exception.WrappedCommandException;
import net.citizensnpcs.editor.Editor;
import net.citizensnpcs.npc.CitizensCharacterManager;
import net.citizensnpcs.npc.CitizensNPCManager;
import net.citizensnpcs.trait.LookClose;
import net.citizensnpcs.trait.text.Text;
import net.citizensnpcs.trait.waypoint.Waypoints;
import net.citizensnpcs.npc.CitizensTraitManager;
import net.citizensnpcs.util.Messaging;
import net.citizensnpcs.util.Metrics;
import net.citizensnpcs.util.StringHelper;
@ -56,18 +46,16 @@ import org.bukkit.plugin.java.JavaPlugin;
import com.google.common.collect.Iterators;
public class Citizens extends JavaPlugin {
private final InstanceFactory<Character> characterManager = DefaultInstanceFactory.create();
private static final String COMPATIBLE_MC_VERSION = "1.2.3";
private final CommandManager commands = new CommandManager();
private boolean compatible;
private Settings config;
private CitizensCharacterManager characterManager;
private volatile CitizensNPCManager npcManager;
private Storage saves;
private final InstanceFactory<Trait> traitManager = DefaultInstanceFactory.create(Owner.class, Spawned.class,
LookClose.class, SpawnLocation.class, Inventory.class, MobType.class, Waypoints.class, Equipment.class,
Text.class);
public InstanceFactory<Character> getCharacterManager() {
public CitizensCharacterManager getCharacterManager() {
return characterManager;
}
@ -173,9 +161,10 @@ public class Citizens extends JavaPlugin {
// Register API managers
npcManager = new CitizensNPCManager(saves);
characterManager = new CitizensCharacterManager();
CitizensAPI.setNPCManager(npcManager);
CitizensAPI.setCharacterManager(characterManager);
CitizensAPI.setTraitManager(traitManager);
CitizensAPI.setTraitManager(new CitizensTraitManager());
// Register events
getServer().getPluginManager().registerEvents(new EventListen(npcManager), this);
@ -246,6 +235,8 @@ public class Citizens extends JavaPlugin {
saves.load();
setupNPCs();
getServer().getPluginManager().callEvent(new CitizensReloadEvent());
}
public void save() {
@ -294,6 +285,4 @@ public class Citizens extends JavaPlugin {
}
return false;
}
private static final String COMPATIBLE_MC_VERSION = "1.2.3";
}

View File

@ -6,8 +6,7 @@ import java.util.List;
import net.citizensnpcs.Citizens;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.trait.Character;
import net.citizensnpcs.api.trait.InstanceFactory;
import net.citizensnpcs.api.npc.character.Character;
import net.citizensnpcs.api.trait.trait.MobType;
import net.citizensnpcs.api.trait.trait.Owner;
import net.citizensnpcs.api.trait.trait.SpawnLocation;
@ -17,6 +16,7 @@ import net.citizensnpcs.command.CommandContext;
import net.citizensnpcs.command.Requirements;
import net.citizensnpcs.command.exception.CommandException;
import net.citizensnpcs.command.exception.NoPermissionsException;
import net.citizensnpcs.npc.CitizensCharacterManager;
import net.citizensnpcs.npc.CitizensNPCManager;
import net.citizensnpcs.trait.LookClose;
import net.citizensnpcs.util.Messaging;
@ -30,7 +30,7 @@ import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
@Requirements(selected = true, ownership = true)
public class NPCCommands {
private final InstanceFactory<Character> characterManager;
private final CitizensCharacterManager characterManager;
private final CitizensNPCManager npcManager;
public NPCCommands(Citizens plugin) {
@ -47,7 +47,7 @@ public class NPCCommands {
max = 2)
public void character(CommandContext args, Player player, NPC npc) throws CommandException {
String name = args.getString(1).toLowerCase();
Character character = characterManager.getInstance(name, npc);
Character character = characterManager.getCharacter(name);
if (character == null)
throw new CommandException("The character '" + args.getString(1) + "' does not exist.");
if (npc.getCharacter() != null && npc.getCharacter().getName().equalsIgnoreCase(character.getName()))
@ -88,22 +88,22 @@ public class NPCCommands {
boolean success = true;
if (args.hasValueFlag("char")) {
String character = args.getFlag("char").toLowerCase();
if (characterManager.getInstance(character, create) == null) {
if (characterManager.getCharacter(character) == null) {
Messaging.sendError(player, "'" + args.getFlag("char") + "' is not a valid character. "
+ create.getName() + " was created at your location without a character.");
success = false;
} else {
create.setCharacter(characterManager.getInstance(character, create));
create.setCharacter(characterManager.getCharacter(character));
successMsg += " with the character " + StringHelper.wrap(character);
}
}
successMsg += " at your location.";
// Set the owner
create.addTrait(new Owner(player.getName()));
create.getTrait(Owner.class).setOwner(player.getName());
// Set the mob type
create.addTrait(new MobType(type.toString()));
create.getTrait(MobType.class).setType(type.toString());
create.spawn(player.getLocation());
npcManager.selectNPC(player, create);
@ -168,10 +168,10 @@ public class NPCCommands {
if (args.hasValueFlag("char")) {
String character = args.getFlag("char");
if (characterManager.getInstance(character) == null)
if (characterManager.getCharacter(character) == null)
throw new CommandException("'" + character + "' is not a valid character.");
for (NPC add : npcManager.getNPCs(characterManager.getInstance(character).getClass()))
for (NPC add : npcManager.getNPCs(characterManager.getCharacter(character).getClass()))
if (!npcs.contains(add) && add.getCharacter() != null
&& add.getCharacter().getName().equals(character.toLowerCase()))
npcs.add(add);

View File

@ -0,0 +1,28 @@
package net.citizensnpcs.npc;
import java.util.HashMap;
import java.util.Map;
import net.citizensnpcs.api.exception.CharacterException;
import net.citizensnpcs.api.npc.character.Character;
import net.citizensnpcs.api.npc.character.CharacterFactory;
import net.citizensnpcs.api.npc.character.CharacterManager;
public class CitizensCharacterManager implements CharacterManager {
private final Map<String, Character> registered = new HashMap<String, Character>();
@Override
public void registerCharacter(CharacterFactory factory) {
try {
Character character = factory.create();
registered.put(character.getName(), character);
} catch (CharacterException ex) {
ex.printStackTrace();
}
}
@Override
public Character getCharacter(String name) {
return registered.get(name);
}
}

View File

@ -110,9 +110,9 @@ public abstract class CitizensNPC extends AbstractNPC {
mcEntity.world.players.remove(mcEntity);
// Set the location
addTrait(new SpawnLocation(loc));
getTrait(SpawnLocation.class).setLocation(loc);
// Set the spawned state
addTrait(new Spawned(true));
getTrait(Spawned.class).setSpawned(true);
return true;
}

View File

@ -9,7 +9,7 @@ import net.citizensnpcs.Citizens;
import net.citizensnpcs.api.event.NPCSelectEvent;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.npc.NPCManager;
import net.citizensnpcs.api.trait.Character;
import net.citizensnpcs.api.npc.character.Character;
import net.citizensnpcs.api.trait.trait.SpawnLocation;
import net.citizensnpcs.api.util.Storage;
import net.citizensnpcs.editor.Editor;

View File

@ -0,0 +1,110 @@
package net.citizensnpcs.npc;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;
import net.citizensnpcs.api.exception.TraitException;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.trait.TraitFactory;
import net.citizensnpcs.api.trait.TraitManager;
import net.citizensnpcs.api.trait.trait.Equipment;
import net.citizensnpcs.api.trait.trait.Inventory;
import net.citizensnpcs.api.trait.trait.MobType;
import net.citizensnpcs.api.trait.trait.Owner;
import net.citizensnpcs.api.trait.trait.Spawned;
import net.citizensnpcs.api.trait.trait.SpawnLocation;
import net.citizensnpcs.trait.LookClose;
import net.citizensnpcs.trait.text.Text;
import net.citizensnpcs.trait.waypoint.Waypoints;
public class CitizensTraitManager implements TraitManager {
private final Map<String, Class<? extends Trait>> registered = new HashMap<String, Class<? extends Trait>>();
public CitizensTraitManager() {
// Register Citizens traits
registerTrait(new TraitFactory(Equipment.class).withName("equipment"));
registerTrait(new TraitFactory(Inventory.class).withName("inventory"));
registerTrait(new TraitFactory(LookClose.class).withName("look-close"));
registerTrait(new TraitFactory(MobType.class).withName("type"));
registerTrait(new TraitFactory(Owner.class).withName("owner"));
registerTrait(new TraitFactory(Spawned.class).withName("spawned"));
registerTrait(new TraitFactory(SpawnLocation.class).withName("location"));
registerTrait(new TraitFactory(Text.class).withName("text"));
registerTrait(new TraitFactory(Waypoints.class).withName("waypoints"));
}
// TODO: Code duplication? Yes. But don't change it unless you test to make
// sure it builds AND works.
@SuppressWarnings("unchecked")
@Override
public <T extends Trait> T getTrait(String name, NPC npc) {
if (!registered.containsKey(name))
return null;
Trait t = getTrait(registered.get(name), npc);
try {
if (t.getName() == null)
t.setName(name);
return (T) t;
} catch (TraitException ex) {
ex.printStackTrace();
}
return null;
}
@Override
public <T extends Trait> T getTrait(Class<T> clazz) {
return getTrait(clazz, null);
}
@SuppressWarnings("unchecked")
@Override
public <T extends Trait> T getTrait(Class<T> clazz, NPC npc) {
for (String name : registered.keySet())
if (registered.get(name).equals(clazz)) {
Trait t = create(registered.get(name), npc);
try {
if (t.getName() == null)
t.setName(name);
return (T) t;
} catch (TraitException ex) {
ex.printStackTrace();
}
}
return null;
}
@SuppressWarnings("unchecked")
@Override
public <T extends Trait> T getTrait(String name) {
if (!registered.containsKey(name))
return null;
return (T) create(registered.get(name), null);
}
@Override
public void registerTrait(TraitFactory factory) {
registered.put(factory.getName(), factory.getTraitClass());
}
@SuppressWarnings("unchecked")
private <T extends Trait> T create(Class<T> trait, NPC npc) {
Constructor<? extends Trait> constructor;
try {
constructor = trait.getConstructor(NPC.class);
} catch (Exception ex) {
constructor = null;
}
try {
if (npc == null)
return (T) trait.newInstance();
return constructor != null ? (T) constructor.newInstance(npc) : (T) trait.newInstance();
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
}

View File

@ -3,16 +3,15 @@ package net.citizensnpcs.trait;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.exception.NPCLoadException;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.trait.SaveId;
import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.util.DataKey;
import net.citizensnpcs.npc.CitizensNPC;
import net.minecraft.server.EntityLiving;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
@SaveId("look-close")
public class LookClose extends Trait implements Runnable, Toggleable {
private final NPC npc;
private boolean lookClose = Setting.DEFAULT_LOOK_CLOSE.asBoolean();

View File

@ -15,7 +15,6 @@ import net.citizensnpcs.Citizens;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.exception.NPCLoadException;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.trait.SaveId;
import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.util.DataKey;
import net.citizensnpcs.editor.Editor;
@ -24,10 +23,10 @@ import net.citizensnpcs.trait.Toggleable;
import net.citizensnpcs.trait.text.prompt.StartPrompt;
import net.citizensnpcs.util.Messaging;
import net.citizensnpcs.util.Paginator;
import net.minecraft.server.EntityHuman;
import net.minecraft.server.EntityLiving;
@SaveId("text")
public class Text extends Trait implements Runnable, Toggleable {
private final Citizens plugin;
private final NPC npc;

View File

@ -1,17 +1,16 @@
package net.citizensnpcs.trait.waypoint;
import java.util.HashMap;
import java.util.Map;
import net.citizensnpcs.api.exception.NPCLoadException;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.trait.DefaultInstanceFactory;
import net.citizensnpcs.api.trait.InstanceFactory;
import net.citizensnpcs.api.trait.SaveId;
import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.util.DataKey;
import net.citizensnpcs.editor.Editor;
import org.bukkit.entity.Player;
@SaveId("waypoints")
public class Waypoints extends Trait {
private final NPC npc;
private WaypointProvider provider = new LinearWaypointProvider();
@ -29,7 +28,11 @@ public class Waypoints extends Trait {
@Override
public void load(DataKey key) throws NPCLoadException {
providerName = key.getString("provider", "linear");
provider = providers.getInstance(providerName);
for (Class<? extends WaypointProvider> clazz : providers.keySet())
if (providers.get(clazz).equals(providerName)) {
provider = create(clazz);
break;
}
if (provider == null)
return;
provider.load(key.getRelative(providerName));
@ -45,21 +48,36 @@ public class Waypoints extends Trait {
}
/**
* Sets the current {@link WaypointProvider} by using the given name. The
* name 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
* @param name
* Class to set as waypoint provider
*/
public void setWaypointProvider(String name) {
this.provider = providers.getInstance(name);
if (this.provider != null) {
providerName = name;
}
public void setWaypointProvider(Class<? extends WaypointProvider> clazz) {
// TODO Probably needs to be changed/fixed. I attempted to make it work
// with refactor. -aPunch
provider = create(clazz);
if (provider != null)
providerName = providers.get(clazz);
}
private static final InstanceFactory<WaypointProvider> providers = DefaultInstanceFactory.create();
private WaypointProvider create(Class<? extends WaypointProvider> clazz) {
if (!providers.containsKey(clazz))
return null;
WaypointProvider provider;
try {
provider = clazz.newInstance();
} catch (Exception ex) {
provider = null;
}
return provider;
}
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
@ -71,10 +89,10 @@ public class Waypoints extends Trait {
* The name of the waypoint provider
*/
public static void registerWaypointProvider(Class<? extends WaypointProvider> clazz, String name) {
providers.register(clazz, name);
providers.put(clazz, name);
}
static {
providers.register(LinearWaypointProvider.class, "linear");
providers.put(LinearWaypointProvider.class, "linear");
}
}