Implement new setTarget

This commit is contained in:
fullwall 2013-03-30 20:47:10 +08:00
parent 14b0387c04
commit 32f745a7d0
3 changed files with 62 additions and 15 deletions

View File

@ -22,6 +22,7 @@ import net.citizensnpcs.util.NMS;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.util.Vector;
@ -134,7 +135,7 @@ public class CitizensNavigator implements Navigator, Runnable {
}
@Override
public void setTarget(LivingEntity target, boolean aggressive) {
public void setTarget(Entity target, boolean aggressive) {
if (!npc.isSpawned())
throw new IllegalStateException("npc is not spawned");
if (target == null) {
@ -146,6 +147,11 @@ public class CitizensNavigator implements Navigator, Runnable {
switchStrategyTo(newStrategy);
}
@Override
public void setTarget(LivingEntity target, boolean aggressive) {
setTarget((Entity) target, aggressive);
}
@Override
public void setTarget(Location target) {
if (!npc.isSpawned())

View File

@ -1,5 +1,7 @@
package net.citizensnpcs.npc.ai;
import java.lang.reflect.Field;
import net.citizensnpcs.api.ai.AttackStrategy;
import net.citizensnpcs.api.ai.EntityTarget;
import net.citizensnpcs.api.ai.NavigatorParameters;
@ -8,11 +10,14 @@ import net.citizensnpcs.api.ai.event.CancelReason;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.PlayerAnimation;
import net.minecraft.server.v1_5_R2.Entity;
import net.minecraft.server.v1_5_R2.EntityLiving;
import net.minecraft.server.v1_5_R2.EntityPlayer;
import net.minecraft.server.v1_5_R2.Navigation;
import net.minecraft.server.v1_5_R2.PathEntity;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_5_R2.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_5_R2.entity.CraftLivingEntity;
import org.bukkit.entity.LivingEntity;
@ -20,17 +25,19 @@ public class MCTargetStrategy implements PathStrategy, EntityTarget {
private final boolean aggro;
private int attackTicks;
private CancelReason cancelReason;
private final EntityLiving handle, target;
private final EntityLiving handle;
private final Navigation navigation;
private final NavigatorParameters parameters;
private final Entity target;
private final NavigationFieldWrapper wrapper;
public MCTargetStrategy(NPC handle, LivingEntity target, boolean aggro, NavigatorParameters params) {
public MCTargetStrategy(NPC handle, org.bukkit.entity.Entity target, boolean aggro, NavigatorParameters params) {
this.handle = ((CraftLivingEntity) handle.getBukkitEntity()).getHandle();
this.target = ((CraftLivingEntity) target).getHandle();
this.target = ((CraftEntity) target).getHandle();
this.navigation = this.handle.getNavigation();
this.aggro = aggro;
this.parameters = params;
this.navigation.a(parameters.avoidWater());
this.wrapper = new NavigationFieldWrapper(this.navigation);
}
private boolean canAttack() {
@ -78,6 +85,10 @@ public class MCTargetStrategy implements PathStrategy, EntityTarget {
return aggro;
}
private void setPath() {
navigation.a(wrapper.findPath(handle, target), parameters.speed());
}
@Override
public void stop() {
navigation.g();
@ -96,8 +107,8 @@ public class MCTargetStrategy implements PathStrategy, EntityTarget {
if (cancelReason != null)
return true;
navigation.a(parameters.avoidWater());
navigation.a(target, parameters.speed());
NMS.look(handle.getControllerLook(), handle, target);
setPath();
NMS.look(handle, target);
if (aggro && canAttack()) {
AttackStrategy strategy = parameters.attackStrategy();
if (strategy != null && strategy.handle((LivingEntity) handle.getBukkitEntity(), getTarget())) {
@ -116,8 +127,39 @@ public class MCTargetStrategy implements PathStrategy, EntityTarget {
return false;
}
private class NavigationFieldWrapper {
float e;
boolean j = true, k, l, m;
private NavigationFieldWrapper(Navigation navigation) {
this.k = navigation.c();
this.l = navigation.a();
try {
if (NAV_E != null)
e = NAV_E.getFloat(navigation);
if (NAV_J != null)
j = NAV_J.getBoolean(navigation);
if (NAV_M != null)
m = NAV_M.getBoolean(navigation);
} catch (Exception ex) {
e = parameters.speed();
}
}
public PathEntity findPath(Entity from, Entity to) {
return handle.world.findPath(from, to, e, j, k, l, m);
}
}
private static final int ATTACK_DELAY_TICKS = 20;
private static final double ATTACK_DISTANCE = 1.75 * 1.75;
private static final Location HANDLE_LOCATION = new Location(null, 0, 0, 0);
private static Field NAV_E, NAV_J, NAV_M;
private static final Location TARGET_LOCATION = new Location(null, 0, 0, 0);
static {
NAV_E = NMS.getField(Navigation.class, "e");
NAV_J = NMS.getField(Navigation.class, "j");
NAV_M = NMS.getField(Navigation.class, "m");
}
}

View File

@ -12,7 +12,6 @@ import java.util.WeakHashMap;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.util.Messaging;
import net.minecraft.server.v1_5_R2.ControllerJump;
import net.minecraft.server.v1_5_R2.ControllerLook;
import net.minecraft.server.v1_5_R2.DamageSource;
import net.minecraft.server.v1_5_R2.EnchantmentManager;
import net.minecraft.server.v1_5_R2.Entity;
@ -77,8 +76,8 @@ public class NMS {
}
}
public static void attack(EntityLiving handle, EntityLiving target) {
int damage = handle instanceof EntityMonster ? ((EntityMonster) handle).c((Entity) target) : 2;
public static void attack(EntityLiving handle, Entity target) {
int damage = handle instanceof EntityMonster ? ((EntityMonster) handle).c(target) : 2;
if (handle.hasEffect(MobEffectList.INCREASE_DAMAGE)) {
damage += 3 << handle.getEffect(MobEffectList.INCREASE_DAMAGE).getAmplifier();
@ -91,8 +90,8 @@ public class NMS {
int knockbackLevel = 0;
if (target instanceof EntityLiving) {
damage += EnchantmentManager.a(handle, target);
knockbackLevel += EnchantmentManager.getKnockbackEnchantmentLevel(handle, target);
damage += EnchantmentManager.a(handle, (EntityLiving) target);
knockbackLevel += EnchantmentManager.getKnockbackEnchantmentLevel(handle, (EntityLiving) target);
}
boolean success = target.damageEntity(DamageSource.mobAttack(handle), damage);
@ -137,7 +136,7 @@ public class NMS {
return constructor;
}
private static Field getField(Class<?> clazz, String field) {
public static Field getField(Class<?> clazz, String field) {
Field f = null;
try {
f = clazz.getDeclaredField(field);
@ -184,8 +183,8 @@ public class NMS {
((CraftServer) Bukkit.getServer()).enablePlugins(PluginLoadOrder.POSTWORLD);
}
public static void look(ControllerLook controllerLook, EntityLiving handle, EntityLiving target) {
controllerLook.a(target, 10.0F, handle.bs());
public static void look(EntityLiving handle, Entity target) {
handle.getControllerLook().a(target, 10.0F, handle.bs());
}
public static void look(LivingEntity bukkitEntity, float yaw, float pitch) {