StealBuffs.java 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  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 java.util.ArrayList;
  17. import java.util.logging.Level;
  18. import com.l2jserver.gameserver.handler.ISkillHandler;
  19. import com.l2jserver.gameserver.model.L2Object;
  20. import com.l2jserver.gameserver.model.ShotType;
  21. import com.l2jserver.gameserver.model.actor.L2Character;
  22. import com.l2jserver.gameserver.model.effects.L2Effect;
  23. import com.l2jserver.gameserver.model.skills.L2Skill;
  24. import com.l2jserver.gameserver.model.skills.L2SkillType;
  25. import com.l2jserver.gameserver.model.stats.Env;
  26. import com.l2jserver.gameserver.model.stats.Formulas;
  27. import com.l2jserver.gameserver.network.SystemMessageId;
  28. import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
  29. public class StealBuffs implements ISkillHandler
  30. {
  31. private static final L2SkillType[] SKILL_IDS =
  32. {
  33. L2SkillType.STEAL_BUFF
  34. };
  35. @Override
  36. public void useSkill(L2Character activeChar, L2Skill skill, L2Object[] targets)
  37. {
  38. L2Character target;
  39. L2Effect effect;
  40. int count = skill.getMaxNegatedEffects();
  41. for (L2Object obj : targets)
  42. {
  43. if (!(obj instanceof L2Character))
  44. {
  45. continue;
  46. }
  47. target = (L2Character) obj;
  48. if (target.isDead())
  49. {
  50. continue;
  51. }
  52. if (!target.isPlayer())
  53. {
  54. continue;
  55. }
  56. Env env;
  57. int lastSkillId = 0;
  58. final L2Effect[] effects = target.getAllEffects();
  59. final ArrayList<L2Effect> toSteal = new ArrayList<>(count);
  60. for (int i = effects.length; --i >= 0;) // reverse order
  61. {
  62. effect = effects[i];
  63. if (effect == null)
  64. {
  65. continue;
  66. }
  67. if (!effect.canBeStolen()) // remove effect if can't be stolen
  68. {
  69. effects[i] = null;
  70. continue;
  71. }
  72. // if eff time is smaller than 5 sec, will not be stolen, just to save CPU,
  73. // avoid synchronization(?) problems and NPEs
  74. if ((effect.getAbnormalTime() - effect.getTime()) < 5)
  75. {
  76. effects[i] = null;
  77. continue;
  78. }
  79. // first pass - only dances/songs
  80. if (!effect.getSkill().isDance())
  81. {
  82. continue;
  83. }
  84. if (effect.getSkill().getId() != lastSkillId)
  85. {
  86. lastSkillId = effect.getSkill().getId();
  87. count--;
  88. }
  89. toSteal.add(effect);
  90. if (count == 0)
  91. {
  92. break;
  93. }
  94. }
  95. if (count > 0) // second pass
  96. {
  97. lastSkillId = 0;
  98. for (int i = effects.length; --i >= 0;)
  99. {
  100. effect = effects[i];
  101. if (effect == null)
  102. {
  103. continue;
  104. }
  105. // second pass - all except dances/songs
  106. if (effect.getSkill().isDance())
  107. {
  108. continue;
  109. }
  110. if (effect.getSkill().getId() != lastSkillId)
  111. {
  112. lastSkillId = effect.getSkill().getId();
  113. count--;
  114. }
  115. toSteal.add(effect);
  116. if (count == 0)
  117. {
  118. break;
  119. }
  120. }
  121. }
  122. if (toSteal.size() == 0)
  123. {
  124. continue;
  125. }
  126. // stealing effects
  127. for (L2Effect eff : toSteal)
  128. {
  129. env = new Env();
  130. env.setCharacter(target);
  131. env.setTarget(activeChar);
  132. env.setSkill(eff.getSkill());
  133. try
  134. {
  135. effect = eff.getEffectTemplate().getStolenEffect(env, eff);
  136. if (effect != null)
  137. {
  138. effect.scheduleEffect();
  139. if (effect.getShowIcon() && activeChar.isPlayer())
  140. {
  141. SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_FEEL_S1_EFFECT);
  142. sm.addSkillName(effect);
  143. activeChar.sendPacket(sm);
  144. }
  145. }
  146. // Finishing stolen effect
  147. eff.exit();
  148. }
  149. catch (RuntimeException e)
  150. {
  151. _log.log(Level.WARNING, "Cannot steal effect: " + eff + " Stealer: " + activeChar + " Stolen: " + target, e);
  152. }
  153. }
  154. // Possibility of a lethal strike
  155. Formulas.calcLethalHit(activeChar, target, skill);
  156. }
  157. if (skill.hasSelfEffects())
  158. {
  159. // Applying self-effects
  160. effect = activeChar.getFirstEffect(skill.getId());
  161. if ((effect != null) && effect.isSelfEffect())
  162. {
  163. // Replace old effect with new one.
  164. effect.exit();
  165. }
  166. skill.getEffectsSelf(activeChar);
  167. }
  168. activeChar.setChargedShot(activeChar.isChargedShot(ShotType.BLESSED_SPIRITSHOTS) ? ShotType.BLESSED_SPIRITSHOTS : ShotType.SPIRITSHOTS, false);
  169. }
  170. @Override
  171. public L2SkillType[] getSkillIds()
  172. {
  173. return SKILL_IDS;
  174. }
  175. }