|
@@ -34,6 +34,7 @@ import com.l2jserver.gameserver.GeoData;
|
|
import com.l2jserver.gameserver.ThreadPoolManager;
|
|
import com.l2jserver.gameserver.ThreadPoolManager;
|
|
import com.l2jserver.gameserver.datatables.NpcData;
|
|
import com.l2jserver.gameserver.datatables.NpcData;
|
|
import com.l2jserver.gameserver.datatables.TerritoryTable;
|
|
import com.l2jserver.gameserver.datatables.TerritoryTable;
|
|
|
|
+import com.l2jserver.gameserver.enums.AISkillScope;
|
|
import com.l2jserver.gameserver.enums.AIType;
|
|
import com.l2jserver.gameserver.enums.AIType;
|
|
import com.l2jserver.gameserver.enums.QuestEventType;
|
|
import com.l2jserver.gameserver.enums.QuestEventType;
|
|
import com.l2jserver.gameserver.instancemanager.DimensionalRiftManager;
|
|
import com.l2jserver.gameserver.instancemanager.DimensionalRiftManager;
|
|
@@ -396,7 +397,7 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
|
|
// self and buffs
|
|
// self and buffs
|
|
if ((lastBuffTick + 30) < GameTimeController.getInstance().getGameTicks())
|
|
if ((lastBuffTick + 30) < GameTimeController.getInstance().getGameTicks())
|
|
{
|
|
{
|
|
- for (L2Skill sk : _skillrender.getBuffSkills())
|
|
|
|
|
|
+ for (L2Skill sk : _skillrender.getAISkills(AISkillScope.BUFF))
|
|
{
|
|
{
|
|
if (cast(sk))
|
|
if (cast(sk))
|
|
{
|
|
{
|
|
@@ -637,7 +638,7 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
|
|
}
|
|
}
|
|
else if (Rnd.nextInt(RANDOM_WALK_RATE) == 0)
|
|
else if (Rnd.nextInt(RANDOM_WALK_RATE) == 0)
|
|
{
|
|
{
|
|
- for (L2Skill sk : _skillrender.getBuffSkills())
|
|
|
|
|
|
+ for (L2Skill sk : _skillrender.getAISkills(AISkillScope.BUFF))
|
|
{
|
|
{
|
|
if (cast(sk))
|
|
if (cast(sk))
|
|
{
|
|
{
|
|
@@ -652,7 +653,7 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
|
|
int x1, y1, z1;
|
|
int x1, y1, z1;
|
|
final int range = Config.MAX_DRIFT_RANGE;
|
|
final int range = Config.MAX_DRIFT_RANGE;
|
|
|
|
|
|
- for (L2Skill sk : _skillrender.getBuffSkills())
|
|
|
|
|
|
+ for (L2Skill sk : _skillrender.getAISkills(AISkillScope.BUFF))
|
|
{
|
|
{
|
|
if (cast(sk))
|
|
if (cast(sk))
|
|
{
|
|
{
|
|
@@ -834,9 +835,10 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
|
|
|
|
|
|
final int combinedCollision = collision + mostHate.getTemplate().getCollisionRadius();
|
|
final int combinedCollision = collision + mostHate.getTemplate().getCollisionRadius();
|
|
|
|
|
|
- if (!_skillrender.getSuicideSkills().isEmpty() && ((int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100) < 30))
|
|
|
|
|
|
+ List<L2Skill> aiSuicideSkills = _skillrender.getAISkills(AISkillScope.SUICIDE);
|
|
|
|
+ if (!aiSuicideSkills.isEmpty() && ((int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100) < 30))
|
|
{
|
|
{
|
|
- final L2Skill skill = _skillrender.getSuicideSkills().get(Rnd.nextInt(_skillrender.getSuicideSkills().size()));
|
|
|
|
|
|
+ final L2Skill skill = aiSuicideSkills.get(Rnd.nextInt(aiSuicideSkills.size()));
|
|
if (Util.checkIfInRange(skill.getAffectRange(), getActiveChar(), mostHate, false) && (Rnd.get(100) < Rnd.get(npc.getMinSkillChance(), npc.getMaxSkillChance())))
|
|
if (Util.checkIfInRange(skill.getAffectRange(), getActiveChar(), mostHate, false) && (Rnd.get(100) < Rnd.get(npc.getMinSkillChance(), npc.getMaxSkillChance())))
|
|
{
|
|
{
|
|
if (cast(skill))
|
|
if (cast(skill))
|
|
@@ -844,7 +846,7 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- for (L2Skill sk : _skillrender.getSuicideSkills())
|
|
|
|
|
|
+ for (L2Skill sk : aiSuicideSkills)
|
|
{
|
|
{
|
|
if (cast(sk))
|
|
if (cast(sk))
|
|
{
|
|
{
|
|
@@ -996,11 +998,12 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- if (!_skillrender.getGeneralskills().isEmpty())
|
|
|
|
|
|
+ if (!_skillrender.getAISkills(AISkillScope.GENERAL).isEmpty())
|
|
{
|
|
{
|
|
// -------------------------------------------------------------------------------
|
|
// -------------------------------------------------------------------------------
|
|
// Heal Condition
|
|
// Heal Condition
|
|
- if (!_skillrender.getHealSkills().isEmpty())
|
|
|
|
|
|
+ List<L2Skill> aiHealSkills = _skillrender.getAISkills(AISkillScope.HEAL);
|
|
|
|
+ if (!aiHealSkills.isEmpty())
|
|
{
|
|
{
|
|
double percentage = (npc.getCurrentHp() / npc.getMaxHp()) * 100;
|
|
double percentage = (npc.getCurrentHp() / npc.getMaxHp()) * 100;
|
|
if (npc.isMinion())
|
|
if (npc.isMinion())
|
|
@@ -1008,7 +1011,7 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
|
|
L2Character leader = npc.getLeader();
|
|
L2Character leader = npc.getLeader();
|
|
if ((leader != null) && !leader.isDead() && (Rnd.get(100) > ((leader.getCurrentHp() / leader.getMaxHp()) * 100)))
|
|
if ((leader != null) && !leader.isDead() && (Rnd.get(100) > ((leader.getCurrentHp() / leader.getMaxHp()) * 100)))
|
|
{
|
|
{
|
|
- for (L2Skill sk : _skillrender.getHealSkills())
|
|
|
|
|
|
+ for (L2Skill sk : aiHealSkills)
|
|
{
|
|
{
|
|
if (sk.getTargetType() == L2TargetType.SELF)
|
|
if (sk.getTargetType() == L2TargetType.SELF)
|
|
{
|
|
{
|
|
@@ -1036,7 +1039,7 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
|
|
}
|
|
}
|
|
if (Rnd.get(100) < ((100 - percentage) / 3))
|
|
if (Rnd.get(100) < ((100 - percentage) / 3))
|
|
{
|
|
{
|
|
- for (L2Skill sk : _skillrender.getHealSkills())
|
|
|
|
|
|
+ for (L2Skill sk : aiHealSkills)
|
|
{
|
|
{
|
|
if (!checkSkillCastConditions(sk))
|
|
if (!checkSkillCastConditions(sk))
|
|
{
|
|
{
|
|
@@ -1048,7 +1051,7 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- for (L2Skill sk : _skillrender.getHealSkills())
|
|
|
|
|
|
+ for (L2Skill sk : aiHealSkills)
|
|
{
|
|
{
|
|
if (!checkSkillCastConditions(sk))
|
|
if (!checkSkillCastConditions(sk))
|
|
{
|
|
{
|
|
@@ -1091,14 +1094,15 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
|
|
}
|
|
}
|
|
// -------------------------------------------------------------------------------
|
|
// -------------------------------------------------------------------------------
|
|
// Res Skill Condition
|
|
// Res Skill Condition
|
|
- if (!_skillrender.getResSkills().isEmpty())
|
|
|
|
|
|
+ List<L2Skill> aiResSkills = _skillrender.getAISkills(AISkillScope.HEAL);
|
|
|
|
+ if (!aiResSkills.isEmpty())
|
|
{
|
|
{
|
|
if (npc.isMinion())
|
|
if (npc.isMinion())
|
|
{
|
|
{
|
|
L2Character leader = npc.getLeader();
|
|
L2Character leader = npc.getLeader();
|
|
if ((leader != null) && leader.isDead())
|
|
if ((leader != null) && leader.isDead())
|
|
{
|
|
{
|
|
- for (L2Skill sk : _skillrender.getResSkills())
|
|
|
|
|
|
+ for (L2Skill sk : aiResSkills)
|
|
{
|
|
{
|
|
if (sk.getTargetType() == L2TargetType.SELF)
|
|
if (sk.getTargetType() == L2TargetType.SELF)
|
|
{
|
|
{
|
|
@@ -1123,7 +1127,7 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- for (L2Skill sk : _skillrender.getResSkills())
|
|
|
|
|
|
+ for (L2Skill sk : aiResSkills)
|
|
{
|
|
{
|
|
if (!checkSkillCastConditions(sk))
|
|
if (!checkSkillCastConditions(sk))
|
|
{
|
|
{
|
|
@@ -1191,16 +1195,17 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
|
|
setTimepass(0);
|
|
setTimepass(0);
|
|
// --------------------------------------------------------------------------------
|
|
// --------------------------------------------------------------------------------
|
|
// Skill Use
|
|
// Skill Use
|
|
- if (!_skillrender.getGeneralskills().isEmpty())
|
|
|
|
|
|
+ List<L2Skill> aiGeneralSkills = _skillrender.getAISkills(AISkillScope.GENERAL);
|
|
|
|
+ if (!aiGeneralSkills.isEmpty())
|
|
{
|
|
{
|
|
if (Rnd.get(100) < Rnd.get(npc.getMinSkillChance(), npc.getMaxSkillChance()))
|
|
if (Rnd.get(100) < Rnd.get(npc.getMinSkillChance(), npc.getMaxSkillChance()))
|
|
{
|
|
{
|
|
- L2Skill skills = _skillrender.getGeneralskills().get(Rnd.nextInt(_skillrender.getGeneralskills().size()));
|
|
|
|
|
|
+ L2Skill skills = aiGeneralSkills.get(Rnd.nextInt(aiGeneralSkills.size()));
|
|
if (cast(skills))
|
|
if (cast(skills))
|
|
{
|
|
{
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- for (L2Skill sk : _skillrender.getGeneralskills())
|
|
|
|
|
|
+ for (L2Skill sk : aiGeneralSkills)
|
|
{
|
|
{
|
|
if (cast(sk))
|
|
if (cast(sk))
|
|
{
|
|
{
|
|
@@ -1283,21 +1288,18 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
|
|
{
|
|
{
|
|
case -1:
|
|
case -1:
|
|
{
|
|
{
|
|
- if (_skillrender.getGeneralskills() != null)
|
|
|
|
|
|
+ for (L2Skill sk : _skillrender.getAISkills(AISkillScope.GENERAL))
|
|
{
|
|
{
|
|
- for (L2Skill sk : _skillrender.getGeneralskills())
|
|
|
|
|
|
+ if (cast(sk))
|
|
{
|
|
{
|
|
- if (cast(sk))
|
|
|
|
- {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
|
|
+ return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
case 1:
|
|
case 1:
|
|
{
|
|
{
|
|
- for (L2Skill sk : _skillrender.getAtkSkills())
|
|
|
|
|
|
+ for (L2Skill sk : _skillrender.getAISkills(AISkillScope.ATTACK))
|
|
{
|
|
{
|
|
if (cast(sk))
|
|
if (cast(sk))
|
|
{
|
|
{
|
|
@@ -1308,7 +1310,7 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
|
|
}
|
|
}
|
|
default:
|
|
default:
|
|
{
|
|
{
|
|
- for (L2Skill sk : _skillrender.getGeneralskills())
|
|
|
|
|
|
+ for (L2Skill sk : _skillrender.getAISkills(AISkillScope.GENERAL))
|
|
{
|
|
{
|
|
if (sk.getId() == getActiveChar().getPrimarySkillId())
|
|
if (sk.getId() == getActiveChar().getPrimarySkillId())
|
|
{
|
|
{
|
|
@@ -1841,14 +1843,14 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
|
|
}
|
|
}
|
|
|
|
|
|
// Check if activeChar has any skill
|
|
// Check if activeChar has any skill
|
|
- if (!_skillrender.getGeneralskills().isEmpty())
|
|
|
|
|
|
+ if (!_skillrender.getAISkills(AISkillScope.GENERAL).isEmpty())
|
|
{
|
|
{
|
|
// -------------------------------------------------------------
|
|
// -------------------------------------------------------------
|
|
// Try to stop the target or disable the target as priority
|
|
// Try to stop the target or disable the target as priority
|
|
int random = Rnd.get(100);
|
|
int random = Rnd.get(100);
|
|
- if (!_skillrender.getImmobiliseSkills().isEmpty() && !getAttackTarget().isImmobilized() && (random < 2))
|
|
|
|
|
|
+ if (!getAttackTarget().isImmobilized() && (random < 2))
|
|
{
|
|
{
|
|
- for (L2Skill sk : _skillrender.getImmobiliseSkills())
|
|
|
|
|
|
+ for (L2Skill sk : _skillrender.getAISkills(AISkillScope.IMMOBILIZE))
|
|
{
|
|
{
|
|
if (!checkSkillCastConditions(sk) || (((sk.getCastRange() + npc.getTemplate().getCollisionRadius() + getAttackTarget().getTemplate().getCollisionRadius()) <= dist2) && !canAura(sk)))
|
|
if (!checkSkillCastConditions(sk) || (((sk.getCastRange() + npc.getTemplate().getCollisionRadius() + getAttackTarget().getTemplate().getCollisionRadius()) <= dist2) && !canAura(sk)))
|
|
{
|
|
{
|
|
@@ -1871,9 +1873,9 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
|
|
}
|
|
}
|
|
// -------------------------------------------------------------
|
|
// -------------------------------------------------------------
|
|
// Same as Above, but with Mute/FEAR etc....
|
|
// Same as Above, but with Mute/FEAR etc....
|
|
- if (!_skillrender.getCostOverTimeSkills().isEmpty() && (random < 5))
|
|
|
|
|
|
+ if (random < 5)
|
|
{
|
|
{
|
|
- for (L2Skill sk : _skillrender.getCostOverTimeSkills())
|
|
|
|
|
|
+ for (L2Skill sk : _skillrender.getAISkills(AISkillScope.COT))
|
|
{
|
|
{
|
|
if (!checkSkillCastConditions(sk) || (((sk.getCastRange() + npc.getTemplate().getCollisionRadius() + getAttackTarget().getTemplate().getCollisionRadius()) <= dist2) && !canAura(sk)))
|
|
if (!checkSkillCastConditions(sk) || (((sk.getCastRange() + npc.getTemplate().getCollisionRadius() + getAttackTarget().getTemplate().getCollisionRadius()) <= dist2) && !canAura(sk)))
|
|
{
|
|
{
|
|
@@ -1895,9 +1897,9 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// -------------------------------------------------------------
|
|
// -------------------------------------------------------------
|
|
- if (!_skillrender.getDebuffSkills().isEmpty() && (random < 8))
|
|
|
|
|
|
+ if (random < 8)
|
|
{
|
|
{
|
|
- for (L2Skill sk : _skillrender.getDebuffSkills())
|
|
|
|
|
|
+ for (L2Skill sk : _skillrender.getAISkills(AISkillScope.DEBUFF))
|
|
{
|
|
{
|
|
if (!checkSkillCastConditions(sk) || (((sk.getCastRange() + npc.getTemplate().getCollisionRadius() + getAttackTarget().getTemplate().getCollisionRadius()) <= dist2) && !canAura(sk)))
|
|
if (!checkSkillCastConditions(sk) || (((sk.getCastRange() + npc.getTemplate().getCollisionRadius() + getAttackTarget().getTemplate().getCollisionRadius()) <= dist2) && !canAura(sk)))
|
|
{
|
|
{
|
|
@@ -1920,9 +1922,9 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
|
|
}
|
|
}
|
|
// -------------------------------------------------------------
|
|
// -------------------------------------------------------------
|
|
// Some side effect skill like CANCEL or NEGATE
|
|
// Some side effect skill like CANCEL or NEGATE
|
|
- if (!_skillrender.getNegativeSkills().isEmpty() && (random < 9))
|
|
|
|
|
|
+ if (random < 9)
|
|
{
|
|
{
|
|
- for (L2Skill sk : _skillrender.getNegativeSkills())
|
|
|
|
|
|
+ for (L2Skill sk : _skillrender.getAISkills(AISkillScope.NEGATIVE))
|
|
{
|
|
{
|
|
if (!checkSkillCastConditions(sk) || (((sk.getCastRange() + npc.getTemplate().getCollisionRadius() + getAttackTarget().getTemplate().getCollisionRadius()) <= dist2) && !canAura(sk)))
|
|
if (!checkSkillCastConditions(sk) || (((sk.getCastRange() + npc.getTemplate().getCollisionRadius() + getAttackTarget().getTemplate().getCollisionRadius()) <= dist2) && !canAura(sk)))
|
|
{
|
|
{
|
|
@@ -1945,9 +1947,9 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
|
|
}
|
|
}
|
|
// -------------------------------------------------------------
|
|
// -------------------------------------------------------------
|
|
// Start ATK SKILL when nothing can be done
|
|
// Start ATK SKILL when nothing can be done
|
|
- if (!_skillrender.getAtkSkills().isEmpty() && (npc.isMovementDisabled() || (npc.getAiType() == AIType.MAGE) || (npc.getAiType() == AIType.HEALER)))
|
|
|
|
|
|
+ if ((npc.isMovementDisabled() || (npc.getAiType() == AIType.MAGE) || (npc.getAiType() == AIType.HEALER)))
|
|
{
|
|
{
|
|
- for (L2Skill sk : _skillrender.getAtkSkills())
|
|
|
|
|
|
+ for (L2Skill sk : _skillrender.getAISkills(AISkillScope.ATTACK))
|
|
{
|
|
{
|
|
if (!checkSkillCastConditions(sk) || (((sk.getCastRange() + npc.getTemplate().getCollisionRadius() + getAttackTarget().getTemplate().getCollisionRadius()) <= dist2) && !canAura(sk)))
|
|
if (!checkSkillCastConditions(sk) || (((sk.getCastRange() + npc.getTemplate().getCollisionRadius() + getAttackTarget().getTemplate().getCollisionRadius()) <= dist2) && !canAura(sk)))
|
|
{
|
|
{
|
|
@@ -2584,7 +2586,7 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
|
|
|
|
|
|
private List<L2Skill> longRangeSkillRender()
|
|
private List<L2Skill> longRangeSkillRender()
|
|
{
|
|
{
|
|
- longRangeSkills = _skillrender.getLongRangeSkills();
|
|
|
|
|
|
+ longRangeSkills = _skillrender.getAISkills(AISkillScope.LONG_RANGE);
|
|
if (longRangeSkills.isEmpty())
|
|
if (longRangeSkills.isEmpty())
|
|
{
|
|
{
|
|
longRangeSkills = getActiveChar().getLongRangeSkill();
|
|
longRangeSkills = getActiveChar().getLongRangeSkill();
|
|
@@ -2594,7 +2596,7 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
|
|
|
|
|
|
private List<L2Skill> shortRangeSkillRender()
|
|
private List<L2Skill> shortRangeSkillRender()
|
|
{
|
|
{
|
|
- shortRangeSkills = _skillrender.getShortRangeSkills();
|
|
|
|
|
|
+ shortRangeSkills = _skillrender.getAISkills(AISkillScope.SHORT_RANGE);
|
|
if (shortRangeSkills.isEmpty())
|
|
if (shortRangeSkills.isEmpty())
|
|
{
|
|
{
|
|
shortRangeSkills = getActiveChar().getShortRangeSkill();
|
|
shortRangeSkills = getActiveChar().getShortRangeSkill();
|