Fix player line of sight checking and make the A* targeting more robust (10 retries before cancelling target)

This commit is contained in:
fullwall 2013-07-03 18:29:57 +08:00
parent 350a63f0b8
commit 6e5f77be62
3 changed files with 63 additions and 2 deletions

View File

@ -136,6 +136,7 @@ public class MCTargetStrategy implements PathStrategy, EntityTarget {
}
private class AStarTargeter implements TargetNavigator {
private int failureTimes = 0;
private AStarNavigationStrategy strategy = new AStarNavigationStrategy(npc, target.getBukkitEntity()
.getLocation(TARGET_LOCATION), parameters);
@ -144,7 +145,15 @@ public class MCTargetStrategy implements PathStrategy, EntityTarget {
strategy = new AStarNavigationStrategy(npc, target.getBukkitEntity().getLocation(TARGET_LOCATION),
parameters);
strategy.update();
cancelReason = strategy.getCancelReason();
CancelReason subReason = strategy.getCancelReason();
if (subReason == CancelReason.STUCK) {
if (failureTimes++ > 10) {
cancelReason = strategy.getCancelReason();
}
} else {
failureTimes = 0;
cancelReason = strategy.getCancelReason();
}
}
@Override

View File

@ -16,6 +16,7 @@ import net.citizensnpcs.util.Util;
import net.citizensnpcs.util.nms.PlayerControllerJump;
import net.citizensnpcs.util.nms.PlayerControllerLook;
import net.citizensnpcs.util.nms.PlayerControllerMove;
import net.citizensnpcs.util.nms.PlayerEntitySenses;
import net.minecraft.server.v1_6_R1.Connection;
import net.minecraft.server.v1_6_R1.Entity;
import net.minecraft.server.v1_6_R1.EntityPlayer;
@ -32,6 +33,7 @@ import net.minecraft.server.v1_6_R1.World;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_6_R1.CraftServer;
import org.bukkit.craftbukkit.v1_6_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_6_R1.entity.CraftPlayer;
import org.bukkit.metadata.MetadataValue;
import org.bukkit.plugin.Plugin;
@ -41,6 +43,7 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
private PlayerControllerJump controllerJump;
private PlayerControllerLook controllerLook;
private PlayerControllerMove controllerMove;
private PlayerEntitySenses entitySenses;
private boolean gravity = true;
private int jumpTicks = 0;
private final CitizensNPC npc;
@ -207,6 +210,7 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
}
public void updateAI() {
entitySenses.a();
controllerMove.c();
controllerLook.a();
controllerJump.b();
@ -238,6 +242,11 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
this.cserver = (CraftServer) Bukkit.getServer();
}
@Override
public EntityHumanNPC getHandle() {
return (EntityHumanNPC) this.entity;
}
@Override
public List<MetadataValue> getMetadata(String metadataKey) {
return cserver.getEntityMetadata().getMetadata(this, metadataKey);
@ -248,6 +257,11 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
return npc;
}
@Override
public boolean hasLineOfSight(org.bukkit.entity.Entity other) {
return getHandle().entitySenses.canSee(((CraftEntity) other).getHandle());
}
@Override
public boolean hasMetadata(String metadataKey) {
return cserver.getEntityMetadata().hasMetadata(this, metadataKey);
@ -259,7 +273,7 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder {
}
public void setGravityEnabled(boolean enabled) {
((EntityHumanNPC) getHandle()).gravity = enabled;
getHandle().gravity = enabled;
}
@Override

View File

@ -0,0 +1,38 @@
package net.citizensnpcs.util.nms;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.server.v1_6_R1.Entity;
import net.minecraft.server.v1_6_R1.EntityLiving;
public class PlayerEntitySenses {
EntityLiving entity;
List<Entity> seenEntities = new ArrayList<Entity>();
List<Entity> unseenEntities = new ArrayList<Entity>();
public PlayerEntitySenses(EntityLiving entityinsentient) {
this.entity = entityinsentient;
}
public void a() {
this.seenEntities.clear();
this.unseenEntities.clear();
}
public boolean canSee(Entity entity) {
if (this.seenEntities.contains(entity)) {
return true;
} else if (this.unseenEntities.contains(entity)) {
return false;
} else {
boolean flag = this.entity.o(entity);
if (flag) {
this.seenEntities.add(entity);
} else {
this.unseenEntities.add(entity);
}
return flag;
}
}
}