{
// Get all information needed to chose between physical or magical attack
L2Skill[] skills = null;
double dist_2 = 0;
int range = 0;
L2SiegeGuardInstance sGuard = (L2SiegeGuardInstance) _actor;
try
{
_actor.setTarget(_attackTarget);
skills = _actor.getAllSkills();
dist_2 = _actor.getPlanDistanceSq(_attackTarget.getX(), _attackTarget.getY());
range = _actor.getPhysicalAttackRange() + _actor.getTemplate().collisionRadius + _attackTarget.getTemplate().collisionRadius;
}
catch (NullPointerException e)
{
//_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.getCastle().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 + 20) * (range + 20))
{
// check for long ranged skills and heal/buff skills
if (!Config.ALT_GAME_MOB_ATTACK_AI
|| (_actor instanceof L2MonsterInstance && Rnd.nextInt(100) <= 5))
for (L2Skill sk : skills)
{
int castRange = sk.getCastRange();
if (((sk.getSkillType() == L2Skill.SkillType.BUFF || sk.getSkillType() == L2Skill.SkillType.HEAL) || (dist_2 >= castRange * castRange / 9)
&& (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() == L2Skill.SkillType.BUFF
|| sk.getSkillType() == L2Skill.SkillType.HEAL)
{
boolean useSkillSelf = true;
if (sk.getSkillType() == L2Skill.SkillType.HEAL
&& _actor.getCurrentHp() > (int) (_actor.getMaxHp() / 1.5))
{
useSkillSelf = false;
break;
}
if (sk.getSkillType() == L2Skill.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.getHomeX();
double homeY = _attackTarget.getY() - sGuard.getHomeY();
// Check if the L2SiegeGuardInstance isn't too far from it's home location
if ((dx * dx + dy * dy > 10000) && (homeX * homeX + homeY * homeY > 3240000) // 1800 * 1800
&& (_actor.getKnownList().knowsObject(_attackTarget)))
{