2012-03-10 06:59:37 +01:00
|
|
|
package net.citizensnpcs.npc.ai;
|
|
|
|
|
|
|
|
import java.lang.reflect.Field;
|
2012-03-27 16:42:15 +02:00
|
|
|
import java.util.Map;
|
2012-03-10 06:59:37 +01:00
|
|
|
|
|
|
|
import net.citizensnpcs.npc.CitizensNPC;
|
|
|
|
import net.minecraft.server.EntityLiving;
|
|
|
|
import net.minecraft.server.Navigation;
|
|
|
|
|
|
|
|
import org.bukkit.Location;
|
2012-03-27 16:42:15 +02:00
|
|
|
import org.bukkit.entity.EntityType;
|
2012-03-10 06:59:37 +01:00
|
|
|
import org.bukkit.entity.Player;
|
|
|
|
|
2012-03-27 16:42:15 +02:00
|
|
|
import com.google.common.collect.Maps;
|
|
|
|
|
2012-03-15 11:06:40 +01:00
|
|
|
public class MCNavigationStrategy implements PathStrategy {
|
2012-05-12 04:01:27 +02:00
|
|
|
private final EntityLiving entity;
|
2012-03-27 16:42:15 +02:00
|
|
|
private final Navigation navigation;
|
2012-03-10 06:59:37 +01:00
|
|
|
|
2012-05-23 10:51:33 +02:00
|
|
|
MCNavigationStrategy(final CitizensNPC npc, final Location dest) {
|
2012-05-12 04:01:27 +02:00
|
|
|
entity = npc.getHandle();
|
2012-03-15 11:06:40 +01:00
|
|
|
if (npc.getBukkitEntity() instanceof Player) {
|
|
|
|
entity.onGround = true;
|
|
|
|
// not sure of a better way around this - if onGround is false, then
|
|
|
|
// navigation won't execute, and calling entity.move doesn't
|
|
|
|
// entirely fix the problem.
|
|
|
|
}
|
2012-05-23 10:51:33 +02:00
|
|
|
navigation = entity.al();
|
2012-03-10 06:59:37 +01:00
|
|
|
navigation.a(dest.getX(), dest.getY(), dest.getZ(), getSpeed(npc.getHandle()));
|
2012-03-15 11:06:40 +01:00
|
|
|
|
2012-03-10 06:59:37 +01:00
|
|
|
}
|
|
|
|
|
2012-03-15 11:06:40 +01:00
|
|
|
MCNavigationStrategy(EntityLiving entity, EntityLiving target) {
|
2012-05-12 04:01:27 +02:00
|
|
|
this.entity = entity;
|
2012-05-23 10:51:33 +02:00
|
|
|
if (entity.getBukkitEntity() instanceof Player) {
|
2012-03-15 11:06:40 +01:00
|
|
|
entity.onGround = true; // see above
|
|
|
|
}
|
2012-03-23 00:49:15 +01:00
|
|
|
navigation = entity.al();
|
2012-03-10 06:59:37 +01:00
|
|
|
navigation.a(target, getSpeed(entity));
|
|
|
|
}
|
|
|
|
|
|
|
|
private float getSpeed(EntityLiving from) {
|
2012-03-27 16:42:15 +02:00
|
|
|
Float cached = MOVEMENT_SPEEDS.get(from.getBukkitEntity().getType());
|
|
|
|
if (cached != null)
|
|
|
|
return cached;
|
|
|
|
if (SPEED_FIELD == null) {
|
|
|
|
MOVEMENT_SPEEDS.put(from.getBukkitEntity().getType(), DEFAULT_SPEED);
|
|
|
|
return DEFAULT_SPEED;
|
|
|
|
}
|
2012-03-10 06:59:37 +01:00
|
|
|
try {
|
2012-03-27 16:42:15 +02:00
|
|
|
float speed = SPEED_FIELD.getFloat(from);
|
|
|
|
MOVEMENT_SPEEDS.put(from.getBukkitEntity().getType(), speed);
|
|
|
|
return speed;
|
|
|
|
} catch (IllegalAccessException ex) {
|
2012-03-10 06:59:37 +01:00
|
|
|
ex.printStackTrace();
|
2012-03-27 16:42:15 +02:00
|
|
|
return DEFAULT_SPEED;
|
2012-03-10 06:59:37 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean update() {
|
|
|
|
return navigation.e();
|
|
|
|
}
|
2012-03-27 16:42:15 +02:00
|
|
|
|
|
|
|
private static final float DEFAULT_SPEED = 0.3F;
|
|
|
|
private static final Map<EntityType, Float> MOVEMENT_SPEEDS = Maps.newEnumMap(EntityType.class);
|
|
|
|
private static Field SPEED_FIELD;
|
|
|
|
static {
|
|
|
|
MOVEMENT_SPEEDS.put(EntityType.IRON_GOLEM, 0.15F);
|
|
|
|
MOVEMENT_SPEEDS.put(EntityType.CHICKEN, 0.25F);
|
|
|
|
MOVEMENT_SPEEDS.put(EntityType.COW, 0.2F);
|
|
|
|
MOVEMENT_SPEEDS.put(EntityType.SHEEP, 0.25F);
|
|
|
|
MOVEMENT_SPEEDS.put(EntityType.VILLAGER, 0.3F);
|
|
|
|
MOVEMENT_SPEEDS.put(EntityType.SNOWMAN, 0.25F);
|
|
|
|
try {
|
|
|
|
SPEED_FIELD = EntityLiving.class.getDeclaredField("bb");
|
|
|
|
SPEED_FIELD.setAccessible(true);
|
|
|
|
} catch (Exception ex) {
|
|
|
|
ex.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
2012-03-10 06:59:37 +01:00
|
|
|
}
|