aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp82
-rw-r--r--src/server/game/Entities/Unit/Unit.h3
-rw-r--r--src/server/game/Spells/Auras/SpellAuraDefines.h2
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp2
4 files changed, 82 insertions, 7 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 3b292e4f7d5..4585e0c8b85 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -2186,6 +2186,74 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
}
}
+void Unit::CalcHealAbsorb(Unit *pVictim, const SpellEntry *healSpell, uint32 &healAmount, uint32 &absorb)
+{
+ if (!healAmount)
+ return;
+
+ int32 RemainingHeal = healAmount;
+ // Get unit state (need for some absorb check)
+ uint32 unitflag = pVictim->GetUInt32Value(UNIT_FIELD_FLAGS);
+ // Need remove expired auras after
+ bool existExpired = false;
+
+ // Incanter's Absorption, for converting to spell power
+ int32 incanterAbsorption = 0;
+
+ // absorb without mana cost
+ AuraEffectList const& vHealAbsorb = pVictim->GetAuraEffectsByType(SPELL_AURA_SCHOOL_HEAL_ABSORB);
+ for (AuraEffectList::const_iterator i = vHealAbsorb.begin(); i != vHealAbsorb.end() && RemainingHeal > 0; ++i)
+ {
+ if (!((*i)->GetMiscValue() & healSpell->SchoolMask))
+ continue;
+
+ SpellEntry const* spellProto = (*i)->GetSpellProto();
+
+ // Max Amount can be absorbed by this aura
+ int32 currentAbsorb = (*i)->GetAmount();
+
+ // Found empty aura (impossible but..)
+ if (currentAbsorb <= 0)
+ {
+ existExpired = true;
+ continue;
+ }
+
+ // currentAbsorb - damage can be absorbed by shield
+ // If need absorb less damage
+ if (RemainingHeal < currentAbsorb)
+ currentAbsorb = RemainingHeal;
+
+ RemainingHeal -= currentAbsorb;
+
+ // Reduce shield amount
+ (*i)->SetAmount((*i)->GetAmount() - currentAbsorb);
+ // Need remove it later
+ if ((*i)->GetAmount() <= 0)
+ existExpired = true;
+ }
+
+ // Remove all expired absorb auras
+ if (existExpired)
+ {
+ for (AuraEffectList::const_iterator i = vHealAbsorb.begin(); i != vHealAbsorb.end();)
+ {
+ AuraEffect *auraEff = *i;
+ ++i;
+ if (auraEff->GetAmount() <= 0)
+ {
+ uint32 removedAuras = pVictim->m_removedAurasCount;
+ auraEff->GetBase()->Remove(AURA_REMOVE_BY_ENEMY_SPELL);
+ if (removedAuras+1 < pVictim->m_removedAurasCount)
+ i = vHealAbsorb.begin();
+ }
+ }
+ }
+
+ absorb = RemainingHeal > 0 ? (healAmount - RemainingHeal) : healAmount;
+ healAmount = RemainingHeal;
+}
+
void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool /*extra*/)
{
if (hasUnitState(UNIT_STAT_CANNOT_AUTOATTACK) || HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED))
@@ -9616,7 +9684,13 @@ void Unit::SetCharm(Unit* charm, bool apply)
int32 Unit::DealHeal(Unit *pVictim, uint32 addhealth, SpellEntry const *spellProto, bool critical)
{
- int32 gain = pVictim->ModifyHealth(int32(addhealth));
+ uint32 absorb = 0;
+ // calculate heal absorb and reduce healing
+ CalcHealAbsorb(pVictim, spellProto, addhealth, absorb);
+ int32 gain = 0;
+
+ if (addhealth)
+ gain = pVictim->ModifyHealth(int32(addhealth));
Unit* unit = this;
@@ -9626,7 +9700,7 @@ int32 Unit::DealHeal(Unit *pVictim, uint32 addhealth, SpellEntry const *spellPro
if (unit->GetTypeId() == TYPEID_PLAYER)
{
// overheal = addhealth - gain
- unit->SendHealSpellLog(pVictim, spellProto->Id, addhealth, addhealth - gain, critical);
+ unit->SendHealSpellLog(pVictim, spellProto->Id, addhealth, addhealth - gain, absorb, critical);
if (BattleGround *bg = unit->ToPlayer()->GetBattleGround())
bg->UpdatePlayerScore((Player*)unit, SCORE_HEALING_DONE, gain);
@@ -9831,7 +9905,7 @@ void Unit::UnsummonAllTotems()
}
}
-void Unit::SendHealSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, uint32 OverHeal, bool critical)
+void Unit::SendHealSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, uint32 OverHeal, uint32 Absorb, bool critical)
{
// we guess size
WorldPacket data(SMSG_SPELLHEALLOG, (8+8+4+4+4+4+1));
@@ -9840,7 +9914,7 @@ void Unit::SendHealSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, uint32
data << uint32(SpellID);
data << uint32(Damage);
data << uint32(OverHeal);
- data << uint32(0); // Absorb amount
+ data << uint32(Absorb); // Absorb amount
data << uint8(critical ? 1 : 0);
SendMessageToSet(&data, true);
}
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 615dfd2cf8a..87bd997a683 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1399,7 +1399,7 @@ class Unit : public WorldObject
virtual bool IsUnderWater() const;
bool isInAccessiblePlaceFor(Creature const* c) const;
- void SendHealSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, uint32 OverHeal, bool critical = false);
+ void SendHealSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, uint32 OverHeal, uint32 Absorb, bool critical = false);
void SendEnergizeSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage,Powers powertype);
void EnergizeBySpell(Unit *pVictim, uint32 SpellID, uint32 Damage, Powers powertype);
uint32 SpellNonMeleeDamageLog(Unit *pVictim, uint32 spellID, uint32 damage);
@@ -1835,6 +1835,7 @@ class Unit : public WorldObject
uint32 CalcNotIgnoreDamageRedunction(uint32 damage, SpellSchoolMask damageSchoolMask);
uint32 CalcArmorReducedDamage(Unit* pVictim, const uint32 damage, SpellEntry const *spellInfo, WeaponAttackType attackType=MAX_ATTACK);
void CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist, SpellEntry const *spellInfo = NULL);
+ void CalcHealAbsorb(Unit *pVictim, const SpellEntry *spellProto, uint32 &healAmount, uint32 &absorb);
void UpdateSpeed(UnitMoveType mtype, bool forced);
float GetSpeed(UnitMoveType mtype) const;
diff --git a/src/server/game/Spells/Auras/SpellAuraDefines.h b/src/server/game/Spells/Auras/SpellAuraDefines.h
index 8b21062e371..81af1e71ecc 100644
--- a/src/server/game/Spells/Auras/SpellAuraDefines.h
+++ b/src/server/game/Spells/Auras/SpellAuraDefines.h
@@ -345,7 +345,7 @@ enum AuraType
SPELL_AURA_298 = 298,
SPELL_AURA_299 = 299,
SPELL_AURA_300 = 300,
- SPELL_AURA_301 = 301,
+ SPELL_AURA_SCHOOL_HEAL_ABSORB = 301,
SPELL_AURA_302 = 302,
SPELL_AURA_303 = 303,
SPELL_AURA_304 = 304,
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 89fcd379e85..54bb87470bc 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -354,7 +354,7 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleNULL, //298 unused
&AuraEffect::HandleNULL, //299 unused
&AuraEffect::HandleNULL, //300 3 spells (share damage?)
- &AuraEffect::HandleNULL, //301 5 spells
+ &AuraEffect::HandleNoImmediateEffect, //301 SPELL_AURA_SCHOOL_HEAL_ABSORB implemented in Unit::CalcHealAbsorb
&AuraEffect::HandleNULL, //302 unused
&AuraEffect::HandleNULL, //303 17 spells
&AuraEffect::HandleNULL, //304 2 spells (alcohol effect?)