From 1a9c6ae0a01f3d471ac8ade7af6a6febaad477fc Mon Sep 17 00:00:00 2001 From: fullwall Date: Sat, 25 Aug 2012 10:40:36 +0800 Subject: [PATCH] Implement changes --- .../command/command/TraitCommands.java | 54 +++++++++++----- .../npc/ai/CitizensNavigator.java | 63 ++++++++++++------- .../npc/ai/MCNavigationStrategy.java | 17 +++-- .../citizensnpcs/npc/ai/MCTargetStrategy.java | 15 ++--- .../net/citizensnpcs/npc/ai/PathStrategy.java | 2 - .../npc/entity/EntityHumanNPC.java | 45 +++++++------ .../waypoint/LinearWaypointProvider.java | 5 +- 7 files changed, 120 insertions(+), 81 deletions(-) diff --git a/src/main/java/net/citizensnpcs/command/command/TraitCommands.java b/src/main/java/net/citizensnpcs/command/command/TraitCommands.java index d3a52c350..1d735a848 100644 --- a/src/main/java/net/citizensnpcs/command/command/TraitCommands.java +++ b/src/main/java/net/citizensnpcs/command/command/TraitCommands.java @@ -1,5 +1,7 @@ package net.citizensnpcs.command.command; +import java.util.List; + import net.citizensnpcs.api.CitizensAPI; import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.api.trait.Trait; @@ -14,35 +16,53 @@ import net.citizensnpcs.util.StringHelper; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; +import com.google.common.base.Joiner; +import com.google.common.base.Splitter; +import com.google.common.collect.Lists; + public class TraitCommands { @Command( aliases = { "trait", "tr" }, - usage = "[trait name]", - desc = "Adds a trait to the NPC", + usage = "[trait name], [trait name]...", + desc = "Adds traits to the NPC", modifiers = { "*" }, min = 1, max = 1, flags = "r", permission = "npc.trait") public void add(CommandContext args, CommandSender sender, NPC npc) throws CommandException { - String traitName = args.getString(0); - if (!sender.hasPermission("citizens.npc.trait." + traitName)) - throw new NoPermissionsException(); + List added = Lists.newArrayList(); + List removed = Lists.newArrayList(); + List failed = Lists.newArrayList(); + for (String traitName : Splitter.on(',').split(args.getJoinedStrings(0))) { + if (!sender.hasPermission("citizens.npc.trait." + traitName)) + failed.add(String.format("%s: No permission", traitName)); - Class clazz = CitizensAPI.getTraitFactory().getTraitClass(traitName); - if (clazz == null) - throw new CommandException("Trait not found."); - boolean remove = npc.hasTrait(clazz); - if (remove) { - npc.removeTrait(clazz); - Messaging.sendF(sender, ChatColor.GREEN + "Trait %s removed successfully.", - StringHelper.wrap(traitName)); - return; + Class clazz = CitizensAPI.getTraitFactory().getTraitClass(traitName); + if (clazz == null) { + failed.add(String.format("%s: Trait not found", traitName)); + continue; + } + boolean remove = npc.hasTrait(clazz); + if (remove) { + npc.removeTrait(clazz); + removed.add(StringHelper.wrap(traitName)); + continue; + } + npc.addTrait(clazz); + added.add(StringHelper.wrap(traitName)); } - npc.addTrait(clazz); - Messaging.sendF(sender, ChatColor.GREEN + "Trait %s added successfully.", - StringHelper.wrap(traitName)); + if (added.size() > 0) + Messaging + .sendF(sender, ChatColor.GREEN + "Added %s successfully.", Joiner.on(", ").join(removed)); + if (removed.size() > 0) + Messaging.sendF(sender, ChatColor.GREEN + "Removed %s successfully.", + Joiner.on(", ").join(removed)); + if (failed.size() > 0) + Messaging + .send(sender, ChatColor.GRAY + "Couldn't change the following traits - " + + Joiner.on(", ").join(failed)); } @Command( diff --git a/src/main/java/net/citizensnpcs/npc/ai/CitizensNavigator.java b/src/main/java/net/citizensnpcs/npc/ai/CitizensNavigator.java index 19a69210e..dd1bc8d79 100644 --- a/src/main/java/net/citizensnpcs/npc/ai/CitizensNavigator.java +++ b/src/main/java/net/citizensnpcs/npc/ai/CitizensNavigator.java @@ -3,6 +3,7 @@ package net.citizensnpcs.npc.ai; import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.api.ai.EntityTarget; import net.citizensnpcs.api.ai.Navigator; +import net.citizensnpcs.api.ai.NavigatorParameters; import net.citizensnpcs.api.ai.TargetType; import net.citizensnpcs.api.ai.event.CancelReason; import net.citizensnpcs.api.ai.event.NavigationBeginEvent; @@ -18,20 +19,25 @@ import org.bukkit.Location; import org.bukkit.entity.LivingEntity; public class CitizensNavigator implements Navigator { + private final NavigatorParameters defaultParams = new NavigatorParameters().speed(UNINITIALISED_SPEED); private PathStrategy executing; + private NavigatorParameters localParams = defaultParams; private final CitizensNPC npc; - private float pathfindingRange = Setting.DEFAULT_PATHFINDING_RANGE.asFloat(); - private float speed = UNINITIALISED_SPEED; + public CitizensNavigator(CitizensNPC npc) { this.npc = npc; } @Override public void cancelNavigation() { - if (executing != null) { + if (isNavigating()) Bukkit.getPluginManager().callEvent(new NavigationCancelEvent(this, CancelReason.PLUGIN)); - } - executing = null; + stopNavigating(); + } + + @Override + public NavigatorParameters getDefaultParameters() { + return defaultParams; } @Override @@ -39,16 +45,21 @@ public class CitizensNavigator implements Navigator { return executing instanceof EntityTarget ? (EntityTarget) executing : null; } + @Override + public NavigatorParameters getLocalParameters() { + return localParams; + } + @Override public float getPathfindingRange() { - return pathfindingRange; + return defaultParams.range(); } @Override public float getSpeed() { - if (speed == -1) + if (defaultParams.speed() == UNINITIALISED_SPEED) throw new IllegalStateException("NPC has not been spawned"); - return speed; + return defaultParams.speed(); } @Override @@ -67,31 +78,34 @@ public class CitizensNavigator implements Navigator { } public void load(DataKey root) { - speed = (float) root.getDouble("speed", speed); - pathfindingRange = (float) root.getDouble("pathfinding-range", pathfindingRange); + defaultParams.speed((float) root.getDouble("speed", UNINITIALISED_SPEED)); + defaultParams.range((float) root.getDouble("pathfinding-range", + Setting.DEFAULT_PATHFINDING_RANGE.asFloat())); } public void onSpawn() { - if (speed == UNINITIALISED_SPEED) - speed = NMSReflection.getSpeedFor(npc.getHandle()); + if (defaultParams.speed() == UNINITIALISED_SPEED) + defaultParams.speed(NMSReflection.getSpeedFor(npc.getHandle())); updatePathfindingRange(); } public void save(DataKey root) { - root.setDouble("speed", speed); - root.setDouble("pathfinding-range", pathfindingRange); + root.setDouble("speed", defaultParams.speed()); + root.setDouble("pathfinding-range", defaultParams.range()); } @Override public void setPathfindingRange(float newRange) { - pathfindingRange = newRange; + defaultParams.range(newRange); + if (isNavigating()) + localParams.range(newRange); } @Override public void setSpeed(float speed) { - this.speed = speed; + defaultParams.speed(speed); if (isNavigating()) - executing.setSpeed(this.speed); + localParams.speed(speed); } @Override @@ -102,7 +116,7 @@ public class CitizensNavigator implements Navigator { cancelNavigation(); return; } - PathStrategy newStrategy = new MCTargetStrategy(npc, target, aggressive, speed); + PathStrategy newStrategy = new MCTargetStrategy(npc, target, aggressive, localParams); switchStrategyTo(newStrategy); } @@ -114,10 +128,15 @@ public class CitizensNavigator implements Navigator { cancelNavigation(); return; } - PathStrategy newStrategy = new MCNavigationStrategy(npc, target, speed); + PathStrategy newStrategy = new MCNavigationStrategy(npc, target, localParams); switchStrategyTo(newStrategy); } + private void stopNavigating() { + executing = null; + localParams = defaultParams; + } + private void switchStrategyTo(PathStrategy newStrategy) { if (executing != null) Bukkit.getPluginManager().callEvent(new NavigationReplaceEvent(this)); @@ -126,17 +145,17 @@ public class CitizensNavigator implements Navigator { } public void update() { - if (executing == null || !npc.isSpawned()) + if (!isNavigating() || !npc.isSpawned()) return; boolean finished = executing.update(); if (finished) { Bukkit.getPluginManager().callEvent(new NavigationCompleteEvent(this)); - executing = null; + stopNavigating(); } } private void updatePathfindingRange() { - NMSReflection.updatePathfindingRange(npc, pathfindingRange); + NMSReflection.updatePathfindingRange(npc, localParams.range()); } private static int UNINITIALISED_SPEED = Integer.MIN_VALUE; diff --git a/src/main/java/net/citizensnpcs/npc/ai/MCNavigationStrategy.java b/src/main/java/net/citizensnpcs/npc/ai/MCNavigationStrategy.java index acbdb1232..51afd200c 100644 --- a/src/main/java/net/citizensnpcs/npc/ai/MCNavigationStrategy.java +++ b/src/main/java/net/citizensnpcs/npc/ai/MCNavigationStrategy.java @@ -1,5 +1,6 @@ package net.citizensnpcs.npc.ai; +import net.citizensnpcs.api.ai.NavigatorParameters; import net.citizensnpcs.api.ai.TargetType; import net.citizensnpcs.npc.CitizensNPC; import net.minecraft.server.EntityLiving; @@ -10,15 +11,17 @@ import org.bukkit.entity.Player; public class MCNavigationStrategy implements PathStrategy { private final Navigation navigation; + private final NavigatorParameters parameters; private final Location target; - MCNavigationStrategy(final CitizensNPC npc, Location dest, float speed) { - this(npc.getHandle(), dest); - navigation.a(dest.getX(), dest.getY(), dest.getZ(), speed); + MCNavigationStrategy(final CitizensNPC npc, Location dest, NavigatorParameters params) { + this(npc.getHandle(), dest, params); + navigation.a(dest.getX(), dest.getY(), dest.getZ(), parameters.speed()); } - private MCNavigationStrategy(EntityLiving entity, Location target) { + private MCNavigationStrategy(EntityLiving entity, Location target, NavigatorParameters params) { this.target = target; + this.parameters = params; if (entity.getBukkitEntity() instanceof Player) { entity.onGround = true; // not sure of a better way around this - if onGround is false, then @@ -38,13 +41,9 @@ public class MCNavigationStrategy implements PathStrategy { return TargetType.LOCATION; } - @Override - public void setSpeed(float speed) { - navigation.a(speed); - } - @Override public boolean update() { + navigation.a(parameters.speed()); return navigation.f(); } } diff --git a/src/main/java/net/citizensnpcs/npc/ai/MCTargetStrategy.java b/src/main/java/net/citizensnpcs/npc/ai/MCTargetStrategy.java index c4e1269d9..12f221e1d 100644 --- a/src/main/java/net/citizensnpcs/npc/ai/MCTargetStrategy.java +++ b/src/main/java/net/citizensnpcs/npc/ai/MCTargetStrategy.java @@ -1,6 +1,7 @@ package net.citizensnpcs.npc.ai; import net.citizensnpcs.api.ai.EntityTarget; +import net.citizensnpcs.api.ai.NavigatorParameters; import net.citizensnpcs.api.ai.TargetType; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.util.Util; @@ -19,14 +20,14 @@ public class MCTargetStrategy implements PathStrategy, EntityTarget { private int attackTicks; private final EntityLiving handle, target; private final Navigation navigation; - private final float speed; + private final NavigatorParameters parameters; - public MCTargetStrategy(CitizensNPC handle, LivingEntity target, boolean aggro, float speed) { + public MCTargetStrategy(CitizensNPC handle, LivingEntity target, boolean aggro, NavigatorParameters params) { this.handle = handle.getHandle(); this.target = ((CraftLivingEntity) target).getHandle(); this.navigation = this.handle.getNavigation(); this.aggro = aggro; - this.speed = speed; + this.parameters = params; } private boolean canAttack() { @@ -59,16 +60,11 @@ public class MCTargetStrategy implements PathStrategy, EntityTarget { return aggro; } - @Override - public void setSpeed(float speed) { - navigation.a(speed); - } - @Override public boolean update() { if (target == null || target.dead) return true; - navigation.a(target, speed); + navigation.a(target, parameters.speed()); handle.getControllerLook().a(target, 10.0F, handle.bf()); if (aggro && canAttack()) { if (handle instanceof EntityMonster) { @@ -87,6 +83,7 @@ public class MCTargetStrategy implements PathStrategy, EntityTarget { return false; } + private static final int ATTACK_DELAY_TICKS = 20; private static final double ATTACK_DISTANCE = 1.75 * 1.75; diff --git a/src/main/java/net/citizensnpcs/npc/ai/PathStrategy.java b/src/main/java/net/citizensnpcs/npc/ai/PathStrategy.java index 7c1eb29bf..43ea83e69 100644 --- a/src/main/java/net/citizensnpcs/npc/ai/PathStrategy.java +++ b/src/main/java/net/citizensnpcs/npc/ai/PathStrategy.java @@ -9,7 +9,5 @@ public interface PathStrategy { TargetType getTargetType(); - void setSpeed(float speed); - boolean update(); } \ No newline at end of file diff --git a/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java b/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java index 5e5dd6ba5..2f8e43676 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java @@ -28,27 +28,11 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder { public EntityHumanNPC(MinecraftServer minecraftServer, World world, String string, ItemInWorldManager itemInWorldManager, NPC npc) { super(minecraftServer, world, string, itemInWorldManager); - this.npc = (CitizensNPC) npc; itemInWorldManager.setGameMode(EnumGamemode.SURVIVAL); - Socket socket = new EmptySocket(); - NetworkManager netMgr = new EmptyNetworkManager(socket, "npc mgr", new NetHandler() { - @Override - public boolean a() { - return false; - } - }, server.E().getPrivate()); - - netServerHandler = new EmptyNetHandler(minecraftServer, netMgr, this); - netMgr.a(netServerHandler); - W = STEP_HEIGHT; // fix moving up slabs and steps - getNavigation().e(true); - - try { - socket.close(); - } catch (IOException ex) { - // swallow - } + this.npc = (CitizensNPC) npc; + if (npc != null) + initialise(minecraftServer); } @Override @@ -86,6 +70,8 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder { @Override public void h_() { super.h_(); + if (npc == null) + return; Navigation navigation = getNavigation(); if (!navigation.f()) { navigation.e(); @@ -99,6 +85,27 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder { npc.update(); } + private void initialise(MinecraftServer minecraftServer) { + Socket socket = new EmptySocket(); + NetworkManager netMgr = new EmptyNetworkManager(socket, "npc mgr", new NetHandler() { + @Override + public boolean a() { + return false; + } + }, server.E().getPrivate()); + + netServerHandler = new EmptyNetHandler(minecraftServer, netMgr, this); + netMgr.a(netServerHandler); + W = STEP_HEIGHT; // fix moving up slabs and steps + getNavigation().e(true); + + try { + socket.close(); + } catch (IOException ex) { + // swallow + } + } + private void moveOnCurrentHeading() { getControllerMove().c(); getControllerLook().a(); diff --git a/src/main/java/net/citizensnpcs/trait/waypoint/LinearWaypointProvider.java b/src/main/java/net/citizensnpcs/trait/waypoint/LinearWaypointProvider.java index 2ed5c7d60..0b4e7606a 100644 --- a/src/main/java/net/citizensnpcs/trait/waypoint/LinearWaypointProvider.java +++ b/src/main/java/net/citizensnpcs/trait/waypoint/LinearWaypointProvider.java @@ -229,7 +229,7 @@ public class LinearWaypointProvider implements WaypointProvider { } @Override - public void run() { + public void run(GoalSelector selector) { } public void setPaused(boolean pause) { @@ -243,8 +243,7 @@ public class LinearWaypointProvider implements WaypointProvider { if (paused || currentDestination != null || !npc.isSpawned() || waypoints.size() == 0) return false; if (waypoints.size() == 1) { - // avoid repeatedly pathing to the same point and wasting - // memory. + // avoid pathing to the same point and wasting memory. Location dest = npc.getBukkitEntity().getLocation(); if (waypoints.get(0).getLocation().distanceSquared(dest) < 3) return false;