diff options
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 82 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 3 | ||||
| -rw-r--r-- | src/server/game/Spells/Auras/SpellAuraDefines.h | 2 | ||||
| -rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.cpp | 2 |
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?) |
