Merge pull request #6314 from Chaplain/spells

Core/Spells: Separation of caster/target part damage/heal bonus calculation.
This commit is contained in:
QAston
2012-05-09 15:10:33 -07:00
13 changed files with 461 additions and 368 deletions
+5 -5
View File
@@ -940,14 +940,14 @@ bool Guardian::InitStatsForLevel(uint8 petlevel)
{
case 510: // mage Water Elemental
{
SetBonusDamage(int32(m_owner->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_FROST) * 0.33f));
SetBonusDamage(int32(m_owner->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_FROST) * 0.33f));
break;
}
case 1964: //force of nature
{
if (!pInfo)
SetCreateHealth(30 + 30*petlevel);
float bonusDmg = m_owner->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_NATURE) * 0.15f;
float bonusDmg = m_owner->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_NATURE) * 0.15f;
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel * 2.5f - (petlevel / 2) + bonusDmg));
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel * 2.5f + (petlevel / 2) + bonusDmg));
break;
@@ -967,7 +967,7 @@ bool Guardian::InitStatsForLevel(uint8 petlevel)
SetCreateHealth(40*petlevel);
SetCreateMana(28 + 10*petlevel);
}
SetBonusDamage(int32(m_owner->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_FIRE) * 0.5f));
SetBonusDamage(int32(m_owner->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_FIRE) * 0.5f));
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel * 4 - petlevel));
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel * 4 + petlevel));
break;
@@ -979,7 +979,7 @@ bool Guardian::InitStatsForLevel(uint8 petlevel)
SetCreateMana(28 + 10*petlevel);
SetCreateHealth(28 + 30*petlevel);
}
int32 bonus_dmg = (int32(m_owner->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_SHADOW)* 0.3f));
int32 bonus_dmg = (int32(m_owner->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_SHADOW)* 0.3f));
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float((petlevel * 4 - petlevel) + bonus_dmg));
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float((petlevel * 4 + petlevel) + bonus_dmg));
@@ -1020,7 +1020,7 @@ bool Guardian::InitStatsForLevel(uint8 petlevel)
}
case 31216: // Mirror Image
{
SetBonusDamage(int32(m_owner->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_FROST) * 0.33f));
SetBonusDamage(int32(m_owner->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_FROST) * 0.33f));
SetDisplayId(m_owner->GetDisplayId());
if (!pInfo)
{
+3 -3
View File
@@ -142,13 +142,13 @@ void Player::ApplySpellPowerBonus(int32 amount, bool apply)
void Player::UpdateSpellDamageAndHealingBonus()
{
// Magic damage modifiers implemented in Unit::SpellDamageBonus
// Magic damage modifiers implemented in Unit::SpellDamageBonusDone
// This information for client side use only
// Get healing bonus for all schools
SetStatInt32Value(PLAYER_FIELD_MOD_HEALING_DONE_POS, SpellBaseHealingBonus(SPELL_SCHOOL_MASK_ALL));
SetStatInt32Value(PLAYER_FIELD_MOD_HEALING_DONE_POS, SpellBaseHealingBonusDone(SPELL_SCHOOL_MASK_ALL));
// Get damage bonus for all schools
for (int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
SetStatInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i, SpellBaseDamageBonus(SpellSchoolMask(1 << i)));
SetStatInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i, SpellBaseDamageBonusDone(SpellSchoolMask(1 << i)));
}
bool Player::UpdateAllStats()
+314 -308
View File
@@ -953,7 +953,9 @@ uint32 Unit::SpellNonMeleeDamageLog(Unit* victim, uint32 spellID, uint32 damage)
{
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellID);
SpellNonMeleeDamage damageInfo(this, victim, spellInfo->Id, spellInfo->SchoolMask);
damage = SpellDamageBonus(victim, spellInfo, damage, SPELL_DIRECT_DAMAGE);
damage = SpellDamageBonusDone(victim, spellInfo, damage, SPELL_DIRECT_DAMAGE);
damage = victim->SpellDamageBonusTaken(spellInfo, damage, SPELL_DIRECT_DAMAGE);
CalculateSpellDamageTaken(&damageInfo, damage, spellInfo);
DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
SendSpellNonMeleeDamageLog(&damageInfo);
@@ -1148,7 +1150,8 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam
damage += CalculateDamage(damageInfo->attackType, false, true);
// Add melee damage bonus
MeleeDamageBonus(damageInfo->target, &damage, damageInfo->attackType);
damage = MeleeDamageBonusDone(damageInfo->target, damage, damageInfo->attackType);
damage = MeleeDamageBonusTaken(damage, damageInfo->attackType);
// Calculate armor reduction
if (IsDamageReducedByArmor((SpellSchoolMask)(damageInfo->damageSchoolMask)))
@@ -1400,7 +1403,10 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss)
uint32 damage = (*dmgShieldItr)->GetAmount();
if (Unit* caster = (*dmgShieldItr)->GetCaster())
damage = caster->SpellDamageBonus(this, i_spellProto, damage, SPELL_DIRECT_DAMAGE);
{
damage = caster->SpellDamageBonusDone(this, i_spellProto, damage, SPELL_DIRECT_DAMAGE);
damage = this->SpellDamageBonusTaken(i_spellProto, damage, SPELL_DIRECT_DAMAGE);
}
// No Unit::CalcAbsorbResist here - opcode doesn't send that data - this damage is probably not affected by that
victim->DealDamageMods(this, damage, NULL);
@@ -3652,7 +3658,10 @@ void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId
// final heal
int32 healAmount = aurEff->GetAmount();
if (Unit* caster = aura->GetCaster())
healAmount = caster->SpellHealingBonus(this, aura->GetSpellInfo(), healAmount, HEAL, dispelInfo.GetRemovedCharges());
{
healAmount = caster->SpellHealingBonusDone(this, aura->GetSpellInfo(), healAmount, HEAL, dispelInfo.GetRemovedCharges());
healAmount = this->SpellHealingBonusTaken(aura->GetSpellInfo(), healAmount, HEAL, dispelInfo.GetRemovedCharges());
}
CastCustomSpell(this, 33778, &healAmount, NULL, NULL, true, NULL, NULL, aura->GetCasterGUID());
// mana
@@ -6724,8 +6733,8 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
return false;
triggered_spell_id = 25742;
float ap = GetTotalAttackPowerValue(BASE_ATTACK);
int32 holy = SpellBaseDamageBonus(SPELL_SCHOOL_MASK_HOLY) +
SpellBaseDamageBonusForVictim(SPELL_SCHOOL_MASK_HOLY, victim);
int32 holy = SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_HOLY) +
victim->SpellBaseDamageBonusTaken(SPELL_SCHOOL_MASK_HOLY);
basepoints0 = (int32)GetAttackTime(BASE_ATTACK) * int32(ap * 0.022f + 0.044f * holy) / 1000;
break;
}
@@ -7435,8 +7444,8 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
float fire_onhit = float(CalculatePctF(dummySpell->Effects[EFFECT_0]. CalcValue(), 1.0f));
float add_spellpower = (float)(SpellBaseDamageBonus(SPELL_SCHOOL_MASK_FIRE)
+ SpellBaseDamageBonusForVictim(SPELL_SCHOOL_MASK_FIRE, victim));
float add_spellpower = (float)(SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_FIRE)
+ victim->SpellBaseDamageBonusTaken(SPELL_SCHOOL_MASK_FIRE));
// 1.3speed = 5%, 2.6speed = 10%, 4.0 speed = 15%, so, 1.0speed = 3.84%
ApplyPctF(add_spellpower, 3.84f);
@@ -9007,7 +9016,7 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
{
if (AuraEffect* aurEff = owner->GetDummyAuraEffect(SPELLFAMILY_WARLOCK, 3220, 0))
{
basepoints0 = int32((aurEff->GetAmount() * owner->SpellBaseDamageBonus(SpellSchoolMask(SPELL_SCHOOL_MASK_MAGIC)) + 100.0f) / 100.0f); // TODO: Is it right?
basepoints0 = int32((aurEff->GetAmount() * owner->SpellBaseDamageBonusDone(SpellSchoolMask(SPELL_SCHOOL_MASK_MAGIC)) + 100.0f) / 100.0f); // TODO: Is it right?
CastCustomSpell(this, trigger_spell_id, &basepoints0, &basepoints0, NULL, true, castItem, triggeredByAura);
return true;
}
@@ -10374,7 +10383,7 @@ void Unit::EnergizeBySpell(Unit* victim, uint32 spellID, uint32 damage, Powers p
victim->getHostileRefManager().threatAssist(this, float(damage) * 0.5f, spellInfo);
}
uint32 Unit::SpellDamageBonus(Unit* victim, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack)
uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack)
{
if (!spellProto || !victim || damagetype == DIRECT_DAMAGE)
return pdamage;
@@ -10387,15 +10396,13 @@ uint32 Unit::SpellDamageBonus(Unit* victim, SpellInfo const* spellProto, uint32
// For totems get damage bonus from owner
if (GetTypeId() == TYPEID_UNIT && ToCreature()->isTotem())
if (Unit* owner = GetOwner())
return owner->SpellDamageBonus(victim, spellProto, pdamage, damagetype);
return owner->SpellDamageBonusDone(victim, spellProto, pdamage, damagetype);
// Taken/Done total percent damage auras
// Done total percent damage auras
float DoneTotalMod = 1.0f;
float ApCoeffMod = 1.0f;
int32 DoneTotal = 0;
int32 TakenTotal = 0;
// ..done
// Pet damage?
if (GetTypeId() == TYPEID_UNIT && !ToCreature()->isPet())
DoneTotalMod *= ToCreature()->GetSpellDamageMod(ToCreature()->GetCreatureTemplate()->rank);
@@ -10726,50 +10733,8 @@ uint32 Unit::SpellDamageBonus(Unit* victim, SpellInfo const* spellProto, uint32
break;
}
// ..taken
float TakenTotalMod = 1.0f;
// from positive and negative SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN
// multiplicative bonus, for example Dispersion + Shadowform (0.10*0.85=0.085)
TakenTotalMod *= victim->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, spellProto->GetSchoolMask());
// .. taken pct: dummy auras
AuraEffectList const& mDummyAuras = victim->GetAuraEffectsByType(SPELL_AURA_DUMMY);
for (AuraEffectList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i)
{
switch ((*i)->GetSpellInfo()->SpellIconID)
{
// Cheat Death
case 2109:
if ((*i)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL)
{
if (victim->GetTypeId() != TYPEID_PLAYER)
continue;
float mod = victim->ToPlayer()->GetRatingBonusValue(CR_CRIT_TAKEN_MELEE) * (-8.0f);
AddPctF(TakenTotalMod, std::max(mod, float((*i)->GetAmount())));
}
break;
}
}
// From caster spells
AuraEffectList const& mOwnerTaken = victim->GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER);
for (AuraEffectList::const_iterator i = mOwnerTaken.begin(); i != mOwnerTaken.end(); ++i)
if ((*i)->GetCasterGUID() == GetGUID() && (*i)->IsAffectedOnSpell(spellProto))
AddPctN(TakenTotalMod, (*i)->GetAmount());
// Mod damage from spell mechanic
if (uint32 mechanicMask = spellProto->GetAllEffectsMechanicMask())
{
AuraEffectList const& mDamageDoneMechanic = victim->GetAuraEffectsByType(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT);
for (AuraEffectList::const_iterator i = mDamageDoneMechanic.begin(); i != mDamageDoneMechanic.end(); ++i)
if (mechanicMask & uint32(1<<((*i)->GetMiscValue())))
AddPctN(TakenTotalMod, (*i)->GetAmount());
}
// Taken/Done fixed damage bonus auras
int32 DoneAdvertisedBenefit = SpellBaseDamageBonus(spellProto->GetSchoolMask());
int32 TakenAdvertisedBenefit = SpellBaseDamageBonusForVictim(spellProto->GetSchoolMask(), victim);
// Done fixed damage bonus auras
int32 DoneAdvertisedBenefit = SpellBaseDamageBonusDone(spellProto->GetSchoolMask());
// Pets just add their bonus damage to their spell damage
// note that their spell damage is just gain of their own auras
if (HasUnitTypeMask(UNIT_MASK_GUARDIAN))
@@ -10804,67 +10769,13 @@ uint32 Unit::SpellDamageBonus(Unit* victim, SpellInfo const* spellProto, uint32
}
}
// Default calculation
if (DoneAdvertisedBenefit || TakenAdvertisedBenefit)
if (DoneAdvertisedBenefit)
{
if (!bonus || coeff < 0)
{
// Damage Done from spell damage bonus
int32 CastingTime = spellProto->IsChanneled() ? spellProto->GetDuration() : spellProto->CalcCastTime();
// Damage over Time spells bonus calculation
float DotFactor = 1.0f;
if (damagetype == DOT)
{
int32 DotDuration = spellProto->GetDuration();
// 200% limit
if (DotDuration > 0)
{
if (DotDuration > 30000)
DotDuration = 30000;
if (!spellProto->IsChanneled())
DotFactor = DotDuration / 15000.0f;
uint8 x = 0;
for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
{
if (spellProto->Effects[j].Effect == SPELL_EFFECT_APPLY_AURA && (
spellProto->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE ||
spellProto->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_LEECH))
{
x = j;
break;
}
}
int32 DotTicks = 6;
if (spellProto->Effects[x].Amplitude != 0)
DotTicks = DotDuration / spellProto->Effects[x].Amplitude;
if (DotTicks)
{
DoneAdvertisedBenefit /= DotTicks;
TakenAdvertisedBenefit /= DotTicks;
}
}
}
// Distribute Damage over multiple effects, reduce by AoE
CastingTime = GetCastingTimeForBonus(spellProto, damagetype, CastingTime);
// 50% for damage and healing spells for leech spells from damage bonus and 0% from healing
for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
{
if (spellProto->Effects[j].Effect == SPELL_EFFECT_HEALTH_LEECH ||
(spellProto->Effects[j].Effect == SPELL_EFFECT_APPLY_AURA && spellProto->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_LEECH))
{
CastingTime /= 2;
break;
}
}
if (spellProto->SchoolMask != SPELL_SCHOOL_MASK_NORMAL)
coeff = (CastingTime / 3500.0f) * DotFactor;
else
coeff = DotFactor;
}
coeff = CalculateDefaultCoefficient(spellProto, damagetype) * int32(stack);
float factorMod = CalculateLevelPenalty(spellProto) * stack;
// level penalty still applied on Taken bonus - is it blizzlike?
TakenTotal+= int32(TakenAdvertisedBenefit * factorMod);
if (Player* modOwner = GetSpellModOwner())
{
coeff *= 100.0f;
@@ -10892,16 +10803,89 @@ uint32 Unit::SpellDamageBonus(Unit* victim, SpellInfo const* spellProto, uint32
if (Player* modOwner = GetSpellModOwner())
modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, tmpDamage);
tmpDamage = (tmpDamage + TakenTotal) * TakenTotalMod;
return uint32(std::max(tmpDamage, 0.0f));
}
uint32 Unit::SpellDamageBonusTaken(SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack)
{
if (!spellProto || damagetype == DIRECT_DAMAGE)
return pdamage;
int32 TakenTotal = 0;
float TakenTotalMod = 1.0f;
//from positive and negative SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN
//multiplicative bonus, for example Dispersion + Shadowform (0.10*0.85=0.085)
TakenTotalMod *= GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, spellProto->GetSchoolMask());
//.. taken pct: dummy auras
AuraEffectList const& mDummyAuras = GetAuraEffectsByType(SPELL_AURA_DUMMY);
for (AuraEffectList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i)
{
switch ((*i)->GetSpellInfo()->SpellIconID)
{
// Cheat Death
case 2109:
if ((*i)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL)
{
if (GetTypeId() != TYPEID_PLAYER)
continue;
float mod = ToPlayer()->GetRatingBonusValue(CR_CRIT_TAKEN_MELEE) * (-8.0f);
AddPctF(TakenTotalMod, std::max(mod, float((*i)->GetAmount())));
}
break;
}
}
// From caster spells
AuraEffectList const& mOwnerTaken = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER);
for (AuraEffectList::const_iterator i = mOwnerTaken.begin(); i != mOwnerTaken.end(); ++i)
if ((*i)->GetCasterGUID() == GetGUID() && (*i)->IsAffectedOnSpell(spellProto))
AddPctN(TakenTotalMod, (*i)->GetAmount());
// Mod damage from spell mechanic
if (uint32 mechanicMask = spellProto->GetAllEffectsMechanicMask())
{
AuraEffectList const& mDamageDoneMechanic = GetAuraEffectsByType(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT);
for (AuraEffectList::const_iterator i = mDamageDoneMechanic.begin(); i != mDamageDoneMechanic.end(); ++i)
if (mechanicMask & uint32(1<<((*i)->GetMiscValue())))
AddPctN(TakenTotalMod, (*i)->GetAmount());
}
int32 TakenAdvertisedBenefit = SpellBaseDamageBonusTaken(spellProto->GetSchoolMask());
// Check for table values
float coeff = 0;
SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id);
if (bonus)
coeff = (damagetype == DOT) ? bonus->dot_damage : bonus->direct_damage;
// Default calculation
if (TakenAdvertisedBenefit)
{
if (!bonus || coeff < 0)
coeff = CalculateDefaultCoefficient(spellProto, damagetype) * int32(stack);
float factorMod = CalculateLevelPenalty(spellProto) * stack;
// level penalty still applied on Taken bonus - is it blizzlike?
if (Player* modOwner = GetSpellModOwner())
{
coeff *= 100.0f;
modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff);
coeff /= 100.0f;
}
TakenTotal+= int32(TakenAdvertisedBenefit * coeff * factorMod);
}
float tmpDamage = (pdamage + TakenTotal) * TakenTotalMod;
return uint32(std::max(tmpDamage, 0.0f));
}
int32 Unit::SpellBaseDamageBonus(SpellSchoolMask schoolMask)
int32 Unit::SpellBaseDamageBonusDone(SpellSchoolMask schoolMask)
{
int32 DoneAdvertisedBenefit = 0;
// ..done
AuraEffectList const& mDamageDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_DONE);
for (AuraEffectList::const_iterator i = mDamageDone.begin(); i != mDamageDone.end(); ++i)
if (((*i)->GetMiscValue() & schoolMask) != 0 &&
@@ -10937,19 +10921,11 @@ int32 Unit::SpellBaseDamageBonus(SpellSchoolMask schoolMask)
return DoneAdvertisedBenefit > 0 ? DoneAdvertisedBenefit : 0;
}
int32 Unit::SpellBaseDamageBonusForVictim(SpellSchoolMask schoolMask, Unit* victim)
int32 Unit::SpellBaseDamageBonusTaken(SpellSchoolMask schoolMask)
{
uint32 creatureTypeMask = victim->GetCreatureTypeMask();
int32 TakenAdvertisedBenefit = 0;
// ..done (for creature type by mask) in taken
AuraEffectList const& mDamageDoneCreature = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_DONE_CREATURE);
for (AuraEffectList::const_iterator i = mDamageDoneCreature.begin(); i != mDamageDoneCreature.end(); ++i)
if (creatureTypeMask & uint32((*i)->GetMiscValue()))
TakenAdvertisedBenefit += (*i)->GetAmount();
// ..taken
AuraEffectList const& mDamageTaken = victim->GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_TAKEN);
AuraEffectList const& mDamageTaken = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_TAKEN);
for (AuraEffectList::const_iterator i = mDamageTaken.begin(); i != mDamageTaken.end(); ++i)
if (((*i)->GetMiscValue() & schoolMask) != 0)
TakenAdvertisedBenefit += (*i)->GetAmount();
@@ -11218,23 +11194,19 @@ uint32 Unit::SpellCriticalHealingBonus(SpellInfo const* spellProto, uint32 damag
return damage;
}
uint32 Unit::SpellHealingBonus(Unit* victim, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack)
uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack)
{
// For totems get healing bonus from owner (statue isn't totem in fact)
if (GetTypeId() == TYPEID_UNIT && ToCreature()->isTotem())
if (Unit* owner = GetOwner())
return owner->SpellHealingBonus(victim, spellProto, healamount, damagetype, stack);
return owner->SpellHealingBonusDone(victim, spellProto, healamount, damagetype, stack);
// no bonus for heal potions/bandages
if (spellProto->SpellFamilyName == SPELLFAMILY_POTION)
return healamount;
// Healing Done
// Taken/Done total percent damage auras
float DoneTotalMod = 1.0f;
float TakenTotalMod = 1.0f;
int32 DoneTotal = 0;
int32 TakenTotal = 0;
// Healing done percent
AuraEffectList const& mHealingDonePct = GetAuraEffectsByType(SPELL_AURA_MOD_HEALING_DONE_PERCENT);
@@ -11297,28 +11269,11 @@ uint32 Unit::SpellHealingBonus(Unit* victim, SpellInfo const* spellProto, uint32
}
}
// Taken/Done fixed damage bonus auras
int32 DoneAdvertisedBenefit = SpellBaseHealingBonus(spellProto->GetSchoolMask());
int32 TakenAdvertisedBenefit = SpellBaseHealingBonusForVictim(spellProto->GetSchoolMask(), victim);
bool scripted = false;
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
switch (spellProto->Effects[i].ApplyAuraName)
{
// These auras do not use healing coeff
case SPELL_AURA_PERIODIC_LEECH:
case SPELL_AURA_PERIODIC_HEALTH_FUNNEL:
scripted = true;
break;
}
if (spellProto->Effects[i].Effect == SPELL_EFFECT_HEALTH_LEECH)
scripted = true;
}
// Done fixed damage bonus auras
int32 DoneAdvertisedBenefit = SpellBaseHealingBonusDone(spellProto->GetSchoolMask());
// Check for table values
SpellBonusEntry const* bonus = !scripted ? sSpellMgr->GetSpellBonusData(spellProto->Id) : NULL;
SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id);
float coeff = 0;
float factorMod = 1.0f;
if (bonus)
@@ -11338,94 +11293,53 @@ uint32 Unit::SpellHealingBonus(Unit* victim, SpellInfo const* spellProto, uint32
(spellProto->IsRangedWeaponSpell() && spellProto->DmgClass !=SPELL_DAMAGE_CLASS_MELEE)? RANGED_ATTACK : BASE_ATTACK));
}
}
else // scripted bonus
{
// Gift of the Naaru
if (spellProto->SpellFamilyFlags[2] & 0x80000000 && spellProto->SpellIconID == 329)
{
scripted = true;
int32 apBonus = int32(std::max(GetTotalAttackPowerValue(BASE_ATTACK), GetTotalAttackPowerValue(RANGED_ATTACK)));
if (apBonus > DoneAdvertisedBenefit)
DoneTotal += int32(apBonus * 0.22f); // 22% of AP per tick
else
DoneTotal += int32(DoneAdvertisedBenefit * 0.377f); // 37.7% of BH per tick
}
// Earthliving - 0.45% of normal hot coeff
else if (spellProto->SpellFamilyName == SPELLFAMILY_SHAMAN && spellProto->SpellFamilyFlags[1] & 0x80000)
factorMod *= 0.45f;
// Already set to scripted? so not uses healing bonus coefficient
// No heal coeff for SPELL_DAMAGE_CLASS_NONE class spells by default
else if (scripted || spellProto->DmgClass == SPELL_DAMAGE_CLASS_NONE)
{
scripted = true;
coeff = 0.0f;
}
}
// Default calculation
if (DoneAdvertisedBenefit || TakenAdvertisedBenefit)
if (DoneAdvertisedBenefit)
{
if ((!bonus && !scripted) || coeff < 0)
{
// Damage Done from spell damage bonus
int32 CastingTime = !spellProto->IsChanneled() ? spellProto->CalcCastTime() : spellProto->GetDuration();
// Damage over Time spells bonus calculation
float DotFactor = 1.0f;
if (damagetype == DOT)
{
int32 DotDuration = spellProto->GetDuration();
// 200% limit
if (DotDuration > 0)
{
if (DotDuration > 30000) DotDuration = 30000;
if (!spellProto->IsChanneled()) DotFactor = DotDuration / 15000.0f;
uint32 x = 0;
for (uint8 j = 0; j < MAX_SPELL_EFFECTS; j++)
{
if (spellProto->Effects[j].Effect == SPELL_EFFECT_APPLY_AURA && (
spellProto->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE ||
spellProto->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_LEECH))
{
x = j;
break;
}
}
int32 DotTicks = 6;
if (spellProto->Effects[x].Amplitude != 0)
DotTicks = DotDuration / spellProto->Effects[x].Amplitude;
if (DotTicks)
{
DoneAdvertisedBenefit = DoneAdvertisedBenefit * int32(stack) / DotTicks;
TakenAdvertisedBenefit = TakenAdvertisedBenefit * int32(stack) / DotTicks;
}
}
}
// Distribute Damage over multiple effects, reduce by AoE
CastingTime = GetCastingTimeForBonus(spellProto, damagetype, CastingTime);
// 50% for damage and healing spells for leech spells from damage bonus and 0% from healing
for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
{
if (spellProto->Effects[j].Effect == SPELL_EFFECT_HEALTH_LEECH ||
(spellProto->Effects[j].Effect == SPELL_EFFECT_APPLY_AURA && spellProto->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_LEECH))
{
CastingTime /= 2;
break;
}
}
// As wowwiki says: C = (Cast Time / 3.5) * 1.88 (for healing spells)
coeff = (CastingTime / 3500.0f) * DotFactor * 1.88f;
}
if (!bonus || coeff < 0)
coeff = CalculateDefaultCoefficient(spellProto, damagetype) * int32(stack) * 1.88f; // As wowwiki says: C = (Cast Time / 3.5) * 1.88 (for healing spells)
factorMod *= CalculateLevelPenalty(spellProto) * stack;
// level penalty still applied on Taken bonus - is it blizzlike?
TakenTotal += int32(TakenAdvertisedBenefit * factorMod);
if (Player* modOwner = GetSpellModOwner())
{
coeff *= 100.0f;
modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff);
coeff /= 100.0f;
}
DoneTotal += int32(DoneAdvertisedBenefit * coeff * factorMod);
// Gift of the Naaru
if (spellProto->SpellFamilyFlags[2] & 0x80000000 && spellProto->SpellIconID == 329)
{
int32 apBonus = int32(std::max(GetTotalAttackPowerValue(BASE_ATTACK), GetTotalAttackPowerValue(RANGED_ATTACK)));
if (apBonus > DoneAdvertisedBenefit)
DoneTotal += int32(apBonus * 0.22f); // 22% of AP per tick
else
DoneTotal += int32(DoneAdvertisedBenefit * 0.377f); // 37.7% of BH per tick
}
else
{
// Earthliving - 0.45% of normal hot coeff
if (spellProto->SpellFamilyName == SPELLFAMILY_SHAMAN && spellProto->SpellFamilyFlags[1] & 0x80000)
factorMod *= 0.45f;
DoneTotal += int32(DoneAdvertisedBenefit * coeff * factorMod);
}
}
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
switch (spellProto->Effects[i].ApplyAuraName)
{
// Bonus healing does not apply to these spells
case SPELL_AURA_PERIODIC_LEECH:
case SPELL_AURA_PERIODIC_HEALTH_FUNNEL:
DoneTotal = 0;
break;
}
if (spellProto->Effects[i].Effect == SPELL_EFFECT_HEALTH_LEECH)
DoneTotal = 0;
}
// use float as more appropriate for negative values and percent applying
@@ -11434,53 +11348,106 @@ uint32 Unit::SpellHealingBonus(Unit* victim, SpellInfo const* spellProto, uint32
if (Player* modOwner = GetSpellModOwner())
modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, heal);
return uint32(std::max(heal, 0.0f));
}
uint32 Unit::SpellHealingBonusTaken(SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack)
{
float TakenTotalMod = 1.0f;
// Healing taken percent
float minval = (float)GetMaxNegativeAuraModifier(SPELL_AURA_MOD_HEALING_PCT);
if (minval)
AddPctF(TakenTotalMod, minval);
float maxval = (float)GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HEALING_PCT);
if (maxval)
AddPctF(TakenTotalMod, maxval);
// Tenacity increase healing % taken
if (AuraEffect const* Tenacity = GetAuraEffect(58549, 0))
AddPctN(TakenTotalMod, Tenacity->GetAmount());
// Healing Done
int32 TakenTotal = 0;
// Taken fixed damage bonus auras
int32 TakenAdvertisedBenefit = SpellBaseHealingBonusTaken(spellProto->GetSchoolMask());
// Nourish cast
if (spellProto->SpellFamilyName == SPELLFAMILY_DRUID && spellProto->SpellFamilyFlags[1] & 0x2000000)
{
// Rejuvenation, Regrowth, Lifebloom, or Wild Growth
if (victim->GetAuraEffect(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_DRUID, 0x50, 0x4000010, 0))
if (GetAuraEffect(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_DRUID, 0x50, 0x4000010, 0))
// increase healing by 20%
TakenTotalMod *= 1.2f;
}
// Taken mods
// Tenacity increase healing % taken
if (AuraEffect const* Tenacity = victim->GetAuraEffect(58549, 0))
AddPctN(TakenTotalMod, Tenacity->GetAmount());
// Healing taken percent
float minval = (float)victim->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_HEALING_PCT);
if (minval)
AddPctF(TakenTotalMod, minval);
float maxval = (float)victim->GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HEALING_PCT);
if (maxval)
AddPctF(TakenTotalMod, maxval);
if (damagetype == DOT)
{
// Healing over time taken percent
float minval_hot = (float)victim->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_HOT_PCT);
float minval_hot = (float)GetMaxNegativeAuraModifier(SPELL_AURA_MOD_HOT_PCT);
if (minval_hot)
AddPctF(TakenTotalMod, minval_hot);
float maxval_hot = (float)victim->GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HOT_PCT);
float maxval_hot = (float)GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HOT_PCT);
if (maxval_hot)
AddPctF(TakenTotalMod, maxval_hot);
}
AuraEffectList const& mHealingGet= victim->GetAuraEffectsByType(SPELL_AURA_MOD_HEALING_RECEIVED);
// Check for table values
SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id);
float coeff = 0;
float factorMod = 1.0f;
if (bonus)
coeff = (damagetype == DOT) ? bonus->dot_damage : bonus->direct_damage;
// Default calculation
if (TakenAdvertisedBenefit)
{
if (!bonus || coeff < 0)
coeff = CalculateDefaultCoefficient(spellProto, damagetype) * int32(stack) * 1.88f; // As wowwiki says: C = (Cast Time / 3.5) * 1.88 (for healing spells)
factorMod *= CalculateLevelPenalty(spellProto) * int32(stack);
if (Player* modOwner = GetSpellModOwner())
{
coeff *= 100.0f;
modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff);
coeff /= 100.0f;
}
// Earthliving - 0.45% of normal hot coeff
if (spellProto->SpellFamilyName == SPELLFAMILY_SHAMAN && spellProto->SpellFamilyFlags[1] & 0x80000)
factorMod *= 0.45f;
TakenTotal += int32(TakenAdvertisedBenefit * coeff * factorMod);
}
AuraEffectList const& mHealingGet= GetAuraEffectsByType(SPELL_AURA_MOD_HEALING_RECEIVED);
for (AuraEffectList::const_iterator i = mHealingGet.begin(); i != mHealingGet.end(); ++i)
if (GetGUID() == (*i)->GetCasterGUID() && (*i)->IsAffectedOnSpell(spellProto))
AddPctN(TakenTotalMod, (*i)->GetAmount());
heal = (int32(heal) + TakenTotal) * TakenTotalMod;
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
switch (spellProto->Effects[i].ApplyAuraName)
{
// Bonus healing does not apply to these spells
case SPELL_AURA_PERIODIC_LEECH:
case SPELL_AURA_PERIODIC_HEALTH_FUNNEL:
TakenTotal = 0;
break;
}
if (spellProto->Effects[i].Effect == SPELL_EFFECT_HEALTH_LEECH)
TakenTotal = 0;
}
float heal = (int32(healamount) + TakenTotal) * TakenTotalMod;
return uint32(std::max(heal, 0.0f));
}
int32 Unit::SpellBaseHealingBonus(SpellSchoolMask schoolMask)
int32 Unit::SpellBaseHealingBonusDone(SpellSchoolMask schoolMask)
{
int32 AdvertisedBenefit = 0;
@@ -11513,13 +11480,15 @@ int32 Unit::SpellBaseHealingBonus(SpellSchoolMask schoolMask)
return AdvertisedBenefit;
}
int32 Unit::SpellBaseHealingBonusForVictim(SpellSchoolMask schoolMask, Unit* victim)
int32 Unit::SpellBaseHealingBonusTaken(SpellSchoolMask schoolMask)
{
int32 AdvertisedBenefit = 0;
AuraEffectList const& mDamageTaken = victim->GetAuraEffectsByType(SPELL_AURA_MOD_HEALING);
AuraEffectList const& mDamageTaken = GetAuraEffectsByType(SPELL_AURA_MOD_HEALING);
for (AuraEffectList::const_iterator i = mDamageTaken.begin(); i != mDamageTaken.end(); ++i)
if (((*i)->GetMiscValue() & schoolMask) != 0)
AdvertisedBenefit += (*i)->GetAmount();
return AdvertisedBenefit;
}
@@ -11662,21 +11631,20 @@ bool Unit::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) cons
return false;
}
void Unit::MeleeDamageBonus(Unit* victim, uint32 *pdamage, WeaponAttackType attType, SpellInfo const* spellProto)
uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType attType, SpellInfo const* spellProto)
{
if (!victim)
return;
return 0;
if (*pdamage == 0)
return;
if (pdamage == 0)
return 0;
uint32 creatureTypeMask = victim->GetCreatureTypeMask();
// Taken/Done fixed damage bonus auras
// Done fixed damage bonus auras
int32 DoneFlatBenefit = 0;
int32 TakenFlatBenefit = 0;
// ..done (for creature type by mask) in taken
// ..done
AuraEffectList const& mDamageDoneCreature = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_DONE_CREATURE);
for (AuraEffectList::const_iterator i = mDamageDoneCreature.begin(); i != mDamageDoneCreature.end(); ++i)
if (creatureTypeMask & uint32((*i)->GetMiscValue()))
@@ -11722,20 +11690,8 @@ void Unit::MeleeDamageBonus(Unit* victim, uint32 *pdamage, WeaponAttackType attT
DoneFlatBenefit += int32(APbonus/14.0f * GetAPMultiplier(attType, normalized));
}
// ..taken
AuraEffectList const& mDamageTaken = victim->GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_TAKEN);
for (AuraEffectList::const_iterator i = mDamageTaken.begin(); i != mDamageTaken.end(); ++i)
if ((*i)->GetMiscValue() & GetMeleeDamageSchoolMask())
TakenFlatBenefit += (*i)->GetAmount();
if (attType != RANGED_ATTACK)
TakenFlatBenefit += victim->GetTotalAuraModifier(SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN);
else
TakenFlatBenefit += victim->GetTotalAuraModifier(SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN);
// Done/Taken total percent damage auras
// Done total percent damage auras
float DoneTotalMod = 1.0f;
float TakenTotalMod = 1.0f;
// ..done
AuraEffectList const& mModDamagePercentDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
@@ -11841,11 +11797,43 @@ void Unit::MeleeDamageBonus(Unit* victim, uint32 *pdamage, WeaponAttackType attT
break;
}
float tmpDamage = float(int32(pdamage) + DoneFlatBenefit) * DoneTotalMod;
// apply spellmod to Done damage
if (spellProto)
if (Player* modOwner = GetSpellModOwner())
modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_DAMAGE, tmpDamage);
// bonus result can be negative
return uint32(std::max(tmpDamage, 0.0f));
}
uint32 Unit::MeleeDamageBonusTaken(uint32 pdamage, WeaponAttackType attType, SpellInfo const *spellProto)
{
if (pdamage == 0)
return 0;
int32 TakenFlatBenefit = 0;
// ..taken
TakenTotalMod *= victim->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, GetMeleeDamageSchoolMask());
AuraEffectList const& mDamageTaken = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_TAKEN);
for (AuraEffectList::const_iterator i = mDamageTaken.begin(); i != mDamageTaken.end(); ++i)
if ((*i)->GetMiscValue() & GetMeleeDamageSchoolMask())
TakenFlatBenefit += (*i)->GetAmount();
if (attType != RANGED_ATTACK)
TakenFlatBenefit += GetTotalAuraModifier(SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN);
else
TakenFlatBenefit += GetTotalAuraModifier(SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN);
// Taken total percent damage auras
float TakenTotalMod = 1.0f;
// ..taken
TakenTotalMod *= GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, GetMeleeDamageSchoolMask());
// From caster spells
AuraEffectList const& mOwnerTaken = victim->GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER);
AuraEffectList const& mOwnerTaken = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER);
for (AuraEffectList::const_iterator i = mOwnerTaken.begin(); i != mOwnerTaken.end(); ++i)
if ((*i)->GetCasterGUID() == GetGUID() && (*i)->IsAffectedOnSpell(spellProto))
AddPctN(TakenTotalMod, (*i)->GetAmount());
@@ -11862,7 +11850,7 @@ void Unit::MeleeDamageBonus(Unit* victim, uint32 *pdamage, WeaponAttackType attT
if (mechanicMask)
{
AuraEffectList const& mDamageDoneMechanic = victim->GetAuraEffectsByType(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT);
AuraEffectList const& mDamageDoneMechanic = GetAuraEffectsByType(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT);
for (AuraEffectList::const_iterator i = mDamageDoneMechanic.begin(); i != mDamageDoneMechanic.end(); ++i)
if (mechanicMask & uint32(1<<((*i)->GetMiscValue())))
AddPctN(TakenTotalMod, (*i)->GetAmount());
@@ -11870,7 +11858,7 @@ void Unit::MeleeDamageBonus(Unit* victim, uint32 *pdamage, WeaponAttackType attT
}
// .. taken pct: dummy auras
AuraEffectList const& mDummyAuras = victim->GetAuraEffectsByType(SPELL_AURA_DUMMY);
AuraEffectList const& mDummyAuras = GetAuraEffectsByType(SPELL_AURA_DUMMY);
for (AuraEffectList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i)
{
switch ((*i)->GetSpellInfo()->SpellIconID)
@@ -11879,9 +11867,9 @@ void Unit::MeleeDamageBonus(Unit* victim, uint32 *pdamage, WeaponAttackType attT
case 2109:
if ((*i)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL)
{
if (victim->GetTypeId() != TYPEID_PLAYER)
if (GetTypeId() != TYPEID_PLAYER)
continue;
float mod = victim->ToPlayer()->GetRatingBonusValue(CR_CRIT_TAKEN_MELEE) * (-8.0f);
float mod = ToPlayer()->GetRatingBonusValue(CR_CRIT_TAKEN_MELEE) * (-8.0f);
AddPctF(TakenTotalMod, std::max(mod, float((*i)->GetAmount())));
}
break;
@@ -11889,38 +11877,31 @@ void Unit::MeleeDamageBonus(Unit* victim, uint32 *pdamage, WeaponAttackType attT
}
// .. taken pct: class scripts
/*AuraEffectList const& mclassScritAuras = GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
for (AuraEffectList::const_iterator i = mclassScritAuras.begin(); i != mclassScritAuras.end(); ++i)
{
switch ((*i)->GetMiscValue())
{
}
}*/
//*AuraEffectList const& mclassScritAuras = GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
//for (AuraEffectList::const_iterator i = mclassScritAuras.begin(); i != mclassScritAuras.end(); ++i)
//{
// switch ((*i)->GetMiscValue())
// {
// }
//}*/
if (attType != RANGED_ATTACK)
{
AuraEffectList const& mModMeleeDamageTakenPercent = victim->GetAuraEffectsByType(SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT);
AuraEffectList const& mModMeleeDamageTakenPercent = GetAuraEffectsByType(SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT);
for (AuraEffectList::const_iterator i = mModMeleeDamageTakenPercent.begin(); i != mModMeleeDamageTakenPercent.end(); ++i)
AddPctN(TakenTotalMod, (*i)->GetAmount());
}
else
{
AuraEffectList const& mModRangedDamageTakenPercent = victim->GetAuraEffectsByType(SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT);
AuraEffectList const& mModRangedDamageTakenPercent = GetAuraEffectsByType(SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT);
for (AuraEffectList::const_iterator i = mModRangedDamageTakenPercent.begin(); i != mModRangedDamageTakenPercent.end(); ++i)
AddPctN(TakenTotalMod, (*i)->GetAmount());
}
float tmpDamage = float(int32(*pdamage) + DoneFlatBenefit) * DoneTotalMod;
// apply spellmod to Done damage
if (spellProto)
if (Player* modOwner = GetSpellModOwner())
modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_DAMAGE, tmpDamage);
tmpDamage = (tmpDamage + TakenFlatBenefit) * TakenTotalMod;
float tmpDamage = (float(pdamage) + TakenFlatBenefit) * TakenTotalMod;
// bonus result can be negative
*pdamage = uint32(std::max(tmpDamage, 0.0f));
return uint32(std::max(tmpDamage, 0.0f));
}
void Unit::ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply)
@@ -14501,7 +14482,8 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "ProcDamageAndSpell: doing %u damage from spell id %u (triggered by %s aura of spell %u)", triggeredByAura->GetAmount(), spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
SpellNonMeleeDamage damageInfo(this, target, spellInfo->Id, spellInfo->SchoolMask);
uint32 newDamage = SpellDamageBonus(target, spellInfo, triggeredByAura->GetAmount(), SPELL_DIRECT_DAMAGE);
uint32 newDamage = SpellDamageBonusDone(target, spellInfo, triggeredByAura->GetAmount(), SPELL_DIRECT_DAMAGE);
newDamage = target->SpellDamageBonusTaken(spellInfo, newDamage, SPELL_DIRECT_DAMAGE);
CalculateSpellDamageTaken(&damageInfo, newDamage, spellInfo);
DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
SendSpellNonMeleeDamageLog(&damageInfo);
@@ -15028,7 +15010,7 @@ void Unit::ApplyCastTimePercentMod(float val, bool apply)
ApplyPercentModFloatValue(UNIT_MOD_CAST_SPEED, -val, apply);
}
uint32 Unit::GetCastingTimeForBonus(SpellInfo const* spellProto, DamageEffectType damagetype, uint32 CastingTime)
uint32 Unit::GetCastingTimeForBonus(SpellInfo const* spellProto, DamageEffectType damagetype, uint32 CastingTime) const
{
// Not apply this to creature casted spells with casttime == 0
if (CastingTime == 0 && GetTypeId() == TYPEID_UNIT && !ToCreature()->isPet())
@@ -15101,20 +15083,21 @@ uint32 Unit::GetCastingTimeForBonus(SpellInfo const* spellProto, DamageEffectTyp
if (AreaEffect)
CastingTime /= 2;
// -5% of total per any additional effect
for (uint8 i = 0; i < effects; ++i)
// 50% for damage and healing spells for leech spells from damage bonus and 0% from healing
for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
{
if (CastingTime > 175)
if (spellProto->Effects[j].Effect == SPELL_EFFECT_HEALTH_LEECH ||
(spellProto->Effects[j].Effect == SPELL_EFFECT_APPLY_AURA && spellProto->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_LEECH))
{
CastingTime -= 175;
}
else
{
CastingTime = 0;
CastingTime /= 2;
break;
}
}
// -5% of total per any additional effect
for (uint8 i = 0; i < effects; ++i)
CastingTime *= 0.95f;
return CastingTime;
}
@@ -15145,6 +15128,29 @@ void Unit::UpdateAuraForGroup(uint8 slot)
}
}
float Unit::CalculateDefaultCoefficient(SpellInfo const *spellInfo, DamageEffectType damagetype) const
{
// Damage over Time spells bonus calculation
float DotFactor = 1.0f;
if (damagetype == DOT)
{
int32 DotDuration = spellInfo->GetDuration();
if (!spellInfo->IsChanneled() && DotDuration > 0)
DotFactor = DotDuration / 15000.0f;
if (uint32 DotTicks = spellInfo->GetMaxTicks())
DotFactor /= DotTicks;
}
int32 CastingTime = spellInfo->IsChanneled() ? spellInfo->GetDuration() : spellInfo->CalcCastTime();
// Distribute Damage over multiple effects, reduce by AoE
CastingTime = GetCastingTimeForBonus(spellInfo, damagetype, CastingTime);
// As wowwiki says: C = (Cast Time / 3.5)
return (CastingTime / 3500.0f) * DotFactor;
}
float Unit::GetAPMultiplier(WeaponAttackType attType, bool normalized)
{
if (!normalized || GetTypeId() != TYPEID_PLAYER)
+16 -8
View File
@@ -2034,12 +2034,20 @@ class Unit : public WorldObject
void UnsummonAllTotems();
Unit* GetMagicHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo);
Unit* GetMeleeHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo = NULL);
int32 SpellBaseDamageBonus(SpellSchoolMask schoolMask);
int32 SpellBaseHealingBonus(SpellSchoolMask schoolMask);
int32 SpellBaseDamageBonusForVictim(SpellSchoolMask schoolMask, Unit* victim);
int32 SpellBaseHealingBonusForVictim(SpellSchoolMask schoolMask, Unit* victim);
uint32 SpellDamageBonus(Unit* victim, SpellInfo const* spellProto, uint32 damage, DamageEffectType damagetype, uint32 stack = 1);
uint32 SpellHealingBonus(Unit* victim, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack = 1);
int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask);
int32 SpellBaseDamageBonusTaken(SpellSchoolMask schoolMask);
uint32 SpellDamageBonusDone(Unit* victim, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack = 1);
uint32 SpellDamageBonusTaken(SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack = 1);
int32 SpellBaseHealingBonusDone(SpellSchoolMask schoolMask);
int32 SpellBaseHealingBonusTaken(SpellSchoolMask schoolMask);
uint32 SpellHealingBonusDone(Unit* victim, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack = 1);
uint32 SpellHealingBonusTaken(SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack = 1);
uint32 MeleeDamageBonusDone(Unit *pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const *spellProto = NULL);
uint32 MeleeDamageBonusTaken(uint32 pdamage,WeaponAttackType attType, SpellInfo const *spellProto = NULL);
bool isSpellBlocked(Unit* victim, SpellInfo const* spellProto, WeaponAttackType attackType = BASE_ATTACK);
bool isBlockCritical();
bool isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType = BASE_ATTACK) const;
@@ -2051,8 +2059,8 @@ class Unit : public WorldObject
void SetContestedPvP(Player* attackedPlayer = NULL);
void MeleeDamageBonus(Unit* victim, uint32 *damage, WeaponAttackType attType, SpellInfo const* spellProto = NULL);
uint32 GetCastingTimeForBonus(SpellInfo const* spellProto, DamageEffectType damagetype, uint32 CastingTime);
uint32 GetCastingTimeForBonus(SpellInfo const* spellProto, DamageEffectType damagetype, uint32 CastingTime) const;
float CalculateDefaultCoefficient(SpellInfo const *spellInfo, DamageEffectType damagetype) const;
uint32 GetRemainingPeriodicAmount(uint64 caster, uint32 spellId, AuraType auraType, uint8 effectIndex = 0) const;
@@ -490,7 +490,7 @@ int32 AuraEffect::CalculateAmount(Unit* caster)
if (GetSpellInfo()->SpellFamilyFlags[1] & 0x1 && GetSpellInfo()->SpellFamilyFlags[2] & 0x8)
{
// +80.68% from sp bonus
DoneActualBenefit += caster->SpellBaseDamageBonus(m_spellInfo->GetSchoolMask()) * 0.8068f;
DoneActualBenefit += caster->SpellBaseDamageBonusDone(m_spellInfo->GetSchoolMask()) * 0.8068f;
// Glyph of Ice Barrier: its weird having a SPELLMOD_ALL_EFFECTS here but its blizzards doing :)
// Glyph of Ice Barrier is only applied at the spell damage bonus because it was already applied to the base value in CalculateSpellDamage
DoneActualBenefit = caster->ApplyEffectModifiers(GetSpellInfo(), m_effIndex, DoneActualBenefit);
@@ -499,13 +499,13 @@ int32 AuraEffect::CalculateAmount(Unit* caster)
else if (GetSpellInfo()->SpellFamilyFlags[0] & 0x8 && GetSpellInfo()->SpellFamilyFlags[2] & 0x8)
{
// +80.68% from sp bonus
DoneActualBenefit += caster->SpellBaseDamageBonus(m_spellInfo->GetSchoolMask()) * 0.8068f;
DoneActualBenefit += caster->SpellBaseDamageBonusDone(m_spellInfo->GetSchoolMask()) * 0.8068f;
}
// Frost Ward
else if (GetSpellInfo()->SpellFamilyFlags[0] & 0x100 && GetSpellInfo()->SpellFamilyFlags[2] & 0x8)
{
// +80.68% from sp bonus
DoneActualBenefit += caster->SpellBaseDamageBonus(m_spellInfo->GetSchoolMask()) * 0.8068f;
DoneActualBenefit += caster->SpellBaseDamageBonusDone(m_spellInfo->GetSchoolMask()) * 0.8068f;
}
break;
case SPELLFAMILY_WARLOCK:
@@ -513,7 +513,7 @@ int32 AuraEffect::CalculateAmount(Unit* caster)
if (m_spellInfo->SpellFamilyFlags[2] & 0x40)
{
// +80.68% from sp bonus
DoneActualBenefit += caster->SpellBaseDamageBonus(m_spellInfo->GetSchoolMask()) * 0.8068f;
DoneActualBenefit += caster->SpellBaseDamageBonusDone(m_spellInfo->GetSchoolMask()) * 0.8068f;
}
break;
case SPELLFAMILY_PRIEST:
@@ -527,7 +527,7 @@ int32 AuraEffect::CalculateAmount(Unit* caster)
if (AuraEffect const* pAurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, 2899, 1))
bonus += CalculatePctN(1.0f, pAurEff->GetAmount());
DoneActualBenefit += caster->SpellBaseHealingBonus(m_spellInfo->GetSchoolMask()) * bonus;
DoneActualBenefit += caster->SpellBaseHealingBonusDone(m_spellInfo->GetSchoolMask()) * bonus;
// Improved PW: Shield: its weird having a SPELLMOD_ALL_EFFECTS here but its blizzards doing :)
// Improved PW: Shield is only applied at the spell healing bonus because it was already applied to the base value in CalculateSpellDamage
DoneActualBenefit = caster->ApplyEffectModifiers(GetSpellInfo(), m_effIndex, DoneActualBenefit);
@@ -555,7 +555,7 @@ int32 AuraEffect::CalculateAmount(Unit* caster)
//+75.00% from sp bonus
float bonus = 0.75f;
DoneActualBenefit += caster->SpellBaseHealingBonus(m_spellInfo->GetSchoolMask()) * bonus;
DoneActualBenefit += caster->SpellBaseHealingBonusDone(m_spellInfo->GetSchoolMask()) * bonus;
// Divine Guardian is only applied at the spell healing bonus because it was already applied to the base value in CalculateSpellDamage
DoneActualBenefit = caster->ApplyEffectModifiers(GetSpellInfo(), m_effIndex, DoneActualBenefit);
DoneActualBenefit *= caster->CalculateLevelPenalty(GetSpellInfo());
@@ -584,7 +584,7 @@ int32 AuraEffect::CalculateAmount(Unit* caster)
if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_MAGE && GetSpellInfo()->SpellFamilyFlags[0] & 0x8000 && m_spellInfo->SpellFamilyFlags[2] & 0x8)
{
// +80.53% from +spd bonus
DoneActualBenefit += caster->SpellBaseDamageBonus(m_spellInfo->GetSchoolMask()) * 0.8053f;;
DoneActualBenefit += caster->SpellBaseDamageBonusDone(m_spellInfo->GetSchoolMask()) * 0.8053f;;
}
break;
case SPELL_AURA_DUMMY:
@@ -592,7 +592,10 @@ int32 AuraEffect::CalculateAmount(Unit* caster)
break;
// Earth Shield
if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_SHAMAN && m_spellInfo->SpellFamilyFlags[1] & 0x400)
amount = caster->SpellHealingBonus(GetBase()->GetUnitOwner(), GetSpellInfo(), amount, SPELL_DIRECT_DAMAGE);
{
amount = caster->SpellHealingBonusDone(GetBase()->GetUnitOwner(), GetSpellInfo(), amount, SPELL_DIRECT_DAMAGE);
amount = GetBase()->GetUnitOwner()->SpellHealingBonusTaken(GetSpellInfo(), amount, SPELL_DIRECT_DAMAGE);
}
break;
case SPELL_AURA_PERIODIC_DAMAGE:
if (!caster)
@@ -933,6 +936,7 @@ void AuraEffect::ChangeAmount(int32 newAmount, bool mark, bool onStackOrReapply)
handleMask |= AURA_EFFECT_HANDLE_CHANGE_AMOUNT;
if (onStackOrReapply)
handleMask |= AURA_EFFECT_HANDLE_REAPPLY;
if (!handleMask)
return;
@@ -1259,7 +1263,7 @@ void AuraEffect::SendTickImmune(Unit* target, Unit* caster) const
caster->SendSpellDamageImmune(target, m_spellInfo->Id);
}
void AuraEffect::PeriodicTick(AuraApplication * aurApp, Unit* caster) const
void AuraEffect::PeriodicTick(AuraApplication * aurApp, Unit* caster)
{
bool prevented = GetBase()->CallScriptEffectPeriodicHandlers(this, aurApp);
if (prevented)
@@ -4962,7 +4966,10 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
int32 stack = GetBase()->GetStackAmount();
int32 heal = m_amount;
if (caster)
heal = caster->SpellHealingBonus(target, GetSpellInfo(), heal, HEAL, stack);
{
heal = caster->SpellHealingBonusDone(target, GetSpellInfo(), heal, HEAL, stack);
heal = target->SpellHealingBonusTaken(GetSpellInfo(), heal, HEAL, stack);
}
target->CastCustomSpell(target, 33778, &heal, &stack, NULL, true, NULL, this, GetCasterGUID());
// restore mana
@@ -6139,7 +6146,7 @@ void AuraEffect::HandlePeriodicTriggerSpellWithValueAuraTick(Unit* target, Unit*
sLog->outDebug(LOG_FILTER_SPELLS_AURAS,"AuraEffect::HandlePeriodicTriggerSpellWithValueAuraTick: Spell %u has non-existent spell %u in EffectTriggered[%d] and is therefor not triggered.", GetId(), triggerSpellId, GetEffIndex());
}
void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster)
{
if (!caster || !target->isAlive())
return;
@@ -6190,7 +6197,8 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
if (GetAuraType() == SPELL_AURA_PERIODIC_DAMAGE)
{
damage = caster->SpellDamageBonus(target, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount());
damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount());
damage = target->SpellDamageBonusTaken(GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount());
// Calculate armor mitigation
if (Unit::IsDamageReducedByArmor(GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), GetEffIndex()))
@@ -6280,7 +6288,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
caster->DealDamage(target, damage, &cleanDamage, DOT, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), true);
}
void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) const
void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster)
{
if (!caster || !target->isAlive())
return;
@@ -6300,7 +6308,9 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
CleanDamage cleanDamage = CleanDamage(0, 0, BASE_ATTACK, MELEE_HIT_NORMAL);
uint32 damage = std::max(GetAmount(), 0);
damage = caster->SpellDamageBonus(target, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount());
damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount());
damage = target->SpellDamageBonusTaken(GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount());
bool crit = IsPeriodicTickCrit(target, caster);
if (crit)
@@ -6338,12 +6348,12 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
if (caster->isAlive())
caster->ProcDamageAndSpell(target, procAttacker, procVictim, procEx, damage, BASE_ATTACK, GetSpellInfo());
int32 new_damage = caster->DealDamage(target, damage, &cleanDamage, DOT, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), false);
if (caster->isAlive())
{
float gainMultiplier = GetSpellInfo()->Effects[GetEffIndex()].CalcValueMultiplier(caster);
uint32 heal = uint32(caster->SpellHealingBonus(caster, GetSpellInfo(), uint32(new_damage * gainMultiplier), DOT, GetBase()->GetStackAmount()));
uint32 heal = uint32(caster->SpellHealingBonusDone(caster, GetSpellInfo(), uint32(new_damage * gainMultiplier), DOT, GetBase()->GetStackAmount()));
heal = uint32(caster->SpellHealingBonusTaken(GetSpellInfo(), heal, DOT, GetBase()->GetStackAmount()));
int32 gain = caster->HealBySpell(caster, GetSpellInfo(), heal);
caster->getHostileRefManager().threatAssist(caster, gain * 0.5f, GetSpellInfo());
@@ -6378,7 +6388,7 @@ void AuraEffect::HandlePeriodicHealthFunnelAuraTick(Unit* target, Unit* caster)
caster->HealBySpell(target, GetSpellInfo(), damage);
}
void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster)
{
if (!caster || !target->isAlive())
return;
@@ -6447,7 +6457,8 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
damage += addition;
}
damage = caster->SpellHealingBonus(target, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount());
damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount());
damage = target->SpellHealingBonusTaken(GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount());
}
bool crit = IsPeriodicTickCrit(target, caster);
@@ -6737,7 +6748,8 @@ void AuraEffect::HandleProcTriggerDamageAuraProc(AuraApplication* aurApp, ProcEv
Unit* target = aurApp->GetTarget();
Unit* triggerTarget = eventInfo.GetProcTarget();
SpellNonMeleeDamage damageInfo(target, triggerTarget, GetId(), GetSpellInfo()->SchoolMask);
uint32 damage = target->SpellDamageBonus(triggerTarget, GetSpellInfo(), GetAmount(), SPELL_DIRECT_DAMAGE);
uint32 damage = target->SpellDamageBonusDone(triggerTarget, GetSpellInfo(), GetAmount(), SPELL_DIRECT_DAMAGE);
damage = triggerTarget->SpellDamageBonusTaken(GetSpellInfo(), damage, SPELL_DIRECT_DAMAGE);
target->CalculateSpellDamageTaken(&damageInfo, damage, GetSpellInfo());
target->DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
target->SendSpellNonMeleeDamageLog(&damageInfo);
@@ -83,7 +83,7 @@ class AuraEffect
bool HasSpellClassMask() const { return m_spellInfo->Effects[m_effIndex].SpellClassMask; }
void SendTickImmune(Unit* target, Unit* caster) const;
void PeriodicTick(AuraApplication * aurApp, Unit* caster) const;
void PeriodicTick(AuraApplication * aurApp, Unit* caster);
void HandleProc(AuraApplication* aurApp, ProcEventInfo& eventInfo);
@@ -285,10 +285,10 @@ class AuraEffect
void HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const;
void HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster) const;
void HandlePeriodicTriggerSpellWithValueAuraTick(Unit* target, Unit* caster) const;
void HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const;
void HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) const;
void HandlePeriodicDamageAurasTick(Unit* target, Unit* caster);
void HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster);
void HandlePeriodicHealthFunnelAuraTick(Unit* target, Unit* caster) const;
void HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const;
void HandlePeriodicHealAurasTick(Unit* target, Unit* caster);
void HandlePeriodicManaLeechAuraTick(Unit* target, Unit* caster) const;
void HandleObsModPowerAuraTick(Unit* target, Unit* caster) const;
void HandlePeriodicEnergizeAuraTick(Unit* target, Unit* caster) const;
+8 -2
View File
@@ -1212,8 +1212,11 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
// Improved Devouring Plague
if (AuraEffect const* aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, 3790, 1))
{
int32 basepoints0 = aurEff->GetAmount() * GetEffect(0)->GetTotalTicks() * caster->SpellDamageBonus(target, GetSpellInfo(), GetEffect(0)->GetAmount(), DOT) / 100;
uint32 damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), GetEffect(0)->GetAmount(), DOT);
damage = target->SpellDamageBonusTaken(GetSpellInfo(), damage, DOT);
int32 basepoints0 = aurEff->GetAmount() * GetEffect(0)->GetTotalTicks() * int32(damage) / 100;
int32 heal = int32(CalculatePctN(basepoints0, 15));
caster->CastCustomSpell(target, 63675, &basepoints0, NULL, NULL, true, NULL, GetEffect(0));
caster->CastCustomSpell(caster, 75999, &heal, NULL, NULL, true, NULL, GetEffect(0));
}
@@ -1224,7 +1227,10 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
// Empowered Renew
if (AuraEffect const* aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, 3021, 1))
{
int32 basepoints0 = aurEff->GetAmount() * GetEffect(0)->GetTotalTicks() * caster->SpellHealingBonus(target, GetSpellInfo(), GetEffect(0)->GetAmount(), HEAL) / 100;
uint32 damage = caster->SpellHealingBonusDone(target, GetSpellInfo(), GetEffect(0)->GetAmount(), HEAL);
damage = target->SpellHealingBonusTaken(GetSpellInfo(), damage, HEAL);
int32 basepoints0 = aurEff->GetAmount() * GetEffect(0)->GetTotalTicks() * int32(damage) / 100;
caster->CastCustomSpell(target, 63544, &basepoints0, NULL, NULL, true, NULL, GetEffect(0));
}
}
+40 -16
View File
@@ -467,7 +467,8 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
if (aura)
{
uint32 pdamage = uint32(std::max(aura->GetAmount(), 0));
pdamage = m_caster->SpellDamageBonus(unitTarget, aura->GetSpellInfo(), pdamage, DOT, aura->GetBase()->GetStackAmount());
pdamage = m_caster->SpellDamageBonusDone(unitTarget, aura->GetSpellInfo(), pdamage, DOT, aura->GetBase()->GetStackAmount());
pdamage = unitTarget->SpellDamageBonusTaken(aura->GetSpellInfo(), pdamage, DOT, aura->GetBase()->GetStackAmount());
uint32 pct_dir = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, (effIndex + 1));
uint8 baseTotalTicks = uint8(m_caster->CalcSpellDuration(aura->GetSpellInfo()) / aura->GetSpellInfo()->Effects[EFFECT_0].Amplitude);
damage += int32(CalculatePctU(pdamage * baseTotalTicks, pct_dir));
@@ -505,7 +506,8 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
// Shadow Word: Death - deals damage equal to damage done to caster
if (m_spellInfo->SpellFamilyFlags[1] & 0x2)
{
int32 back_damage = m_caster->SpellDamageBonus(unitTarget, m_spellInfo, (uint32)damage, SPELL_DIRECT_DAMAGE);
int32 back_damage = m_caster->SpellDamageBonusDone(unitTarget, m_spellInfo, (uint32)damage, SPELL_DIRECT_DAMAGE);
back_damage = unitTarget->SpellDamageBonusTaken(m_spellInfo, (uint32)back_damage, SPELL_DIRECT_DAMAGE);
// Pain and Suffering reduces damage
if (AuraEffect* aurEff = m_caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, 2874, 0))
AddPctN(back_damage, -aurEff->GetAmount());
@@ -712,7 +714,10 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
}
if (m_originalCaster && damage > 0 && apply_direct_bonus)
damage = m_originalCaster->SpellDamageBonus(unitTarget, m_spellInfo, (uint32)damage, SPELL_DIRECT_DAMAGE);
{
damage = m_originalCaster->SpellDamageBonusDone(unitTarget, m_spellInfo, (uint32)damage, SPELL_DIRECT_DAMAGE);
damage = unitTarget->SpellDamageBonusTaken(m_spellInfo, (uint32)damage, SPELL_DIRECT_DAMAGE);
}
m_damage += damage;
}
@@ -1391,7 +1396,8 @@ void Spell::EffectPowerDrain(SpellEffIndex effIndex)
return;
// add spell damage bonus
damage = m_caster->SpellDamageBonus(unitTarget, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE);
damage = m_caster->SpellDamageBonusDone(unitTarget, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE);
damage = unitTarget->SpellDamageBonusTaken(m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE);
// resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
int32 power = damage;
@@ -1554,7 +1560,10 @@ void Spell::EffectHeal(SpellEffIndex /*effIndex*/)
int32 tickheal = targetAura->GetAmount();
if (Unit* auraCaster = targetAura->GetCaster())
tickheal = auraCaster->SpellHealingBonus(unitTarget, targetAura->GetSpellInfo(), tickheal, DOT);
{
tickheal = auraCaster->SpellHealingBonusDone(unitTarget, targetAura->GetSpellInfo(), tickheal, DOT);
tickheal = unitTarget->SpellHealingBonusTaken(targetAura->GetSpellInfo(), tickheal, DOT);
}
//int32 tickheal = targetAura->GetSpellInfo()->EffectBasePoints[idx] + 1;
//It is said that talent bonus should not be included
@@ -1578,7 +1587,8 @@ void Spell::EffectHeal(SpellEffIndex /*effIndex*/)
// Glyph of Nourish
else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DRUID && m_spellInfo->SpellFamilyFlags[1] & 0x2000000)
{
addhealth = caster->SpellHealingBonus(unitTarget, m_spellInfo, addhealth, HEAL);
addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL);
addhealth = unitTarget->SpellHealingBonusTaken(m_spellInfo, addhealth, HEAL);
if (AuraEffect const* aurEff = m_caster->GetAuraEffect(62971, 0))
{
@@ -1592,9 +1602,11 @@ void Spell::EffectHeal(SpellEffIndex /*effIndex*/)
}
// Death Pact - return pct of max health to caster
else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && m_spellInfo->SpellFamilyFlags[0] & 0x00080000)
addhealth = caster->SpellHealingBonus(unitTarget, m_spellInfo, int32(caster->CountPctFromMaxHealth(damage)), HEAL);
addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, int32(caster->CountPctFromMaxHealth(damage)), HEAL);
else
addhealth = caster->SpellHealingBonus(unitTarget, m_spellInfo, addhealth, HEAL);
addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL);
addhealth = unitTarget->SpellHealingBonusTaken(m_spellInfo, addhealth, HEAL);
// Remove Grievious bite if fully healed
if (unitTarget->HasAura(48920) && (unitTarget->GetHealth() + addhealth >= unitTarget->GetMaxHealth()))
@@ -1620,7 +1632,10 @@ void Spell::EffectHealPct(SpellEffIndex /*effIndex*/)
if (m_spellInfo->Id == 59754 && unitTarget == m_caster)
return;
m_healing += m_originalCaster->SpellHealingBonus(unitTarget, m_spellInfo, unitTarget->CountPctFromMaxHealth(damage), HEAL);
uint32 heal = m_originalCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, unitTarget->CountPctFromMaxHealth(damage), HEAL);
heal = unitTarget->SpellHealingBonusTaken(m_spellInfo, heal, HEAL);
m_healing += heal;
}
void Spell::EffectHealMechanical(SpellEffIndex /*effIndex*/)
@@ -1635,7 +1650,9 @@ void Spell::EffectHealMechanical(SpellEffIndex /*effIndex*/)
if (!m_originalCaster)
return;
m_healing += m_originalCaster->SpellHealingBonus(unitTarget, m_spellInfo, uint32(damage), HEAL);
uint32 heal = m_originalCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, uint32(damage), HEAL);
m_healing += unitTarget->SpellHealingBonusTaken(m_spellInfo, heal, HEAL);;
}
void Spell::EffectHealthLeech(SpellEffIndex effIndex)
@@ -1646,7 +1663,8 @@ void Spell::EffectHealthLeech(SpellEffIndex effIndex)
if (!unitTarget || !unitTarget->isAlive() || damage < 0)
return;
damage = m_caster->SpellDamageBonus(unitTarget, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE);
damage = m_caster->SpellDamageBonusDone(unitTarget, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE);
damage = unitTarget->SpellDamageBonusTaken(m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE);
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "HealthLeech :%i", damage);
@@ -1658,7 +1676,9 @@ void Spell::EffectHealthLeech(SpellEffIndex effIndex)
if (m_caster->isAlive())
{
healthGain = m_caster->SpellHealingBonus(m_caster, m_spellInfo, healthGain, HEAL);
healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL);
healthGain = m_caster->SpellHealingBonusTaken(m_spellInfo, healthGain, HEAL);
m_caster->HealBySpell(m_caster, m_spellInfo, uint32(healthGain));
}
}
@@ -3352,7 +3372,7 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
if (m_spellInfo->Id == 20467)
{
spell_bonus += int32(0.08f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
spell_bonus += int32(0.13f * m_caster->SpellBaseDamageBonus(m_spellInfo->GetSchoolMask()));
spell_bonus += int32(0.13f * m_caster->SpellBaseDamageBonusDone(m_spellInfo->GetSchoolMask()));
}
break;
}
@@ -3521,8 +3541,9 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
uint32 eff_damage(std::max(weaponDamage, 0));
// Add melee damage bonuses (also check for negative)
m_caster->MeleeDamageBonus(unitTarget, &eff_damage, m_attackType, m_spellInfo);
m_damage += eff_damage;
uint32 damage = m_caster->MeleeDamageBonusDone(unitTarget, eff_damage, m_attackType, m_spellInfo);
m_damage += unitTarget->MeleeDamageBonusTaken(damage, m_attackType, m_spellInfo);
}
void Spell::EffectThreat(SpellEffIndex /*effIndex*/)
@@ -3565,7 +3586,10 @@ void Spell::EffectHealMaxHealth(SpellEffIndex /*effIndex*/)
addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
if (m_originalCaster)
m_healing += m_originalCaster->SpellHealingBonus(unitTarget, m_spellInfo, addhealth, HEAL);
{
uint32 heal = m_originalCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL);
m_healing += unitTarget->SpellHealingBonusTaken(m_spellInfo, heal, HEAL);
}
}
void Spell::EffectInterruptCast(SpellEffIndex effIndex)
+29
View File
@@ -1972,6 +1972,35 @@ uint32 SpellInfo::CalcCastTime(Unit* caster, Spell* spell) const
return (castTime > 0) ? uint32(castTime) : 0;
}
uint32 SpellInfo::GetMaxTicks() const
{
int32 DotDuration = GetDuration();
if (DotDuration == 0)
return 1;
// 200% limit
if (DotDuration > 30000)
DotDuration = 30000;
uint8 x = 0;
for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
{
if (Effects[j].Effect == SPELL_EFFECT_APPLY_AURA && (
Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE ||
Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_HEAL ||
Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_LEECH))
{
x = j;
break;
}
}
if (Effects[x].Amplitude != 0)
return DotDuration / Effects[x].Amplitude;
return 6;
}
uint32 SpellInfo::GetRecoveryTime() const
{
return RecoveryTime > CategoryRecoveryTime ? RecoveryTime : CategoryRecoveryTime;
+2
View File
@@ -440,6 +440,8 @@ public:
int32 GetDuration() const;
int32 GetMaxDuration() const;
uint32 GetMaxTicks() const;
uint32 CalcCastTime(Unit* caster = NULL, Spell* spell = NULL) const;
uint32 GetRecoveryTime() const;
+2 -1
View File
@@ -137,8 +137,9 @@ class spell_hun_chimera_shot : public SpellScriptLoader
{
int32 TickCount = aurEff->GetTotalTicks();
spellId = HUNTER_SPELL_CHIMERA_SHOT_SERPENT;
basePoint = caster->SpellDamageBonus(unitTarget, aura->GetSpellInfo(), aurEff->GetAmount(), DOT, aura->GetStackAmount());
basePoint = caster->SpellDamageBonusDone(unitTarget, aura->GetSpellInfo(), aurEff->GetAmount(), DOT, aura->GetStackAmount());
ApplyPctN(basePoint, TickCount * 40);
basePoint = unitTarget->SpellDamageBonusTaken(aura->GetSpellInfo(), basePoint, DOT, aura->GetStackAmount());
}
// Viper Sting - Instantly restores mana to you equal to 60% of the total amount drained by your Viper Sting.
else if (familyFlag[1] & 0x00000080)
+3 -1
View File
@@ -488,7 +488,7 @@ class spell_sha_healing_stream_totem : public SpellScriptLoader
if (Unit* owner = caster->GetOwner())
{
if (triggeringSpell)
damage = int32(owner->SpellHealingBonus(target, triggeringSpell, damage, HEAL));
damage = int32(owner->SpellHealingBonusDone(target, triggeringSpell, damage, HEAL));
// Restorative Totems
if (AuraEffect* dummy = owner->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_SHAMAN, ICON_ID_RESTORATIVE_TOTEMS, 1))
@@ -497,6 +497,8 @@ class spell_sha_healing_stream_totem : public SpellScriptLoader
// Glyph of Healing Stream Totem
if (AuraEffect const* aurEff = owner->GetAuraEffect(SPELL_GLYPH_OF_HEALING_STREAM_TOTEM, EFFECT_0))
AddPctN(damage, aurEff->GetAmount());
damage = int32(target->SpellHealingBonusTaken(triggeringSpell, damage, HEAL));
}
caster->CastCustomSpell(target, SPELL_HEALING_STREAM_TOTEM_HEAL, &damage, 0, 0, true, 0, 0, GetOriginalCaster()->GetGUID());
}
+4 -1
View File
@@ -181,7 +181,7 @@ class spell_warr_deep_wounds : public SpellScriptLoader
if (Unit* caster = GetCaster())
{
// apply percent damage mods
damage = caster->SpellDamageBonus(target, GetSpellInfo(), damage, SPELL_DIRECT_DAMAGE);
damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, SPELL_DIRECT_DAMAGE);
ApplyPctN(damage, 16 * sSpellMgr->GetSpellRank(GetSpellInfo()->Id));
@@ -193,6 +193,9 @@ class spell_warr_deep_wounds : public SpellScriptLoader
damage += aurEff->GetAmount() * (ticks - aurEff->GetTickNumber());
damage = damage / ticks;
damage = target->SpellDamageBonusTaken(GetSpellInfo(), damage, SPELL_DIRECT_DAMAGE);
caster->CastCustomSpell(target, SPELL_DEEP_WOUNDS_RANK_PERIODIC, &damage, NULL, NULL, true);
}
}