From 6e5f77be626dd93ee7946a4eb02d030f4b7d4d7b Mon Sep 17 00:00:00 2001 From: fullwall Date: Wed, 3 Jul 2013 18:29:57 +0800 Subject: [PATCH] Fix player line of sight checking and make the A* targeting more robust (10 retries before cancelling target) --- .../citizensnpcs/npc/ai/MCTargetStrategy.java | 11 +++++- .../npc/entity/EntityHumanNPC.java | 16 +++++++- .../util/nms/PlayerEntitySenses.java | 38 +++++++++++++++++++ 3 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 src/main/java/net/citizensnpcs/util/nms/PlayerEntitySenses.java diff --git a/src/main/java/net/citizensnpcs/npc/ai/MCTargetStrategy.java b/src/main/java/net/citizensnpcs/npc/ai/MCTargetStrategy.java index d04ef444d..9619d891b 100644 --- a/src/main/java/net/citizensnpcs/npc/ai/MCTargetStrategy.java +++ b/src/main/java/net/citizensnpcs/npc/ai/MCTargetStrategy.java @@ -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 diff --git a/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java b/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java index acb83ce9b..24059fb08 100644 --- a/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java +++ b/src/main/java/net/citizensnpcs/npc/entity/EntityHumanNPC.java @@ -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 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 diff --git a/src/main/java/net/citizensnpcs/util/nms/PlayerEntitySenses.java b/src/main/java/net/citizensnpcs/util/nms/PlayerEntitySenses.java new file mode 100644 index 000000000..39737480d --- /dev/null +++ b/src/main/java/net/citizensnpcs/util/nms/PlayerEntitySenses.java @@ -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 seenEntities = new ArrayList(); + List unseenEntities = new ArrayList(); + + 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; + } + } +} \ No newline at end of file