mirror of
https://github.com/CitizensDev/Citizens2.git
synced 2025-01-05 07:57:41 +01:00
Initial work
This commit is contained in:
parent
e1bca417d8
commit
b0ff804209
@ -8,15 +8,14 @@ import java.util.Iterator;
|
||||
import net.citizensnpcs.Settings.Setting;
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.CitizensPlugin;
|
||||
import net.citizensnpcs.api.attachment.AttachmentFactory;
|
||||
import net.citizensnpcs.api.event.CitizensReloadEvent;
|
||||
import net.citizensnpcs.api.exception.NPCLoadException;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.npc.NPCRegistry;
|
||||
import net.citizensnpcs.api.npc.character.CharacterManager;
|
||||
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.util.DataKey;
|
||||
import net.citizensnpcs.api.util.DatabaseStorage;
|
||||
import net.citizensnpcs.api.util.NBTStorage;
|
||||
@ -35,7 +34,7 @@ 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.CitizensAttachmentFactory;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.CitizensNPCRegistry;
|
||||
import net.citizensnpcs.npc.CitizensTraitManager;
|
||||
@ -47,7 +46,6 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
@ -55,7 +53,6 @@ import org.bukkit.plugin.java.JavaPlugin;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
public class Citizens extends JavaPlugin implements CitizensPlugin {
|
||||
private final CitizensCharacterManager characterManager = new CitizensCharacterManager();
|
||||
private final CommandManager commands = new CommandManager();
|
||||
private boolean compatible;
|
||||
private Settings config;
|
||||
@ -63,12 +60,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 TraitManager traitManager;
|
||||
|
||||
@Override
|
||||
public CharacterManager getCharacterManager() {
|
||||
return characterManager;
|
||||
}
|
||||
private CitizensAttachmentFactory attachmentFactory;
|
||||
|
||||
public Iterable<net.citizensnpcs.command.Command> getCommands(String base) {
|
||||
return commands.getCommands(base);
|
||||
@ -89,8 +81,8 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
|
||||
}
|
||||
|
||||
@Override
|
||||
public TraitManager getTraitManager() {
|
||||
return traitManager;
|
||||
public AttachmentFactory getAttachmentFactory() {
|
||||
return attachmentFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -139,7 +131,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
Bukkit.getPluginManager().callEvent(new CitizensDisableEvent());
|
||||
CitizensAPI.getServer().callEvent(new CitizensDisableEvent());
|
||||
|
||||
tearDownScripting();
|
||||
// Don't bother with this part if MC versions are not compatible
|
||||
@ -155,7 +147,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
|
||||
@Override
|
||||
public void onEnable() {
|
||||
// Disable if the server is not using the compatible Minecraft version
|
||||
String mcVersion = ((CraftServer) getServer()).getServer().getVersion();
|
||||
String mcVersion = CitizensAPI.getServer().getMinecraftVersion();
|
||||
compatible = mcVersion.startsWith(COMPATIBLE_MC_VERSION);
|
||||
if (!compatible) {
|
||||
Messaging.severeF("v%s is not compatible with Minecraft v%s. Disabling.", getDescription().getVersion(),
|
||||
@ -170,7 +162,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
|
||||
setupStorage();
|
||||
|
||||
npcRegistry = new CitizensNPCRegistry(saves);
|
||||
traitManager = new CitizensTraitManager(this);
|
||||
attachmentFactory = new CitizensTraitManager(this);
|
||||
selector = new NPCSelector(this);
|
||||
CitizensAPI.setImplementation(this);
|
||||
|
||||
@ -203,7 +195,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
|
||||
return Iterables.size(npcRegistry);
|
||||
}
|
||||
});
|
||||
characterManager.addPlotters(metrics);
|
||||
attachmentFactory.addPlotters(metrics);
|
||||
metrics.start();
|
||||
Messaging.log("Metrics started.");
|
||||
} catch (IOException e) {
|
||||
@ -248,7 +240,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
|
||||
despawnNPCs();
|
||||
setupNPCs();
|
||||
|
||||
getServer().getPluginManager().callEvent(new CitizensReloadEvent());
|
||||
CitizensAPI.getServer().callEvent(new CitizensReloadEvent());
|
||||
}
|
||||
|
||||
private void despawnNPCs() {
|
||||
|
@ -2,17 +2,5 @@ package net.citizensnpcs;
|
||||
|
||||
import net.citizensnpcs.api.event.CitizensEvent;
|
||||
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
public class CitizensDisableEvent extends CitizensEvent {
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
package net.citizensnpcs;
|
||||
|
||||
import javassist.compiler.ast.Pair;
|
||||
import net.citizensnpcs.Settings.Setting;
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.abstraction.WorldVector;
|
||||
import net.citizensnpcs.api.event.NPCDamageByEntityEvent;
|
||||
import net.citizensnpcs.api.event.NPCDamageEvent;
|
||||
import net.citizensnpcs.api.event.NPCLeftClickEvent;
|
||||
@ -16,9 +18,6 @@ import net.citizensnpcs.util.Util;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
@ -37,7 +36,6 @@ import org.bukkit.event.world.WorldUnloadEvent;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import com.google.gson.internal.Pair;
|
||||
|
||||
public class EventListen implements Listener {
|
||||
private final NPCRegistry npcRegistry = CitizensAPI.getNPCRegistry();
|
||||
@ -52,8 +50,8 @@ public class EventListen implements Listener {
|
||||
if (!toRespawn.containsKey(coord))
|
||||
return;
|
||||
for (int id : toRespawn.get(coord)) {
|
||||
NPC npc = npcRegistry.getNPC(id);
|
||||
npc.spawn(npc.getTrait(CurrentLocation.class).getLocation());
|
||||
NPC npc = npcRegistry.getById(id);
|
||||
npc.spawn(npc.getAttachment(CurrentLocation.class).getLocation());
|
||||
}
|
||||
toRespawn.removeAll(coord);
|
||||
}
|
||||
@ -67,9 +65,8 @@ public class EventListen implements Listener {
|
||||
for (NPC npc : npcRegistry) {
|
||||
if (!npc.isSpawned())
|
||||
continue;
|
||||
Location loc = npc.getBukkitEntity().getLocation();
|
||||
if (event.getWorld().equals(loc.getWorld()) && event.getChunk().getX() == loc.getChunk().getX()
|
||||
&& event.getChunk().getZ() == loc.getChunk().getZ()) {
|
||||
WorldVector loc = npc.getEntity().getLocation();
|
||||
if (event.getWorld().equals(loc.getWorld()) && event.getChunk().equals(loc.getChunk())) {
|
||||
npc.despawn();
|
||||
toRespawn.put(coord, npc.getId());
|
||||
}
|
||||
@ -87,22 +84,15 @@ public class EventListen implements Listener {
|
||||
NPC npc = npcRegistry.getNPC(event.getEntity());
|
||||
if (event instanceof EntityDamageByEntityEvent) {
|
||||
NPCDamageByEntityEvent damageEvent = new NPCDamageByEntityEvent(npc, (EntityDamageByEntityEvent) event);
|
||||
Bukkit.getPluginManager().callEvent(damageEvent);
|
||||
CitizensAPI.getServer().callEvent(damageEvent);
|
||||
|
||||
if (!damageEvent.isCancelled() || !(damageEvent.getDamager() instanceof Player))
|
||||
return;
|
||||
Player damager = (Player) damageEvent.getDamager();
|
||||
|
||||
// Call left-click event
|
||||
NPCLeftClickEvent leftClickEvent = new NPCLeftClickEvent(npc, damager);
|
||||
Bukkit.getPluginManager().callEvent(leftClickEvent);
|
||||
if (leftClickEvent.isCancelled())
|
||||
return;
|
||||
|
||||
if (npc.getCharacter() != null)
|
||||
npc.getCharacter().onLeftClick(npc, damager);
|
||||
CitizensAPI.getServer().callEvent(new NPCLeftClickEvent(npc, damager));
|
||||
} else {
|
||||
Bukkit.getPluginManager().callEvent(new NPCDamageEvent(npc, event));
|
||||
CitizensAPI.getServer().callEvent(new NPCDamageEvent(npc, event));
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,9 +121,6 @@ public class EventListen implements Listener {
|
||||
// TODO: move this into text.class
|
||||
if (Util.isSettingFulfilled(player, Setting.TALK_ITEM) && !npc.getTrait(Text.class).shouldTalkClose())
|
||||
npc.getTrait(Text.class).sendText(player);
|
||||
|
||||
if (npc.getCharacter() != null)
|
||||
npc.getCharacter().onRightClick(npc, player);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -15,9 +15,9 @@ import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import net.citizensnpcs.api.abstraction.MobType;
|
||||
import net.citizensnpcs.api.attachment.builtin.Owner;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.trait.MobType;
|
||||
import net.citizensnpcs.api.trait.trait.Owner;
|
||||
import net.citizensnpcs.command.exception.CommandException;
|
||||
import net.citizensnpcs.command.exception.CommandUsageException;
|
||||
import net.citizensnpcs.command.exception.NoPermissionsException;
|
||||
@ -104,19 +104,19 @@ public class CommandManager {
|
||||
throw new RequirementMissingException("You must have an NPC selected to execute that command.");
|
||||
|
||||
if (cmdRequirements.ownership() && npc != null && !sender.hasPermission("citizens.admin")
|
||||
&& !npc.getTrait(Owner.class).isOwnedBy(sender))
|
||||
&& !npc.getAttachment(Owner.class).isOwnedBy(sender))
|
||||
throw new RequirementMissingException("You must be the owner of this NPC to execute that command.");
|
||||
|
||||
if (npc != null) {
|
||||
Set<EntityType> types = Sets.newEnumSet(Arrays.asList(cmdRequirements.types()), EntityType.class);
|
||||
Set<MobType> types = Sets.newEnumSet(Arrays.asList(cmdRequirements.types()), MobType.class);
|
||||
if (types.contains(EntityType.UNKNOWN))
|
||||
types = EnumSet.allOf(EntityType.class);
|
||||
types = EnumSet.allOf(MobType.class);
|
||||
types.removeAll(Sets.newHashSet(cmdRequirements.excludedTypes()));
|
||||
|
||||
EntityType type = EntityType.valueOf(npc.getTrait(MobType.class).getType());
|
||||
if (!types.contains(type)) {
|
||||
if (!types.contains(npc.getEntity().getType())) {
|
||||
throw new RequirementMissingException("The NPC cannot be the mob type '"
|
||||
+ type.name().toLowerCase().replace('_', '-') + "' to use that command.");
|
||||
+ npc.getEntity().getType().name().toLowerCase().replace('_', '-')
|
||||
+ "' to use that command.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package net.citizensnpcs.command;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
import org.bukkit.entity.EntityType;
|
||||
import net.citizensnpcs.api.abstraction.MobType;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Requirements {
|
||||
@ -12,7 +12,7 @@ public @interface Requirements {
|
||||
|
||||
boolean selected() default false;
|
||||
|
||||
EntityType[] types() default { EntityType.UNKNOWN };
|
||||
MobType[] types() default { MobType.UNKNOWN };
|
||||
|
||||
EntityType[] excludedTypes() default { EntityType.UNKNOWN };
|
||||
MobType[] excludedTypes() default { MobType.UNKNOWN };
|
||||
}
|
@ -6,13 +6,12 @@ import java.util.List;
|
||||
import net.citizensnpcs.Citizens;
|
||||
import net.citizensnpcs.Settings.Setting;
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.abstraction.CommandSender;
|
||||
import net.citizensnpcs.api.abstraction.MobType;
|
||||
import net.citizensnpcs.api.attachment.builtin.Owner;
|
||||
import net.citizensnpcs.api.attachment.builtin.Spawned;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.npc.NPCRegistry;
|
||||
import net.citizensnpcs.api.npc.character.Character;
|
||||
import net.citizensnpcs.api.npc.character.CharacterManager;
|
||||
import net.citizensnpcs.api.trait.trait.MobType;
|
||||
import net.citizensnpcs.api.trait.trait.Owner;
|
||||
import net.citizensnpcs.api.trait.trait.Spawned;
|
||||
import net.citizensnpcs.command.Command;
|
||||
import net.citizensnpcs.command.CommandContext;
|
||||
import net.citizensnpcs.command.Requirements;
|
||||
@ -32,10 +31,7 @@ import net.citizensnpcs.util.Paginator;
|
||||
import net.citizensnpcs.util.StringHelper;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Ageable;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Villager.Profession;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||
|
||||
@ -43,7 +39,6 @@ import com.google.common.base.Splitter;
|
||||
|
||||
@Requirements(selected = true, ownership = true)
|
||||
public class NPCCommands {
|
||||
private final CharacterManager characterManager = CitizensAPI.getCharacterManager();
|
||||
private final NPCRegistry npcRegistry;
|
||||
private final NPCSelector selector;
|
||||
|
||||
@ -61,10 +56,10 @@ 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 = { MobType.CHICKEN, MobType.COW, MobType.OCELOT,
|
||||
MobType.PIG, MobType.SHEEP, MobType.VILLAGER, MobType.WOLF })
|
||||
public void age(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
||||
Age trait = npc.getTrait(Age.class);
|
||||
Age trait = npc.getAttachment(Age.class);
|
||||
|
||||
if (args.argsLength() > 1) {
|
||||
int age = 0;
|
||||
@ -94,7 +89,7 @@ public class NPCCommands {
|
||||
"behaviour", "ai" }, min = 2, max = -1)
|
||||
public void behaviour(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
||||
Iterable<String> files = Splitter.on(',').split(args.getJoinedStrings(1, ','));
|
||||
npc.getTrait(Behaviour.class).addScripts(files);
|
||||
npc.getAttachment(Behaviour.class).addScripts(files);
|
||||
sender.sendMessage(ChatColor.GREEN + "Behaviours added.");
|
||||
}
|
||||
|
||||
@ -117,7 +112,7 @@ public class NPCCommands {
|
||||
&& !sender.hasPermission("citizens.npc.character.*") && !sender.hasPermission("citizens.admin"))
|
||||
throw new NoPermissionsException();
|
||||
|
||||
EntityType type = EntityType.valueOf(npc.getTrait(MobType.class).getType());
|
||||
MobType type = MobType.valueOf(npc.getAttachment(MobType.class).getType());
|
||||
if (!character.getValidTypes().isEmpty() && !character.getValidTypes().contains(type)) {
|
||||
Messaging.sendError(sender, "This NPC cannot be given the character '" + character.getName() + "'.");
|
||||
return;
|
||||
@ -143,13 +138,13 @@ public class NPCCommands {
|
||||
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;
|
||||
MobType type = MobType.PLAYER;
|
||||
if (args.hasValueFlag("type")) {
|
||||
type = EntityType.fromName(args.getFlag("type"));
|
||||
type = MobType.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;
|
||||
type = MobType.PLAYER;
|
||||
}
|
||||
}
|
||||
npc = npcRegistry.createNPC(type, name);
|
||||
@ -185,7 +180,7 @@ public class NPCCommands {
|
||||
}
|
||||
|
||||
if (args.hasValueFlag("behaviour")) {
|
||||
npc.getTrait(Behaviour.class).addScripts(Splitter.on(",").split(args.getFlag("behaviour")));
|
||||
npc.getAttachment(Behaviour.class).addScripts(Splitter.on(",").split(args.getFlag("behaviour")));
|
||||
msg += " with the specified behaviours";
|
||||
}
|
||||
|
||||
@ -194,16 +189,16 @@ public class NPCCommands {
|
||||
// Initialize necessary traits
|
||||
npc.addTrait(Owner.class);
|
||||
if (!Setting.SERVER_OWNS_NPCS.asBoolean())
|
||||
npc.getTrait(Owner.class).setOwner(player.getName());
|
||||
npc.getTrait(MobType.class).setType(type.toString());
|
||||
npc.getAttachment(Owner.class).setOwner(player.getName());
|
||||
npc.getAttachment(MobType.class).setType(type.toString());
|
||||
npc.addTrait(LookClose.class);
|
||||
npc.addTrait(Text.class);
|
||||
|
||||
npc.spawn(player.getLocation());
|
||||
|
||||
// Set age after entity spawns
|
||||
if (npc.getBukkitEntity() instanceof Ageable)
|
||||
npc.getTrait(Age.class).setAge(age);
|
||||
if (npc.getEntity() instanceof Ageable)
|
||||
npc.getAttachment(Age.class).setAge(age);
|
||||
|
||||
selector.select(player, npc);
|
||||
Messaging.send(player, msg);
|
||||
@ -218,7 +213,7 @@ public class NPCCommands {
|
||||
max = 1,
|
||||
permission = "npc.despawn")
|
||||
public void despawn(CommandContext args, CommandSender sender, NPC npc) {
|
||||
npc.getTrait(Spawned.class).setSpawned(false);
|
||||
npc.getAttachment(Spawned.class).setSpawned(false);
|
||||
npc.despawn();
|
||||
Messaging.send(sender, ChatColor.GREEN + "You despawned " + StringHelper.wrap(npc.getName()) + ".");
|
||||
}
|
||||
@ -241,14 +236,14 @@ public class NPCCommands {
|
||||
npcs.add(add);
|
||||
} else if (args.getValueFlags().size() == 0 && sender instanceof Player) {
|
||||
for (NPC add : npcRegistry) {
|
||||
if (!npcs.contains(add) && add.getTrait(Owner.class).isOwnedBy(sender))
|
||||
if (!npcs.contains(add) && add.getAttachment(Owner.class).isOwnedBy(sender))
|
||||
npcs.add(add);
|
||||
}
|
||||
} else {
|
||||
if (args.hasValueFlag("owner")) {
|
||||
String name = args.getFlag("owner");
|
||||
for (NPC add : npcRegistry) {
|
||||
if (!npcs.contains(add) && add.getTrait(Owner.class).isOwnedBy(name))
|
||||
if (!npcs.contains(add) && add.getAttachment(Owner.class).isOwnedBy(name))
|
||||
npcs.add(add);
|
||||
}
|
||||
}
|
||||
@ -256,11 +251,11 @@ public class NPCCommands {
|
||||
if (args.hasValueFlag("type")) {
|
||||
String type = args.getFlag("type");
|
||||
|
||||
if (EntityType.fromName(type.replace('-', '_')) == null)
|
||||
if (MobType.fromName(type.replace('-', '_')) == null)
|
||||
throw new CommandException("'" + type + "' is not a valid mob type.");
|
||||
|
||||
for (NPC add : npcRegistry) {
|
||||
if (!npcs.contains(add) && add.getTrait(MobType.class).getType().equalsIgnoreCase(type))
|
||||
if (!npcs.contains(add) && add.getEntity().getType().equalsIgnoreCase(type))
|
||||
npcs.add(add);
|
||||
}
|
||||
}
|
||||
@ -301,7 +296,7 @@ public class NPCCommands {
|
||||
permission = "npc.lookclose")
|
||||
public void lookClose(CommandContext args, CommandSender sender, NPC npc) {
|
||||
String msg = StringHelper.wrap(npc.getName()) + " will "
|
||||
+ (npc.getTrait(LookClose.class).toggle() ? "now rotate" : "no longer rotate");
|
||||
+ (npc.getAttachment(LookClose.class).toggle() ? "now rotate" : "no longer rotate");
|
||||
Messaging.send(sender, msg + " when a player is nearby.");
|
||||
}
|
||||
|
||||
@ -311,7 +306,7 @@ public class NPCCommands {
|
||||
Messaging.send(sender, " <a>ID: <e>" + npc.getId());
|
||||
Messaging.send(sender, " <a>Character: <e>"
|
||||
+ (npc.getCharacter() != null ? npc.getCharacter().getName() : "None"));
|
||||
Messaging.send(sender, " <a>Type: <e>" + npc.getTrait(MobType.class).getType());
|
||||
Messaging.send(sender, " <a>Type: <e>" + npc.getEntity().getType());
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -325,13 +320,13 @@ public class NPCCommands {
|
||||
public void owner(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
||||
if (args.argsLength() == 1) {
|
||||
Messaging.send(sender, StringHelper.wrap(npc.getName() + "'s Owner: ")
|
||||
+ npc.getTrait(Owner.class).getOwner());
|
||||
+ npc.getAttachment(Owner.class).getOwner());
|
||||
return;
|
||||
}
|
||||
String name = args.getString(1);
|
||||
if (npc.getTrait(Owner.class).isOwnedBy(name))
|
||||
if (npc.getAttachment(Owner.class).isOwnedBy(name))
|
||||
throw new CommandException("'" + name + "' is already the owner of " + npc.getName() + ".");
|
||||
npc.getTrait(Owner.class).setOwner(name);
|
||||
npc.getAttachment(Owner.class).setOwner(name);
|
||||
Messaging.send(sender, (name.equalsIgnoreCase("server") ? "<a>The server" : StringHelper.wrap(name))
|
||||
+ " is now the owner of " + StringHelper.wrap(npc.getName()) + ".");
|
||||
}
|
||||
@ -344,10 +339,10 @@ public class NPCCommands {
|
||||
min = 1,
|
||||
max = 1,
|
||||
permission = "npc.power")
|
||||
@Requirements(selected = true, ownership = true, types = { EntityType.CREEPER })
|
||||
@Requirements(selected = true, ownership = true, types = { MobType.CREEPER })
|
||||
public void power(CommandContext args, CommandSender sender, NPC npc) {
|
||||
String msg = StringHelper.wrap(npc.getName()) + " will "
|
||||
+ (npc.getTrait(Powered.class).toggle() ? "now" : "no longer");
|
||||
+ (npc.getAttachment(Powered.class).toggle() ? "now" : "no longer");
|
||||
Messaging.send(sender, msg += " be powered.");
|
||||
}
|
||||
|
||||
@ -359,11 +354,11 @@ public class NPCCommands {
|
||||
min = 2,
|
||||
max = 2,
|
||||
permission = "npc.profession")
|
||||
@Requirements(selected = true, ownership = true, types = { EntityType.VILLAGER })
|
||||
@Requirements(selected = true, ownership = true, types = { MobType.VILLAGER })
|
||||
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()));
|
||||
npc.getAttachment(VillagerProfession.class).setProfession(Profession.valueOf(profession.toUpperCase()));
|
||||
Messaging.send(
|
||||
sender,
|
||||
StringHelper.wrap(npc.getName()) + " is now the profession "
|
||||
@ -396,11 +391,11 @@ public class NPCCommands {
|
||||
Player player = (Player) sender;
|
||||
if (npc == null)
|
||||
throw new CommandException("You must have an NPC selected to execute that command.");
|
||||
if (!npc.getTrait(Owner.class).isOwnedBy(player))
|
||||
if (!npc.getAttachment(Owner.class).isOwnedBy(player))
|
||||
throw new CommandException("You must be the owner of this NPC to execute that command.");
|
||||
if (!player.hasPermission("citizens.npc.remove") && !player.hasPermission("citizens.admin"))
|
||||
throw new NoPermissionsException();
|
||||
npc.remove();
|
||||
npc.destroy();
|
||||
Messaging.send(player, "<a>You permanently removed " + StringHelper.wrap(npc.getName()) + ".");
|
||||
}
|
||||
|
||||
@ -419,7 +414,7 @@ public class NPCCommands {
|
||||
Messaging.sendError(sender, "NPC names cannot be longer than 16 characters. The name has been shortened.");
|
||||
newName = newName.substring(0, 15);
|
||||
}
|
||||
npc.setName(newName);
|
||||
npc.rename(newName);
|
||||
String msg = String.format("You renamed %s to %s.", StringHelper.wrap(oldName), StringHelper.wrap(newName));
|
||||
Messaging.send(sender, ChatColor.GREEN + msg);
|
||||
}
|
||||
@ -434,8 +429,8 @@ public class NPCCommands {
|
||||
permission = "npc.select")
|
||||
@Requirements(ownership = true)
|
||||
public void select(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
|
||||
NPC toSelect = npcRegistry.getNPC(args.getInteger(1));
|
||||
if (toSelect == null || !toSelect.getTrait(Spawned.class).shouldSpawn())
|
||||
NPC toSelect = npcRegistry.getById(args.getInteger(1));
|
||||
if (toSelect == null || !toSelect.getAttachment(Spawned.class).shouldSpawn())
|
||||
throw new CommandException("No NPC with the ID '" + args.getInteger(1) + "' is spawned.");
|
||||
if (npc != null && toSelect.getId() == npc.getId())
|
||||
throw new CommandException("You already have that NPC selected.");
|
||||
@ -457,7 +452,7 @@ public class NPCCommands {
|
||||
if (respawn == null)
|
||||
throw new CommandException("No NPC with the ID '" + args.getInteger(1) + "' exists.");
|
||||
|
||||
if (!respawn.getTrait(Owner.class).isOwnedBy(player))
|
||||
if (!respawn.getAttachment(Owner.class).isOwnedBy(player))
|
||||
throw new CommandException("You must be the owner of this NPC to execute that command.");
|
||||
|
||||
if (respawn.spawn(player.getLocation())) {
|
||||
@ -478,7 +473,7 @@ public class NPCCommands {
|
||||
max = 1,
|
||||
permission = "npc.controllable")
|
||||
public void controllable(CommandContext args, CommandSender sender, NPC npc) {
|
||||
boolean enabled = npc.getTrait(Controllable.class).toggle();
|
||||
boolean enabled = npc.getAttachment(Controllable.class).toggle();
|
||||
if (enabled) {
|
||||
Messaging.send(sender, StringHelper.wrap(npc.getName()) + " can now be controlled.");
|
||||
} else {
|
||||
@ -497,8 +492,8 @@ public class NPCCommands {
|
||||
public void tp(CommandContext args, Player player, NPC npc) {
|
||||
// Spawn the NPC if it isn't spawned to prevent NPEs
|
||||
if (!npc.isSpawned())
|
||||
npc.spawn(npc.getTrait(CurrentLocation.class).getLocation());
|
||||
player.teleport(npc.getBukkitEntity(), TeleportCause.COMMAND);
|
||||
npc.spawn(npc.getAttachment(CurrentLocation.class).getLocation());
|
||||
player.teleport(npc.getEntity(), TeleportCause.COMMAND);
|
||||
Messaging.send(player, ChatColor.GREEN + "You teleported to " + StringHelper.wrap(npc.getName()) + ".");
|
||||
}
|
||||
|
||||
@ -507,8 +502,8 @@ public class NPCCommands {
|
||||
public void tphere(CommandContext args, Player player, NPC npc) {
|
||||
// Spawn the NPC if it isn't spawned to prevent NPEs
|
||||
if (!npc.isSpawned())
|
||||
npc.spawn(npc.getTrait(CurrentLocation.class).getLocation());
|
||||
npc.getBukkitEntity().teleport(player, TeleportCause.COMMAND);
|
||||
npc.spawn(npc.getAttachment(CurrentLocation.class).getLocation());
|
||||
npc.getEntity().teleport(player, TeleportCause.COMMAND);
|
||||
Messaging.send(player, StringHelper.wrap(npc.getName()) + " was teleported to your location.");
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package net.citizensnpcs.npc;
|
||||
|
||||
import net.citizensnpcs.api.attachment.Attachment;
|
||||
import net.citizensnpcs.api.attachment.AttachmentFactory;
|
||||
import net.citizensnpcs.api.attachment.AttachmentInfo;
|
||||
|
||||
public class CitizensAttachmentFactory implements AttachmentFactory {
|
||||
@Override
|
||||
public <T extends Attachment> T getAttachment(Class<T> clazz) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Attachment> T getAttachment(String name) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerAttachment(AttachmentInfo info) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
package net.citizensnpcs.npc;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import net.citizensnpcs.Metrics;
|
||||
import net.citizensnpcs.Metrics.Graph;
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
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;
|
||||
import net.citizensnpcs.util.StringHelper;
|
||||
|
||||
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 {
|
||||
Character character = factory.create();
|
||||
registered.put(character.getName(), character); // TODO: this only
|
||||
// allows singletons
|
||||
// for characters.
|
||||
} catch (CharacterException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void addPlotters(Metrics metrics) {
|
||||
Graph graph = metrics.createGraph("Character Type Usage");
|
||||
for (final Character character : registered.values()) {
|
||||
graph.addPlotter(new Metrics.Plotter(StringHelper.capitalize(character.getName())) {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return CitizensAPI.getNPCRegistry().getNPCs(character.getClass()).size();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,52 +1,28 @@
|
||||
package net.citizensnpcs.npc;
|
||||
|
||||
import net.citizensnpcs.Settings.Setting;
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.abstraction.LivingEntity;
|
||||
import net.citizensnpcs.api.abstraction.WorldVector;
|
||||
import net.citizensnpcs.api.attachment.Attachment;
|
||||
import net.citizensnpcs.api.attachment.builtin.Spawned;
|
||||
import net.citizensnpcs.api.event.NPCDespawnEvent;
|
||||
import net.citizensnpcs.api.event.NPCSpawnEvent;
|
||||
import net.citizensnpcs.api.exception.NPCLoadException;
|
||||
import net.citizensnpcs.api.npc.AbstractNPC;
|
||||
import net.citizensnpcs.api.npc.character.Character;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.trait.trait.Spawned;
|
||||
import net.citizensnpcs.api.npc.NPCRegistry;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
import net.citizensnpcs.npc.ai.CitizensAI;
|
||||
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.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
|
||||
public abstract class CitizensNPC extends AbstractNPC {
|
||||
private final CitizensAI ai = new CitizensAI(this);
|
||||
protected EntityLiving mcEntity;
|
||||
private final CitizensTraitManager traitManager;
|
||||
|
||||
protected CitizensNPC(int id, String name) {
|
||||
super(id, name);
|
||||
traitManager = (CitizensTraitManager) CitizensAPI.getTraitManager();
|
||||
// TODO: remove this dependency
|
||||
public class CitizensNPC extends AbstractNPC {
|
||||
public CitizensNPC(String name) {
|
||||
super(CitizensAPI.getNPCRegistry(), name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void chat(Player player, String message) {
|
||||
Messaging.sendWithNPC(player, Setting.CHAT_PREFIX.asString() + message, this);
|
||||
public CitizensNPC(NPCRegistry registry, String name) {
|
||||
super(registry, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void chat(String message) {
|
||||
for (Player player : Bukkit.getOnlinePlayers())
|
||||
chat(player, message);
|
||||
}
|
||||
|
||||
protected abstract EntityLiving createHandle(Location loc);
|
||||
|
||||
@Override
|
||||
public boolean despawn() {
|
||||
if (!isSpawned()) {
|
||||
@ -54,136 +30,85 @@ public abstract class CitizensNPC extends AbstractNPC {
|
||||
return false;
|
||||
}
|
||||
|
||||
Bukkit.getPluginManager().callEvent(new NPCDespawnEvent(this));
|
||||
boolean keepSelected = getTrait(Spawned.class).shouldSpawn();
|
||||
if (!keepSelected)
|
||||
removeMetadata("selectors", CitizensAPI.getPlugin());
|
||||
getBukkitEntity().remove();
|
||||
mcEntity = null;
|
||||
CitizensAPI.getServer().callEvent(new NPCDespawnEvent(this));
|
||||
getEntity().remove();
|
||||
controller = null;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CitizensAI getAI() {
|
||||
return ai;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LivingEntity getBukkitEntity() {
|
||||
return (LivingEntity) getHandle().getBukkitEntity();
|
||||
}
|
||||
|
||||
public EntityLiving getHandle() {
|
||||
return mcEntity;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trait getTraitFor(Class<? extends Trait> clazz) {
|
||||
return traitManager.getTrait(clazz, this);
|
||||
public LivingEntity getEntity() {
|
||||
return (LivingEntity) controller.getEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSpawned() {
|
||||
return getHandle() != null;
|
||||
return getEntity() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Attachment getAttachmentFor(Class<? extends Attachment> clazz) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public void load(DataKey root) {
|
||||
Character character = CitizensAPI.getCharacterManager().getCharacter(root.getString("character"));
|
||||
|
||||
// Load the character if it exists
|
||||
if (character != null) {
|
||||
try {
|
||||
character.load(root.getRelative("characters." + character.getName()));
|
||||
} catch (NPCLoadException e) {
|
||||
Messaging.severe(String.format("Unable to load character '%s': %s.", character.getName(),
|
||||
e.getMessage()));
|
||||
}
|
||||
setCharacter(character);
|
||||
}
|
||||
|
||||
// Load traits
|
||||
for (DataKey traitKey : root.getRelative("traits").getSubKeys()) {
|
||||
Trait trait = traitManager.getTrait(traitKey.name(), this);
|
||||
for (DataKey attachmentKey : root.getRelative("traits").getSubKeys()) {
|
||||
Attachment trait = attachmentFactory.getTrait(attachmentKey.name(), this);
|
||||
if (trait == null) {
|
||||
Messaging.severeF("Skipped missing trait '%s' while loading NPC ID: '%d'. Has the name changed?",
|
||||
traitKey.name(), getId());
|
||||
Messaging.severeF("Skipped missing attachment '%s' while loading NPC ID: '%d'. Has the name changed?",
|
||||
attachmentKey.name(), getId());
|
||||
continue;
|
||||
}
|
||||
addTrait(trait);
|
||||
addAttachment(trait);
|
||||
try {
|
||||
getTrait(trait.getClass()).load(traitKey);
|
||||
getAttachment(trait.getClass()).load(attachmentKey);
|
||||
} catch (NPCLoadException ex) {
|
||||
Messaging.logF("The trait '%s' failed to load for NPC ID: '%d'.", traitKey.name(), getId(),
|
||||
Messaging.logF("The attachment '%s' failed to load for NPC ID: '%d'.", attachmentKey.name(), getId(),
|
||||
ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Spawn the NPC
|
||||
if (getTrait(Spawned.class).shouldSpawn()) {
|
||||
Location spawnLoc = getTrait(CurrentLocation.class).getLocation();
|
||||
if (getAttachment(Spawned.class).shouldSpawn()) {
|
||||
WorldVector spawnLoc = getAttachment(CurrentLocation.class).getLocation();
|
||||
if (spawnLoc != null)
|
||||
spawn(spawnLoc);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
super.remove();
|
||||
CitizensAPI.getNPCRegistry().deregister(this);
|
||||
}
|
||||
|
||||
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 (Trait trait : traits.values()) {
|
||||
for (Attachment trait : attachments.values()) {
|
||||
trait.save(root.getRelative("traits." + trait.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
super.setName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean spawn(Location loc) {
|
||||
Validate.notNull(loc, "location cannot be null");
|
||||
public boolean spawn(WorldVector at) {
|
||||
if (at == null)
|
||||
throw new IllegalArgumentException("location cannot be null");
|
||||
if (isSpawned()) {
|
||||
Messaging.debug("NPC (ID: " + getId() + ") is already spawned.");
|
||||
return false;
|
||||
}
|
||||
NPCSpawnEvent spawnEvent = new NPCSpawnEvent(this, loc);
|
||||
Bukkit.getPluginManager().callEvent(spawnEvent);
|
||||
NPCSpawnEvent spawnEvent = new NPCSpawnEvent(this, at);
|
||||
CitizensAPI.getServer().callEvent(spawnEvent);
|
||||
if (spawnEvent.isCancelled())
|
||||
return false;
|
||||
|
||||
mcEntity = createHandle(loc);
|
||||
|
||||
mcEntity.world.addEntity(mcEntity);
|
||||
mcEntity.world.players.remove(mcEntity);
|
||||
controller.spawn(at);
|
||||
|
||||
// Set the spawned state
|
||||
getTrait(CurrentLocation.class).setLocation(loc);
|
||||
getTrait(Spawned.class).setSpawned(true);
|
||||
getAttachment(CurrentLocation.class).setLocation(at);
|
||||
getAttachment(Spawned.class).setSpawned(true);
|
||||
|
||||
// Modify NPC using traits after the entity has been created
|
||||
for (Trait trait : traits.values())
|
||||
trait.onNPCSpawn();
|
||||
for (Attachment attached : attachments.values())
|
||||
attached.onSpawn();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -191,7 +116,6 @@ public abstract class CitizensNPC extends AbstractNPC {
|
||||
public void update() {
|
||||
try {
|
||||
super.update();
|
||||
ai.update();
|
||||
} catch (Exception ex) {
|
||||
Messaging.logF("Exception while updating %d: %s.", getId(), ex.getMessage());
|
||||
ex.printStackTrace();
|
||||
|
@ -1,145 +1,29 @@
|
||||
package net.citizensnpcs.npc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.citizensnpcs.api.abstraction.MobType;
|
||||
import net.citizensnpcs.api.abstraction.WorldVector;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.npc.NPCRegistry;
|
||||
import net.citizensnpcs.api.npc.character.Character;
|
||||
import net.citizensnpcs.api.util.Storage;
|
||||
import net.citizensnpcs.npc.ai.NPCHandle;
|
||||
import net.citizensnpcs.npc.entity.CitizensBlazeNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensCaveSpiderNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensChickenNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensCowNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensCreeperNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensEnderDragonNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensEndermanNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensGhastNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensGiantNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensHumanNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensIronGolemNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensMagmaCubeNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensMushroomCowNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensOcelotNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensPigNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensPigZombieNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensSheepNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensSilverfishNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensSkeletonNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensSlimeNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensSnowmanNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensSpiderNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensSquidNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensVillagerNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensWolfNPC;
|
||||
import net.citizensnpcs.npc.entity.CitizensZombieNPC;
|
||||
import net.citizensnpcs.util.ByIdArray;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.craftbukkit.entity.CraftEntity;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
public class CitizensNPCRegistry implements NPCRegistry {
|
||||
private final ByIdArray<NPC> npcs = new ByIdArray<NPC>();
|
||||
private final Storage saves;
|
||||
private final Map<EntityType, Class<? extends CitizensNPC>> types = new EnumMap<EntityType, Class<? extends CitizensNPC>>(
|
||||
EntityType.class);
|
||||
|
||||
public CitizensNPCRegistry(Storage saves) {
|
||||
this.saves = saves;
|
||||
|
||||
types.put(EntityType.BLAZE, CitizensBlazeNPC.class);
|
||||
types.put(EntityType.CAVE_SPIDER, CitizensCaveSpiderNPC.class);
|
||||
types.put(EntityType.CHICKEN, CitizensChickenNPC.class);
|
||||
types.put(EntityType.COW, CitizensCowNPC.class);
|
||||
types.put(EntityType.CREEPER, CitizensCreeperNPC.class);
|
||||
types.put(EntityType.ENDER_DRAGON, CitizensEnderDragonNPC.class);
|
||||
types.put(EntityType.ENDERMAN, CitizensEndermanNPC.class);
|
||||
types.put(EntityType.GHAST, CitizensGhastNPC.class);
|
||||
types.put(EntityType.GIANT, CitizensGiantNPC.class);
|
||||
types.put(EntityType.IRON_GOLEM, CitizensIronGolemNPC.class);
|
||||
types.put(EntityType.MAGMA_CUBE, CitizensMagmaCubeNPC.class);
|
||||
types.put(EntityType.MUSHROOM_COW, CitizensMushroomCowNPC.class);
|
||||
types.put(EntityType.OCELOT, CitizensOcelotNPC.class);
|
||||
types.put(EntityType.PIG, CitizensPigNPC.class);
|
||||
types.put(EntityType.PIG_ZOMBIE, CitizensPigZombieNPC.class);
|
||||
types.put(EntityType.PLAYER, CitizensHumanNPC.class);
|
||||
types.put(EntityType.SHEEP, CitizensSheepNPC.class);
|
||||
types.put(EntityType.SILVERFISH, CitizensSilverfishNPC.class);
|
||||
types.put(EntityType.SKELETON, CitizensSkeletonNPC.class);
|
||||
types.put(EntityType.SLIME, CitizensSlimeNPC.class);
|
||||
types.put(EntityType.SNOWMAN, CitizensSnowmanNPC.class);
|
||||
types.put(EntityType.SPIDER, CitizensSpiderNPC.class);
|
||||
types.put(EntityType.SQUID, CitizensSquidNPC.class);
|
||||
types.put(EntityType.VILLAGER, CitizensVillagerNPC.class);
|
||||
types.put(EntityType.WOLF, CitizensWolfNPC.class);
|
||||
types.put(EntityType.ZOMBIE, CitizensZombieNPC.class);
|
||||
}
|
||||
|
||||
public NPC createNPC(EntityType type, int id, String name, Character character) {
|
||||
CitizensNPC npc = getByType(type, id, name);
|
||||
if (npc == null)
|
||||
throw new IllegalStateException("Could not create NPC.");
|
||||
if (character != null)
|
||||
npc.setCharacter(character);
|
||||
npcs.put(npc.getId(), npc);
|
||||
return npc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC createNPC(EntityType type, String name) {
|
||||
return createNPC(type, name, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC createNPC(EntityType type, String name, Character character) {
|
||||
return createNPC(type, generateUniqueId(), name, character);
|
||||
}
|
||||
|
||||
private int generateUniqueId() {
|
||||
int count = 0;
|
||||
while (getNPC(count++) != null)
|
||||
; // TODO: doesn't respect existing save data that might not have
|
||||
// been loaded. This causes DBs with NPCs that weren't loaded to
|
||||
// have conflicting primary keys.
|
||||
return count - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC(Entity entity) {
|
||||
Validate.notNull(entity);
|
||||
net.minecraft.server.Entity handle = ((CraftEntity) entity).getHandle();
|
||||
return handle instanceof NPCHandle ? ((NPCHandle) handle).getNPC() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NPC getNPC(int id) {
|
||||
public NPC getById(int id) {
|
||||
if (id < 0)
|
||||
throw new IllegalArgumentException("invalid id");
|
||||
return npcs.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<NPC> getNPCs(Class<? extends Character> character) {
|
||||
List<NPC> npcs = new ArrayList<NPC>();
|
||||
for (NPC npc : this) {
|
||||
if (npc.getCharacter() != null && npc.getCharacter().getClass().equals(character))
|
||||
npcs.add(npc);
|
||||
}
|
||||
return npcs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNPC(Entity entity) {
|
||||
return getNPC(entity) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<NPC> iterator() {
|
||||
return npcs.iterator();
|
||||
@ -153,24 +37,15 @@ public class CitizensNPCRegistry implements NPCRegistry {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deregisterAll() {
|
||||
Iterator<NPC> itr = iterator();
|
||||
while (itr.hasNext()) {
|
||||
NPC npc = itr.next();
|
||||
itr.remove();
|
||||
npc.despawn();
|
||||
saves.getKey("npc").removeKey(String.valueOf(npc.getId()));
|
||||
}
|
||||
public NPC createAndSpawn(String name, WorldVector at, MobType type) {
|
||||
NPC npc = new CitizensNPC(this, name);
|
||||
npc.setEntityController(null); // TODO;
|
||||
npc.spawn(at);
|
||||
return npc;
|
||||
}
|
||||
|
||||
private CitizensNPC getByType(EntityType type, int id, String name) {
|
||||
Class<? extends CitizensNPC> npcClass = types.get(type);
|
||||
if (npcClass == null)
|
||||
throw new IllegalArgumentException("Invalid EntityType: " + type);
|
||||
try {
|
||||
return npcClass.getConstructor(int.class, String.class).newInstance(id, name);
|
||||
} catch (Exception ex) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public int register(NPC npc) {
|
||||
return npcs.add(npc);
|
||||
}
|
||||
}
|
@ -6,9 +6,7 @@ import net.citizensnpcs.Settings.Setting;
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.event.NPCRemoveEvent;
|
||||
import net.citizensnpcs.api.event.NPCRightClickEvent;
|
||||
import net.citizensnpcs.api.event.NPCSelectEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.trait.Owner;
|
||||
import net.citizensnpcs.editor.Editor;
|
||||
import net.citizensnpcs.util.Messaging;
|
||||
import net.citizensnpcs.util.Util;
|
||||
|
@ -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<WeakReference<NavigationCallback>> callbacks = Lists.newArrayList();
|
||||
private PathStrategy executing;
|
||||
private final List<GoalEntry> executingGoals = Lists.newArrayList();
|
||||
private final List<GoalEntry> goals = Lists.newArrayList();
|
||||
private List<Goal> toRemove = null;
|
||||
private final CitizensNPC npc;
|
||||
private boolean paused;
|
||||
|
||||
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<NavigationCallback>(callback));
|
||||
callback.onAttach(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeGoal(Goal goal) {
|
||||
if (toRemove == null)
|
||||
toRemove = Lists.newArrayList();
|
||||
toRemove.add(goal);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
private void removeGoals() {
|
||||
if (toRemove == null)
|
||||
return;
|
||||
for (Goal goal : toRemove) {
|
||||
Iterator<GoalEntry> 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 static class GoalEntry implements Comparable<GoalEntry> {
|
||||
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;
|
||||
}
|
||||
|
||||
public Goal getGoal() {
|
||||
return goal;
|
||||
}
|
||||
|
||||
public int getPriority() {
|
||||
return priority;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 31 + ((goal == null) ? 0 : goal.hashCode());
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
package net.citizensnpcs.npc.ai;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
|
||||
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;
|
||||
|
||||
MCNavigationStrategy(final CitizensNPC npc, final Location dest) {
|
||||
entity = npc.getHandle();
|
||||
if (npc.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
|
||||
public boolean update() {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
package net.citizensnpcs.npc.ai;
|
||||
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.util.Util;
|
||||
import net.minecraft.server.EntityLiving;
|
||||
import net.minecraft.server.EntityMonster;
|
||||
import net.minecraft.server.EntityPlayer;
|
||||
import net.minecraft.server.Packet18ArmAnimation;
|
||||
|
||||
import org.bukkit.craftbukkit.entity.CraftLivingEntity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
||||
public class MCTargetStrategy implements PathStrategy {
|
||||
private final boolean aggro;
|
||||
private final EntityLiving handle, target;
|
||||
|
||||
public MCTargetStrategy(CitizensNPC handle, LivingEntity target, boolean aggro) {
|
||||
this.handle = handle.getHandle();
|
||||
this.target = ((CraftLivingEntity) target).getHandle();
|
||||
this.aggro = aggro;
|
||||
}
|
||||
|
||||
private boolean canAttack() {
|
||||
return handle.attackTicks == 0
|
||||
&& (handle.boundingBox.e > target.boundingBox.b && handle.boundingBox.b < target.boundingBox.e)
|
||||
&& distanceSquared() <= ATTACK_DISTANCE && handle.h(target);
|
||||
}
|
||||
|
||||
private double distanceSquared() {
|
||||
return handle.getBukkitEntity().getLocation().distanceSquared(target.getBukkitEntity().getLocation());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update() {
|
||||
if (target == null || target.dead)
|
||||
return true;
|
||||
new MCNavigationStrategy(handle, target).update();
|
||||
handle.getControllerLook().a(target, 10.0F, handle.D());
|
||||
if (aggro && canAttack()) {
|
||||
if (handle instanceof EntityMonster) {
|
||||
((EntityMonster) handle).a((net.minecraft.server.Entity) target);
|
||||
// the cast is necessary to resolve overloaded method a
|
||||
} else if (handle instanceof EntityPlayer) {
|
||||
EntityPlayer humanHandle = (EntityPlayer) handle;
|
||||
humanHandle.attack(target);
|
||||
Util.sendPacketNearby(handle.getBukkitEntity().getLocation(), new Packet18ArmAnimation(humanHandle, 1),
|
||||
64);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static final double ATTACK_DISTANCE = 1.75 * 1.75;
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package net.citizensnpcs.npc.ai;
|
||||
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
|
||||
public interface NPCHandle {
|
||||
public NPC getNPC();
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
package net.citizensnpcs.npc.ai;
|
||||
|
||||
public interface PathStrategy {
|
||||
|
||||
boolean update();
|
||||
}
|
@ -4,9 +4,6 @@ import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.npc.CitizensMobNPC;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.npc.ai.NPCHandle;
|
||||
import net.minecraft.server.EntityBlaze;
|
||||
import net.minecraft.server.PathfinderGoalSelector;
|
||||
import net.minecraft.server.World;
|
||||
|
||||
import org.bukkit.entity.Blaze;
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
package net.citizensnpcs.trait;
|
||||
|
||||
import net.citizensnpcs.api.attachment.Attachment;
|
||||
import net.citizensnpcs.api.exception.NPCLoadException;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
|
||||
import org.bukkit.entity.Ageable;
|
||||
|
||||
public class Age extends Trait implements Runnable, Toggleable {
|
||||
public class Age extends Attachment implements Runnable, Toggleable {
|
||||
private int age = 0;
|
||||
private boolean locked = true;
|
||||
private boolean ageable = false;
|
||||
@ -26,7 +26,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);
|
||||
|
@ -7,11 +7,11 @@ import java.util.Map.Entry;
|
||||
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.ai.Goal;
|
||||
import net.citizensnpcs.api.attachment.Attachment;
|
||||
import net.citizensnpcs.api.exception.NPCLoadException;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.scripting.CompileCallback;
|
||||
import net.citizensnpcs.api.scripting.ScriptFactory;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
@ -23,7 +23,7 @@ import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
public class Behaviour extends Trait {
|
||||
public class Behaviour extends Attachment {
|
||||
private final Map<Goal, Integer> addedGoals = Maps.newHashMap();
|
||||
private final Function<String, File> fileConverterFunction = new Function<String, File>() {
|
||||
@Override
|
||||
@ -59,7 +59,7 @@ public class Behaviour extends Trait {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNPCSpawn() {
|
||||
public void onSpawn() {
|
||||
for (Entry<Goal, Integer> entry : addedGoals.entrySet()) {
|
||||
npc.getAI().addGoal(entry.getValue(), entry.getKey());
|
||||
}
|
||||
|
@ -1,22 +1,19 @@
|
||||
package net.citizensnpcs.trait;
|
||||
|
||||
import net.citizensnpcs.api.attachment.Attachment;
|
||||
import net.citizensnpcs.api.event.NPCRightClickEvent;
|
||||
import net.citizensnpcs.api.exception.NPCLoadException;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.minecraft.server.EntityLiving;
|
||||
import net.minecraft.server.EntityPlayer;
|
||||
|
||||
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 Attachment implements Runnable, Listener, Toggleable {
|
||||
private final CitizensNPC npc;
|
||||
private boolean enabled;
|
||||
|
||||
|
@ -1,26 +1,27 @@
|
||||
package net.citizensnpcs.trait;
|
||||
|
||||
import net.citizensnpcs.api.abstraction.WorldVector;
|
||||
import net.citizensnpcs.api.attachment.Attachment;
|
||||
import net.citizensnpcs.api.exception.NPCLoadException;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
|
||||
public class CurrentLocation extends Trait implements Runnable {
|
||||
private Location loc;
|
||||
public class CurrentLocation extends Attachment implements Runnable {
|
||||
private WorldVector loc;
|
||||
private final NPC npc;
|
||||
|
||||
public CurrentLocation(NPC npc) {
|
||||
this.npc = npc;
|
||||
}
|
||||
|
||||
public Location getLocation() {
|
||||
public WorldVector getLocation() {
|
||||
return loc;
|
||||
}
|
||||
|
||||
public void setLocation(Location loc) {
|
||||
public void setLocation(WorldVector loc) {
|
||||
this.loc = loc;
|
||||
}
|
||||
|
||||
@ -38,7 +39,7 @@ public class CurrentLocation extends Trait implements Runnable {
|
||||
if (!npc.isSpawned())
|
||||
return;
|
||||
|
||||
loc = npc.getBukkitEntity().getLocation();
|
||||
loc = npc.getEntity().getLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,14 +1,14 @@
|
||||
package net.citizensnpcs.trait;
|
||||
|
||||
import net.citizensnpcs.api.attachment.Attachment;
|
||||
import net.citizensnpcs.api.exception.NPCLoadException;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
|
||||
import org.bukkit.entity.Villager;
|
||||
import org.bukkit.entity.Villager.Profession;
|
||||
|
||||
public class VillagerProfession extends Trait {
|
||||
public class VillagerProfession extends Attachment {
|
||||
private final NPC npc;
|
||||
private Profession profession = Profession.FARMER;
|
||||
|
||||
@ -26,9 +26,9 @@ public class VillagerProfession extends Trait {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNPCSpawn() {
|
||||
if (npc.getBukkitEntity() instanceof Villager)
|
||||
((Villager) npc.getBukkitEntity()).setProfession(profession);
|
||||
public void onSpawn() {
|
||||
if (npc.getEntity() instanceof Villager)
|
||||
((Villager) npc.getEntity()).setProfession(profession);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -38,8 +38,8 @@ public class VillagerProfession extends Trait {
|
||||
|
||||
public void setProfession(Profession profession) {
|
||||
this.profession = profession;
|
||||
if (npc.getBukkitEntity() instanceof Villager)
|
||||
((Villager) npc.getBukkitEntity()).setProfession(profession);
|
||||
if (npc.getEntity() instanceof Villager)
|
||||
((Villager) npc.getEntity()).setProfession(profession);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,9 +1,9 @@
|
||||
package net.citizensnpcs.trait;
|
||||
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.attachment.Attachment;
|
||||
import net.citizensnpcs.api.exception.NPCLoadException;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
|
||||
import org.bukkit.DyeColor;
|
||||
@ -12,7 +12,7 @@ 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 Attachment implements Listener {
|
||||
private DyeColor color = DyeColor.WHITE;
|
||||
private final NPC npc;
|
||||
boolean sheep = false;
|
||||
@ -31,9 +31,9 @@ public class WoolColor extends Trait implements Listener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNPCSpawn() {
|
||||
if (npc.getBukkitEntity() instanceof Sheep) {
|
||||
((Sheep) npc.getBukkitEntity()).setColor(color);
|
||||
public void onSpawn() {
|
||||
if (npc.getEntity() instanceof Sheep) {
|
||||
((Sheep) npc.getEntity()).setColor(color);
|
||||
sheep = true;
|
||||
} else
|
||||
sheep = false;
|
||||
@ -53,7 +53,7 @@ public class WoolColor extends Trait implements Listener {
|
||||
public void setColor(DyeColor color) {
|
||||
this.color = color;
|
||||
if (sheep)
|
||||
((Sheep) npc.getBukkitEntity()).setColor(color);
|
||||
((Sheep) npc.getEntity()).setColor(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -8,17 +8,15 @@ import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import net.citizensnpcs.Settings.Setting;
|
||||
import net.citizensnpcs.api.attachment.Attachment;
|
||||
import net.citizensnpcs.api.exception.NPCLoadException;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.util.DataKey;
|
||||
import net.citizensnpcs.editor.Editor;
|
||||
import net.citizensnpcs.npc.CitizensNPC;
|
||||
import net.citizensnpcs.trait.Toggleable;
|
||||
import net.citizensnpcs.util.Messaging;
|
||||
import net.citizensnpcs.util.Paginator;
|
||||
import net.minecraft.server.EntityHuman;
|
||||
import net.minecraft.server.EntityLiving;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.conversations.Conversation;
|
||||
@ -28,7 +26,7 @@ import org.bukkit.conversations.ConversationFactory;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class Text extends Trait implements Runnable, Toggleable, ConversationAbandonedListener {
|
||||
public class Text extends Attachment implements Runnable, Toggleable, ConversationAbandonedListener {
|
||||
private final Map<String, Calendar> cooldowns = new HashMap<String, Calendar>();
|
||||
private int currentIndex;
|
||||
private final NPC npc;
|
||||
@ -93,7 +91,7 @@ public class Text extends Trait implements Runnable, Toggleable, ConversationAba
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNPCSpawn() {
|
||||
public void onSpawn() {
|
||||
if (text.isEmpty())
|
||||
populateDefaultText();
|
||||
}
|
||||
|
@ -1,85 +0,0 @@
|
||||
package net.citizensnpcs.trait.waypoint;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import net.citizensnpcs.api.ai.AI;
|
||||
import net.citizensnpcs.api.ai.NavigationCallback;
|
||||
|
||||
import org.bukkit.Location;
|
||||
|
||||
public class GenericWaypointCallback extends NavigationCallback {
|
||||
private AI ai;
|
||||
private Location dest;
|
||||
private boolean executing;
|
||||
private Iterator<Waypoint> itr;
|
||||
private final Iterable<Waypoint> provider;
|
||||
|
||||
public GenericWaypointCallback(Iterable<Waypoint> provider) {
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
private void ensureItr() {
|
||||
if (itr == null || !itr.hasNext()) {
|
||||
itr = provider.iterator();
|
||||
}
|
||||
}
|
||||
|
||||
@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
|
||||
public boolean onCancel(AI ai, CancelReason reason) {
|
||||
if (executing && reason == CancelReason.REPLACE) {
|
||||
executing = false;
|
||||
return false;
|
||||
}
|
||||
executing = true;
|
||||
ensureItr();
|
||||
if (dest == null && itr.hasNext())
|
||||
dest = itr.next().getLocation();
|
||||
if (dest != null) {
|
||||
ai.setDestination(dest);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCompletion(AI ai) {
|
||||
if (executing) { // if we're executing, we need to get the next waypoint
|
||||
ensureItr();
|
||||
dest = itr.hasNext() ? itr.next().getLocation() : null;
|
||||
} else {
|
||||
executing = true;
|
||||
// we're free to return to our waypoints!
|
||||
// if we had a destination, we will return to it.
|
||||
}
|
||||
if (dest != null) {
|
||||
ai.setDestination(dest);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void onProviderChanged() {
|
||||
itr = provider.iterator();
|
||||
if (ai == null)
|
||||
return;
|
||||
dest = itr.hasNext() ? itr.next().getLocation() : null;
|
||||
if (dest != null) {
|
||||
ai.setDestination(dest);
|
||||
}
|
||||
}
|
||||
}
|
@ -4,13 +4,13 @@ import java.util.Arrays;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import net.citizensnpcs.Settings.Setting;
|
||||
import net.citizensnpcs.api.abstraction.CommandSender;
|
||||
import net.citizensnpcs.api.abstraction.Player;
|
||||
import net.citizensnpcs.api.attachment.builtin.Owner;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.trait.Owner;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
|
||||
@ -68,7 +68,7 @@ public class Messaging {
|
||||
send = send.replace("<player>", player.getName());
|
||||
send = send.replace("<world>", player.getWorld().getName());
|
||||
}
|
||||
send = send.replace("<owner>", npc.getTrait(Owner.class).getOwner());
|
||||
send = send.replace("<owner>", npc.getAttachment(Owner.class).getOwner());
|
||||
send = send.replace("<npc>", npc.getName());
|
||||
send = send.replace("<id>", Integer.toString(npc.getId()));
|
||||
|
||||
|
@ -7,16 +7,15 @@ import java.util.Comparator;
|
||||
import java.util.Map;
|
||||
|
||||
import net.citizensnpcs.Settings.Setting;
|
||||
import net.minecraft.server.Packet;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.avaje.ebeaninternal.server.cluster.Packet;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
|
Loading…
Reference in New Issue
Block a user