From 836e1cf6a446a67bb812d7266d26f07fcb318e75 Mon Sep 17 00:00:00 2001 From: fullwall Date: Sat, 10 Mar 2012 13:59:37 +0800 Subject: [PATCH] Pathfinding changes --- src/main/java/net/citizensnpcs/Citizens.java | 4 +- .../net/citizensnpcs/npc/ai/CitizensAI.java | 47 ++++++++-------- .../npc/ai/NavigationStrategy.java | 53 +++++++++++++++++++ .../citizensnpcs/npc/ai/TargetStrategy.java | 2 +- .../npc/entity/CitizensHumanNPC.java | 8 +-- .../npc/entity/EntityHumanNPC.java | 21 +++++++- .../waypoint/GenericWaypointCallback.java | 9 ++-- .../trait/waypoint/Waypoints.java | 13 ++--- 8 files changed, 115 insertions(+), 42 deletions(-) create mode 100644 src/main/java/net/citizensnpcs/npc/ai/NavigationStrategy.java diff --git a/src/main/java/net/citizensnpcs/Citizens.java b/src/main/java/net/citizensnpcs/Citizens.java index 1a1f33208..97fdfbe64 100644 --- a/src/main/java/net/citizensnpcs/Citizens.java +++ b/src/main/java/net/citizensnpcs/Citizens.java @@ -254,8 +254,8 @@ public class Citizens extends JavaPlugin { if (!key.keyExists("name")) throw new NPCLoadException("Could not find a name for the NPC with ID '" + id + "'."); - NPC npc = npcManager.createNPC(EntityType.valueOf(key.getString("traits.type").toUpperCase()), id, key - .getString("name"), null); + NPC npc = npcManager.createNPC(EntityType.valueOf(key.getString("traits.type").toUpperCase()), id, + key.getString("name"), null); try { ((CitizensNPC) npc).load(key); } catch (NPCException ex) { diff --git a/src/main/java/net/citizensnpcs/npc/ai/CitizensAI.java b/src/main/java/net/citizensnpcs/npc/ai/CitizensAI.java index 9ff20543c..d627ac2ff 100644 --- a/src/main/java/net/citizensnpcs/npc/ai/CitizensAI.java +++ b/src/main/java/net/citizensnpcs/npc/ai/CitizensAI.java @@ -38,6 +38,20 @@ public class CitizensAI implements AI { Collections.sort(goals); } + @Override + public void cancelDestination() { + if (executing != null) { + Iterator> itr = callbacks.iterator(); + while (itr.hasNext()) { + NavigationCallback next = itr.next().get(); + if (next == null || next.onCancel(this, PathCancelReason.CANCEL)) { + itr.remove(); + } + } + } + executing = null; + } + @Override public boolean hasDestination() { return executing != null; @@ -82,20 +96,15 @@ public class CitizensAI implements AI { @Override public void setDestination(Location destination) { - if (executing != null) { - Iterator> itr = callbacks.iterator(); - while (itr.hasNext()) { - NavigationCallback next = itr.next().get(); - if (next == null || next.onCancel(this, PathCancelReason.PLUGIN)) { - itr.remove(); - } - } - } - executing = new MoveStrategy(npc, destination); + if (destination == null) + throw new IllegalArgumentException("destination cannot be null"); + boolean replaced = executing != null; + executing = new NavigationStrategy(npc, destination); + Iterator> itr = callbacks.iterator(); while (itr.hasNext()) { NavigationCallback next = itr.next().get(); - if (next == null || next.onBegin(this)) { + if (next == null || (replaced && next.onCancel(this, PathCancelReason.REPLACE)) || next.onBegin(this)) { itr.remove(); } } @@ -103,20 +112,16 @@ public class CitizensAI implements AI { @Override public void setTarget(LivingEntity target, boolean aggressive) { - if (executing != null) { - Iterator> itr = callbacks.iterator(); - while (itr.hasNext()) { - NavigationCallback next = itr.next().get(); - if (next == null || next.onCancel(this, PathCancelReason.PLUGIN)) { - itr.remove(); - } - } - } + if (target == null) + throw new IllegalArgumentException("target cannot be null"); + + boolean replaced = executing != null; executing = new TargetStrategy(npc, target, aggressive); + Iterator> itr = callbacks.iterator(); while (itr.hasNext()) { NavigationCallback next = itr.next().get(); - if (next == null || next.onBegin(this)) { + if (next == null || (replaced && next.onCancel(this, PathCancelReason.REPLACE)) || next.onBegin(this)) { itr.remove(); } } diff --git a/src/main/java/net/citizensnpcs/npc/ai/NavigationStrategy.java b/src/main/java/net/citizensnpcs/npc/ai/NavigationStrategy.java new file mode 100644 index 000000000..36030de21 --- /dev/null +++ b/src/main/java/net/citizensnpcs/npc/ai/NavigationStrategy.java @@ -0,0 +1,53 @@ +package net.citizensnpcs.npc.ai; + +import java.lang.reflect.Field; + +import net.citizensnpcs.npc.CitizensNPC; +import net.citizensnpcs.npc.entity.EntityHumanNPC; +import net.minecraft.server.EntityLiving; +import net.minecraft.server.Navigation; + +import org.bukkit.Location; +import org.bukkit.entity.Player; + +public class NavigationStrategy implements PathStrategy { + private final Navigation navigation; + private EntityHumanNPC entity = null; + + NavigationStrategy(CitizensNPC npc, Location dest) { + navigation = npc.getHandle().ak(); + navigation.a(dest.getX(), dest.getY(), dest.getZ(), getSpeed(npc.getHandle())); + if (npc.getBukkitEntity() instanceof Player) + entity = (EntityHumanNPC) npc.getHandle(); + } + + NavigationStrategy(EntityLiving entity, EntityLiving target) { + if (entity instanceof EntityHumanNPC) + entity = entity; + navigation = entity.ak(); + navigation.a(target, getSpeed(entity)); + } + + private float getSpeed(EntityLiving from) { + try { + Field field = EntityLiving.class.getDeclaredField("bb"); + field.setAccessible(true); + return field.getFloat(from); + } catch (Exception ex) { + ex.printStackTrace(); + return 0.7F; + } + } + + @Override + public boolean update() { + if (entity != null) { + navigation.d(); + entity.getControllerMove().c(); + entity.getControllerLook().a(); + entity.getControllerJump().b(); + entity.moveOnCurrentHeading(); + } + return navigation.e(); + } +} diff --git a/src/main/java/net/citizensnpcs/npc/ai/TargetStrategy.java b/src/main/java/net/citizensnpcs/npc/ai/TargetStrategy.java index ccdfbc801..2bda74e82 100644 --- a/src/main/java/net/citizensnpcs/npc/ai/TargetStrategy.java +++ b/src/main/java/net/citizensnpcs/npc/ai/TargetStrategy.java @@ -33,7 +33,7 @@ public class TargetStrategy implements PathStrategy { public boolean update() { if (target == null || target.dead) return true; - current = new MoveStrategy(handle, handle.world.findPath(handle, target, 16F, true, false, false, true)); + current = new NavigationStrategy(handle, target); if (aggro && canAttack()) { if (handle instanceof EntityMonster) { ((EntityMonster) handle).a(target); diff --git a/src/main/java/net/citizensnpcs/npc/entity/CitizensHumanNPC.java b/src/main/java/net/citizensnpcs/npc/entity/CitizensHumanNPC.java index da34a5ede..74d3ad987 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/CitizensHumanNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/CitizensHumanNPC.java @@ -5,7 +5,6 @@ import net.citizensnpcs.api.util.DataKey; import net.citizensnpcs.npc.CitizensNPC; import net.citizensnpcs.npc.CitizensNPCManager; import net.citizensnpcs.util.StringHelper; - import net.minecraft.server.EntityLiving; import net.minecraft.server.ItemInWorldManager; import net.minecraft.server.WorldServer; @@ -32,7 +31,7 @@ public class CitizensHumanNPC extends CitizensNPC { @Override public Player getBukkitEntity() { - return (Player) getHandle().getBukkitEntity(); + return getHandle().getBukkitEntity(); } @Override @@ -56,7 +55,8 @@ public class CitizensHumanNPC extends CitizensNPC { @Override public void update() { super.update(); - if (mcEntity == null) - return; + if (mcEntity != null) { + mcEntity.move(0, -0.1, 0); + } } } \ 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 ab453a5d2..cc30cd5a2 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java @@ -55,9 +55,28 @@ public class EntityHumanNPC extends EntityPlayer { return super.getBukkitEntity(); } + public void moveOnCurrentHeading() { + if (this.aZ) { + if (aT()) { + this.motY += 0.03999999910593033D; + } else if (aU()) { + this.motY += 0.03999999910593033D; + } else if (this.onGround && this.q == 0) { + this.motY = 0.5; + this.q = 10; + } + } else { + this.q = 0; + } + + aX *= 0.98F; + this.a(aW, aX); + } + public void removeFromPlayerMap(String name) { - if (players != null) + if (players != null) { players.remove(name); + } } private static Map players; diff --git a/src/main/java/net/citizensnpcs/trait/waypoint/GenericWaypointCallback.java b/src/main/java/net/citizensnpcs/trait/waypoint/GenericWaypointCallback.java index baae6463d..f7ba1ebd5 100644 --- a/src/main/java/net/citizensnpcs/trait/waypoint/GenericWaypointCallback.java +++ b/src/main/java/net/citizensnpcs/trait/waypoint/GenericWaypointCallback.java @@ -4,7 +4,6 @@ import java.util.Iterator; import net.citizensnpcs.api.ai.AI; import net.citizensnpcs.api.ai.NavigationCallback; -import net.citizensnpcs.util.Messaging; import org.bukkit.Location; @@ -20,8 +19,9 @@ public class GenericWaypointCallback extends NavigationCallback { } private void ensureItr() { - if (itr == null || !itr.hasNext()) + if (itr == null || !itr.hasNext()) { itr = provider.iterator(); + } } @Override @@ -43,7 +43,7 @@ public class GenericWaypointCallback extends NavigationCallback { @Override public boolean onCancel(AI ai, PathCancelReason reason) { - if (executing) { + if (executing && reason == PathCancelReason.REPLACE) { executing = false; } else { executing = true; @@ -60,8 +60,9 @@ public class GenericWaypointCallback extends NavigationCallback { @Override public boolean onCompletion(AI ai) { if (executing) { // if we're executing, we need to get the next waypoint + if (!itr.hasNext()) + itr = provider.iterator(); dest = itr.hasNext() ? itr.next().getLocation() : null; - Messaging.log("fetched next"); } else { executing = true; // we're free to return to our waypoints! diff --git a/src/main/java/net/citizensnpcs/trait/waypoint/Waypoints.java b/src/main/java/net/citizensnpcs/trait/waypoint/Waypoints.java index a72ae66b5..f2004a2f9 100644 --- a/src/main/java/net/citizensnpcs/trait/waypoint/Waypoints.java +++ b/src/main/java/net/citizensnpcs/trait/waypoint/Waypoints.java @@ -56,25 +56,20 @@ public class Waypoints extends Trait { * Class to set as waypoint provider */ public void setWaypointProvider(Class clazz) { - // TODO Probably needs to be changed/fixed. I attempted to make it work - // with refactor. -aPunch provider = create(clazz); - if (provider != null) + if (provider != null) { providerName = providers.get(clazz); + } } private WaypointProvider create(Class clazz) { if (!providers.containsKey(clazz)) return null; - - WaypointProvider provider; try { - provider = clazz.newInstance(); + return clazz.newInstance(); } catch (Exception ex) { - provider = null; + return null; } - - return provider; } private static final Map, String> providers = new HashMap, String>();