mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-03-07 09:40:28 +00:00
fix(Core/Spells): Implement TrinityCore spell_group and spell_group_stack_rules (#23346)
Co-authored-by: treeston <treeston.mmoc@gmail.com> Co-authored-by: Trisjdc <trisjdc@gmail.com> Co-authored-by: QAston <none@none> Co-authored-by: ariel- <ariel-@users.noreply.github.com> Co-authored-by: Shauren <shauren.trinity@gmail.com> Co-authored-by: Jelle Meeus <sogladev@gmail.com>
This commit is contained in:
@@ -212,7 +212,7 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS] =
|
||||
&AuraEffect::HandleModStateImmunityMask, //147 SPELL_AURA_MECHANIC_IMMUNITY_MASK
|
||||
&AuraEffect::HandleAuraRetainComboPoints, //148 SPELL_AURA_RETAIN_COMBO_POINTS
|
||||
&AuraEffect::HandleNoImmediateEffect, //149 SPELL_AURA_REDUCE_PUSHBACK
|
||||
&AuraEffect::HandleShieldBlockValue, //150 SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT
|
||||
&AuraEffect::HandleShieldBlockValuePercent, //150 SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT
|
||||
&AuraEffect::HandleAuraTrackStealthed, //151 SPELL_AURA_TRACK_STEALTHED
|
||||
&AuraEffect::HandleNoImmediateEffect, //152 SPELL_AURA_MOD_DETECTED_RANGE implemented in Creature::GetAggroRange
|
||||
&AuraEffect::HandleNoImmediateEffect, //153 SPELL_AURA_SPLIT_DAMAGE_FLAT
|
||||
@@ -393,7 +393,6 @@ AuraEffect::AuraEffect(Aura* base, uint8 effIndex, int32* baseAmount, Unit* cast
|
||||
m_amount = CalculateAmount(caster);
|
||||
m_casterLevel = caster ? caster->GetLevel() : 0;
|
||||
m_applyResilience = caster && caster->CanApplyResilience();
|
||||
m_auraGroup = sSpellMgr->GetSpellGroup(GetId());
|
||||
|
||||
CalculateSpellMod();
|
||||
|
||||
@@ -3000,14 +2999,17 @@ void AuraEffect::HandleAuraModDisarm(AuraApplication const* aurApp, uint8 mode,
|
||||
// Handle damage modification, shapeshifted druids are not affected
|
||||
if (target->IsPlayer() && (!target->IsInFeralForm() || target->GetShapeshiftForm() == FORM_GHOSTWOLF))
|
||||
{
|
||||
if (Item* pItem = target->ToPlayer()->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
|
||||
Player* player = target->ToPlayer();
|
||||
if (Item* pItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
|
||||
{
|
||||
WeaponAttackType attacktype = Player::GetAttackBySlot(slot);
|
||||
WeaponAttackType attackType = Player::GetAttackBySlot(slot);
|
||||
|
||||
if (attacktype < MAX_ATTACK)
|
||||
player->ApplyItemDependentAuras(pItem, !apply);
|
||||
if (attackType < MAX_ATTACK)
|
||||
{
|
||||
target->ToPlayer()->_ApplyWeaponDamage(slot, pItem->GetTemplate(), nullptr, !apply);
|
||||
target->ToPlayer()->_ApplyWeaponDependentAuraMods(pItem, attacktype, !apply);
|
||||
player->_ApplyWeaponDamage(slot, pItem->GetTemplate(), nullptr, !apply);
|
||||
if (!apply) // apply case already handled on item dependent aura removal (if any)
|
||||
player->UpdateWeaponDependentAuras(attackType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3439,9 +3441,17 @@ void AuraEffect::HandleModThreat(AuraApplication const* aurApp, uint8 mode, bool
|
||||
return;
|
||||
|
||||
Unit* target = aurApp->GetTarget();
|
||||
for (int8 i = 0; i < MAX_SPELL_SCHOOL; ++i)
|
||||
for (uint8 i = 0; i < MAX_SPELL_SCHOOL; ++i)
|
||||
if (GetMiscValue() & (1 << i))
|
||||
ApplyPercentModFloatVar(target->m_threatModifier[i], float(GetAmount()), apply);
|
||||
{
|
||||
if (apply)
|
||||
AddPct(target->m_threatModifier[i], GetAmount());
|
||||
else
|
||||
{
|
||||
float amount = target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_THREAT, 1 << i);
|
||||
target->m_threatModifier[i] = amount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AuraEffect::HandleAuraModTotalThreat(AuraApplication const* aurApp, uint8 mode, bool apply) const
|
||||
@@ -4318,7 +4328,7 @@ void AuraEffect::HandleAuraModResistanceExclusive(AuraApplication const* aurApp,
|
||||
|
||||
Unit* target = aurApp->GetTarget();
|
||||
|
||||
for (int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL; x++)
|
||||
for (uint8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL; x++)
|
||||
{
|
||||
if (GetMiscValue() & int32(1 << x))
|
||||
{
|
||||
@@ -4326,9 +4336,9 @@ void AuraEffect::HandleAuraModResistanceExclusive(AuraApplication const* aurApp,
|
||||
if (amount < GetAmount())
|
||||
{
|
||||
float value = float(GetAmount() - amount);
|
||||
target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_VALUE, value, apply);
|
||||
if (target->IsPlayer())
|
||||
target->ApplyResistanceBuffModsMod(SpellSchools(x), aurApp->IsPositive(), value, apply);
|
||||
target->HandleStatFlatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_VALUE, value, apply);
|
||||
if (target->IsPlayer() || target->IsPet())
|
||||
target->UpdateResistanceBuffModsMod(SpellSchools(x));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4345,9 +4355,9 @@ void AuraEffect::HandleAuraModResistance(AuraApplication const* aurApp, uint8 mo
|
||||
{
|
||||
if (GetMiscValue() & int32(1 << x))
|
||||
{
|
||||
target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), TOTAL_VALUE, float(GetAmount()), apply);
|
||||
target->HandleStatFlatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), TOTAL_VALUE, float(GetAmount()), apply);
|
||||
if (target->IsPlayer() || target->IsPet())
|
||||
target->ApplyResistanceBuffModsMod(SpellSchools(x), GetAmount() > 0, (float)GetAmount(), apply);
|
||||
target->UpdateResistanceBuffModsMod(SpellSchools(x));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4358,32 +4368,39 @@ void AuraEffect::HandleAuraModBaseResistancePCT(AuraApplication const* aurApp, u
|
||||
return;
|
||||
|
||||
Unit* target = aurApp->GetTarget();
|
||||
for (int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL; x++)
|
||||
for (uint8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL; x++)
|
||||
{
|
||||
if (GetMiscValue() & int32(1 << x))
|
||||
{
|
||||
target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_PCT, float(GetAmount()), apply);
|
||||
if (apply)
|
||||
target->ApplyStatPctModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_PCT, float(GetAmount()));
|
||||
else
|
||||
{
|
||||
float amount = target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_BASE_RESISTANCE_PCT, 1 << x);
|
||||
target->SetStatPctModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_PCT, amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AuraEffect::HandleModResistancePercent(AuraApplication const* aurApp, uint8 mode, bool apply) const
|
||||
void AuraEffect::HandleModResistancePercent(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const
|
||||
{
|
||||
if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
|
||||
return;
|
||||
|
||||
Unit* target = aurApp->GetTarget();
|
||||
|
||||
for (int8 i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++)
|
||||
for (uint8 i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++)
|
||||
{
|
||||
if (GetMiscValue() & int32(1 << i))
|
||||
{
|
||||
target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_PCT, float(GetAmount()), apply);
|
||||
float amount = target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_RESISTANCE_PCT, 1 << i);
|
||||
if (target->GetPctModifierValue(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_PCT) == amount)
|
||||
continue;
|
||||
|
||||
target->SetStatPctModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_PCT, amount);
|
||||
if (target->IsPlayer() || target->IsPet())
|
||||
{
|
||||
target->ApplyResistanceBuffModsPercentMod(SpellSchools(i), true, (float)GetAmount(), apply);
|
||||
target->ApplyResistanceBuffModsPercentMod(SpellSchools(i), false, (float)GetAmount(), apply);
|
||||
}
|
||||
target->UpdateResistanceBuffModsMod(SpellSchools(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4398,7 +4415,7 @@ void AuraEffect::HandleModBaseResistance(AuraApplication const* aurApp, uint8 mo
|
||||
{
|
||||
if (GetMiscValue() & (1 << i))
|
||||
{
|
||||
target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_VALUE, float(GetAmount()), apply);
|
||||
target->HandleStatFlatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_VALUE, float(GetAmount()), apply);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4430,23 +4447,28 @@ void AuraEffect::HandleAuraModStat(AuraApplication const* aurApp, uint8 mode, bo
|
||||
if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
|
||||
return;
|
||||
|
||||
Unit* target = aurApp->GetTarget();
|
||||
|
||||
if (GetMiscValue() < -2 || GetMiscValue() > 4)
|
||||
{
|
||||
LOG_ERROR("spells.aura.effect", "WARNING: Spell {} effect {} has an unsupported misc value ({}) for SPELL_AURA_MOD_STAT ", GetId(), GetEffIndex(), GetMiscValue());
|
||||
return;
|
||||
}
|
||||
|
||||
Unit* target = aurApp->GetTarget();
|
||||
int32 spellGroupVal = target->GetHighestExclusiveSameEffectSpellGroupValue(this, SPELL_AURA_MOD_STAT, true, GetMiscValue());
|
||||
if (std::abs(spellGroupVal) >= std::abs(GetAmount()))
|
||||
return;
|
||||
|
||||
for (int32 i = STAT_STRENGTH; i < MAX_STATS; i++)
|
||||
{
|
||||
// -1 or -2 is all stats (misc < -2 checked in function beginning)
|
||||
if (GetMiscValue() < 0 || GetMiscValue() == i)
|
||||
{
|
||||
//target->ApplyStatMod(Stats(i), m_amount, apply);
|
||||
target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_VALUE, float(GetAmount()), apply);
|
||||
if (spellGroupVal)
|
||||
target->HandleStatFlatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_VALUE, float(GetAmount()), !apply);
|
||||
|
||||
target->HandleStatFlatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_VALUE, float(GetAmount()), apply);
|
||||
if (target->IsPlayer() || target->IsPet())
|
||||
target->ApplyStatBuffMod(Stats(i), (float)GetAmount(), apply);
|
||||
target->UpdateStatBuffMod(Stats(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4470,8 +4492,16 @@ void AuraEffect::HandleModPercentStat(AuraApplication const* aurApp, uint8 mode,
|
||||
|
||||
for (int32 i = STAT_STRENGTH; i < MAX_STATS; ++i)
|
||||
{
|
||||
if (GetMiscValue() == i || GetMiscValue() == -1)
|
||||
target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), BASE_PCT, float(m_amount), apply);
|
||||
if (apply)
|
||||
target->ApplyStatPctModifier(UnitMods(UNIT_MOD_STAT_START + i), BASE_PCT, float(GetAmount()));
|
||||
else
|
||||
{
|
||||
float amount = target->GetTotalAuraMultiplier(SPELL_AURA_MOD_PERCENT_STAT, [i](AuraEffect const* aurEff)
|
||||
{
|
||||
return (aurEff->GetMiscValue() == i || aurEff->GetMiscValue() == -1);
|
||||
});
|
||||
target->SetStatPctModifier(UnitMods(UNIT_MOD_STAT_START + i), BASE_PCT, amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4549,7 +4579,7 @@ void AuraEffect::HandleModHealingDone(AuraApplication const* aurApp, uint8 mode,
|
||||
target->ToPlayer()->UpdateSpellDamageAndHealingBonus();
|
||||
}
|
||||
|
||||
void AuraEffect::HandleModTotalPercentStat(AuraApplication const* aurApp, uint8 mode, bool apply) const
|
||||
void AuraEffect::HandleModTotalPercentStat(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const
|
||||
{
|
||||
if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
|
||||
return;
|
||||
@@ -4565,39 +4595,22 @@ void AuraEffect::HandleModTotalPercentStat(AuraApplication const* aurApp, uint8
|
||||
// save current health state
|
||||
float healthPct = target->GetHealthPct();
|
||||
bool alive = target->IsAlive();
|
||||
float value = GetAmount();
|
||||
|
||||
if (GetId() == 67480) // xinef: hack fix for blessing of sanctuary stats stack with blessing of kings...
|
||||
{
|
||||
if (value) // not turned off
|
||||
value = 10.0f;
|
||||
for (int32 i = STAT_STRENGTH; i < MAX_STATS; i++)
|
||||
{
|
||||
if (i == STAT_STRENGTH || i == STAT_STAMINA)
|
||||
{
|
||||
if (apply && (target->IsPlayer() || target->IsPet()))
|
||||
target->ApplyStatPercentBuffMod(Stats(i), value, apply);
|
||||
|
||||
target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_PCT, value, apply);
|
||||
|
||||
if (!apply && (target->IsPlayer() || target->IsPet()))
|
||||
target->ApplyStatPercentBuffMod(Stats(i), value, apply);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (int32 i = STAT_STRENGTH; i < MAX_STATS; i++)
|
||||
{
|
||||
if (GetMiscValue() == i || GetMiscValue() == -1)
|
||||
{
|
||||
if (apply && (target->IsPlayer() || target->IsPet()))
|
||||
target->ApplyStatPercentBuffMod(Stats(i), value, apply);
|
||||
float amount = target->GetTotalAuraMultiplier(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, [i](AuraEffect const* aurEff)
|
||||
{
|
||||
return (aurEff->GetMiscValue() == i || aurEff->GetMiscValue() == -1);
|
||||
});
|
||||
|
||||
target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_PCT, value, apply);
|
||||
if (target->GetPctModifierValue(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_PCT) == amount)
|
||||
continue;
|
||||
|
||||
if (!apply && (target->IsPlayer() || target->IsPet()))
|
||||
target->ApplyStatPercentBuffMod(Stats(i), value, apply);
|
||||
target->SetStatPctModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_PCT, amount);
|
||||
if (target->IsPlayer() || target->IsPet())
|
||||
target->UpdateStatBuffMod(Stats(i));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4693,7 +4706,7 @@ void AuraEffect::HandleAuraModIncreaseHealth(AuraApplication const* aurApp, uint
|
||||
|
||||
if (apply)
|
||||
{
|
||||
target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(GetAmount()), apply);
|
||||
target->HandleStatFlatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(GetAmount()), apply);
|
||||
target->ModifyHealth(GetAmount());
|
||||
}
|
||||
else
|
||||
@@ -4702,7 +4715,7 @@ void AuraEffect::HandleAuraModIncreaseHealth(AuraApplication const* aurApp, uint
|
||||
target->ModifyHealth(-GetAmount());
|
||||
else
|
||||
target->SetHealth(1);
|
||||
target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(GetAmount()), apply);
|
||||
target->HandleStatFlatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(GetAmount()), apply);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4716,7 +4729,7 @@ void AuraEffect::HandleAuraModIncreaseMaxHealth(AuraApplication const* aurApp, u
|
||||
uint32 oldhealth = target->GetHealth();
|
||||
double healthPercentage = (double)oldhealth / (double)target->GetMaxHealth();
|
||||
|
||||
target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(GetAmount()), apply);
|
||||
target->HandleStatFlatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(GetAmount()), apply);
|
||||
|
||||
// refresh percentage
|
||||
if (oldhealth > 0)
|
||||
@@ -4746,7 +4759,7 @@ void AuraEffect::HandleAuraModIncreaseEnergy(AuraApplication const* aurApp, uint
|
||||
|
||||
UnitMods unitMod = UnitMods(static_cast<uint16>(UNIT_MOD_POWER_START) + PowerType);
|
||||
|
||||
target->HandleStatModifier(unitMod, TOTAL_VALUE, float(GetAmount()), apply);
|
||||
target->HandleStatFlatModifier(unitMod, TOTAL_VALUE, float(GetAmount()), apply);
|
||||
}
|
||||
|
||||
void AuraEffect::HandleAuraModIncreaseEnergyPercent(AuraApplication const* aurApp, uint8 mode, bool apply) const
|
||||
@@ -4765,17 +4778,16 @@ void AuraEffect::HandleAuraModIncreaseEnergyPercent(AuraApplication const* aurAp
|
||||
// return;
|
||||
|
||||
UnitMods unitMod = UnitMods(static_cast<uint16>(UNIT_MOD_POWER_START) + PowerType);
|
||||
float amount = float(GetAmount());
|
||||
|
||||
if (apply)
|
||||
{
|
||||
target->HandleStatModifier(unitMod, TOTAL_PCT, amount, apply);
|
||||
target->ModifyPowerPct(PowerType, amount, apply);
|
||||
float amount = float(GetAmount());
|
||||
target->ApplyStatPctModifier(unitMod, TOTAL_PCT, amount);
|
||||
}
|
||||
else
|
||||
{
|
||||
target->ModifyPowerPct(PowerType, amount, apply);
|
||||
target->HandleStatModifier(unitMod, TOTAL_PCT, amount, apply);
|
||||
float amount = target->GetTotalAuraMultiplierByMiscValue(SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT, GetMiscValue());
|
||||
target->SetStatPctModifier(unitMod, TOTAL_PCT, amount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4788,7 +4800,14 @@ void AuraEffect::HandleAuraModIncreaseHealthPercent(AuraApplication const* aurAp
|
||||
|
||||
// Unit will keep hp% after MaxHealth being modified if unit is alive.
|
||||
float percent = target->GetHealthPct();
|
||||
target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_PCT, float(GetAmount()), apply);
|
||||
|
||||
if (apply)
|
||||
target->ApplyStatPctModifier(UNIT_MOD_HEALTH, TOTAL_PCT, float(GetAmount()));
|
||||
else
|
||||
{
|
||||
float amount = target->GetTotalAuraMultiplier(SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT);
|
||||
target->SetStatPctModifier(UNIT_MOD_HEALTH, TOTAL_PCT, amount);
|
||||
}
|
||||
|
||||
// Xinef: pct was rounded down and could "kill" creature by setting its health to 0 making npc zombie
|
||||
if (target->IsAlive())
|
||||
@@ -4803,7 +4822,13 @@ void AuraEffect::HandleAuraIncreaseBaseHealthPercent(AuraApplication const* aurA
|
||||
|
||||
Unit* target = aurApp->GetTarget();
|
||||
|
||||
target->HandleStatModifier(UNIT_MOD_HEALTH, BASE_PCT, float(GetAmount()), apply);
|
||||
if (apply)
|
||||
target->ApplyStatPctModifier(UNIT_MOD_HEALTH, BASE_PCT, float(GetAmount()));
|
||||
else
|
||||
{
|
||||
float amount = target->GetTotalAuraMultiplier(SPELL_AURA_MOD_BASE_HEALTH_PCT);
|
||||
target->SetStatPctModifier(UNIT_MOD_HEALTH, BASE_PCT, amount);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************/
|
||||
@@ -4857,34 +4882,17 @@ void AuraEffect::HandleAuraModRegenInterrupt(AuraApplication const* aurApp, uint
|
||||
HandleModManaRegen(aurApp, mode, apply);
|
||||
}
|
||||
|
||||
void AuraEffect::HandleAuraModWeaponCritPercent(AuraApplication const* aurApp, uint8 mode, bool apply) const
|
||||
void AuraEffect::HandleAuraModWeaponCritPercent(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const
|
||||
{
|
||||
if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
|
||||
return;
|
||||
|
||||
Unit* target = aurApp->GetTarget();
|
||||
Player* target = aurApp->GetTarget()->ToPlayer();
|
||||
|
||||
if (!target->IsPlayer())
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < MAX_ATTACK; ++i)
|
||||
if (Item* pItem = target->ToPlayer()->GetWeaponForAttack(WeaponAttackType(i), true))
|
||||
target->ToPlayer()->_ApplyWeaponDependentAuraCritMod(pItem, WeaponAttackType(i), this, apply);
|
||||
|
||||
// mods must be applied base at equipped weapon class and subclass comparison
|
||||
// with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask
|
||||
// GetMiscValue() comparison with item generated damage types
|
||||
|
||||
if (GetSpellInfo()->EquippedItemClass == -1)
|
||||
{
|
||||
target->ToPlayer()->HandleBaseModValue(CRIT_PERCENTAGE, FLAT_MOD, float (GetAmount()), apply);
|
||||
target->ToPlayer()->HandleBaseModValue(OFFHAND_CRIT_PERCENTAGE, FLAT_MOD, float (GetAmount()), apply);
|
||||
target->ToPlayer()->HandleBaseModValue(RANGED_CRIT_PERCENTAGE, FLAT_MOD, float (GetAmount()), apply);
|
||||
}
|
||||
else
|
||||
{
|
||||
// done in Player::_ApplyWeaponDependentAuraMods
|
||||
}
|
||||
target->UpdateAllWeaponDependentCritAuras();
|
||||
}
|
||||
|
||||
void AuraEffect::HandleModHitChance(AuraApplication const* aurApp, uint8 mode, bool apply) const
|
||||
@@ -4960,9 +4968,7 @@ void AuraEffect::HandleAuraModCritPct(AuraApplication const* aurApp, uint8 mode,
|
||||
return;
|
||||
}
|
||||
|
||||
target->ToPlayer()->HandleBaseModValue(CRIT_PERCENTAGE, FLAT_MOD, float (GetAmount()), apply);
|
||||
target->ToPlayer()->HandleBaseModValue(OFFHAND_CRIT_PERCENTAGE, FLAT_MOD, float (GetAmount()), apply);
|
||||
target->ToPlayer()->HandleBaseModValue(RANGED_CRIT_PERCENTAGE, FLAT_MOD, float (GetAmount()), apply);
|
||||
target->ToPlayer()->UpdateAllWeaponDependentCritAuras();
|
||||
|
||||
// included in Player::UpdateSpellCritChance calculation
|
||||
target->ToPlayer()->UpdateAllSpellCritChances();
|
||||
@@ -4986,6 +4992,13 @@ void AuraEffect::HandleModCastingSpeed(AuraApplication const* aurApp, uint8 mode
|
||||
return;
|
||||
}
|
||||
|
||||
int32 spellGroupVal = target->GetHighestExclusiveSameEffectSpellGroupValue(this, GetAuraType());
|
||||
if (std::abs(spellGroupVal) >= std::abs(GetAmount()))
|
||||
return;
|
||||
|
||||
if (spellGroupVal)
|
||||
target->ApplyCastTimePercentMod(float(spellGroupVal), !apply);
|
||||
|
||||
target->ApplyCastTimePercentMod((float)GetAmount(), apply);
|
||||
}
|
||||
|
||||
@@ -5007,6 +5020,17 @@ void AuraEffect::HandleModCombatSpeedPct(AuraApplication const* aurApp, uint8 mo
|
||||
return;
|
||||
|
||||
Unit* target = aurApp->GetTarget();
|
||||
int32 spellGroupVal = target->GetHighestExclusiveSameEffectSpellGroupValue(this, SPELL_AURA_MELEE_SLOW);
|
||||
if (std::abs(spellGroupVal) >= std::abs(GetAmount()))
|
||||
return;
|
||||
|
||||
if (spellGroupVal)
|
||||
{
|
||||
target->ApplyCastTimePercentMod(float(spellGroupVal), !apply);
|
||||
target->ApplyAttackTimePercentMod(BASE_ATTACK, float(spellGroupVal), !apply);
|
||||
target->ApplyAttackTimePercentMod(OFF_ATTACK, float(spellGroupVal), !apply);
|
||||
target->ApplyAttackTimePercentMod(RANGED_ATTACK, float(spellGroupVal), !apply);
|
||||
}
|
||||
|
||||
target->ApplyCastTimePercentMod(float(GetAmount()), apply);
|
||||
target->ApplyAttackTimePercentMod(BASE_ATTACK, float(GetAmount()), apply);
|
||||
@@ -5031,7 +5055,15 @@ void AuraEffect::HandleModMeleeSpeedPct(AuraApplication const* aurApp, uint8 mod
|
||||
return;
|
||||
|
||||
Unit* target = aurApp->GetTarget();
|
||||
int32 spellGroupVal = target->GetHighestExclusiveSameEffectSpellGroupValue(this, SPELL_AURA_MOD_MELEE_HASTE);
|
||||
if (std::abs(spellGroupVal) >= std::abs(GetAmount()))
|
||||
return;
|
||||
|
||||
if (spellGroupVal)
|
||||
{
|
||||
target->ApplyAttackTimePercentMod(BASE_ATTACK, float(spellGroupVal), !apply);
|
||||
target->ApplyAttackTimePercentMod(OFF_ATTACK, float(spellGroupVal), !apply);
|
||||
}
|
||||
target->ApplyAttackTimePercentMod(BASE_ATTACK, float(GetAmount()), apply);
|
||||
target->ApplyAttackTimePercentMod(OFF_ATTACK, float(GetAmount()), apply);
|
||||
}
|
||||
@@ -5105,7 +5137,7 @@ void AuraEffect::HandleAuraModAttackPower(AuraApplication const* aurApp, uint8 m
|
||||
|
||||
Unit* target = aurApp->GetTarget();
|
||||
|
||||
target->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(GetAmount()), apply);
|
||||
target->HandleStatFlatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(GetAmount()), apply);
|
||||
}
|
||||
|
||||
void AuraEffect::HandleAuraModRangedAttackPower(AuraApplication const* aurApp, uint8 mode, bool apply) const
|
||||
@@ -5118,7 +5150,7 @@ void AuraEffect::HandleAuraModRangedAttackPower(AuraApplication const* aurApp, u
|
||||
if ((target->getClassMask() & CLASSMASK_WAND_USERS) != 0)
|
||||
return;
|
||||
|
||||
target->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(GetAmount()), apply);
|
||||
target->HandleStatFlatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(GetAmount()), apply);
|
||||
}
|
||||
|
||||
void AuraEffect::HandleAuraModAttackPowerPercent(AuraApplication const* aurApp, uint8 mode, bool apply) const
|
||||
@@ -5129,7 +5161,13 @@ void AuraEffect::HandleAuraModAttackPowerPercent(AuraApplication const* aurApp,
|
||||
Unit* target = aurApp->GetTarget();
|
||||
|
||||
//UNIT_FIELD_ATTACK_POWER_MULTIPLIER = multiplier - 1
|
||||
target->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_PCT, float(GetAmount()), apply);
|
||||
if (apply)
|
||||
target->ApplyStatPctModifier(UNIT_MOD_ATTACK_POWER, TOTAL_PCT, float(GetAmount()));
|
||||
else
|
||||
{
|
||||
float amount = target->GetTotalAuraMultiplier(SPELL_AURA_MOD_ATTACK_POWER_PCT);
|
||||
target->SetStatPctModifier(UNIT_MOD_ATTACK_POWER, TOTAL_PCT, amount);
|
||||
}
|
||||
}
|
||||
|
||||
void AuraEffect::HandleAuraModRangedAttackPowerPercent(AuraApplication const* aurApp, uint8 mode, bool apply) const
|
||||
@@ -5143,7 +5181,13 @@ void AuraEffect::HandleAuraModRangedAttackPowerPercent(AuraApplication const* au
|
||||
return;
|
||||
|
||||
//UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = multiplier - 1
|
||||
target->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_PCT, float(GetAmount()), apply);
|
||||
if (apply)
|
||||
target->ApplyStatPctModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_PCT, float(GetAmount()));
|
||||
else
|
||||
{
|
||||
float amount = target->GetTotalAuraMultiplier(SPELL_AURA_MOD_RANGED_ATTACK_POWER_PCT);
|
||||
target->SetStatPctModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_PCT, amount);
|
||||
}
|
||||
}
|
||||
|
||||
void AuraEffect::HandleAuraModRangedAttackPowerOfStatPercent(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const
|
||||
@@ -5184,85 +5228,25 @@ void AuraEffect::HandleModDamageDone(AuraApplication const* aurApp, uint8 mode,
|
||||
|
||||
Unit* target = aurApp->GetTarget();
|
||||
|
||||
// apply item specific bonuses for already equipped weapon
|
||||
if (target->IsPlayer())
|
||||
{
|
||||
for (int i = 0; i < MAX_ATTACK; ++i)
|
||||
if (Item* pItem = target->ToPlayer()->GetWeaponForAttack(WeaponAttackType(i), true))
|
||||
target->ToPlayer()->_ApplyWeaponDependentAuraDamageMod(pItem, WeaponAttackType(i), this, apply);
|
||||
}
|
||||
if ((GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL) != 0)
|
||||
target->UpdateAllDamageDoneMods();
|
||||
|
||||
// GetMiscValue() is bitmask of spell schools
|
||||
// 1 (0-bit) - normal school damage (SPELL_SCHOOL_MASK_NORMAL)
|
||||
// 126 - full bitmask all magic damages (SPELL_SCHOOL_MASK_MAGIC) including wands
|
||||
// 127 - full bitmask any damages
|
||||
//
|
||||
// mods must be applied base at equipped weapon class and subclass comparison
|
||||
// with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask
|
||||
// GetMiscValue() comparison with item generated damage types
|
||||
|
||||
if ((GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL) != 0 && sScriptMgr->CanModAuraEffectDamageDone(this, target, aurApp, mode, apply))
|
||||
{
|
||||
// apply generic physical damage bonuses including wand case
|
||||
if (GetSpellInfo()->EquippedItemClass == -1 || !target->IsPlayer())
|
||||
{
|
||||
target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_VALUE, float(GetAmount()), apply);
|
||||
target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_VALUE, float(GetAmount()), apply);
|
||||
target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_VALUE, float(GetAmount()), apply);
|
||||
|
||||
if (target->IsPlayer())
|
||||
{
|
||||
if (GetAmount() > 0)
|
||||
target->ApplyModInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS, GetAmount(), apply);
|
||||
else
|
||||
target->ApplyModInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG, GetAmount(), apply);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// done in Player::_ApplyWeaponDependentAuraMods
|
||||
}
|
||||
}
|
||||
|
||||
// Skip non magic case for Speedup
|
||||
if ((GetMiscValue() & SPELL_SCHOOL_MASK_MAGIC) == 0)
|
||||
return;
|
||||
|
||||
if (GetSpellInfo()->EquippedItemClass != -1 || GetSpellInfo()->EquippedItemInventoryTypeMask != 0)
|
||||
{
|
||||
// wand magic case (skip generic to all item spell bonuses)
|
||||
// done in Player::_ApplyWeaponDependentAuraMods
|
||||
|
||||
// Skip item specific requirements for not wand magic damage
|
||||
return;
|
||||
}
|
||||
|
||||
// Magic damage modifiers implemented in Unit::SpellDamageBonus
|
||||
// Magic damage modifiers implemented in Unit::SpellBaseDamageBonus
|
||||
// This information for client side use only
|
||||
if (target->IsPlayer())
|
||||
{
|
||||
if (GetAmount() > 0)
|
||||
{
|
||||
for (uint32 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++)
|
||||
{
|
||||
if ((GetMiscValue() & (1 << i)) != 0)
|
||||
target->ApplyModInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + i, GetAmount(), apply);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint32 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++)
|
||||
{
|
||||
if ((GetMiscValue() & (1 << i)) != 0)
|
||||
target->ApplyModInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + i, GetAmount(), apply);
|
||||
}
|
||||
}
|
||||
|
||||
uint16 baseField = GetAmount() >= 0 ? PLAYER_FIELD_MOD_DAMAGE_DONE_POS : PLAYER_FIELD_MOD_DAMAGE_DONE_NEG;
|
||||
for (uint16 i = 0; i < MAX_SPELL_SCHOOL; ++i)
|
||||
if (GetMiscValue() & (1 << i))
|
||||
target->ApplyModUInt32Value(baseField + i, GetAmount(), apply);
|
||||
|
||||
if (Guardian* pet = target->ToPlayer()->GetGuardianPet())
|
||||
pet->UpdateAttackPowerAndDamage();
|
||||
}
|
||||
}
|
||||
|
||||
void AuraEffect::HandleModDamagePercentDone(AuraApplication const* aurApp, uint8 mode, bool apply) const
|
||||
void AuraEffect::HandleModDamagePercentDone(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const
|
||||
{
|
||||
if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
|
||||
return;
|
||||
@@ -5271,39 +5255,32 @@ void AuraEffect::HandleModDamagePercentDone(AuraApplication const* aurApp, uint8
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
if (!sScriptMgr->CanModAuraEffectModDamagePercentDone(this, target, aurApp, mode, apply))
|
||||
return;
|
||||
if ((GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL))
|
||||
target->UpdateAllDamagePctDoneMods();
|
||||
|
||||
if (target->IsPlayer())
|
||||
{
|
||||
for (int i = 0; i < MAX_ATTACK; ++i)
|
||||
if (Item* item = target->ToPlayer()->GetWeaponForAttack(WeaponAttackType(i), false))
|
||||
target->ToPlayer()->_ApplyWeaponDependentAuraDamageMod(item, WeaponAttackType(i), this, apply);
|
||||
}
|
||||
|
||||
if ((GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL) && (GetSpellInfo()->EquippedItemClass == -1 || !target->IsPlayer()))
|
||||
{
|
||||
target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, float(GetAmount()), apply);
|
||||
target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(GetAmount()), apply);
|
||||
target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_PCT, float(GetAmount()), apply);
|
||||
|
||||
if (target->IsPlayer())
|
||||
target->ToPlayer()->ApplyPercentModFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT, float (GetAmount()), apply);
|
||||
}
|
||||
else
|
||||
{
|
||||
// done in Player::_ApplyWeaponDependentAuraMods for SPELL_SCHOOL_MASK_NORMAL && EquippedItemClass != -1 and also for wand case
|
||||
for (uint8 i = 0; i < MAX_SPELL_SCHOOL; ++i)
|
||||
{
|
||||
if (GetMiscValue() & (1 << i))
|
||||
{
|
||||
// only aura type modifying PLAYER_FIELD_MOD_DAMAGE_DONE_PCT
|
||||
float amount = target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, 1 << i);
|
||||
target->SetFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT + i, amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AuraEffect::HandleModOffhandDamagePercent(AuraApplication const* aurApp, uint8 mode, bool apply) const
|
||||
void AuraEffect::HandleModOffhandDamagePercent(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const
|
||||
{
|
||||
if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
|
||||
return;
|
||||
|
||||
Unit* target = aurApp->GetTarget();
|
||||
|
||||
target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(GetAmount()), apply);
|
||||
// also handles spell group stacks
|
||||
target->UpdateDamagePctDoneMods(OFF_ATTACK);
|
||||
}
|
||||
|
||||
void AuraEffect::HandleShieldBlockValue(AuraApplication const* aurApp, uint8 mode, bool apply) const
|
||||
@@ -5311,14 +5288,29 @@ void AuraEffect::HandleShieldBlockValue(AuraApplication const* aurApp, uint8 mod
|
||||
if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
|
||||
return;
|
||||
|
||||
Unit* target = aurApp->GetTarget();
|
||||
Player* target = aurApp->GetTarget()->ToPlayer();
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
BaseModType modType = FLAT_MOD;
|
||||
if (GetAuraType() == SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT)
|
||||
modType = PCT_MOD;
|
||||
target->HandleBaseModFlatValue(SHIELD_BLOCK_VALUE, float(GetAmount()), apply);
|
||||
}
|
||||
|
||||
if (target->IsPlayer())
|
||||
target->ToPlayer()->HandleBaseModValue(SHIELD_BLOCK_VALUE, modType, float(GetAmount()), apply);
|
||||
void AuraEffect::HandleShieldBlockValuePercent(AuraApplication const* aurApp, uint8 mode, bool apply) const
|
||||
{
|
||||
if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
|
||||
return;
|
||||
|
||||
Player* target = aurApp->GetTarget()->ToPlayer();
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
if (apply)
|
||||
target->ApplyBaseModPctValue(SHIELD_BLOCK_VALUE, float(GetAmount()));
|
||||
else
|
||||
{
|
||||
float amount = target->GetTotalAuraMultiplier(SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT);
|
||||
target->SetBaseModPctValue(SHIELD_BLOCK_VALUE, amount);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************/
|
||||
|
||||
Reference in New Issue
Block a user