diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index bf747be48..ba6c10424 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -333,7 +333,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleNULL, //280 SPELL_AURA_MOD_TARGET_ARMOR_PCT &Aura::HandleNULL, //281 SPELL_AURA_MOD_HONOR_GAIN &Aura::HandleAuraIncreaseBaseHealthPercent, //282 SPELL_AURA_INCREASE_BASE_HEALTH_PERCENT - &Aura::HandleNULL //283 SPD/heal from AP? + &Aura::HandleNoImmediateEffect //283 SPELL_AURA_MOD_HEALING_RECEIVED implemented in Unit::SpellHealingBonus }; Aura::Aura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem) : diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 108bd404b..61e88cc5d 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -8110,33 +8110,101 @@ uint32 Unit::SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount, spellProto->Id == 38395 || spellProto->Id == 40972) return healamount; - int32 AdvertisedBenefit = SpellBaseHealingBonus(GetSpellSchoolMask(spellProto)); - uint32 CastingTime = GetSpellCastTime(spellProto); + // Taken/Done total percent damage auras + float DoneTotalMod = 1.0f; + float TakenTotalMod = 1.0f; + uint32 DoneTotal = 0; + uint32 TakenTotal = 0; - // Healing Taken - AdvertisedBenefit += SpellBaseHealingBonusForVictim(GetSpellSchoolMask(spellProto), pVictim); + // Healing done percent + AuraList const& mHealingDonePct = GetAurasByType(SPELL_AURA_MOD_HEALING_DONE_PERCENT); + for(AuraList::const_iterator i = mHealingDonePct.begin();i != mHealingDonePct.end(); ++i) + DoneTotalMod *= (100.0f + (*i)->GetModifier()->m_amount) / 100.0f; - // Blessing of Light dummy effects healing taken from Holy Light and Flash of Light - if (spellProto->SpellFamilyName == SPELLFAMILY_PALADIN && (spellProto->SpellFamilyFlags & 0x00000000C0000000LL)) + // done scripted mod (take it from owner) + Unit *owner = GetOwner(); + if (!owner) owner = this; + AuraList const& mOverrideClassScript= owner->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); + for(AuraList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i) { - AuraList const& mDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY); - for(AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i) + if (!(*i)->isAffectedOnSpell(spellProto)) + continue; + switch((*i)->GetModifier()->m_miscvalue) { - if((*i)->GetSpellProto()->SpellVisual[0] == 9180) + case 4415: // Increased Rejuvenation Healing + case 4953: + case 3736: // Hateful Totem of the Third Wind / Increased Lesser Healing Wave / LK Arena (4/5/6) Totem of the Third Wind / Savage Totem of the Third Wind + DoneTotal+=(*i)->GetModifier()->m_amount; + break; + case 7997: // Renewed Hope + case 7998: + if (pVictim->HasAura(6788)) + DoneTotalMod *=((*i)->GetModifier()->m_amount + 100.0f)/100.0f; + break; + case 21: // Test of Faith + case 6935: + case 6918: + if (pVictim->GetHealth() < pVictim->GetMaxHealth()/2) + DoneTotalMod *=((*i)->GetModifier()->m_amount + 100.0f)/100.0f; + break; + case 7798: // Glyph of Regrowth { - // Flash of Light - if ((spellProto->SpellFamilyFlags & 0x0000000040000000LL) && (*i)->GetEffIndex() == 1) - AdvertisedBenefit += (*i)->GetModifier()->m_amount; - // Holy Light - else if ((spellProto->SpellFamilyFlags & 0x0000000080000000LL) && (*i)->GetEffIndex() == 0) - AdvertisedBenefit += (*i)->GetModifier()->m_amount; + AuraList const& auras = pVictim->GetAurasByType(SPELL_AURA_PERIODIC_HEAL); + for(AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + { + SpellEntry const* m_spell = (*itr)->GetSpellProto(); + if (m_spell->SpellFamilyName == SPELLFAMILY_DRUID && + m_spell->SpellFamilyFlags & 0x0000000000000040LL) + { + DoneTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f; + break; + } + } + break; } + case 8477: // Nourish Heal Boost + { + int32 stepPercent = (*i)->GetModifier()->m_amount; + int32 modPercent = 0; + AuraMap const& victimAuras = pVictim->GetAuras(); + for (AuraMap::const_iterator itr = victimAuras.begin(); itr != victimAuras.end(); ++itr) + { + if (itr->second->GetCasterGUID()!=GetGUID()) + continue; + SpellEntry const* m_spell = itr->second->GetSpellProto(); + if ( m_spell->SpellFamilyName != SPELLFAMILY_DRUID || + !(m_spell->SpellFamilyFlags & 0x0000001000000050LL)) + continue; + modPercent += stepPercent * itr->second->GetStackAmount(); + } + DoneTotalMod *= (modPercent+100.0f)/100.0f; + break; + } + case 7871: // Glyph of Lesser Healing Wave + { + AuraList const& auras = pVictim->GetAurasByType(SPELL_AURA_DUMMY); + for(AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + { + if ((*itr)->GetCasterGUID()!=GetGUID()) + continue; + SpellEntry const* m_spell = (*itr)->GetSpellProto(); + if (m_spell->SpellFamilyName == SPELLFAMILY_SHAMAN && + m_spell->SpellFamilyFlags & 0x0000040000000000LL) + { + DoneTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f; + break; + } + } + break; + } + default: + break; } } - float ActualBenefit = 0.0f; - - if (AdvertisedBenefit != 0) + int32 DoneAdvertisedBenefit = SpellBaseHealingBonus(GetSpellSchoolMask(spellProto)); + int32 TakenAdvertisedBenefit = SpellBaseHealingBonusForVictim(GetSpellSchoolMask(spellProto), pVictim); + if (DoneAdvertisedBenefit != 0 && TakenAdvertisedBenefit!=0) { // Healing over Time spells float DotFactor = 1.0f; @@ -8163,9 +8231,13 @@ uint32 Unit::SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount, if(spellProto->EffectAmplitude[x] != 0) DotTicks = DotDuration / spellProto->EffectAmplitude[x]; if(DotTicks) - AdvertisedBenefit /= DotTicks; + { + DoneAdvertisedBenefit /= DotTicks; + TakenAdvertisedBenefit /= DotTicks; + } } } + uint32 CastingTime = GetSpellCastTime(spellProto); // distribute healing to all effects, reduce AoE damage CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime ); @@ -8184,12 +8256,15 @@ uint32 Unit::SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount, // Exception switch (spellProto->SpellFamilyName) { - case SPELLFAMILY_SHAMAN: + case SPELLFAMILY_GENERIC: // Healing stream from totem (add 6% per tick from hill bonus owner) - if (spellProto->SpellFamilyFlags & 0x000000002000LL) + // Possibly need do it on apply dummy aura + if (spellProto->Id == 52042) CastingTime = 210; + break; + case SPELLFAMILY_SHAMAN: // Earth Shield 30% per charge - else if (spellProto->SpellFamilyFlags & 0x40000000000LL) + if (spellProto->SpellFamilyFlags & 0x40000000000LL) CastingTime = 1050; break; case SPELLFAMILY_DRUID: @@ -8239,48 +8314,44 @@ uint32 Unit::SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount, SpellModSpellDamage /= 100.0f; - ActualBenefit = (float)AdvertisedBenefit * ((float)CastingTime / 3500.0f) * DotFactor * SpellModSpellDamage * LvlPenalty; + DoneTotal += (float)DoneAdvertisedBenefit * ((float)CastingTime / 3500.0f) * DotFactor * SpellModSpellDamage * LvlPenalty; + TakenTotal += (float)TakenAdvertisedBenefit * ((float)CastingTime / 3500.0f) * DotFactor * SpellModSpellDamage * LvlPenalty; } // use float as more appropriate for negative values and percent applying - float heal = healamount + ActualBenefit; - - // TODO: check for ALL/SPELLS type - // Healing done percent - AuraList const& mHealingDonePct = GetAurasByType(SPELL_AURA_MOD_HEALING_DONE_PERCENT); - for(AuraList::const_iterator i = mHealingDonePct.begin();i != mHealingDonePct.end(); ++i) - heal *= (100.0f + (*i)->GetModifier()->m_amount) / 100.0f; - + float heal = (healamount + DoneTotal)*DoneTotalMod; // apply spellmod to Done amount if(Player* modOwner = GetSpellModOwner()) modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, heal); + // Taken mods // Healing Wave cast if (spellProto->SpellFamilyName == SPELLFAMILY_SHAMAN && spellProto->SpellFamilyFlags & 0x0000000000000040LL) { - // Search for Healing Way on Victim (stack up to 3 time) - int32 pctMod = 0; + // Search for Healing Way on Victim Unit::AuraList const& auraDummy = pVictim->GetAurasByType(SPELL_AURA_DUMMY); for(Unit::AuraList::const_iterator itr = auraDummy.begin(); itr!=auraDummy.end(); ++itr) if((*itr)->GetId() == 29203) - pctMod += (*itr)->GetModifier()->m_amount; - // Apply bonus - if (pctMod) - heal = heal * (100 + pctMod) / 100; + TakenTotalMod *= (*itr)->GetModifier()->m_amount; } // Healing taken percent float minval = pVictim->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_HEALING_PCT); if(minval) - heal *= (100.0f + minval) / 100.0f; + TakenTotalMod *= (100.0f + minval) / 100.0f; float maxval = pVictim->GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HEALING_PCT); if(maxval) - heal *= (100.0f + maxval) / 100.0f; + TakenTotalMod *= (100.0f + maxval) / 100.0f; - if (heal < 0) heal = 0; + AuraList const& mHealingGet= pVictim->GetAurasByType(SPELL_AURA_MOD_HEALING_RECEIVED); + for(AuraList::const_iterator i = mHealingGet.begin(); i != mHealingGet.end(); ++i) + if ((*i)->isAffectedOnSpell(spellProto)) + TakenTotalMod *= ((*i)->GetModifier()->m_amount + 100.0f) / 100.0f; - return uint32(heal); + heal = (heal + TakenTotal) * TakenTotalMod; + + return heal < 0 ? 0 : uint32(heal); } int32 Unit::SpellBaseHealingBonus(SpellSchoolMask schoolMask) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 8b9bbd4e5..71d4d56a9 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7189" + #define REVISION_NR "7190" #endif // __REVISION_NR_H__