|
@@ -4,18 +4,24 @@
|
|
package handlers.effecthandlers;
|
|
package handlers.effecthandlers;
|
|
|
|
|
|
import com.l2jserver.gameserver.model.L2Effect;
|
|
import com.l2jserver.gameserver.model.L2Effect;
|
|
|
|
+import com.l2jserver.gameserver.model.L2ItemInstance;
|
|
import com.l2jserver.gameserver.model.actor.L2Character;
|
|
import com.l2jserver.gameserver.model.actor.L2Character;
|
|
|
|
+import com.l2jserver.gameserver.model.actor.L2Npc;
|
|
|
|
+import com.l2jserver.gameserver.model.actor.L2Summon;
|
|
import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
|
|
import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
|
|
|
|
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
|
import com.l2jserver.gameserver.network.SystemMessageId;
|
|
import com.l2jserver.gameserver.network.SystemMessageId;
|
|
import com.l2jserver.gameserver.network.serverpackets.StatusUpdate;
|
|
import com.l2jserver.gameserver.network.serverpackets.StatusUpdate;
|
|
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
|
|
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
|
|
import com.l2jserver.gameserver.skills.Env;
|
|
import com.l2jserver.gameserver.skills.Env;
|
|
|
|
+import com.l2jserver.gameserver.skills.Formulas;
|
|
|
|
+import com.l2jserver.gameserver.skills.Stats;
|
|
import com.l2jserver.gameserver.templates.effects.EffectTemplate;
|
|
import com.l2jserver.gameserver.templates.effects.EffectTemplate;
|
|
|
|
+import com.l2jserver.gameserver.templates.item.L2Item;
|
|
import com.l2jserver.gameserver.templates.skills.L2EffectType;
|
|
import com.l2jserver.gameserver.templates.skills.L2EffectType;
|
|
|
|
|
|
/**
|
|
/**
|
|
* @author UnAfraid
|
|
* @author UnAfraid
|
|
- *
|
|
|
|
*/
|
|
*/
|
|
public class EffectHeal extends L2Effect
|
|
public class EffectHeal extends L2Effect
|
|
{
|
|
{
|
|
@@ -23,7 +29,6 @@ public class EffectHeal extends L2Effect
|
|
{
|
|
{
|
|
super(env, template);
|
|
super(env, template);
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public L2EffectType getEffectType()
|
|
public L2EffectType getEffectType()
|
|
@@ -35,12 +40,88 @@ public class EffectHeal extends L2Effect
|
|
public boolean onStart()
|
|
public boolean onStart()
|
|
{
|
|
{
|
|
L2Character target = getEffected();
|
|
L2Character target = getEffected();
|
|
|
|
+ L2Character activeChar = getEffector();
|
|
if (target == null || target.isDead() || target instanceof L2DoorInstance)
|
|
if (target == null || target.isDead() || target instanceof L2DoorInstance)
|
|
return false;
|
|
return false;
|
|
|
|
|
|
- StatusUpdate su = new StatusUpdate(target);
|
|
|
|
-
|
|
|
|
double amount = calc();
|
|
double amount = calc();
|
|
|
|
+ final L2ItemInstance weaponInst = activeChar.getActiveWeaponInstance();
|
|
|
|
+ double staticShotBonus = 0;
|
|
|
|
+ int mAtkMul = 1;
|
|
|
|
+
|
|
|
|
+ if (weaponInst != null && weaponInst.getChargedSpiritshot() != L2ItemInstance.CHARGED_NONE)
|
|
|
|
+ {
|
|
|
|
+ if (activeChar instanceof L2PcInstance && ((L2PcInstance) activeChar).isMageClass())
|
|
|
|
+ {
|
|
|
|
+ staticShotBonus = getSkill().getMpConsume(); // static bonus for spiritshots
|
|
|
|
+
|
|
|
|
+ if (weaponInst.getChargedSpiritshot() == L2ItemInstance.CHARGED_BLESSED_SPIRITSHOT)
|
|
|
|
+ {
|
|
|
|
+ mAtkMul = 4;
|
|
|
|
+ staticShotBonus *= 2.4; // static bonus for blessed spiritshots
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ mAtkMul = 2;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ // no static bonus
|
|
|
|
+ // grade dynamic bonus
|
|
|
|
+ switch (weaponInst.getItem().getItemGrade())
|
|
|
|
+ {
|
|
|
|
+ case L2Item.CRYSTAL_S84:
|
|
|
|
+ mAtkMul = 4;
|
|
|
|
+ break;
|
|
|
|
+ case L2Item.CRYSTAL_S80:
|
|
|
|
+ mAtkMul = 2;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ // shot dynamic bonus
|
|
|
|
+ if (weaponInst.getChargedSpiritshot() == L2ItemInstance.CHARGED_BLESSED_SPIRITSHOT)
|
|
|
|
+ mAtkMul *= 4; // 16x/8x/4x s84/s80/other
|
|
|
|
+ else
|
|
|
|
+ mAtkMul += 1; // 5x/3x/1x s84/s80/other
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ weaponInst.setChargedSpiritshot(L2ItemInstance.CHARGED_NONE);
|
|
|
|
+ }
|
|
|
|
+ // If there is no weapon equipped, check for an active summon.
|
|
|
|
+ else if (activeChar instanceof L2Summon && ((L2Summon) activeChar).getChargedSpiritShot() != L2ItemInstance.CHARGED_NONE)
|
|
|
|
+ {
|
|
|
|
+ staticShotBonus = getSkill().getMpConsume(); // static bonus for spiritshots
|
|
|
|
+
|
|
|
|
+ if (((L2Summon) activeChar).getChargedSpiritShot() == L2ItemInstance.CHARGED_BLESSED_SPIRITSHOT)
|
|
|
|
+ {
|
|
|
|
+ staticShotBonus *= 2.4; // static bonus for blessed spiritshots
|
|
|
|
+ mAtkMul = 4;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ mAtkMul = 2;
|
|
|
|
+
|
|
|
|
+ ((L2Summon) activeChar).setChargedSpiritShot(L2ItemInstance.CHARGED_NONE);
|
|
|
|
+ }
|
|
|
|
+ else if (activeChar instanceof L2Npc && ((L2Npc) activeChar)._spiritshotcharged)
|
|
|
|
+ {
|
|
|
|
+ staticShotBonus = 2.4 * getSkill().getMpConsume(); // always blessed spiritshots
|
|
|
|
+ mAtkMul = 4;
|
|
|
|
+
|
|
|
|
+ ((L2Npc) activeChar)._spiritshotcharged = false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!getSkill().isStaticHeal())
|
|
|
|
+ {
|
|
|
|
+ amount += staticShotBonus + Math.sqrt(mAtkMul * activeChar.getMAtk(activeChar, null));
|
|
|
|
+ amount *= target.calcStat(Stats.HEAL_EFFECTIVNESS, 100, null, null) / 100;
|
|
|
|
+ // Healer proficiency (since CT1)
|
|
|
|
+ amount *= activeChar.calcStat(Stats.HEAL_PROFICIENCY, 100, null, null) / 100;
|
|
|
|
+ // Extra bonus (since CT1.5)
|
|
|
|
+ if (!getSkill().isPotion())
|
|
|
|
+ amount += target.calcStat(Stats.HEAL_STATIC_BONUS, 0, null, null);
|
|
|
|
+
|
|
|
|
+ // Heal critic, since CT2.3 Gracia Final
|
|
|
|
+ if (!getSkill().isPotion() && Formulas.calcMCrit(activeChar.getMCriticalHit(target, getSkill())))
|
|
|
|
+ amount *= 3;
|
|
|
|
+ }
|
|
|
|
|
|
amount = Math.min(amount, target.getMaxRecoverableHp() - target.getCurrentHp());
|
|
amount = Math.min(amount, target.getMaxRecoverableHp() - target.getCurrentHp());
|
|
|
|
|
|
@@ -48,23 +129,35 @@ public class EffectHeal extends L2Effect
|
|
if (amount < 0)
|
|
if (amount < 0)
|
|
amount = 0;
|
|
amount = 0;
|
|
|
|
|
|
- // To prevent -value heals, set the value only if current hp is less than max recoverable.
|
|
|
|
- if (target.getCurrentHp() < target.getMaxRecoverableHp())
|
|
|
|
- target.setCurrentHp(amount + target.getCurrentHp());
|
|
|
|
|
|
+ target.setCurrentHp(amount + target.getCurrentHp());
|
|
|
|
+ StatusUpdate su = new StatusUpdate(target);
|
|
|
|
+ su.addAttribute(StatusUpdate.CUR_HP, (int) target.getCurrentHp());
|
|
|
|
+ target.sendPacket(su);
|
|
|
|
|
|
- SystemMessage sm;
|
|
|
|
- if (getEffector().getObjectId() != target.getObjectId())
|
|
|
|
|
|
+ if (target instanceof L2PcInstance)
|
|
{
|
|
{
|
|
- sm = SystemMessage.getSystemMessage(SystemMessageId.S2_HP_RESTORED_BY_C1);
|
|
|
|
- sm.addCharName(getEffector());
|
|
|
|
|
|
+ if (getSkill().getId() == 4051)
|
|
|
|
+ {
|
|
|
|
+ SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.REJUVENATING_HP);
|
|
|
|
+ target.sendPacket(sm);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ if (activeChar instanceof L2PcInstance && activeChar != target)
|
|
|
|
+ {
|
|
|
|
+ SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S2_HP_RESTORED_BY_C1);
|
|
|
|
+ sm.addString(activeChar.getName());
|
|
|
|
+ sm.addNumber((int) amount);
|
|
|
|
+ target.sendPacket(sm);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_HP_RESTORED);
|
|
|
|
+ sm.addNumber((int) amount);
|
|
|
|
+ target.sendPacket(sm);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- else
|
|
|
|
- sm = SystemMessage.getSystemMessage(SystemMessageId.S1_HP_RESTORED);
|
|
|
|
-
|
|
|
|
- sm.addNumber((int)amount);
|
|
|
|
- target.sendPacket(sm);
|
|
|
|
- su.addAttribute(StatusUpdate.CUR_HP, (int) target.getCurrentHp());
|
|
|
|
- target.sendPacket(su);
|
|
|
|
|
|
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|