Advertisement
Guest User

Untitled

a guest
Feb 28th, 2016
203
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 63.18 KB | None | 0 0
  1. /*
  2. * This program is free software: you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation, either version 3 of the License, or (at your option) any later
  5. * version.
  6. *
  7. * This program is distributed in the hope that it will be useful, but WITHOUT
  8. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  9. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  10. * details.
  11. *
  12. * You should have received a copy of the GNU General Public License along with
  13. * this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. package net.sf.l2j.gameserver.model;
  16.  
  17. import custom.events.DMEvent;
  18. import custom.events.TvTEvent;
  19.  
  20. import java.util.ArrayList;
  21. import java.util.Collections;
  22. import java.util.List;
  23. import java.util.StringTokenizer;
  24. import java.util.logging.Logger;
  25.  
  26. import net.sf.l2j.gameserver.datatables.SkillTable;
  27. import net.sf.l2j.gameserver.datatables.SkillTreeTable;
  28. import net.sf.l2j.gameserver.geoengine.GeoEngine;
  29. import net.sf.l2j.gameserver.model.actor.L2Attackable;
  30. import net.sf.l2j.gameserver.model.actor.L2Character;
  31. import net.sf.l2j.gameserver.model.actor.L2Npc;
  32. import net.sf.l2j.gameserver.model.actor.L2Playable;
  33. import net.sf.l2j.gameserver.model.actor.L2Summon;
  34. import net.sf.l2j.gameserver.model.actor.instance.L2ArtefactInstance;
  35. import net.sf.l2j.gameserver.model.actor.instance.L2ChestInstance;
  36. import net.sf.l2j.gameserver.model.actor.instance.L2CubicInstance;
  37. import net.sf.l2j.gameserver.model.actor.instance.L2DoorInstance;
  38. import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
  39. import net.sf.l2j.gameserver.model.actor.instance.L2PetInstance;
  40. import net.sf.l2j.gameserver.model.actor.instance.L2SiegeFlagInstance;
  41. import net.sf.l2j.gameserver.model.actor.instance.L2SummonInstance;
  42. import net.sf.l2j.gameserver.model.holder.IntIntHolder;
  43. import net.sf.l2j.gameserver.model.item.kind.Armor;
  44. import net.sf.l2j.gameserver.model.item.type.ArmorType;
  45. import net.sf.l2j.gameserver.model.item.type.WeaponType;
  46. import net.sf.l2j.gameserver.model.zone.ZoneId;
  47. import net.sf.l2j.gameserver.network.SystemMessageId;
  48. import net.sf.l2j.gameserver.network.serverpackets.SystemMessage;
  49. import net.sf.l2j.gameserver.skills.Env;
  50. import net.sf.l2j.gameserver.skills.Formulas;
  51. import net.sf.l2j.gameserver.skills.Stats;
  52. import net.sf.l2j.gameserver.skills.basefuncs.Func;
  53. import net.sf.l2j.gameserver.skills.basefuncs.FuncTemplate;
  54. import net.sf.l2j.gameserver.skills.conditions.Condition;
  55. import net.sf.l2j.gameserver.skills.effects.EffectTemplate;
  56. import net.sf.l2j.gameserver.taskmanager.DecayTaskManager;
  57. import net.sf.l2j.gameserver.templates.StatsSet;
  58. import net.sf.l2j.gameserver.templates.skills.L2SkillType;
  59. import net.sf.l2j.gameserver.util.Util;
  60.  
  61. public abstract class L2Skill implements IChanceSkillTrigger
  62. {
  63. protected static final Logger _log = Logger.getLogger(L2Skill.class.getName());
  64.  
  65. private static final L2Object[] _emptyTargetList = new L2Object[0];
  66.  
  67. public static final int SKILL_LUCKY = 194;
  68. public static final int SKILL_CREATE_COMMON = 1320;
  69. public static final int SKILL_CREATE_DWARVEN = 172;
  70. public static final int SKILL_CRYSTALLIZE = 248;
  71. public static final int SKILL_DIVINE_INSPIRATION = 1405;
  72. public static final int SKILL_NPC_RACE = 4416;
  73.  
  74. public static enum SkillOpType
  75. {
  76. OP_PASSIVE,
  77. OP_ACTIVE,
  78. OP_TOGGLE
  79. }
  80.  
  81. /** Target types of skills : SELF, PARTY, CLAN, PET... */
  82. public static enum SkillTargetType
  83. {
  84. TARGET_NONE,
  85. TARGET_SELF,
  86. TARGET_ONE,
  87. TARGET_PARTY,
  88. TARGET_ALLY,
  89. TARGET_CLAN,
  90. TARGET_PET,
  91. TARGET_AREA,
  92. TARGET_FRONT_AREA,
  93. TARGET_BEHIND_AREA,
  94. TARGET_AURA,
  95. TARGET_FRONT_AURA,
  96. TARGET_BEHIND_AURA,
  97. TARGET_CORPSE,
  98. TARGET_UNDEAD,
  99. TARGET_AURA_UNDEAD,
  100. TARGET_CORPSE_ALLY,
  101. TARGET_CORPSE_PLAYER,
  102. TARGET_CORPSE_PET,
  103. TARGET_AREA_CORPSE_MOB,
  104. TARGET_CORPSE_MOB,
  105. TARGET_UNLOCKABLE,
  106. TARGET_HOLY,
  107. TARGET_PARTY_MEMBER,
  108. TARGET_PARTY_OTHER,
  109. TARGET_SUMMON,
  110. TARGET_AREA_SUMMON,
  111. TARGET_ENEMY_SUMMON,
  112. TARGET_OWNER_PET,
  113. TARGET_GROUND
  114. }
  115.  
  116. // conditional values
  117. public static final int COND_BEHIND = 0x0008;
  118. public static final int COND_CRIT = 0x0010;
  119.  
  120. private final int _id;
  121. private final int _level;
  122.  
  123. private final String _name;
  124. private final SkillOpType _operateType;
  125.  
  126. private final boolean _magic;
  127.  
  128. private final int _mpConsume;
  129. private final int _mpInitialConsume;
  130. private final int _hpConsume;
  131.  
  132. private final int _targetConsume;
  133. private final int _targetConsumeId;
  134.  
  135. private final int _itemConsume; // items consumption
  136. private final int _itemConsumeId;
  137.  
  138. private final int _castRange;
  139. private final int _effectRange;
  140.  
  141. private final int _abnormalLvl; // Abnormal levels for skills and their canceling
  142. private final int _effectAbnormalLvl;
  143.  
  144. private final int _hitTime; // all times in milliseconds
  145. private final int _coolTime;
  146.  
  147. private final int _reuseDelay;
  148. private final int _equipDelay;
  149.  
  150. private final int _buffDuration;
  151.  
  152. /** Target type of the skill : SELF, PARTY, CLAN, PET... */
  153. private final SkillTargetType _targetType;
  154.  
  155. private final double _power;
  156.  
  157. private final int _magicLevel;
  158.  
  159. private final int _negateLvl; // abnormalLvl is negated with negateLvl
  160. private final int[] _negateId; // cancels the effect of skill ID
  161. private final L2SkillType[] _negateStats; // lists the effect types that are canceled
  162. private final int _maxNegatedEffects; // maximum number of effects to negate
  163.  
  164. private final int _levelDepend;
  165.  
  166. private final int _skillRadius; // Effecting area of the skill, in radius.
  167.  
  168. private final L2SkillType _skillType;
  169. private final L2SkillType _effectType;
  170.  
  171. private final int _effectId;
  172. private final int _effectPower;
  173. private final int _effectLvl;
  174.  
  175. private final boolean _ispotion;
  176. private final byte _element;
  177.  
  178. private final boolean _ignoreResists;
  179.  
  180. private final boolean _staticReuse;
  181. private final boolean _staticHitTime;
  182.  
  183. private final int _reuseHashCode;
  184.  
  185. private final Stats _stat;
  186.  
  187. private final int _condition;
  188. private final int _conditionValue;
  189.  
  190. private final boolean _overhit;
  191. private final boolean _killByDOT;
  192. private final boolean _isSuicideAttack;
  193.  
  194. private final boolean _isDemonicSkill;
  195. private final boolean _isFlyingSkill;
  196. private final boolean _isStriderSkill;
  197.  
  198. private final boolean _isSiegeSummonSkill;
  199.  
  200. private final int _weaponsAllowed;
  201.  
  202. private final boolean _nextActionIsAttack;
  203.  
  204. private final int _minPledgeClass;
  205.  
  206. private final boolean _isOffensive;
  207. private final int _maxCharges;
  208. private final int _numCharges;
  209.  
  210. private final int _triggeredId;
  211. private final int _triggeredLevel;
  212. protected ChanceCondition _chanceCondition = null;
  213. private final String _chanceType;
  214.  
  215. private final String _flyType;
  216. private final int _flyRadius;
  217. private final float _flyCourse;
  218.  
  219. private final int _feed;
  220.  
  221. private final boolean _isHeroSkill; // If true the skill is a Hero Skill
  222.  
  223. private final int _baseCritRate; // percent of success for skill critical hit (especially for PDAM & BLOW - they're not affected by rCrit values or buffs). Default loads -1 for all other skills but 0 to PDAM & BLOW
  224. private final int _lethalEffect1; // percent of success for lethal 1st effect (hit cp to 1 or if mob hp to 50%) (only for PDAM skills)
  225. private final int _lethalEffect2; // percent of success for lethal 2nd effect (hit cp,hp to 1 or if mob hp to 1) (only for PDAM skills)
  226. private final boolean _directHpDmg; // If true then dmg is being make directly
  227. private final boolean _isDance; // If true then casting more dances will cost more MP
  228. private final int _nextDanceCost;
  229. private final float _sSBoost; // If true skill will have SoulShot boost (power*2)
  230. private final int _aggroPoints;
  231.  
  232. protected List<Condition> _preCondition;
  233. protected List<Condition> _itemPreCondition;
  234. protected List<FuncTemplate> _funcTemplates;
  235. protected List<EffectTemplate> _effectTemplates;
  236. protected List<EffectTemplate> _effectTemplatesSelf;
  237.  
  238. private final String _attribute;
  239.  
  240. private final boolean _isDebuff;
  241. private final boolean _stayAfterDeath; // skill should stay after death
  242.  
  243. private final boolean _removedOnAnyActionExceptMove;
  244. private final boolean _removedOnDamage;
  245.  
  246. private final boolean _canBeReflected;
  247. private final boolean _canBeDispeled;
  248.  
  249. private final boolean _isClanSkill;
  250.  
  251. private final boolean _ignoreShield;
  252.  
  253. private final boolean _simultaneousCast;
  254.  
  255. private L2ExtractableSkill _extractableItems = null;
  256.  
  257. protected L2Skill(StatsSet set)
  258. {
  259. _id = set.getInteger("skill_id");
  260. _level = set.getInteger("level");
  261.  
  262. _name = set.getString("name");
  263. _operateType = set.getEnum("operateType", SkillOpType.class);
  264.  
  265. _magic = set.getBool("isMagic", false);
  266. _ispotion = set.getBool("isPotion", false);
  267.  
  268. _mpConsume = set.getInteger("mpConsume", 0);
  269. _mpInitialConsume = set.getInteger("mpInitialConsume", 0);
  270. _hpConsume = set.getInteger("hpConsume", 0);
  271.  
  272. _targetConsume = set.getInteger("targetConsumeCount", 0);
  273. _targetConsumeId = set.getInteger("targetConsumeId", 0);
  274.  
  275. _itemConsume = set.getInteger("itemConsumeCount", 0);
  276. _itemConsumeId = set.getInteger("itemConsumeId", 0);
  277.  
  278. _castRange = set.getInteger("castRange", 0);
  279. _effectRange = set.getInteger("effectRange", -1);
  280.  
  281. _abnormalLvl = set.getInteger("abnormalLvl", -1);
  282. _effectAbnormalLvl = set.getInteger("effectAbnormalLvl", -1); // support for a separate effect abnormal lvl, e.g. poison inside a different skill
  283. _negateLvl = set.getInteger("negateLvl", -1);
  284.  
  285. _hitTime = set.getInteger("hitTime", 0);
  286. _coolTime = set.getInteger("coolTime", 0);
  287.  
  288. _reuseDelay = set.getInteger("reuseDelay", 0);
  289. _equipDelay = set.getInteger("equipDelay", 0);
  290.  
  291. _buffDuration = set.getInteger("buffDuration", 0);
  292.  
  293. _skillRadius = set.getInteger("skillRadius", 80);
  294.  
  295. _targetType = set.getEnum("target", SkillTargetType.class);
  296.  
  297. _power = set.getFloat("power", 0.f);
  298.  
  299. _attribute = set.getString("attribute", "");
  300. String str = set.getString("negateStats", "");
  301.  
  302. if (str.isEmpty())
  303. _negateStats = new L2SkillType[0];
  304. else
  305. {
  306. String[] stats = str.split(" ");
  307. L2SkillType[] array = new L2SkillType[stats.length];
  308.  
  309. for (int i = 0; i < stats.length; i++)
  310. {
  311. L2SkillType type = null;
  312. try
  313. {
  314. type = Enum.valueOf(L2SkillType.class, stats[i]);
  315. }
  316. catch (Exception e)
  317. {
  318. throw new IllegalArgumentException("SkillId: " + _id + "Enum value of type " + L2SkillType.class.getName() + " required, but found: " + stats[i]);
  319. }
  320.  
  321. array[i] = type;
  322. }
  323. _negateStats = array;
  324. }
  325.  
  326. String negateId = set.getString("negateId", null);
  327. if (negateId != null)
  328. {
  329. String[] valuesSplit = negateId.split(",");
  330. _negateId = new int[valuesSplit.length];
  331. for (int i = 0; i < valuesSplit.length; i++)
  332. {
  333. _negateId[i] = Integer.parseInt(valuesSplit[i]);
  334. }
  335. }
  336. else
  337. _negateId = new int[0];
  338.  
  339. _maxNegatedEffects = set.getInteger("maxNegated", 0);
  340.  
  341. _magicLevel = set.getInteger("magicLvl", SkillTreeTable.getInstance().getMinSkillLevel(_id, _level));
  342. _levelDepend = set.getInteger("lvlDepend", 0);
  343. _ignoreResists = set.getBool("ignoreResists", false);
  344.  
  345. _staticReuse = set.getBool("staticReuse", false);
  346. _staticHitTime = set.getBool("staticHitTime", false);
  347.  
  348. String reuseHash = set.getString("sharedReuse", null);
  349. if (reuseHash != null)
  350. {
  351. try
  352. {
  353. String[] valuesSplit = reuseHash.split("-");
  354. _reuseHashCode = SkillTable.getSkillHashCode(Integer.parseInt(valuesSplit[0]), Integer.parseInt(valuesSplit[1]));
  355. }
  356. catch (Exception e)
  357. {
  358. throw new IllegalArgumentException("SkillId: " + _id + " invalid sharedReuse value: " + reuseHash + ", \"skillId-skillLvl\" required");
  359. }
  360. }
  361. else
  362. _reuseHashCode = SkillTable.getSkillHashCode(_id, _level);
  363.  
  364. _stat = set.getEnum("stat", Stats.class, null);
  365. _ignoreShield = set.getBool("ignoreShld", false);
  366.  
  367. _skillType = set.getEnum("skillType", L2SkillType.class);
  368. _effectType = set.getEnum("effectType", L2SkillType.class, null);
  369.  
  370. _effectId = set.getInteger("effectId", 0);
  371. _effectPower = set.getInteger("effectPower", 0);
  372. _effectLvl = set.getInteger("effectLevel", 0);
  373.  
  374. _element = set.getByte("element", (byte) -1);
  375.  
  376. _condition = set.getInteger("condition", 0);
  377. _conditionValue = set.getInteger("conditionValue", 0);
  378.  
  379. _overhit = set.getBool("overHit", false);
  380. _killByDOT = set.getBool("killByDOT", false);
  381. _isSuicideAttack = set.getBool("isSuicideAttack", false);
  382.  
  383. _isDemonicSkill = set.getBool("isDemonicSkill", false);
  384. _isFlyingSkill = set.getBool("isFlyingSkill", false);
  385. _isStriderSkill = set.getBool("isStriderSkill", false);
  386.  
  387. _isSiegeSummonSkill = set.getBool("isSiegeSummonSkill", false);
  388.  
  389. String weaponsAllowedString = set.getString("weaponsAllowed", null);
  390. if (weaponsAllowedString != null)
  391. {
  392. int mask = 0;
  393. StringTokenizer st = new StringTokenizer(weaponsAllowedString, ",");
  394. while (st.hasMoreTokens())
  395. {
  396. int old = mask;
  397. String item = st.nextToken();
  398. for (WeaponType wt : WeaponType.values())
  399. {
  400. if (wt.name().equals(item))
  401. {
  402. mask |= wt.mask();
  403. break;
  404. }
  405. }
  406.  
  407. for (ArmorType at : ArmorType.values())
  408. {
  409. if (at.name().equals(item))
  410. {
  411. mask |= at.mask();
  412. break;
  413. }
  414. }
  415.  
  416. if (old == mask)
  417. _log.info("[weaponsAllowed] Unknown item type name: " + item);
  418. }
  419. _weaponsAllowed = mask;
  420. }
  421. else
  422. _weaponsAllowed = 0;
  423.  
  424. _nextActionIsAttack = set.getBool("nextActionAttack", false);
  425.  
  426. _minPledgeClass = set.getInteger("minPledgeClass", 0);
  427.  
  428. _triggeredId = set.getInteger("triggeredId", 0);
  429. _triggeredLevel = set.getInteger("triggeredLevel", 0);
  430. _chanceType = set.getString("chanceType", "");
  431. if (!_chanceType.isEmpty())
  432. _chanceCondition = ChanceCondition.parse(set);
  433.  
  434. _isOffensive = set.getBool("offensive", isSkillTypeOffensive());
  435. _maxCharges = set.getInteger("maxCharges", 0);
  436. _numCharges = set.getInteger("numCharges", 0);
  437.  
  438. _isHeroSkill = SkillTable.isHeroSkill(_id);
  439.  
  440. _baseCritRate = set.getInteger("baseCritRate", (_skillType == L2SkillType.PDAM || _skillType == L2SkillType.BLOW) ? 0 : -1);
  441. _lethalEffect1 = set.getInteger("lethal1", 0);
  442. _lethalEffect2 = set.getInteger("lethal2", 0);
  443.  
  444. _directHpDmg = set.getBool("dmgDirectlyToHp", false);
  445. _isDance = set.getBool("isDance", false);
  446. _nextDanceCost = set.getInteger("nextDanceCost", 0);
  447. _sSBoost = set.getFloat("SSBoost", 0.f);
  448. _aggroPoints = set.getInteger("aggroPoints", 0);
  449.  
  450. _isDebuff = set.getBool("isDebuff", false);
  451. _stayAfterDeath = set.getBool("stayAfterDeath", false);
  452.  
  453. _removedOnAnyActionExceptMove = set.getBool("removedOnAnyActionExceptMove", false);
  454. _removedOnDamage = set.getBool("removedOnDamage", _skillType == L2SkillType.SLEEP);
  455.  
  456. _flyType = set.getString("flyType", null);
  457. _flyRadius = set.getInteger("flyRadius", 0);
  458. _flyCourse = set.getFloat("flyCourse", 0);
  459.  
  460. _feed = set.getInteger("feed", 0);
  461.  
  462. _canBeReflected = set.getBool("canBeReflected", true);
  463. _canBeDispeled = set.getBool("canBeDispeled", true);
  464.  
  465. _isClanSkill = set.getBool("isClanSkill", false);
  466.  
  467. _simultaneousCast = set.getBool("simultaneousCast", false);
  468.  
  469. String capsuled_items = set.getString("capsuled_items_skill", null);
  470. if (capsuled_items != null)
  471. {
  472. if (capsuled_items.isEmpty())
  473. _log.warning("Empty extractable data for skill: " + _id);
  474.  
  475. _extractableItems = parseExtractableSkill(_id, _level, capsuled_items);
  476. }
  477. }
  478.  
  479. public abstract void useSkill(L2Character caster, L2Object[] targets);
  480.  
  481. public final boolean isPotion()
  482. {
  483. return _ispotion;
  484. }
  485.  
  486. public final int getConditionValue()
  487. {
  488. return _conditionValue;
  489. }
  490.  
  491. public final L2SkillType getSkillType()
  492. {
  493. return _skillType;
  494. }
  495.  
  496. public final byte getElement()
  497. {
  498. return _element;
  499. }
  500.  
  501. /**
  502. * @return the target type of the skill : SELF, PARTY, CLAN, PET...
  503. */
  504. public final SkillTargetType getTargetType()
  505. {
  506. return _targetType;
  507. }
  508.  
  509. public final int getCondition()
  510. {
  511. return _condition;
  512. }
  513.  
  514. public final boolean isOverhit()
  515. {
  516. return _overhit;
  517. }
  518.  
  519. public final boolean killByDOT()
  520. {
  521. return _killByDOT;
  522. }
  523.  
  524. // RnP (skills)
  525. // Integer[] sks = {3132 , 3135 , 3136 , 3133 , 3141 , 3142 , 3134};
  526.  
  527.  
  528. public final boolean isSuicideAttack()
  529. {
  530. return _isSuicideAttack;
  531. }
  532.  
  533. public final boolean isDemonicSkill()
  534. {
  535. return _isDemonicSkill;
  536. }
  537.  
  538. public final boolean isFlyingSkill()
  539. {
  540. return _isFlyingSkill;
  541. }
  542.  
  543. public final boolean isStriderSkill()
  544. {
  545. return _isStriderSkill;
  546. }
  547.  
  548. public final boolean isSiegeSummonSkill()
  549. {
  550. return _isSiegeSummonSkill;
  551. }
  552.  
  553. /**
  554. * @param activeChar
  555. * @return the power of the skill.
  556. */
  557. public final double getPower(L2Character activeChar)
  558. {
  559. if (activeChar == null)
  560. return _power;
  561.  
  562. switch (_skillType)
  563. {
  564. case DEATHLINK:
  565. return _power * Math.pow(1.7165 - activeChar.getCurrentHp() / activeChar.getMaxHp(), 2) * 0.577;
  566. case FATAL:
  567. return _power + (_power * Math.pow(1.7165 - activeChar.getCurrentHp() / activeChar.getMaxHp(), 3.5) * 0.577);
  568. default:
  569. return _power;
  570. }
  571. }
  572.  
  573. public final double getPower()
  574. {
  575. return _power;
  576. }
  577.  
  578. public final L2SkillType[] getNegateStats()
  579. {
  580. return _negateStats;
  581. }
  582.  
  583. public final int getAbnormalLvl()
  584. {
  585. return _abnormalLvl;
  586. }
  587.  
  588. public final int getNegateLvl()
  589. {
  590. return _negateLvl;
  591. }
  592.  
  593. public final int[] getNegateId()
  594. {
  595. return _negateId;
  596. }
  597.  
  598. public final int getMagicLevel()
  599. {
  600. return _magicLevel;
  601. }
  602.  
  603. public final int getMaxNegatedEffects()
  604. {
  605. return _maxNegatedEffects;
  606. }
  607.  
  608. public final int getLevelDepend()
  609. {
  610. return _levelDepend;
  611. }
  612.  
  613. /**
  614. * @return true if skill should ignore all resistances.
  615. */
  616. public final boolean ignoreResists()
  617. {
  618. return _ignoreResists;
  619. }
  620.  
  621. public int getTriggeredId()
  622. {
  623. return _triggeredId;
  624. }
  625.  
  626. public int getTriggeredLevel()
  627. {
  628. return _triggeredLevel;
  629. }
  630.  
  631. public boolean triggerAnotherSkill()
  632. {
  633. return _triggeredId > 1;
  634. }
  635.  
  636. /**
  637. * @return true if skill effects should be removed on any action except movement
  638. */
  639. public final boolean isRemovedOnAnyActionExceptMove()
  640. {
  641. return _removedOnAnyActionExceptMove;
  642. }
  643.  
  644. /**
  645. * @return true if skill effects should be removed on damage
  646. */
  647. public final boolean isRemovedOnDamage()
  648. {
  649. return _removedOnDamage;
  650. }
  651.  
  652. /**
  653. * @return the additional effect power or base probability.
  654. */
  655. public final double getEffectPower()
  656. {
  657. if (_effectTemplates != null)
  658. {
  659. for (EffectTemplate et : _effectTemplates)
  660. {
  661. if (et.effectPower > 0)
  662. return et.effectPower;
  663. }
  664. }
  665.  
  666. if (_effectPower > 0)
  667. return _effectPower;
  668.  
  669. // Allow damage dealing skills having proper resist even without specified effectPower.
  670. switch (_skillType)
  671. {
  672. case PDAM:
  673. case MDAM:
  674. return 20;
  675.  
  676. default:
  677. // to let debuffs succeed even without specified power
  678. return (_power <= 0 || 100 < _power) ? 20 : _power;
  679. }
  680. }
  681.  
  682. /**
  683. * @return the additional effect Id.
  684. */
  685. public final int getEffectId()
  686. {
  687. return _effectId;
  688. }
  689.  
  690. /**
  691. * @return the additional effect level.
  692. */
  693. public final int getEffectLvl()
  694. {
  695. return _effectLvl;
  696. }
  697.  
  698. public final int getEffectAbnormalLvl()
  699. {
  700. return _effectAbnormalLvl;
  701. }
  702.  
  703. /**
  704. * @return the additional effect skill type (ex : STUN, PARALYZE,...).
  705. */
  706. public final L2SkillType getEffectType()
  707. {
  708. if (_effectTemplates != null)
  709. {
  710. for (EffectTemplate et : _effectTemplates)
  711. {
  712. if (et.effectType != null)
  713. return et.effectType;
  714. }
  715. }
  716.  
  717. if (_effectType != null)
  718. return _effectType;
  719.  
  720. // to let damage dealing skills having proper resist even without specified effectType
  721. switch (_skillType)
  722. {
  723. case PDAM:
  724. return L2SkillType.STUN;
  725. case MDAM:
  726. return L2SkillType.PARALYZE;
  727. default:
  728. return _skillType;
  729. }
  730. }
  731.  
  732. /**
  733. * @return true if character should attack target after skill
  734. */
  735. public final boolean nextActionIsAttack()
  736. {
  737. return _nextActionIsAttack;
  738. }
  739.  
  740. /**
  741. * @return Returns the buffDuration.
  742. */
  743. public final int getBuffDuration()
  744. {
  745. return _buffDuration;
  746. }
  747.  
  748. /**
  749. * @return Returns the castRange.
  750. */
  751. public final int getCastRange()
  752. {
  753. return _castRange;
  754. }
  755.  
  756. /**
  757. * @return Returns the effectRange.
  758. */
  759. public final int getEffectRange()
  760. {
  761. return _effectRange;
  762. }
  763.  
  764. /**
  765. * @return Returns the hpConsume.
  766. */
  767. public final int getHpConsume()
  768. {
  769. return _hpConsume;
  770. }
  771.  
  772. /**
  773. * @return Returns the boolean _isDebuff.
  774. */
  775. public final boolean isDebuff()
  776. {
  777. return _isDebuff;
  778. }
  779.  
  780. /**
  781. * @return the skill id.
  782. */
  783. public final int getId()
  784. {
  785. return _id;
  786. }
  787.  
  788. public final Stats getStat()
  789. {
  790. return _stat;
  791. }
  792.  
  793. /**
  794. * @return the _targetConsumeId.
  795. */
  796. public final int getTargetConsumeId()
  797. {
  798. return _targetConsumeId;
  799. }
  800.  
  801. /**
  802. * @return the targetConsume.
  803. */
  804. public final int getTargetConsume()
  805. {
  806. return _targetConsume;
  807. }
  808.  
  809. /**
  810. * @return the itemConsume.
  811. */
  812. public final int getItemConsume()
  813. {
  814. return _itemConsume;
  815. }
  816.  
  817. /**
  818. * @return the itemConsumeId.
  819. */
  820. public final int getItemConsumeId()
  821. {
  822. return _itemConsumeId;
  823. }
  824.  
  825. /**
  826. * @return the level.
  827. */
  828. public final int getLevel()
  829. {
  830. return _level;
  831. }
  832.  
  833. /**
  834. * @return the magic.
  835. */
  836. public final boolean isMagic()
  837. {
  838. return _magic;
  839. }
  840.  
  841. /**
  842. * @return true to set static reuse.
  843. */
  844. public final boolean isStaticReuse()
  845. {
  846. return _staticReuse;
  847. }
  848.  
  849. /**
  850. * @return true to set static hittime.
  851. */
  852. public final boolean isStaticHitTime()
  853. {
  854. return _staticHitTime;
  855. }
  856.  
  857. /**
  858. * @return Returns the mpConsume.
  859. */
  860. public final int getMpConsume()
  861. {
  862. return _mpConsume;
  863. }
  864.  
  865. /**
  866. * @return Returns the mpInitialConsume.
  867. */
  868. public final int getMpInitialConsume()
  869. {
  870. return _mpInitialConsume;
  871. }
  872.  
  873. /**
  874. * @return Returns the name.
  875. */
  876. public final String getName()
  877. {
  878. return _name;
  879. }
  880.  
  881. /**
  882. * @return Returns the reuseDelay.
  883. */
  884. public final int getReuseDelay()
  885. {
  886. return _reuseDelay;
  887. }
  888.  
  889. public final int getEquipDelay()
  890. {
  891. return _equipDelay;
  892. }
  893.  
  894. public final int getReuseHashCode()
  895. {
  896. return _reuseHashCode;
  897. }
  898.  
  899. public final int getHitTime()
  900. {
  901. return _hitTime;
  902. }
  903.  
  904. /**
  905. * @return Returns the coolTime.
  906. */
  907. public final int getCoolTime()
  908. {
  909. return _coolTime;
  910. }
  911.  
  912. public final int getSkillRadius()
  913. {
  914. return _skillRadius;
  915. }
  916.  
  917. public final boolean isActive()
  918. {
  919. return _operateType == SkillOpType.OP_ACTIVE;
  920. }
  921.  
  922. public final boolean isPassive()
  923. {
  924. return _operateType == SkillOpType.OP_PASSIVE;
  925. }
  926.  
  927. public final boolean isToggle()
  928. {
  929. return _operateType == SkillOpType.OP_TOGGLE;
  930. }
  931.  
  932. public boolean isChance()
  933. {
  934. return _chanceCondition != null && isPassive();
  935. }
  936.  
  937. public final boolean isDance()
  938. {
  939. return _isDance;
  940. }
  941.  
  942. public final int getNextDanceMpCost()
  943. {
  944. return _nextDanceCost;
  945. }
  946.  
  947. public final float getSSBoost()
  948. {
  949. return _sSBoost;
  950. }
  951.  
  952. public final int getAggroPoints()
  953. {
  954. return _aggroPoints;
  955. }
  956.  
  957. public final boolean useSoulShot()
  958. {
  959. switch (_skillType)
  960. {
  961. case BLOW:
  962. case PDAM:
  963. case STUN:
  964. case CHARGEDAM:
  965. return true;
  966. }
  967. return false;
  968. }
  969.  
  970. public final boolean useSpiritShot()
  971. {
  972. return isMagic();
  973. }
  974.  
  975. public final int getWeaponsAllowed()
  976. {
  977. return _weaponsAllowed;
  978. }
  979.  
  980. public boolean isSimultaneousCast()
  981. {
  982. return _simultaneousCast;
  983. }
  984.  
  985. public int getMinPledgeClass()
  986. {
  987. return _minPledgeClass;
  988. }
  989.  
  990. public String getAttributeName()
  991. {
  992. return _attribute;
  993. }
  994.  
  995. public boolean ignoreShield()
  996. {
  997. return _ignoreShield;
  998. }
  999.  
  1000. public boolean canBeReflected()
  1001. {
  1002. return _canBeReflected;
  1003. }
  1004.  
  1005. public boolean canBeDispeled()
  1006. {
  1007. return _canBeDispeled;
  1008. }
  1009.  
  1010. public boolean isClanSkill()
  1011. {
  1012. return _isClanSkill;
  1013. }
  1014.  
  1015. public final String getFlyType()
  1016. {
  1017. return _flyType;
  1018. }
  1019.  
  1020. public final int getFlyRadius()
  1021. {
  1022. return _flyRadius;
  1023. }
  1024.  
  1025. public int getFeed()
  1026. {
  1027. return _feed;
  1028. }
  1029.  
  1030. public final float getFlyCourse()
  1031. {
  1032. return _flyCourse;
  1033. }
  1034.  
  1035. public final int getMaxCharges()
  1036. {
  1037. return _maxCharges;
  1038. }
  1039.  
  1040. @Override
  1041. public boolean triggersChanceSkill()
  1042. {
  1043. return _triggeredId > 0 && isChance();
  1044. }
  1045.  
  1046. @Override
  1047. public int getTriggeredChanceId()
  1048. {
  1049. return _triggeredId;
  1050. }
  1051.  
  1052. @Override
  1053. public int getTriggeredChanceLevel()
  1054. {
  1055. return _triggeredLevel;
  1056. }
  1057.  
  1058. @Override
  1059. public ChanceCondition getTriggeredChanceCondition()
  1060. {
  1061. return _chanceCondition;
  1062. }
  1063.  
  1064. public final boolean isPvpSkill()
  1065. {
  1066. switch (_skillType)
  1067. {
  1068. case DOT:
  1069. case BLEED:
  1070. case POISON:
  1071. case DEBUFF:
  1072. case AGGDEBUFF:
  1073. case STUN:
  1074. case ROOT:
  1075. case FEAR:
  1076. case SLEEP:
  1077. case MDOT:
  1078. case MUTE:
  1079. case WEAKNESS:
  1080. case PARALYZE:
  1081. case CANCEL:
  1082. case MAGE_BANE:
  1083. case WARRIOR_BANE:
  1084. case BETRAY:
  1085. case AGGDAMAGE:
  1086. case AGGREDUCE_CHAR:
  1087. case MANADAM:
  1088. return true;
  1089. default:
  1090. return false;
  1091. }
  1092. }
  1093.  
  1094. public final boolean is7Signs()
  1095. {
  1096. if (_id > 4360 && _id < 4367)
  1097. return true;
  1098. return false;
  1099. }
  1100.  
  1101. public final boolean isStayAfterDeath()
  1102. {
  1103. return _stayAfterDeath;
  1104. }
  1105.  
  1106. public final boolean isOffensive()
  1107. {
  1108. return _isOffensive;
  1109. }
  1110.  
  1111. public final boolean isHeroSkill()
  1112. {
  1113. return _isHeroSkill;
  1114. }
  1115.  
  1116. public final int getNumCharges()
  1117. {
  1118. return _numCharges;
  1119. }
  1120.  
  1121. public final int getBaseCritRate()
  1122. {
  1123. return _baseCritRate;
  1124. }
  1125.  
  1126. public final int getLethalChance1()
  1127. {
  1128. return _lethalEffect1;
  1129. }
  1130.  
  1131. public final int getLethalChance2()
  1132. {
  1133. return _lethalEffect2;
  1134. }
  1135.  
  1136. public final boolean getDmgDirectlyToHP()
  1137. {
  1138. return _directHpDmg;
  1139. }
  1140.  
  1141. public final boolean isSkillTypeOffensive()
  1142. {
  1143. switch (_skillType)
  1144. {
  1145. case PDAM:
  1146. case MDAM:
  1147. case CPDAMPERCENT:
  1148. case DOT:
  1149. case BLEED:
  1150. case POISON:
  1151. case AGGDAMAGE:
  1152. case DEBUFF:
  1153. case AGGDEBUFF:
  1154. case STUN:
  1155. case ROOT:
  1156. case CONFUSION:
  1157. case ERASE:
  1158. case BLOW:
  1159. case FATAL:
  1160. case FEAR:
  1161. case DRAIN:
  1162. case SLEEP:
  1163. case CHARGEDAM:
  1164. case DEATHLINK:
  1165. case DETECT_WEAKNESS:
  1166. case MANADAM:
  1167. case MDOT:
  1168. case MUTE:
  1169. case SOULSHOT:
  1170. case SPIRITSHOT:
  1171. case SPOIL:
  1172. case WEAKNESS:
  1173. case SWEEP:
  1174. case PARALYZE:
  1175. case DRAIN_SOUL:
  1176. case AGGREDUCE:
  1177. case CANCEL:
  1178. case MAGE_BANE:
  1179. case WARRIOR_BANE:
  1180. case AGGREMOVE:
  1181. case AGGREDUCE_CHAR:
  1182. case BETRAY:
  1183. case DELUXE_KEY_UNLOCK:
  1184. case SOW:
  1185. case HARVEST:
  1186. case INSTANT_JUMP:
  1187. return true;
  1188. default:
  1189. return isDebuff();
  1190. }
  1191. }
  1192.  
  1193. public final boolean getWeaponDependancy(L2Character activeChar)
  1194. {
  1195. int weaponsAllowed = getWeaponsAllowed();
  1196. // check to see if skill has a weapon dependency.
  1197. if (weaponsAllowed == 0)
  1198. return true;
  1199.  
  1200. int mask = 0;
  1201.  
  1202. if (activeChar.getActiveWeaponItem() != null)
  1203. mask |= activeChar.getActiveWeaponItem().getItemType().mask();
  1204. if (activeChar.getSecondaryWeaponItem() != null && activeChar.getSecondaryWeaponItem() instanceof Armor)
  1205. mask |= ((ArmorType) activeChar.getSecondaryWeaponItem().getItemType()).mask();
  1206.  
  1207. if ((mask & weaponsAllowed) != 0)
  1208. return true;
  1209.  
  1210. activeChar.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.S1_CANNOT_BE_USED).addSkillName(this));
  1211. return false;
  1212. }
  1213.  
  1214. public boolean checkCondition(L2Character activeChar, L2Object target, boolean itemOrWeapon)
  1215. {
  1216. final List<Condition> preCondition = (itemOrWeapon) ? _itemPreCondition : _preCondition;
  1217. if (preCondition == null || preCondition.isEmpty())
  1218. return true;
  1219.  
  1220. final Env env = new Env();
  1221. env.setCharacter(activeChar);
  1222. if (target instanceof L2Character)
  1223. env.setTarget((L2Character) target);
  1224.  
  1225. env.setSkill(this);
  1226.  
  1227. for (Condition cond : preCondition)
  1228. {
  1229. if (!cond.test(env))
  1230. {
  1231. final int msgId = cond.getMessageId();
  1232. if (msgId != 0)
  1233. {
  1234. SystemMessage sm = SystemMessage.getSystemMessage(msgId);
  1235. if (cond.isAddName())
  1236. sm.addSkillName(_id);
  1237. activeChar.sendPacket(sm);
  1238. }
  1239. else
  1240. {
  1241. final String msg = cond.getMessage();
  1242. if (msg != null)
  1243. activeChar.sendMessage(msg);
  1244. }
  1245. return false;
  1246. }
  1247. }
  1248. return true;
  1249. }
  1250.  
  1251. public final L2Object[] getTargetList(L2Character activeChar, boolean onlyFirst)
  1252. {
  1253. // Init to null the target of the skill
  1254. L2Character target = null;
  1255.  
  1256. // Get the L2Objcet targeted by the user of the skill at this moment
  1257. L2Object objTarget = activeChar.getTarget();
  1258. // If the L2Object targeted is a L2Character, it becomes the L2Character target
  1259. if (objTarget instanceof L2Character)
  1260. {
  1261. target = (L2Character) objTarget;
  1262. }
  1263.  
  1264. return getTargetList(activeChar, onlyFirst, target);
  1265. }
  1266.  
  1267. /**
  1268. * @param activeChar : The skill caster.
  1269. * @param onlyFirst : Returns the first target only, dropping others results.
  1270. * @param target : The skill target, which can be used as a radius center or as main target.
  1271. * @return an L2Object[] consisting of all targets, depending of the skill type.
  1272. */
  1273. public final L2Object[] getTargetList(L2Character activeChar, boolean onlyFirst, L2Character target)
  1274. {
  1275. switch (_targetType)
  1276. {
  1277. case TARGET_ONE:
  1278. {
  1279. boolean canTargetSelf = false;
  1280. switch (_skillType)
  1281. {
  1282. case BUFF:
  1283. case HEAL:
  1284. case HOT:
  1285. case HEAL_PERCENT:
  1286. case MANARECHARGE:
  1287. case MANAHEAL:
  1288. case NEGATE:
  1289. case CANCEL_DEBUFF:
  1290. case REFLECT:
  1291. case COMBATPOINTHEAL:
  1292. case SEED:
  1293. case BALANCE_LIFE:
  1294. canTargetSelf = true;
  1295. break;
  1296. }
  1297.  
  1298. if (target == null || target.isDead() || (target == activeChar && !canTargetSelf))
  1299. {
  1300. activeChar.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.TARGET_IS_INCORRECT));
  1301. return _emptyTargetList;
  1302. }
  1303.  
  1304. return new L2Character[]
  1305. {
  1306. target
  1307. };
  1308. }
  1309. case TARGET_SELF:
  1310. case TARGET_GROUND:
  1311. {
  1312. return new L2Character[]
  1313. {
  1314. activeChar
  1315. };
  1316. }
  1317. case TARGET_HOLY:
  1318. {
  1319. if (!(target instanceof L2ArtefactInstance))
  1320. {
  1321. activeChar.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.TARGET_IS_INCORRECT));
  1322. return _emptyTargetList;
  1323. }
  1324.  
  1325. return new L2Character[]
  1326. {
  1327. target
  1328. };
  1329. }
  1330. case TARGET_PET:
  1331. {
  1332. target = activeChar.getPet();
  1333. if (target != null && !target.isDead())
  1334. return new L2Character[]
  1335. {
  1336. target
  1337. };
  1338.  
  1339. return _emptyTargetList;
  1340. }
  1341. case TARGET_SUMMON:
  1342. {
  1343. target = activeChar.getPet();
  1344. if (target != null && !target.isDead() && target instanceof L2SummonInstance)
  1345. return new L2Character[]
  1346. {
  1347. target
  1348. };
  1349.  
  1350. return _emptyTargetList;
  1351. }
  1352. case TARGET_OWNER_PET:
  1353. {
  1354. if (activeChar instanceof L2Summon)
  1355. {
  1356. target = activeChar.getActingPlayer();
  1357. if (target != null && !target.isDead())
  1358. return new L2Character[]
  1359. {
  1360. target
  1361. };
  1362. }
  1363.  
  1364. return _emptyTargetList;
  1365. }
  1366. case TARGET_CORPSE_PET:
  1367. {
  1368. if (activeChar instanceof L2PcInstance)
  1369. {
  1370. target = activeChar.getPet();
  1371. if (target != null && target.isDead())
  1372. return new L2Character[]
  1373. {
  1374. target
  1375. };
  1376. }
  1377.  
  1378. return _emptyTargetList;
  1379. }
  1380. case TARGET_AURA:
  1381. case TARGET_FRONT_AURA:
  1382. case TARGET_BEHIND_AURA:
  1383. {
  1384. List<L2Character> targetList = new ArrayList<>();
  1385.  
  1386. // Go through the L2Character _knownList
  1387. if (_skillType == L2SkillType.DUMMY)
  1388. {
  1389. if (onlyFirst)
  1390. return new L2Character[]
  1391. {
  1392. activeChar
  1393. };
  1394.  
  1395. final L2PcInstance sourcePlayer = activeChar.getActingPlayer();
  1396.  
  1397. targetList.add(activeChar);
  1398. for (L2Character obj : activeChar.getKnownList().getKnownTypeInRadius(L2Character.class, _skillRadius))
  1399. {
  1400. if (!(obj == activeChar || obj == sourcePlayer || obj instanceof L2Npc || obj instanceof L2Attackable))
  1401. continue;
  1402.  
  1403. targetList.add(obj);
  1404. }
  1405. }
  1406. else
  1407. {
  1408. final boolean srcInArena = activeChar.isInArena();
  1409.  
  1410. for (L2Character obj : activeChar.getKnownList().getKnownTypeInRadius(L2Character.class, _skillRadius))
  1411. {
  1412. if (obj instanceof L2Attackable || obj instanceof L2Playable)
  1413. {
  1414. switch (_targetType)
  1415. {
  1416. case TARGET_FRONT_AURA:
  1417. if (!obj.isInFrontOf(activeChar))
  1418. continue;
  1419. break;
  1420. case TARGET_BEHIND_AURA:
  1421. if (!obj.isBehind(activeChar))
  1422. continue;
  1423. break;
  1424. }
  1425.  
  1426. if (!checkForAreaOffensiveSkills(activeChar, obj, this, srcInArena))
  1427. continue;
  1428.  
  1429. if (onlyFirst)
  1430. return new L2Character[]
  1431. {
  1432. obj
  1433. };
  1434.  
  1435. targetList.add(obj);
  1436. }
  1437. }
  1438. }
  1439. return targetList.toArray(new L2Character[targetList.size()]);
  1440. }
  1441. case TARGET_AREA_SUMMON:
  1442. {
  1443. target = activeChar.getPet();
  1444. if (target == null || !(target instanceof L2SummonInstance) || target.isDead())
  1445. return _emptyTargetList;
  1446.  
  1447. if (onlyFirst)
  1448. return new L2Character[]
  1449. {
  1450. target
  1451. };
  1452.  
  1453. final boolean srcInArena = activeChar.isInArena();
  1454. List<L2Character> targetList = new ArrayList<>();
  1455.  
  1456. for (L2Character obj : target.getKnownList().getKnownType(L2Character.class))
  1457. {
  1458. if (obj == null || obj == target || obj == activeChar)
  1459. continue;
  1460.  
  1461. if (!Util.checkIfInRange(_skillRadius, target, obj, true))
  1462. continue;
  1463.  
  1464. if (!(obj instanceof L2Attackable || obj instanceof L2Playable))
  1465. continue;
  1466.  
  1467. if (!checkForAreaOffensiveSkills(activeChar, obj, this, srcInArena))
  1468. continue;
  1469.  
  1470. targetList.add(obj);
  1471. }
  1472.  
  1473. if (targetList.isEmpty())
  1474. return _emptyTargetList;
  1475.  
  1476. return targetList.toArray(new L2Character[targetList.size()]);
  1477. }
  1478. case TARGET_AREA:
  1479. case TARGET_FRONT_AREA:
  1480. case TARGET_BEHIND_AREA:
  1481. {
  1482. if (((target == null || target == activeChar || target.isAlikeDead()) && _castRange >= 0) || (!(target instanceof L2Attackable || target instanceof L2Playable)))
  1483. {
  1484. activeChar.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.TARGET_IS_INCORRECT));
  1485. return _emptyTargetList;
  1486. }
  1487.  
  1488. final L2Character origin;
  1489. final boolean srcInArena = activeChar.isInArena();
  1490. List<L2Character> targetList = new ArrayList<>();
  1491.  
  1492. if (_castRange >= 0)
  1493. {
  1494. if (!checkForAreaOffensiveSkills(activeChar, target, this, srcInArena))
  1495. return _emptyTargetList;
  1496.  
  1497. if (onlyFirst)
  1498. return new L2Character[]
  1499. {
  1500. target
  1501. };
  1502.  
  1503. origin = target;
  1504. targetList.add(origin); // Add target to target list
  1505. }
  1506. else
  1507. origin = activeChar;
  1508.  
  1509. for (L2Character obj : activeChar.getKnownList().getKnownType(L2Character.class))
  1510. {
  1511. if (!(obj instanceof L2Attackable || obj instanceof L2Playable))
  1512. continue;
  1513.  
  1514. if (obj == origin)
  1515. continue;
  1516.  
  1517. if (Util.checkIfInRange(_skillRadius, origin, obj, true))
  1518. {
  1519. switch (_targetType)
  1520. {
  1521. case TARGET_FRONT_AREA:
  1522. if (!obj.isInFrontOf(activeChar))
  1523. continue;
  1524. break;
  1525. case TARGET_BEHIND_AREA:
  1526. if (!obj.isBehind(activeChar))
  1527. continue;
  1528. break;
  1529. }
  1530.  
  1531. if (!checkForAreaOffensiveSkills(activeChar, obj, this, srcInArena))
  1532. continue;
  1533.  
  1534. targetList.add(obj);
  1535. }
  1536. }
  1537.  
  1538. if (targetList.isEmpty())
  1539. return _emptyTargetList;
  1540.  
  1541. return targetList.toArray(new L2Character[targetList.size()]);
  1542. }
  1543. case TARGET_PARTY:
  1544. {
  1545. if (onlyFirst)
  1546. return new L2Character[]
  1547. {
  1548. activeChar
  1549. };
  1550.  
  1551. List<L2Character> targetList = new ArrayList<>();
  1552. targetList.add(activeChar);
  1553.  
  1554. final int radius = _skillRadius;
  1555. final L2PcInstance player = activeChar.getActingPlayer();
  1556.  
  1557. if (activeChar instanceof L2Summon)
  1558. {
  1559. if (addCharacter(activeChar, player, radius, false))
  1560. targetList.add(player);
  1561. }
  1562. else if (activeChar instanceof L2PcInstance)
  1563. {
  1564. if (addSummon(activeChar, player, radius, false))
  1565. targetList.add(player.getPet());
  1566. }
  1567.  
  1568. if (activeChar.isInParty())
  1569. {
  1570. // Get a list of Party Members
  1571. for (L2PcInstance partyMember : activeChar.getParty().getPartyMembers())
  1572. {
  1573. if (partyMember == null || partyMember == player)
  1574. continue;
  1575.  
  1576. if (addCharacter(activeChar, partyMember, radius, false))
  1577. targetList.add(partyMember);
  1578.  
  1579. if (addSummon(activeChar, partyMember, radius, false))
  1580. targetList.add(partyMember.getPet());
  1581. }
  1582. }
  1583. return targetList.toArray(new L2Character[targetList.size()]);
  1584. }
  1585. case TARGET_PARTY_MEMBER:
  1586. {
  1587. if (target != null && (target == activeChar || (activeChar.isInParty() && target.isInParty() && activeChar.getParty().getPartyLeaderOID() == target.getParty().getPartyLeaderOID()) || (activeChar instanceof L2PcInstance && target instanceof L2Summon && activeChar.getPet() == target) || (activeChar instanceof L2Summon && target instanceof L2PcInstance && activeChar == target.getPet())))
  1588. {
  1589. if (!target.isDead())
  1590. {
  1591. // If a target is found, return it in a table else send a system message TARGET_IS_INCORRECT
  1592. return new L2Character[]
  1593. {
  1594. target
  1595. };
  1596. }
  1597. return _emptyTargetList;
  1598. }
  1599.  
  1600. activeChar.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.TARGET_IS_INCORRECT));
  1601. return _emptyTargetList;
  1602. }
  1603. case TARGET_PARTY_OTHER:
  1604. {
  1605. if (target != null && target != activeChar && activeChar.isInParty() && target.isInParty() && activeChar.getParty().getPartyLeaderOID() == target.getParty().getPartyLeaderOID())
  1606. {
  1607. if (!target.isDead())
  1608. {
  1609. if (target instanceof L2PcInstance)
  1610. {
  1611. switch (getId())
  1612. {
  1613. // FORCE BUFFS may cancel here but there should be a proper condition
  1614. case 426:
  1615. if (!((L2PcInstance) target).isMageClass())
  1616. return new L2Character[]
  1617. {
  1618. target
  1619. };
  1620. return _emptyTargetList;
  1621.  
  1622. case 427:
  1623. if (((L2PcInstance) target).isMageClass())
  1624. return new L2Character[]
  1625. {
  1626. target
  1627. };
  1628.  
  1629. return _emptyTargetList;
  1630. }
  1631. }
  1632. return new L2Character[]
  1633. {
  1634. target
  1635. };
  1636. }
  1637. return _emptyTargetList;
  1638. }
  1639.  
  1640. activeChar.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.TARGET_IS_INCORRECT));
  1641. return _emptyTargetList;
  1642. }
  1643. case TARGET_ALLY:
  1644. {
  1645. final L2PcInstance player = activeChar.getActingPlayer();
  1646. if (player == null)
  1647. return _emptyTargetList;
  1648.  
  1649. if (onlyFirst || player.isInOlympiadMode())
  1650. return new L2Character[]
  1651. {
  1652. activeChar
  1653. };
  1654.  
  1655. List<L2Character> targetList = new ArrayList<>();
  1656. targetList.add(player);
  1657.  
  1658. final int radius = _skillRadius;
  1659.  
  1660. if (addSummon(activeChar, player, radius, false))
  1661. targetList.add(player.getPet());
  1662.  
  1663. if (player.getClan() != null)
  1664. {
  1665. for (L2PcInstance obj : activeChar.getKnownList().getKnownTypeInRadius(L2PcInstance.class, radius))
  1666. {
  1667. if ((obj.getAllyId() == 0 || obj.getAllyId() != player.getAllyId()) && (obj.getClan() == null || obj.getClanId() != player.getClanId()))
  1668. continue;
  1669.  
  1670. if (player.isInDuel())
  1671. {
  1672. if (player.getDuelId() != obj.getDuelId())
  1673. continue;
  1674.  
  1675. if (player.isInParty() && obj.isInParty() && player.getParty().getPartyLeaderOID() != obj.getParty().getPartyLeaderOID())
  1676. continue;
  1677. }
  1678.  
  1679. if (!player.checkPvpSkill(obj, this))
  1680. continue;
  1681.  
  1682. if (!TvTEvent.checkForTvTSkill(player, obj, this) || !DMEvent.checkForDMSkill(player, obj, this))
  1683. {
  1684. continue;
  1685. }
  1686.  
  1687. final L2Summon summon = obj.getPet();
  1688. if (summon != null && !summon.isDead())
  1689. targetList.add(summon);
  1690.  
  1691. if (!obj.isDead())
  1692. targetList.add(obj);
  1693. }
  1694. }
  1695. return targetList.toArray(new L2Character[targetList.size()]);
  1696. }
  1697. case TARGET_CORPSE_ALLY:
  1698. {
  1699. final L2PcInstance player = activeChar.getActingPlayer();
  1700. if (player == null)
  1701. return _emptyTargetList;
  1702.  
  1703. if (onlyFirst || player.isInOlympiadMode())
  1704. return new L2Character[]
  1705. {
  1706. activeChar
  1707. };
  1708.  
  1709. final int radius = _skillRadius;
  1710. List<L2Character> targetList = new ArrayList<>();
  1711.  
  1712. targetList.add(activeChar);
  1713.  
  1714. if (player.getClan() != null)
  1715. {
  1716. for (L2PcInstance obj : activeChar.getKnownList().getKnownTypeInRadius(L2PcInstance.class, radius))
  1717. {
  1718. if (!obj.isDead())
  1719. continue;
  1720.  
  1721. if ((obj.getAllyId() == 0 || obj.getAllyId() != player.getAllyId()) && (obj.getClan() == null || obj.getClanId() != player.getClanId()))
  1722. continue;
  1723.  
  1724. if (player.isInDuel())
  1725. {
  1726. if (player.getDuelId() != obj.getDuelId())
  1727. continue;
  1728.  
  1729. if (player.isInParty() && obj.isInParty() && player.getParty().getPartyLeaderOID() != obj.getParty().getPartyLeaderOID())
  1730. continue;
  1731. }
  1732.  
  1733. if (!TvTEvent.checkForTvTSkill(player, obj, this) || !DMEvent.checkForDMSkill(player, obj, this))
  1734. {
  1735. continue;
  1736. }
  1737.  
  1738. // Siege battlefield resurrect has been made possible for participants
  1739. if (obj.isInsideZone(ZoneId.SIEGE) && !obj.isInSiege())
  1740. continue;
  1741.  
  1742. targetList.add(obj);
  1743. }
  1744. }
  1745. return targetList.toArray(new L2Character[targetList.size()]);
  1746. }
  1747. case TARGET_CLAN:
  1748. {
  1749. List<L2Character> targetList = new ArrayList<>();
  1750.  
  1751. if (activeChar instanceof L2Playable)
  1752. {
  1753. final L2PcInstance player = activeChar.getActingPlayer();
  1754. if (player == null)
  1755. return _emptyTargetList;
  1756.  
  1757. if (onlyFirst || player.isInOlympiadMode())
  1758. return new L2Character[]
  1759. {
  1760. activeChar
  1761. };
  1762.  
  1763. targetList.add(player);
  1764.  
  1765. final int radius = _skillRadius;
  1766.  
  1767. if (addSummon(activeChar, player, radius, false))
  1768. targetList.add(player.getPet());
  1769.  
  1770. final L2Clan clan = player.getClan();
  1771. if (clan != null)
  1772. {
  1773. for (L2ClanMember member : clan.getMembers())
  1774. {
  1775. final L2PcInstance obj = member.getPlayerInstance();
  1776. if (obj == null || obj == player)
  1777. continue;
  1778.  
  1779. if (player.isInDuel())
  1780. {
  1781. if (player.getDuelId() != obj.getDuelId())
  1782. continue;
  1783.  
  1784. if (player.isInParty() && obj.isInParty() && player.getParty().getPartyLeaderOID() != obj.getParty().getPartyLeaderOID())
  1785. continue;
  1786. }
  1787.  
  1788. if (!player.checkPvpSkill(obj, this))
  1789. continue;
  1790.  
  1791. if (!TvTEvent.checkForTvTSkill(player, obj, this) || !DMEvent.checkForDMSkill(player, obj, this))
  1792. {
  1793. continue;
  1794. }
  1795.  
  1796. if (addSummon(activeChar, obj, radius, false))
  1797. targetList.add(obj.getPet());
  1798.  
  1799. if (!addCharacter(activeChar, obj, radius, false))
  1800. continue;
  1801.  
  1802. targetList.add(obj);
  1803. }
  1804. }
  1805. }
  1806. else if (activeChar instanceof L2Npc)
  1807. {
  1808. targetList.add(activeChar);
  1809. for (L2Npc newTarget : activeChar.getKnownList().getKnownTypeInRadius(L2Npc.class, _castRange))
  1810. {
  1811. if (newTarget.isDead() || !Util.contains(((L2Npc) activeChar).getTemplate().getClans(), newTarget.getTemplate().getClans()))
  1812. continue;
  1813.  
  1814. targetList.add(newTarget);
  1815. }
  1816. }
  1817. return targetList.toArray(new L2Character[targetList.size()]);
  1818. }
  1819. case TARGET_CORPSE_PLAYER:
  1820. {
  1821. if (!(activeChar instanceof L2PcInstance))
  1822. return _emptyTargetList;
  1823.  
  1824. if (target != null && target.isDead())
  1825. {
  1826. final L2PcInstance targetPlayer;
  1827. if (target instanceof L2PcInstance)
  1828. targetPlayer = (L2PcInstance) target;
  1829. else
  1830. targetPlayer = null;
  1831.  
  1832. final L2PetInstance targetPet;
  1833. if (target instanceof L2PetInstance)
  1834. targetPet = (L2PetInstance) target;
  1835. else
  1836. targetPet = null;
  1837.  
  1838. if (targetPlayer != null || targetPet != null)
  1839. {
  1840. boolean condGood = true;
  1841.  
  1842. if (_skillType == L2SkillType.RESURRECT)
  1843. {
  1844. final L2PcInstance player = (L2PcInstance) activeChar;
  1845.  
  1846. if (targetPlayer != null)
  1847. {
  1848. // check target is not in a active siege zone
  1849. if (targetPlayer.isInsideZone(ZoneId.SIEGE) && !targetPlayer.isInSiege())
  1850. {
  1851. condGood = false;
  1852. activeChar.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.CANNOT_BE_RESURRECTED_DURING_SIEGE));
  1853. }
  1854.  
  1855. if (targetPlayer.isFestivalParticipant()) // Check to see if the current player target is in a festival.
  1856. {
  1857. condGood = false;
  1858. activeChar.sendMessage("You may not resurrect participants in a festival.");
  1859. }
  1860.  
  1861. if (targetPlayer.isReviveRequested())
  1862. {
  1863. if (targetPlayer.isRevivingPet())
  1864. player.sendPacket(SystemMessageId.MASTER_CANNOT_RES); // While a pet is attempting to resurrect, it cannot help in resurrecting its master.
  1865. else
  1866. player.sendPacket(SystemMessageId.RES_HAS_ALREADY_BEEN_PROPOSED); // Resurrection is already been proposed.
  1867. condGood = false;
  1868. }
  1869. }
  1870. else if (targetPet != null)
  1871. {
  1872. if (targetPet.getOwner() != player)
  1873. {
  1874. if (targetPet.getOwner().isReviveRequested())
  1875. {
  1876. if (targetPet.getOwner().isRevivingPet())
  1877. player.sendPacket(SystemMessageId.RES_HAS_ALREADY_BEEN_PROPOSED); // Resurrection is already been proposed.
  1878. else
  1879. player.sendPacket(SystemMessageId.CANNOT_RES_PET2); // A pet cannot be resurrected while it's owner is in the process of resurrecting.
  1880. condGood = false;
  1881. }
  1882. }
  1883. }
  1884. }
  1885.  
  1886. if (condGood)
  1887. return new L2Character[]
  1888. {
  1889. target
  1890. };
  1891. }
  1892. }
  1893. activeChar.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.TARGET_IS_INCORRECT));
  1894. return _emptyTargetList;
  1895. }
  1896. case TARGET_CORPSE_MOB:
  1897. {
  1898. if (!(target instanceof L2Attackable) || !target.isDead())
  1899. {
  1900. activeChar.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.TARGET_IS_INCORRECT));
  1901. return _emptyTargetList;
  1902. }
  1903.  
  1904. // Corpse mob only available for half time
  1905. if (_skillType == L2SkillType.DRAIN && !DecayTaskManager.getInstance().isCorpseActionAllowed((L2Attackable) target))
  1906. {
  1907. activeChar.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.CORPSE_TOO_OLD_SKILL_NOT_USED));
  1908. return _emptyTargetList;
  1909. }
  1910.  
  1911. return new L2Character[]
  1912. {
  1913. target
  1914. };
  1915. }
  1916. case TARGET_AREA_CORPSE_MOB:
  1917. {
  1918. if ((!(target instanceof L2Attackable)) || !target.isDead())
  1919. {
  1920. activeChar.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.TARGET_IS_INCORRECT));
  1921. return _emptyTargetList;
  1922. }
  1923.  
  1924. if (onlyFirst)
  1925. return new L2Character[]
  1926. {
  1927. target
  1928. };
  1929.  
  1930. List<L2Character> targetList = new ArrayList<>();
  1931. targetList.add(target);
  1932.  
  1933. final boolean srcInArena = activeChar.isInArena();
  1934.  
  1935. for (L2Character obj : activeChar.getKnownList().getKnownTypeInRadius(L2Character.class, _skillRadius))
  1936. {
  1937. if (!(obj instanceof L2Attackable || obj instanceof L2Playable))
  1938. continue;
  1939.  
  1940. if (!checkForAreaOffensiveSkills(activeChar, obj, this, srcInArena))
  1941. continue;
  1942.  
  1943. targetList.add(obj);
  1944. }
  1945.  
  1946. if (targetList.isEmpty())
  1947. return _emptyTargetList;
  1948.  
  1949. return targetList.toArray(new L2Character[targetList.size()]);
  1950. }
  1951. case TARGET_UNLOCKABLE:
  1952. {
  1953. if (!(target instanceof L2DoorInstance) && !(target instanceof L2ChestInstance))
  1954. return _emptyTargetList;
  1955.  
  1956. return new L2Character[]
  1957. {
  1958. target
  1959. };
  1960.  
  1961. }
  1962. case TARGET_UNDEAD:
  1963. {
  1964. if (target instanceof L2Npc || target instanceof L2SummonInstance)
  1965. {
  1966. if (!target.isUndead() || target.isDead())
  1967. {
  1968. activeChar.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.TARGET_IS_INCORRECT));
  1969. return _emptyTargetList;
  1970. }
  1971.  
  1972. return new L2Character[]
  1973. {
  1974. target
  1975. };
  1976. }
  1977.  
  1978. activeChar.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.TARGET_IS_INCORRECT));
  1979. return _emptyTargetList;
  1980. }
  1981. case TARGET_AURA_UNDEAD:
  1982. {
  1983. List<L2Character> targetList = new ArrayList<>();
  1984.  
  1985. for (L2Character obj : activeChar.getKnownList().getKnownTypeInRadius(L2Character.class, _skillRadius))
  1986. {
  1987. if (obj instanceof L2Npc || obj instanceof L2SummonInstance)
  1988. target = obj;
  1989. else
  1990. continue;
  1991.  
  1992. if (target.isAlikeDead() || !target.isUndead())
  1993. continue;
  1994.  
  1995. if (!GeoEngine.getInstance().canSeeTarget(activeChar, target))
  1996. continue;
  1997.  
  1998. if (onlyFirst)
  1999. return new L2Character[]
  2000. {
  2001. obj
  2002. };
  2003.  
  2004. targetList.add(obj);
  2005. }
  2006.  
  2007. if (targetList.isEmpty())
  2008. return _emptyTargetList;
  2009.  
  2010. return targetList.toArray(new L2Character[targetList.size()]);
  2011. }
  2012. case TARGET_ENEMY_SUMMON:
  2013. {
  2014. if (target instanceof L2Summon)
  2015. {
  2016. final L2Summon targetSummon = (L2Summon) target;
  2017. final L2PcInstance summonOwner = targetSummon.getActingPlayer();
  2018.  
  2019. if (activeChar instanceof L2PcInstance && activeChar.getPet() != targetSummon && !targetSummon.isDead() && (summonOwner.getPvpFlag() != 0 || summonOwner.getKarma() > 0) || (summonOwner.isInsideZone(ZoneId.PVP) && activeChar.isInsideZone(ZoneId.PVP)) || (summonOwner.isInDuel() && ((L2PcInstance) activeChar).isInDuel() && summonOwner.getDuelId() == ((L2PcInstance) activeChar).getDuelId()))
  2020. return new L2Character[]
  2021. {
  2022. targetSummon
  2023. };
  2024. }
  2025. return _emptyTargetList;
  2026. }
  2027. default:
  2028. {
  2029. activeChar.sendMessage("Target type of skill is not currently handled");
  2030. return _emptyTargetList;
  2031. }
  2032. }
  2033. }
  2034.  
  2035. public final L2Object[] getTargetList(L2Character activeChar)
  2036. {
  2037. return getTargetList(activeChar, false);
  2038. }
  2039.  
  2040. public final L2Object getFirstOfTargetList(L2Character activeChar)
  2041. {
  2042. L2Object[] targets = getTargetList(activeChar, true);
  2043. if (targets.length == 0)
  2044. return null;
  2045.  
  2046. return targets[0];
  2047. }
  2048.  
  2049. /**
  2050. * Check if target should be added to the target list.
  2051. * <ul>
  2052. * <li>Target is dead.</li>
  2053. * <li>Target same as caster.</li>
  2054. * <li>Target inside peace zone.</li>
  2055. * <li>Target in the same party than caster.</li>
  2056. * <li>Caster can see target.</li>
  2057. * </ul>
  2058. * Additional checks.
  2059. * <ul>
  2060. * <li>Mustn't be in Observer mode.</li>
  2061. * <li>If not in PvP zones (arena, siege): target in not the same clan and alliance with caster, and usual PvP skill check.</li>
  2062. * <li>In case caster and target are L2Attackable : verify if caster isn't confused.</li>
  2063. * </ul>
  2064. * Caution: distance is not checked.
  2065. * @param caster The skill caster.
  2066. * @param target The victim
  2067. * @param skill The skill to use.
  2068. * @param sourceInArena True means the caster is in a pvp or siege zone, and so the additional check will be skipped.
  2069. * @return
  2070. */
  2071. public static final boolean checkForAreaOffensiveSkills(L2Character caster, L2Character target, L2Skill skill, boolean sourceInArena)
  2072. {
  2073. if (target == null || target.isDead() || target == caster)
  2074. return false;
  2075.  
  2076. final L2PcInstance player = caster.getActingPlayer();
  2077. final L2PcInstance targetPlayer = target.getActingPlayer();
  2078. if (player != null && targetPlayer != null)
  2079. {
  2080. if (targetPlayer == caster || targetPlayer == player)
  2081. return false;
  2082.  
  2083. if (targetPlayer.inObserverMode())
  2084. return false;
  2085.  
  2086. if (!TvTEvent.checkForTvTSkill(player, targetPlayer, skill) || !DMEvent.checkForDMSkill(player, targetPlayer, skill))
  2087. {
  2088. return false;
  2089. }
  2090.  
  2091. if (skill.isOffensive() && player.getSiegeState() > 0 && player.isInsideZone(ZoneId.SIEGE) && player.getSiegeState() == targetPlayer.getSiegeState())
  2092. return false;
  2093.  
  2094. if (target.isInsideZone(ZoneId.PEACE))
  2095. return false;
  2096.  
  2097. if (player.isInParty() && targetPlayer.isInParty())
  2098. {
  2099. // Same party
  2100. if (player.getParty().getPartyLeaderOID() == targetPlayer.getParty().getPartyLeaderOID())
  2101. return false;
  2102.  
  2103. // Same commandchannel
  2104. if (player.getParty().getCommandChannel() != null && player.getParty().getCommandChannel() == targetPlayer.getParty().getCommandChannel())
  2105. return false;
  2106. }
  2107.  
  2108. if (!sourceInArena && !(targetPlayer.isInsideZone(ZoneId.PVP) && !targetPlayer.isInsideZone(ZoneId.SIEGE)))
  2109. {
  2110. if (player.getAllyId() != 0 && player.getAllyId() == targetPlayer.getAllyId())
  2111. return false;
  2112.  
  2113. if (player.getClanId() != 0 && player.getClanId() == targetPlayer.getClanId())
  2114. return false;
  2115.  
  2116. if (!player.checkPvpSkill(targetPlayer, skill))
  2117. return false;
  2118. }
  2119. }
  2120. else if (target instanceof L2Attackable)
  2121. {
  2122. if (caster instanceof L2Attackable && !caster.isConfused())
  2123. return false;
  2124.  
  2125. if (skill.isOffensive() && !target.isAutoAttackable(caster))
  2126. return false;
  2127. }
  2128. return GeoEngine.getInstance().canSeeTarget(caster, target);
  2129. }
  2130.  
  2131. public static final boolean addSummon(L2Character caster, L2PcInstance owner, int radius, boolean isDead)
  2132. {
  2133. final L2Summon summon = owner.getPet();
  2134.  
  2135. if (summon == null)
  2136. return false;
  2137.  
  2138. return addCharacter(caster, summon, radius, isDead);
  2139. }
  2140.  
  2141. public static final boolean addCharacter(L2Character caster, L2Character target, int radius, boolean isDead)
  2142. {
  2143. if (isDead != target.isDead())
  2144. return false;
  2145.  
  2146. if (radius > 0 && !Util.checkIfInRange(radius, caster, target, true))
  2147. return false;
  2148.  
  2149. return true;
  2150. }
  2151.  
  2152. public final List<Func> getStatFuncs(L2Character player)
  2153. {
  2154. if (_funcTemplates == null)
  2155. return Collections.emptyList();
  2156.  
  2157. if (!(player instanceof L2Playable) && !(player instanceof L2Attackable))
  2158. return Collections.emptyList();
  2159.  
  2160. final List<Func> funcs = new ArrayList<>(_funcTemplates.size());
  2161.  
  2162. final Env env = new Env();
  2163. env.setCharacter(player);
  2164. env.setSkill(this);
  2165.  
  2166. for (FuncTemplate t : _funcTemplates)
  2167. {
  2168. final Func f = t.getFunc(env, this); // skill is owner
  2169. if (f != null)
  2170. funcs.add(f);
  2171. }
  2172. return funcs;
  2173. }
  2174.  
  2175. public boolean hasEffects()
  2176. {
  2177. return (_effectTemplates != null && !_effectTemplates.isEmpty());
  2178. }
  2179.  
  2180. public List<EffectTemplate> getEffectTemplates()
  2181. {
  2182. return _effectTemplates;
  2183. }
  2184.  
  2185. public boolean hasSelfEffects()
  2186. {
  2187. return (_effectTemplatesSelf != null && !_effectTemplatesSelf.isEmpty());
  2188. }
  2189.  
  2190. /**
  2191. * @param effector
  2192. * @param effected
  2193. * @param env parameters for secondary effects (shield and ss/bss/bsss)
  2194. * @return an array with the effects that have been added to effector
  2195. */
  2196. public final List<L2Effect> getEffects(L2Character effector, L2Character effected, Env env)
  2197. {
  2198. if (!hasEffects() || isPassive())
  2199. return Collections.emptyList();
  2200.  
  2201. // doors and siege flags cannot receive any effects
  2202. if (effected instanceof L2DoorInstance || effected instanceof L2SiegeFlagInstance)
  2203. return Collections.emptyList();
  2204.  
  2205. if (effector != effected)
  2206. {
  2207. if (isOffensive() || isDebuff())
  2208. {
  2209. if (effected.isInvul())
  2210. return Collections.emptyList();
  2211.  
  2212. if (effector instanceof L2PcInstance && ((L2PcInstance) effector).isGM())
  2213. {
  2214. if (!((L2PcInstance) effector).getAccessLevel().canGiveDamage())
  2215. return Collections.emptyList();
  2216. }
  2217. }
  2218. }
  2219.  
  2220. final List<L2Effect> effects = new ArrayList<>(_effectTemplates.size());
  2221.  
  2222. if (env == null)
  2223. env = new Env();
  2224.  
  2225. env.setSkillMastery(Formulas.calcSkillMastery(effector, this));
  2226. env.setCharacter(effector);
  2227. env.setTarget(effected);
  2228. env.setSkill(this);
  2229.  
  2230. for (EffectTemplate et : _effectTemplates)
  2231. {
  2232. boolean success = true;
  2233.  
  2234. if (et.effectPower > -1)
  2235. success = Formulas.calcEffectSuccess(effector, effected, et, this, env.getShield(), env.isBlessedSpiritShot());
  2236.  
  2237. if (success)
  2238. {
  2239. final L2Effect e = et.getEffect(env);
  2240. if (e != null)
  2241. {
  2242. e.scheduleEffect();
  2243. effects.add(e);
  2244. }
  2245. }
  2246. // display fail message only for effects with icons
  2247. else if (et.icon && effector instanceof L2PcInstance)
  2248. ((L2PcInstance) effector).sendPacket(SystemMessage.getSystemMessage(SystemMessageId.S1_RESISTED_YOUR_S2).addCharName(effected).addSkillName(this));
  2249. }
  2250. return effects;
  2251. }
  2252.  
  2253. /**
  2254. * Warning: this method doesn't consider modifier (shield, ss, sps, bss) for secondary effects
  2255. * @param effector
  2256. * @param effected
  2257. * @return An array of L2Effect.
  2258. */
  2259. public final List<L2Effect> getEffects(L2Character effector, L2Character effected)
  2260. {
  2261. return getEffects(effector, effected, null);
  2262. }
  2263.  
  2264. /**
  2265. * This method has suffered some changes in CT2.2 ->CT2.3<br>
  2266. * Effect engine is now supporting secondary effects with independent success/fail calculus from effect skill. Env parameter has been added to pass parameters like soulshot, spiritshots, blessed spiritshots or shield deffence. Some other optimizations have been done <br>
  2267. * <br>
  2268. * This new feature works following next rules: <li>To enable feature, effectPower must be over -1 (check DocumentSkill#attachEffect for further information)</li> <li>If main skill fails, secondary effect always fail</li>
  2269. * @param effector
  2270. * @param effected
  2271. * @param env parameters for secondary effects (shield and ss/bss/bsss)
  2272. * @return An array of L2Effect.
  2273. */
  2274. public final List<L2Effect> getEffects(L2CubicInstance effector, L2Character effected, Env env)
  2275. {
  2276. if (!hasEffects() || isPassive())
  2277. return Collections.emptyList();
  2278.  
  2279. if (effector.getOwner() != effected)
  2280. {
  2281. if (isDebuff() || isOffensive())
  2282. {
  2283. if (effected.isInvul())
  2284. return Collections.emptyList();
  2285.  
  2286. if (effector.getOwner().isGM() && !effector.getOwner().getAccessLevel().canGiveDamage())
  2287. return Collections.emptyList();
  2288. }
  2289. }
  2290.  
  2291. final List<L2Effect> effects = new ArrayList<>(_effectTemplates.size());
  2292.  
  2293. if (env == null)
  2294. env = new Env();
  2295.  
  2296. env.setCharacter(effector.getOwner());
  2297. env.setCubic(effector);
  2298. env.setTarget(effected);
  2299. env.setSkill(this);
  2300.  
  2301. for (EffectTemplate et : _effectTemplates)
  2302. {
  2303. boolean success = true;
  2304. if (et.effectPower > -1)
  2305. success = Formulas.calcEffectSuccess(effector.getOwner(), effected, et, this, env.getShield(), env.isBlessedSpiritShot());
  2306.  
  2307. if (success)
  2308. {
  2309. final L2Effect e = et.getEffect(env);
  2310. if (e != null)
  2311. {
  2312. e.scheduleEffect();
  2313. effects.add(e);
  2314. }
  2315. }
  2316. }
  2317. return effects;
  2318. }
  2319.  
  2320. public final List<L2Effect> getEffectsSelf(L2Character effector)
  2321. {
  2322. if (!hasSelfEffects() || isPassive())
  2323. return Collections.emptyList();
  2324.  
  2325. final List<L2Effect> effects = new ArrayList<>(_effectTemplatesSelf.size());
  2326.  
  2327. final Env env = new Env();
  2328. env.setCharacter(effector);
  2329. env.setTarget(effector);
  2330. env.setSkill(this);
  2331.  
  2332. for (EffectTemplate et : _effectTemplatesSelf)
  2333. {
  2334. final L2Effect e = et.getEffect(env);
  2335. if (e != null)
  2336. {
  2337. e.setSelfEffect();
  2338. e.scheduleEffect();
  2339. effects.add(e);
  2340. }
  2341. }
  2342. return effects;
  2343. }
  2344.  
  2345. public final void attach(FuncTemplate f)
  2346. {
  2347. if (_funcTemplates == null)
  2348. _funcTemplates = new ArrayList<>(1);
  2349.  
  2350. _funcTemplates.add(f);
  2351. }
  2352.  
  2353. public final void attach(EffectTemplate effect)
  2354. {
  2355. if (_effectTemplates == null)
  2356. _effectTemplates = new ArrayList<>(1);
  2357.  
  2358. _effectTemplates.add(effect);
  2359. }
  2360.  
  2361. public final void attachSelf(EffectTemplate effect)
  2362. {
  2363. if (_effectTemplatesSelf == null)
  2364. _effectTemplatesSelf = new ArrayList<>(1);
  2365.  
  2366. _effectTemplatesSelf.add(effect);
  2367. }
  2368.  
  2369. public final void attach(Condition c, boolean itemOrWeapon)
  2370. {
  2371. if (itemOrWeapon)
  2372. {
  2373. if (_itemPreCondition == null)
  2374. _itemPreCondition = new ArrayList<>();
  2375.  
  2376. _itemPreCondition.add(c);
  2377. }
  2378. else
  2379. {
  2380. if (_preCondition == null)
  2381. _preCondition = new ArrayList<>();
  2382.  
  2383. _preCondition.add(c);
  2384. }
  2385. }
  2386.  
  2387. /**
  2388. * @param skillId
  2389. * @param skillLvl
  2390. * @param values
  2391. * @return L2ExtractableSkill
  2392. * @author Zoey76
  2393. */
  2394. private L2ExtractableSkill parseExtractableSkill(int skillId, int skillLvl, String values)
  2395. {
  2396. final String[] prodLists = values.split(";");
  2397. final List<L2ExtractableProductItem> products = new ArrayList<>();
  2398.  
  2399. for (String prodList : prodLists)
  2400. {
  2401. final String[] prodData = prodList.split(",");
  2402.  
  2403. if (prodData.length < 3)
  2404. _log.warning("Extractable skills data: Error in Skill Id: " + skillId + " Level: " + skillLvl + " -> wrong seperator!");
  2405.  
  2406. final int lenght = prodData.length - 1;
  2407.  
  2408. List<IntIntHolder> items = null;
  2409. double chance = 0;
  2410. int prodId = 0;
  2411. int quantity = 0;
  2412.  
  2413. try
  2414. {
  2415. items = new ArrayList<>(lenght / 2);
  2416. for (int j = 0; j < lenght; j++)
  2417. {
  2418. prodId = Integer.parseInt(prodData[j]);
  2419. quantity = Integer.parseInt(prodData[j += 1]);
  2420.  
  2421. if (prodId <= 0 || quantity <= 0)
  2422. _log.warning("Extractable skills data: Error in Skill Id: " + skillId + " Level: " + skillLvl + " wrong production Id: " + prodId + " or wrond quantity: " + quantity + "!");
  2423.  
  2424. items.add(new IntIntHolder(prodId, quantity));
  2425. }
  2426. chance = Double.parseDouble(prodData[lenght]);
  2427. }
  2428. catch (Exception e)
  2429. {
  2430. _log.warning("Extractable skills data: Error in Skill Id: " + skillId + " Level: " + skillLvl + " -> incomplete/invalid production data or wrong seperator!");
  2431. }
  2432. products.add(new L2ExtractableProductItem(items, chance));
  2433. }
  2434.  
  2435. if (products.isEmpty())
  2436. _log.warning("Extractable skills data: Error in Skill Id: " + skillId + " Level: " + skillLvl + " -> There are no production items!");
  2437.  
  2438. return new L2ExtractableSkill(SkillTable.getSkillHashCode(this), products);
  2439. }
  2440.  
  2441. public L2ExtractableSkill getExtractableSkill()
  2442. {
  2443. return _extractableItems;
  2444. }
  2445.  
  2446. public boolean isDamage()
  2447. {
  2448. switch (_skillType)
  2449. {
  2450. case PDAM:
  2451. case MDAM:
  2452. case DRAIN:
  2453. case BLOW:
  2454. case CPDAMPERCENT:
  2455. case FATAL:
  2456. return true;
  2457. }
  2458. return false;
  2459. }
  2460.  
  2461. public boolean isAOE()
  2462. {
  2463. switch (_targetType)
  2464. {
  2465. case TARGET_AREA:
  2466. case TARGET_AURA:
  2467. case TARGET_BEHIND_AREA:
  2468. case TARGET_BEHIND_AURA:
  2469. case TARGET_FRONT_AREA:
  2470. case TARGET_FRONT_AURA:
  2471. return true;
  2472. }
  2473. return false;
  2474. }
  2475.  
  2476. @Override
  2477. public String toString()
  2478. {
  2479. return "" + _name + "[id=" + _id + ",lvl=" + _level + "]";
  2480. }
  2481. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement