This commit is contained in:
fullwall 2012-09-29 23:07:48 +08:00
parent 5d2ce8d37f
commit 6228339667
9 changed files with 193 additions and 191 deletions

View File

@ -146,7 +146,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
try {
commands.execute(split, sender, sender, npc);
} catch (ServerCommandException ex) {
Messaging.sendTr(sender, Messages.INGAME_COMMAND);
Messaging.sendTr(sender, Messages.COMMAND_MUST_BE_INGAME);
} catch (CommandUsageException ex) {
Messaging.sendError(sender, ex.getMessage());
Messaging.sendError(sender, ex.getUsage());

View File

@ -20,6 +20,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.command.exception.ServerCommandException;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.NPCSelector;
import net.citizensnpcs.trait.Age;
@ -42,6 +43,7 @@ import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Ageable;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
@ -453,79 +455,67 @@ public class NPCCommands {
+ " is now the owner of " + StringHelper.wrap(npc.getName()) + ".");
}
@Command(
aliases = { "npc" },
usage = "pose (--save [name]|--load [name]|--remove [name]|--list) (-a)",
desc = "Changes/Saves/Lists NPC's head pose(s)",
flags = "a",
modifiers = { "pose" },
min = 1,
max = 2,
permission = "npc.pose")
@Requirements(selected = true, ownership = true, types = { EntityType.PLAYER })
public void position(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
@Command(
aliases = { "npc" },
usage = "pose (--save [name]|--load [name]|--remove [name]|--list) (-a)",
desc = "Changes/Saves/Lists NPC's head pose(s)",
flags = "a",
modifiers = { "pose" },
min = 1,
max = 2,
permission = "npc.pose")
@Requirements(selected = true, ownership = true, types = EntityType.PLAYER)
public void pose(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
Poses trait = npc.getTrait(Poses.class);
if (args.hasValueFlag("save")) {
if (args.getFlag("save").isEmpty())
throw new CommandException("Invalid name.");
Poses trait = npc.getTrait(Poses.class);
if (!(sender instanceof Player))
throw new ServerCommandException();
if (args.hasValueFlag("save")) {
if (!args.getFlag("save").isEmpty()) {
if (sender instanceof Player) {
if (trait.addPose(args.getFlag("save"), ((Player) sender).getLocation()))
Messaging.sendF(sender, ChatColor.GREEN + "Pose added.");
else throw new CommandException("The pose '" + args.getFlag("load") + "' already exists.");
}
else
throw new CommandException("This command may be used in-game only.");
}
else
throw new CommandException("Invalid name.");
}
if (trait.addPose(args.getFlag("save"), ((Player) sender).getLocation())) {
Messaging.sendF(sender, ChatColor.GREEN + "Pose added.");
} else
throw new CommandException("The pose '" + args.getFlag("load") + "' already exists.");
} else if (args.hasValueFlag("load")) {
if (args.getFlag("load").isEmpty())
throw new CommandException("Invalid name.");
else if (args.hasValueFlag("load")) {
if (!args.getFlag("load").isEmpty()) {
if (trait.getPose(args.getFlag("load")) != null)
trait.assumePose(trait.getPose(args.getFlag("load")));
else
throw new CommandException("The pose '" + args.getFlag("load") + "' does not exist.");
}
else
throw new CommandException("Invalid name.");
}
Pose pose = trait.getPose(args.getFlag("load"));
if (pose == null)
throw new CommandException("The pose '" + args.getFlag("load") + "' does not exist.");
trait.assumePose(pose);
} else if (args.hasValueFlag("remove")) {
if (args.getFlag("remove").isEmpty())
throw new CommandException("Invalid name.");
if (trait.removePose(trait.getPose(args.getFlag("remove"))))
Messaging.sendF(sender, ChatColor.GREEN + "Position removed.");
else
throw new CommandException("The pose '" + args.getFlag("remove") + "' does not exist.");
} else if (!args.hasFlag('a')) {
Paginator paginator = new Paginator().header("Pose");
paginator.addLine("<e>Key: <a>ID <b>Name <c>Pitch/Yaw");
for (int i = 0; i < trait.getPoses().size(); i++) {
String line = "<a>" + i + "<b> " + trait.getPoses().get(i).getName() + "<c> "
+ trait.getPoses().get(i).getPitch() + "/" + trait.getPoses().get(i).getYaw();
paginator.addLine(line);
}
else if (args.hasValueFlag("remove")) {
if (!args.getFlag("remove").isEmpty()) {
if (trait.removePose(trait.getPose(args.getFlag("remove"))))
Messaging.sendF(sender, ChatColor.GREEN + "Position removed.");
else
throw new CommandException("The pose '" + args.getFlag("remove") + "' does not exist.");
}
else
throw new CommandException("Invalid name.");
}
else if (!args.hasFlag('a')) {
Paginator paginator = new Paginator().header("Pose");
paginator.addLine("<e>Key: <a>ID <b>Name <c>Pitch/Yaw");
for (int i = 0; i < trait.getPoses().size(); i ++) {
String line = "<a>" + i + "<b> " + trait.getPoses().get(i).getName() + "<c> " + trait.getPoses().get(i).getPitch() + "/" + trait.getPoses().get(i).getYaw();
paginator.addLine(line);
}
int page = args.getInteger(1, 1);
if (!paginator.sendPage(sender, page))
throw new CommandException("The page '" + page + "' does not exist.");
}
int page = args.getInteger(1, 1);
if (!paginator.sendPage(sender, page))
throw new CommandException("The page '" + page + "' does not exist.");
}
// Assume Player's pose
if (args.hasFlag('a')) {
if (sender instanceof Player) {
trait.assumePose(new Pose(sender.getName(), ((Player) sender).getLocation().getPitch(), ((Player) sender).getLocation().getYaw()));
return;
}
else
Messaging.sendF(sender, ChatColor.YELLOW + "This command can only be used by a Player in-game");
}
}
// Assume Player's pose
if (!args.hasFlag('a'))
return;
if (sender instanceof Player) {
Location location = ((Player) sender).getLocation();
trait.assumePose(new Pose(sender.getName(), location.getPitch(), location.getYaw()));
} else
throw new ServerCommandException();
}
@Command(
aliases = { "npc" },
@ -613,17 +603,31 @@ public class NPCCommands {
@Command(
aliases = { "npc" },
usage = "select|sel [id]",
usage = "select|sel [id] (--r range)",
desc = "Select a NPC with the given ID",
modifiers = { "select", "sel" },
min = 2,
min = 1,
max = 2,
permission = "npc.select")
@Requirements(ownership = true)
public void select(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
NPC toSelect = npcRegistry.getById(args.getInteger(1));
NPC toSelect = null;
if (args.argsLength() == 0) {
if (!(sender instanceof Player))
throw new ServerCommandException();
double range = Math.abs(args.getFlagDouble("r", 10));
List<Entity> search = ((Player) sender).getNearbyEntities(range, range, range);
for (Entity possibleNPC : search) {
NPC test = npcRegistry.getNPC(possibleNPC);
if (test == null)
continue;
toSelect = test;
break;
}
} else
toSelect = npcRegistry.getById(args.getInteger(1));
if (toSelect == null || !toSelect.getTrait(Spawned.class).shouldSpawn())
throw new CommandException("No NPC with the ID '" + args.getInteger(1) + "' is spawned.");
throw new CommandException("No NPC could be found.");
if (npc != null && toSelect.getId() == npc.getId())
throw new CommandException("You already have that NPC selected.");
selector.select(sender, toSelect);

View File

@ -11,6 +11,7 @@ import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.util.DataKey;
import net.citizensnpcs.command.CommandConfigurable;
import net.citizensnpcs.command.CommandContext;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import org.bukkit.Location;
@ -29,7 +30,7 @@ public class LookClose extends Trait implements Toggleable, CommandConfigurable
}
private boolean canSeeTarget() {
return realisticLooking ? Util.rayTrace(npc.getBukkitEntity(), lookingAt) : true;
return realisticLooking ? NMS.rayTrace(npc.getBukkitEntity(), lookingAt) : true;
}
@Override

View File

@ -1,75 +1,73 @@
package net.citizensnpcs.trait;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Location;
import net.citizensnpcs.api.exception.NPCLoadException;
import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.util.DataKey;
import net.citizensnpcs.util.Messaging;
import net.citizensnpcs.util.Pose;
import net.citizensnpcs.util.Util;
import org.bukkit.Location;
public class Poses extends Trait {
private final List<Pose> poses = new ArrayList<Pose>();
private final List<Pose> poses = new ArrayList<Pose>();
Pose currentPosition = null;
public Poses() {
super("poses");
}
public Poses() {
super("poses");
}
public boolean addPose(String name, Location location) {
Pose newPose = new Pose(name, location.getPitch(), location.getYaw());
if (poses.contains(newPose))
return false;
poses.add(newPose);
return true;
}
@Override
public void load(DataKey key) throws NPCLoadException {
for (DataKey sub : key.getRelative("list").getIntegerSubKeys())
try {
poses.add(new Pose(sub.getString("").split(";")[0], Float.valueOf(sub.getString("").split(";")[1]), Float.valueOf(sub.getString("").split(";")[2]))) ;
} catch(Exception e) { /* Perhaps remove the entry if bad? Warn console? */ }
}
public void assumePose(Pose pose) {
if (!npc.isSpawned())
npc.spawn(npc.getTrait(CurrentLocation.class).getLocation());
@Override
public void save(DataKey key) {
key.removeKey("list");
for (int i = 0; i < poses.size(); i++)
key.setString("list." + String.valueOf(i), poses.get(i).stringValue());
}
Util.assumePose(npc.getBukkitEntity(), pose);
}
public List<Pose> getPoses() {
return poses;
}
public Pose getPose(String name) {
for (Pose pose : poses)
if (pose.getName().equalsIgnoreCase(name))
return pose;
return null;
}
public boolean addPose(String name, Location location) {
Pose newPose = new Pose(name, location.getPitch(), location.getYaw());
public List<Pose> getPoses() {
return poses;
}
if (poses.contains(newPose)) return false;
poses.add(newPose);
return true;
}
public boolean removePose(Pose pose) {
if (poses.contains(pose)) {
poses.remove(pose);
return true;
}
else return false;
}
public Pose getPose(String name) {
for (Pose pose : poses)
if (pose.getName().equalsIgnoreCase(name)) return pose;
return null;
}
public void assumePose(Pose pose) {
if (!npc.isSpawned())
npc.spawn(npc.getTrait(CurrentLocation.class).getLocation());
Util.assumePose(npc.getBukkitEntity(), pose);
}
@Override
public void load(DataKey key) throws NPCLoadException {
for (DataKey sub : key.getRelative("list").getIntegerSubKeys())
try {
String[] parts = sub.getString("").split(";");
poses.add(new Pose(parts[0], Float.valueOf(parts[1]), Float.valueOf(parts[2])));
} catch (NumberFormatException e) {
Messaging.logF("Skipping pose %s - invalid yaw/pitch (%s).", sub.name(), e.getMessage());
}
}
public boolean removePose(Pose pose) {
if (poses.contains(pose)) {
poses.remove(pose);
return true;
}
return false;
}
@Override
public void save(DataKey key) {
key.removeKey("list");
for (int i = 0; i < poses.size(); i++)
key.setString("list." + String.valueOf(i), poses.get(i).stringValue());
}
}

View File

@ -99,13 +99,11 @@ public class LinearWaypointProvider implements WaypointProvider {
}
private final class LinearWaypointEditor extends Editor {
private final Player player;
boolean editing = true;
int editingSlot = waypoints.size() - 1;
private final Player player;
private boolean showPath;
Map<Waypoint, Entity> waypointMarkers = Maps.newHashMap();
private static final int LARGEST_SLOT = 8;
private LinearWaypointEditor(Player player) {
this.player = player;
}
@ -189,17 +187,6 @@ public class LinearWaypointProvider implements WaypointProvider {
}, 1);
}
@EventHandler(ignoreCancelled = true)
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
if (!player.equals(event.getPlayer()) || !showPath)
return;
if (!event.getRightClicked().hasMetadata("waypointindex"))
return;
editingSlot = event.getRightClicked().getMetadata("waypointindex").get(0).asInt();
Messaging.sendF(player, ChatColor.GREEN + "Editing slot set to %s.",
StringHelper.wrap(editingSlot));
}
@EventHandler(ignoreCancelled = true)
public void onPlayerInteract(PlayerInteractEvent event) {
if (!event.getPlayer().equals(player) || event.getAction() == Action.PHYSICAL)
@ -249,6 +236,17 @@ public class LinearWaypointProvider implements WaypointProvider {
currentGoal.onProviderChanged();
}
@EventHandler(ignoreCancelled = true)
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
if (!player.equals(event.getPlayer()) || !showPath)
return;
if (!event.getRightClicked().hasMetadata("waypointindex"))
return;
editingSlot = event.getRightClicked().getMetadata("waypointindex").get(0).asInt();
Messaging.sendF(player, ChatColor.GREEN + "Editing slot set to %s.",
StringHelper.wrap(editingSlot));
}
@EventHandler
public void onPlayerItemHeldChange(PlayerItemHeldEvent event) {
if (!event.getPlayer().equals(player) || waypoints.size() == 0)
@ -293,6 +291,8 @@ public class LinearWaypointProvider implements WaypointProvider {
Messaging.sendF(player, "%s showing waypoint markers.", StringHelper.wrap("Stopped"));
}
}
private static final int LARGEST_SLOT = 8;
}
private class LinearWaypointGoal implements Goal {

View File

@ -16,12 +16,12 @@ public enum Messages {
CITIZENS_IMPLEMENTATION_DISABLED("citizens.changed-implementation",
"Citizens implementation changed, disabling plugin."),
COMMAND_INVALID_NUMBER("citizens.commands.invalid-number", "That is not a valid number."),
COMMAND_MUST_BE_INGAME("citizens.commands.must-be-ingame", "You must be ingame to use that command."),
COMMAND_REPORT_ERROR("citizens.commands.console-error", "Please report this error: [See console]"),
ERROR_INITALISING_SUB_PLUGIN("citizens.sub-plugins.error-on-load", "{0} initializing {1}"),
ERROR_LOADING_ECONOMY("citizens.economy.error-loading",
"Unable to use economy handling. Has Vault been enabled?"),
FAILED_LOAD_SAVES("citizens.saves.load-failed", "Unable to load saves, disabling..."),
INGAME_COMMAND("citizens.commands.must-be-ingame", "You must be ingame to use that command."),
LOAD_TASK_NOT_SCHEDULED("citizens.load-task-error", "NPC load task couldn't be scheduled - disabling..."),
LOADING_SUB_PLUGIN("citizens.sub-plugins.load", "Loading {0}"),
LOCALE_NOTIFICATION("citizens.notifications.locale", "Using locale {0}."),

View File

@ -31,6 +31,7 @@ public class NMS {
}
private static final float DEFAULT_SPEED = 0.4F;
private static Map<Class<? extends Entity>, Integer> ENTITY_CLASS_TO_INT;
private static final Map<Class<? extends Entity>, Constructor<? extends Entity>> ENTITY_CONSTRUCTOR_CACHE = new WeakHashMap<Class<? extends Entity>, Constructor<? extends Entity>>();
private static Map<Integer, Class<? extends Entity>> ENTITY_INT_TO_CLASS;
@ -41,7 +42,6 @@ public class NMS {
private static Field PATHFINDING_RANGE;
private static Field SPEED_FIELD;
private static Field THREAD_STOPPER;
public static void attack(EntityLiving handle, EntityLiving target) {
handle.k(target);
}
@ -103,6 +103,17 @@ public class NMS {
controllerLook.a(target, 10.0F, handle.bf());
}
public static void look(EntityLiving handle, float yaw, float pitch) {
handle.yaw = handle.as = yaw;
handle.pitch = pitch;
}
public static boolean rayTrace(LivingEntity entity, LivingEntity entity2) {
EntityLiving from = ((CraftLivingEntity) entity).getHandle();
EntityLiving to = ((CraftLivingEntity) entity2).getHandle();
return from.l(to);
}
public static void registerEntityClass(Class<? extends Entity> clazz) {
if (ENTITY_CLASS_TO_INT.containsKey(clazz))
return;

View File

@ -9,8 +9,8 @@ import org.apache.commons.lang.builder.HashCodeBuilder;
public class Pose {
private final String name;
private final float yaw;
private final float pitch;
private final float yaw;
public Pose(String name, float pitch, float yaw) {
this.yaw = yaw;
@ -18,34 +18,6 @@ public class Pose {
this.name = name;
}
@Override
public int hashCode() {
return new HashCodeBuilder(13, 21).
append(name).
toHashCode();
}
@Override
public String toString() {
return "Name: " + name + " Pitch: " + pitch + " Yaw: " + yaw;
}
public String stringValue() {
return name + ";" + pitch + ";" + yaw;
}
public float getYaw() {
return yaw;
}
public float getPitch() {
return pitch;
}
public String getName() {
return name;
}
@Override
public boolean equals(Object object) {
if (object == null) return false;
@ -58,5 +30,33 @@ public class Pose {
append(name, op.getName()).
isEquals();
}
public String getName() {
return name;
}
public float getPitch() {
return pitch;
}
public float getYaw() {
return yaw;
}
@Override
public int hashCode() {
return new HashCodeBuilder(13, 21).
append(name).
toHashCode();
}
public String stringValue() {
return name + ";" + pitch + ";" + yaw;
}
@Override
public String toString() {
return "Name: " + name + " Pitch: " + pitch + " Yaw: " + yaw;
}
}

View File

@ -16,7 +16,6 @@ import org.bukkit.craftbukkit.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
@ -28,6 +27,11 @@ public class Util {
private Util() {
}
public static void assumePose(org.bukkit.entity.Entity entity, Pose pose) {
EntityLiving handle = ((CraftLivingEntity) entity).getHandle();
NMS.look(handle, pose.getYaw(), pose.getPitch());
}
public static void callCollisionEvent(NPC npc, net.minecraft.server.Entity entity) {
if (NPCCollisionEvent.getHandlerList().getRegisteredListeners().length > 0)
Bukkit.getPluginManager().callEvent(new NPCCollisionEvent(npc, entity.getBukkitEntity()));
@ -54,21 +58,11 @@ public class Util {
double yaw = (Math.acos(xDiff / distanceXZ) * 180 / Math.PI);
double pitch = (Math.acos(yDiff / distanceY) * 180 / Math.PI) - 90;
if (zDiff < 0.0) {
if (zDiff < 0.0)
yaw = yaw + (Math.abs(180 - yaw) * 2);
}
EntityLiving handle = ((CraftLivingEntity) from).getHandle();
handle.yaw = (float) yaw - 90;
handle.pitch = (float) pitch;
handle.as = handle.yaw;
}
public static void assumePose(Entity entity, Pose pose) {
EntityLiving handle = ((CraftLivingEntity) entity).getHandle();
handle.yaw = (float) pose.getYaw();
handle.pitch = (float) pose.getPitch();
handle.as = handle.yaw;
NMS.look(handle, (float) yaw - 90, (float) pitch);
}
public static boolean isSettingFulfilled(Player player, Setting setting) {
@ -96,12 +90,6 @@ public class Util {
return type;
}
public static boolean rayTrace(LivingEntity entity, LivingEntity entity2) {
EntityLiving from = ((CraftLivingEntity) entity).getHandle();
EntityLiving to = ((CraftLivingEntity) entity2).getHandle();
return from.l(to);
}
public static void sendPacketNearby(Location location, Packet packet, double radius) {
radius *= radius;
final World world = location.getWorld();