Code improvements.

This commit is contained in:
MobiusDev
2016-04-24 16:30:15 +00:00
parent 8bd51aba1c
commit 2dd14bef9b
860 changed files with 8865 additions and 17041 deletions

View File

@ -580,13 +580,9 @@ public abstract class AbstractAI implements Ctrl
}
sendPacket = false;
}
else if (_actor.isOnGeodataPath())
else if (_actor.isOnGeodataPath() && (GameTimeController.getInstance().getGameTicks() < (_moveToPawnTimeout + 10)))
{
// minimum time to calculate new route is 2 seconds
if (GameTimeController.getInstance().getGameTicks() < (_moveToPawnTimeout + 10))
{
return;
}
return;
}
}
@ -678,18 +674,20 @@ public abstract class AbstractAI implements Ctrl
_clientMovingToPawnOffset = 0;
if (_clientMoving || (loc != null))
if (!_clientMoving && (loc == null))
{
_clientMoving = false;
// Send a Server->Client packet StopMove to the actor and all L2PcInstance in its _knownPlayers
_actor.broadcastPacket(new StopMove(_actor));
if (loc != null)
{
// Send a Server->Client packet StopRotation to the actor and all L2PcInstance in its _knownPlayers
_actor.broadcastPacket(new StopRotation(_actor.getObjectId(), loc.getHeading(), 0));
}
return;
}
_clientMoving = false;
// Send a Server->Client packet StopMove to the actor and all L2PcInstance in its _knownPlayers
_actor.broadcastPacket(new StopMove(_actor));
if (loc != null)
{
// Send a Server->Client packet StopRotation to the actor and all L2PcInstance in its _knownPlayers
_actor.broadcastPacket(new StopRotation(_actor.getObjectId(), loc.getHeading(), 0));
}
}
@ -814,20 +812,17 @@ public abstract class AbstractAI implements Ctrl
*/
public void describeStateToPlayer(L2PcInstance player)
{
if (getActor().isVisibleFor(player))
if (getActor().isVisibleFor(player) && _clientMoving)
{
if (_clientMoving)
if ((_clientMovingToPawnOffset != 0) && (_followTarget != null))
{
if ((_clientMovingToPawnOffset != 0) && (_followTarget != null))
{
// Send a Server->Client packet MoveToPawn to the actor and all L2PcInstance in its _knownPlayers
player.sendPacket(new MoveToPawn(_actor, _followTarget, _clientMovingToPawnOffset));
}
else
{
// Send a Server->Client packet CharMoveToLocation to the actor and all L2PcInstance in its _knownPlayers
player.sendPacket(new MoveToLocation(_actor));
}
// Send a Server->Client packet MoveToPawn to the actor and all L2PcInstance in its _knownPlayers
player.sendPacket(new MoveToPawn(_actor, _followTarget, _clientMovingToPawnOffset));
}
else
{
// Send a Server->Client packet CharMoveToLocation to the actor and all L2PcInstance in its _knownPlayers
player.sendPacket(new MoveToLocation(_actor));
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -36,17 +36,19 @@ public class L2BoatAI extends L2VehicleAI
@Override
protected void moveTo(int x, int y, int z)
{
if (!_actor.isMovementDisabled())
if (_actor.isMovementDisabled())
{
if (!_clientMoving)
{
_actor.broadcastPacket(new VehicleStarted(getActor(), 1));
}
_clientMoving = true;
_actor.moveToLocation(x, y, z, 0);
_actor.broadcastPacket(new VehicleDeparture(getActor()));
return;
}
if (!_clientMoving)
{
_actor.broadcastPacket(new VehicleStarted(getActor(), 1));
}
_clientMoving = true;
_actor.moveToLocation(x, y, z, 0);
_actor.broadcastPacket(new VehicleDeparture(getActor()));
}
@Override

View File

@ -186,31 +186,32 @@ public class L2CharacterAI extends AbstractAI
protected void onIntentionActive()
{
// Check if the Intention is not already Active
if (getIntention() != AI_INTENTION_ACTIVE)
if (getIntention() == AI_INTENTION_ACTIVE)
{
// Set the AI Intention to AI_INTENTION_ACTIVE
changeIntention(AI_INTENTION_ACTIVE, null, null);
// Init cast and attack target
setCastTarget(null);
setAttackTarget(null);
// Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)
clientStopMoving(null);
// Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)
clientStopAutoAttack();
// Also enable random animations for this L2Character if allowed
// This is only for mobs - town npcs are handled in their constructor
if (_actor instanceof L2Attackable)
{
((L2Npc) _actor).startRandomAnimationTimer();
}
// Launch the Think Event
onEvtThink();
return;
}
changeIntention(AI_INTENTION_ACTIVE, null, null);
// Init cast and attack target
setCastTarget(null);
setAttackTarget(null);
// Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)
clientStopMoving(null);
// Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)
clientStopAutoAttack();
// Also enable random animations for this L2Character if allowed
// This is only for mobs - town npcs are handled in their constructor
if (_actor instanceof L2Attackable)
{
((L2Npc) _actor).startRandomAnimationTimer();
}
// Launch the Think Event
onEvtThink();
}
/**
@ -245,20 +246,7 @@ public class L2CharacterAI extends AbstractAI
@Override
protected void onIntentionAttack(L2Character target)
{
if (target == null)
{
clientActionFailed();
return;
}
if (getIntention() == AI_INTENTION_REST)
{
// Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
clientActionFailed();
return;
}
if (_actor.isAllSkillsDisabled() || _actor.isCastingNow() || _actor.isAfraid())
if ((target == null) || (getIntention() == AI_INTENTION_REST) || _actor.isAllSkillsDisabled() || _actor.isCastingNow() || _actor.isAfraid())
{
// Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
clientActionFailed();
@ -356,14 +344,7 @@ public class L2CharacterAI extends AbstractAI
@Override
protected void onIntentionMoveTo(Location loc)
{
if (getIntention() == AI_INTENTION_REST)
{
// Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
clientActionFailed();
return;
}
if (_actor.isAllSkillsDisabled() || _actor.isCastingNow())
if ((getIntention() == AI_INTENTION_REST) || _actor.isAllSkillsDisabled() || _actor.isCastingNow())
{
// Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
clientActionFailed();
@ -395,36 +376,7 @@ public class L2CharacterAI extends AbstractAI
@Override
protected void onIntentionFollow(L2Character target)
{
if (getIntention() == AI_INTENTION_REST)
{
// Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
clientActionFailed();
return;
}
if (_actor.isAllSkillsDisabled() || _actor.isCastingNow())
{
// Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
clientActionFailed();
return;
}
if (_actor.isMovementDisabled())
{
// Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
clientActionFailed();
return;
}
// Dead actors can`t follow
if (_actor.isDead())
{
clientActionFailed();
return;
}
// do not follow yourself
if (_actor == target)
if ((getIntention() == AI_INTENTION_REST) || _actor.isAllSkillsDisabled() || _actor.isCastingNow() || _actor.isMovementDisabled() || _actor.isDead() || (_actor == target))
{
clientActionFailed();
return;
@ -452,14 +404,7 @@ public class L2CharacterAI extends AbstractAI
@Override
protected void onIntentionPickUp(L2Object object)
{
if (getIntention() == AI_INTENTION_REST)
{
// Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
clientActionFailed();
return;
}
if (_actor.isAllSkillsDisabled() || _actor.isCastingNow())
if ((getIntention() == AI_INTENTION_REST) || _actor.isAllSkillsDisabled() || _actor.isCastingNow())
{
// Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
clientActionFailed();
@ -479,7 +424,7 @@ public class L2CharacterAI extends AbstractAI
// Set the AI pick up target
setTarget(object);
if ((object.getX() == 0) && (object.getY() == 0)) // TODO: Find the drop&spawn bug
if ((object.getX() == 0) && (object.getY() == 0))
{
_log.warning("Object in coords 0,0 - using a temporary fix");
object.setXYZ(getActor().getX(), getActor().getY(), getActor().getZ() + 5);
@ -502,14 +447,7 @@ public class L2CharacterAI extends AbstractAI
@Override
protected void onIntentionInteract(L2Object object)
{
if (getIntention() == AI_INTENTION_REST)
{
// Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
clientActionFailed();
return;
}
if (_actor.isAllSkillsDisabled() || _actor.isCastingNow())
if ((getIntention() == AI_INTENTION_REST) || _actor.isAllSkillsDisabled() || _actor.isCastingNow())
{
// Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
clientActionFailed();
@ -519,17 +457,19 @@ public class L2CharacterAI extends AbstractAI
// Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)
clientStopAutoAttack();
if (getIntention() != AI_INTENTION_INTERACT)
if (getIntention() == AI_INTENTION_INTERACT)
{
// Set the Intention of this AbstractAI to AI_INTENTION_INTERACT
changeIntention(AI_INTENTION_INTERACT, object, null);
// Set the AI interact target
setTarget(object);
// Move the actor to Pawn server side AND client side by sending Server->Client packet MoveToPawn (broadcast)
moveToPawn(object, 60);
return;
}
// Set the Intention of this AbstractAI to AI_INTENTION_INTERACT
changeIntention(AI_INTENTION_INTERACT, object, null);
// Set the AI interact target
setTarget(object);
// Move the actor to Pawn server side AND client side by sending Server->Client packet MoveToPawn (broadcast)
moveToPawn(object, 60);
}
/**
@ -856,22 +796,24 @@ public class L2CharacterAI extends AbstractAI
}
// Check if the targeted object was the actor
if (_actor == object)
if (_actor != object)
{
// Cancel AI target
setTarget(null);
setAttackTarget(null);
setCastTarget(null);
// Stop an AI Follow Task
stopFollow();
// Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)
clientStopMoving(null);
// Set the Intention of this AbstractAI to AI_INTENTION_IDLE
changeIntention(AI_INTENTION_IDLE, null, null);
return;
}
// Cancel AI target
setTarget(null);
setAttackTarget(null);
setCastTarget(null);
// Stop an AI Follow Task
stopFollow();
// Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)
clientStopMoving(null);
// Set the Intention of this AbstractAI to AI_INTENTION_IDLE
changeIntention(AI_INTENTION_IDLE, null, null);
}
/**
@ -969,16 +911,7 @@ public class L2CharacterAI extends AbstractAI
}
// If pathfinding enabled the creature will go to the destination or it will go to the nearest obstacle.
final Location destination;
if (Config.PATHFINDING > 0)
{
destination = GeoData.getInstance().moveCheck(_actor.getX(), _actor.getY(), _actor.getZ(), posX, posY, posZ, _actor.getInstanceId());
}
else
{
destination = new Location(posX, posY, posZ);
}
setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, destination);
setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, (Config.PATHFINDING > 0 ? GeoData.getInstance().moveCheck(_actor.getX(), _actor.getY(), _actor.getZ(), posX, posY, posZ, _actor.getInstanceId()) : new Location(posX, posY, posZ)));
}
protected boolean maybeMoveToPosition(ILocational worldPosition, int offset)
@ -1122,14 +1055,11 @@ public class L2CharacterAI extends AbstractAI
}
// while flying there is no move to cast
if ((_actor.getAI().getIntention() == CtrlIntention.AI_INTENTION_CAST) && (_actor instanceof L2PcInstance) && _actor.isTransformed())
if ((_actor.getAI().getIntention() == CtrlIntention.AI_INTENTION_CAST) && (_actor instanceof L2PcInstance) && _actor.isTransformed() && !_actor.getTransformation().isCombat())
{
if (!_actor.getTransformation().isCombat())
{
_actor.sendPacket(SystemMessageId.THE_DISTANCE_IS_TOO_FAR_AND_SO_THE_CASTING_HAS_BEEN_STOPPED);
_actor.sendPacket(ActionFailed.STATIC_PACKET);
return true;
}
_actor.sendPacket(SystemMessageId.THE_DISTANCE_IS_TOO_FAR_AND_SO_THE_CASTING_HAS_BEEN_STOPPED);
_actor.sendPacket(ActionFailed.STATIC_PACKET);
return true;
}
// If not running, set the L2Character movement type to run and send Server->Client packet ChangeMoveType to all others L2PcInstance
@ -1220,29 +1150,17 @@ public class L2CharacterAI extends AbstractAI
*/
protected boolean checkTargetLost(L2Object target)
{
// check if player is fakedeath
if (target instanceof L2PcInstance)
if ((target instanceof L2PcInstance) && ((L2PcInstance) target).isFakeDeath())
{
final L2PcInstance target2 = (L2PcInstance) target; // convert object to chara
if (target2.isFakeDeath())
{
target2.stopFakeDeath(true);
return false;
}
((L2PcInstance) target).stopFakeDeath(true);
return false;
}
if (target == null)
if ((target != null) && ((_actor == null) || (_skill == null) || !_skill.isBad() || (_skill.getAffectRange() <= 0) || GeoData.getInstance().canSeeTarget(_actor, target)))
{
// Set the Intention of this AbstractAI to AI_INTENTION_ACTIVE
setIntention(AI_INTENTION_ACTIVE);
return true;
return false;
}
if ((_actor != null) && (_skill != null) && _skill.isBad() && (_skill.getAffectRange() > 0) && !GeoData.getInstance().canSeeTarget(_actor, target))
{
setIntention(AI_INTENTION_ACTIVE);
return true;
}
return false;
setIntention(AI_INTENTION_ACTIVE);
return true;
}
protected class SelfAnalysis
@ -1498,22 +1416,8 @@ public class L2CharacterAI extends AbstractAI
isFighter = true;
}
}
if (target.getRunSpeed() < (_actor.getRunSpeed() - 3))
{
isSlower = true;
}
else
{
isSlower = false;
}
if ((target.getMDef(null, null) * 1.2) > _actor.getMAtk(null, null))
{
isMagicResistant = true;
}
else
{
isMagicResistant = false;
}
isSlower = target.getRunSpeed() < (_actor.getRunSpeed() - 3);
isMagicResistant = (target.getMDef(null, null) * 1.2) > _actor.getMAtk(null, null);
if (target.getBuffCount() < 4)
{
isCanceled = true;
@ -1545,20 +1449,10 @@ public class L2CharacterAI extends AbstractAI
boolean cancast = true;
for (L2Character target : _actor.getKnownList().getKnownCharactersInRadius(sk.getAffectRange()))
{
if (!GeoData.getInstance().canSeeTarget(_actor, target))
if (!GeoData.getInstance().canSeeTarget(_actor, target) || ((target instanceof L2Attackable) && !((L2Npc) _actor).isChaos()))
{
continue;
}
if (target instanceof L2Attackable)
{
final L2Npc actors = ((L2Npc) _actor);
if (!actors.isChaos())
{
continue;
}
}
if (target.isAffectedBySkill(sk.getId()))
{
cancast = false;
@ -1574,20 +1468,10 @@ public class L2CharacterAI extends AbstractAI
boolean cancast = true;
for (L2Character target : getAttackTarget().getKnownList().getKnownCharactersInRadius(sk.getAffectRange()))
{
if (!GeoData.getInstance().canSeeTarget(_actor, target) || (target == null))
if (!GeoData.getInstance().canSeeTarget(_actor, target) || (target == null) || ((target instanceof L2Attackable) && !((L2Npc) _actor).isChaos()))
{
continue;
}
if (target instanceof L2Attackable)
{
final L2Npc actors = ((L2Npc) _actor);
if (!actors.isChaos())
{
continue;
}
}
if (!target.getEffectList().isEmpty())
{
cancast = true;
@ -1606,20 +1490,10 @@ public class L2CharacterAI extends AbstractAI
boolean cancast = false;
for (L2Character target : _actor.getKnownList().getKnownCharactersInRadius(sk.getAffectRange()))
{
if (!GeoData.getInstance().canSeeTarget(_actor, target))
if (!GeoData.getInstance().canSeeTarget(_actor, target) || ((target instanceof L2Attackable) && !((L2Npc) _actor).isChaos()))
{
continue;
}
if (target instanceof L2Attackable)
{
final L2Npc actors = ((L2Npc) _actor);
if (!actors.isChaos())
{
continue;
}
}
if (!target.getEffectList().isEmpty())
{
cancast = true;
@ -1635,20 +1509,10 @@ public class L2CharacterAI extends AbstractAI
boolean cancast = true;
for (L2Character target : getAttackTarget().getKnownList().getKnownCharactersInRadius(sk.getAffectRange()))
{
if (!GeoData.getInstance().canSeeTarget(_actor, target))
if (!GeoData.getInstance().canSeeTarget(_actor, target) || ((target instanceof L2Attackable) && !((L2Npc) _actor).isChaos()))
{
continue;
}
if (target instanceof L2Attackable)
{
final L2Npc actors = ((L2Npc) _actor);
if (!actors.isChaos())
{
continue;
}
}
if (target.isAffectedBySkill(sk.getId()))
{
cancast = false;
@ -1675,9 +1539,7 @@ public class L2CharacterAI extends AbstractAI
{
continue;
}
final L2Npc targets = ((L2Npc) target);
final L2Npc actors = ((L2Npc) _actor);
if (targets.isInMyClan(actors))
if (((L2Npc) target).isInMyClan(((L2Npc) _actor)))
{
count++;
if (target.isAffectedBySkill(sk.getId()))

View File

@ -19,7 +19,6 @@ package com.l2jmobius.gameserver.ai;
import static com.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ACTIVE;
import static com.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ATTACK;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
@ -67,16 +66,9 @@ public final class L2ControllableMobAI extends L2AttackableAI
protected void thinkFollow()
{
final L2Attackable me = (L2Attackable) _actor;
if (!Util.checkIfInRange(MobGroupTable.FOLLOW_RANGE, me, getForcedTarget(), true))
if (!Util.checkIfInRange(MobGroupTable.FOLLOW_RANGE, _actor, getForcedTarget(), true))
{
final int signX = (Rnd.nextInt(2) == 0) ? -1 : 1;
final int signY = (Rnd.nextInt(2) == 0) ? -1 : 1;
final int randX = Rnd.nextInt(MobGroupTable.FOLLOW_RANGE);
final int randY = Rnd.nextInt(MobGroupTable.FOLLOW_RANGE);
moveTo(getForcedTarget().getX() + (signX * randX), getForcedTarget().getY() + (signY * randY), getForcedTarget().getZ());
moveTo(getForcedTarget().getX() + (((Rnd.nextInt(2) == 0) ? -1 : 1) * Rnd.nextInt(MobGroupTable.FOLLOW_RANGE)), getForcedTarget().getY() + (((Rnd.nextInt(2) == 0) ? -1 : 1) * Rnd.nextInt(MobGroupTable.FOLLOW_RANGE)), getForcedTarget().getZ());
}
}
@ -159,29 +151,29 @@ public final class L2ControllableMobAI extends L2AttackableAI
npc.setTarget(getAttackTarget());
if (!_actor.isMuted())
if (_actor.isMuted())
{
int max_range = 0;
// check distant skills
for (Skill sk : _actor.getAllSkills())
{
if (Util.checkIfInRange(sk.getCastRange(), _actor, getAttackTarget(), true) && !_actor.isSkillDisabled(sk) && (_actor.getCurrentMp() > _actor.getStat().getMpConsume(sk)))
{
_actor.doCast(sk);
return;
}
max_range = Math.max(max_range, sk.getCastRange());
}
if (!isNotMoving())
{
moveToPawn(getAttackTarget(), max_range);
}
return;
}
int max_range = 0;
// check distant skills
for (Skill sk : _actor.getAllSkills())
{
if (Util.checkIfInRange(sk.getCastRange(), _actor, getAttackTarget(), true) && !_actor.isSkillDisabled(sk) && (_actor.getCurrentMp() > _actor.getStat().getMpConsume(sk)))
{
_actor.doCast(sk);
return;
}
max_range = Math.max(max_range, sk.getCastRange());
}
if (!isNotMoving())
{
moveToPawn(getAttackTarget(), max_range);
}
}
protected void thinkAttackGroup()
@ -284,10 +276,8 @@ public final class L2ControllableMobAI extends L2AttackableAI
if (getAttackTarget() != null)
{
// stop hating
final L2Attackable npc = (L2Attackable) _actor;
npc.stopHating(getAttackTarget());
((L2Attackable) _actor).stopHating(getAttackTarget());
}
setIntention(AI_INTENTION_ACTIVE);
}
else
@ -295,21 +285,17 @@ public final class L2ControllableMobAI extends L2AttackableAI
// notify aggression
if (((L2Npc) _actor).getTemplate().getClans() != null)
{
final Collection<L2Object> objs = _actor.getKnownList().getKnownObjects().values();
for (L2Object obj : objs)
for (L2Object obj : _actor.getKnownList().getKnownObjects().values())
{
if (!(obj instanceof L2Npc))
{
continue;
}
final L2Npc npc = (L2Npc) obj;
if (!npc.isInMyClan((L2Npc) _actor))
{
continue;
}
if (_actor.isInsideRadius(npc, npc.getTemplate().getClanHelpRange(), false, true) && (Math.abs(getAttackTarget().getZ() - npc.getZ()) < 200))
{
npc.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, getAttackTarget(), 1);
@ -343,16 +329,7 @@ public final class L2ControllableMobAI extends L2AttackableAI
}
// Force mobs to attack anybody if confused.
L2Character hated;
if (_actor.isConfused())
{
hated = findNextRndTarget();
}
else
{
hated = getAttackTarget();
}
final L2Character hated = _actor.isConfused() ? findNextRndTarget() : getAttackTarget();
if (hated == null)
{
@ -387,22 +364,15 @@ public final class L2ControllableMobAI extends L2AttackableAI
protected void thinkActive()
{
setAttackTarget(findNextRndTarget());
L2Character hated;
if (_actor.isConfused())
final L2Character hated = _actor.isConfused() ? findNextRndTarget() : getAttackTarget();
if (hated == null)
{
hated = findNextRndTarget();
}
else
{
hated = getAttackTarget();
return;
}
if (hated != null)
{
_actor.setRunning();
setIntention(CtrlIntention.AI_INTENTION_ATTACK, hated);
}
_actor.setRunning();
setIntention(CtrlIntention.AI_INTENTION_ATTACK, hated);
}
private boolean checkAutoAttackCondition(L2Character target)
@ -436,14 +406,10 @@ public final class L2ControllableMobAI extends L2AttackableAI
return false;
}
// Check if the target is a L2Playable
if (target.isPlayable())
// Check if the target isn't in silent move mode
if (target.isPlayable() && ((L2Playable) target).isSilentMovingAffected())
{
// Check if the target isn't in silent move mode
if (((L2Playable) target).isSilentMovingAffected())
{
return false;
}
return false;
}
return me.isAggressive();
}
@ -451,11 +417,7 @@ public final class L2ControllableMobAI extends L2AttackableAI
private L2Character findNextRndTarget()
{
final List<L2Character> potentialTarget = _actor.getKnownList().getKnownCharactersInRadius(getActiveChar().getAggroRange()).stream().filter(this::checkAutoAttackCondition).collect(Collectors.toList());
if (potentialTarget.isEmpty())
{
return null;
}
return potentialTarget.get(Rnd.nextInt(potentialTarget.size()));
return potentialTarget.isEmpty() ? null : potentialTarget.get(Rnd.nextInt(potentialTarget.size()));
}
private L2ControllableMobInstance findNextGroupTarget()

View File

@ -173,5 +173,4 @@ public class L2DoorAI extends L2CharacterAI
}
}
}
}

View File

@ -140,19 +140,9 @@ public class L2FortSiegeGuardAI extends L2CharacterAI implements Runnable
return false;
}
}
// Check if the target isn't invulnerable
if ((target != null) && target.isInvul())
if ((target != null) && target.isInvul() && ((target.isPlayer() && target.isGM()) || (target.isSummon() && ((L2Summon) target).getOwner().isGM())))
{
// However EffectInvincible requires to check GMs specially
if (target.isPlayer() && target.isGM())
{
return false;
}
if (target.isSummon() && ((L2Summon) target).getOwner().isGM())
{
return false;
}
return false;
}
// Get the owner if the target is a summon
@ -164,18 +154,7 @@ public class L2FortSiegeGuardAI extends L2CharacterAI implements Runnable
target = owner;
}
}
// Check if the target is a L2PcInstance
if (target instanceof L2Playable)
{
// Check if the target isn't in silent move mode AND too far (>100)
if (((L2Playable) target).isSilentMovingAffected() && !_actor.isInsideRadius(target, 250, false, false))
{
return false;
}
}
// Los Check Here
return (_actor.isAutoAttackable(target) && GeoData.getInstance().canSeeTarget(_actor, target));
return (!(target instanceof L2Playable) || !((L2Playable) target).isSilentMovingAffected() || _actor.isInsideRadius(target, 250, false, false)) && _actor.isAutoAttackable(target) && GeoData.getInstance().canSeeTarget(_actor, target);
}
/**
@ -198,17 +177,7 @@ public class L2FortSiegeGuardAI extends L2CharacterAI implements Runnable
// Check if actor is not dead
if (!_actor.isAlikeDead())
{
final L2Attackable npc = (L2Attackable) _actor;
// If its _knownPlayer isn't empty set the Intention to AI_INTENTION_ACTIVE
if (!npc.getKnownList().getKnownPlayers().isEmpty())
{
intention = AI_INTENTION_ACTIVE;
}
else
{
intention = AI_INTENTION_IDLE;
}
intention = ((L2Attackable) _actor).getKnownList().getKnownPlayers().isEmpty() ? AI_INTENTION_IDLE : AI_INTENTION_ACTIVE;
}
if (intention == AI_INTENTION_IDLE)
@ -291,30 +260,14 @@ public class L2FortSiegeGuardAI extends L2CharacterAI implements Runnable
{
continue;
}
if (autoAttackCondition(target)) // check aggression
if (autoAttackCondition(target) && (npc.getHating(target) == 0)) // check aggression
{
// Get the hate level of the L2Attackable against this L2Character target contained in _aggroList
final 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);
}
npc.addDamageHate(target, 0, 1);
}
}
// Chose a target from its aggroList
L2Character hated;
if (_actor.isConfused())
{
hated = getAttackTarget(); // Force mobs to attack anybody if confused
}
else
{
hated = npc.getMostHated();
// _mostHatedAnalysis.Update(hated);
}
final L2Character hated = _actor.isConfused() ? getAttackTarget() : npc.getMostHated();
// Order to the L2Attackable to attack the target
if (hated != null)
@ -340,14 +293,7 @@ public class L2FortSiegeGuardAI extends L2CharacterAI implements Runnable
// Order to the L2SiegeGuardInstance to return to its home location because there's no target to attack
if (_actor.getWalkSpeed() >= 0)
{
if (_actor instanceof L2DefenderInstance)
{
((L2DefenderInstance) _actor).returnHome();
}
else
{
((L2FortCommanderInstance) _actor).returnHome();
}
(_actor instanceof L2DefenderInstance ? (L2DefenderInstance) _actor : (L2FortCommanderInstance) _actor).returnHome();
}
}
@ -369,17 +315,10 @@ public class L2FortSiegeGuardAI extends L2CharacterAI implements Runnable
_log.warning(getClass().getSimpleName() + ": thinkAttack(); timeout=" + (_attackTimeout - GameTimeController.getInstance().getGameTicks()));
}
if (_attackTimeout < GameTimeController.getInstance().getGameTicks())
if ((_attackTimeout < GameTimeController.getInstance().getGameTicks()) && _actor.isRunning())
{
// Check if the actor is running
if (_actor.isRunning())
{
// Set the actor movement type to walk and send Server->Client packet ChangeMoveType to all others L2PcInstance
_actor.setWalking();
// Calculate a new attack timeout
_attackTimeout = MAX_ATTACK_TIMEOUT + GameTimeController.getInstance().getGameTicks();
}
_actor.setWalking();
_attackTimeout = MAX_ATTACK_TIMEOUT + GameTimeController.getInstance().getGameTicks();
}
final L2Character attackTarget = getAttackTarget();
@ -389,8 +328,7 @@ public class L2FortSiegeGuardAI extends L2CharacterAI implements Runnable
// Stop hating this target after the attack timeout or if target is dead
if (attackTarget != null)
{
final L2Attackable npc = (L2Attackable) _actor;
npc.stopHating(attackTarget);
((L2Attackable) _actor).stopHating(attackTarget);
}
// Cancel target and timeout
@ -412,16 +350,11 @@ public class L2FortSiegeGuardAI extends L2CharacterAI implements Runnable
{
final L2Character target = getAttackTarget();
// Call all L2Object of its Faction inside the Faction Range
if ((((L2Npc) _actor).getTemplate().getClans() == null) || (target == null))
if ((((L2Npc) _actor).getTemplate().getClans() == null) || (target == null) || target.isInvul())
{
return;
}
if (target.isInvul())
{
return; // speeding it up for siege guards
}
// Go through all L2Character that belong to its faction
// for (L2Character cha : _actor.getKnownList().getKnownCharactersInRadius(((L2NpcInstance) _actor).getFactionRange()+_actor.getTemplate().collisionRadius))
for (L2Character cha : _actor.getKnownList().getKnownCharactersInRadius(1000))
@ -430,46 +363,32 @@ public class L2FortSiegeGuardAI extends L2CharacterAI implements Runnable
{
continue;
}
if (!(cha instanceof L2Npc))
{
if (_selfAnalysis.hasHealOrResurrect && (cha instanceof L2PcInstance) && ((L2Npc) _actor).getFort().getSiege().checkIsDefender(((L2PcInstance) cha).getClan()))
if (_selfAnalysis.hasHealOrResurrect && (cha instanceof L2PcInstance) && ((L2Npc) _actor).getFort().getSiege().checkIsDefender(((L2PcInstance) cha).getClan())//
&& !_actor.isAttackingDisabled() && (cha.getCurrentHp() < (cha.getMaxHp() * 0.6)) && (_actor.getCurrentHp() > (_actor.getMaxHp() / 2)) && (_actor.getCurrentMp() > (_actor.getMaxMp() / 2)) && cha.isInCombat())
{
// heal friends
if (!_actor.isAttackingDisabled() && (cha.getCurrentHp() < (cha.getMaxHp() * 0.6)) && (_actor.getCurrentHp() > (_actor.getMaxHp() / 2)) && (_actor.getCurrentMp() > (_actor.getMaxMp() / 2)) && cha.isInCombat())
for (Skill sk : _selfAnalysis.healSkills)
{
for (Skill sk : _selfAnalysis.healSkills)
if ((_actor.getCurrentMp() < sk.getMpConsume()) || _actor.isSkillDisabled(sk) || !Util.checkIfInRange(sk.getCastRange(), _actor, cha, true))
{
if (_actor.getCurrentMp() < sk.getMpConsume())
{
continue;
}
if (_actor.isSkillDisabled(sk))
{
continue;
}
if (!Util.checkIfInRange(sk.getCastRange(), _actor, cha, true))
{
continue;
}
final int chance = 5;
if (chance >= Rnd.get(100))
{
continue;
}
if (!GeoData.getInstance().canSeeTarget(_actor, cha))
{
break;
}
final L2Object OldTarget = _actor.getTarget();
_actor.setTarget(cha);
clientStopMoving(null);
_actor.doCast(sk);
_actor.setTarget(OldTarget);
return;
continue;
}
final int chance = 5;
if (chance >= Rnd.get(100))
{
continue;
}
if (!GeoData.getInstance().canSeeTarget(_actor, cha))
{
break;
}
final L2Object OldTarget = _actor.getTarget();
_actor.setTarget(cha);
clientStopMoving(null);
_actor.doCast(sk);
_actor.setTarget(OldTarget);
return;
}
}
continue;
@ -484,11 +403,7 @@ public class L2FortSiegeGuardAI extends L2CharacterAI implements Runnable
if (npc.getAI() != null) // TODO: possibly check not needed
{
if (!npc.isDead() && (Math.abs(target.getZ() - npc.getZ()) < 600)
// && _actor.getAttackByList().contains(getAttackTarget())
&& ((npc.getAI()._intention == CtrlIntention.AI_INTENTION_IDLE) || (npc.getAI()._intention == CtrlIntention.AI_INTENTION_ACTIVE))
// limiting aggro for siege guards
&& target.isInsideRadius(npc, 1500, true, false) && GeoData.getInstance().canSeeTarget(npc, target))
if (!npc.isDead() && (Math.abs(target.getZ() - npc.getZ()) < 600) && ((npc.getAI()._intention == CtrlIntention.AI_INTENTION_IDLE) || (npc.getAI()._intention == CtrlIntention.AI_INTENTION_ACTIVE)) && target.isInsideRadius(npc, 1500, true, false) && GeoData.getInstance().canSeeTarget(npc, target))
{
// Notify the L2Object AI with EVT_AGGRESSION
npc.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, getAttackTarget(), 1);
@ -499,19 +414,10 @@ public class L2FortSiegeGuardAI extends L2CharacterAI implements Runnable
{
for (Skill sk : _selfAnalysis.healSkills)
{
if (_actor.getCurrentMp() < sk.getMpConsume())
if ((_actor.getCurrentMp() < sk.getMpConsume()) || _actor.isSkillDisabled(sk) || !Util.checkIfInRange(sk.getCastRange(), _actor, npc, true))
{
continue;
}
if (_actor.isSkillDisabled(sk))
{
continue;
}
if (!Util.checkIfInRange(sk.getCastRange(), _actor, npc, true))
{
continue;
}
final int chance = 4;
if (chance >= Rnd.get(100))
{
@ -521,7 +427,6 @@ public class L2FortSiegeGuardAI extends L2CharacterAI implements Runnable
{
break;
}
final L2Object OldTarget = _actor.getTarget();
_actor.setTarget(npc);
clientStopMoving(null);
@ -540,17 +445,8 @@ public class L2FortSiegeGuardAI extends L2CharacterAI implements Runnable
Collection<Skill> skills = null;
double dist_2 = 0;
int range = 0;
L2DefenderInstance sGuard;
if (_actor instanceof L2FortCommanderInstance)
{
sGuard = (L2FortCommanderInstance) _actor;
}
else
{
sGuard = (L2DefenderInstance) _actor;
}
final L2DefenderInstance sGuard = _actor instanceof L2FortCommanderInstance ? (L2FortCommanderInstance) _actor : (L2DefenderInstance) _actor;
L2Character attackTarget = getAttackTarget();
try
{
_actor.setTarget(attackTarget);
@ -564,7 +460,6 @@ public class L2FortSiegeGuardAI extends L2CharacterAI implements Runnable
}
catch (NullPointerException e)
{
// _log.warning("AttackableAI: Attack target is NULL.");
_actor.setTarget(null);
setIntention(AI_INTENTION_IDLE, null, null);
return;
@ -580,16 +475,6 @@ public class L2FortSiegeGuardAI extends L2CharacterAI implements Runnable
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)))
{
@ -645,8 +530,7 @@ public class L2FortSiegeGuardAI extends L2CharacterAI implements Runnable
final double homeY = attackTarget.getY() - sGuard.getSpawn().getY();
// 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)))
if ((((dx * dx) + (dy * dy)) > 10000) && (((homeX * homeX) + (homeY * homeY)) > 3240000) && (_actor.getKnownList().knowsObject(attackTarget)))
{
// Cancel the target
_actor.getKnownList().removeKnownObject(attackTarget);
@ -658,7 +542,7 @@ public class L2FortSiegeGuardAI extends L2CharacterAI implements Runnable
{
// Temporary hack for preventing guards jumping off towers,
// before replacing this with effective geodata checks and AI modification
if ((dz * dz) < (170 * 170)) // normally 130 if guard z coordinates correct
if ((dz * dz) < (170 * 170))
{
if (_selfAnalysis.isMage)
{
@ -668,112 +552,87 @@ public class L2FortSiegeGuardAI extends L2CharacterAI implements Runnable
{
return;
}
if (attackTarget.isMoving())
{
moveToPawn(attackTarget, range - 70);
}
else
{
moveToPawn(attackTarget, range);
}
moveToPawn(attackTarget, attackTarget.isMoving() ? range - 70 : range);
}
}
}
return;
}
// Else, if the actor is muted and far from target, just "move to pawn"
else if (_actor.isMuted() && (dist_2 > (range * range)))
else
{
// Temporary hack for preventing guards jumping off towers,
// before replacing this with effective geodata checks and AI modification
final double dz = _actor.getZ() - attackTarget.getZ();
if ((dz * dz) < (170 * 170)) // normally 130 if guard z coordinates correct
if (_actor.isMuted() && (dist_2 > (range * range)))
{
if (_selfAnalysis.isMage)
// Temporary hack for preventing guards jumping off towers,
// before replacing this with effective geodata checks and AI modification
final double dz = _actor.getZ() - attackTarget.getZ();
if ((dz * dz) < (170 * 170)) // normally 130 if guard z coordinates correct
{
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
{
hated = ((L2Attackable) _actor).getMostHated();
}
if (hated == null)
{
setIntention(AI_INTENTION_ACTIVE, null, null);
return;
}
if (hated != attackTarget)
{
attackTarget = hated;
}
_attackTimeout = MAX_ATTACK_TIMEOUT + GameTimeController.getInstance().getGameTicks();
// check for close combat skills && heal/buff skills
if (!_actor.isMuted() && (Rnd.nextInt(100) <= 5))
{
for (Skill sk : skills)
{
final int castRange = sk.getCastRange();
if (((castRange * castRange) >= dist_2) && !sk.isPassive() && (_actor.getCurrentMp() >= _actor.getStat().getMpConsume(sk)) && !_actor.isSkillDisabled(sk))
if (_selfAnalysis.isMage)
{
range = _selfAnalysis.maxCastRange - 50;
}
if (_actor.getWalkSpeed() <= 0)
{
final L2Object OldTarget = _actor.getTarget();
if ((sk.isContinuous() && !sk.isDebuff()) || (sk.hasEffectType(L2EffectType.HEAL)))
{
boolean useSkillSelf = true;
if ((sk.hasEffectType(L2EffectType.HEAL)) && (_actor.getCurrentHp() > (int) (_actor.getMaxHp() / 1.5)))
{
useSkillSelf = false;
break;
}
if ((sk.isContinuous() && !sk.isDebuff()) && _actor.isAffectedBySkill(sk.getId()))
{
useSkillSelf = false;
}
if (useSkillSelf)
{
_actor.setTarget(_actor);
}
}
clientStopMoving(null);
_actor.doCast(sk);
_actor.setTarget(OldTarget);
return;
}
moveToPawn(attackTarget, attackTarget.isMoving() ? range - 70 : range);
}
return;
}
if (dist_2 <= (range * range))
{
final L2Character hated = _actor.isConfused() ? attackTarget : ((L2Attackable) _actor).getMostHated();
if (hated == null)
{
setIntention(AI_INTENTION_ACTIVE, null, null);
return;
}
if (hated != attackTarget)
{
attackTarget = hated;
}
_attackTimeout = MAX_ATTACK_TIMEOUT + GameTimeController.getInstance().getGameTicks();
// check for close combat skills && heal/buff skills
if (!_actor.isMuted() && (Rnd.nextInt(100) <= 5))
{
for (Skill sk : skills)
{
final int castRange = sk.getCastRange();
if (((castRange * castRange) >= dist_2) && !sk.isPassive() && (_actor.getCurrentMp() >= _actor.getStat().getMpConsume(sk)) && !_actor.isSkillDisabled(sk))
{
final L2Object OldTarget = _actor.getTarget();
if ((sk.isContinuous() && !sk.isDebuff()) || (sk.hasEffectType(L2EffectType.HEAL)))
{
boolean useSkillSelf = true;
if ((sk.hasEffectType(L2EffectType.HEAL)) && (_actor.getCurrentHp() > (int) (_actor.getMaxHp() / 1.5)))
{
useSkillSelf = false;
break;
}
if ((sk.isContinuous() && !sk.isDebuff()) && _actor.isAffectedBySkill(sk.getId()))
{
useSkillSelf = false;
}
if (useSkillSelf)
{
_actor.setTarget(_actor);
}
}
clientStopMoving(null);
_actor.doCast(sk);
_actor.setTarget(OldTarget);
return;
}
}
}
// Finally, do the physical attack itself
_actor.doAttack(attackTarget);
}
// Finally, do the physical attack itself
_actor.doAttack(attackTarget);
}
}
@ -900,15 +759,7 @@ public class L2FortSiegeGuardAI extends L2CharacterAI implements Runnable
_actor.setRunning();
}
L2DefenderInstance sGuard;
if (_actor instanceof L2FortCommanderInstance)
{
sGuard = (L2FortCommanderInstance) _actor;
}
else
{
sGuard = (L2DefenderInstance) _actor;
}
final L2DefenderInstance sGuard = _actor instanceof L2FortCommanderInstance ? (L2FortCommanderInstance) _actor : (L2DefenderInstance) _actor;
final double homeX = target.getX() - sGuard.getSpawn().getX();
final double homeY = target.getY() - sGuard.getSpawn().getY();

View File

@ -116,5 +116,4 @@ public abstract class L2PlayableAI extends L2CharacterAI
}
super.onIntentionCast(skill, target);
}
}

View File

@ -131,13 +131,11 @@ public class L2PlayerAI extends L2PlayableAI
if (getIntention() == AI_INTENTION_CAST)
{
// run interrupted or next intention
final IntentionCommand nextIntention = _nextIntention;
if (nextIntention != null)
if (_nextIntention != null)
{
if (nextIntention._crtlIntention != AI_INTENTION_CAST) // previous state shouldn't be casting
if (_nextIntention._crtlIntention != AI_INTENTION_CAST)
{
setIntention(nextIntention._crtlIntention, nextIntention._arg0, nextIntention._arg1);
setIntention(_nextIntention._crtlIntention, _nextIntention._arg0, _nextIntention._arg1);
}
else
{
@ -155,16 +153,17 @@ public class L2PlayerAI extends L2PlayableAI
@Override
protected void onIntentionRest()
{
if (getIntention() != AI_INTENTION_REST)
if (getIntention() == AI_INTENTION_REST)
{
changeIntention(AI_INTENTION_REST, null, null);
setTarget(null);
if (getAttackTarget() != null)
{
setAttackTarget(null);
}
clientStopMoving(null);
return;
}
changeIntention(AI_INTENTION_REST, null, null);
setTarget(null);
if (getAttackTarget() != null)
{
setAttackTarget(null);
}
clientStopMoving(null);
}
@Override
@ -293,11 +292,7 @@ public class L2PlayerAI extends L2PlayableAI
return;
}
final L2Object target = getTarget();
if (checkTargetLost(target))
{
return;
}
if (maybeMoveToPawn(target, 36))
if (checkTargetLost(target) || maybeMoveToPawn(target, 36))
{
return;
}
@ -312,11 +307,7 @@ public class L2PlayerAI extends L2PlayableAI
return;
}
final L2Object target = getTarget();
if (checkTargetLost(target))
{
return;
}
if (maybeMoveToPawn(target, 36))
if (checkTargetLost(target) || maybeMoveToPawn(target, 36))
{
return;
}

View File

@ -32,12 +32,13 @@ public class L2ShuttleAI extends L2VehicleAI
@Override
public void moveTo(int x, int y, int z)
{
if (!_actor.isMovementDisabled())
if (_actor.isMovementDisabled())
{
_clientMoving = true;
_actor.moveToLocation(x, y, z, 0);
_actor.broadcastPacket(new ExShuttleMove(getActor(), x, y, z));
return;
}
_clientMoving = true;
_actor.moveToLocation(x, y, z, 0);
_actor.broadcastPacket(new ExShuttleMove(getActor(), x, y, z));
}
@Override

View File

@ -130,17 +130,9 @@ public class L2SiegeGuardAI extends L2CharacterAI implements Runnable
}
// Check if the target isn't invulnerable
if (target.isInvul())
if (target.isInvul() && ((target.isPlayer() && target.isGM()) || (target.isSummon() && ((L2Summon) target).getOwner().isGM())))
{
// However EffectInvincible requires to check GMs specially
if (target.isPlayer() && target.isGM())
{
return false;
}
if (target.isSummon() && ((L2Summon) target).getOwner().isGM())
{
return false;
}
return false;
}
// Get the owner if the target is a summon
@ -153,15 +145,12 @@ public class L2SiegeGuardAI extends L2CharacterAI implements Runnable
}
}
// Check if the target is a L2PcInstance
if (target instanceof L2Playable)
// Check if the target isn't in silent move mode AND too far (>100)
if ((target instanceof L2Playable) && ((L2Playable) target).isSilentMovingAffected() && !_actor.isInsideRadius(target, 250, false, false))
{
// Check if the target isn't in silent move mode AND too far (>100)
if (((L2Playable) target).isSilentMovingAffected() && !_actor.isInsideRadius(target, 250, false, false))
{
return false;
}
return false;
}
// Los Check Here
return (_actor.isAutoAttackable(target) && GeoData.getInstance().canSeeTarget(_actor, target));
}
@ -186,17 +175,7 @@ public class L2SiegeGuardAI extends L2CharacterAI implements Runnable
// Check if actor is not dead
if (!_actor.isAlikeDead())
{
final L2Attackable npc = (L2Attackable) _actor;
// If its _knownPlayer isn't empty set the Intention to AI_INTENTION_ACTIVE
if (!npc.getKnownList().getKnownPlayers().isEmpty())
{
intention = AI_INTENTION_ACTIVE;
}
else
{
intention = AI_INTENTION_IDLE;
}
intention = ((L2Attackable) _actor).getKnownList().getKnownPlayers().isEmpty() ? AI_INTENTION_IDLE : AI_INTENTION_ACTIVE;
}
if (intention == AI_INTENTION_IDLE)
@ -279,30 +258,14 @@ public class L2SiegeGuardAI extends L2CharacterAI implements Runnable
{
continue;
}
if (autoAttackCondition(target)) // check aggression
if (autoAttackCondition(target) && (npc.getHating(target) == 0)) // check aggression
{
// Get the hate level of the L2Attackable against this L2Character target contained in _aggroList
final 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);
}
npc.addDamageHate(target, 0, 1);
}
}
// Chose a target from its aggroList
L2Character hated;
if (_actor.isConfused())
{
hated = getAttackTarget(); // Force mobs to attack anybody if confused
}
else
{
hated = npc.getMostHated();
// _mostHatedAnalysis.Update(hated);
}
final L2Character hated = _actor.isConfused() ? getAttackTarget() : npc.getMostHated();
// Order to the L2Attackable to attack the target
if (hated != null)
@ -347,17 +310,13 @@ public class L2SiegeGuardAI extends L2CharacterAI implements Runnable
_log.info(getClass().getSimpleName() + ": thinkAttack(); timeout=" + (_attackTimeout - GameTimeController.getInstance().getGameTicks()));
}
if (_attackTimeout < GameTimeController.getInstance().getGameTicks())
if ((_attackTimeout < GameTimeController.getInstance().getGameTicks()) && _actor.isRunning())
{
// Check if the actor is running
if (_actor.isRunning())
{
// Set the actor movement type to walk and send Server->Client packet ChangeMoveType to all others L2PcInstance
_actor.setWalking();
// Calculate a new attack timeout
_attackTimeout = MAX_ATTACK_TIMEOUT + GameTimeController.getInstance().getGameTicks();
}
// Set the actor movement type to walk and send Server->Client packet ChangeMoveType to all others L2PcInstance
_actor.setWalking();
// Calculate a new attack timeout
_attackTimeout = MAX_ATTACK_TIMEOUT + GameTimeController.getInstance().getGameTicks();
}
final L2Character attackTarget = getAttackTarget();
@ -367,8 +326,7 @@ public class L2SiegeGuardAI extends L2CharacterAI implements Runnable
// Stop hating this target after the attack timeout or if target is dead
if (attackTarget != null)
{
final L2Attackable npc = (L2Attackable) _actor;
npc.stopHating(attackTarget);
((L2Attackable) _actor).stopHating(attackTarget);
}
// Cancel target and timeout
@ -390,16 +348,11 @@ public class L2SiegeGuardAI extends L2CharacterAI implements Runnable
{
final L2Character target = getAttackTarget();
// Call all L2Object of its Faction inside the Faction Range
if ((((L2Npc) _actor).getTemplate().getClans() == null) || (target == null))
if ((((L2Npc) _actor).getTemplate().getClans() == null) || (target == null) || target.isInvul())
{
return;
}
if (target.isInvul())
{
return; // speeding it up for siege guards
}
// Go through all L2Character that belong to its faction
// for (L2Character cha : _actor.getKnownList().getKnownCharactersInRadius(((L2NpcInstance) _actor).getFactionRange()+_actor.getTemplate().collisionRadius))
for (L2Character cha : _actor.getKnownList().getKnownCharactersInRadius(1000))
@ -408,46 +361,32 @@ public class L2SiegeGuardAI extends L2CharacterAI implements Runnable
{
continue;
}
if (!(cha instanceof L2Npc))
{
if (_selfAnalysis.hasHealOrResurrect && (cha instanceof L2PcInstance) && (((L2Npc) _actor).getCastle().getSiege().checkIsDefender(((L2PcInstance) cha).getClan())))
if (_selfAnalysis.hasHealOrResurrect && (cha instanceof L2PcInstance) && (((L2Npc) _actor).getCastle().getSiege().checkIsDefender(((L2PcInstance) cha).getClan()))//
&& !_actor.isAttackingDisabled() && (cha.getCurrentHp() < (cha.getMaxHp() * 0.6)) && (_actor.getCurrentHp() > (_actor.getMaxHp() / 2)) && (_actor.getCurrentMp() > (_actor.getMaxMp() / 2)) && cha.isInCombat())
{
// heal friends
if (!_actor.isAttackingDisabled() && (cha.getCurrentHp() < (cha.getMaxHp() * 0.6)) && (_actor.getCurrentHp() > (_actor.getMaxHp() / 2)) && (_actor.getCurrentMp() > (_actor.getMaxMp() / 2)) && cha.isInCombat())
for (Skill sk : _selfAnalysis.healSkills)
{
for (Skill sk : _selfAnalysis.healSkills)
if ((_actor.getCurrentMp() < sk.getMpConsume()) || _actor.isSkillDisabled(sk) || !Util.checkIfInRange(sk.getCastRange(), _actor, cha, true))
{
if (_actor.getCurrentMp() < sk.getMpConsume())
{
continue;
}
if (_actor.isSkillDisabled(sk))
{
continue;
}
if (!Util.checkIfInRange(sk.getCastRange(), _actor, cha, true))
{
continue;
}
final int chance = 5;
if (chance >= Rnd.get(100))
{
continue;
}
if (!GeoData.getInstance().canSeeTarget(_actor, cha))
{
break;
}
final L2Object OldTarget = _actor.getTarget();
_actor.setTarget(cha);
clientStopMoving(null);
_actor.doCast(sk);
_actor.setTarget(OldTarget);
return;
continue;
}
final int chance = 5;
if (chance >= Rnd.get(100))
{
continue;
}
if (!GeoData.getInstance().canSeeTarget(_actor, cha))
{
break;
}
final L2Object OldTarget = _actor.getTarget();
_actor.setTarget(cha);
clientStopMoving(null);
_actor.doCast(sk);
_actor.setTarget(OldTarget);
return;
}
}
continue;
@ -462,11 +401,7 @@ public class L2SiegeGuardAI extends L2CharacterAI implements Runnable
if (npc.getAI() != null) // TODO: possibly check not needed
{
if (!npc.isDead() && (Math.abs(target.getZ() - npc.getZ()) < 600)
// && _actor.getAttackByList().contains(getAttackTarget())
&& ((npc.getAI()._intention == CtrlIntention.AI_INTENTION_IDLE) || (npc.getAI()._intention == CtrlIntention.AI_INTENTION_ACTIVE))
// limiting aggro for siege guards
&& target.isInsideRadius(npc, 1500, true, false) && GeoData.getInstance().canSeeTarget(npc, target))
if (!npc.isDead() && (Math.abs(target.getZ() - npc.getZ()) < 600) && ((npc.getAI()._intention == CtrlIntention.AI_INTENTION_IDLE) || (npc.getAI()._intention == CtrlIntention.AI_INTENTION_ACTIVE)) && target.isInsideRadius(npc, 1500, true, false) && GeoData.getInstance().canSeeTarget(npc, target))
{
// Notify the L2Object AI with EVT_AGGRESSION
npc.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, getAttackTarget(), 1);
@ -477,19 +412,10 @@ public class L2SiegeGuardAI extends L2CharacterAI implements Runnable
{
for (Skill sk : _selfAnalysis.healSkills)
{
if (_actor.getCurrentMp() < sk.getMpConsume())
if ((_actor.getCurrentMp() < sk.getMpConsume()) || _actor.isSkillDisabled(sk) || !Util.checkIfInRange(sk.getCastRange(), _actor, npc, true))
{
continue;
}
if (_actor.isSkillDisabled(sk))
{
continue;
}
if (!Util.checkIfInRange(sk.getCastRange(), _actor, npc, true))
{
continue;
}
final int chance = 4;
if (chance >= Rnd.get(100))
{
@ -499,7 +425,6 @@ public class L2SiegeGuardAI extends L2CharacterAI implements Runnable
{
break;
}
final L2Object OldTarget = _actor.getTarget();
_actor.setTarget(npc);
clientStopMoving(null);
@ -540,16 +465,13 @@ public class L2SiegeGuardAI extends L2CharacterAI implements Runnable
}
// never attack defenders
if (attackTarget instanceof L2PcInstance)
if ((attackTarget instanceof L2PcInstance) && (sGuard.getConquerableHall() == null) && sGuard.getCastle().getSiege().checkIsDefender(((L2PcInstance) attackTarget).getClan()))
{
if ((sGuard.getConquerableHall() == null) && sGuard.getCastle().getSiege().checkIsDefender(((L2PcInstance) attackTarget).getClan()))
{
// Cancel the target
sGuard.stopHating(attackTarget);
_actor.setTarget(null);
setIntention(AI_INTENTION_IDLE, null, null);
return;
}
// Cancel the target
sGuard.stopHating(attackTarget);
_actor.setTarget(null);
setIntention(AI_INTENTION_IDLE, null, null);
return;
}
if (!GeoData.getInstance().canSeeTarget(_actor, attackTarget))
@ -640,110 +562,85 @@ public class L2SiegeGuardAI extends L2CharacterAI implements Runnable
{
range = _selfAnalysis.maxCastRange - 50;
}
if (attackTarget.isMoving())
{
moveToPawn(attackTarget, range - 70);
}
else
{
moveToPawn(attackTarget, range);
}
moveToPawn(attackTarget, attackTarget.isMoving() ? range - 70 : range);
}
}
}
return;
}
// Else, if the actor is muted and far from target, just "move to pawn"
else if (_actor.isMuted() && (dist_2 > (range * range)) && !_selfAnalysis.isHealer)
else
{
// Temporary hack for preventing guards jumping off towers,
// before replacing this with effective geodata checks and AI modification
final double dz = _actor.getZ() - attackTarget.getZ();
if ((dz * dz) < (170 * 170)) // normally 130 if guard z coordinates correct
if (_actor.isMuted() && (dist_2 > (range * range)) && !_selfAnalysis.isHealer)
{
if (_selfAnalysis.isMage)
// Temporary hack for preventing guards jumping off towers,
// before replacing this with effective geodata checks and AI modification
final double dz = _actor.getZ() - attackTarget.getZ();
if ((dz * dz) < (170 * 170)) // normally 130 if guard z coordinates correct
{
range = _selfAnalysis.maxCastRange - 50;
if (_selfAnalysis.isMage)
{
range = _selfAnalysis.maxCastRange - 50;
}
moveToPawn(attackTarget, attackTarget.isMoving() ? range - 70 : range);
}
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
{
hated = ((L2Attackable) _actor).getMostHated();
}
if (hated == null)
{
setIntention(AI_INTENTION_ACTIVE, null, null);
return;
}
if (hated != attackTarget)
if (dist_2 <= (range * range))
{
attackTarget = hated;
}
_attackTimeout = MAX_ATTACK_TIMEOUT + GameTimeController.getInstance().getGameTicks();
// check for close combat skills && heal/buff skills
if (!_actor.isMuted() && (Rnd.nextInt(100) <= 5))
{
for (Skill sk : skills)
final L2Character hated = _actor.isConfused() ? attackTarget : ((L2Attackable) _actor).getMostHated();
if (hated == null)
{
final int castRange = sk.getCastRange();
if (((castRange * castRange) >= dist_2) && !sk.isPassive() && (_actor.getCurrentMp() >= _actor.getStat().getMpConsume(sk)) && !_actor.isSkillDisabled(sk))
setIntention(AI_INTENTION_ACTIVE, null, null);
return;
}
if (hated != attackTarget)
{
attackTarget = hated;
}
_attackTimeout = MAX_ATTACK_TIMEOUT + GameTimeController.getInstance().getGameTicks();
// check for close combat skills && heal/buff skills
if (!_actor.isMuted() && (Rnd.nextInt(100) <= 5))
{
for (Skill sk : skills)
{
final L2Object OldTarget = _actor.getTarget();
if ((sk.isContinuous() && !sk.isDebuff()) || (sk.hasEffectType(L2EffectType.HEAL)))
{
boolean useSkillSelf = true;
if ((sk.hasEffectType(L2EffectType.HEAL)) && (_actor.getCurrentHp() > (int) (_actor.getMaxHp() / 1.5)))
{
useSkillSelf = false;
break;
}
if ((sk.isContinuous() && !sk.isDebuff()) && _actor.isAffectedBySkill(sk.getId()))
{
useSkillSelf = false;
}
if (useSkillSelf)
{
_actor.setTarget(_actor);
}
}
final int castRange = sk.getCastRange();
clientStopMoving(null);
_actor.doCast(sk);
_actor.setTarget(OldTarget);
return;
if (((castRange * castRange) >= dist_2) && !sk.isPassive() && (_actor.getCurrentMp() >= _actor.getStat().getMpConsume(sk)) && !_actor.isSkillDisabled(sk))
{
final L2Object OldTarget = _actor.getTarget();
if ((sk.isContinuous() && !sk.isDebuff()) || (sk.hasEffectType(L2EffectType.HEAL)))
{
boolean useSkillSelf = true;
if ((sk.hasEffectType(L2EffectType.HEAL)) && (_actor.getCurrentHp() > (int) (_actor.getMaxHp() / 1.5)))
{
useSkillSelf = false;
break;
}
if ((sk.isContinuous() && !sk.isDebuff()) && _actor.isAffectedBySkill(sk.getId()))
{
useSkillSelf = false;
}
if (useSkillSelf)
{
_actor.setTarget(_actor);
}
}
clientStopMoving(null);
_actor.doCast(sk);
_actor.setTarget(OldTarget);
return;
}
}
}
}
// Finally, do the physical attack itself
if (!_selfAnalysis.isHealer)
{
_actor.doAttack(attackTarget);
// Finally, do the physical attack itself
if (!_selfAnalysis.isHealer)
{
_actor.doAttack(attackTarget);
}
}
}
}

View File

@ -70,10 +70,9 @@ public class L2SummonAI extends L2PlayableAI implements Runnable
@Override
protected void onIntentionActive()
{
final L2Summon summon = (L2Summon) _actor;
if (_startFollow)
{
setIntention(AI_INTENTION_FOLLOW, summon.getOwner());
setIntention(AI_INTENTION_FOLLOW, ((L2Summon) _actor).getOwner());
}
else
{
@ -138,11 +137,7 @@ public class L2SummonAI extends L2PlayableAI implements Runnable
private void thinkPickUp()
{
if (checkTargetLost(getTarget()))
{
return;
}
if (maybeMoveToPawn(getTarget(), 36))
if (checkTargetLost(getTarget()) || maybeMoveToPawn(getTarget(), 36))
{
return;
}
@ -152,11 +147,7 @@ public class L2SummonAI extends L2PlayableAI implements Runnable
private void thinkInteract()
{
if (checkTargetLost(getTarget()))
{
return;
}
if (maybeMoveToPawn(getTarget(), 36))
if (checkTargetLost(getTarget()) || maybeMoveToPawn(getTarget(), 36))
{
return;
}
@ -245,23 +236,23 @@ public class L2SummonAI extends L2PlayableAI implements Runnable
@Override
public void run()
{
if (_startAvoid)
if (!_startAvoid)
{
_startAvoid = false;
if (!_clientMoving && !_actor.isDead() && !_actor.isMovementDisabled())
{
final int ownerX = ((L2Summon) _actor).getOwner().getX();
final int ownerY = ((L2Summon) _actor).getOwner().getY();
final double angle = Math.toRadians(Rnd.get(-90, 90)) + Math.atan2(ownerY - _actor.getY(), ownerX - _actor.getX());
final int targetX = ownerX + (int) (AVOID_RADIUS * Math.cos(angle));
final int targetY = ownerY + (int) (AVOID_RADIUS * Math.sin(angle));
if (GeoData.getInstance().canMove(_actor.getX(), _actor.getY(), _actor.getZ(), targetX, targetY, _actor.getZ(), _actor.getInstanceId()))
{
moveTo(targetX, targetY, _actor.getZ());
}
}
return;
}
_startAvoid = false;
if (_clientMoving || _actor.isDead() || _actor.isMovementDisabled())
{
return;
}
final int ownerX = ((L2Summon) _actor).getOwner().getX();
final int ownerY = ((L2Summon) _actor).getOwner().getY();
final double angle = Math.toRadians(Rnd.get(-90, 90)) + Math.atan2(ownerY - _actor.getY(), ownerX - _actor.getX());
final int targetX = ownerX + (int) (AVOID_RADIUS * Math.cos(angle));
final int targetY = ownerY + (int) (AVOID_RADIUS * Math.sin(angle));
if (GeoData.getInstance().canMove(_actor.getX(), _actor.getY(), _actor.getZ(), targetX, targetY, _actor.getZ(), _actor.getInstanceId()))
{
moveTo(targetX, targetY, _actor.getZ());
}
}

View File

@ -111,11 +111,7 @@ public final class FighterAI implements Runnable
// Out of combat follow logic.
if (!_guard.isInCombat())
{
final int moveToLocX = _player.getLocation().getX() + Rnd.get((_followRange * -1), _followRange);
final int moveToLocY = _player.getLocation().getY() + Rnd.get((_followRange * -1), _followRange);
final int moveToLocZ = _player.getLocation().getZ();
final Location moveToLocation = new Location(moveToLocX, moveToLocY, moveToLocZ);
_guard.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, moveToLocation);
_guard.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, (new Location((_player.getLocation().getX() + Rnd.get((_followRange * -1), _followRange)), (_player.getLocation().getY() + Rnd.get((_followRange * -1), _followRange)), _player.getLocation().getZ())));
}
}
}

View File

@ -119,11 +119,7 @@ public final class HealerAI implements Runnable
// Out of combat follow logic.
if (!_guard.isInCombat())
{
final int moveToLocX = _player.getLocation().getX() + Rnd.get((_followRange * -1), _followRange);
final int moveToLocY = _player.getLocation().getY() + Rnd.get((_followRange * -1), _followRange);
final int moveToLocZ = _player.getLocation().getZ();
final Location moveToLocation = new Location(moveToLocX, moveToLocY, moveToLocZ);
_guard.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, moveToLocation);
_guard.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, (new Location((_player.getLocation().getX() + Rnd.get((_followRange * -1), _followRange)), (_player.getLocation().getY() + Rnd.get((_followRange * -1), _followRange)), _player.getLocation().getZ())));
}
}
}