Implement changes

This commit is contained in:
fullwall 2012-08-25 10:40:36 +08:00
parent 98e8b3e991
commit 28356f54a0
7 changed files with 120 additions and 81 deletions

View File

@ -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);
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))
throw new NoPermissionsException();
failed.add(String.format("%s: No permission", traitName));
Class<? extends Trait> clazz = CitizensAPI.getTraitFactory().getTraitClass(traitName);
if (clazz == null)
throw new CommandException("Trait not found.");
if (clazz == null) {
failed.add(String.format("%s: Trait not found", traitName));
continue;
}
boolean remove = npc.hasTrait(clazz);
if (remove) {
npc.removeTrait(clazz);
Messaging.sendF(sender, ChatColor.GREEN + "Trait %s removed successfully.",
StringHelper.wrap(traitName));
return;
removed.add(StringHelper.wrap(traitName));
continue;
}
npc.addTrait(clazz);
Messaging.sendF(sender, ChatColor.GREEN + "Trait %s added successfully.",
StringHelper.wrap(traitName));
added.add(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(

View File

@ -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));
stopNavigating();
}
executing = null;
@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;

View File

@ -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();
}
}

View File

@ -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;

View File

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

View File

@ -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();

View File

@ -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;