L2Skill[] skills = null;
double dist_2 = 0;
int range = 0;
L2FortSiegeGuardInstance sGuard;
sGuard = (L2FortSiegeGuardInstance) _actor;
L2Character attackTarget = getAttackTarget();
try
{
_actor.setTarget(attackTarget);
skills = _actor.getAllSkills();
dist_2 = _actor.getPlanDistanceSq(attackTarget.getX(), attackTarget.getY());
range = _actor.getPhysicalAttackRange() + _actor.getTemplate().collisionRadius + attackTarget.getTemplate().collisionRadius;
if(attackTarget.isMoving())
{
range += 50;
}
}
catch(NullPointerException e)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
//_log.warning("AttackableAI: Attack target is NULL.");
_actor.setTarget(null);
setIntention(AI_INTENTION_IDLE, null, null);
return;
}
// never attack defenders
if(attackTarget instanceof L2PcInstance && sGuard.getFort().getSiege().checkIsDefender(((L2PcInstance) attackTarget).getClan()))
{
// Cancel the target
sGuard.stopHating(attackTarget);
_actor.setTarget(null);
setIntention(AI_INTENTION_IDLE, null, null);
return;
}
if(!GeoData.getInstance().canSeeTarget(_actor, attackTarget))
{
// Siege guards differ from normal mobs currently:
// If target cannot seen, don't attack any more
sGuard.stopHating(attackTarget);
_actor.setTarget(null);
setIntention(AI_INTENTION_IDLE, null, null);
return;
}
// Check if the actor isn't muted and if it is far from target
if(!_actor.isMuted() && dist_2 > range * range)
{
// check for long ranged skills and heal/buff skills
for(L2Skill sk : skills)
{
int castRange = sk.getCastRange();
if(dist_2 <= castRange * castRange && castRange > 70 && !_actor.isSkillDisabled(sk.getId()) && _actor.getCurrentMp() >= _actor.getStat().getMpConsume(sk) && !sk.isPassive())
{
L2Object OldTarget = _actor.getTarget();
if(sk.getSkillType() == SkillType.BUFF || sk.getSkillType() == SkillType.HEAL)
{
boolean useSkillSelf = true;
if(sk.getSkillType() == SkillType.HEAL && _actor.getCurrentHp() > (int) (_actor.getMaxHp() / 1.5))
{
useSkillSelf = false;
break;
}
if(sk.getSkillType() == SkillType.BUFF)
{
L2Effect[] effects = _actor.getAllEffects();
for(int i = 0; effects != null && i < effects.length; i++)
{
L2Effect effect = effects[i];
if(effect.getSkill() == sk)
{
useSkillSelf = false;
break;
}
}
}
if(useSkillSelf)
{
_actor.setTarget(_actor);
}
}
clientStopMoving(null);
_accessor.doCast(sk);
_actor.setTarget(OldTarget);
return;
}
}
// Check if the L2SiegeGuardInstance is attacking, knows the target and can't run
if(!_actor.isAttackingNow() && _actor.getRunSpeed() == 0 && _actor.getKnownList().knowsObject(attackTarget))
{
// Cancel the target
_actor.getKnownList().removeKnownObject(attackTarget);
_actor.setTarget(null);
setIntention(AI_INTENTION_IDLE, null, null);
}
else
{
double dx = _actor.getX() - attackTarget.getX();
double dy = _actor.getY() - attackTarget.getY();
double dz = _actor.getZ() - attackTarget.getZ();
double homeX = attackTarget.getX() - sGuard.getSpawn().getLocx();
double homeY = attackTarget.getY() - sGuard.getSpawn().getLocy();
// Check if the L2SiegeGuardInstance isn't too far from it's home location
if(dx * dx + dy * dy > 10000 && homeX * homeX + homeY * homeY > 3240000 && _actor.getKnownList().knowsObject(attackTarget))
{
// Cancel the target
_actor.getKnownList().removeKnownObject(attackTarget);
_actor.setTarget(null);
setIntention(AI_INTENTION_IDLE, null, null);
}
else
// Move the actor to Pawn server side AND client side by sending Server->Client packet MoveToPawn (broadcast)
{
// Temporary hack for preventing guards jumping off towers,
// before replacing this with effective GeoClient checks and AI modification
if(dz * dz < 170 * 170) // normally 130 if guard z coordinates correct
{
//if (_selfAnalysis.isMage)
// range = _selfAnalysis.maxCastRange - 50;
if(_actor.getWalkSpeed() <= 0)
return;
if(attackTarget.isMoving())
{
moveToPawn(attackTarget, range - 70);
}
else
{
moveToPawn(attackTarget, range);
}
}
}
}
return;
}
// Else, if the actor is muted and far from target, just "move to pawn"
else if(_actor.isMuted() && dist_2 > range * range)
{
// Temporary hack for preventing guards jumping off towers,
// before replacing this with effective GeoClient checks and AI modification
double dz = _actor.getZ() - attackTarget.getZ();
if(dz * dz < 170 * 170) // normally 130 if guard z coordinates correct
{
//if (_selfAnalysis.isMage)
// range = _selfAnalysis.maxCastRange - 50;
if(_actor.getWalkSpeed() <= 0)
return;
if(attackTarget.isMoving())
{
moveToPawn(attackTarget, range - 70);
}
else
{
moveToPawn(attackTarget, range);
}
}
return;
}
// Else, if this is close enough to attack
else if(dist_2 <= range * range)
{
// Force mobs to attack anybody if confused
L2Character hated = null;
if(_actor.isConfused())
{
hated = attackTarget;
}
else