Cancel.java 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  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 handlers.skillhandlers;
  16. import com.l2jserver.Config;
  17. import com.l2jserver.gameserver.handler.ISkillHandler;
  18. import com.l2jserver.gameserver.model.L2Effect;
  19. import com.l2jserver.gameserver.model.L2ItemInstance;
  20. import com.l2jserver.gameserver.model.L2Object;
  21. import com.l2jserver.gameserver.model.L2Skill;
  22. import com.l2jserver.gameserver.model.actor.L2Character;
  23. import com.l2jserver.gameserver.model.actor.L2Npc;
  24. import com.l2jserver.gameserver.model.actor.L2Summon;
  25. import com.l2jserver.gameserver.skills.Formulas;
  26. import com.l2jserver.gameserver.skills.Stats;
  27. import com.l2jserver.gameserver.templates.skills.L2SkillType;
  28. import com.l2jserver.util.Rnd;
  29. import com.l2jserver.util.StringUtil;
  30. /**
  31. *
  32. * @author DS
  33. *
  34. */
  35. public class Cancel implements ISkillHandler
  36. {
  37. private static final L2SkillType[] SKILL_IDS =
  38. {
  39. L2SkillType.CANCEL,
  40. };
  41. /**
  42. *
  43. * @see com.l2jserver.gameserver.handler.ISkillHandler#useSkill(com.l2jserver.gameserver.model.actor.L2Character, com.l2jserver.gameserver.model.L2Skill, com.l2jserver.gameserver.model.L2Object[])
  44. */
  45. @Override
  46. public void useSkill(L2Character activeChar, L2Skill skill, L2Object[] targets)
  47. {
  48. final L2ItemInstance weaponInst = activeChar.getActiveWeaponInstance();
  49. if (weaponInst != null)
  50. {
  51. if (skill.isMagic())
  52. {
  53. if (weaponInst.getChargedSpiritshot() == L2ItemInstance.CHARGED_BLESSED_SPIRITSHOT)
  54. weaponInst.setChargedSpiritshot(L2ItemInstance.CHARGED_NONE);
  55. else if (weaponInst.getChargedSpiritshot() == L2ItemInstance.CHARGED_SPIRITSHOT)
  56. weaponInst.setChargedSpiritshot(L2ItemInstance.CHARGED_NONE);
  57. }
  58. }
  59. else if (activeChar instanceof L2Summon)
  60. {
  61. final L2Summon activeSummon = (L2Summon) activeChar;
  62. if (skill.isMagic())
  63. {
  64. if (activeSummon.getChargedSpiritShot() == L2ItemInstance.CHARGED_BLESSED_SPIRITSHOT)
  65. activeSummon.setChargedSpiritShot(L2ItemInstance.CHARGED_NONE);
  66. else if (activeSummon.getChargedSpiritShot() == L2ItemInstance.CHARGED_SPIRITSHOT)
  67. activeSummon.setChargedSpiritShot(L2ItemInstance.CHARGED_NONE);
  68. }
  69. }
  70. else if (activeChar instanceof L2Npc)
  71. {
  72. ((L2Npc)activeChar)._soulshotcharged = false;
  73. ((L2Npc)activeChar)._spiritshotcharged = false;
  74. }
  75. L2Character target;
  76. L2Effect effect;
  77. final int cancelLvl, minRate, maxRate;
  78. cancelLvl = skill.getMagicLevel();
  79. minRate = 25;
  80. maxRate = 80;
  81. for (L2Object obj : targets)
  82. {
  83. if (!(obj instanceof L2Character))
  84. continue;
  85. target = (L2Character)obj;
  86. if (target.isDead())
  87. continue;
  88. int lastCanceledSkillId = 0;
  89. int count = skill.getMaxNegatedEffects();
  90. double rate = skill.getPower();
  91. final double vulnModifier = target.calcStat(Stats.CANCEL_VULN, 0, target, null);
  92. final double profModifier = activeChar.calcStat(Stats.CANCEL_PROF, 0, target, null);
  93. double res = vulnModifier + profModifier;
  94. double resMod = 1;
  95. if (res != 0)
  96. {
  97. if (res < 0)
  98. {
  99. resMod = 1 - 0.075 * res;
  100. resMod = 1 / resMod;
  101. }
  102. else
  103. resMod = 1 + 0.02 * res;
  104. rate *= resMod;
  105. }
  106. if (activeChar.isDebug())
  107. {
  108. final StringBuilder stat = new StringBuilder(100);
  109. StringUtil.append(stat,
  110. skill.getName(),
  111. " power:", String.valueOf((int)skill.getPower()),
  112. " lvl:", String.valueOf(cancelLvl),
  113. " res:", String.format("%1.2f", resMod), "(",
  114. String.format("%1.2f", profModifier), "/",
  115. String.format("%1.2f", vulnModifier),
  116. ") total:", String.valueOf(rate)
  117. );
  118. final String result = stat.toString();
  119. if (activeChar.isDebug())
  120. activeChar.sendDebugMessage(result);
  121. if (Config.DEVELOPER)
  122. _log.info(result);
  123. }
  124. final L2Effect[] effects = target.getAllEffects();
  125. if (skill.getNegateAbnormals() != null) // Cancel for abnormals
  126. {
  127. for (L2Effect eff : effects)
  128. {
  129. if (eff == null)
  130. continue;
  131. for (String negateAbnormalType : skill.getNegateAbnormals().keySet())
  132. {
  133. if (negateAbnormalType.equalsIgnoreCase(eff.getAbnormalType()) && skill.getNegateAbnormals().get(negateAbnormalType) >= eff.getAbnormalLvl())
  134. {
  135. if (calcCancelSuccess(eff, cancelLvl, (int)rate, minRate, maxRate))
  136. eff.exit();
  137. }
  138. }
  139. }
  140. }
  141. else
  142. {
  143. for (int i = effects.length; --i >= 0;)
  144. {
  145. effect = effects[i];
  146. if (effect == null)
  147. continue;
  148. if (!effect.canBeStolen())
  149. {
  150. effects[i] = null;
  151. continue;
  152. }
  153. // first pass - dances/songs only
  154. if (!effect.getSkill().isDance())
  155. continue;
  156. if (effect.getSkill().getId() == lastCanceledSkillId)
  157. {
  158. effect.exit(); // this skill already canceled
  159. continue;
  160. }
  161. if (!calcCancelSuccess(effect, cancelLvl, (int)rate, minRate, maxRate))
  162. continue;
  163. lastCanceledSkillId = effect.getSkill().getId();
  164. effect.exit();
  165. count--;
  166. if (count == 0)
  167. break;
  168. }
  169. if (count != 0)
  170. {
  171. lastCanceledSkillId = 0;
  172. for (int i = effects.length; --i >= 0;)
  173. {
  174. effect = effects[i];
  175. if (effect == null)
  176. continue;
  177. // second pass - all except dances/songs
  178. if (effect.getSkill().isDance())
  179. continue;
  180. if (effect.getSkill().getId() == lastCanceledSkillId)
  181. {
  182. effect.exit(); // this skill already canceled
  183. continue;
  184. }
  185. if (!calcCancelSuccess(effect, cancelLvl, (int)rate, minRate, maxRate))
  186. continue;
  187. lastCanceledSkillId = effect.getSkill().getId();
  188. effect.exit();
  189. count--;
  190. if (count == 0)
  191. break;
  192. }
  193. }
  194. }
  195. //Possibility of a lethal strike
  196. Formulas.calcLethalHit(activeChar, target, skill);
  197. }
  198. // Applying self-effects
  199. if (skill.hasSelfEffects())
  200. {
  201. effect = activeChar.getFirstEffect(skill.getId());
  202. if (effect != null && effect.isSelfEffect())
  203. {
  204. //Replace old effect with new one.
  205. effect.exit();
  206. }
  207. skill.getEffectsSelf(activeChar);
  208. }
  209. }
  210. private boolean calcCancelSuccess(L2Effect effect, int cancelLvl, int baseRate, int minRate, int maxRate)
  211. {
  212. int rate = 2 * (cancelLvl - effect.getSkill().getMagicLevel());
  213. rate += effect.getAbnormalTime()/120;
  214. rate += baseRate;
  215. if (rate < minRate)
  216. rate = minRate;
  217. else if (rate > maxRate)
  218. rate = maxRate;
  219. return Rnd.get(100) < rate;
  220. }
  221. /**
  222. *
  223. * @see com.l2jserver.gameserver.handler.ISkillHandler#getSkillIds()
  224. */
  225. @Override
  226. public L2SkillType[] getSkillIds()
  227. {
  228. return SKILL_IDS;
  229. }
  230. }