Heal.java 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  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.gameserver.handler.ISkillHandler;
  17. import com.l2jserver.gameserver.handler.SkillHandler;
  18. import com.l2jserver.gameserver.model.L2Object;
  19. import com.l2jserver.gameserver.model.ShotType;
  20. import com.l2jserver.gameserver.model.actor.L2Character;
  21. import com.l2jserver.gameserver.model.actor.instance.L2SiegeFlagInstance;
  22. import com.l2jserver.gameserver.model.items.L2Item;
  23. import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
  24. import com.l2jserver.gameserver.model.skills.L2Skill;
  25. import com.l2jserver.gameserver.model.skills.L2SkillType;
  26. import com.l2jserver.gameserver.model.stats.Formulas;
  27. import com.l2jserver.gameserver.model.stats.Stats;
  28. import com.l2jserver.gameserver.network.SystemMessageId;
  29. import com.l2jserver.gameserver.network.serverpackets.StatusUpdate;
  30. import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
  31. public class Heal implements ISkillHandler
  32. {
  33. private static final L2SkillType[] SKILL_IDS =
  34. {
  35. L2SkillType.HEAL,
  36. L2SkillType.HEAL_STATIC
  37. };
  38. @Override
  39. public void useSkill(L2Character activeChar, L2Skill skill, L2Object[] targets)
  40. {
  41. //check for other effects
  42. ISkillHandler handler = SkillHandler.getInstance().getHandler(L2SkillType.BUFF);
  43. if (handler != null)
  44. handler.useSkill(activeChar, skill, targets);
  45. double power = skill.getPower();
  46. boolean sps = skill.isMagic() && activeChar.isChargedShot(ShotType.SPIRITSHOTS);
  47. boolean bss = skill.isMagic() && activeChar.isChargedShot(ShotType.BLESSED_SPIRITSHOTS);
  48. switch (skill.getSkillType())
  49. {
  50. case HEAL_STATIC:
  51. break;
  52. default:
  53. double staticShotBonus = 0;
  54. int mAtkMul = 1; // mAtk multiplier
  55. if ((sps || bss) && (activeChar.isPlayer() && activeChar.getActingPlayer().isMageClass()) || activeChar.isSummon())
  56. {
  57. staticShotBonus = skill.getMpConsume(); // static bonus for spiritshots
  58. if (bss)
  59. {
  60. mAtkMul = 4;
  61. staticShotBonus *= 2.4; // static bonus for blessed spiritshots
  62. }
  63. else
  64. mAtkMul = 2;
  65. }
  66. else if ((sps || bss) && activeChar.isNpc())
  67. {
  68. staticShotBonus = 2.4 * skill.getMpConsume(); // always blessed spiritshots
  69. mAtkMul = 4;
  70. }
  71. else
  72. {
  73. // no static bonus
  74. // grade dynamic bonus
  75. final L2ItemInstance weaponInst = activeChar.getActiveWeaponInstance();
  76. if (weaponInst != null)
  77. {
  78. switch (weaponInst.getItem().getItemGrade())
  79. {
  80. case L2Item.CRYSTAL_S84:
  81. mAtkMul = 4;
  82. break;
  83. case L2Item.CRYSTAL_S80:
  84. mAtkMul = 2;
  85. break;
  86. }
  87. }
  88. // shot dynamic bonus
  89. if (bss)
  90. mAtkMul *= 4; // 16x/8x/4x s84/s80/other
  91. else
  92. mAtkMul += 1; // 5x/3x/1x s84/s80/other
  93. }
  94. power += staticShotBonus + Math.sqrt(mAtkMul * activeChar.getMAtk(activeChar, null));
  95. activeChar.setChargedShot(bss ? ShotType.BLESSED_SPIRITSHOTS : ShotType.SPIRITSHOTS, false);
  96. }
  97. double hp;
  98. for (L2Character target: (L2Character[]) targets)
  99. {
  100. // We should not heal if char is dead/invul
  101. if (target == null || target.isDead() || target.isInvul())
  102. continue;
  103. if (target.isDoor() || target instanceof L2SiegeFlagInstance)
  104. continue;
  105. // Player holding a cursed weapon can't be healed and can't heal
  106. if (target != activeChar)
  107. {
  108. if (target.isPlayer() && target.getActingPlayer().isCursedWeaponEquipped())
  109. continue;
  110. else if (activeChar.isPlayer() && activeChar.getActingPlayer().isCursedWeaponEquipped())
  111. continue;
  112. }
  113. switch (skill.getSkillType())
  114. {
  115. case HEAL_PERCENT:
  116. hp = target.getMaxHp() * power / 100.0;
  117. break;
  118. default:
  119. hp = power;
  120. hp *= target.calcStat(Stats.HEAL_EFFECTIVNESS, 100, null, null) / 100;
  121. }
  122. // Healer proficiency (since CT1)
  123. hp *= activeChar.calcStat(Stats.HEAL_PROFICIENCY, 100, null, null) / 100;
  124. // Extra bonus (since CT1.5)
  125. if (!skill.isStatic())
  126. hp += target.calcStat(Stats.HEAL_STATIC_BONUS, 0, null, null);
  127. // Heal critic, since CT2.3 Gracia Final
  128. if(skill.getSkillType() == L2SkillType.HEAL && !skill.isStatic()
  129. && Formulas.calcMCrit(activeChar.getMCriticalHit(target, skill)))
  130. hp *= 3;
  131. //from CT2 u will receive exact HP, u can't go over it, if u have full HP and u get HP buff, u will receive 0HP restored message
  132. hp = Math.min(hp, target.getMaxRecoverableHp() - target.getCurrentHp());
  133. if (hp < 0)
  134. hp = 0;
  135. target.setCurrentHp(hp + target.getCurrentHp());
  136. StatusUpdate su = new StatusUpdate(target);
  137. su.addAttribute(StatusUpdate.CUR_HP, (int) target.getCurrentHp());
  138. target.sendPacket(su);
  139. if (target.isPlayer())
  140. {
  141. if (skill.getId() == 4051)
  142. {
  143. SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.REJUVENATING_HP);
  144. target.sendPacket(sm);
  145. }
  146. else
  147. {
  148. if (activeChar.isPlayer() && activeChar != target)
  149. {
  150. SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S2_HP_RESTORED_BY_C1);
  151. sm.addString(activeChar.getName());
  152. sm.addNumber((int) hp);
  153. target.sendPacket(sm);
  154. }
  155. else
  156. {
  157. SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_HP_RESTORED);
  158. sm.addNumber((int) hp);
  159. target.sendPacket(sm);
  160. }
  161. }
  162. }
  163. }
  164. }
  165. @Override
  166. public L2SkillType[] getSkillIds()
  167. {
  168. return SKILL_IDS;
  169. }
  170. }