Bugfixes, speed updates during pathfinding

This commit is contained in:
fullwall 2012-08-07 22:04:52 +08:00
parent e51a671862
commit e0638f2df7
10 changed files with 67 additions and 34 deletions

View File

@ -8,6 +8,7 @@ import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.CitizensAPI; import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.npc.NPCRegistry; import net.citizensnpcs.api.npc.NPCRegistry;
import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.trait.trait.MobType; import net.citizensnpcs.api.trait.trait.MobType;
import net.citizensnpcs.api.trait.trait.Owner; import net.citizensnpcs.api.trait.trait.Owner;
import net.citizensnpcs.api.trait.trait.Spawned; import net.citizensnpcs.api.trait.trait.Spawned;
@ -70,6 +71,10 @@ public class NPCCommands {
public void age(CommandContext args, CommandSender sender, NPC npc) throws CommandException { public void age(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
Age trait = npc.getTrait(Age.class); Age trait = npc.getTrait(Age.class);
boolean toggleLock = args.hasFlag('l');
if (toggleLock)
Messaging.send(sender, "<a>Age " + (trait.toggle() ? "locked" : "unlocked") + ".");
if (args.argsLength() > 1) { if (args.argsLength() > 1) {
int age = 0; int age = 0;
String ageStr = "an adult"; String ageStr = "an adult";
@ -77,7 +82,7 @@ public class NPCCommands {
age = args.getInteger(1); age = args.getInteger(1);
if (age < -24000 || age > 0) if (age < -24000 || age > 0)
throw new CommandException("Invalid age. Valid: adult, baby, number between -24000 and 0"); throw new CommandException("Invalid age. Valid: adult, baby, number between -24000 and 0");
ageStr = "age " + age; ageStr = "age " + StringHelper.wrap(age);
} catch (NumberFormatException ex) { } catch (NumberFormatException ex) {
if (args.getString(1).equalsIgnoreCase("baby")) { if (args.getString(1).equalsIgnoreCase("baby")) {
age = -24000; age = -24000;
@ -87,11 +92,9 @@ public class NPCCommands {
} }
trait.setAge(age); trait.setAge(age);
Messaging.send(sender, StringHelper.wrap(npc.getName()) + " is now " + ageStr + "."); Messaging.sendF(sender, StringHelper.wrap(npc.getName()) + " is now %s.", ageStr);
} } else if (!toggleLock)
trait.describe(sender);
if (args.hasFlag('l'))
Messaging.send(sender, "<a>Age " + (trait.toggle() ? "locked" : "unlocked") + ".");
} }
@Command( @Command(
@ -104,19 +107,19 @@ public class NPCCommands {
public void behaviour(CommandContext args, CommandSender sender, NPC npc) throws CommandException { public void behaviour(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
Iterable<String> files = Splitter.on(',').split(args.getJoinedStrings(1, ',')); Iterable<String> files = Splitter.on(',').split(args.getJoinedStrings(1, ','));
if (args.hasFlag('r')) { if (args.hasFlag('r')) {
npc.getTrait(Behaviour.class).addScripts(files);
sender.sendMessage(ChatColor.GREEN + "Behaviours added.");
} else {
npc.getTrait(Behaviour.class).removeScripts(files); npc.getTrait(Behaviour.class).removeScripts(files);
sender.sendMessage(ChatColor.GREEN + "Behaviours removed."); sender.sendMessage(ChatColor.GREEN + "Behaviours removed.");
} else {
npc.getTrait(Behaviour.class).addScripts(files);
sender.sendMessage(ChatColor.GREEN + "Behaviours added.");
} }
} }
@Command( @Command(
aliases = { "npc" }, aliases = { "npc" },
usage = "controllable", usage = "controllable|control",
desc = "Toggles whether the NPC can be ridden and controlled", desc = "Toggles whether the NPC can be ridden and controlled",
modifiers = { "controllable" }, modifiers = { "controllable", "control" },
min = 1, min = 1,
max = 1, max = 1,
permission = "npc.controllable") permission = "npc.controllable")
@ -155,16 +158,15 @@ public class NPCCommands {
@Command( @Command(
aliases = { "npc" }, aliases = { "npc" },
usage = "create [name] ((-b) --type (type) --char (char) --behaviour (behaviour))", usage = "create [name] ((-b) --type (type) --trait ('trait1, trait2...') --b (behaviour))",
desc = "Create a new NPC", desc = "Create a new NPC",
flags = "b", flags = "b",
modifiers = { "create" }, modifiers = { "create" },
min = 2, min = 2,
max = 5,
permission = "npc.create") permission = "npc.create")
@Requirements @Requirements
public void create(CommandContext args, final Player player, NPC npc) { public void create(CommandContext args, final Player player, NPC npc) {
String name = args.getString(1); String name = StringHelper.parseColors(args.getJoinedStrings(1));
if (name.length() > 16) { if (name.length() > 16) {
Messaging.sendError(player, Messaging.sendError(player,
"NPC names cannot be longer than 16 characters. The name has been shortened."); "NPC names cannot be longer than 16 characters. The name has been shortened.");
@ -183,6 +185,7 @@ public class NPCCommands {
type = EntityType.PLAYER; type = EntityType.PLAYER;
} }
} }
npc = npcRegistry.createNPC(type, name); npc = npcRegistry.createNPC(type, name);
String msg = ChatColor.GREEN + "You created " + StringHelper.wrap(npc.getName()) String msg = ChatColor.GREEN + "You created " + StringHelper.wrap(npc.getName())
+ " at your location"; + " at your location";
@ -197,8 +200,17 @@ public class NPCCommands {
msg += " as a baby"; msg += " as a baby";
} }
} }
if (args.hasValueFlag("trait")) {
Iterable<String> parts = Splitter.on(",").trimResults().split(args.getFlag("trait"));
for (String tr : parts) {
Class<? extends Trait> clazz = CitizensAPI.getTraitFactory().getTraitClass(tr);
if (clazz != null)
npc.addTrait(clazz);
}
msg += " with the specified traits";
}
if (args.hasValueFlag("behaviour")) { if (args.hasValueFlag("b")) {
npc.getTrait(Behaviour.class).addScripts(Splitter.on(",").split(args.getFlag("behaviour"))); npc.getTrait(Behaviour.class).addScripts(Splitter.on(",").split(args.getFlag("behaviour")));
msg += " with the specified behaviours"; msg += " with the specified behaviours";
} }
@ -393,32 +405,28 @@ public class NPCCommands {
@Command( @Command(
aliases = { "npc" }, aliases = { "npc" },
usage = "profession [profession]", usage = "profession|prof [profession]",
desc = "Set a NPC's profession", desc = "Set a NPC's profession",
modifiers = { "profession" }, modifiers = { "profession", "prof" },
min = 2, min = 2,
max = 2, max = 2,
permission = "npc.profession") permission = "npc.profession")
@Requirements(selected = true, ownership = true, types = { EntityType.VILLAGER }) @Requirements(selected = true, ownership = true, types = { EntityType.VILLAGER })
public void profession(CommandContext args, CommandSender sender, NPC npc) throws CommandException { public void profession(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
String profession = args.getString(1); String profession = args.getString(1);
Profession parsed;
try { try {
npc.getTrait(VillagerProfession.class) parsed = Profession.valueOf(profession.toUpperCase());
.setProfession(Profession.valueOf(profession.toUpperCase()));
Messaging.send(sender, StringHelper.wrap(npc.getName()) + " is now the profession "
+ StringHelper.wrap(profession.toUpperCase()) + ".");
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
throw new CommandException("'" + profession + "' is not a valid profession."); throw new CommandException("'" + profession + "' is not a valid profession.");
} }
npc.getTrait(VillagerProfession.class).setProfession(parsed);
Messaging.send(sender,
StringHelper.wrap(npc.getName()) + " is now a " + StringHelper.wrap(profession) + ".");
} }
@Command( @Command(aliases = { "npc" }, usage = "remove|rem (all)", desc = "Remove a NPC", modifiers = { "remove",
aliases = { "npc" }, "rem" }, min = 1, max = 2)
usage = "remove (all)",
desc = "Remove a NPC",
modifiers = { "remove" },
min = 1,
max = 2)
@Requirements @Requirements
public void remove(CommandContext args, CommandSender sender, NPC npc) throws CommandException { public void remove(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
if (args.argsLength() == 2) { if (args.argsLength() == 2) {
@ -466,9 +474,9 @@ public class NPCCommands {
@Command( @Command(
aliases = { "npc" }, aliases = { "npc" },
usage = "select [id]", usage = "select|sel [id]",
desc = "Select a NPC with the given ID", desc = "Select a NPC with the given ID",
modifiers = { "select" }, modifiers = { "select", "sel" },
min = 2, min = 2,
max = 2, max = 2,
permission = "npc.select") permission = "npc.select")
@ -547,7 +555,7 @@ public class NPCCommands {
} }
@Command(aliases = { "npc" }, usage = "tphere", desc = "Teleport a NPC to your location", modifiers = { @Command(aliases = { "npc" }, usage = "tphere", desc = "Teleport a NPC to your location", modifiers = {
"tphere", "move" }, min = 1, max = 1, permission = "npc.tphere") "tphere", "tph", "move" }, min = 1, max = 1, permission = "npc.tphere")
public void tphere(CommandContext args, Player player, NPC npc) { public void tphere(CommandContext args, Player player, NPC npc) {
// Spawn the NPC if it isn't spawned to prevent NPEs // Spawn the NPC if it isn't spawned to prevent NPEs
if (!npc.isSpawned()) if (!npc.isSpawned())

View File

@ -139,10 +139,10 @@ public abstract class CitizensNPC extends AbstractNPC {
getTrait(CurrentLocation.class).setLocation(loc); getTrait(CurrentLocation.class).setLocation(loc);
getTrait(Spawned.class).setSpawned(true); getTrait(Spawned.class).setSpawned(true);
navigator.onSpawn();
// Modify NPC using traits after the entity has been created // Modify NPC using traits after the entity has been created
for (Trait trait : traits.values()) for (Trait trait : traits.values())
trait.onSpawn(); trait.onSpawn();
navigator.onSpawn();
return true; return true;
} }

View File

@ -46,6 +46,8 @@ public class CitizensNavigator implements Navigator {
@Override @Override
public float getSpeed() { public float getSpeed() {
if (speed == -1)
throw new IllegalStateException("NPC has not been spawned");
return speed; return speed;
} }
@ -88,6 +90,8 @@ public class CitizensNavigator implements Navigator {
@Override @Override
public void setSpeed(float speed) { public void setSpeed(float speed) {
this.speed = speed; this.speed = speed;
if (isNavigating())
executing.setSpeed(this.speed);
} }
@Override @Override

View File

@ -38,6 +38,11 @@ public class MCNavigationStrategy implements PathStrategy {
return TargetType.LOCATION; return TargetType.LOCATION;
} }
@Override
public void setSpeed(float speed) {
navigation.a(speed);
}
@Override @Override
public boolean update() { public boolean update() {
return navigation.f(); return navigation.f();

View File

@ -84,6 +84,10 @@ public class MCTargetStrategy implements PathStrategy, EntityTarget {
} }
private static final int ATTACK_DELAY_TICKS = 20; private static final int ATTACK_DELAY_TICKS = 20;
private static final double ATTACK_DISTANCE = 1.75 * 1.75; private static final double ATTACK_DISTANCE = 1.75 * 1.75;
@Override
public void setSpeed(float speed) {
navigation.a(speed);
}
} }

View File

@ -10,4 +10,6 @@ public interface PathStrategy {
TargetType getTargetType(); TargetType getTargetType();
boolean update(); boolean update();
void setSpeed(float speed);
} }

View File

@ -3,7 +3,10 @@ package net.citizensnpcs.trait;
import net.citizensnpcs.api.exception.NPCLoadException; import net.citizensnpcs.api.exception.NPCLoadException;
import net.citizensnpcs.api.trait.Trait; import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.util.DataKey; import net.citizensnpcs.api.util.DataKey;
import net.citizensnpcs.util.Messaging;
import net.citizensnpcs.util.StringHelper;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Ageable; import org.bukkit.entity.Ageable;
public class Age extends Trait implements Toggleable { public class Age extends Trait implements Toggleable {
@ -64,4 +67,9 @@ public class Age extends Trait implements Toggleable {
public String toString() { public String toString() {
return "Age{age=" + age + ",locked=" + locked + "}"; return "Age{age=" + age + ",locked=" + locked + "}";
} }
public void describe(CommandSender sender) {
Messaging.sendF(sender, "%s's age is %s and %s locked.", StringHelper.wrap(npc.getName()),
StringHelper.wrap(age), StringHelper.wrap(locked ? "is" : "isn't"));
}
} }

View File

@ -72,6 +72,7 @@ public class Controllable extends Trait implements Toggleable {
boolean onGround = handle.onGround; boolean onGround = handle.onGround;
handle.motX += handle.passenger.motX * (onGround ? GROUND_SPEED : AIR_SPEED); handle.motX += handle.passenger.motX * (onGround ? GROUND_SPEED : AIR_SPEED);
handle.motZ += handle.passenger.motZ * (onGround ? GROUND_SPEED : AIR_SPEED); handle.motZ += handle.passenger.motZ * (onGround ? GROUND_SPEED : AIR_SPEED);
handle.e(npc.getNavigator().getSpeed());
} }
@Override @Override

View File

@ -40,7 +40,7 @@ public class LookClose extends Trait implements Toggleable, CommandConfigurable
} }
private void findNewTarget() { private void findNewTarget() {
List<Entity> nearby = npc.getBukkitEntity().getNearbyEntities(range / 2, range, range / 2); List<Entity> nearby = npc.getBukkitEntity().getNearbyEntities(range, range, range);
final Location npcLocation = npc.getBukkitEntity().getLocation(); final Location npcLocation = npc.getBukkitEntity().getLocation();
Collections.sort(nearby, new Comparator<Entity>() { Collections.sort(nearby, new Comparator<Entity>() {
@Override @Override

View File

@ -64,6 +64,7 @@ public class StringHelper {
for (ChatColor color : ChatColor.values()) { for (ChatColor color : ChatColor.values()) {
parsed = parsed.replace("<" + color.getChar() + ">", color.toString()); parsed = parsed.replace("<" + color.getChar() + ">", color.toString());
} }
parsed = ChatColor.translateAlternateColorCodes('&', parsed);
return parsed; return parsed;
} }