Disablers.java 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899
  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.handler.skillhandlers;
  16. import java.io.IOException;
  17. import java.util.logging.Level;
  18. import java.util.logging.Logger;
  19. import net.sf.l2j.Config;
  20. import net.sf.l2j.gameserver.ai.CtrlEvent;
  21. import net.sf.l2j.gameserver.ai.CtrlIntention;
  22. import net.sf.l2j.gameserver.ai.L2AttackableAI;
  23. import net.sf.l2j.gameserver.handler.ISkillHandler;
  24. import net.sf.l2j.gameserver.handler.SkillHandler;
  25. import net.sf.l2j.gameserver.instancemanager.DuelManager;
  26. import net.sf.l2j.gameserver.model.L2Attackable;
  27. import net.sf.l2j.gameserver.model.L2Character;
  28. import net.sf.l2j.gameserver.model.L2Effect;
  29. import net.sf.l2j.gameserver.model.L2ItemInstance;
  30. import net.sf.l2j.gameserver.model.L2Object;
  31. import net.sf.l2j.gameserver.model.L2Skill;
  32. import net.sf.l2j.gameserver.model.L2Summon;
  33. import net.sf.l2j.gameserver.model.actor.instance.L2CubicInstance;
  34. import net.sf.l2j.gameserver.model.actor.instance.L2NpcInstance;
  35. import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
  36. import net.sf.l2j.gameserver.model.actor.instance.L2SiegeSummonInstance;
  37. import net.sf.l2j.gameserver.model.base.Experience;
  38. import net.sf.l2j.gameserver.network.SystemMessageId;
  39. import net.sf.l2j.gameserver.network.serverpackets.SystemMessage;
  40. import net.sf.l2j.gameserver.skills.Formulas;
  41. import net.sf.l2j.gameserver.skills.Stats;
  42. import net.sf.l2j.gameserver.skills.funcs.Func;
  43. import net.sf.l2j.gameserver.templates.L2SkillType;
  44. import net.sf.l2j.util.Rnd;
  45. /**
  46. * This Handles Disabler skills
  47. * @author _drunk_
  48. */
  49. public class Disablers implements ISkillHandler
  50. {
  51. private static final L2SkillType[] SKILL_IDS =
  52. {
  53. L2SkillType.STUN,
  54. L2SkillType.ROOT,
  55. L2SkillType.SLEEP,
  56. L2SkillType.CONFUSION,
  57. L2SkillType.AGGDAMAGE,
  58. L2SkillType.AGGREDUCE,
  59. L2SkillType.AGGREDUCE_CHAR,
  60. L2SkillType.AGGREMOVE,
  61. L2SkillType.UNBLEED,
  62. L2SkillType.UNPOISON,
  63. L2SkillType.MUTE,
  64. L2SkillType.FAKE_DEATH,
  65. L2SkillType.CONFUSE_MOB_ONLY,
  66. L2SkillType.NEGATE,
  67. L2SkillType.CANCEL,
  68. L2SkillType.CANCEL_DEBUFF,
  69. L2SkillType.PARALYZE,
  70. L2SkillType.ERASE,
  71. L2SkillType.MAGE_BANE,
  72. L2SkillType.WARRIOR_BANE,
  73. L2SkillType.BETRAY,
  74. L2SkillType.DISARM
  75. };
  76. protected static final Logger _log = Logger.getLogger(L2Skill.class.getName());
  77. private String[] _negateStats = null;
  78. private float _negatePower = 0.f;
  79. private int _negateId = 0;
  80. /**
  81. *
  82. * @see net.sf.l2j.gameserver.handler.ISkillHandler#useSkill(net.sf.l2j.gameserver.model.L2Character, net.sf.l2j.gameserver.model.L2Skill, net.sf.l2j.gameserver.model.L2Object[])
  83. */
  84. public void useSkill(L2Character activeChar, L2Skill skill, L2Object[] targets)
  85. {
  86. L2SkillType type = skill.getSkillType();
  87. boolean ss = false;
  88. boolean sps = false;
  89. boolean bss = false;
  90. L2ItemInstance weaponInst = activeChar.getActiveWeaponInstance();
  91. if (activeChar instanceof L2PcInstance)
  92. {
  93. if (weaponInst == null && skill.isOffensive())
  94. {
  95. activeChar.sendMessage("You must equip a weapon before casting a spell.");
  96. return;
  97. }
  98. }
  99. if (weaponInst != null)
  100. {
  101. if (skill.isMagic())
  102. {
  103. if (weaponInst.getChargedSpiritshot() == L2ItemInstance.CHARGED_BLESSED_SPIRITSHOT)
  104. {
  105. bss = true;
  106. if (skill.getId() != 1020) // vitalize
  107. weaponInst.setChargedSpiritshot(L2ItemInstance.CHARGED_NONE);
  108. }
  109. else if (weaponInst.getChargedSpiritshot() == L2ItemInstance.CHARGED_SPIRITSHOT)
  110. {
  111. sps = true;
  112. if (skill.getId() != 1020) // vitalize
  113. weaponInst.setChargedSpiritshot(L2ItemInstance.CHARGED_NONE);
  114. }
  115. }
  116. else
  117. {
  118. if (weaponInst.getChargedSoulshot() == L2ItemInstance.CHARGED_SOULSHOT)
  119. {
  120. ss = true;
  121. if (skill.getId() != 1020) // vitalize
  122. weaponInst.setChargedSoulshot(L2ItemInstance.CHARGED_NONE);
  123. }
  124. }
  125. }
  126. // If there is no weapon equipped, check for an active summon.
  127. else if (activeChar instanceof L2Summon)
  128. {
  129. L2Summon activeSummon = (L2Summon) activeChar;
  130. if (skill.isMagic())
  131. {
  132. if (activeSummon.getChargedSpiritShot() == L2ItemInstance.CHARGED_BLESSED_SPIRITSHOT)
  133. {
  134. bss = true;
  135. activeSummon.setChargedSpiritShot(L2ItemInstance.CHARGED_NONE);
  136. }
  137. else if (activeSummon.getChargedSpiritShot() == L2ItemInstance.CHARGED_SPIRITSHOT)
  138. {
  139. sps = true;
  140. activeSummon.setChargedSpiritShot(L2ItemInstance.CHARGED_NONE);
  141. }
  142. }
  143. else
  144. {
  145. if (activeSummon.getChargedSoulShot() == L2ItemInstance.CHARGED_SOULSHOT)
  146. {
  147. ss = true;
  148. activeSummon.setChargedSoulShot(L2ItemInstance.CHARGED_NONE);
  149. }
  150. }
  151. }
  152. else if (activeChar instanceof L2NpcInstance)
  153. {
  154. bss = ((L2NpcInstance) activeChar).isUsingShot(false);
  155. ss = ((L2NpcInstance) activeChar).isUsingShot(true);
  156. }
  157. for (int index = 0; index < targets.length; index++)
  158. {
  159. // Get a target
  160. if (!(targets[index] instanceof L2Character))
  161. continue;
  162. L2Character target = (L2Character) targets[index];
  163. if (target == null || target.isDead() || target.isInvul()) //bypass if target is null, invul or dead
  164. continue;
  165. switch (type)
  166. {
  167. case BETRAY:
  168. {
  169. if (Formulas.getInstance().calcSkillSuccess(activeChar, target, skill, ss, sps, bss))
  170. skill.getEffects(activeChar, target);
  171. else
  172. {
  173. SystemMessage sm = new SystemMessage(SystemMessageId.S1_WAS_UNAFFECTED_BY_S2);
  174. sm.addCharName(target);
  175. sm.addSkillName(skill);
  176. activeChar.sendPacket(sm);
  177. }
  178. break;
  179. }
  180. case FAKE_DEATH:
  181. {
  182. // stun/fakedeath is not mdef dependant, it depends on lvl difference, target CON and power of stun
  183. skill.getEffects(activeChar, target);
  184. break;
  185. }
  186. case ROOT:
  187. case DISARM:
  188. case STUN:
  189. {
  190. if (target.reflectSkill(skill))
  191. target = activeChar;
  192. if (Formulas.getInstance().calcSkillSuccess(activeChar, target, skill, ss, sps, bss))
  193. skill.getEffects(activeChar, target);
  194. else
  195. {
  196. if (activeChar instanceof L2PcInstance)
  197. {
  198. SystemMessage sm = new SystemMessage(SystemMessageId.S1_WAS_UNAFFECTED_BY_S2);
  199. sm.addCharName(target);
  200. sm.addSkillName(skill);
  201. activeChar.sendPacket(sm);
  202. }
  203. }
  204. break;
  205. }
  206. case SLEEP:
  207. case PARALYZE: //use same as root for now
  208. {
  209. if (target.reflectSkill(skill))
  210. target = activeChar;
  211. if (Formulas.getInstance().calcSkillSuccess(activeChar, target, skill, ss, sps, bss))
  212. skill.getEffects(activeChar, target);
  213. else
  214. {
  215. if (activeChar instanceof L2PcInstance)
  216. {
  217. SystemMessage sm = new SystemMessage(SystemMessageId.S1_WAS_UNAFFECTED_BY_S2);
  218. sm.addCharName(target);
  219. sm.addSkillName(skill);
  220. activeChar.sendPacket(sm);
  221. }
  222. }
  223. break;
  224. }
  225. case CONFUSION:
  226. case MUTE:
  227. {
  228. if (target.reflectSkill(skill))
  229. target = activeChar;
  230. if (Formulas.getInstance().calcSkillSuccess(activeChar, target, skill, ss, sps, bss))
  231. {
  232. // stop same type effect if avaiable
  233. L2Effect[] effects = target.getAllEffects();
  234. for (L2Effect e : effects)
  235. if (e.getSkill().getSkillType() == type)
  236. e.exit();
  237. // then restart
  238. // Make above skills mdef dependant
  239. if (Formulas.getInstance().calcSkillSuccess(activeChar, target, skill, ss, sps, bss))
  240. //if(Formulas.getInstance().calcMagicAffected(activeChar, target, skill))
  241. skill.getEffects(activeChar, target);
  242. else
  243. {
  244. if (activeChar instanceof L2PcInstance)
  245. {
  246. SystemMessage sm = new SystemMessage(SystemMessageId.S1_WAS_UNAFFECTED_BY_S2);
  247. sm.addCharName(target);
  248. sm.addSkillName(skill);
  249. activeChar.sendPacket(sm);
  250. }
  251. }
  252. }
  253. else
  254. {
  255. if (activeChar instanceof L2PcInstance)
  256. {
  257. SystemMessage sm = new SystemMessage(SystemMessageId.S1_WAS_UNAFFECTED_BY_S2);
  258. sm.addCharName(target);
  259. sm.addSkillName(skill);
  260. activeChar.sendPacket(sm);
  261. }
  262. }
  263. break;
  264. }
  265. case CONFUSE_MOB_ONLY:
  266. {
  267. // do nothing if not on mob
  268. if (target instanceof L2Attackable)
  269. {
  270. if (Formulas.getInstance().calcSkillSuccess(activeChar, target, skill, ss, sps, bss))
  271. {
  272. L2Effect[] effects = target.getAllEffects();
  273. for (L2Effect e : effects)
  274. {
  275. if (e.getSkill().getSkillType() == type)
  276. e.exit();
  277. }
  278. skill.getEffects(activeChar, target);
  279. }
  280. else
  281. {
  282. if (activeChar instanceof L2PcInstance)
  283. {
  284. SystemMessage sm = new SystemMessage(SystemMessageId.S1_WAS_UNAFFECTED_BY_S2);
  285. sm.addCharName(target);
  286. sm.addSkillName(skill);
  287. activeChar.sendPacket(sm);
  288. }
  289. }
  290. }
  291. else
  292. activeChar.sendPacket(new SystemMessage(SystemMessageId.TARGET_IS_INCORRECT));
  293. break;
  294. }
  295. case AGGDAMAGE:
  296. {
  297. if (target instanceof L2Attackable)
  298. target.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, activeChar, (int) ((150 * skill.getPower()) / (target.getLevel() + 7)));
  299. // TODO [Nemesiss] should this have 100% chance?
  300. skill.getEffects(activeChar, target);
  301. break;
  302. }
  303. case AGGREDUCE:
  304. {
  305. // these skills needs to be rechecked
  306. if (target instanceof L2Attackable)
  307. {
  308. skill.getEffects(activeChar, target);
  309. double aggdiff = ((L2Attackable) target).getHating(activeChar) - target.calcStat(Stats.AGGRESSION, ((L2Attackable) target).getHating(activeChar), target, skill);
  310. if (skill.getPower() > 0)
  311. ((L2Attackable) target).reduceHate(null, (int) skill.getPower());
  312. else if (aggdiff > 0)
  313. ((L2Attackable) target).reduceHate(null, (int) aggdiff);
  314. }
  315. // when fail, target.getAI().notifyEvent(CtrlEvent.EVT_ATTACKED, activeChar);
  316. break;
  317. }
  318. case AGGREDUCE_CHAR:
  319. {
  320. // these skills needs to be rechecked
  321. if (Formulas.getInstance().calcSkillSuccess(activeChar, target, skill, ss, sps, bss))
  322. {
  323. if (target instanceof L2Attackable)
  324. {
  325. L2Attackable targ = (L2Attackable) target;
  326. targ.stopHating(activeChar);
  327. if (targ.getMostHated() == null)
  328. {
  329. ((L2AttackableAI) targ.getAI()).setGlobalAggro(-25);
  330. targ.clearAggroList();
  331. targ.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
  332. targ.setWalking();
  333. }
  334. }
  335. skill.getEffects(activeChar, target);
  336. }
  337. else
  338. {
  339. if (activeChar instanceof L2PcInstance)
  340. {
  341. SystemMessage sm = new SystemMessage(SystemMessageId.S1_WAS_UNAFFECTED_BY_S2);
  342. sm.addCharName(target);
  343. sm.addSkillName(skill);
  344. activeChar.sendPacket(sm);
  345. }
  346. target.getAI().notifyEvent(CtrlEvent.EVT_ATTACKED, activeChar);
  347. }
  348. break;
  349. }
  350. case AGGREMOVE:
  351. {
  352. // these skills needs to be rechecked
  353. if (target instanceof L2Attackable && !target.isRaid())
  354. {
  355. if (Formulas.getInstance().calcSkillSuccess(activeChar, target, skill, ss, sps, bss))
  356. {
  357. if (skill.getTargetType() == L2Skill.SkillTargetType.TARGET_UNDEAD)
  358. {
  359. if (target.isUndead())
  360. ((L2Attackable) target).reduceHate(null, ((L2Attackable) target).getHating(((L2Attackable) target).getMostHated()));
  361. }
  362. else
  363. ((L2Attackable) target).reduceHate(null, ((L2Attackable) target).getHating(((L2Attackable) target).getMostHated()));
  364. }
  365. else
  366. {
  367. if (activeChar instanceof L2PcInstance)
  368. {
  369. SystemMessage sm = new SystemMessage(SystemMessageId.S1_WAS_UNAFFECTED_BY_S2);
  370. sm.addCharName(target);
  371. sm.addSkillName(skill);
  372. activeChar.sendPacket(sm);
  373. }
  374. target.getAI().notifyEvent(CtrlEvent.EVT_ATTACKED, activeChar);
  375. }
  376. }
  377. else
  378. target.getAI().notifyEvent(CtrlEvent.EVT_ATTACKED, activeChar);
  379. break;
  380. }
  381. case UNBLEED:
  382. {
  383. negateEffect(target, L2SkillType.BLEED, skill.getPower(), skill.getMaxNegatedEffects());
  384. break;
  385. }
  386. case UNPOISON:
  387. {
  388. negateEffect(target, L2SkillType.POISON, skill.getPower(), skill.getMaxNegatedEffects());
  389. break;
  390. }
  391. case ERASE:
  392. {
  393. if (Formulas.getInstance().calcSkillSuccess(activeChar, target, skill, ss, sps, bss)
  394. // doesn't affect siege golem or wild hog cannon
  395. && !(target instanceof L2SiegeSummonInstance))
  396. {
  397. L2PcInstance summonOwner = null;
  398. L2Summon summonPet = null;
  399. summonOwner = ((L2Summon) target).getOwner();
  400. summonPet = summonOwner.getPet();
  401. if (summonPet != null)
  402. {
  403. summonPet.unSummon(summonOwner);
  404. SystemMessage sm = new SystemMessage(SystemMessageId.LETHAL_STRIKE);
  405. summonOwner.sendPacket(sm);
  406. }
  407. }
  408. else
  409. {
  410. if (activeChar instanceof L2PcInstance)
  411. {
  412. SystemMessage sm = new SystemMessage(SystemMessageId.S1_WAS_UNAFFECTED_BY_S2);
  413. sm.addCharName(target);
  414. sm.addSkillName(skill);
  415. activeChar.sendPacket(sm);
  416. }
  417. }
  418. break;
  419. }
  420. case MAGE_BANE:
  421. {
  422. if (target.reflectSkill(skill))
  423. target = activeChar;
  424. if (!Formulas.getInstance().calcSkillSuccess(activeChar, target, skill, ss, sps, bss))
  425. {
  426. if (activeChar instanceof L2PcInstance)
  427. {
  428. SystemMessage sm = new SystemMessage(SystemMessageId.S1_WAS_UNAFFECTED_BY_S2);
  429. sm.addCharName(target);
  430. sm.addSkillName(skill);
  431. activeChar.sendPacket(sm);
  432. }
  433. continue;
  434. }
  435. L2Effect[] effects = target.getAllEffects();
  436. for (L2Effect e : effects)
  437. {
  438. for (Func f : e.getStatFuncs())
  439. {
  440. if (f.stat == Stats.MAGIC_ATTACK || f.stat == Stats.MAGIC_ATTACK_SPEED)
  441. {
  442. e.exit();
  443. break;
  444. }
  445. }
  446. }
  447. break;
  448. }
  449. case WARRIOR_BANE:
  450. {
  451. if (target.reflectSkill(skill))
  452. target = activeChar;
  453. if (!Formulas.getInstance().calcSkillSuccess(activeChar, target, skill, ss, sps, bss))
  454. {
  455. if (activeChar instanceof L2PcInstance)
  456. {
  457. SystemMessage sm = new SystemMessage(SystemMessageId.S1_WAS_UNAFFECTED_BY_S2);
  458. sm.addCharName(target);
  459. sm.addSkillName(skill);
  460. activeChar.sendPacket(sm);
  461. }
  462. continue;
  463. }
  464. L2Effect[] effects = target.getAllEffects();
  465. for (L2Effect e : effects)
  466. {
  467. for (Func f : e.getStatFuncs())
  468. {
  469. if (f.stat == Stats.RUN_SPEED || f.stat == Stats.POWER_ATTACK_SPEED)
  470. {
  471. e.exit();
  472. break;
  473. }
  474. }
  475. }
  476. break;
  477. }
  478. case CANCEL_DEBUFF:
  479. {
  480. L2Effect[] effects = target.getAllEffects();
  481. if (effects.length == 0 || effects == null)
  482. break;
  483. int count = (skill.getMaxNegatedEffects() > 0) ? skill.getMaxNegatedEffects() : -2;
  484. for (L2Effect e : effects)
  485. {
  486. if (e.getSkill().isDebuff() && count < skill.getMaxNegatedEffects())
  487. {
  488. e.exit();
  489. if (count > -1)
  490. count++;
  491. }
  492. }
  493. break;
  494. }
  495. case CANCEL:
  496. case NEGATE:
  497. {
  498. if (target.reflectSkill(skill))
  499. target = activeChar;
  500. if (skill.cancelEffect() > 0)
  501. {
  502. L2Effect[] effects = target.getAllEffects();
  503. for (L2Effect e : effects)
  504. {
  505. if (e.getSkill().getId() == skill.cancelEffect())
  506. e.exit();
  507. }
  508. }
  509. //TODO@ Rewrite it to properly use Formulas class.
  510. // cancel
  511. else if (skill.getId() == 1056)
  512. {
  513. int lvlmodifier = 52 + skill.getLevel() * 2;
  514. if (skill.getLevel() == 12)
  515. lvlmodifier = (Experience.MAX_LEVEL - 1);
  516. int landrate = 90;
  517. if ((target.getLevel() - lvlmodifier) > 0)
  518. landrate = 90 - 4 * (target.getLevel() - lvlmodifier);
  519. landrate = (int) activeChar.calcStat(Stats.CANCEL_VULN, landrate, target, null);
  520. if (Rnd.get(100) < landrate)
  521. {
  522. L2Effect[] effects = target.getAllEffects();
  523. int maxfive = skill.getMaxNegatedEffects();
  524. for (L2Effect e : effects)
  525. {
  526. // do not delete signet effects!
  527. switch (e.getEffectType())
  528. {
  529. case SIGNET_GROUND:
  530. case SIGNET_EFFECT:
  531. continue;
  532. }
  533. if (e.getSkill().getId() != 4082 && e.getSkill().getId() != 4215 && e.getSkill().getId() != 4515 && e.getSkill().getId() != 110 && e.getSkill().getId() != 111 && e.getSkill().getId() != 1323
  534. && e.getSkill().getId() != 1325) // Cannot cancel skills 4082, 4215, 4515, 110, 111, 1323, 1325
  535. {
  536. if (e.getSkill().getSkillType() != L2SkillType.BUFF) //sleep, slow, surrenders etc
  537. e.exit();
  538. else
  539. {
  540. int rate = 100;
  541. int level = e.getLevel();
  542. if (level > 0)
  543. rate = Integer.valueOf(150 / (1 + level));
  544. if (rate > 95)
  545. rate = 95;
  546. else if (rate < 5)
  547. rate = 5;
  548. if (Rnd.get(100) < rate)
  549. {
  550. e.exit();
  551. maxfive--;
  552. if (maxfive == 0)
  553. break;
  554. }
  555. }
  556. }
  557. }
  558. }
  559. else
  560. {
  561. if (activeChar instanceof L2PcInstance)
  562. {
  563. SystemMessage sm = new SystemMessage(SystemMessageId.S1_WAS_UNAFFECTED_BY_S2);
  564. sm.addCharName(target);
  565. sm.addSkillName(skill);
  566. activeChar.sendPacket(sm);
  567. }
  568. }
  569. break;
  570. }
  571. // fishing potion
  572. else if (skill.getId() == 2275)
  573. {
  574. _negatePower = skill.getNegatePower();
  575. _negateId = skill.getNegateId();
  576. negateEffect(target, L2SkillType.BUFF, _negatePower, _negateId, -1);
  577. }
  578. // all others negate type skills
  579. else
  580. {
  581. _negateStats = skill.getNegateStats();
  582. _negatePower = skill.getNegatePower();
  583. int removedBuffs = (skill.getMaxNegatedEffects() > 0) ? 0 : -2;
  584. for (String stat : _negateStats)
  585. {
  586. if (removedBuffs > skill.getMaxNegatedEffects())
  587. break;
  588. stat = stat.toLowerCase().intern();
  589. if (stat == "buff")
  590. {
  591. int lvlmodifier = 52 + skill.getMagicLevel() * 2;
  592. if (skill.getMagicLevel() == 12)
  593. lvlmodifier = (Experience.MAX_LEVEL - 1);
  594. int landrate = 90;
  595. if ((target.getLevel() - lvlmodifier) > 0)
  596. landrate = 90 - 4 * (target.getLevel() - lvlmodifier);
  597. landrate = (int) activeChar.calcStat(Stats.CANCEL_VULN, landrate, target, null);
  598. if (Rnd.get(100) < landrate)
  599. removedBuffs += negateEffect(target, L2SkillType.BUFF, -1, skill.getMaxNegatedEffects());
  600. }
  601. else if (stat == "debuff" && removedBuffs < skill.getMaxNegatedEffects())
  602. removedBuffs += negateEffect(target, L2SkillType.DEBUFF, -1, skill.getMaxNegatedEffects());
  603. else if (stat == "weakness" && removedBuffs < skill.getMaxNegatedEffects())
  604. removedBuffs += negateEffect(target, L2SkillType.WEAKNESS, -1, skill.getMaxNegatedEffects());
  605. else if (stat == "stun" && removedBuffs < skill.getMaxNegatedEffects())
  606. removedBuffs += negateEffect(target, L2SkillType.STUN, -1, skill.getMaxNegatedEffects());
  607. else if (stat == "sleep" && removedBuffs < skill.getMaxNegatedEffects())
  608. removedBuffs += negateEffect(target, L2SkillType.SLEEP, -1, skill.getMaxNegatedEffects());
  609. else if (stat == "confusion" && removedBuffs < skill.getMaxNegatedEffects())
  610. removedBuffs += negateEffect(target, L2SkillType.CONFUSION, -1, skill.getMaxNegatedEffects());
  611. else if (stat == "mute" && removedBuffs < skill.getMaxNegatedEffects())
  612. removedBuffs += negateEffect(target, L2SkillType.MUTE, -1, skill.getMaxNegatedEffects());
  613. else if (stat == "fear" && removedBuffs < skill.getMaxNegatedEffects())
  614. removedBuffs += negateEffect(target, L2SkillType.FEAR, -1, skill.getMaxNegatedEffects());
  615. else if (stat == "poison" && removedBuffs < skill.getMaxNegatedEffects())
  616. removedBuffs += negateEffect(target, L2SkillType.POISON, _negatePower, skill.getMaxNegatedEffects());
  617. else if (stat == "bleed" && removedBuffs < skill.getMaxNegatedEffects())
  618. removedBuffs += negateEffect(target, L2SkillType.BLEED, _negatePower, skill.getMaxNegatedEffects());
  619. else if (stat == "paralyze" && removedBuffs < skill.getMaxNegatedEffects())
  620. removedBuffs += negateEffect(target, L2SkillType.PARALYZE, -1, skill.getMaxNegatedEffects());
  621. else if (stat == "root" && removedBuffs < skill.getMaxNegatedEffects())
  622. removedBuffs += negateEffect(target, L2SkillType.ROOT, -1, skill.getMaxNegatedEffects());
  623. else if (stat == "heal" && removedBuffs < skill.getMaxNegatedEffects())
  624. {
  625. ISkillHandler Healhandler = SkillHandler.getInstance().getSkillHandler(L2SkillType.HEAL);
  626. if (Healhandler == null)
  627. {
  628. _log.severe("Couldn't find skill handler for HEAL.");
  629. continue;
  630. }
  631. L2Object tgts[] = new L2Object[]
  632. {
  633. target
  634. };
  635. try
  636. {
  637. Healhandler.useSkill(activeChar, skill, tgts);
  638. }
  639. catch (IOException e)
  640. {
  641. _log.log(Level.WARNING, "", e);
  642. }
  643. }
  644. }//end for
  645. }//end else
  646. if (Formulas.getInstance().calcSkillSuccess(activeChar, target, skill, ss, sps, bss))
  647. {
  648. skill.getEffects(activeChar, target);
  649. }
  650. }// end case
  651. }//end switch
  652. //Possibility of a lethal strike
  653. Formulas.getInstance().calcLethalHit(activeChar, target, skill);
  654. }//end for
  655. // self Effect :]
  656. L2Effect effect = activeChar.getFirstEffect(skill.getId());
  657. if (effect != null && effect.isSelfEffect())
  658. {
  659. //Replace old effect with new one.
  660. effect.exit();
  661. }
  662. skill.getEffectsSelf(activeChar);
  663. } //end void
  664. public void useCubicSkill(L2CubicInstance activeCubic, L2Skill skill, L2Object[] targets)
  665. {
  666. if (Config.DEBUG)
  667. _log.info("Disablers: useCubicSkill()");
  668. L2SkillType type = skill.getSkillType();
  669. for (int index = 0; index < targets.length; index++)
  670. {
  671. // Get a target
  672. if (!(targets[index] instanceof L2Character))
  673. continue;
  674. L2Character target = (L2Character) targets[index];
  675. if (target == null || target.isDead()) //bypass if target is null or dead
  676. continue;
  677. switch (type)
  678. {
  679. case STUN:
  680. {
  681. if (Formulas.getInstance().calcCubicSkillSuccess(activeCubic, target, skill))
  682. {
  683. // if this is a debuff let the duel manager know about it
  684. // so the debuff can be removed after the duel
  685. // (player & target must be in the same duel)
  686. if (target instanceof L2PcInstance && ((L2PcInstance) target).isInDuel() && skill.getSkillType() == L2SkillType.DEBUFF && activeCubic.getOwner().getDuelId() == ((L2PcInstance) target).getDuelId())
  687. {
  688. DuelManager dm = DuelManager.getInstance();
  689. for (L2Effect debuff : skill.getEffects(activeCubic.getOwner(), target))
  690. if (debuff != null)
  691. dm.onBuff(((L2PcInstance) target), debuff);
  692. }
  693. else
  694. skill.getEffects(activeCubic, target);
  695. SystemMessage sm = new SystemMessage(SystemMessageId.S1_SUCCEEDED);
  696. sm.addSkillName(skill);
  697. activeCubic.getOwner().sendPacket(sm);
  698. if (Config.DEBUG)
  699. _log.info("Disablers: useCubicSkill() -> success");
  700. }
  701. else
  702. {
  703. SystemMessage sm = new SystemMessage(SystemMessageId.S1_WAS_UNAFFECTED_BY_S2);
  704. sm.addCharName(target);
  705. sm.addSkillName(skill);
  706. activeCubic.getOwner().sendPacket(sm);
  707. if (Config.DEBUG)
  708. _log.info("Disablers: useCubicSkill() -> failed");
  709. }
  710. break;
  711. }
  712. case PARALYZE: //use same as root for now
  713. {
  714. if (Formulas.getInstance().calcCubicSkillSuccess(activeCubic, target, skill))
  715. {
  716. // if this is a debuff let the duel manager know about it
  717. // so the debuff can be removed after the duel
  718. // (player & target must be in the same duel)
  719. if (target instanceof L2PcInstance && ((L2PcInstance) target).isInDuel() && skill.getSkillType() == L2SkillType.DEBUFF && activeCubic.getOwner().getDuelId() == ((L2PcInstance) target).getDuelId())
  720. {
  721. DuelManager dm = DuelManager.getInstance();
  722. for (L2Effect debuff : skill.getEffects(activeCubic.getOwner(), target))
  723. if (debuff != null)
  724. dm.onBuff(((L2PcInstance) target), debuff);
  725. }
  726. else
  727. skill.getEffects(activeCubic, target);
  728. SystemMessage sm = new SystemMessage(SystemMessageId.S1_SUCCEEDED);
  729. sm.addSkillName(skill);
  730. activeCubic.getOwner().sendPacket(sm);
  731. if (Config.DEBUG)
  732. _log.info("Disablers: useCubicSkill() -> success");
  733. }
  734. else
  735. {
  736. SystemMessage sm = new SystemMessage(SystemMessageId.S1_WAS_UNAFFECTED_BY_S2);
  737. sm.addCharName(target);
  738. sm.addSkillName(skill);
  739. activeCubic.getOwner().sendPacket(sm);
  740. if (Config.DEBUG)
  741. _log.info("Disablers: useCubicSkill() -> failed");
  742. }
  743. break;
  744. }
  745. case CANCEL_DEBUFF:
  746. {
  747. L2Effect[] effects = target.getAllEffects();
  748. if (effects == null || effects.length == 0)
  749. break;
  750. int count = (skill.getMaxNegatedEffects() > 0) ? 0 : -2;
  751. for (L2Effect e : effects)
  752. {
  753. if (e.getSkill().isDebuff() && count < skill.getMaxNegatedEffects())
  754. {
  755. e.exit();
  756. if (count > -1)
  757. count++;
  758. }
  759. }
  760. break;
  761. }
  762. }//end switch
  763. }//end for
  764. }
  765. /**
  766. *
  767. * @param target
  768. * @param type
  769. * @param power
  770. * @param maxRemoved
  771. * @return
  772. */
  773. private int negateEffect(L2Character target, L2SkillType type, double power, int maxRemoved)
  774. {
  775. return negateEffect(target, type, power, 0, maxRemoved);
  776. }
  777. /**
  778. *
  779. * @param target
  780. * @param type
  781. * @param power
  782. * @param skillId
  783. * @param maxRemoved
  784. * @return
  785. */
  786. private int negateEffect(L2Character target, L2SkillType type, double power, int skillId, int maxRemoved)
  787. {
  788. L2Effect[] effects = target.getAllEffects();
  789. int count = (maxRemoved <= 0) ? -2 : 0;
  790. for (L2Effect e : effects)
  791. {
  792. if (power == -1) // if power is -1 the effect is always removed without power/lvl check ^^
  793. {
  794. if (e.getSkill().getSkillType() == type || (e.getSkill().getEffectType() != null && e.getSkill().getEffectType() == type))
  795. {
  796. if (skillId != 0)
  797. {
  798. if (skillId == e.getSkill().getId() && count < maxRemoved)
  799. {
  800. e.exit();
  801. if (count > -1)
  802. count++;
  803. }
  804. }
  805. else if (count < maxRemoved)
  806. {
  807. e.exit();
  808. if (count > -1)
  809. count++;
  810. }
  811. }
  812. }
  813. else if ((e.getSkill().getSkillType() == type && e.getSkill().getPower() <= power) || (e.getSkill().getEffectType() != null && e.getSkill().getEffectType() == type && e.getSkill().getEffectLvl() <= power))
  814. {
  815. if (skillId != 0)
  816. {
  817. if (skillId == e.getSkill().getId() && count < maxRemoved)
  818. {
  819. e.exit();
  820. if (count > -1)
  821. count++;
  822. }
  823. }
  824. else if (count < maxRemoved)
  825. {
  826. e.exit();
  827. if (count > -1)
  828. count++;
  829. }
  830. }
  831. }
  832. return (maxRemoved <= 0) ? count + 2 : count;
  833. }
  834. /**
  835. *
  836. * @see net.sf.l2j.gameserver.handler.ISkillHandler#getSkillIds()
  837. */
  838. public L2SkillType[] getSkillIds()
  839. {
  840. return SKILL_IDS;
  841. }
  842. }