* <li>If the actor is a L2MonsterInstance that can't attack, order to it to random walk (1/100)</li><BR><BR>
*
*/
private void thinkActive()
{
L2Attackable npc = (L2Attackable) _actor;
// Update every 1s the _globalAggro counter to come close to 0
if (_globalAggro != 0)
{
if (_globalAggro < 0) _globalAggro++;
else _globalAggro--;
}
// Add all autoAttackable L2Character in L2Attackable Aggro Range to its _aggroList with 0 damage and 1 hate
// A L2Attackable isn't aggressive during 10s after its spawn because _globalAggro is set to -10
if (_globalAggro >= 0)
{
// Get all visible objects inside its Aggro Range
//L2Object[] objects = L2World.getInstance().getVisibleObjects(_actor, ((L2NpcInstance)_actor).getAggroRange());
// Go through visible objects
for (L2Object obj : npc.getKnownList().getKnownObjects().values())
{
if (obj == null || !(obj instanceof L2Character)) continue;
L2Character target = (L2Character) obj;
/*
* Check to see if this is a festival mob spawn.
* If it is, then check to see if the aggro trigger
* is a festival participant...if so, move to attack it.
*/
if ((_actor instanceof L2FestivalMonsterInstance) && obj instanceof L2PcInstance)
{
L2PcInstance targetPlayer = (L2PcInstance) obj;
if (!(targetPlayer.isFestivalParticipant())) continue;
}
// For each L2Character check if the target is autoattackable
if (autoAttackCondition(target)) // check aggression
{
// Get the hate level of the L2Attackable against this L2Character target contained in _aggroList
int hating = npc.getHating(target);
// Add the attacker to the L2Attackable _aggroList with 0 damage and 1 hate
if (hating == 0) npc.addDamageHate(target, 0, 1);
}
}
// Chose a target from its aggroList
L2Character hated;
if (_actor.isConfused()) hated = getAttackTarget(); // Force mobs to attak anybody if confused
else hated = npc.getMostHated();
// Order to the L2Attackable to attack the target
if (hated != null)
{
// Get the hate level of the L2Attackable against this L2Character target contained in _aggroList
int aggro = npc.getHating(hated);
if (aggro + _globalAggro > 0)
{
// Set the L2Character movement type to run and send Server->Client packet ChangeMoveType to all others L2PcInstance
if (!_actor.isRunning()) _actor.setRunning();
// Set the AI Intention to AI_INTENTION_ATTACK
setIntention(CtrlIntention.AI_INTENTION_ATTACK, hated);
}
return;
}
}
// Check if the actor is a L2GuardInstance
if (_actor instanceof L2GuardInstance)
{
// Order to the L2GuardInstance to return to its home location because there's no target to attack
((L2GuardInstance) _actor).returnHome();
}
// If this is a festival monster, then it remains in the same location.
if (_actor instanceof L2FestivalMonsterInstance) return;
// Minions following leader
if (_actor instanceof L2MinionInstance && ((L2MinionInstance)_actor).getLeader() != null)
{
int offset;
if (_actor.isRaid()) offset = 500; // for Raids - need correction
else offset = 200; // for normal minions - need correction :)
if(((L2MinionInstance)_actor).getLeader().isRunning()) _actor.setRunning();
else _actor.setWalking();
if (_actor.getPlanDistanceSq(((L2MinionInstance)_actor).getLeader()) > offset*offset)
{
int x1, y1, z1;
x1 = ((L2MinionInstance)_actor).getLeader().getX() + Rnd.nextInt( (offset - 30) * 2 ) - ( offset - 30 );
y1 = ((L2MinionInstance)_actor).getLeader().getY() + Rnd.nextInt( (offset - 30) * 2 ) - ( offset - 30 );
z1 = ((L2MinionInstance)_actor).getLeader().getZ();
// Move the actor to Location (x,y,z) server side AND client side by sending Server->Client packet CharMoveToLocation (broadcast)
moveTo(x1, y1, z1);
return;
}
}
// Order to the L2MonsterInstance to random walk (1/100)
else if (npc.getSpawn() != null && Rnd.nextInt(RANDOM_WALK_RATE) == 0)
{
int x1, y1, z1;
// If NPC with random coord in territory
if (npc.getSpawn().getLocx() == 0 && npc.getSpawn().getLocy() == 0)
{
// If NPC with random fixed coord, don't move
if (Territory.getInstance().getProcMax(npc.getSpawn().getLocation()) > 0) return;
// Calculate a destination point in the spawn area
int p[] = Territory.getInstance().getRandomPoint(npc.getSpawn().getLocation());
x1 = p[0];
y1 = p[1];
z1 = p[2];
// Calculate the distance between the current position of the L2Character and the target (x,y)
double distance2 = _actor.getPlanDistanceSq(x1, y1);
if (distance2 > Config.MAX_DRIFT_RANGE * Config.MAX_DRIFT_RANGE)
{
npc.setisReturningToSpawnPoint(true);
float delay = (float) Math.sqrt(distance2) / Config.MAX_DRIFT_RANGE;
x1 = _actor.getX() + (int) ((x1 - _actor.getX()) / delay);
y1 = _actor.getY() + (int) ((y1 - _actor.getY()) / delay);
}
else
npc.setisReturningToSpawnPoint(false);
}
else
{
// If NPC with fixed coord
x1 = npc.getSpawn().getLocx() + Rnd.nextInt(Config.MAX_DRIFT_RANGE * 2)
- Config.MAX_DRIFT_RANGE;
y1 = npc.getSpawn().getLocy() + Rnd.nextInt(Config.MAX_DRIFT_RANGE * 2)
- Config.MAX_DRIFT_RANGE;
z1 = npc.getZ();
}
//_log.config("Curent pos ("+getX()+", "+getY()+"), moving to ("+x1+", "+y1+").");
// Move the actor to Location (x,y,z) server side AND client side by sending Server->Client packet CharMoveToLocation (broadcast)
moveTo(x1, y1, z1);