Core/Auras: Implement basic absorb scaling with spellpower (#31405)
This commit is contained in:
@@ -7584,6 +7584,124 @@ int32 Unit::SpellBaseHealingBonusDone(SpellSchoolMask schoolMask) const
|
||||
return advertisedBenefit;
|
||||
}
|
||||
|
||||
int32 Unit::SpellBaseAbsorbBonusDone(SpellSchoolMask schoolMask) const
|
||||
{
|
||||
return SpellBaseHealingBonusDone(schoolMask);
|
||||
}
|
||||
|
||||
int32 Unit::SpellAbsorbBonusDone(Unit* victim, SpellInfo const* spellProto, int32 absorbamount, SpellEffectInfo const& spellEffectInfo, uint32 stack /*= 1*/, AuraEffect const* aurEff /*= nullptr*/) const
|
||||
{
|
||||
if (GetTypeId() == TYPEID_UNIT && IsTotem())
|
||||
if (Unit* owner = GetOwner())
|
||||
return owner->SpellAbsorbBonusDone(victim, spellProto, absorbamount, spellEffectInfo, stack, aurEff);
|
||||
|
||||
if (spellProto->HasAttribute(SPELL_ATTR3_IGNORE_CASTER_MODIFIERS)
|
||||
|| spellProto->HasAttribute(SPELL_ATTR6_IGNORE_HEALING_MODIFIERS)
|
||||
|| spellProto->HasAttribute(SPELL_ATTR9_IGNORE_CASTER_HEALING_MODIFIERS))
|
||||
return absorbamount;
|
||||
|
||||
int32 doneTotal = 0;
|
||||
float doneTotalMod = 1.f;
|
||||
|
||||
int32 doneAdvertisedBenefit = SpellBaseAbsorbBonusDone(spellProto->GetSchoolMask());
|
||||
doneAdvertisedBenefit += victim->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_HEALING, spellProto->GetSchoolMask());
|
||||
|
||||
if (HasUnitTypeMask(UNIT_MASK_GUARDIAN))
|
||||
doneAdvertisedBenefit += static_cast<Guardian const*>(this)->GetBonusDamage();
|
||||
|
||||
if (doneAdvertisedBenefit)
|
||||
{
|
||||
float coeff = spellEffectInfo.BonusCoefficient;
|
||||
|
||||
if (Player* modOwner = GetSpellModOwner())
|
||||
{
|
||||
coeff *= 100.f;
|
||||
modOwner->ApplySpellMod(spellProto, SpellModOp::BonusCoefficient, coeff);
|
||||
coeff /= 100.f;
|
||||
}
|
||||
|
||||
doneTotal += int32(doneAdvertisedBenefit * coeff * stack);
|
||||
}
|
||||
|
||||
doneTotalMod = SpellAbsorbPctDone(victim, spellProto);
|
||||
|
||||
float absorbAmount = float(absorbamount + doneTotal) * doneTotalMod;
|
||||
|
||||
return static_cast<int32>(std::round(absorbAmount));
|
||||
}
|
||||
|
||||
float Unit::SpellAbsorbPctDone(Unit* victim, SpellInfo const* spellProto) const
|
||||
{
|
||||
if (GetTypeId() == TYPEID_UNIT && IsTotem())
|
||||
if (Unit* owner = GetOwner())
|
||||
return owner->SpellAbsorbPctDone(victim, spellProto);
|
||||
|
||||
float doneTotalMod = 1.f;
|
||||
|
||||
if (Player* modOwner = GetSpellModOwner())
|
||||
AddPct(doneTotalMod, modOwner->GetRatingBonusValue(CR_VERSATILITY_DAMAGE_DONE) + modOwner->GetTotalAuraModifier(SPELL_AURA_MOD_VERSATILITY));
|
||||
|
||||
if (Player const* thisPlayer = ToPlayer())
|
||||
{
|
||||
float maxModHealingPercentSchool = 0.f;
|
||||
for (uint32 i = 0; i < MAX_SPELL_SCHOOL; ++i)
|
||||
if (spellProto->GetSchoolMask() & (1 << i))
|
||||
maxModHealingPercentSchool = std::max(maxModHealingPercentSchool, thisPlayer->m_activePlayerData->ModHealingDonePercent[i]);
|
||||
|
||||
doneTotalMod *= maxModHealingPercentSchool;
|
||||
}
|
||||
else
|
||||
doneTotalMod *= GetTotalAuraMultiplier(SPELL_AURA_MOD_HEALING_DONE_PERCENT);
|
||||
|
||||
return doneTotalMod;
|
||||
}
|
||||
|
||||
int32 Unit::SpellAbsorbBonusTaken(Unit* caster, SpellInfo const* spellProto, int32 absorbamount) const
|
||||
{
|
||||
bool allowPositive = !spellProto->HasAttribute(SPELL_ATTR6_IGNORE_HEALING_MODIFIERS);
|
||||
bool allowNegative = !spellProto->HasAttribute(SPELL_ATTR6_IGNORE_HEALING_MODIFIERS) || spellProto->HasAttribute(SPELL_ATTR13_ALWAYS_ALLOW_NEGATIVE_HEALING_PERCENT_MODIFIERS);
|
||||
if (!allowPositive && !allowNegative)
|
||||
return absorbamount;
|
||||
|
||||
float takenTotalMod = 1.f;
|
||||
|
||||
if (allowNegative)
|
||||
{
|
||||
float minval = float(GetMaxNegativeAuraModifier(SPELL_AURA_MOD_HEALING_PCT));
|
||||
if (minval)
|
||||
AddPct(takenTotalMod, minval);
|
||||
}
|
||||
|
||||
if (allowPositive)
|
||||
{
|
||||
float maxval = float(GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HEALING_PCT));
|
||||
if (maxval)
|
||||
AddPct(takenTotalMod, maxval);
|
||||
}
|
||||
|
||||
if (caster)
|
||||
{
|
||||
takenTotalMod *= GetTotalAuraMultiplier(SPELL_AURA_MOD_HEALING_RECEIVED, [caster, spellProto, allowPositive, allowNegative](AuraEffect const* aurEff)
|
||||
{
|
||||
if (caster->GetGUID() != aurEff->GetCasterGUID() || !aurEff->IsAffectingSpell(spellProto))
|
||||
return false;
|
||||
|
||||
if (aurEff->GetAmount() > 0)
|
||||
{
|
||||
if (!allowPositive)
|
||||
return false;
|
||||
}
|
||||
else if (!allowNegative)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
float absorb = absorbamount * takenTotalMod;
|
||||
return static_cast<int32>(std::round(absorb));
|
||||
}
|
||||
|
||||
bool Unit::IsImmunedToSpell(SpellInfo const* spellInfo, WorldObject const* caster, bool requireImmunityPurgesEffectAttribute /*= false*/) const
|
||||
{
|
||||
if (!spellInfo)
|
||||
|
||||
@@ -1661,6 +1661,11 @@ class TC_GAME_API Unit : public WorldObject
|
||||
float SpellHealingPctDone(Unit* victim, SpellInfo const* spellProto) const;
|
||||
int32 SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, int32 healamount, DamageEffectType damagetype) const;
|
||||
|
||||
int32 SpellBaseAbsorbBonusDone(SpellSchoolMask schoolMask) const;
|
||||
int32 SpellAbsorbBonusDone(Unit* victim, SpellInfo const* spellProto, int32 absorbamount, SpellEffectInfo const& spellEffectInfo, uint32 stack = 1, AuraEffect const* aurEff = nullptr) const;
|
||||
float SpellAbsorbPctDone(Unit* victim, SpellInfo const* spellProto) const;
|
||||
int32 SpellAbsorbBonusTaken(Unit* caster, SpellInfo const* spellProto, int32 absorbamount) const;
|
||||
|
||||
int32 MeleeDamageBonusDone(Unit* pVictim, int32 damage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo const* spellProto = nullptr, SpellEffectInfo const* spellEffectInfo = nullptr, Mechanics mechanic = MECHANIC_NONE, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL, Spell* spell = nullptr, AuraEffect const* aurEff = nullptr);
|
||||
int32 MeleeDamageBonusTaken(Unit* attacker, int32 pdamage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo const* spellProto = nullptr, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL);
|
||||
|
||||
|
||||
@@ -781,6 +781,13 @@ int32 AuraEffect::CalculateAmount(Unit* caster)
|
||||
amount = int32(unitOwner->CountPctFromMaxHealth(10));
|
||||
break;
|
||||
case SPELL_AURA_SCHOOL_ABSORB:
|
||||
m_canBeRecalculated = false;
|
||||
if (!caster || !unitOwner)
|
||||
break;
|
||||
|
||||
amount = caster->SpellAbsorbBonusDone(unitOwner, m_spellInfo, amount, m_effectInfo, 1, this);
|
||||
amount = unitOwner->SpellAbsorbBonusTaken(caster, m_spellInfo, amount);
|
||||
break;
|
||||
case SPELL_AURA_MANA_SHIELD:
|
||||
m_canBeRecalculated = false;
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user