Pathfinding changes

This commit is contained in:
fullwall 2012-03-10 13:59:37 +08:00
parent d2cc9982ec
commit 836e1cf6a4
8 changed files with 115 additions and 42 deletions

View File

@ -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) {

View File

@ -38,6 +38,20 @@ public class CitizensAI implements AI {
Collections.sort(goals);
}
@Override
public void cancelDestination() {
if (executing != null) {
Iterator<WeakReference<NavigationCallback>> 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<WeakReference<NavigationCallback>> 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<WeakReference<NavigationCallback>> 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<WeakReference<NavigationCallback>> 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<WeakReference<NavigationCallback>> 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();
}
}

View File

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

View File

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

View File

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

View File

@ -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<String, CraftPlayer> players;

View File

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

View File

@ -56,25 +56,20 @@ public class Waypoints extends Trait {
* Class to set as waypoint provider
*/
public void setWaypointProvider(Class<? extends WaypointProvider> 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<? extends WaypointProvider> 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<Class<? extends WaypointProvider>, String> providers = new HashMap<Class<? extends WaypointProvider>, String>();