Add Anchors, saveable 'locations' for your NPCs. Usage: /npc anchor (--save [name]|--assume [name]|--remove [name]) (-a)

Also renamed /npc pose --load to /npc pose --assume
This commit is contained in:
Jeremy Schroeder 2012-10-12 21:24:42 -04:00
parent 983ef2f1fd
commit 59218ae28c
6 changed files with 210 additions and 6 deletions

View File

@ -25,6 +25,7 @@ import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.NPCSelector;
import net.citizensnpcs.npc.Template;
import net.citizensnpcs.trait.Age;
import net.citizensnpcs.trait.Anchors;
import net.citizensnpcs.trait.Behaviour;
import net.citizensnpcs.trait.Controllable;
import net.citizensnpcs.trait.CurrentLocation;
@ -32,6 +33,7 @@ import net.citizensnpcs.trait.LookClose;
import net.citizensnpcs.trait.Poses;
import net.citizensnpcs.trait.Powered;
import net.citizensnpcs.trait.VillagerProfession;
import net.citizensnpcs.util.Anchor;
import net.citizensnpcs.util.Messages;
import net.citizensnpcs.util.Messaging;
import net.citizensnpcs.util.Paginator;
@ -108,6 +110,71 @@ public class NPCCommands {
trait.setAge(age);
}
@Command(
aliases = { "npc" },
usage = "anchor (--save [name]|--assume [name]|--remove [name]) (-a)",
desc = "Changes/Saves/Lists NPC's location anchor(s)",
flags = "a",
modifiers = { "anchor" },
min = 1,
max = 2,
permission = "npc.anchor")
@Requirements(selected = true, ownership = true, types = EntityType.PLAYER)
public void anchor(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
Anchors trait = npc.getTrait(Anchors.class);
if (args.hasValueFlag("save")) {
if (args.getFlag("save").isEmpty())
throw new CommandException(Messages.INVALID_ANCHOR_NAME);
if (!(sender instanceof Player))
throw new ServerCommandException();
if (trait.addAnchor(args.getFlag("save"), ((Player) sender).getLocation())) {
Messaging.sendTr(sender, Messages.ANCHOR_ADDED);
} else
throw new CommandException(Messages.ANCHOR_ALREADY_EXISTS, args.getFlag("save"));
} else if (args.hasValueFlag("assume")) {
if (args.getFlag("assume").isEmpty())
throw new CommandException(Messages.INVALID_ANCHOR_NAME);
Anchor anchor = trait.getAnchor(args.getFlag("assume"));
if (anchor == null)
throw new CommandException(Messages.ANCHOR_MISSING, args.getFlag("assume"));
npc.getBukkitEntity().teleport(anchor.getLocation());
} else if (args.hasValueFlag("remove")) {
if (args.getFlag("remove").isEmpty())
throw new CommandException(Messages.INVALID_ANCHOR_NAME);
if (trait.removeAnchor(trait.getAnchor(args.getFlag("remove"))))
Messaging.sendTr(sender, Messages.ANCHOR_REMOVED);
else
throw new CommandException(Messages.ANCHOR_MISSING, args.getFlag("remove"));
} else if (!args.hasFlag('a')) {
Paginator paginator = new Paginator().header("Anchors");
paginator.addLine("<e>Key: <a>ID <b>Name <c>World <d>Location (X,Y,Z)");
for (int i = 0; i < trait.getAnchors().size(); i++) {
String line = "<a>" + i + "<b> " + trait.getAnchors().get(i).getName() + "<c> "
+ trait.getAnchors().get(i).getLocation().getWorld().getName() + "<d> "
+ trait.getAnchors().get(i).getLocation().getBlockX()+ ", "
+ trait.getAnchors().get(i).getLocation().getBlockY()+ ", "
+ trait.getAnchors().get(i).getLocation().getBlockZ();
paginator.addLine(line);
}
int page = args.getInteger(1, 1);
if (!paginator.sendPage(sender, page))
throw new CommandException(Messages.COMMAND_PAGE_MISSING);
}
// Assume Player's position
if (!args.hasFlag('a'))
return;
if (sender instanceof Player) {
Location location = ((Player) sender).getLocation();
npc.getBukkitEntity().teleport(location);
} else
throw new ServerCommandException();
}
@Command(
aliases = { "npc" },
usage = "behaviour [scripts] (-r)",
@ -474,7 +541,7 @@ public class NPCCommands {
@Command(
aliases = { "npc" },
usage = "pose (--save [name]|--load [name]|--remove [name]|--list) (-a)",
usage = "pose (--save [name]|--assume [name]|--remove [name]) (-a)",
desc = "Changes/Saves/Lists NPC's head pose(s)",
flags = "a",
modifiers = { "pose" },
@ -494,14 +561,14 @@ public class NPCCommands {
if (trait.addPose(args.getFlag("save"), ((Player) sender).getLocation())) {
Messaging.sendTr(sender, Messages.POSE_ADDED);
} else
throw new CommandException(Messages.POSE_ALREADY_EXISTS, args.getFlag("load"));
} else if (args.hasValueFlag("load")) {
if (args.getFlag("load").isEmpty())
throw new CommandException(Messages.POSE_ALREADY_EXISTS, args.getFlag("assume"));
} else if (args.hasValueFlag("assume")) {
if (args.getFlag("assume").isEmpty())
throw new CommandException(Messages.INVALID_POSE_NAME);
Pose pose = trait.getPose(args.getFlag("load"));
Pose pose = trait.getPose(args.getFlag("assume"));
if (pose == null)
throw new CommandException(Messages.POSE_MISSING, args.getFlag("load"));
throw new CommandException(Messages.POSE_MISSING, args.getFlag("assume"));
trait.assumePose(pose);
} else if (args.hasValueFlag("remove")) {
if (args.getFlag("remove").isEmpty())

View File

@ -16,6 +16,7 @@ import net.citizensnpcs.api.trait.trait.MobType;
import net.citizensnpcs.api.trait.trait.Owner;
import net.citizensnpcs.api.trait.trait.Spawned;
import net.citizensnpcs.trait.Age;
import net.citizensnpcs.trait.Anchors;
import net.citizensnpcs.trait.Behaviour;
import net.citizensnpcs.trait.Controllable;
import net.citizensnpcs.trait.CurrentLocation;
@ -55,6 +56,7 @@ public class CitizensTraitFactory implements TraitFactory {
registerTrait(TraitInfo.create(Controllable.class).withName("controllable"));
registerTrait(TraitInfo.create(Behaviour.class).withName("behaviour"));
registerTrait(TraitInfo.create(Poses.class).withName("poses"));
registerTrait(TraitInfo.create(Anchors.class).withName("anchors"));
for (String trait : registered.keySet())
INTERNAL_TRAITS.add(trait);

View File

@ -0,0 +1,67 @@
package net.citizensnpcs.trait;
import java.util.ArrayList;
import java.util.List;
import net.citizensnpcs.api.exception.NPCLoadException;
import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.util.DataKey;
import net.citizensnpcs.util.Messages;
import net.citizensnpcs.util.Messaging;
import net.citizensnpcs.util.Anchor;
import org.bukkit.Bukkit;
import org.bukkit.Location;
public class Anchors extends Trait {
private final List<Anchor> anchors = new ArrayList<Anchor>();
public Anchors() {
super("anchors");
}
public boolean addAnchor(String name, Location location) {
Anchor newAnchor = new Anchor(name, location);
if (anchors.contains(newAnchor))
return false;
anchors.add(newAnchor);
return true;
}
public Anchor getAnchor(String name) {
for (Anchor anchor : anchors)
if (anchor.getName().equalsIgnoreCase(name))
return anchor;
return null;
}
public List<Anchor> getAnchors() {
return anchors;
}
@Override
public void load(DataKey key) throws NPCLoadException {
for (DataKey sub : key.getRelative("list").getIntegerSubKeys())
try {
String[] parts = sub.getString("").split(";");
anchors.add(new Anchor(parts[0], new Location(Bukkit.getServer().getWorld(parts[1]), Double.valueOf(parts[2]), Double.valueOf(parts[3]), Double.valueOf(parts[4]))));
} catch (NumberFormatException e) {
Messaging.logTr(Messages.SKIPPING_INVALID_ANCHOR, sub.name(), e.getMessage());
}
}
public boolean removeAnchor(Anchor anchor) {
if (anchors.contains(anchor)) {
anchors.remove(anchor);
return true;
}
return false;
}
@Override
public void save(DataKey key) {
key.removeKey("list");
for (int i = 0; i < anchors.size(); i++)
key.setString("list." + String.valueOf(i), anchors.get(i).stringValue());
}
}

View File

@ -0,0 +1,57 @@
package net.citizensnpcs.util;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.bukkit.Location;
/*
* Anchor object which holds a Location with a name to identify.
*/
public class Anchor {
private final String name;
private final Location location;
public Anchor(String name, Location location) {
this.location = location;
this.name = name;
}
@Override
public boolean equals(Object object) {
if (object == null) return false;
if (object == this) return true;
if (object.getClass() != getClass())
return false;
Anchor op = (Anchor) object;
return new EqualsBuilder().
append(name, op.getName()).
isEquals();
}
public String getName() {
return name;
}
public Location getLocation() {
return location;
}
@Override
public int hashCode() {
return new HashCodeBuilder(13, 21).
append(name).
toHashCode();
}
public String stringValue() {
return name + ";" + location.getWorld().getName() + ";" + location.getX() + ";" + location.getY() + ";" + location.getZ();
}
@Override
public String toString() {
return "Name: " + name + " World: " + location.getWorld().getName() + " Location: " + location.getBlockX() + "," + location.getBlockY() + "," + location.getBlockZ();
}
}

View File

@ -9,6 +9,10 @@ public class Messages {
public static final String AGE_UNLOCKED = "citizens.commands.npc.age.unlocked";
public static final String ALREADY_IN_EDITOR = "citizens.editors.already-in-editor";
public static final String ALREADY_OWNER = "citizens.commands.npc.owner.already-owner";
public static final String ANCHOR_ADDED = "citizens.commands.npc.anchor.added";
public static final String ANCHOR_ALREADY_EXISTS = "citizens.commands.npc.anchor.already-exists";
public static final String ANCHOR_MISSING = "citizens.commands.npc.anchor.missing";
public static final String ANCHOR_REMOVED = "citizens.commands.npc.anchor.removed";
public static final String AVAILABLE_WAYPOINT_PROVIDERS = "citizens.waypoints.available-providers-header";
public static final String BEHAVIOUR_HELP = "citizens.commands.npc.behaviour.help";
public static final String BEHAVIOURS_ADDED = "citizens.commands.npc.behaviour.added";
@ -60,6 +64,7 @@ public class Messages {
public static final String FAILED_TO_MOUNT_NPC = "citizens.commands.npc.mount.failed";
public static final String FAILED_TO_REMOVE = "citizens.commands.trait.failed-to-remove";
public static final String INVALID_AGE = "citizens.commands.npc.age.invalid-age";
public static final String INVALID_ANCHOR_NAME = "citizens.commands.npc.anchor.invalid-name";
public static final String INVALID_POSE_NAME = "citizens.commands.npc.pose.invalid-name";
public static final String INVALID_PROFESSION = "citizens.commands.npc.profession.invalid-profession";
public static final String LINEAR_WAYPOINT_EDITOR_ADDED_WAYPOINT = "citizens.editors.waypoints.linear.added-waypoint";
@ -125,6 +130,7 @@ public class Messages {
public static final String SHEARED_STOPPED = "citizens.editors.equipment.sheared-stopped";
public static final String SKIPPING_BROKEN_TRAIT = "citizens.notifications.skipping-broken-trait";
public static final String SKIPPING_INVALID_POSE = "citizens.notifications.skipping-invalid-pose";
public static final String SKIPPING_INVALID_ANCHOR = "citizens.notifications.skipping-invalid-anchor";
public static final String SPEED_MODIFIER_ABOVE_LIMIT = "citizens.commands.npc.speed.modifier-above-limit";
public static final String SPEED_MODIFIER_SET = "citizens.commands.npc.speed.set";
public static final String TELEPORTED_TO_NPC = "citizens.commands.npc.tp.teleported";

View File

@ -15,6 +15,11 @@ citizens.commands.npc.age.set-baby=[[{0}]] is now a baby.
citizens.commands.npc.age.set-normal=[[{0}]] is now age [[{1}]].
citizens.commands.npc.age.set=[[{0}]] is now [[{1}]].
citizens.commands.npc.age.unlocked=Age unlocked.
citizens.commands.npc.anchor.added=Anchor added.
citizens.commands.npc.anchor.already-exists=The anchor '{0}' already exists.
citizens.commands.npc.anchor.invalid-name=Invalid anchor name.
citizens.commands.npc.anchor.missing=The anchor '{1}' does not exist.
citizens.commands.npc.anchor.removed=Anchor removed.
citizens.commands.npc.behaviour.added=Behaviours added.
citizens.commands.npc.behaviour.help=The scripts argument is a comma-separated list of file names. Scripts will be loaded automatically and run every tick. Use the [[-r]] flag to remove behaviours.
citizens.commands.npc.behaviour.removed=Behaviours removed.