protected void update(L2Character actor, L2Character target) { // update status once in 4 tries if (target == character && System.nanoTime() % 4 == 0) return; character = target; if (target == null) return; isMage = false; isBalanced = false; isArcher = false; isFighter = false; double multi = (double) target.getMAtk(null, null) / target.getPAtk(null); if (multi > 1.5) { isMage = true; } else if (multi > 0.8) { isBalanced = true; } else { L2Weapon weapon = target.getActiveWeaponItem(); if (weapon != null && weapon.getItemType().isBowType()) isArcher = true; else isFighter = true; } isCanceled = target.getBuffCount() < 4; isSlower = target.getRunSpeed() < actor.getRunSpeed() - 3; isMagicResistant = target.getMDef(null, null) * 1.2 > actor.getMAtk(null, null); }
/** * Modify current Intention and actions if the target is lost or dead.<br> * <br> * <B><U> Actions</U> : <I>If the target is lost or dead</I></B><br> * <br> * <li>Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop * (broadcast) * <li>Stop the actor movement server side AND client side by sending Server->Client packet * StopMove/StopRotation (broadcast) * <li>Set the Intention of this AbstractAI to AI_INTENTION_ACTIVE<br> * <br> * <B><U> Example of use </U> :</B><br> * <br> * <li>L2PLayerAI, L2SummonAI<br> * <br> * * @param target The targeted L2Object * @return True if the target is lost or dead (false if fakedeath) */ protected boolean checkTargetLostOrDead(L2Character target) { if (target == null || target.isAlikeDead()) { // check if player is fakedeath if (target != null && target.isFakeDeath()) { target.stopFakeDeath(true); return false; } // Set the Intention of this AbstractAI to AI_INTENTION_ACTIVE setIntention(AI_INTENTION_ACTIVE); return true; } return false; }
@Override protected void onEvtAttacked(L2Character attacker) { if (!(attacker instanceof L2Attackable) || !attacker.isCoreAIDisabled()) clientStartAutoAttack(); }
protected void init(L2Character actor) { switch (((L2NpcTemplate) actor.getTemplate()).getAI()) { case FIGHTER: isFighter = true; break; case MAGE: isMage = true; break; case CORPSE: case BALANCED: isBalanced = true; break; case ARCHER: isArcher = true; break; case HEALER: isHealer = true; break; default: isFighter = true; break; } // water movement analysis if (actor instanceof L2Npc) { switch (((L2Npc) actor).getNpcId()) { case 20314: // Great White Shark case 20849: // Light Worm cannotMoveOnLand = true; break; default: cannotMoveOnLand = false; break; } } final ArrayList<L2Skill> generalSkills0 = L2Collections.newArrayList(); final ArrayList<L2Skill> buffSkills0 = L2Collections.newArrayList(); final ArrayList<L2Skill> debuffSkills0 = L2Collections.newArrayList(); final ArrayList<L2Skill> cancelSkills0 = L2Collections.newArrayList(); final ArrayList<L2Skill> healSkills0 = L2Collections.newArrayList(); // final ArrayList<L2Skill> trickSkills0 = L2Collections.newArrayList(); final ArrayList<L2Skill> generalDisablers0 = L2Collections.newArrayList(); final ArrayList<L2Skill> sleepSkills0 = L2Collections.newArrayList(); final ArrayList<L2Skill> rootSkills0 = L2Collections.newArrayList(); final ArrayList<L2Skill> muteSkills0 = L2Collections.newArrayList(); final ArrayList<L2Skill> resurrectSkills0 = L2Collections.newArrayList(); // skill analysis for (L2Skill sk : actor.getAllSkills()) { if (sk.isPassive()) continue; int castRange = sk.getCastRange(); boolean hasLongRangeDamageSkill = false; switch (sk.getSkillType()) { case HEAL: case HEAL_PERCENT: case HEAL_STATIC: case BALANCE_LIFE: case HOT: healSkills0.add(sk); hasHealOrResurrect = true; continue; // won't be considered something for fighting case BUFF: buffSkills0.add(sk); continue; // won't be considered something for fighting case PARALYZE: case STUN: // hardcoding petrification until improvements are made to // EffectTemplate... petrification is totally different for // AI than paralyze switch (sk.getId()) { case 367: case 4111: case 4383: case 4616: case 4578: sleepSkills0.add(sk); break; default: generalDisablers0.add(sk); break; } break; case MUTE: muteSkills0.add(sk); break; case SLEEP: sleepSkills0.add(sk); break; case ROOT: rootSkills0.add(sk); break; case FEAR: // could be used as an alternative for healing? case CONFUSION: // trickSkills.add(sk); case DEBUFF: debuffSkills0.add(sk); break; case CANCEL: case MAGE_BANE: case WARRIOR_BANE: case NEGATE: cancelSkills0.add(sk); break; case RESURRECT: resurrectSkills0.add(sk); hasHealOrResurrect = true; break; case NOTDONE: case COREDONE: continue; // won't be considered something for fighting default: generalSkills0.add(sk); hasLongRangeDamageSkill = true; break; } if (castRange > 70) { hasLongRangeSkills = true; if (hasLongRangeDamageSkill) hasLongRangeDamageSkills = true; } if (castRange > maxCastRange) maxCastRange = castRange; } // Because of missing skills, some mages/balanced cannot play like mages if (!hasLongRangeDamageSkills && isMage) { isBalanced = true; isMage = false; isFighter = false; } if (!hasLongRangeSkills && (isMage || isBalanced)) { isBalanced = false; isMage = false; isFighter = true; } if (generalSkills0.isEmpty() && isMage) { isBalanced = true; isMage = false; } generalSkills = convert(generalSkills0); buffSkills = convert(buffSkills0); debuffSkills = convert(debuffSkills0); cancelSkills = convert(cancelSkills0); healSkills = convert(healSkills0); // this.trickSkills = convert(trickSkills0); generalDisablers = convert(generalDisablers0); sleepSkills = convert(sleepSkills0); rootSkills = convert(rootSkills0); muteSkills = convert(muteSkills0); resurrectSkills = convert(resurrectSkills0); }