Implement changes

This commit is contained in:
fullwall 2012-08-25 10:40:36 +08:00
parent 26538aafb0
commit 1a9c6ae0a0
7 changed files with 120 additions and 81 deletions

View File

@ -1,5 +1,7 @@
package net.citizensnpcs.command.command; package net.citizensnpcs.command.command;
import java.util.List;
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.trait.Trait; import net.citizensnpcs.api.trait.Trait;
@ -14,35 +16,53 @@ import net.citizensnpcs.util.StringHelper;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; 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 { public class TraitCommands {
@Command( @Command(
aliases = { "trait", "tr" }, aliases = { "trait", "tr" },
usage = "[trait name]", usage = "[trait name], [trait name]...",
desc = "Adds a trait to the NPC", desc = "Adds traits to the NPC",
modifiers = { "*" }, modifiers = { "*" },
min = 1, min = 1,
max = 1, max = 1,
flags = "r", flags = "r",
permission = "npc.trait") permission = "npc.trait")
public void add(CommandContext args, CommandSender sender, NPC npc) throws CommandException { public void add(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
String traitName = args.getString(0); List<String> added = Lists.newArrayList();
List<String> removed = Lists.newArrayList();
List<String> failed = Lists.newArrayList();
for (String traitName : Splitter.on(',').split(args.getJoinedStrings(0))) {
if (!sender.hasPermission("citizens.npc.trait." + traitName)) if (!sender.hasPermission("citizens.npc.trait." + traitName))
throw new NoPermissionsException(); failed.add(String.format("%s: No permission", traitName));
Class<? extends Trait> clazz = CitizensAPI.getTraitFactory().getTraitClass(traitName); Class<? extends Trait> clazz = CitizensAPI.getTraitFactory().getTraitClass(traitName);
if (clazz == null) if (clazz == null) {
throw new CommandException("Trait not found."); failed.add(String.format("%s: Trait not found", traitName));
continue;
}
boolean remove = npc.hasTrait(clazz); boolean remove = npc.hasTrait(clazz);
if (remove) { if (remove) {
npc.removeTrait(clazz); npc.removeTrait(clazz);
Messaging.sendF(sender, ChatColor.GREEN + "Trait %s removed successfully.", removed.add(StringHelper.wrap(traitName));
StringHelper.wrap(traitName)); continue;
return;
} }
npc.addTrait(clazz); npc.addTrait(clazz);
Messaging.sendF(sender, ChatColor.GREEN + "Trait %s added successfully.", added.add(StringHelper.wrap(traitName));
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( @Command(

View File

@ -3,6 +3,7 @@ package net.citizensnpcs.npc.ai;
import net.citizensnpcs.Settings.Setting; import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.ai.EntityTarget; import net.citizensnpcs.api.ai.EntityTarget;
import net.citizensnpcs.api.ai.Navigator; import net.citizensnpcs.api.ai.Navigator;
import net.citizensnpcs.api.ai.NavigatorParameters;
import net.citizensnpcs.api.ai.TargetType; import net.citizensnpcs.api.ai.TargetType;
import net.citizensnpcs.api.ai.event.CancelReason; import net.citizensnpcs.api.ai.event.CancelReason;
import net.citizensnpcs.api.ai.event.NavigationBeginEvent; import net.citizensnpcs.api.ai.event.NavigationBeginEvent;
@ -18,20 +19,25 @@ import org.bukkit.Location;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
public class CitizensNavigator implements Navigator { public class CitizensNavigator implements Navigator {
private final NavigatorParameters defaultParams = new NavigatorParameters().speed(UNINITIALISED_SPEED);
private PathStrategy executing; private PathStrategy executing;
private NavigatorParameters localParams = defaultParams;
private final CitizensNPC npc; private final CitizensNPC npc;
private float pathfindingRange = Setting.DEFAULT_PATHFINDING_RANGE.asFloat();
private float speed = UNINITIALISED_SPEED;
public CitizensNavigator(CitizensNPC npc) { public CitizensNavigator(CitizensNPC npc) {
this.npc = npc; this.npc = npc;
} }
@Override @Override
public void cancelNavigation() { public void cancelNavigation() {
if (executing != null) { if (isNavigating())
Bukkit.getPluginManager().callEvent(new NavigationCancelEvent(this, CancelReason.PLUGIN)); Bukkit.getPluginManager().callEvent(new NavigationCancelEvent(this, CancelReason.PLUGIN));
stopNavigating();
} }
executing = null;
@Override
public NavigatorParameters getDefaultParameters() {
return defaultParams;
} }
@Override @Override
@ -39,16 +45,21 @@ public class CitizensNavigator implements Navigator {
return executing instanceof EntityTarget ? (EntityTarget) executing : null; return executing instanceof EntityTarget ? (EntityTarget) executing : null;
} }
@Override
public NavigatorParameters getLocalParameters() {
return localParams;
}
@Override @Override
public float getPathfindingRange() { public float getPathfindingRange() {
return pathfindingRange; return defaultParams.range();
} }
@Override @Override
public float getSpeed() { public float getSpeed() {
if (speed == -1) if (defaultParams.speed() == UNINITIALISED_SPEED)
throw new IllegalStateException("NPC has not been spawned"); throw new IllegalStateException("NPC has not been spawned");
return speed; return defaultParams.speed();
} }
@Override @Override
@ -67,31 +78,34 @@ public class CitizensNavigator implements Navigator {
} }
public void load(DataKey root) { public void load(DataKey root) {
speed = (float) root.getDouble("speed", speed); defaultParams.speed((float) root.getDouble("speed", UNINITIALISED_SPEED));
pathfindingRange = (float) root.getDouble("pathfinding-range", pathfindingRange); defaultParams.range((float) root.getDouble("pathfinding-range",
Setting.DEFAULT_PATHFINDING_RANGE.asFloat()));
} }
public void onSpawn() { public void onSpawn() {
if (speed == UNINITIALISED_SPEED) if (defaultParams.speed() == UNINITIALISED_SPEED)
speed = NMSReflection.getSpeedFor(npc.getHandle()); defaultParams.speed(NMSReflection.getSpeedFor(npc.getHandle()));
updatePathfindingRange(); updatePathfindingRange();
} }
public void save(DataKey root) { public void save(DataKey root) {
root.setDouble("speed", speed); root.setDouble("speed", defaultParams.speed());
root.setDouble("pathfinding-range", pathfindingRange); root.setDouble("pathfinding-range", defaultParams.range());
} }
@Override @Override
public void setPathfindingRange(float newRange) { public void setPathfindingRange(float newRange) {
pathfindingRange = newRange; defaultParams.range(newRange);
if (isNavigating())
localParams.range(newRange);
} }
@Override @Override
public void setSpeed(float speed) { public void setSpeed(float speed) {
this.speed = speed; defaultParams.speed(speed);
if (isNavigating()) if (isNavigating())
executing.setSpeed(this.speed); localParams.speed(speed);
} }
@Override @Override
@ -102,7 +116,7 @@ public class CitizensNavigator implements Navigator {
cancelNavigation(); cancelNavigation();
return; return;
} }
PathStrategy newStrategy = new MCTargetStrategy(npc, target, aggressive, speed); PathStrategy newStrategy = new MCTargetStrategy(npc, target, aggressive, localParams);
switchStrategyTo(newStrategy); switchStrategyTo(newStrategy);
} }
@ -114,10 +128,15 @@ public class CitizensNavigator implements Navigator {
cancelNavigation(); cancelNavigation();
return; return;
} }
PathStrategy newStrategy = new MCNavigationStrategy(npc, target, speed); PathStrategy newStrategy = new MCNavigationStrategy(npc, target, localParams);
switchStrategyTo(newStrategy); switchStrategyTo(newStrategy);
} }
private void stopNavigating() {
executing = null;
localParams = defaultParams;
}
private void switchStrategyTo(PathStrategy newStrategy) { private void switchStrategyTo(PathStrategy newStrategy) {
if (executing != null) if (executing != null)
Bukkit.getPluginManager().callEvent(new NavigationReplaceEvent(this)); Bukkit.getPluginManager().callEvent(new NavigationReplaceEvent(this));
@ -126,17 +145,17 @@ public class CitizensNavigator implements Navigator {
} }
public void update() { public void update() {
if (executing == null || !npc.isSpawned()) if (!isNavigating() || !npc.isSpawned())
return; return;
boolean finished = executing.update(); boolean finished = executing.update();
if (finished) { if (finished) {
Bukkit.getPluginManager().callEvent(new NavigationCompleteEvent(this)); Bukkit.getPluginManager().callEvent(new NavigationCompleteEvent(this));
executing = null; stopNavigating();
} }
} }
private void updatePathfindingRange() { private void updatePathfindingRange() {
NMSReflection.updatePathfindingRange(npc, pathfindingRange); NMSReflection.updatePathfindingRange(npc, localParams.range());
} }
private static int UNINITIALISED_SPEED = Integer.MIN_VALUE; private static int UNINITIALISED_SPEED = Integer.MIN_VALUE;

View File

@ -1,5 +1,6 @@
package net.citizensnpcs.npc.ai; package net.citizensnpcs.npc.ai;
import net.citizensnpcs.api.ai.NavigatorParameters;
import net.citizensnpcs.api.ai.TargetType; import net.citizensnpcs.api.ai.TargetType;
import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.CitizensNPC;
import net.minecraft.server.EntityLiving; import net.minecraft.server.EntityLiving;
@ -10,15 +11,17 @@ import org.bukkit.entity.Player;
public class MCNavigationStrategy implements PathStrategy { public class MCNavigationStrategy implements PathStrategy {
private final Navigation navigation; private final Navigation navigation;
private final NavigatorParameters parameters;
private final Location target; private final Location target;
MCNavigationStrategy(final CitizensNPC npc, Location dest, float speed) { MCNavigationStrategy(final CitizensNPC npc, Location dest, NavigatorParameters params) {
this(npc.getHandle(), dest); this(npc.getHandle(), dest, params);
navigation.a(dest.getX(), dest.getY(), dest.getZ(), speed); 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.target = target;
this.parameters = params;
if (entity.getBukkitEntity() instanceof Player) { if (entity.getBukkitEntity() instanceof Player) {
entity.onGround = true; entity.onGround = true;
// not sure of a better way around this - if onGround is false, then // 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; return TargetType.LOCATION;
} }
@Override
public void setSpeed(float speed) {
navigation.a(speed);
}
@Override @Override
public boolean update() { public boolean update() {
navigation.a(parameters.speed());
return navigation.f(); return navigation.f();
} }
} }

View File

@ -1,6 +1,7 @@
package net.citizensnpcs.npc.ai; package net.citizensnpcs.npc.ai;
import net.citizensnpcs.api.ai.EntityTarget; import net.citizensnpcs.api.ai.EntityTarget;
import net.citizensnpcs.api.ai.NavigatorParameters;
import net.citizensnpcs.api.ai.TargetType; import net.citizensnpcs.api.ai.TargetType;
import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.util.Util; import net.citizensnpcs.util.Util;
@ -19,14 +20,14 @@ public class MCTargetStrategy implements PathStrategy, EntityTarget {
private int attackTicks; private int attackTicks;
private final EntityLiving handle, target; private final EntityLiving handle, target;
private final Navigation navigation; 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.handle = handle.getHandle();
this.target = ((CraftLivingEntity) target).getHandle(); this.target = ((CraftLivingEntity) target).getHandle();
this.navigation = this.handle.getNavigation(); this.navigation = this.handle.getNavigation();
this.aggro = aggro; this.aggro = aggro;
this.speed = speed; this.parameters = params;
} }
private boolean canAttack() { private boolean canAttack() {
@ -59,16 +60,11 @@ public class MCTargetStrategy implements PathStrategy, EntityTarget {
return aggro; return aggro;
} }
@Override
public void setSpeed(float speed) {
navigation.a(speed);
}
@Override @Override
public boolean update() { public boolean update() {
if (target == null || target.dead) if (target == null || target.dead)
return true; return true;
navigation.a(target, speed); navigation.a(target, parameters.speed());
handle.getControllerLook().a(target, 10.0F, handle.bf()); handle.getControllerLook().a(target, 10.0F, handle.bf());
if (aggro && canAttack()) { if (aggro && canAttack()) {
if (handle instanceof EntityMonster) { if (handle instanceof EntityMonster) {
@ -87,6 +83,7 @@ public class MCTargetStrategy implements PathStrategy, EntityTarget {
return false; return false;
} }
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;

View File

@ -9,7 +9,5 @@ public interface PathStrategy {
TargetType getTargetType(); TargetType getTargetType();
void setSpeed(float speed);
boolean update(); boolean update();
} }

View File

@ -28,27 +28,11 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
public EntityHumanNPC(MinecraftServer minecraftServer, World world, String string, public EntityHumanNPC(MinecraftServer minecraftServer, World world, String string,
ItemInWorldManager itemInWorldManager, NPC npc) { ItemInWorldManager itemInWorldManager, NPC npc) {
super(minecraftServer, world, string, itemInWorldManager); super(minecraftServer, world, string, itemInWorldManager);
this.npc = (CitizensNPC) npc;
itemInWorldManager.setGameMode(EnumGamemode.SURVIVAL); itemInWorldManager.setGameMode(EnumGamemode.SURVIVAL);
Socket socket = new EmptySocket(); this.npc = (CitizensNPC) npc;
NetworkManager netMgr = new EmptyNetworkManager(socket, "npc mgr", new NetHandler() { if (npc != null)
@Override initialise(minecraftServer);
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
}
} }
@Override @Override
@ -86,6 +70,8 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
@Override @Override
public void h_() { public void h_() {
super.h_(); super.h_();
if (npc == null)
return;
Navigation navigation = getNavigation(); Navigation navigation = getNavigation();
if (!navigation.f()) { if (!navigation.f()) {
navigation.e(); navigation.e();
@ -99,6 +85,27 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
npc.update(); 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() { private void moveOnCurrentHeading() {
getControllerMove().c(); getControllerMove().c();
getControllerLook().a(); getControllerLook().a();

View File

@ -229,7 +229,7 @@ public class LinearWaypointProvider implements WaypointProvider {
} }
@Override @Override
public void run() { public void run(GoalSelector selector) {
} }
public void setPaused(boolean pause) { public void setPaused(boolean pause) {
@ -243,8 +243,7 @@ public class LinearWaypointProvider implements WaypointProvider {
if (paused || currentDestination != null || !npc.isSpawned() || waypoints.size() == 0) if (paused || currentDestination != null || !npc.isSpawned() || waypoints.size() == 0)
return false; return false;
if (waypoints.size() == 1) { if (waypoints.size() == 1) {
// avoid repeatedly pathing to the same point and wasting // avoid pathing to the same point and wasting memory.
// memory.
Location dest = npc.getBukkitEntity().getLocation(); Location dest = npc.getBukkitEntity().getLocation();
if (waypoints.get(0).getLocation().distanceSquared(dest) < 3) if (waypoints.get(0).getLocation().distanceSquared(dest) < 3)
return false; return false;