Minor base AI class cleanup.
This commit is contained in:
parent
5f13d2db66
commit
0506c469a3
@ -66,10 +66,10 @@ public abstract class AbstractAI implements Ctrl
|
||||
private WorldObject _target;
|
||||
|
||||
/** The skill we are currently casting by INTENTION_CAST */
|
||||
Skill _skill;
|
||||
ItemInstance _item;
|
||||
boolean _forceUse;
|
||||
boolean _dontMove;
|
||||
protected Skill _skill;
|
||||
protected ItemInstance _item;
|
||||
protected boolean _forceUse;
|
||||
protected boolean _dontMove;
|
||||
|
||||
/** Different internal state flags */
|
||||
protected int _moveToPawnTimeout;
|
||||
@ -182,7 +182,7 @@ public abstract class AbstractAI implements Ctrl
|
||||
}
|
||||
case AI_INTENTION_CAST:
|
||||
{
|
||||
onIntentionCast((Skill) args[0], (WorldObject) args[1], args.length > 2 ? (ItemInstance) args[2] : null, args.length > 3 ? (boolean) args[3] : false, args.length > 4 ? (boolean) args[4] : false);
|
||||
onIntentionCast((Skill) args[0], (WorldObject) args[1], args.length > 2 ? (ItemInstance) args[2] : null, args.length > 3 && (boolean) args[3], args.length > 4 && (boolean) args[4]);
|
||||
break;
|
||||
}
|
||||
case AI_INTENTION_MOVE_TO:
|
||||
|
@ -114,8 +114,6 @@ public class AttackableAI extends CreatureAI
|
||||
return false;
|
||||
}
|
||||
|
||||
final Attackable me = getActiveChar();
|
||||
|
||||
// Check if the target isn't dead, is in the Aggro range and is at the same height
|
||||
if (target.isAlikeDead())
|
||||
{
|
||||
@ -123,6 +121,7 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
|
||||
// Check if the target is a Playable and if the AI isn't a Raid Boss, can See Silent Moving players and the target isn't in silent move mode
|
||||
final Attackable me = getActiveChar();
|
||||
if (target.isPlayable() && !(me.isRaid()) && !(me.canSeeThroughSilentMove()) && ((Playable) target).isSilentMovingAffected())
|
||||
{
|
||||
return false;
|
||||
@ -545,10 +544,6 @@ public class AttackableAI extends CreatureAI
|
||||
// Order to the MonsterInstance to random walk (1/100)
|
||||
else if ((npc.getSpawn() != null) && (Rnd.get(RANDOM_WALK_RATE) == 0) && npc.isRandomWalkingEnabled())
|
||||
{
|
||||
int x1 = 0;
|
||||
int y1 = 0;
|
||||
int z1 = 0;
|
||||
final int range = Config.MAX_DRIFT_RANGE;
|
||||
for (Skill sk : npc.getTemplate().getAISkills(AISkillScope.BUFF))
|
||||
{
|
||||
target = skillTargetReconsider(sk, true);
|
||||
@ -560,9 +555,10 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
}
|
||||
|
||||
x1 = npc.getSpawn().getX();
|
||||
y1 = npc.getSpawn().getY();
|
||||
z1 = npc.getSpawn().getZ();
|
||||
int x1 = npc.getSpawn().getX();
|
||||
int y1 = npc.getSpawn().getY();
|
||||
int z1 = npc.getSpawn().getZ();
|
||||
final int range = Config.MAX_DRIFT_RANGE;
|
||||
if (!npc.isInsideRadius2D(x1, y1, 0, range))
|
||||
{
|
||||
npc.setReturningToSpawnPoint(true);
|
||||
@ -761,7 +757,6 @@ public class AttackableAI extends CreatureAI
|
||||
return;
|
||||
}
|
||||
|
||||
final int combinedCollision = collision + target.getTemplate().getCollisionRadius();
|
||||
final List<Skill> aiSuicideSkills = npc.getTemplate().getAISkills(AISkillScope.SUICIDE);
|
||||
if (!aiSuicideSkills.isEmpty() && ((int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100) < 30) && npc.hasSkillChance())
|
||||
{
|
||||
@ -778,6 +773,7 @@ public class AttackableAI extends CreatureAI
|
||||
// In case many mobs are trying to hit from same place, move a bit, circling around the target
|
||||
// Note from Gnacik:
|
||||
// On l2js because of that sometimes mobs don't attack player only running around player without any sense, so decrease chance for now
|
||||
final int combinedCollision = collision + target.getTemplate().getCollisionRadius();
|
||||
if (!npc.isMovementDisabled() && (Rnd.get(100) <= 3))
|
||||
{
|
||||
for (Attackable nearby : World.getInstance().getVisibleObjects(npc, Attackable.class))
|
||||
@ -1231,7 +1227,6 @@ public class AttackableAI extends CreatureAI
|
||||
Creature creature = null;
|
||||
for (AggroInfo aggro : npc.getAggroList().values())
|
||||
{
|
||||
searchValue = aggro.getHate();
|
||||
if (checkTarget(aggro.getAttacker()) && (aggro.getHate() > searchValue))
|
||||
{
|
||||
searchValue = aggro.getHate();
|
||||
|
@ -381,12 +381,13 @@ public class ControllableMobAI extends AttackableAI
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final Attackable me = (Attackable) _actor;
|
||||
|
||||
if (target.isNpc() || target.isDoor())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final Attackable me = (Attackable) _actor;
|
||||
if (target.isAlikeDead() || !me.isInsideRadius2D(target, me.getAggroRange()) || (Math.abs(_actor.getZ() - target.getZ()) > 100))
|
||||
{
|
||||
return false;
|
||||
|
@ -92,11 +92,13 @@ public class DoppelgangerAI extends CreatureAI
|
||||
setTarget(null);
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean val = _startFollow;
|
||||
if (maybeMoveToPawn(target, _actor.getMagicalAttackRange(_skill)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
getActor().followSummoner(false);
|
||||
setIntention(AI_INTENTION_IDLE);
|
||||
_startFollow = val;
|
||||
|
@ -33,7 +33,7 @@ import org.l2jmobius.gameserver.network.SystemMessageId;
|
||||
*/
|
||||
public abstract class PlayableAI extends CreatureAI
|
||||
{
|
||||
public PlayableAI(Playable playable)
|
||||
protected PlayableAI(Playable playable)
|
||||
{
|
||||
super(playable);
|
||||
}
|
||||
|
@ -65,11 +65,6 @@ public class PlayerAI extends PlayableAI
|
||||
@Override
|
||||
protected synchronized void changeIntention(CtrlIntention intention, Object... args)
|
||||
{
|
||||
final Object localArg0 = args.length > 0 ? args[0] : null;
|
||||
final Object localArg1 = args.length > 1 ? args[1] : null;
|
||||
final Object globalArg0 = (_intentionArgs != null) && (_intentionArgs.length > 0) ? _intentionArgs[0] : null;
|
||||
final Object globalArg1 = (_intentionArgs != null) && (_intentionArgs.length > 1) ? _intentionArgs[1] : null;
|
||||
|
||||
// do nothing unless CAST intention
|
||||
// however, forget interrupted actions when starting to use an offensive skill
|
||||
if ((intention != AI_INTENTION_CAST) || ((Skill) args[0]).isBad())
|
||||
@ -79,6 +74,11 @@ public class PlayerAI extends PlayableAI
|
||||
return;
|
||||
}
|
||||
|
||||
final Object localArg0 = args.length > 0 ? args[0] : null;
|
||||
final Object localArg1 = args.length > 1 ? args[1] : null;
|
||||
final Object globalArg0 = (_intentionArgs != null) && (_intentionArgs.length > 0) ? _intentionArgs[0] : null;
|
||||
final Object globalArg1 = (_intentionArgs != null) && (_intentionArgs.length > 1) ? _intentionArgs[1] : null;
|
||||
|
||||
// do nothing if next intention is same as current one.
|
||||
if ((intention == _intention) && (globalArg0 == localArg0) && (globalArg1 == localArg1))
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ public abstract class VehicleAI extends CreatureAI
|
||||
* Simple AI for vehicles
|
||||
* @param vehicle
|
||||
*/
|
||||
public VehicleAI(Vehicle vehicle)
|
||||
protected VehicleAI(Vehicle vehicle)
|
||||
{
|
||||
super(vehicle);
|
||||
}
|
||||
|
@ -66,10 +66,10 @@ public abstract class AbstractAI implements Ctrl
|
||||
private WorldObject _target;
|
||||
|
||||
/** The skill we are currently casting by INTENTION_CAST */
|
||||
Skill _skill;
|
||||
ItemInstance _item;
|
||||
boolean _forceUse;
|
||||
boolean _dontMove;
|
||||
protected Skill _skill;
|
||||
protected ItemInstance _item;
|
||||
protected boolean _forceUse;
|
||||
protected boolean _dontMove;
|
||||
|
||||
/** Different internal state flags */
|
||||
protected int _moveToPawnTimeout;
|
||||
@ -182,7 +182,7 @@ public abstract class AbstractAI implements Ctrl
|
||||
}
|
||||
case AI_INTENTION_CAST:
|
||||
{
|
||||
onIntentionCast((Skill) args[0], (WorldObject) args[1], args.length > 2 ? (ItemInstance) args[2] : null, args.length > 3 ? (boolean) args[3] : false, args.length > 4 ? (boolean) args[4] : false);
|
||||
onIntentionCast((Skill) args[0], (WorldObject) args[1], args.length > 2 ? (ItemInstance) args[2] : null, args.length > 3 && (boolean) args[3], args.length > 4 && (boolean) args[4]);
|
||||
break;
|
||||
}
|
||||
case AI_INTENTION_MOVE_TO:
|
||||
|
@ -114,8 +114,6 @@ public class AttackableAI extends CreatureAI
|
||||
return false;
|
||||
}
|
||||
|
||||
final Attackable me = getActiveChar();
|
||||
|
||||
// Check if the target isn't dead, is in the Aggro range and is at the same height
|
||||
if (target.isAlikeDead())
|
||||
{
|
||||
@ -123,6 +121,7 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
|
||||
// Check if the target is a Playable and if the AI isn't a Raid Boss, can See Silent Moving players and the target isn't in silent move mode
|
||||
final Attackable me = getActiveChar();
|
||||
if (target.isPlayable() && !(me.isRaid()) && !(me.canSeeThroughSilentMove()) && ((Playable) target).isSilentMovingAffected())
|
||||
{
|
||||
return false;
|
||||
@ -545,10 +544,6 @@ public class AttackableAI extends CreatureAI
|
||||
// Order to the MonsterInstance to random walk (1/100)
|
||||
else if ((npc.getSpawn() != null) && (Rnd.get(RANDOM_WALK_RATE) == 0) && npc.isRandomWalkingEnabled())
|
||||
{
|
||||
int x1 = 0;
|
||||
int y1 = 0;
|
||||
int z1 = 0;
|
||||
final int range = Config.MAX_DRIFT_RANGE;
|
||||
for (Skill sk : npc.getTemplate().getAISkills(AISkillScope.BUFF))
|
||||
{
|
||||
target = skillTargetReconsider(sk, true);
|
||||
@ -560,9 +555,10 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
}
|
||||
|
||||
x1 = npc.getSpawn().getX();
|
||||
y1 = npc.getSpawn().getY();
|
||||
z1 = npc.getSpawn().getZ();
|
||||
int x1 = npc.getSpawn().getX();
|
||||
int y1 = npc.getSpawn().getY();
|
||||
int z1 = npc.getSpawn().getZ();
|
||||
final int range = Config.MAX_DRIFT_RANGE;
|
||||
if (!npc.isInsideRadius2D(x1, y1, 0, range))
|
||||
{
|
||||
npc.setReturningToSpawnPoint(true);
|
||||
@ -761,7 +757,6 @@ public class AttackableAI extends CreatureAI
|
||||
return;
|
||||
}
|
||||
|
||||
final int combinedCollision = collision + target.getTemplate().getCollisionRadius();
|
||||
final List<Skill> aiSuicideSkills = npc.getTemplate().getAISkills(AISkillScope.SUICIDE);
|
||||
if (!aiSuicideSkills.isEmpty() && ((int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100) < 30) && npc.hasSkillChance())
|
||||
{
|
||||
@ -778,6 +773,7 @@ public class AttackableAI extends CreatureAI
|
||||
// In case many mobs are trying to hit from same place, move a bit, circling around the target
|
||||
// Note from Gnacik:
|
||||
// On l2js because of that sometimes mobs don't attack player only running around player without any sense, so decrease chance for now
|
||||
final int combinedCollision = collision + target.getTemplate().getCollisionRadius();
|
||||
if (!npc.isMovementDisabled() && (Rnd.get(100) <= 3))
|
||||
{
|
||||
for (Attackable nearby : World.getInstance().getVisibleObjects(npc, Attackable.class))
|
||||
@ -1231,7 +1227,6 @@ public class AttackableAI extends CreatureAI
|
||||
Creature creature = null;
|
||||
for (AggroInfo aggro : npc.getAggroList().values())
|
||||
{
|
||||
searchValue = aggro.getHate();
|
||||
if (checkTarget(aggro.getAttacker()) && (aggro.getHate() > searchValue))
|
||||
{
|
||||
searchValue = aggro.getHate();
|
||||
|
@ -381,12 +381,13 @@ public class ControllableMobAI extends AttackableAI
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final Attackable me = (Attackable) _actor;
|
||||
|
||||
if (target.isNpc() || target.isDoor())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final Attackable me = (Attackable) _actor;
|
||||
if (target.isAlikeDead() || !me.isInsideRadius2D(target, me.getAggroRange()) || (Math.abs(_actor.getZ() - target.getZ()) > 100))
|
||||
{
|
||||
return false;
|
||||
|
@ -92,11 +92,13 @@ public class DoppelgangerAI extends CreatureAI
|
||||
setTarget(null);
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean val = _startFollow;
|
||||
if (maybeMoveToPawn(target, _actor.getMagicalAttackRange(_skill)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
getActor().followSummoner(false);
|
||||
setIntention(AI_INTENTION_IDLE);
|
||||
_startFollow = val;
|
||||
|
@ -33,7 +33,7 @@ import org.l2jmobius.gameserver.network.SystemMessageId;
|
||||
*/
|
||||
public abstract class PlayableAI extends CreatureAI
|
||||
{
|
||||
public PlayableAI(Playable playable)
|
||||
protected PlayableAI(Playable playable)
|
||||
{
|
||||
super(playable);
|
||||
}
|
||||
|
@ -65,11 +65,6 @@ public class PlayerAI extends PlayableAI
|
||||
@Override
|
||||
protected synchronized void changeIntention(CtrlIntention intention, Object... args)
|
||||
{
|
||||
final Object localArg0 = args.length > 0 ? args[0] : null;
|
||||
final Object localArg1 = args.length > 1 ? args[1] : null;
|
||||
final Object globalArg0 = (_intentionArgs != null) && (_intentionArgs.length > 0) ? _intentionArgs[0] : null;
|
||||
final Object globalArg1 = (_intentionArgs != null) && (_intentionArgs.length > 1) ? _intentionArgs[1] : null;
|
||||
|
||||
// do nothing unless CAST intention
|
||||
// however, forget interrupted actions when starting to use an offensive skill
|
||||
if ((intention != AI_INTENTION_CAST) || ((Skill) args[0]).isBad())
|
||||
@ -79,6 +74,11 @@ public class PlayerAI extends PlayableAI
|
||||
return;
|
||||
}
|
||||
|
||||
final Object localArg0 = args.length > 0 ? args[0] : null;
|
||||
final Object localArg1 = args.length > 1 ? args[1] : null;
|
||||
final Object globalArg0 = (_intentionArgs != null) && (_intentionArgs.length > 0) ? _intentionArgs[0] : null;
|
||||
final Object globalArg1 = (_intentionArgs != null) && (_intentionArgs.length > 1) ? _intentionArgs[1] : null;
|
||||
|
||||
// do nothing if next intention is same as current one.
|
||||
if ((intention == _intention) && (globalArg0 == localArg0) && (globalArg1 == localArg1))
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ public abstract class VehicleAI extends CreatureAI
|
||||
* Simple AI for vehicles
|
||||
* @param vehicle
|
||||
*/
|
||||
public VehicleAI(Vehicle vehicle)
|
||||
protected VehicleAI(Vehicle vehicle)
|
||||
{
|
||||
super(vehicle);
|
||||
}
|
||||
|
@ -66,10 +66,10 @@ public abstract class AbstractAI implements Ctrl
|
||||
private WorldObject _target;
|
||||
|
||||
/** The skill we are currently casting by INTENTION_CAST */
|
||||
Skill _skill;
|
||||
ItemInstance _item;
|
||||
boolean _forceUse;
|
||||
boolean _dontMove;
|
||||
protected Skill _skill;
|
||||
protected ItemInstance _item;
|
||||
protected boolean _forceUse;
|
||||
protected boolean _dontMove;
|
||||
|
||||
/** Different internal state flags */
|
||||
protected int _moveToPawnTimeout;
|
||||
@ -182,7 +182,7 @@ public abstract class AbstractAI implements Ctrl
|
||||
}
|
||||
case AI_INTENTION_CAST:
|
||||
{
|
||||
onIntentionCast((Skill) args[0], (WorldObject) args[1], args.length > 2 ? (ItemInstance) args[2] : null, args.length > 3 ? (boolean) args[3] : false, args.length > 4 ? (boolean) args[4] : false);
|
||||
onIntentionCast((Skill) args[0], (WorldObject) args[1], args.length > 2 ? (ItemInstance) args[2] : null, args.length > 3 && (boolean) args[3], args.length > 4 && (boolean) args[4]);
|
||||
break;
|
||||
}
|
||||
case AI_INTENTION_MOVE_TO:
|
||||
|
@ -114,8 +114,6 @@ public class AttackableAI extends CreatureAI
|
||||
return false;
|
||||
}
|
||||
|
||||
final Attackable me = getActiveChar();
|
||||
|
||||
// Check if the target isn't dead, is in the Aggro range and is at the same height
|
||||
if (target.isAlikeDead())
|
||||
{
|
||||
@ -123,6 +121,7 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
|
||||
// Check if the target is a Playable and if the AI isn't a Raid Boss, can See Silent Moving players and the target isn't in silent move mode
|
||||
final Attackable me = getActiveChar();
|
||||
if (target.isPlayable() && !(me.isRaid()) && !(me.canSeeThroughSilentMove()) && ((Playable) target).isSilentMovingAffected())
|
||||
{
|
||||
return false;
|
||||
@ -545,10 +544,6 @@ public class AttackableAI extends CreatureAI
|
||||
// Order to the MonsterInstance to random walk (1/100)
|
||||
else if ((npc.getSpawn() != null) && (Rnd.get(RANDOM_WALK_RATE) == 0) && npc.isRandomWalkingEnabled())
|
||||
{
|
||||
int x1 = 0;
|
||||
int y1 = 0;
|
||||
int z1 = 0;
|
||||
final int range = Config.MAX_DRIFT_RANGE;
|
||||
for (Skill sk : npc.getTemplate().getAISkills(AISkillScope.BUFF))
|
||||
{
|
||||
target = skillTargetReconsider(sk, true);
|
||||
@ -560,9 +555,10 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
}
|
||||
|
||||
x1 = npc.getSpawn().getX();
|
||||
y1 = npc.getSpawn().getY();
|
||||
z1 = npc.getSpawn().getZ();
|
||||
int x1 = npc.getSpawn().getX();
|
||||
int y1 = npc.getSpawn().getY();
|
||||
int z1 = npc.getSpawn().getZ();
|
||||
final int range = Config.MAX_DRIFT_RANGE;
|
||||
if (!npc.isInsideRadius2D(x1, y1, 0, range))
|
||||
{
|
||||
npc.setReturningToSpawnPoint(true);
|
||||
@ -761,7 +757,6 @@ public class AttackableAI extends CreatureAI
|
||||
return;
|
||||
}
|
||||
|
||||
final int combinedCollision = collision + target.getTemplate().getCollisionRadius();
|
||||
final List<Skill> aiSuicideSkills = npc.getTemplate().getAISkills(AISkillScope.SUICIDE);
|
||||
if (!aiSuicideSkills.isEmpty() && ((int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100) < 30) && npc.hasSkillChance())
|
||||
{
|
||||
@ -778,6 +773,7 @@ public class AttackableAI extends CreatureAI
|
||||
// In case many mobs are trying to hit from same place, move a bit, circling around the target
|
||||
// Note from Gnacik:
|
||||
// On l2js because of that sometimes mobs don't attack player only running around player without any sense, so decrease chance for now
|
||||
final int combinedCollision = collision + target.getTemplate().getCollisionRadius();
|
||||
if (!npc.isMovementDisabled() && (Rnd.get(100) <= 3))
|
||||
{
|
||||
for (Attackable nearby : World.getInstance().getVisibleObjects(npc, Attackable.class))
|
||||
@ -1231,7 +1227,6 @@ public class AttackableAI extends CreatureAI
|
||||
Creature creature = null;
|
||||
for (AggroInfo aggro : npc.getAggroList().values())
|
||||
{
|
||||
searchValue = aggro.getHate();
|
||||
if (checkTarget(aggro.getAttacker()) && (aggro.getHate() > searchValue))
|
||||
{
|
||||
searchValue = aggro.getHate();
|
||||
|
@ -381,12 +381,13 @@ public class ControllableMobAI extends AttackableAI
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final Attackable me = (Attackable) _actor;
|
||||
|
||||
if (target.isNpc() || target.isDoor())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final Attackable me = (Attackable) _actor;
|
||||
if (target.isAlikeDead() || !me.isInsideRadius2D(target, me.getAggroRange()) || (Math.abs(_actor.getZ() - target.getZ()) > 100))
|
||||
{
|
||||
return false;
|
||||
|
@ -92,11 +92,13 @@ public class DoppelgangerAI extends CreatureAI
|
||||
setTarget(null);
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean val = _startFollow;
|
||||
if (maybeMoveToPawn(target, _actor.getMagicalAttackRange(_skill)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
getActor().followSummoner(false);
|
||||
setIntention(AI_INTENTION_IDLE);
|
||||
_startFollow = val;
|
||||
|
@ -33,7 +33,7 @@ import org.l2jmobius.gameserver.network.SystemMessageId;
|
||||
*/
|
||||
public abstract class PlayableAI extends CreatureAI
|
||||
{
|
||||
public PlayableAI(Playable playable)
|
||||
protected PlayableAI(Playable playable)
|
||||
{
|
||||
super(playable);
|
||||
}
|
||||
|
@ -65,11 +65,6 @@ public class PlayerAI extends PlayableAI
|
||||
@Override
|
||||
protected synchronized void changeIntention(CtrlIntention intention, Object... args)
|
||||
{
|
||||
final Object localArg0 = args.length > 0 ? args[0] : null;
|
||||
final Object localArg1 = args.length > 1 ? args[1] : null;
|
||||
final Object globalArg0 = (_intentionArgs != null) && (_intentionArgs.length > 0) ? _intentionArgs[0] : null;
|
||||
final Object globalArg1 = (_intentionArgs != null) && (_intentionArgs.length > 1) ? _intentionArgs[1] : null;
|
||||
|
||||
// do nothing unless CAST intention
|
||||
// however, forget interrupted actions when starting to use an offensive skill
|
||||
if ((intention != AI_INTENTION_CAST) || ((Skill) args[0]).isBad())
|
||||
@ -79,6 +74,11 @@ public class PlayerAI extends PlayableAI
|
||||
return;
|
||||
}
|
||||
|
||||
final Object localArg0 = args.length > 0 ? args[0] : null;
|
||||
final Object localArg1 = args.length > 1 ? args[1] : null;
|
||||
final Object globalArg0 = (_intentionArgs != null) && (_intentionArgs.length > 0) ? _intentionArgs[0] : null;
|
||||
final Object globalArg1 = (_intentionArgs != null) && (_intentionArgs.length > 1) ? _intentionArgs[1] : null;
|
||||
|
||||
// do nothing if next intention is same as current one.
|
||||
if ((intention == _intention) && (globalArg0 == localArg0) && (globalArg1 == localArg1))
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ public abstract class VehicleAI extends CreatureAI
|
||||
* Simple AI for vehicles
|
||||
* @param vehicle
|
||||
*/
|
||||
public VehicleAI(Vehicle vehicle)
|
||||
protected VehicleAI(Vehicle vehicle)
|
||||
{
|
||||
super(vehicle);
|
||||
}
|
||||
|
@ -66,10 +66,10 @@ public abstract class AbstractAI implements Ctrl
|
||||
private WorldObject _target;
|
||||
|
||||
/** The skill we are currently casting by INTENTION_CAST */
|
||||
Skill _skill;
|
||||
ItemInstance _item;
|
||||
boolean _forceUse;
|
||||
boolean _dontMove;
|
||||
protected Skill _skill;
|
||||
protected ItemInstance _item;
|
||||
protected boolean _forceUse;
|
||||
protected boolean _dontMove;
|
||||
|
||||
/** Different internal state flags */
|
||||
protected int _moveToPawnTimeout;
|
||||
@ -182,7 +182,7 @@ public abstract class AbstractAI implements Ctrl
|
||||
}
|
||||
case AI_INTENTION_CAST:
|
||||
{
|
||||
onIntentionCast((Skill) args[0], (WorldObject) args[1], args.length > 2 ? (ItemInstance) args[2] : null, args.length > 3 ? (boolean) args[3] : false, args.length > 4 ? (boolean) args[4] : false);
|
||||
onIntentionCast((Skill) args[0], (WorldObject) args[1], args.length > 2 ? (ItemInstance) args[2] : null, args.length > 3 && (boolean) args[3], args.length > 4 && (boolean) args[4]);
|
||||
break;
|
||||
}
|
||||
case AI_INTENTION_MOVE_TO:
|
||||
|
@ -114,8 +114,6 @@ public class AttackableAI extends CreatureAI
|
||||
return false;
|
||||
}
|
||||
|
||||
final Attackable me = getActiveChar();
|
||||
|
||||
// Check if the target isn't dead, is in the Aggro range and is at the same height
|
||||
if (target.isAlikeDead())
|
||||
{
|
||||
@ -123,6 +121,7 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
|
||||
// Check if the target is a Playable and if the AI isn't a Raid Boss, can See Silent Moving players and the target isn't in silent move mode
|
||||
final Attackable me = getActiveChar();
|
||||
if (target.isPlayable() && !(me.isRaid()) && !(me.canSeeThroughSilentMove()) && ((Playable) target).isSilentMovingAffected())
|
||||
{
|
||||
return false;
|
||||
@ -545,10 +544,6 @@ public class AttackableAI extends CreatureAI
|
||||
// Order to the MonsterInstance to random walk (1/100)
|
||||
else if ((npc.getSpawn() != null) && (Rnd.get(RANDOM_WALK_RATE) == 0) && npc.isRandomWalkingEnabled())
|
||||
{
|
||||
int x1 = 0;
|
||||
int y1 = 0;
|
||||
int z1 = 0;
|
||||
final int range = Config.MAX_DRIFT_RANGE;
|
||||
for (Skill sk : npc.getTemplate().getAISkills(AISkillScope.BUFF))
|
||||
{
|
||||
target = skillTargetReconsider(sk, true);
|
||||
@ -560,9 +555,10 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
}
|
||||
|
||||
x1 = npc.getSpawn().getX();
|
||||
y1 = npc.getSpawn().getY();
|
||||
z1 = npc.getSpawn().getZ();
|
||||
int x1 = npc.getSpawn().getX();
|
||||
int y1 = npc.getSpawn().getY();
|
||||
int z1 = npc.getSpawn().getZ();
|
||||
final int range = Config.MAX_DRIFT_RANGE;
|
||||
if (!npc.isInsideRadius2D(x1, y1, 0, range))
|
||||
{
|
||||
npc.setReturningToSpawnPoint(true);
|
||||
@ -761,7 +757,6 @@ public class AttackableAI extends CreatureAI
|
||||
return;
|
||||
}
|
||||
|
||||
final int combinedCollision = collision + target.getTemplate().getCollisionRadius();
|
||||
final List<Skill> aiSuicideSkills = npc.getTemplate().getAISkills(AISkillScope.SUICIDE);
|
||||
if (!aiSuicideSkills.isEmpty() && ((int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100) < 30) && npc.hasSkillChance())
|
||||
{
|
||||
@ -778,6 +773,7 @@ public class AttackableAI extends CreatureAI
|
||||
// In case many mobs are trying to hit from same place, move a bit, circling around the target
|
||||
// Note from Gnacik:
|
||||
// On l2js because of that sometimes mobs don't attack player only running around player without any sense, so decrease chance for now
|
||||
final int combinedCollision = collision + target.getTemplate().getCollisionRadius();
|
||||
if (!npc.isMovementDisabled() && (Rnd.get(100) <= 3))
|
||||
{
|
||||
for (Attackable nearby : World.getInstance().getVisibleObjects(npc, Attackable.class))
|
||||
@ -1231,7 +1227,6 @@ public class AttackableAI extends CreatureAI
|
||||
Creature creature = null;
|
||||
for (AggroInfo aggro : npc.getAggroList().values())
|
||||
{
|
||||
searchValue = aggro.getHate();
|
||||
if (checkTarget(aggro.getAttacker()) && (aggro.getHate() > searchValue))
|
||||
{
|
||||
searchValue = aggro.getHate();
|
||||
|
@ -381,12 +381,13 @@ public class ControllableMobAI extends AttackableAI
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final Attackable me = (Attackable) _actor;
|
||||
|
||||
if (target.isNpc() || target.isDoor())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final Attackable me = (Attackable) _actor;
|
||||
if (target.isAlikeDead() || !me.isInsideRadius2D(target, me.getAggroRange()) || (Math.abs(_actor.getZ() - target.getZ()) > 100))
|
||||
{
|
||||
return false;
|
||||
|
@ -92,11 +92,13 @@ public class DoppelgangerAI extends CreatureAI
|
||||
setTarget(null);
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean val = _startFollow;
|
||||
if (maybeMoveToPawn(target, _actor.getMagicalAttackRange(_skill)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
getActor().followSummoner(false);
|
||||
setIntention(AI_INTENTION_IDLE);
|
||||
_startFollow = val;
|
||||
|
@ -33,7 +33,7 @@ import org.l2jmobius.gameserver.network.SystemMessageId;
|
||||
*/
|
||||
public abstract class PlayableAI extends CreatureAI
|
||||
{
|
||||
public PlayableAI(Playable playable)
|
||||
protected PlayableAI(Playable playable)
|
||||
{
|
||||
super(playable);
|
||||
}
|
||||
|
@ -65,11 +65,6 @@ public class PlayerAI extends PlayableAI
|
||||
@Override
|
||||
protected synchronized void changeIntention(CtrlIntention intention, Object... args)
|
||||
{
|
||||
final Object localArg0 = args.length > 0 ? args[0] : null;
|
||||
final Object localArg1 = args.length > 1 ? args[1] : null;
|
||||
final Object globalArg0 = (_intentionArgs != null) && (_intentionArgs.length > 0) ? _intentionArgs[0] : null;
|
||||
final Object globalArg1 = (_intentionArgs != null) && (_intentionArgs.length > 1) ? _intentionArgs[1] : null;
|
||||
|
||||
// do nothing unless CAST intention
|
||||
// however, forget interrupted actions when starting to use an offensive skill
|
||||
if ((intention != AI_INTENTION_CAST) || ((Skill) args[0]).isBad())
|
||||
@ -79,6 +74,11 @@ public class PlayerAI extends PlayableAI
|
||||
return;
|
||||
}
|
||||
|
||||
final Object localArg0 = args.length > 0 ? args[0] : null;
|
||||
final Object localArg1 = args.length > 1 ? args[1] : null;
|
||||
final Object globalArg0 = (_intentionArgs != null) && (_intentionArgs.length > 0) ? _intentionArgs[0] : null;
|
||||
final Object globalArg1 = (_intentionArgs != null) && (_intentionArgs.length > 1) ? _intentionArgs[1] : null;
|
||||
|
||||
// do nothing if next intention is same as current one.
|
||||
if ((intention == _intention) && (globalArg0 == localArg0) && (globalArg1 == localArg1))
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ public abstract class VehicleAI extends CreatureAI
|
||||
* Simple AI for vehicles
|
||||
* @param vehicle
|
||||
*/
|
||||
public VehicleAI(Vehicle vehicle)
|
||||
protected VehicleAI(Vehicle vehicle)
|
||||
{
|
||||
super(vehicle);
|
||||
}
|
||||
|
@ -66,10 +66,10 @@ public abstract class AbstractAI implements Ctrl
|
||||
private WorldObject _target;
|
||||
|
||||
/** The skill we are currently casting by INTENTION_CAST */
|
||||
Skill _skill;
|
||||
ItemInstance _item;
|
||||
boolean _forceUse;
|
||||
boolean _dontMove;
|
||||
protected Skill _skill;
|
||||
protected ItemInstance _item;
|
||||
protected boolean _forceUse;
|
||||
protected boolean _dontMove;
|
||||
|
||||
/** Different internal state flags */
|
||||
protected int _moveToPawnTimeout;
|
||||
@ -182,7 +182,7 @@ public abstract class AbstractAI implements Ctrl
|
||||
}
|
||||
case AI_INTENTION_CAST:
|
||||
{
|
||||
onIntentionCast((Skill) args[0], (WorldObject) args[1], args.length > 2 ? (ItemInstance) args[2] : null, args.length > 3 ? (boolean) args[3] : false, args.length > 4 ? (boolean) args[4] : false);
|
||||
onIntentionCast((Skill) args[0], (WorldObject) args[1], args.length > 2 ? (ItemInstance) args[2] : null, args.length > 3 && (boolean) args[3], args.length > 4 && (boolean) args[4]);
|
||||
break;
|
||||
}
|
||||
case AI_INTENTION_MOVE_TO:
|
||||
|
@ -114,8 +114,6 @@ public class AttackableAI extends CreatureAI
|
||||
return false;
|
||||
}
|
||||
|
||||
final Attackable me = getActiveChar();
|
||||
|
||||
// Check if the target isn't dead, is in the Aggro range and is at the same height
|
||||
if (target.isAlikeDead())
|
||||
{
|
||||
@ -123,6 +121,7 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
|
||||
// Check if the target is a Playable and if the AI isn't a Raid Boss, can See Silent Moving players and the target isn't in silent move mode
|
||||
final Attackable me = getActiveChar();
|
||||
if (target.isPlayable() && !(me.isRaid()) && !(me.canSeeThroughSilentMove()) && ((Playable) target).isSilentMovingAffected())
|
||||
{
|
||||
return false;
|
||||
@ -545,10 +544,6 @@ public class AttackableAI extends CreatureAI
|
||||
// Order to the MonsterInstance to random walk (1/100)
|
||||
else if ((npc.getSpawn() != null) && (Rnd.get(RANDOM_WALK_RATE) == 0) && npc.isRandomWalkingEnabled())
|
||||
{
|
||||
int x1 = 0;
|
||||
int y1 = 0;
|
||||
int z1 = 0;
|
||||
final int range = Config.MAX_DRIFT_RANGE;
|
||||
for (Skill sk : npc.getTemplate().getAISkills(AISkillScope.BUFF))
|
||||
{
|
||||
target = skillTargetReconsider(sk, true);
|
||||
@ -560,9 +555,10 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
}
|
||||
|
||||
x1 = npc.getSpawn().getX();
|
||||
y1 = npc.getSpawn().getY();
|
||||
z1 = npc.getSpawn().getZ();
|
||||
int x1 = npc.getSpawn().getX();
|
||||
int y1 = npc.getSpawn().getY();
|
||||
int z1 = npc.getSpawn().getZ();
|
||||
final int range = Config.MAX_DRIFT_RANGE;
|
||||
if (!npc.isInsideRadius2D(x1, y1, 0, range))
|
||||
{
|
||||
npc.setReturningToSpawnPoint(true);
|
||||
@ -761,7 +757,6 @@ public class AttackableAI extends CreatureAI
|
||||
return;
|
||||
}
|
||||
|
||||
final int combinedCollision = collision + target.getTemplate().getCollisionRadius();
|
||||
final List<Skill> aiSuicideSkills = npc.getTemplate().getAISkills(AISkillScope.SUICIDE);
|
||||
if (!aiSuicideSkills.isEmpty() && ((int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100) < 30) && npc.hasSkillChance())
|
||||
{
|
||||
@ -778,6 +773,7 @@ public class AttackableAI extends CreatureAI
|
||||
// In case many mobs are trying to hit from same place, move a bit, circling around the target
|
||||
// Note from Gnacik:
|
||||
// On l2js because of that sometimes mobs don't attack player only running around player without any sense, so decrease chance for now
|
||||
final int combinedCollision = collision + target.getTemplate().getCollisionRadius();
|
||||
if (!npc.isMovementDisabled() && (Rnd.get(100) <= 3))
|
||||
{
|
||||
for (Attackable nearby : World.getInstance().getVisibleObjects(npc, Attackable.class))
|
||||
@ -1231,7 +1227,6 @@ public class AttackableAI extends CreatureAI
|
||||
Creature creature = null;
|
||||
for (AggroInfo aggro : npc.getAggroList().values())
|
||||
{
|
||||
searchValue = aggro.getHate();
|
||||
if (checkTarget(aggro.getAttacker()) && (aggro.getHate() > searchValue))
|
||||
{
|
||||
searchValue = aggro.getHate();
|
||||
|
@ -381,12 +381,13 @@ public class ControllableMobAI extends AttackableAI
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final Attackable me = (Attackable) _actor;
|
||||
|
||||
if (target.isNpc() || target.isDoor())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final Attackable me = (Attackable) _actor;
|
||||
if (target.isAlikeDead() || !me.isInsideRadius2D(target, me.getAggroRange()) || (Math.abs(_actor.getZ() - target.getZ()) > 100))
|
||||
{
|
||||
return false;
|
||||
|
@ -92,11 +92,13 @@ public class DoppelgangerAI extends CreatureAI
|
||||
setTarget(null);
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean val = _startFollow;
|
||||
if (maybeMoveToPawn(target, _actor.getMagicalAttackRange(_skill)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
getActor().followSummoner(false);
|
||||
setIntention(AI_INTENTION_IDLE);
|
||||
_startFollow = val;
|
||||
|
@ -33,7 +33,7 @@ import org.l2jmobius.gameserver.network.SystemMessageId;
|
||||
*/
|
||||
public abstract class PlayableAI extends CreatureAI
|
||||
{
|
||||
public PlayableAI(Playable playable)
|
||||
protected PlayableAI(Playable playable)
|
||||
{
|
||||
super(playable);
|
||||
}
|
||||
|
@ -65,11 +65,6 @@ public class PlayerAI extends PlayableAI
|
||||
@Override
|
||||
protected synchronized void changeIntention(CtrlIntention intention, Object... args)
|
||||
{
|
||||
final Object localArg0 = args.length > 0 ? args[0] : null;
|
||||
final Object localArg1 = args.length > 1 ? args[1] : null;
|
||||
final Object globalArg0 = (_intentionArgs != null) && (_intentionArgs.length > 0) ? _intentionArgs[0] : null;
|
||||
final Object globalArg1 = (_intentionArgs != null) && (_intentionArgs.length > 1) ? _intentionArgs[1] : null;
|
||||
|
||||
// do nothing unless CAST intention
|
||||
// however, forget interrupted actions when starting to use an offensive skill
|
||||
if ((intention != AI_INTENTION_CAST) || ((Skill) args[0]).isBad())
|
||||
@ -79,6 +74,11 @@ public class PlayerAI extends PlayableAI
|
||||
return;
|
||||
}
|
||||
|
||||
final Object localArg0 = args.length > 0 ? args[0] : null;
|
||||
final Object localArg1 = args.length > 1 ? args[1] : null;
|
||||
final Object globalArg0 = (_intentionArgs != null) && (_intentionArgs.length > 0) ? _intentionArgs[0] : null;
|
||||
final Object globalArg1 = (_intentionArgs != null) && (_intentionArgs.length > 1) ? _intentionArgs[1] : null;
|
||||
|
||||
// do nothing if next intention is same as current one.
|
||||
if ((intention == _intention) && (globalArg0 == localArg0) && (globalArg1 == localArg1))
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ public abstract class VehicleAI extends CreatureAI
|
||||
* Simple AI for vehicles
|
||||
* @param vehicle
|
||||
*/
|
||||
public VehicleAI(Vehicle vehicle)
|
||||
protected VehicleAI(Vehicle vehicle)
|
||||
{
|
||||
super(vehicle);
|
||||
}
|
||||
|
@ -66,10 +66,10 @@ public abstract class AbstractAI implements Ctrl
|
||||
private WorldObject _target;
|
||||
|
||||
/** The skill we are currently casting by INTENTION_CAST */
|
||||
Skill _skill;
|
||||
ItemInstance _item;
|
||||
boolean _forceUse;
|
||||
boolean _dontMove;
|
||||
protected Skill _skill;
|
||||
protected ItemInstance _item;
|
||||
protected boolean _forceUse;
|
||||
protected boolean _dontMove;
|
||||
|
||||
/** Different internal state flags */
|
||||
protected int _moveToPawnTimeout;
|
||||
@ -182,7 +182,7 @@ public abstract class AbstractAI implements Ctrl
|
||||
}
|
||||
case AI_INTENTION_CAST:
|
||||
{
|
||||
onIntentionCast((Skill) args[0], (WorldObject) args[1], args.length > 2 ? (ItemInstance) args[2] : null, args.length > 3 ? (boolean) args[3] : false, args.length > 4 ? (boolean) args[4] : false);
|
||||
onIntentionCast((Skill) args[0], (WorldObject) args[1], args.length > 2 ? (ItemInstance) args[2] : null, args.length > 3 && (boolean) args[3], args.length > 4 && (boolean) args[4]);
|
||||
break;
|
||||
}
|
||||
case AI_INTENTION_MOVE_TO:
|
||||
|
@ -114,8 +114,6 @@ public class AttackableAI extends CreatureAI
|
||||
return false;
|
||||
}
|
||||
|
||||
final Attackable me = getActiveChar();
|
||||
|
||||
// Check if the target isn't dead, is in the Aggro range and is at the same height
|
||||
if (target.isAlikeDead())
|
||||
{
|
||||
@ -123,6 +121,7 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
|
||||
// Check if the target is a Playable and if the AI isn't a Raid Boss, can See Silent Moving players and the target isn't in silent move mode
|
||||
final Attackable me = getActiveChar();
|
||||
if (target.isPlayable() && !(me.isRaid()) && !(me.canSeeThroughSilentMove()) && ((Playable) target).isSilentMovingAffected())
|
||||
{
|
||||
return false;
|
||||
@ -545,10 +544,6 @@ public class AttackableAI extends CreatureAI
|
||||
// Order to the MonsterInstance to random walk (1/100)
|
||||
else if ((npc.getSpawn() != null) && (Rnd.get(RANDOM_WALK_RATE) == 0) && npc.isRandomWalkingEnabled())
|
||||
{
|
||||
int x1 = 0;
|
||||
int y1 = 0;
|
||||
int z1 = 0;
|
||||
final int range = Config.MAX_DRIFT_RANGE;
|
||||
for (Skill sk : npc.getTemplate().getAISkills(AISkillScope.BUFF))
|
||||
{
|
||||
target = skillTargetReconsider(sk, true);
|
||||
@ -560,9 +555,10 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
}
|
||||
|
||||
x1 = npc.getSpawn().getX();
|
||||
y1 = npc.getSpawn().getY();
|
||||
z1 = npc.getSpawn().getZ();
|
||||
int x1 = npc.getSpawn().getX();
|
||||
int y1 = npc.getSpawn().getY();
|
||||
int z1 = npc.getSpawn().getZ();
|
||||
final int range = Config.MAX_DRIFT_RANGE;
|
||||
if (!npc.isInsideRadius2D(x1, y1, 0, range))
|
||||
{
|
||||
npc.setReturningToSpawnPoint(true);
|
||||
@ -761,7 +757,6 @@ public class AttackableAI extends CreatureAI
|
||||
return;
|
||||
}
|
||||
|
||||
final int combinedCollision = collision + target.getTemplate().getCollisionRadius();
|
||||
final List<Skill> aiSuicideSkills = npc.getTemplate().getAISkills(AISkillScope.SUICIDE);
|
||||
if (!aiSuicideSkills.isEmpty() && ((int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100) < 30) && npc.hasSkillChance())
|
||||
{
|
||||
@ -778,6 +773,7 @@ public class AttackableAI extends CreatureAI
|
||||
// In case many mobs are trying to hit from same place, move a bit, circling around the target
|
||||
// Note from Gnacik:
|
||||
// On l2js because of that sometimes mobs don't attack player only running around player without any sense, so decrease chance for now
|
||||
final int combinedCollision = collision + target.getTemplate().getCollisionRadius();
|
||||
if (!npc.isMovementDisabled() && (Rnd.get(100) <= 3))
|
||||
{
|
||||
for (Attackable nearby : World.getInstance().getVisibleObjects(npc, Attackable.class))
|
||||
@ -1231,7 +1227,6 @@ public class AttackableAI extends CreatureAI
|
||||
Creature creature = null;
|
||||
for (AggroInfo aggro : npc.getAggroList().values())
|
||||
{
|
||||
searchValue = aggro.getHate();
|
||||
if (checkTarget(aggro.getAttacker()) && (aggro.getHate() > searchValue))
|
||||
{
|
||||
searchValue = aggro.getHate();
|
||||
|
@ -381,12 +381,13 @@ public class ControllableMobAI extends AttackableAI
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final Attackable me = (Attackable) _actor;
|
||||
|
||||
if (target.isNpc() || target.isDoor())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final Attackable me = (Attackable) _actor;
|
||||
if (target.isAlikeDead() || !me.isInsideRadius2D(target, me.getAggroRange()) || (Math.abs(_actor.getZ() - target.getZ()) > 100))
|
||||
{
|
||||
return false;
|
||||
|
@ -92,11 +92,13 @@ public class DoppelgangerAI extends CreatureAI
|
||||
setTarget(null);
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean val = _startFollow;
|
||||
if (maybeMoveToPawn(target, _actor.getMagicalAttackRange(_skill)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
getActor().followSummoner(false);
|
||||
setIntention(AI_INTENTION_IDLE);
|
||||
_startFollow = val;
|
||||
|
@ -33,7 +33,7 @@ import org.l2jmobius.gameserver.network.SystemMessageId;
|
||||
*/
|
||||
public abstract class PlayableAI extends CreatureAI
|
||||
{
|
||||
public PlayableAI(Playable playable)
|
||||
protected PlayableAI(Playable playable)
|
||||
{
|
||||
super(playable);
|
||||
}
|
||||
|
@ -65,11 +65,6 @@ public class PlayerAI extends PlayableAI
|
||||
@Override
|
||||
protected synchronized void changeIntention(CtrlIntention intention, Object... args)
|
||||
{
|
||||
final Object localArg0 = args.length > 0 ? args[0] : null;
|
||||
final Object localArg1 = args.length > 1 ? args[1] : null;
|
||||
final Object globalArg0 = (_intentionArgs != null) && (_intentionArgs.length > 0) ? _intentionArgs[0] : null;
|
||||
final Object globalArg1 = (_intentionArgs != null) && (_intentionArgs.length > 1) ? _intentionArgs[1] : null;
|
||||
|
||||
// do nothing unless CAST intention
|
||||
// however, forget interrupted actions when starting to use an offensive skill
|
||||
if ((intention != AI_INTENTION_CAST) || ((Skill) args[0]).isBad())
|
||||
@ -79,6 +74,11 @@ public class PlayerAI extends PlayableAI
|
||||
return;
|
||||
}
|
||||
|
||||
final Object localArg0 = args.length > 0 ? args[0] : null;
|
||||
final Object localArg1 = args.length > 1 ? args[1] : null;
|
||||
final Object globalArg0 = (_intentionArgs != null) && (_intentionArgs.length > 0) ? _intentionArgs[0] : null;
|
||||
final Object globalArg1 = (_intentionArgs != null) && (_intentionArgs.length > 1) ? _intentionArgs[1] : null;
|
||||
|
||||
// do nothing if next intention is same as current one.
|
||||
if ((intention == _intention) && (globalArg0 == localArg0) && (globalArg1 == localArg1))
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ public abstract class VehicleAI extends CreatureAI
|
||||
* Simple AI for vehicles
|
||||
* @param vehicle
|
||||
*/
|
||||
public VehicleAI(Vehicle vehicle)
|
||||
protected VehicleAI(Vehicle vehicle)
|
||||
{
|
||||
super(vehicle);
|
||||
}
|
||||
|
@ -66,10 +66,10 @@ public abstract class AbstractAI implements Ctrl
|
||||
private WorldObject _target;
|
||||
|
||||
/** The skill we are currently casting by INTENTION_CAST */
|
||||
Skill _skill;
|
||||
ItemInstance _item;
|
||||
boolean _forceUse;
|
||||
boolean _dontMove;
|
||||
protected Skill _skill;
|
||||
protected ItemInstance _item;
|
||||
protected boolean _forceUse;
|
||||
protected boolean _dontMove;
|
||||
|
||||
/** Different internal state flags */
|
||||
protected int _moveToPawnTimeout;
|
||||
@ -182,7 +182,7 @@ public abstract class AbstractAI implements Ctrl
|
||||
}
|
||||
case AI_INTENTION_CAST:
|
||||
{
|
||||
onIntentionCast((Skill) args[0], (WorldObject) args[1], args.length > 2 ? (ItemInstance) args[2] : null, args.length > 3 ? (boolean) args[3] : false, args.length > 4 ? (boolean) args[4] : false);
|
||||
onIntentionCast((Skill) args[0], (WorldObject) args[1], args.length > 2 ? (ItemInstance) args[2] : null, args.length > 3 && (boolean) args[3], args.length > 4 && (boolean) args[4]);
|
||||
break;
|
||||
}
|
||||
case AI_INTENTION_MOVE_TO:
|
||||
|
@ -114,8 +114,6 @@ public class AttackableAI extends CreatureAI
|
||||
return false;
|
||||
}
|
||||
|
||||
final Attackable me = getActiveChar();
|
||||
|
||||
// Check if the target isn't dead, is in the Aggro range and is at the same height
|
||||
if (target.isAlikeDead())
|
||||
{
|
||||
@ -123,6 +121,7 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
|
||||
// Check if the target is a Playable and if the AI isn't a Raid Boss, can See Silent Moving players and the target isn't in silent move mode
|
||||
final Attackable me = getActiveChar();
|
||||
if (target.isPlayable() && !(me.isRaid()) && !(me.canSeeThroughSilentMove()) && ((Playable) target).isSilentMovingAffected())
|
||||
{
|
||||
return false;
|
||||
@ -545,10 +544,6 @@ public class AttackableAI extends CreatureAI
|
||||
// Order to the MonsterInstance to random walk (1/100)
|
||||
else if ((npc.getSpawn() != null) && (Rnd.get(RANDOM_WALK_RATE) == 0) && npc.isRandomWalkingEnabled())
|
||||
{
|
||||
int x1 = 0;
|
||||
int y1 = 0;
|
||||
int z1 = 0;
|
||||
final int range = Config.MAX_DRIFT_RANGE;
|
||||
for (Skill sk : npc.getTemplate().getAISkills(AISkillScope.BUFF))
|
||||
{
|
||||
target = skillTargetReconsider(sk, true);
|
||||
@ -560,9 +555,10 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
}
|
||||
|
||||
x1 = npc.getSpawn().getX();
|
||||
y1 = npc.getSpawn().getY();
|
||||
z1 = npc.getSpawn().getZ();
|
||||
int x1 = npc.getSpawn().getX();
|
||||
int y1 = npc.getSpawn().getY();
|
||||
int z1 = npc.getSpawn().getZ();
|
||||
final int range = Config.MAX_DRIFT_RANGE;
|
||||
if (!npc.isInsideRadius2D(x1, y1, 0, range))
|
||||
{
|
||||
npc.setReturningToSpawnPoint(true);
|
||||
@ -761,7 +757,6 @@ public class AttackableAI extends CreatureAI
|
||||
return;
|
||||
}
|
||||
|
||||
final int combinedCollision = collision + target.getTemplate().getCollisionRadius();
|
||||
final List<Skill> aiSuicideSkills = npc.getTemplate().getAISkills(AISkillScope.SUICIDE);
|
||||
if (!aiSuicideSkills.isEmpty() && ((int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100) < 30) && npc.hasSkillChance())
|
||||
{
|
||||
@ -778,6 +773,7 @@ public class AttackableAI extends CreatureAI
|
||||
// In case many mobs are trying to hit from same place, move a bit, circling around the target
|
||||
// Note from Gnacik:
|
||||
// On l2js because of that sometimes mobs don't attack player only running around player without any sense, so decrease chance for now
|
||||
final int combinedCollision = collision + target.getTemplate().getCollisionRadius();
|
||||
if (!npc.isMovementDisabled() && (Rnd.get(100) <= 3))
|
||||
{
|
||||
for (Attackable nearby : World.getInstance().getVisibleObjects(npc, Attackable.class))
|
||||
@ -1231,7 +1227,6 @@ public class AttackableAI extends CreatureAI
|
||||
Creature creature = null;
|
||||
for (AggroInfo aggro : npc.getAggroList().values())
|
||||
{
|
||||
searchValue = aggro.getHate();
|
||||
if (checkTarget(aggro.getAttacker()) && (aggro.getHate() > searchValue))
|
||||
{
|
||||
searchValue = aggro.getHate();
|
||||
|
@ -381,12 +381,13 @@ public class ControllableMobAI extends AttackableAI
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final Attackable me = (Attackable) _actor;
|
||||
|
||||
if (target.isNpc() || target.isDoor())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final Attackable me = (Attackable) _actor;
|
||||
if (target.isAlikeDead() || !me.isInsideRadius2D(target, me.getAggroRange()) || (Math.abs(_actor.getZ() - target.getZ()) > 100))
|
||||
{
|
||||
return false;
|
||||
|
@ -92,11 +92,13 @@ public class DoppelgangerAI extends CreatureAI
|
||||
setTarget(null);
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean val = _startFollow;
|
||||
if (maybeMoveToPawn(target, _actor.getMagicalAttackRange(_skill)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
getActor().followSummoner(false);
|
||||
setIntention(AI_INTENTION_IDLE);
|
||||
_startFollow = val;
|
||||
|
@ -33,7 +33,7 @@ import org.l2jmobius.gameserver.network.SystemMessageId;
|
||||
*/
|
||||
public abstract class PlayableAI extends CreatureAI
|
||||
{
|
||||
public PlayableAI(Playable playable)
|
||||
protected PlayableAI(Playable playable)
|
||||
{
|
||||
super(playable);
|
||||
}
|
||||
|
@ -65,11 +65,6 @@ public class PlayerAI extends PlayableAI
|
||||
@Override
|
||||
protected synchronized void changeIntention(CtrlIntention intention, Object... args)
|
||||
{
|
||||
final Object localArg0 = args.length > 0 ? args[0] : null;
|
||||
final Object localArg1 = args.length > 1 ? args[1] : null;
|
||||
final Object globalArg0 = (_intentionArgs != null) && (_intentionArgs.length > 0) ? _intentionArgs[0] : null;
|
||||
final Object globalArg1 = (_intentionArgs != null) && (_intentionArgs.length > 1) ? _intentionArgs[1] : null;
|
||||
|
||||
// do nothing unless CAST intention
|
||||
// however, forget interrupted actions when starting to use an offensive skill
|
||||
if ((intention != AI_INTENTION_CAST) || ((Skill) args[0]).isBad())
|
||||
@ -79,6 +74,11 @@ public class PlayerAI extends PlayableAI
|
||||
return;
|
||||
}
|
||||
|
||||
final Object localArg0 = args.length > 0 ? args[0] : null;
|
||||
final Object localArg1 = args.length > 1 ? args[1] : null;
|
||||
final Object globalArg0 = (_intentionArgs != null) && (_intentionArgs.length > 0) ? _intentionArgs[0] : null;
|
||||
final Object globalArg1 = (_intentionArgs != null) && (_intentionArgs.length > 1) ? _intentionArgs[1] : null;
|
||||
|
||||
// do nothing if next intention is same as current one.
|
||||
if ((intention == _intention) && (globalArg0 == localArg0) && (globalArg1 == localArg1))
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ public abstract class VehicleAI extends CreatureAI
|
||||
* Simple AI for vehicles
|
||||
* @param vehicle
|
||||
*/
|
||||
public VehicleAI(Vehicle vehicle)
|
||||
protected VehicleAI(Vehicle vehicle)
|
||||
{
|
||||
super(vehicle);
|
||||
}
|
||||
|
@ -66,10 +66,10 @@ public abstract class AbstractAI implements Ctrl
|
||||
private WorldObject _target;
|
||||
|
||||
/** The skill we are currently casting by INTENTION_CAST */
|
||||
Skill _skill;
|
||||
ItemInstance _item;
|
||||
boolean _forceUse;
|
||||
boolean _dontMove;
|
||||
protected Skill _skill;
|
||||
protected ItemInstance _item;
|
||||
protected boolean _forceUse;
|
||||
protected boolean _dontMove;
|
||||
|
||||
/** Different internal state flags */
|
||||
protected int _moveToPawnTimeout;
|
||||
@ -182,7 +182,7 @@ public abstract class AbstractAI implements Ctrl
|
||||
}
|
||||
case AI_INTENTION_CAST:
|
||||
{
|
||||
onIntentionCast((Skill) args[0], (WorldObject) args[1], args.length > 2 ? (ItemInstance) args[2] : null, args.length > 3 ? (boolean) args[3] : false, args.length > 4 ? (boolean) args[4] : false);
|
||||
onIntentionCast((Skill) args[0], (WorldObject) args[1], args.length > 2 ? (ItemInstance) args[2] : null, args.length > 3 && (boolean) args[3], args.length > 4 && (boolean) args[4]);
|
||||
break;
|
||||
}
|
||||
case AI_INTENTION_MOVE_TO:
|
||||
|
@ -114,8 +114,6 @@ public class AttackableAI extends CreatureAI
|
||||
return false;
|
||||
}
|
||||
|
||||
final Attackable me = getActiveChar();
|
||||
|
||||
// Check if the target isn't dead, is in the Aggro range and is at the same height
|
||||
if (target.isAlikeDead())
|
||||
{
|
||||
@ -123,6 +121,7 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
|
||||
// Check if the target is a Playable and if the AI isn't a Raid Boss, can See Silent Moving players and the target isn't in silent move mode
|
||||
final Attackable me = getActiveChar();
|
||||
if (target.isPlayable() && !(me.isRaid()) && !(me.canSeeThroughSilentMove()) && ((Playable) target).isSilentMovingAffected())
|
||||
{
|
||||
return false;
|
||||
@ -545,10 +544,6 @@ public class AttackableAI extends CreatureAI
|
||||
// Order to the MonsterInstance to random walk (1/100)
|
||||
else if ((npc.getSpawn() != null) && (Rnd.get(RANDOM_WALK_RATE) == 0) && npc.isRandomWalkingEnabled())
|
||||
{
|
||||
int x1 = 0;
|
||||
int y1 = 0;
|
||||
int z1 = 0;
|
||||
final int range = Config.MAX_DRIFT_RANGE;
|
||||
for (Skill sk : npc.getTemplate().getAISkills(AISkillScope.BUFF))
|
||||
{
|
||||
target = skillTargetReconsider(sk, true);
|
||||
@ -560,9 +555,10 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
}
|
||||
|
||||
x1 = npc.getSpawn().getX();
|
||||
y1 = npc.getSpawn().getY();
|
||||
z1 = npc.getSpawn().getZ();
|
||||
int x1 = npc.getSpawn().getX();
|
||||
int y1 = npc.getSpawn().getY();
|
||||
int z1 = npc.getSpawn().getZ();
|
||||
final int range = Config.MAX_DRIFT_RANGE;
|
||||
if (!npc.isInsideRadius2D(x1, y1, 0, range))
|
||||
{
|
||||
npc.setReturningToSpawnPoint(true);
|
||||
@ -761,7 +757,6 @@ public class AttackableAI extends CreatureAI
|
||||
return;
|
||||
}
|
||||
|
||||
final int combinedCollision = collision + target.getTemplate().getCollisionRadius();
|
||||
final List<Skill> aiSuicideSkills = npc.getTemplate().getAISkills(AISkillScope.SUICIDE);
|
||||
if (!aiSuicideSkills.isEmpty() && ((int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100) < 30) && npc.hasSkillChance())
|
||||
{
|
||||
@ -778,6 +773,7 @@ public class AttackableAI extends CreatureAI
|
||||
// In case many mobs are trying to hit from same place, move a bit, circling around the target
|
||||
// Note from Gnacik:
|
||||
// On l2js because of that sometimes mobs don't attack player only running around player without any sense, so decrease chance for now
|
||||
final int combinedCollision = collision + target.getTemplate().getCollisionRadius();
|
||||
if (!npc.isMovementDisabled() && (Rnd.get(100) <= 3))
|
||||
{
|
||||
for (Attackable nearby : World.getInstance().getVisibleObjects(npc, Attackable.class))
|
||||
@ -1231,7 +1227,6 @@ public class AttackableAI extends CreatureAI
|
||||
Creature creature = null;
|
||||
for (AggroInfo aggro : npc.getAggroList().values())
|
||||
{
|
||||
searchValue = aggro.getHate();
|
||||
if (checkTarget(aggro.getAttacker()) && (aggro.getHate() > searchValue))
|
||||
{
|
||||
searchValue = aggro.getHate();
|
||||
|
@ -381,12 +381,13 @@ public class ControllableMobAI extends AttackableAI
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final Attackable me = (Attackable) _actor;
|
||||
|
||||
if (target.isNpc() || target.isDoor())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final Attackable me = (Attackable) _actor;
|
||||
if (target.isAlikeDead() || !me.isInsideRadius2D(target, me.getAggroRange()) || (Math.abs(_actor.getZ() - target.getZ()) > 100))
|
||||
{
|
||||
return false;
|
||||
|
@ -92,11 +92,13 @@ public class DoppelgangerAI extends CreatureAI
|
||||
setTarget(null);
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean val = _startFollow;
|
||||
if (maybeMoveToPawn(target, _actor.getMagicalAttackRange(_skill)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
getActor().followSummoner(false);
|
||||
setIntention(AI_INTENTION_IDLE);
|
||||
_startFollow = val;
|
||||
|
@ -33,7 +33,7 @@ import org.l2jmobius.gameserver.network.SystemMessageId;
|
||||
*/
|
||||
public abstract class PlayableAI extends CreatureAI
|
||||
{
|
||||
public PlayableAI(Playable playable)
|
||||
protected PlayableAI(Playable playable)
|
||||
{
|
||||
super(playable);
|
||||
}
|
||||
|
@ -65,11 +65,6 @@ public class PlayerAI extends PlayableAI
|
||||
@Override
|
||||
protected synchronized void changeIntention(CtrlIntention intention, Object... args)
|
||||
{
|
||||
final Object localArg0 = args.length > 0 ? args[0] : null;
|
||||
final Object localArg1 = args.length > 1 ? args[1] : null;
|
||||
final Object globalArg0 = (_intentionArgs != null) && (_intentionArgs.length > 0) ? _intentionArgs[0] : null;
|
||||
final Object globalArg1 = (_intentionArgs != null) && (_intentionArgs.length > 1) ? _intentionArgs[1] : null;
|
||||
|
||||
// do nothing unless CAST intention
|
||||
// however, forget interrupted actions when starting to use an offensive skill
|
||||
if ((intention != AI_INTENTION_CAST) || ((Skill) args[0]).isBad())
|
||||
@ -79,6 +74,11 @@ public class PlayerAI extends PlayableAI
|
||||
return;
|
||||
}
|
||||
|
||||
final Object localArg0 = args.length > 0 ? args[0] : null;
|
||||
final Object localArg1 = args.length > 1 ? args[1] : null;
|
||||
final Object globalArg0 = (_intentionArgs != null) && (_intentionArgs.length > 0) ? _intentionArgs[0] : null;
|
||||
final Object globalArg1 = (_intentionArgs != null) && (_intentionArgs.length > 1) ? _intentionArgs[1] : null;
|
||||
|
||||
// do nothing if next intention is same as current one.
|
||||
if ((intention == _intention) && (globalArg0 == localArg0) && (globalArg1 == localArg1))
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ public abstract class VehicleAI extends CreatureAI
|
||||
* Simple AI for vehicles
|
||||
* @param vehicle
|
||||
*/
|
||||
public VehicleAI(Vehicle vehicle)
|
||||
protected VehicleAI(Vehicle vehicle)
|
||||
{
|
||||
super(vehicle);
|
||||
}
|
||||
|
@ -66,10 +66,10 @@ public abstract class AbstractAI implements Ctrl
|
||||
private WorldObject _target;
|
||||
|
||||
/** The skill we are currently casting by INTENTION_CAST */
|
||||
Skill _skill;
|
||||
ItemInstance _item;
|
||||
boolean _forceUse;
|
||||
boolean _dontMove;
|
||||
protected Skill _skill;
|
||||
protected ItemInstance _item;
|
||||
protected boolean _forceUse;
|
||||
protected boolean _dontMove;
|
||||
|
||||
/** Different internal state flags */
|
||||
protected int _moveToPawnTimeout;
|
||||
@ -182,7 +182,7 @@ public abstract class AbstractAI implements Ctrl
|
||||
}
|
||||
case AI_INTENTION_CAST:
|
||||
{
|
||||
onIntentionCast((Skill) args[0], (WorldObject) args[1], args.length > 2 ? (ItemInstance) args[2] : null, args.length > 3 ? (boolean) args[3] : false, args.length > 4 ? (boolean) args[4] : false);
|
||||
onIntentionCast((Skill) args[0], (WorldObject) args[1], args.length > 2 ? (ItemInstance) args[2] : null, args.length > 3 && (boolean) args[3], args.length > 4 && (boolean) args[4]);
|
||||
break;
|
||||
}
|
||||
case AI_INTENTION_MOVE_TO:
|
||||
|
@ -114,8 +114,6 @@ public class AttackableAI extends CreatureAI
|
||||
return false;
|
||||
}
|
||||
|
||||
final Attackable me = getActiveChar();
|
||||
|
||||
// Check if the target isn't dead, is in the Aggro range and is at the same height
|
||||
if (target.isAlikeDead())
|
||||
{
|
||||
@ -123,6 +121,7 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
|
||||
// Check if the target is a Playable and if the AI isn't a Raid Boss, can See Silent Moving players and the target isn't in silent move mode
|
||||
final Attackable me = getActiveChar();
|
||||
if (target.isPlayable() && !(me.isRaid()) && !(me.canSeeThroughSilentMove()) && ((Playable) target).isSilentMovingAffected())
|
||||
{
|
||||
return false;
|
||||
@ -545,10 +544,6 @@ public class AttackableAI extends CreatureAI
|
||||
// Order to the MonsterInstance to random walk (1/100)
|
||||
else if ((npc.getSpawn() != null) && (Rnd.get(RANDOM_WALK_RATE) == 0) && npc.isRandomWalkingEnabled())
|
||||
{
|
||||
int x1 = 0;
|
||||
int y1 = 0;
|
||||
int z1 = 0;
|
||||
final int range = Config.MAX_DRIFT_RANGE;
|
||||
for (Skill sk : npc.getTemplate().getAISkills(AISkillScope.BUFF))
|
||||
{
|
||||
target = skillTargetReconsider(sk, true);
|
||||
@ -560,9 +555,10 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
}
|
||||
|
||||
x1 = npc.getSpawn().getX();
|
||||
y1 = npc.getSpawn().getY();
|
||||
z1 = npc.getSpawn().getZ();
|
||||
int x1 = npc.getSpawn().getX();
|
||||
int y1 = npc.getSpawn().getY();
|
||||
int z1 = npc.getSpawn().getZ();
|
||||
final int range = Config.MAX_DRIFT_RANGE;
|
||||
if (!npc.isInsideRadius2D(x1, y1, 0, range))
|
||||
{
|
||||
npc.setReturningToSpawnPoint(true);
|
||||
@ -761,7 +757,6 @@ public class AttackableAI extends CreatureAI
|
||||
return;
|
||||
}
|
||||
|
||||
final int combinedCollision = collision + target.getTemplate().getCollisionRadius();
|
||||
final List<Skill> aiSuicideSkills = npc.getTemplate().getAISkills(AISkillScope.SUICIDE);
|
||||
if (!aiSuicideSkills.isEmpty() && ((int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100) < 30) && npc.hasSkillChance())
|
||||
{
|
||||
@ -778,6 +773,7 @@ public class AttackableAI extends CreatureAI
|
||||
// In case many mobs are trying to hit from same place, move a bit, circling around the target
|
||||
// Note from Gnacik:
|
||||
// On l2js because of that sometimes mobs don't attack player only running around player without any sense, so decrease chance for now
|
||||
final int combinedCollision = collision + target.getTemplate().getCollisionRadius();
|
||||
if (!npc.isMovementDisabled() && (Rnd.get(100) <= 3))
|
||||
{
|
||||
for (Attackable nearby : World.getInstance().getVisibleObjects(npc, Attackable.class))
|
||||
@ -1231,7 +1227,6 @@ public class AttackableAI extends CreatureAI
|
||||
Creature creature = null;
|
||||
for (AggroInfo aggro : npc.getAggroList().values())
|
||||
{
|
||||
searchValue = aggro.getHate();
|
||||
if (checkTarget(aggro.getAttacker()) && (aggro.getHate() > searchValue))
|
||||
{
|
||||
searchValue = aggro.getHate();
|
||||
|
@ -381,12 +381,13 @@ public class ControllableMobAI extends AttackableAI
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final Attackable me = (Attackable) _actor;
|
||||
|
||||
if (target.isNpc() || target.isDoor())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final Attackable me = (Attackable) _actor;
|
||||
if (target.isAlikeDead() || !me.isInsideRadius2D(target, me.getAggroRange()) || (Math.abs(_actor.getZ() - target.getZ()) > 100))
|
||||
{
|
||||
return false;
|
||||
|
@ -92,11 +92,13 @@ public class DoppelgangerAI extends CreatureAI
|
||||
setTarget(null);
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean val = _startFollow;
|
||||
if (maybeMoveToPawn(target, _actor.getMagicalAttackRange(_skill)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
getActor().followSummoner(false);
|
||||
setIntention(AI_INTENTION_IDLE);
|
||||
_startFollow = val;
|
||||
|
@ -33,7 +33,7 @@ import org.l2jmobius.gameserver.network.SystemMessageId;
|
||||
*/
|
||||
public abstract class PlayableAI extends CreatureAI
|
||||
{
|
||||
public PlayableAI(Playable playable)
|
||||
protected PlayableAI(Playable playable)
|
||||
{
|
||||
super(playable);
|
||||
}
|
||||
|
@ -65,11 +65,6 @@ public class PlayerAI extends PlayableAI
|
||||
@Override
|
||||
protected synchronized void changeIntention(CtrlIntention intention, Object... args)
|
||||
{
|
||||
final Object localArg0 = args.length > 0 ? args[0] : null;
|
||||
final Object localArg1 = args.length > 1 ? args[1] : null;
|
||||
final Object globalArg0 = (_intentionArgs != null) && (_intentionArgs.length > 0) ? _intentionArgs[0] : null;
|
||||
final Object globalArg1 = (_intentionArgs != null) && (_intentionArgs.length > 1) ? _intentionArgs[1] : null;
|
||||
|
||||
// do nothing unless CAST intention
|
||||
// however, forget interrupted actions when starting to use an offensive skill
|
||||
if ((intention != AI_INTENTION_CAST) || ((Skill) args[0]).isBad())
|
||||
@ -79,6 +74,11 @@ public class PlayerAI extends PlayableAI
|
||||
return;
|
||||
}
|
||||
|
||||
final Object localArg0 = args.length > 0 ? args[0] : null;
|
||||
final Object localArg1 = args.length > 1 ? args[1] : null;
|
||||
final Object globalArg0 = (_intentionArgs != null) && (_intentionArgs.length > 0) ? _intentionArgs[0] : null;
|
||||
final Object globalArg1 = (_intentionArgs != null) && (_intentionArgs.length > 1) ? _intentionArgs[1] : null;
|
||||
|
||||
// do nothing if next intention is same as current one.
|
||||
if ((intention == _intention) && (globalArg0 == localArg0) && (globalArg1 == localArg1))
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ public abstract class VehicleAI extends CreatureAI
|
||||
* Simple AI for vehicles
|
||||
* @param vehicle
|
||||
*/
|
||||
public VehicleAI(Vehicle vehicle)
|
||||
protected VehicleAI(Vehicle vehicle)
|
||||
{
|
||||
super(vehicle);
|
||||
}
|
||||
|
@ -66,10 +66,10 @@ public abstract class AbstractAI implements Ctrl
|
||||
private WorldObject _target;
|
||||
|
||||
/** The skill we are currently casting by INTENTION_CAST */
|
||||
Skill _skill;
|
||||
ItemInstance _item;
|
||||
boolean _forceUse;
|
||||
boolean _dontMove;
|
||||
protected Skill _skill;
|
||||
protected ItemInstance _item;
|
||||
protected boolean _forceUse;
|
||||
protected boolean _dontMove;
|
||||
|
||||
/** Different internal state flags */
|
||||
protected int _moveToPawnTimeout;
|
||||
@ -182,7 +182,7 @@ public abstract class AbstractAI implements Ctrl
|
||||
}
|
||||
case AI_INTENTION_CAST:
|
||||
{
|
||||
onIntentionCast((Skill) args[0], (WorldObject) args[1], args.length > 2 ? (ItemInstance) args[2] : null, args.length > 3 ? (boolean) args[3] : false, args.length > 4 ? (boolean) args[4] : false);
|
||||
onIntentionCast((Skill) args[0], (WorldObject) args[1], args.length > 2 ? (ItemInstance) args[2] : null, args.length > 3 && (boolean) args[3], args.length > 4 && (boolean) args[4]);
|
||||
break;
|
||||
}
|
||||
case AI_INTENTION_MOVE_TO:
|
||||
|
@ -114,8 +114,6 @@ public class AttackableAI extends CreatureAI
|
||||
return false;
|
||||
}
|
||||
|
||||
final Attackable me = getActiveChar();
|
||||
|
||||
// Check if the target isn't dead, is in the Aggro range and is at the same height
|
||||
if (target.isAlikeDead())
|
||||
{
|
||||
@ -123,6 +121,7 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
|
||||
// Check if the target is a Playable and if the AI isn't a Raid Boss, can See Silent Moving players and the target isn't in silent move mode
|
||||
final Attackable me = getActiveChar();
|
||||
if (target.isPlayable() && !(me.isRaid()) && !(me.canSeeThroughSilentMove()) && ((Playable) target).isSilentMovingAffected())
|
||||
{
|
||||
return false;
|
||||
@ -545,10 +544,6 @@ public class AttackableAI extends CreatureAI
|
||||
// Order to the MonsterInstance to random walk (1/100)
|
||||
else if ((npc.getSpawn() != null) && (Rnd.get(RANDOM_WALK_RATE) == 0) && npc.isRandomWalkingEnabled())
|
||||
{
|
||||
int x1 = 0;
|
||||
int y1 = 0;
|
||||
int z1 = 0;
|
||||
final int range = Config.MAX_DRIFT_RANGE;
|
||||
for (Skill sk : npc.getTemplate().getAISkills(AISkillScope.BUFF))
|
||||
{
|
||||
target = skillTargetReconsider(sk, true);
|
||||
@ -560,9 +555,10 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
}
|
||||
|
||||
x1 = npc.getSpawn().getX();
|
||||
y1 = npc.getSpawn().getY();
|
||||
z1 = npc.getSpawn().getZ();
|
||||
int x1 = npc.getSpawn().getX();
|
||||
int y1 = npc.getSpawn().getY();
|
||||
int z1 = npc.getSpawn().getZ();
|
||||
final int range = Config.MAX_DRIFT_RANGE;
|
||||
if (!npc.isInsideRadius2D(x1, y1, 0, range))
|
||||
{
|
||||
npc.setReturningToSpawnPoint(true);
|
||||
@ -761,7 +757,6 @@ public class AttackableAI extends CreatureAI
|
||||
return;
|
||||
}
|
||||
|
||||
final int combinedCollision = collision + target.getTemplate().getCollisionRadius();
|
||||
final List<Skill> aiSuicideSkills = npc.getTemplate().getAISkills(AISkillScope.SUICIDE);
|
||||
if (!aiSuicideSkills.isEmpty() && ((int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100) < 30) && npc.hasSkillChance())
|
||||
{
|
||||
@ -778,6 +773,7 @@ public class AttackableAI extends CreatureAI
|
||||
// In case many mobs are trying to hit from same place, move a bit, circling around the target
|
||||
// Note from Gnacik:
|
||||
// On l2js because of that sometimes mobs don't attack player only running around player without any sense, so decrease chance for now
|
||||
final int combinedCollision = collision + target.getTemplate().getCollisionRadius();
|
||||
if (!npc.isMovementDisabled() && (Rnd.get(100) <= 3))
|
||||
{
|
||||
for (Attackable nearby : World.getInstance().getVisibleObjects(npc, Attackable.class))
|
||||
@ -1231,7 +1227,6 @@ public class AttackableAI extends CreatureAI
|
||||
Creature creature = null;
|
||||
for (AggroInfo aggro : npc.getAggroList().values())
|
||||
{
|
||||
searchValue = aggro.getHate();
|
||||
if (checkTarget(aggro.getAttacker()) && (aggro.getHate() > searchValue))
|
||||
{
|
||||
searchValue = aggro.getHate();
|
||||
|
@ -381,12 +381,13 @@ public class ControllableMobAI extends AttackableAI
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final Attackable me = (Attackable) _actor;
|
||||
|
||||
if (target.isNpc() || target.isDoor())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final Attackable me = (Attackable) _actor;
|
||||
if (target.isAlikeDead() || !me.isInsideRadius2D(target, me.getAggroRange()) || (Math.abs(_actor.getZ() - target.getZ()) > 100))
|
||||
{
|
||||
return false;
|
||||
|
@ -92,11 +92,13 @@ public class DoppelgangerAI extends CreatureAI
|
||||
setTarget(null);
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean val = _startFollow;
|
||||
if (maybeMoveToPawn(target, _actor.getMagicalAttackRange(_skill)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
getActor().followSummoner(false);
|
||||
setIntention(AI_INTENTION_IDLE);
|
||||
_startFollow = val;
|
||||
|
@ -33,7 +33,7 @@ import org.l2jmobius.gameserver.network.SystemMessageId;
|
||||
*/
|
||||
public abstract class PlayableAI extends CreatureAI
|
||||
{
|
||||
public PlayableAI(Playable playable)
|
||||
protected PlayableAI(Playable playable)
|
||||
{
|
||||
super(playable);
|
||||
}
|
||||
|
@ -65,11 +65,6 @@ public class PlayerAI extends PlayableAI
|
||||
@Override
|
||||
protected synchronized void changeIntention(CtrlIntention intention, Object... args)
|
||||
{
|
||||
final Object localArg0 = args.length > 0 ? args[0] : null;
|
||||
final Object localArg1 = args.length > 1 ? args[1] : null;
|
||||
final Object globalArg0 = (_intentionArgs != null) && (_intentionArgs.length > 0) ? _intentionArgs[0] : null;
|
||||
final Object globalArg1 = (_intentionArgs != null) && (_intentionArgs.length > 1) ? _intentionArgs[1] : null;
|
||||
|
||||
// do nothing unless CAST intention
|
||||
// however, forget interrupted actions when starting to use an offensive skill
|
||||
if ((intention != AI_INTENTION_CAST) || ((Skill) args[0]).isBad())
|
||||
@ -79,6 +74,11 @@ public class PlayerAI extends PlayableAI
|
||||
return;
|
||||
}
|
||||
|
||||
final Object localArg0 = args.length > 0 ? args[0] : null;
|
||||
final Object localArg1 = args.length > 1 ? args[1] : null;
|
||||
final Object globalArg0 = (_intentionArgs != null) && (_intentionArgs.length > 0) ? _intentionArgs[0] : null;
|
||||
final Object globalArg1 = (_intentionArgs != null) && (_intentionArgs.length > 1) ? _intentionArgs[1] : null;
|
||||
|
||||
// do nothing if next intention is same as current one.
|
||||
if ((intention == _intention) && (globalArg0 == localArg0) && (globalArg1 == localArg1))
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ public abstract class VehicleAI extends CreatureAI
|
||||
* Simple AI for vehicles
|
||||
* @param vehicle
|
||||
*/
|
||||
public VehicleAI(Vehicle vehicle)
|
||||
protected VehicleAI(Vehicle vehicle)
|
||||
{
|
||||
super(vehicle);
|
||||
}
|
||||
|
@ -131,8 +131,6 @@ public class AttackableAI extends CreatureAI
|
||||
return false;
|
||||
}
|
||||
|
||||
final Attackable me = getActiveChar();
|
||||
|
||||
// Check if the target isn't invulnerable
|
||||
if (target.isInvul())
|
||||
{
|
||||
@ -155,6 +153,7 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
|
||||
// Check if the target isn't dead, is in the Aggro range and is at the same height
|
||||
final Attackable me = getActiveChar();
|
||||
if (target.isAlikeDead() || !me.isInsideRadius2D(target, me.getAggroRange()) || (Math.abs(_actor.getZ() - target.getZ()) > 300))
|
||||
{
|
||||
return false;
|
||||
@ -424,15 +423,12 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
}
|
||||
|
||||
if ((obj instanceof PlayerInstance) || (obj instanceof Summon))
|
||||
if (((obj instanceof PlayerInstance) || (obj instanceof Summon)) && !target.isAlikeDead() && !npc.isInsideRadius3D(obj, npc.getAggroRange()))
|
||||
{
|
||||
if (!target.isAlikeDead() && !npc.isInsideRadius3D(obj, npc.getAggroRange()))
|
||||
final PlayerInstance targetPlayer = obj instanceof PlayerInstance ? (PlayerInstance) obj : ((Summon) obj).getOwner();
|
||||
for (Quest quest : npc.getTemplate().getEventQuests(EventType.ON_AGGRO_RANGE_ENTER))
|
||||
{
|
||||
final PlayerInstance targetPlayer = obj instanceof PlayerInstance ? (PlayerInstance) obj : ((Summon) obj).getOwner();
|
||||
for (Quest quest : npc.getTemplate().getEventQuests(EventType.ON_AGGRO_RANGE_ENTER))
|
||||
{
|
||||
quest.notifyAggroRangeEnter(npc, targetPlayer, obj instanceof Summon);
|
||||
}
|
||||
quest.notifyAggroRangeEnter(npc, targetPlayer, obj instanceof Summon);
|
||||
}
|
||||
}
|
||||
|
||||
@ -555,7 +551,7 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
|
||||
// Calculate a destination point in the spawn area
|
||||
final int p[] = TerritoryTable.getInstance().getRandomPoint(npc.getSpawn().getLocation());
|
||||
final int[] p = TerritoryTable.getInstance().getRandomPoint(npc.getSpawn().getLocation());
|
||||
x1 = p[0];
|
||||
y1 = p[1];
|
||||
z1 = p[2];
|
||||
@ -565,7 +561,7 @@ public class AttackableAI extends CreatureAI
|
||||
if (distance2 > (Config.MAX_DRIFT_RANGE * Config.MAX_DRIFT_RANGE))
|
||||
{
|
||||
npc.setReturningToSpawnPoint(true);
|
||||
final float delay = (float) Math.sqrt(distance2) / Config.MAX_DRIFT_RANGE;
|
||||
final double delay = Math.sqrt(distance2) / Config.MAX_DRIFT_RANGE;
|
||||
x1 = _actor.getX() + (int) ((x1 - _actor.getX()) / delay);
|
||||
y1 = _actor.getY() + (int) ((y1 - _actor.getY()) / delay);
|
||||
}
|
||||
@ -660,17 +656,14 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
}
|
||||
|
||||
if (_attackTimeout < GameTimeTaskManager.getGameTicks())
|
||||
// Check if the actor is running
|
||||
if ((_attackTimeout < GameTimeTaskManager.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 PlayerInstance
|
||||
_actor.setWalking();
|
||||
|
||||
// Calculate a new attack timeout
|
||||
_attackTimeout = MAX_ATTACK_TIMEOUT + GameTimeTaskManager.getGameTicks();
|
||||
}
|
||||
// Set the actor movement type to walk and send Server->Client packet ChangeMoveType to all others PlayerInstance
|
||||
_actor.setWalking();
|
||||
|
||||
// Calculate a new attack timeout
|
||||
_attackTimeout = MAX_ATTACK_TIMEOUT + GameTimeTaskManager.getGameTicks();
|
||||
}
|
||||
|
||||
// Check if target is dead or if timeout is expired to stop this attack
|
||||
@ -715,33 +708,27 @@ public class AttackableAI extends CreatureAI
|
||||
// Check if the WorldObject is inside the Faction Range of the actor
|
||||
if ((_actor.getAttackByList() != null) && _actor.isInsideRadius3D(npc, npc.getFactionRange()) && (npc.getAI() != null) && _actor.getAttackByList().contains(originalAttackTarget))
|
||||
{
|
||||
if ((npc.getAI().getIntention() == AI_INTENTION_IDLE) || (npc.getAI().getIntention() == AI_INTENTION_ACTIVE))
|
||||
if (((npc.getAI().getIntention() == AI_INTENTION_IDLE) || (npc.getAI().getIntention() == AI_INTENTION_ACTIVE)) && GeoEngine.getInstance().canSeeTarget(_actor, npc) && (Math.abs(originalAttackTarget.getZ() - npc.getZ()) < 600))
|
||||
{
|
||||
if (GeoEngine.getInstance().canSeeTarget(_actor, npc) && (Math.abs(originalAttackTarget.getZ() - npc.getZ()) < 600))
|
||||
if ((originalAttackTarget instanceof PlayerInstance) && originalAttackTarget.isInParty() && originalAttackTarget.getParty().isInDimensionalRift())
|
||||
{
|
||||
if ((originalAttackTarget instanceof PlayerInstance) && originalAttackTarget.isInParty() && originalAttackTarget.getParty().isInDimensionalRift())
|
||||
final byte riftType = originalAttackTarget.getParty().getDimensionalRift().getType();
|
||||
final byte riftRoom = originalAttackTarget.getParty().getDimensionalRift().getCurrentRoom();
|
||||
if ((_actor instanceof RiftInvaderInstance) && !DimensionalRiftManager.getInstance().getRoom(riftType, riftRoom).checkIfInZone(npc.getX(), npc.getY(), npc.getZ()))
|
||||
{
|
||||
final byte riftType = originalAttackTarget.getParty().getDimensionalRift().getType();
|
||||
final byte riftRoom = originalAttackTarget.getParty().getDimensionalRift().getCurrentRoom();
|
||||
if ((_actor instanceof RiftInvaderInstance) && !DimensionalRiftManager.getInstance().getRoom(riftType, riftRoom).checkIfInZone(npc.getX(), npc.getY(), npc.getZ()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// Notify the WorldObject AI with EVT_AGGRESSION
|
||||
npc.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, originalAttackTarget, 1);
|
||||
}
|
||||
// Notify the WorldObject AI with EVT_AGGRESSION
|
||||
npc.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, originalAttackTarget, 1);
|
||||
}
|
||||
|
||||
if (GeoEngine.getInstance().canSeeTarget(_actor, npc) && (Math.abs(originalAttackTarget.getZ() - npc.getZ()) < 500))
|
||||
if (GeoEngine.getInstance().canSeeTarget(_actor, npc) && (Math.abs(originalAttackTarget.getZ() - npc.getZ()) < 500) && ((originalAttackTarget instanceof PlayerInstance) || (originalAttackTarget instanceof Summon)))
|
||||
{
|
||||
if ((originalAttackTarget instanceof PlayerInstance) || (originalAttackTarget instanceof Summon))
|
||||
final PlayerInstance player = originalAttackTarget instanceof PlayerInstance ? (PlayerInstance) originalAttackTarget : ((Summon) originalAttackTarget).getOwner();
|
||||
for (Quest quest : npc.getTemplate().getEventQuests(EventType.ON_FACTION_CALL))
|
||||
{
|
||||
final PlayerInstance player = originalAttackTarget instanceof PlayerInstance ? (PlayerInstance) originalAttackTarget : ((Summon) originalAttackTarget).getOwner();
|
||||
for (Quest quest : npc.getTemplate().getEventQuests(EventType.ON_FACTION_CALL))
|
||||
{
|
||||
quest.notifyFactionCall(npc, (NpcInstance) _actor, player, (originalAttackTarget instanceof Summon));
|
||||
}
|
||||
quest.notifyFactionCall(npc, (NpcInstance) _actor, player, (originalAttackTarget instanceof Summon));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -756,14 +743,12 @@ public class AttackableAI extends CreatureAI
|
||||
|
||||
// Get all information needed to chose between physical or magical attack
|
||||
Collection<Skill> skills = null;
|
||||
double dist2 = 0;
|
||||
int range = 0;
|
||||
|
||||
try
|
||||
{
|
||||
_actor.setTarget(originalAttackTarget);
|
||||
skills = _actor.getAllSkills();
|
||||
// dist2 = _actor.getPlanDistanceSq(originalAttackTarget.getX(), originalAttackTarget.getY());
|
||||
range = _actor.getPhysicalAttackRange() + _actor.getTemplate().getCollisionRadius() + originalAttackTarget.getTemplate().getCollisionRadius();
|
||||
}
|
||||
catch (NullPointerException e)
|
||||
@ -772,7 +757,6 @@ public class AttackableAI extends CreatureAI
|
||||
return;
|
||||
}
|
||||
|
||||
final Weapon weapon = _actor.getActiveWeaponItem();
|
||||
final int collision = _actor.getTemplate().getCollisionRadius();
|
||||
final int combinedCollision = collision + originalAttackTarget.getTemplate().getCollisionRadius();
|
||||
|
||||
@ -820,6 +804,7 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
}
|
||||
|
||||
final Weapon weapon = _actor.getActiveWeaponItem();
|
||||
if ((weapon != null) && (weapon.getItemType() == WeaponType.BOW))
|
||||
{
|
||||
// Micht: kepping this one otherwise we should do 2 sqrt
|
||||
@ -874,7 +859,7 @@ public class AttackableAI extends CreatureAI
|
||||
setAttackTarget(hated);
|
||||
}
|
||||
// We should calculate new distance cuz mob can have changed the target
|
||||
dist2 = _actor.calculateDistanceSq2D(hated);
|
||||
final double dist2 = _actor.calculateDistanceSq2D(hated);
|
||||
if (hated.isMoving())
|
||||
{
|
||||
range += 50;
|
||||
@ -899,13 +884,12 @@ public class AttackableAI extends CreatureAI
|
||||
{
|
||||
if ((sk.getSkillType() == Skill.SkillType.BUFF) || (sk.getSkillType() == Skill.SkillType.HEAL))
|
||||
{
|
||||
boolean useSkillSelf = true;
|
||||
if ((sk.getSkillType() == Skill.SkillType.HEAL) && (_actor.getCurrentHp() > (int) (_actor.getMaxHp() / 1.5)))
|
||||
{
|
||||
useSkillSelf = false;
|
||||
break;
|
||||
}
|
||||
|
||||
boolean useSkillSelf = true;
|
||||
if (sk.getSkillType() == Skill.SkillType.BUFF)
|
||||
{
|
||||
for (Effect effect : _actor.getAllEffects())
|
||||
@ -958,13 +942,12 @@ public class AttackableAI extends CreatureAI
|
||||
{
|
||||
if ((sk.getSkillType() == Skill.SkillType.BUFF) || (sk.getSkillType() == Skill.SkillType.HEAL))
|
||||
{
|
||||
useSkillSelf = true;
|
||||
if ((sk.getSkillType() == Skill.SkillType.HEAL) && (_actor.getCurrentHp() > (int) (_actor.getMaxHp() / 1.5)))
|
||||
{
|
||||
useSkillSelf = false;
|
||||
break;
|
||||
}
|
||||
|
||||
useSkillSelf = true;
|
||||
if (sk.getSkillType() == Skill.SkillType.BUFF)
|
||||
{
|
||||
for (Effect effect : _actor.getAllEffects())
|
||||
|
@ -381,12 +381,12 @@ public class ControllableMobAI extends AttackableAI
|
||||
return false;
|
||||
}
|
||||
|
||||
final Attackable me = (Attackable) _actor;
|
||||
if ((target instanceof FolkInstance) || (target instanceof DoorInstance))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final Attackable me = (Attackable) _actor;
|
||||
if (target.isAlikeDead() || !me.isInsideRadius2D(target, me.getAggroRange()) || (Math.abs(_actor.getZ() - target.getZ()) > 100))
|
||||
{
|
||||
return false;
|
||||
|
@ -132,7 +132,7 @@ public class DoorAI extends CreatureAI
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onEvtArrivedBlocked(Location blocked_at_loc)
|
||||
protected void onEvtArrivedBlocked(Location blockedAtLoc)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -185,14 +185,10 @@ public class FortSiegeGuardAI extends CreatureAI implements Runnable
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the target is a PlayerInstance
|
||||
if (currentTarget instanceof PlayerInstance)
|
||||
// Check if the target is a PlayerInstance and if the target isn't in silent move mode AND too far (>100)
|
||||
if ((currentTarget instanceof PlayerInstance) && ((PlayerInstance) currentTarget).isSilentMoving() && !_actor.isInsideRadius2D(currentTarget, 250))
|
||||
{
|
||||
// Check if the target isn't in silent move mode AND too far (>100)
|
||||
if (((PlayerInstance) currentTarget).isSilentMoving() && !_actor.isInsideRadius2D(currentTarget, 250))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Los Check Here
|
||||
@ -652,12 +648,12 @@ public class FortSiegeGuardAI extends CreatureAI implements Runnable
|
||||
final WorldObject 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;
|
||||
}
|
||||
|
||||
boolean useSkillSelf = true;
|
||||
if (sk.getSkillType() == SkillType.BUFF)
|
||||
{
|
||||
for (Effect effect : _actor.getAllEffects())
|
||||
@ -788,12 +784,12 @@ public class FortSiegeGuardAI extends CreatureAI implements Runnable
|
||||
final WorldObject 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;
|
||||
}
|
||||
|
||||
boolean useSkillSelf = true;
|
||||
if (sk.getSkillType() == SkillType.BUFF)
|
||||
{
|
||||
for (Effect effect : _actor.getAllEffects())
|
||||
|
@ -38,17 +38,17 @@ public class NpcWalkerAI extends CreatureAI implements Runnable
|
||||
/**
|
||||
* home points for xyz
|
||||
*/
|
||||
int _homeX;
|
||||
private int _homeX;
|
||||
|
||||
/**
|
||||
* home points for xyz
|
||||
*/
|
||||
int _homeY;
|
||||
private int _homeY;
|
||||
|
||||
/**
|
||||
* home points for xyz
|
||||
*/
|
||||
int _homeZ;
|
||||
private int _homeZ;
|
||||
|
||||
/**
|
||||
* route of the current npc
|
||||
|
@ -317,7 +317,6 @@ public class SiegeGuardAI extends CreatureAI implements Runnable
|
||||
Collection<Skill> skills = null;
|
||||
double dist2 = 0;
|
||||
int range = 0;
|
||||
final SiegeGuardInstance sGuard = (SiegeGuardInstance) _actor;
|
||||
final Creature attackTarget = getAttackTarget();
|
||||
|
||||
try
|
||||
@ -335,6 +334,7 @@ public class SiegeGuardAI extends CreatureAI implements Runnable
|
||||
}
|
||||
|
||||
// never attack defenders
|
||||
final SiegeGuardInstance sGuard = (SiegeGuardInstance) _actor;
|
||||
if ((attackTarget instanceof PlayerInstance) && sGuard.getCastle().getSiege().checkIsDefender(((PlayerInstance) attackTarget).getClan()))
|
||||
{
|
||||
// Cancel the target
|
||||
@ -367,12 +367,12 @@ public class SiegeGuardAI extends CreatureAI implements Runnable
|
||||
{
|
||||
if ((sk.getSkillType() == Skill.SkillType.BUFF) || (sk.getSkillType() == Skill.SkillType.HEAL))
|
||||
{
|
||||
boolean useSkillSelf = true;
|
||||
if (((sk.getSkillType() == Skill.SkillType.BUFF) || (sk.getSkillType() == Skill.SkillType.HEAL) || ((dist2 >= ((castRange * castRange) / 9)) && (dist2 <= (castRange * castRange)) && (castRange > 70))) && !_actor.isSkillDisabled(sk) && (_actor.getCurrentMp() >= _actor.getStat().getMpConsume(sk)) && !sk.isPassive())
|
||||
{
|
||||
useSkillSelf = false;
|
||||
break;
|
||||
}
|
||||
|
||||
boolean useSkillSelf = true;
|
||||
if (sk.getSkillType() == Skill.SkillType.BUFF)
|
||||
{
|
||||
for (Effect effect : _actor.getAllEffects())
|
||||
@ -481,13 +481,12 @@ public class SiegeGuardAI extends CreatureAI implements Runnable
|
||||
{
|
||||
if ((sk.getSkillType() == Skill.SkillType.BUFF) || (sk.getSkillType() == Skill.SkillType.HEAL))
|
||||
{
|
||||
boolean useSkillSelf = true;
|
||||
if ((sk.getSkillType() == Skill.SkillType.HEAL) && (_actor.getCurrentHp() > (int) (_actor.getMaxHp() / 1.5)))
|
||||
{
|
||||
useSkillSelf = false;
|
||||
break;
|
||||
}
|
||||
|
||||
boolean useSkillSelf = true;
|
||||
if (sk.getSkillType() == Skill.SkillType.BUFF)
|
||||
{
|
||||
for (Effect effect : _actor.getAllEffects())
|
||||
|
@ -85,7 +85,6 @@ public class SummonAI extends CreatureAI
|
||||
|
||||
private void thinkCast()
|
||||
{
|
||||
final Summon summon = (Summon) _actor;
|
||||
final Creature target = getCastTarget();
|
||||
if (checkTargetLost(target))
|
||||
{
|
||||
@ -99,6 +98,7 @@ public class SummonAI extends CreatureAI
|
||||
}
|
||||
|
||||
clientStopMoving(null);
|
||||
final Summon summon = (Summon) _actor;
|
||||
summon.setFollowStatus(false);
|
||||
setIntention(AI_INTENTION_IDLE);
|
||||
_accessor.doCast(skill);
|
||||
|
@ -131,8 +131,6 @@ public class AttackableAI extends CreatureAI
|
||||
return false;
|
||||
}
|
||||
|
||||
final Attackable me = getActiveChar();
|
||||
|
||||
// Check if the target isn't invulnerable
|
||||
if (target.isInvul())
|
||||
{
|
||||
@ -155,6 +153,7 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
|
||||
// Check if the target isn't dead, is in the Aggro range and is at the same height
|
||||
final Attackable me = getActiveChar();
|
||||
if (target.isAlikeDead() || !me.isInsideRadius2D(target, me.getAggroRange()) || (Math.abs(_actor.getZ() - target.getZ()) > 300))
|
||||
{
|
||||
return false;
|
||||
@ -424,15 +423,12 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
}
|
||||
|
||||
if ((obj instanceof PlayerInstance) || (obj instanceof Summon))
|
||||
if (((obj instanceof PlayerInstance) || (obj instanceof Summon)) && !target.isAlikeDead() && !npc.isInsideRadius3D(obj, npc.getAggroRange()))
|
||||
{
|
||||
if (!target.isAlikeDead() && !npc.isInsideRadius3D(obj, npc.getAggroRange()))
|
||||
final PlayerInstance targetPlayer = obj instanceof PlayerInstance ? (PlayerInstance) obj : ((Summon) obj).getOwner();
|
||||
for (Quest quest : npc.getTemplate().getEventQuests(EventType.ON_AGGRO_RANGE_ENTER))
|
||||
{
|
||||
final PlayerInstance targetPlayer = obj instanceof PlayerInstance ? (PlayerInstance) obj : ((Summon) obj).getOwner();
|
||||
for (Quest quest : npc.getTemplate().getEventQuests(EventType.ON_AGGRO_RANGE_ENTER))
|
||||
{
|
||||
quest.notifyAggroRangeEnter(npc, targetPlayer, obj instanceof Summon);
|
||||
}
|
||||
quest.notifyAggroRangeEnter(npc, targetPlayer, obj instanceof Summon);
|
||||
}
|
||||
}
|
||||
|
||||
@ -555,7 +551,7 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
|
||||
// Calculate a destination point in the spawn area
|
||||
final int p[] = TerritoryTable.getInstance().getRandomPoint(npc.getSpawn().getLocation());
|
||||
final int[] p = TerritoryTable.getInstance().getRandomPoint(npc.getSpawn().getLocation());
|
||||
x1 = p[0];
|
||||
y1 = p[1];
|
||||
z1 = p[2];
|
||||
@ -565,7 +561,7 @@ public class AttackableAI extends CreatureAI
|
||||
if (distance2 > (Config.MAX_DRIFT_RANGE * Config.MAX_DRIFT_RANGE))
|
||||
{
|
||||
npc.setReturningToSpawnPoint(true);
|
||||
final float delay = (float) Math.sqrt(distance2) / Config.MAX_DRIFT_RANGE;
|
||||
final double delay = Math.sqrt(distance2) / Config.MAX_DRIFT_RANGE;
|
||||
x1 = _actor.getX() + (int) ((x1 - _actor.getX()) / delay);
|
||||
y1 = _actor.getY() + (int) ((y1 - _actor.getY()) / delay);
|
||||
}
|
||||
@ -660,17 +656,14 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
}
|
||||
|
||||
if (_attackTimeout < GameTimeTaskManager.getGameTicks())
|
||||
// Check if the actor is running
|
||||
if ((_attackTimeout < GameTimeTaskManager.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 PlayerInstance
|
||||
_actor.setWalking();
|
||||
|
||||
// Calculate a new attack timeout
|
||||
_attackTimeout = MAX_ATTACK_TIMEOUT + GameTimeTaskManager.getGameTicks();
|
||||
}
|
||||
// Set the actor movement type to walk and send Server->Client packet ChangeMoveType to all others PlayerInstance
|
||||
_actor.setWalking();
|
||||
|
||||
// Calculate a new attack timeout
|
||||
_attackTimeout = MAX_ATTACK_TIMEOUT + GameTimeTaskManager.getGameTicks();
|
||||
}
|
||||
|
||||
// Check if target is dead or if timeout is expired to stop this attack
|
||||
@ -715,33 +708,27 @@ public class AttackableAI extends CreatureAI
|
||||
// Check if the WorldObject is inside the Faction Range of the actor
|
||||
if ((_actor.getAttackByList() != null) && _actor.isInsideRadius3D(npc, npc.getFactionRange()) && (npc.getAI() != null) && _actor.getAttackByList().contains(originalAttackTarget))
|
||||
{
|
||||
if ((npc.getAI().getIntention() == AI_INTENTION_IDLE) || (npc.getAI().getIntention() == AI_INTENTION_ACTIVE))
|
||||
if (((npc.getAI().getIntention() == AI_INTENTION_IDLE) || (npc.getAI().getIntention() == AI_INTENTION_ACTIVE)) && GeoEngine.getInstance().canSeeTarget(_actor, npc) && (Math.abs(originalAttackTarget.getZ() - npc.getZ()) < 600))
|
||||
{
|
||||
if (GeoEngine.getInstance().canSeeTarget(_actor, npc) && (Math.abs(originalAttackTarget.getZ() - npc.getZ()) < 600))
|
||||
if ((originalAttackTarget instanceof PlayerInstance) && originalAttackTarget.isInParty() && originalAttackTarget.getParty().isInDimensionalRift())
|
||||
{
|
||||
if ((originalAttackTarget instanceof PlayerInstance) && originalAttackTarget.isInParty() && originalAttackTarget.getParty().isInDimensionalRift())
|
||||
final byte riftType = originalAttackTarget.getParty().getDimensionalRift().getType();
|
||||
final byte riftRoom = originalAttackTarget.getParty().getDimensionalRift().getCurrentRoom();
|
||||
if ((_actor instanceof RiftInvaderInstance) && !DimensionalRiftManager.getInstance().getRoom(riftType, riftRoom).checkIfInZone(npc.getX(), npc.getY(), npc.getZ()))
|
||||
{
|
||||
final byte riftType = originalAttackTarget.getParty().getDimensionalRift().getType();
|
||||
final byte riftRoom = originalAttackTarget.getParty().getDimensionalRift().getCurrentRoom();
|
||||
if ((_actor instanceof RiftInvaderInstance) && !DimensionalRiftManager.getInstance().getRoom(riftType, riftRoom).checkIfInZone(npc.getX(), npc.getY(), npc.getZ()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// Notify the WorldObject AI with EVT_AGGRESSION
|
||||
npc.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, originalAttackTarget, 1);
|
||||
}
|
||||
// Notify the WorldObject AI with EVT_AGGRESSION
|
||||
npc.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, originalAttackTarget, 1);
|
||||
}
|
||||
|
||||
if (GeoEngine.getInstance().canSeeTarget(_actor, npc) && (Math.abs(originalAttackTarget.getZ() - npc.getZ()) < 500))
|
||||
if (GeoEngine.getInstance().canSeeTarget(_actor, npc) && (Math.abs(originalAttackTarget.getZ() - npc.getZ()) < 500) && ((originalAttackTarget instanceof PlayerInstance) || (originalAttackTarget instanceof Summon)))
|
||||
{
|
||||
if ((originalAttackTarget instanceof PlayerInstance) || (originalAttackTarget instanceof Summon))
|
||||
final PlayerInstance player = originalAttackTarget instanceof PlayerInstance ? (PlayerInstance) originalAttackTarget : ((Summon) originalAttackTarget).getOwner();
|
||||
for (Quest quest : npc.getTemplate().getEventQuests(EventType.ON_FACTION_CALL))
|
||||
{
|
||||
final PlayerInstance player = originalAttackTarget instanceof PlayerInstance ? (PlayerInstance) originalAttackTarget : ((Summon) originalAttackTarget).getOwner();
|
||||
for (Quest quest : npc.getTemplate().getEventQuests(EventType.ON_FACTION_CALL))
|
||||
{
|
||||
quest.notifyFactionCall(npc, (NpcInstance) _actor, player, (originalAttackTarget instanceof Summon));
|
||||
}
|
||||
quest.notifyFactionCall(npc, (NpcInstance) _actor, player, (originalAttackTarget instanceof Summon));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -756,14 +743,12 @@ public class AttackableAI extends CreatureAI
|
||||
|
||||
// Get all information needed to chose between physical or magical attack
|
||||
Collection<Skill> skills = null;
|
||||
double dist2 = 0;
|
||||
int range = 0;
|
||||
|
||||
try
|
||||
{
|
||||
_actor.setTarget(originalAttackTarget);
|
||||
skills = _actor.getAllSkills();
|
||||
// dist2 = _actor.getPlanDistanceSq(originalAttackTarget.getX(), originalAttackTarget.getY());
|
||||
range = _actor.getPhysicalAttackRange() + _actor.getTemplate().getCollisionRadius() + originalAttackTarget.getTemplate().getCollisionRadius();
|
||||
}
|
||||
catch (NullPointerException e)
|
||||
@ -772,7 +757,6 @@ public class AttackableAI extends CreatureAI
|
||||
return;
|
||||
}
|
||||
|
||||
final Weapon weapon = _actor.getActiveWeaponItem();
|
||||
final int collision = _actor.getTemplate().getCollisionRadius();
|
||||
final int combinedCollision = collision + originalAttackTarget.getTemplate().getCollisionRadius();
|
||||
|
||||
@ -820,6 +804,7 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
}
|
||||
|
||||
final Weapon weapon = _actor.getActiveWeaponItem();
|
||||
if ((weapon != null) && (weapon.getItemType() == WeaponType.BOW))
|
||||
{
|
||||
// Micht: kepping this one otherwise we should do 2 sqrt
|
||||
@ -874,7 +859,7 @@ public class AttackableAI extends CreatureAI
|
||||
setAttackTarget(hated);
|
||||
}
|
||||
// We should calculate new distance cuz mob can have changed the target
|
||||
dist2 = _actor.calculateDistanceSq2D(hated);
|
||||
final double dist2 = _actor.calculateDistanceSq2D(hated);
|
||||
if (hated.isMoving())
|
||||
{
|
||||
range += 50;
|
||||
@ -899,13 +884,12 @@ public class AttackableAI extends CreatureAI
|
||||
{
|
||||
if ((sk.getSkillType() == Skill.SkillType.BUFF) || (sk.getSkillType() == Skill.SkillType.HEAL))
|
||||
{
|
||||
boolean useSkillSelf = true;
|
||||
if ((sk.getSkillType() == Skill.SkillType.HEAL) && (_actor.getCurrentHp() > (int) (_actor.getMaxHp() / 1.5)))
|
||||
{
|
||||
useSkillSelf = false;
|
||||
break;
|
||||
}
|
||||
|
||||
boolean useSkillSelf = true;
|
||||
if (sk.getSkillType() == Skill.SkillType.BUFF)
|
||||
{
|
||||
for (Effect effect : _actor.getAllEffects())
|
||||
@ -958,13 +942,12 @@ public class AttackableAI extends CreatureAI
|
||||
{
|
||||
if ((sk.getSkillType() == Skill.SkillType.BUFF) || (sk.getSkillType() == Skill.SkillType.HEAL))
|
||||
{
|
||||
useSkillSelf = true;
|
||||
if ((sk.getSkillType() == Skill.SkillType.HEAL) && (_actor.getCurrentHp() > (int) (_actor.getMaxHp() / 1.5)))
|
||||
{
|
||||
useSkillSelf = false;
|
||||
break;
|
||||
}
|
||||
|
||||
useSkillSelf = true;
|
||||
if (sk.getSkillType() == Skill.SkillType.BUFF)
|
||||
{
|
||||
for (Effect effect : _actor.getAllEffects())
|
||||
|
@ -381,12 +381,12 @@ public class ControllableMobAI extends AttackableAI
|
||||
return false;
|
||||
}
|
||||
|
||||
final Attackable me = (Attackable) _actor;
|
||||
if ((target instanceof FolkInstance) || (target instanceof DoorInstance))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final Attackable me = (Attackable) _actor;
|
||||
if (target.isAlikeDead() || !me.isInsideRadius2D(target, me.getAggroRange()) || (Math.abs(_actor.getZ() - target.getZ()) > 100))
|
||||
{
|
||||
return false;
|
||||
|
@ -132,7 +132,7 @@ public class DoorAI extends CreatureAI
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onEvtArrivedBlocked(Location blocked_at_loc)
|
||||
protected void onEvtArrivedBlocked(Location blockedAtLoc)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -185,14 +185,10 @@ public class FortSiegeGuardAI extends CreatureAI implements Runnable
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the target is a PlayerInstance
|
||||
if (currentTarget instanceof PlayerInstance)
|
||||
// Check if the target is a PlayerInstance and if the target isn't in silent move mode AND too far (>100)
|
||||
if ((currentTarget instanceof PlayerInstance) && ((PlayerInstance) currentTarget).isSilentMoving() && !_actor.isInsideRadius2D(currentTarget, 250))
|
||||
{
|
||||
// Check if the target isn't in silent move mode AND too far (>100)
|
||||
if (((PlayerInstance) currentTarget).isSilentMoving() && !_actor.isInsideRadius2D(currentTarget, 250))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Los Check Here
|
||||
@ -652,12 +648,12 @@ public class FortSiegeGuardAI extends CreatureAI implements Runnable
|
||||
final WorldObject 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;
|
||||
}
|
||||
|
||||
boolean useSkillSelf = true;
|
||||
if (sk.getSkillType() == SkillType.BUFF)
|
||||
{
|
||||
for (Effect effect : _actor.getAllEffects())
|
||||
@ -788,12 +784,12 @@ public class FortSiegeGuardAI extends CreatureAI implements Runnable
|
||||
final WorldObject 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;
|
||||
}
|
||||
|
||||
boolean useSkillSelf = true;
|
||||
if (sk.getSkillType() == SkillType.BUFF)
|
||||
{
|
||||
for (Effect effect : _actor.getAllEffects())
|
||||
|
@ -38,17 +38,17 @@ public class NpcWalkerAI extends CreatureAI implements Runnable
|
||||
/**
|
||||
* home points for xyz
|
||||
*/
|
||||
int _homeX;
|
||||
private int _homeX;
|
||||
|
||||
/**
|
||||
* home points for xyz
|
||||
*/
|
||||
int _homeY;
|
||||
private int _homeY;
|
||||
|
||||
/**
|
||||
* home points for xyz
|
||||
*/
|
||||
int _homeZ;
|
||||
private int _homeZ;
|
||||
|
||||
/**
|
||||
* route of the current npc
|
||||
|
@ -317,7 +317,6 @@ public class SiegeGuardAI extends CreatureAI implements Runnable
|
||||
Collection<Skill> skills = null;
|
||||
double dist2 = 0;
|
||||
int range = 0;
|
||||
final SiegeGuardInstance sGuard = (SiegeGuardInstance) _actor;
|
||||
final Creature attackTarget = getAttackTarget();
|
||||
|
||||
try
|
||||
@ -335,6 +334,7 @@ public class SiegeGuardAI extends CreatureAI implements Runnable
|
||||
}
|
||||
|
||||
// never attack defenders
|
||||
final SiegeGuardInstance sGuard = (SiegeGuardInstance) _actor;
|
||||
if ((attackTarget instanceof PlayerInstance) && sGuard.getCastle().getSiege().checkIsDefender(((PlayerInstance) attackTarget).getClan()))
|
||||
{
|
||||
// Cancel the target
|
||||
@ -367,12 +367,12 @@ public class SiegeGuardAI extends CreatureAI implements Runnable
|
||||
{
|
||||
if ((sk.getSkillType() == Skill.SkillType.BUFF) || (sk.getSkillType() == Skill.SkillType.HEAL))
|
||||
{
|
||||
boolean useSkillSelf = true;
|
||||
if (((sk.getSkillType() == Skill.SkillType.BUFF) || (sk.getSkillType() == Skill.SkillType.HEAL) || ((dist2 >= ((castRange * castRange) / 9)) && (dist2 <= (castRange * castRange)) && (castRange > 70))) && !_actor.isSkillDisabled(sk) && (_actor.getCurrentMp() >= _actor.getStat().getMpConsume(sk)) && !sk.isPassive())
|
||||
{
|
||||
useSkillSelf = false;
|
||||
break;
|
||||
}
|
||||
|
||||
boolean useSkillSelf = true;
|
||||
if (sk.getSkillType() == Skill.SkillType.BUFF)
|
||||
{
|
||||
for (Effect effect : _actor.getAllEffects())
|
||||
@ -481,13 +481,12 @@ public class SiegeGuardAI extends CreatureAI implements Runnable
|
||||
{
|
||||
if ((sk.getSkillType() == Skill.SkillType.BUFF) || (sk.getSkillType() == Skill.SkillType.HEAL))
|
||||
{
|
||||
boolean useSkillSelf = true;
|
||||
if ((sk.getSkillType() == Skill.SkillType.HEAL) && (_actor.getCurrentHp() > (int) (_actor.getMaxHp() / 1.5)))
|
||||
{
|
||||
useSkillSelf = false;
|
||||
break;
|
||||
}
|
||||
|
||||
boolean useSkillSelf = true;
|
||||
if (sk.getSkillType() == Skill.SkillType.BUFF)
|
||||
{
|
||||
for (Effect effect : _actor.getAllEffects())
|
||||
|
@ -85,7 +85,6 @@ public class SummonAI extends CreatureAI
|
||||
|
||||
private void thinkCast()
|
||||
{
|
||||
final Summon summon = (Summon) _actor;
|
||||
final Creature target = getCastTarget();
|
||||
if (checkTargetLost(target))
|
||||
{
|
||||
@ -99,6 +98,7 @@ public class SummonAI extends CreatureAI
|
||||
}
|
||||
|
||||
clientStopMoving(null);
|
||||
final Summon summon = (Summon) _actor;
|
||||
summon.setFollowStatus(false);
|
||||
setIntention(AI_INTENTION_IDLE);
|
||||
_accessor.doCast(skill);
|
||||
|
@ -71,7 +71,7 @@ public abstract class AbstractAI implements Ctrl
|
||||
protected Creature _followTarget;
|
||||
|
||||
/** The skill we are currently casting by INTENTION_CAST */
|
||||
Skill _skill;
|
||||
protected Skill _skill;
|
||||
|
||||
/** Different internal state flags */
|
||||
private int _moveToPawnTimeout;
|
||||
|
@ -171,8 +171,6 @@ public class AttackableAI extends CreatureAI
|
||||
return false;
|
||||
}
|
||||
|
||||
final Attackable me = getActiveChar();
|
||||
|
||||
// Check if the target isn't invulnerable
|
||||
if (target.isInvul())
|
||||
{
|
||||
@ -195,6 +193,7 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
|
||||
// Check if the target isn't dead, is in the Aggro range and is at the same height
|
||||
final Attackable me = getActiveChar();
|
||||
if (target.isAlikeDead() || (target.isPlayable() && !me.isInsideRadius3D(target, me.getAggroRange())))
|
||||
{
|
||||
return false;
|
||||
@ -682,10 +681,7 @@ public class AttackableAI extends CreatureAI
|
||||
// Order to the MonsterInstance to random walk (1/100)
|
||||
else if ((npc.getSpawn() != null) && (Rnd.get(RANDOM_WALK_RATE) == 0) && npc.isRandomWalkingEnabled())
|
||||
{
|
||||
int x1 = 0;
|
||||
int y1 = 0;
|
||||
int z1 = 0;
|
||||
final int range = Config.MAX_DRIFT_RANGE;
|
||||
|
||||
for (Skill sk : npc.getTemplate().getAISkills(AISkillScope.BUFF))
|
||||
{
|
||||
if (cast(sk))
|
||||
@ -694,9 +690,10 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
}
|
||||
|
||||
x1 = npc.getSpawn().getX();
|
||||
y1 = npc.getSpawn().getY();
|
||||
z1 = npc.getSpawn().getZ();
|
||||
int x1 = npc.getSpawn().getX();
|
||||
int y1 = npc.getSpawn().getY();
|
||||
int z1 = npc.getSpawn().getZ();
|
||||
final int range = Config.MAX_DRIFT_RANGE;
|
||||
if (!npc.isInsideRadius2D(x1, y1, 0, range))
|
||||
{
|
||||
npc.setReturningToSpawnPoint(true);
|
||||
@ -919,7 +916,6 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
|
||||
// Initialize data
|
||||
final int combinedCollision = collision + mostHate.getTemplate().getCollisionRadius();
|
||||
final List<Skill> aiSuicideSkills = npc.getTemplate().getAISkills(AISkillScope.SUICIDE);
|
||||
if (!aiSuicideSkills.isEmpty() && ((int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100) < 30))
|
||||
{
|
||||
@ -935,6 +931,7 @@ public class AttackableAI extends CreatureAI
|
||||
// Note from Gnacik:
|
||||
// On l2js because of that sometimes mobs don't attack player only running
|
||||
// around player without any sense, so decrease chance for now
|
||||
final int combinedCollision = collision + mostHate.getTemplate().getCollisionRadius();
|
||||
if (!npc.isMovementDisabled() && (Rnd.get(100) <= 3))
|
||||
{
|
||||
for (Attackable nearby : World.getInstance().getVisibleObjects(npc, Attackable.class))
|
||||
@ -1048,7 +1045,6 @@ public class AttackableAI extends CreatureAI
|
||||
final List<Skill> aiHealSkills = npc.getTemplate().getAISkills(AISkillScope.HEAL);
|
||||
if (!aiHealSkills.isEmpty())
|
||||
{
|
||||
double percentage = (npc.getCurrentHp() / npc.getMaxHp()) * 100;
|
||||
if (npc.isMinion())
|
||||
{
|
||||
final Creature leader = npc.getLeader();
|
||||
@ -1086,6 +1082,7 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
}
|
||||
|
||||
double percentage = (npc.getCurrentHp() / npc.getMaxHp()) * 100;
|
||||
if (Rnd.get(100) < ((100 - percentage) / 3))
|
||||
{
|
||||
for (Skill sk : aiHealSkills)
|
||||
@ -1329,7 +1326,6 @@ public class AttackableAI extends CreatureAI
|
||||
|
||||
final double dist = caster.calculateDistance2D(attackTarget);
|
||||
double dist2 = dist - attackTarget.getTemplate().getCollisionRadius();
|
||||
final double range = caster.getPhysicalAttackRange() + caster.getTemplate().getCollisionRadius() + attackTarget.getTemplate().getCollisionRadius();
|
||||
final double srange = sk.getCastRange() + caster.getTemplate().getCollisionRadius();
|
||||
if (attackTarget.isMoving())
|
||||
{
|
||||
@ -1452,7 +1448,6 @@ public class AttackableAI extends CreatureAI
|
||||
|
||||
if (sk.hasEffectType(EffectType.HEAL))
|
||||
{
|
||||
double percentage = (caster.getCurrentHp() / caster.getMaxHp()) * 100;
|
||||
if (caster.isMinion() && (sk.getTargetType() != TargetType.SELF))
|
||||
{
|
||||
final Creature leader = caster.getLeader();
|
||||
@ -1473,6 +1468,7 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
}
|
||||
|
||||
double percentage = (caster.getCurrentHp() / caster.getMaxHp()) * 100;
|
||||
if (Rnd.get(100) < ((100 - percentage) / 3))
|
||||
{
|
||||
clientStopMoving(null);
|
||||
@ -1556,6 +1552,7 @@ public class AttackableAI extends CreatureAI
|
||||
{
|
||||
if (sk.getTargetType() == TargetType.ONE)
|
||||
{
|
||||
final double range = caster.getPhysicalAttackRange() + caster.getTemplate().getCollisionRadius() + attackTarget.getTemplate().getCollisionRadius();
|
||||
if (!attackTarget.isDead() && (dist2 <= srange) && ((dist2 > range) || attackTarget.isMoving()) && !attackTarget.isAffectedBySkill(sk.getId()))
|
||||
{
|
||||
clientStopMoving(null);
|
||||
@ -1756,20 +1753,19 @@ public class AttackableAI extends CreatureAI
|
||||
|
||||
private void movementDisable()
|
||||
{
|
||||
final Attackable npc = getActiveChar();
|
||||
final Creature target = getAttackTarget();
|
||||
if (target == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Attackable npc = getActiveChar();
|
||||
if (npc.getTarget() == null)
|
||||
{
|
||||
npc.setTarget(target);
|
||||
}
|
||||
|
||||
final double dist = npc.calculateDistance2D(target);
|
||||
final int range = npc.getPhysicalAttackRange() + npc.getTemplate().getCollisionRadius() + target.getTemplate().getCollisionRadius();
|
||||
|
||||
// TODO(Zoey76): Review this "magic changes".
|
||||
final int random = Rnd.get(100);
|
||||
@ -1804,6 +1800,7 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
|
||||
// If cannot cast, try to attack.
|
||||
final int range = npc.getPhysicalAttackRange() + npc.getTemplate().getCollisionRadius() + target.getTemplate().getCollisionRadius();
|
||||
if ((dist <= range) && GeoEngine.getInstance().canSeeTarget(npc, target))
|
||||
{
|
||||
_actor.doAttack(target);
|
||||
@ -2107,6 +2104,7 @@ public class AttackableAI extends CreatureAI
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
dist = actor.calculateDistance2D(obj);
|
||||
|
@ -135,7 +135,6 @@ public class ControllableMobAI extends AttackableAI
|
||||
@Override
|
||||
protected void thinkCast()
|
||||
{
|
||||
final Attackable npc = (Attackable) _actor;
|
||||
if ((getAttackTarget() == null) || getAttackTarget().isAlikeDead())
|
||||
{
|
||||
setAttackTarget(findNextRndTarget());
|
||||
@ -147,6 +146,7 @@ public class ControllableMobAI extends AttackableAI
|
||||
return;
|
||||
}
|
||||
|
||||
final Attackable npc = (Attackable) _actor;
|
||||
npc.setTarget(getAttackTarget());
|
||||
|
||||
if (_actor.isMuted())
|
||||
|
@ -133,7 +133,7 @@ public class DoorAI extends CreatureAI
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onEvtArrivedBlocked(Location blocked_at_loc)
|
||||
protected void onEvtArrivedBlocked(Location blockedAtLoc)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -447,7 +447,6 @@ public class FortSiegeGuardAI extends CreatureAI implements Runnable
|
||||
Collection<Skill> skills = null;
|
||||
double dist2 = 0;
|
||||
int range = 0;
|
||||
final DefenderInstance sGuard = _actor instanceof FortCommanderInstance ? (FortCommanderInstance) _actor : (DefenderInstance) _actor;
|
||||
Creature attackTarget = getAttackTarget();
|
||||
try
|
||||
{
|
||||
@ -468,6 +467,7 @@ public class FortSiegeGuardAI extends CreatureAI implements Runnable
|
||||
}
|
||||
|
||||
// never attack defenders
|
||||
final DefenderInstance sGuard = _actor instanceof FortCommanderInstance ? (FortCommanderInstance) _actor : (DefenderInstance) _actor;
|
||||
if (attackTarget.isPlayer() && sGuard.getFort().getSiege().checkIsDefender(((PlayerInstance) attackTarget).getClan()))
|
||||
{
|
||||
// Cancel the target
|
||||
@ -489,13 +489,12 @@ public class FortSiegeGuardAI extends CreatureAI implements Runnable
|
||||
final WorldObject oldTarget = _actor.getTarget();
|
||||
if ((sk.isContinuous() && !sk.isDebuff()) || sk.hasEffectType(EffectType.HEAL))
|
||||
{
|
||||
boolean useSkillSelf = true;
|
||||
if (sk.hasEffectType(EffectType.HEAL) && (_actor.getCurrentHp() > (int) (_actor.getMaxHp() / 1.5)))
|
||||
{
|
||||
useSkillSelf = false;
|
||||
break;
|
||||
}
|
||||
|
||||
boolean useSkillSelf = true;
|
||||
if (sk.isContinuous() && !sk.isDebuff() && _actor.isAffectedBySkill(sk.getId()))
|
||||
{
|
||||
useSkillSelf = false;
|
||||
@ -600,13 +599,12 @@ public class FortSiegeGuardAI extends CreatureAI implements Runnable
|
||||
final WorldObject oldTarget = _actor.getTarget();
|
||||
if ((sk.isContinuous() && !sk.isDebuff()) || sk.hasEffectType(EffectType.HEAL))
|
||||
{
|
||||
boolean useSkillSelf = true;
|
||||
if (sk.hasEffectType(EffectType.HEAL) && (_actor.getCurrentHp() > (int) (_actor.getMaxHp() / 1.5)))
|
||||
{
|
||||
useSkillSelf = false;
|
||||
break;
|
||||
}
|
||||
|
||||
boolean useSkillSelf = true;
|
||||
if (sk.isContinuous() && !sk.isDebuff() && _actor.isAffectedBySkill(sk.getId()))
|
||||
{
|
||||
useSkillSelf = false;
|
||||
|
@ -32,7 +32,7 @@ import org.l2jmobius.gameserver.network.SystemMessageId;
|
||||
*/
|
||||
public abstract class PlayableAI extends CreatureAI
|
||||
{
|
||||
public PlayableAI(Playable playable)
|
||||
protected PlayableAI(Playable playable)
|
||||
{
|
||||
super(playable);
|
||||
}
|
||||
|
@ -436,7 +436,6 @@ public class SiegeGuardAI extends CreatureAI implements Runnable
|
||||
Collection<Skill> skills = null;
|
||||
double dist2 = 0;
|
||||
int range = 0;
|
||||
final DefenderInstance sGuard = (DefenderInstance) _actor;
|
||||
Creature attackTarget = getAttackTarget();
|
||||
|
||||
try
|
||||
@ -458,6 +457,7 @@ public class SiegeGuardAI extends CreatureAI implements Runnable
|
||||
}
|
||||
|
||||
// never attack defenders
|
||||
final DefenderInstance sGuard = (DefenderInstance) _actor;
|
||||
if (attackTarget.isPlayer() && (sGuard.getConquerableHall() == null) && sGuard.getCastle().getSiege().checkIsDefender(((PlayerInstance) attackTarget).getClan()))
|
||||
{
|
||||
// Cancel the target
|
||||
@ -489,13 +489,12 @@ public class SiegeGuardAI extends CreatureAI implements Runnable
|
||||
final WorldObject oldTarget = _actor.getTarget();
|
||||
if ((sk.isContinuous() && !sk.isDebuff()) || sk.hasEffectType(EffectType.HEAL))
|
||||
{
|
||||
boolean useSkillSelf = true;
|
||||
if (sk.hasEffectType(EffectType.HEAL) && (_actor.getCurrentHp() > (int) (_actor.getMaxHp() / 1.5)))
|
||||
{
|
||||
useSkillSelf = false;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
boolean useSkillSelf = true;
|
||||
if (sk.isContinuous() && !sk.isDebuff() && _actor.isAffectedBySkill(sk.getId()))
|
||||
{
|
||||
useSkillSelf = false;
|
||||
@ -596,13 +595,12 @@ public class SiegeGuardAI extends CreatureAI implements Runnable
|
||||
final WorldObject oldTarget = _actor.getTarget();
|
||||
if ((sk.isContinuous() && !sk.isDebuff()) || sk.hasEffectType(EffectType.HEAL))
|
||||
{
|
||||
boolean useSkillSelf = true;
|
||||
if (sk.hasEffectType(EffectType.HEAL) && (_actor.getCurrentHp() > (int) (_actor.getMaxHp() / 1.5)))
|
||||
{
|
||||
useSkillSelf = false;
|
||||
break;
|
||||
}
|
||||
|
||||
boolean useSkillSelf = true;
|
||||
if (sk.isContinuous() && !sk.isDebuff() && _actor.isAffectedBySkill(sk.getId()))
|
||||
{
|
||||
useSkillSelf = false;
|
||||
|
@ -118,7 +118,6 @@ public class SummonAI extends PlayableAI implements Runnable
|
||||
|
||||
private void thinkCast()
|
||||
{
|
||||
final Summon summon = (Summon) _actor;
|
||||
if (checkTargetLost(getCastTarget()))
|
||||
{
|
||||
setCastTarget(null);
|
||||
@ -132,6 +131,7 @@ public class SummonAI extends PlayableAI implements Runnable
|
||||
}
|
||||
|
||||
clientStopMoving(null);
|
||||
final Summon summon = (Summon) _actor;
|
||||
summon.setFollowStatus(false);
|
||||
setIntention(AI_INTENTION_IDLE);
|
||||
_startFollow = val;
|
||||
|
@ -30,7 +30,7 @@ public abstract class VehicleAI extends CreatureAI
|
||||
* Simple AI for vehicles
|
||||
* @param vehicle
|
||||
*/
|
||||
public VehicleAI(Vehicle vehicle)
|
||||
protected VehicleAI(Vehicle vehicle)
|
||||
{
|
||||
super(vehicle);
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ public abstract class AbstractAI implements Ctrl
|
||||
protected Creature _followTarget;
|
||||
|
||||
/** The skill we are currently casting by INTENTION_CAST */
|
||||
Skill _skill;
|
||||
protected Skill _skill;
|
||||
|
||||
/** Different internal state flags */
|
||||
private int _moveToPawnTimeout;
|
||||
|
@ -171,8 +171,6 @@ public class AttackableAI extends CreatureAI
|
||||
return false;
|
||||
}
|
||||
|
||||
final Attackable me = getActiveChar();
|
||||
|
||||
// Check if the target isn't invulnerable
|
||||
if (target.isInvul())
|
||||
{
|
||||
@ -195,6 +193,7 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
|
||||
// Check if the target isn't dead, is in the Aggro range and is at the same height
|
||||
final Attackable me = getActiveChar();
|
||||
if (target.isAlikeDead() || (target.isPlayable() && !me.isInsideRadius3D(target, me.getAggroRange())))
|
||||
{
|
||||
return false;
|
||||
@ -682,10 +681,7 @@ public class AttackableAI extends CreatureAI
|
||||
// Order to the MonsterInstance to random walk (1/100)
|
||||
else if ((npc.getSpawn() != null) && (Rnd.get(RANDOM_WALK_RATE) == 0) && npc.isRandomWalkingEnabled())
|
||||
{
|
||||
int x1 = 0;
|
||||
int y1 = 0;
|
||||
int z1 = 0;
|
||||
final int range = Config.MAX_DRIFT_RANGE;
|
||||
|
||||
for (Skill sk : npc.getTemplate().getAISkills(AISkillScope.BUFF))
|
||||
{
|
||||
if (cast(sk))
|
||||
@ -694,9 +690,10 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
}
|
||||
|
||||
x1 = npc.getSpawn().getX();
|
||||
y1 = npc.getSpawn().getY();
|
||||
z1 = npc.getSpawn().getZ();
|
||||
int x1 = npc.getSpawn().getX();
|
||||
int y1 = npc.getSpawn().getY();
|
||||
int z1 = npc.getSpawn().getZ();
|
||||
final int range = Config.MAX_DRIFT_RANGE;
|
||||
if (!npc.isInsideRadius2D(x1, y1, 0, range))
|
||||
{
|
||||
npc.setReturningToSpawnPoint(true);
|
||||
@ -919,7 +916,6 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
|
||||
// Initialize data
|
||||
final int combinedCollision = collision + mostHate.getTemplate().getCollisionRadius();
|
||||
final List<Skill> aiSuicideSkills = npc.getTemplate().getAISkills(AISkillScope.SUICIDE);
|
||||
if (!aiSuicideSkills.isEmpty() && ((int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100) < 30))
|
||||
{
|
||||
@ -935,6 +931,7 @@ public class AttackableAI extends CreatureAI
|
||||
// Note from Gnacik:
|
||||
// On l2js because of that sometimes mobs don't attack player only running
|
||||
// around player without any sense, so decrease chance for now
|
||||
final int combinedCollision = collision + mostHate.getTemplate().getCollisionRadius();
|
||||
if (!npc.isMovementDisabled() && (Rnd.get(100) <= 3))
|
||||
{
|
||||
for (Attackable nearby : World.getInstance().getVisibleObjects(npc, Attackable.class))
|
||||
@ -1048,7 +1045,6 @@ public class AttackableAI extends CreatureAI
|
||||
final List<Skill> aiHealSkills = npc.getTemplate().getAISkills(AISkillScope.HEAL);
|
||||
if (!aiHealSkills.isEmpty())
|
||||
{
|
||||
double percentage = (npc.getCurrentHp() / npc.getMaxHp()) * 100;
|
||||
if (npc.isMinion())
|
||||
{
|
||||
final Creature leader = npc.getLeader();
|
||||
@ -1086,6 +1082,7 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
}
|
||||
|
||||
double percentage = (npc.getCurrentHp() / npc.getMaxHp()) * 100;
|
||||
if (Rnd.get(100) < ((100 - percentage) / 3))
|
||||
{
|
||||
for (Skill sk : aiHealSkills)
|
||||
@ -1329,7 +1326,6 @@ public class AttackableAI extends CreatureAI
|
||||
|
||||
final double dist = caster.calculateDistance2D(attackTarget);
|
||||
double dist2 = dist - attackTarget.getTemplate().getCollisionRadius();
|
||||
final double range = caster.getPhysicalAttackRange() + caster.getTemplate().getCollisionRadius() + attackTarget.getTemplate().getCollisionRadius();
|
||||
final double srange = sk.getCastRange() + caster.getTemplate().getCollisionRadius();
|
||||
if (attackTarget.isMoving())
|
||||
{
|
||||
@ -1452,7 +1448,6 @@ public class AttackableAI extends CreatureAI
|
||||
|
||||
if (sk.hasEffectType(EffectType.HEAL))
|
||||
{
|
||||
double percentage = (caster.getCurrentHp() / caster.getMaxHp()) * 100;
|
||||
if (caster.isMinion() && (sk.getTargetType() != TargetType.SELF))
|
||||
{
|
||||
final Creature leader = caster.getLeader();
|
||||
@ -1473,6 +1468,7 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
}
|
||||
|
||||
double percentage = (caster.getCurrentHp() / caster.getMaxHp()) * 100;
|
||||
if (Rnd.get(100) < ((100 - percentage) / 3))
|
||||
{
|
||||
clientStopMoving(null);
|
||||
@ -1556,6 +1552,7 @@ public class AttackableAI extends CreatureAI
|
||||
{
|
||||
if (sk.getTargetType() == TargetType.ONE)
|
||||
{
|
||||
final double range = caster.getPhysicalAttackRange() + caster.getTemplate().getCollisionRadius() + attackTarget.getTemplate().getCollisionRadius();
|
||||
if (!attackTarget.isDead() && (dist2 <= srange) && ((dist2 > range) || attackTarget.isMoving()) && !attackTarget.isAffectedBySkill(sk.getId()))
|
||||
{
|
||||
clientStopMoving(null);
|
||||
@ -1756,20 +1753,19 @@ public class AttackableAI extends CreatureAI
|
||||
|
||||
private void movementDisable()
|
||||
{
|
||||
final Attackable npc = getActiveChar();
|
||||
final Creature target = getAttackTarget();
|
||||
if (target == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Attackable npc = getActiveChar();
|
||||
if (npc.getTarget() == null)
|
||||
{
|
||||
npc.setTarget(target);
|
||||
}
|
||||
|
||||
final double dist = npc.calculateDistance2D(target);
|
||||
final int range = npc.getPhysicalAttackRange() + npc.getTemplate().getCollisionRadius() + target.getTemplate().getCollisionRadius();
|
||||
|
||||
// TODO(Zoey76): Review this "magic changes".
|
||||
final int random = Rnd.get(100);
|
||||
@ -1804,6 +1800,7 @@ public class AttackableAI extends CreatureAI
|
||||
}
|
||||
|
||||
// If cannot cast, try to attack.
|
||||
final int range = npc.getPhysicalAttackRange() + npc.getTemplate().getCollisionRadius() + target.getTemplate().getCollisionRadius();
|
||||
if ((dist <= range) && GeoEngine.getInstance().canSeeTarget(npc, target))
|
||||
{
|
||||
_actor.doAttack(target);
|
||||
@ -2107,6 +2104,7 @@ public class AttackableAI extends CreatureAI
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
dist = actor.calculateDistance2D(obj);
|
||||
|
@ -135,7 +135,6 @@ public class ControllableMobAI extends AttackableAI
|
||||
@Override
|
||||
protected void thinkCast()
|
||||
{
|
||||
final Attackable npc = (Attackable) _actor;
|
||||
if ((getAttackTarget() == null) || getAttackTarget().isAlikeDead())
|
||||
{
|
||||
setAttackTarget(findNextRndTarget());
|
||||
@ -147,6 +146,7 @@ public class ControllableMobAI extends AttackableAI
|
||||
return;
|
||||
}
|
||||
|
||||
final Attackable npc = (Attackable) _actor;
|
||||
npc.setTarget(getAttackTarget());
|
||||
|
||||
if (_actor.isMuted())
|
||||
|
@ -133,7 +133,7 @@ public class DoorAI extends CreatureAI
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onEvtArrivedBlocked(Location blocked_at_loc)
|
||||
protected void onEvtArrivedBlocked(Location blockedAtLoc)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -447,7 +447,6 @@ public class FortSiegeGuardAI extends CreatureAI implements Runnable
|
||||
Collection<Skill> skills = null;
|
||||
double dist2 = 0;
|
||||
int range = 0;
|
||||
final DefenderInstance sGuard = _actor instanceof FortCommanderInstance ? (FortCommanderInstance) _actor : (DefenderInstance) _actor;
|
||||
Creature attackTarget = getAttackTarget();
|
||||
try
|
||||
{
|
||||
@ -468,6 +467,7 @@ public class FortSiegeGuardAI extends CreatureAI implements Runnable
|
||||
}
|
||||
|
||||
// never attack defenders
|
||||
final DefenderInstance sGuard = _actor instanceof FortCommanderInstance ? (FortCommanderInstance) _actor : (DefenderInstance) _actor;
|
||||
if (attackTarget.isPlayer() && sGuard.getFort().getSiege().checkIsDefender(((PlayerInstance) attackTarget).getClan()))
|
||||
{
|
||||
// Cancel the target
|
||||
@ -489,13 +489,12 @@ public class FortSiegeGuardAI extends CreatureAI implements Runnable
|
||||
final WorldObject oldTarget = _actor.getTarget();
|
||||
if ((sk.isContinuous() && !sk.isDebuff()) || sk.hasEffectType(EffectType.HEAL))
|
||||
{
|
||||
boolean useSkillSelf = true;
|
||||
if (sk.hasEffectType(EffectType.HEAL) && (_actor.getCurrentHp() > (int) (_actor.getMaxHp() / 1.5)))
|
||||
{
|
||||
useSkillSelf = false;
|
||||
break;
|
||||
}
|
||||
|
||||
boolean useSkillSelf = true;
|
||||
if (sk.isContinuous() && !sk.isDebuff() && _actor.isAffectedBySkill(sk.getId()))
|
||||
{
|
||||
useSkillSelf = false;
|
||||
@ -600,13 +599,12 @@ public class FortSiegeGuardAI extends CreatureAI implements Runnable
|
||||
final WorldObject oldTarget = _actor.getTarget();
|
||||
if ((sk.isContinuous() && !sk.isDebuff()) || sk.hasEffectType(EffectType.HEAL))
|
||||
{
|
||||
boolean useSkillSelf = true;
|
||||
if (sk.hasEffectType(EffectType.HEAL) && (_actor.getCurrentHp() > (int) (_actor.getMaxHp() / 1.5)))
|
||||
{
|
||||
useSkillSelf = false;
|
||||
break;
|
||||
}
|
||||
|
||||
boolean useSkillSelf = true;
|
||||
if (sk.isContinuous() && !sk.isDebuff() && _actor.isAffectedBySkill(sk.getId()))
|
||||
{
|
||||
useSkillSelf = false;
|
||||
|
@ -32,7 +32,7 @@ import org.l2jmobius.gameserver.network.SystemMessageId;
|
||||
*/
|
||||
public abstract class PlayableAI extends CreatureAI
|
||||
{
|
||||
public PlayableAI(Playable playable)
|
||||
protected PlayableAI(Playable playable)
|
||||
{
|
||||
super(playable);
|
||||
}
|
||||
|
@ -436,7 +436,6 @@ public class SiegeGuardAI extends CreatureAI implements Runnable
|
||||
Collection<Skill> skills = null;
|
||||
double dist2 = 0;
|
||||
int range = 0;
|
||||
final DefenderInstance sGuard = (DefenderInstance) _actor;
|
||||
Creature attackTarget = getAttackTarget();
|
||||
|
||||
try
|
||||
@ -458,6 +457,7 @@ public class SiegeGuardAI extends CreatureAI implements Runnable
|
||||
}
|
||||
|
||||
// never attack defenders
|
||||
final DefenderInstance sGuard = (DefenderInstance) _actor;
|
||||
if (attackTarget.isPlayer() && (sGuard.getConquerableHall() == null) && sGuard.getCastle().getSiege().checkIsDefender(((PlayerInstance) attackTarget).getClan()))
|
||||
{
|
||||
// Cancel the target
|
||||
@ -489,13 +489,12 @@ public class SiegeGuardAI extends CreatureAI implements Runnable
|
||||
final WorldObject oldTarget = _actor.getTarget();
|
||||
if ((sk.isContinuous() && !sk.isDebuff()) || sk.hasEffectType(EffectType.HEAL))
|
||||
{
|
||||
boolean useSkillSelf = true;
|
||||
if (sk.hasEffectType(EffectType.HEAL) && (_actor.getCurrentHp() > (int) (_actor.getMaxHp() / 1.5)))
|
||||
{
|
||||
useSkillSelf = false;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
boolean useSkillSelf = true;
|
||||
if (sk.isContinuous() && !sk.isDebuff() && _actor.isAffectedBySkill(sk.getId()))
|
||||
{
|
||||
useSkillSelf = false;
|
||||
@ -596,13 +595,12 @@ public class SiegeGuardAI extends CreatureAI implements Runnable
|
||||
final WorldObject oldTarget = _actor.getTarget();
|
||||
if ((sk.isContinuous() && !sk.isDebuff()) || sk.hasEffectType(EffectType.HEAL))
|
||||
{
|
||||
boolean useSkillSelf = true;
|
||||
if (sk.hasEffectType(EffectType.HEAL) && (_actor.getCurrentHp() > (int) (_actor.getMaxHp() / 1.5)))
|
||||
{
|
||||
useSkillSelf = false;
|
||||
break;
|
||||
}
|
||||
|
||||
boolean useSkillSelf = true;
|
||||
if (sk.isContinuous() && !sk.isDebuff() && _actor.isAffectedBySkill(sk.getId()))
|
||||
{
|
||||
useSkillSelf = false;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user