80 lines
2.6 KiB
Java
80 lines
2.6 KiB
Java
package net.citizensnpcs.npc.ai;
|
|
|
|
import net.citizensnpcs.api.ai.EntityTarget;
|
|
import net.citizensnpcs.api.ai.TargetType;
|
|
import net.citizensnpcs.npc.CitizensNPC;
|
|
import net.citizensnpcs.util.Util;
|
|
import net.minecraft.server.EntityLiving;
|
|
import net.minecraft.server.EntityMonster;
|
|
import net.minecraft.server.EntityPlayer;
|
|
import net.minecraft.server.Packet18ArmAnimation;
|
|
|
|
import org.bukkit.Location;
|
|
import org.bukkit.craftbukkit.entity.CraftLivingEntity;
|
|
import org.bukkit.entity.LivingEntity;
|
|
|
|
public class MCTargetStrategy implements PathStrategy, EntityTarget {
|
|
private final boolean aggro;
|
|
private final EntityLiving handle, target;
|
|
private final float speed;
|
|
|
|
public MCTargetStrategy(CitizensNPC handle, LivingEntity target, boolean aggro, float speed) {
|
|
this.handle = handle.getHandle();
|
|
this.target = ((CraftLivingEntity) target).getHandle();
|
|
this.aggro = aggro;
|
|
this.speed = speed;
|
|
}
|
|
|
|
private boolean canAttack() {
|
|
return handle.attackTicks == 0
|
|
&& (handle.boundingBox.e > target.boundingBox.b && handle.boundingBox.b < target.boundingBox.e)
|
|
&& distanceSquared() <= ATTACK_DISTANCE && handle.h(target);
|
|
}
|
|
|
|
private double distanceSquared() {
|
|
return handle.getBukkitEntity().getLocation().distanceSquared(target.getBukkitEntity().getLocation());
|
|
}
|
|
|
|
@Override
|
|
public LivingEntity getTarget() {
|
|
return (LivingEntity) target.getBukkitEntity();
|
|
}
|
|
|
|
@Override
|
|
public Location getTargetAsLocation() {
|
|
return getTarget().getLocation();
|
|
}
|
|
|
|
@Override
|
|
public TargetType getTargetType() {
|
|
return TargetType.ENTITY;
|
|
}
|
|
|
|
@Override
|
|
public boolean isAggressive() {
|
|
return aggro;
|
|
}
|
|
|
|
@Override
|
|
public boolean update() {
|
|
if (target == null || target.dead)
|
|
return true;
|
|
new MCNavigationStrategy(handle, target, speed).update();
|
|
handle.getControllerLook().a(target, 10.0F, handle.D());
|
|
if (aggro && canAttack()) {
|
|
if (handle instanceof EntityMonster) {
|
|
((EntityMonster) handle).a((net.minecraft.server.Entity) target);
|
|
// the cast is necessary to resolve overloaded method a
|
|
} else if (handle instanceof EntityPlayer) {
|
|
EntityPlayer humanHandle = (EntityPlayer) handle;
|
|
humanHandle.attack(target);
|
|
Util.sendPacketNearby(handle.getBukkitEntity().getLocation(), new Packet18ArmAnimation(
|
|
humanHandle, 1), 64);
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private static final double ATTACK_DISTANCE = 1.75 * 1.75;
|
|
} |