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:
@@ -38,6 +38,7 @@
|
||||
#include "PoolMgr.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "SpellAuraDefines.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "TemporarySummon.h"
|
||||
@@ -601,13 +602,13 @@ bool Creature::UpdateEntry(uint32 Entry, const CreatureData* data, bool changele
|
||||
SetMeleeDamageSchool(SpellSchools(cInfo->dmgschool));
|
||||
CreatureBaseStats const* stats = sObjectMgr->GetCreatureBaseStats(GetLevel(), cInfo->unit_class);
|
||||
float armor = stats->GenerateArmor(cInfo);
|
||||
SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, armor);
|
||||
SetModifierValue(UNIT_MOD_RESISTANCE_HOLY, BASE_VALUE, float(cInfo->resistance[SPELL_SCHOOL_HOLY]));
|
||||
SetModifierValue(UNIT_MOD_RESISTANCE_FIRE, BASE_VALUE, float(cInfo->resistance[SPELL_SCHOOL_FIRE]));
|
||||
SetModifierValue(UNIT_MOD_RESISTANCE_NATURE, BASE_VALUE, float(cInfo->resistance[SPELL_SCHOOL_NATURE]));
|
||||
SetModifierValue(UNIT_MOD_RESISTANCE_FROST, BASE_VALUE, float(cInfo->resistance[SPELL_SCHOOL_FROST]));
|
||||
SetModifierValue(UNIT_MOD_RESISTANCE_SHADOW, BASE_VALUE, float(cInfo->resistance[SPELL_SCHOOL_SHADOW]));
|
||||
SetModifierValue(UNIT_MOD_RESISTANCE_ARCANE, BASE_VALUE, float(cInfo->resistance[SPELL_SCHOOL_ARCANE]));
|
||||
SetStatFlatModifier(UNIT_MOD_ARMOR, BASE_VALUE, armor);
|
||||
SetStatFlatModifier(UNIT_MOD_RESISTANCE_HOLY, BASE_VALUE, float(cInfo->resistance[SPELL_SCHOOL_HOLY]));
|
||||
SetStatFlatModifier(UNIT_MOD_RESISTANCE_FIRE, BASE_VALUE, float(cInfo->resistance[SPELL_SCHOOL_FIRE]));
|
||||
SetStatFlatModifier(UNIT_MOD_RESISTANCE_NATURE, BASE_VALUE, float(cInfo->resistance[SPELL_SCHOOL_NATURE]));
|
||||
SetStatFlatModifier(UNIT_MOD_RESISTANCE_FROST, BASE_VALUE, float(cInfo->resistance[SPELL_SCHOOL_FROST]));
|
||||
SetStatFlatModifier(UNIT_MOD_RESISTANCE_SHADOW, BASE_VALUE, float(cInfo->resistance[SPELL_SCHOOL_SHADOW]));
|
||||
SetStatFlatModifier(UNIT_MOD_RESISTANCE_ARCANE, BASE_VALUE, float(cInfo->resistance[SPELL_SCHOOL_ARCANE]));
|
||||
|
||||
SetCanModifyStats(true);
|
||||
UpdateAllStats();
|
||||
@@ -1017,10 +1018,7 @@ void Creature::Regenerate(Powers power)
|
||||
}
|
||||
|
||||
// Apply modifiers (if any).
|
||||
AuraEffectList const& ModPowerRegenPCTAuras = GetAuraEffectsByType(SPELL_AURA_MOD_POWER_REGEN_PERCENT);
|
||||
for (AuraEffectList::const_iterator i = ModPowerRegenPCTAuras.begin(); i != ModPowerRegenPCTAuras.end(); ++i)
|
||||
if (Powers((*i)->GetMiscValue()) == power)
|
||||
AddPct(addvalue, (*i)->GetAmount());
|
||||
addvalue *= GetTotalAuraMultiplierByMiscValue(SPELL_AURA_MOD_POWER_REGEN_PERCENT, power);
|
||||
|
||||
addvalue += GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, power) * (power == POWER_FOCUS ? PET_FOCUS_REGEN_INTERVAL.count() : CREATURE_REGEN_INTERVAL) / (5 * IN_MILLISECONDS);
|
||||
|
||||
@@ -1056,9 +1054,7 @@ void Creature::RegenerateHealth()
|
||||
}
|
||||
|
||||
// Apply modifiers (if any).
|
||||
AuraEffectList const& ModPowerRegenPCTAuras = GetAuraEffectsByType(SPELL_AURA_MOD_HEALTH_REGEN_PERCENT);
|
||||
for (AuraEffectList::const_iterator i = ModPowerRegenPCTAuras.begin(); i != ModPowerRegenPCTAuras.end(); ++i)
|
||||
AddPct(addvalue, (*i)->GetAmount());
|
||||
addvalue *= GetTotalAuraMultiplier(SPELL_AURA_MOD_HEALTH_REGEN_PERCENT);
|
||||
|
||||
addvalue += GetTotalAuraModifier(SPELL_AURA_MOD_REGEN) * CREATURE_REGEN_INTERVAL / (5 * IN_MILLISECONDS);
|
||||
|
||||
@@ -1558,8 +1554,8 @@ void Creature::SelectLevel(bool changelevel)
|
||||
|
||||
/// @todo: set UNIT_FIELD_POWER*, for some creature class case (energy, etc)
|
||||
|
||||
SetModifierValue(UNIT_MOD_HEALTH, BASE_VALUE, (float)health);
|
||||
SetModifierValue(UNIT_MOD_MANA, BASE_VALUE, (float)mana);
|
||||
SetStatFlatModifier(UNIT_MOD_HEALTH, BASE_VALUE, (float)health);
|
||||
SetStatFlatModifier(UNIT_MOD_MANA, BASE_VALUE, (float)mana);
|
||||
|
||||
// damage
|
||||
|
||||
@@ -1577,8 +1573,8 @@ void Creature::SelectLevel(bool changelevel)
|
||||
SetBaseWeaponDamage(RANGED_ATTACK, MINDAMAGE, weaponBaseMinDamage);
|
||||
SetBaseWeaponDamage(RANGED_ATTACK, MAXDAMAGE, weaponBaseMaxDamage);
|
||||
|
||||
SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, stats->AttackPower);
|
||||
SetModifierValue(UNIT_MOD_ATTACK_POWER_RANGED, BASE_VALUE, stats->RangedAttackPower);
|
||||
SetStatFlatModifier(UNIT_MOD_ATTACK_POWER, BASE_VALUE, stats->AttackPower);
|
||||
SetStatFlatModifier(UNIT_MOD_ATTACK_POWER_RANGED, BASE_VALUE, stats->RangedAttackPower);
|
||||
|
||||
sScriptMgr->OnCreatureSelectLevel(cInfo, this);
|
||||
}
|
||||
|
||||
@@ -815,13 +815,6 @@ void Object::ApplyModSignedFloatValue(uint16 index, float val, bool apply)
|
||||
SetFloatValue(index, cur);
|
||||
}
|
||||
|
||||
void Object::ApplyPercentModFloatValue(uint16 index, float val, bool apply)
|
||||
{
|
||||
float value = GetFloatValue(index);
|
||||
ApplyPercentModFloatVar(value, val, apply);
|
||||
SetFloatValue(index, value);
|
||||
}
|
||||
|
||||
void Object::ApplyModPositiveFloatValue(uint16 index, float val, bool apply)
|
||||
{
|
||||
float cur = GetFloatValue(index);
|
||||
|
||||
@@ -165,7 +165,6 @@ public:
|
||||
void ApplyModUInt64Value(uint16 index, int32 val, bool apply);
|
||||
void ApplyModPositiveFloatValue(uint16 index, float val, bool apply);
|
||||
void ApplyModSignedFloatValue(uint16 index, float val, bool apply);
|
||||
void ApplyPercentModFloatValue(uint16 index, float val, bool apply);
|
||||
|
||||
void SetFlag(uint16 index, uint32 newFlag);
|
||||
void RemoveFlag(uint16 index, uint32 oldFlag);
|
||||
|
||||
@@ -1075,7 +1075,7 @@ bool Guardian::InitStatsForLevel(uint8 petlevel)
|
||||
SetMeleeDamageSchool(SpellSchools(cinfo->dmgschool));
|
||||
}
|
||||
|
||||
SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, float(petlevel * 50));
|
||||
SetStatFlatModifier(UNIT_MOD_ARMOR, BASE_VALUE, float(petlevel * 50));
|
||||
|
||||
uint32 attackTime = BASE_ATTACK_TIME;
|
||||
if (!owner->IsClass(CLASS_HUNTER, CLASS_CONTEXT_PET) && cinfo->BaseAttackTime >= 1000)
|
||||
@@ -1094,7 +1094,7 @@ bool Guardian::InitStatsForLevel(uint8 petlevel)
|
||||
// xinef: hunter pets should not inherit template resistances
|
||||
if (!IsHunterPet())
|
||||
for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
|
||||
SetModifierValue(UnitMods(UNIT_MOD_RESISTANCE_START + i), BASE_VALUE, float(cinfo->resistance[i]));
|
||||
SetStatFlatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), BASE_VALUE, float(cinfo->resistance[i]));
|
||||
|
||||
//health, mana, armor and resistance
|
||||
PetLevelInfo const* pInfo = sObjectMgr->GetPetLevelInfo(creature_ID, petlevel);
|
||||
@@ -1111,15 +1111,15 @@ bool Guardian::InitStatsForLevel(uint8 petlevel)
|
||||
}
|
||||
|
||||
SetCreateHealth(pInfo->health*factorHealth);
|
||||
SetModifierValue(UNIT_MOD_HEALTH, BASE_VALUE, (float)pInfo->health);
|
||||
SetStatFlatModifier(UNIT_MOD_HEALTH, BASE_VALUE, (float)pInfo->health);
|
||||
if (petType != HUNTER_PET) //hunter pet use focus
|
||||
{
|
||||
SetCreateMana(pInfo->mana);
|
||||
SetModifierValue(UNIT_MOD_MANA, BASE_VALUE, (float)pInfo->mana);
|
||||
SetStatFlatModifier(UNIT_MOD_MANA, BASE_VALUE, (float)pInfo->mana);
|
||||
}
|
||||
|
||||
if (pInfo->armor > 0)
|
||||
SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, float(pInfo->armor));
|
||||
SetStatFlatModifier(UNIT_MOD_ARMOR, BASE_VALUE, float(pInfo->armor));
|
||||
|
||||
for (uint8 stat = 0; stat < MAX_STATS; ++stat)
|
||||
SetCreateStat(Stats(stat), float(pInfo->stats[stat]));
|
||||
@@ -1138,9 +1138,9 @@ bool Guardian::InitStatsForLevel(uint8 petlevel)
|
||||
}
|
||||
|
||||
SetCreateHealth(std::max<uint32>(1, stats->BaseHealth[cinfo->expansion]*factorHealth));
|
||||
SetModifierValue(UNIT_MOD_HEALTH, BASE_VALUE, GetCreateHealth());
|
||||
SetStatFlatModifier(UNIT_MOD_HEALTH, BASE_VALUE, GetCreateHealth());
|
||||
SetCreateMana(stats->BaseMana * factorMana);
|
||||
SetModifierValue(UNIT_MOD_MANA, BASE_VALUE, GetCreateMana());
|
||||
SetStatFlatModifier(UNIT_MOD_MANA, BASE_VALUE, GetCreateMana());
|
||||
|
||||
// xinef: added some multipliers so debuffs can affect pets in any way...
|
||||
SetCreateStat(STAT_STRENGTH, 22);
|
||||
@@ -1174,24 +1174,6 @@ bool Guardian::InitStatsForLevel(uint8 petlevel)
|
||||
|
||||
switch (GetEntry())
|
||||
{
|
||||
case NPC_FELGUARD:
|
||||
{
|
||||
// xinef: Glyph of Felguard, so ugly im crying... no appropriate spell
|
||||
if (AuraEffect* aurEff = owner->GetAuraEffectDummy(SPELL_GLYPH_OF_FELGUARD))
|
||||
{
|
||||
HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_PCT, aurEff->GetAmount(), true);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case NPC_VOIDWALKER:
|
||||
{
|
||||
if (AuraEffect* aurEff = owner->GetAuraEffectDummy(SPELL_GLYPH_OF_VOIDWALKER))
|
||||
{
|
||||
HandleStatModifier(UNIT_MOD_STAT_STAMINA, TOTAL_PCT, aurEff->GetAmount(), true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NPC_WATER_ELEMENTAL_PERM:
|
||||
{
|
||||
AddAura(SPELL_PET_AVOIDANCE, this);
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "Pet.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SpellAuraDefines.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
|
||||
// KillRewarder incapsulates logic of rewarding player upon kill with:
|
||||
@@ -162,9 +163,7 @@ void KillRewarder::_RewardXP(Player* player, float rate)
|
||||
if (xp)
|
||||
{
|
||||
// 4.2.2. Apply auras modifying rewarded XP (SPELL_AURA_MOD_XP_PCT).
|
||||
Unit::AuraEffectList const& auras = player->GetAuraEffectsByType(SPELL_AURA_MOD_XP_PCT);
|
||||
for (Unit::AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i)
|
||||
AddPct(xp, (*i)->GetAmount());
|
||||
xp *= player->GetTotalAuraMultiplier(SPELL_AURA_MOD_XP_PCT);
|
||||
|
||||
// 4.2.3. Give XP to player.
|
||||
sScriptMgr->OnPlayerGiveXP(player, xp, _victim, PlayerXPSource::XPSOURCE_KILL);
|
||||
|
||||
@@ -69,8 +69,10 @@
|
||||
#include "Realm.h"
|
||||
#include "ReputationMgr.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "SocialMgr.h"
|
||||
#include "Spell.h"
|
||||
#include "SpellAuraDefines.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellMgr.h"
|
||||
@@ -312,8 +314,8 @@ Player::Player(WorldSession* session): Unit(), m_mover(this)
|
||||
|
||||
for (uint8 i = 0; i < BASEMOD_END; ++i)
|
||||
{
|
||||
m_auraBaseMod[i][FLAT_MOD] = 0.0f;
|
||||
m_auraBaseMod[i][PCT_MOD] = 1.0f;
|
||||
m_auraBaseFlatMod[i] = 0.0f;
|
||||
m_auraBasePctMod[i] = 1.0f;
|
||||
}
|
||||
|
||||
for (uint8 i = 0; i < MAX_COMBAT_RATING; i++)
|
||||
@@ -831,9 +833,7 @@ int32 Player::getMaxTimer(MirrorTimerType timer)
|
||||
if (!IsAlive() || HasWaterBreathingAura() || GetSession()->GetSecurity() >= AccountTypes(sWorld->getIntConfig(CONFIG_DISABLE_BREATHING)))
|
||||
return DISABLED_MIRROR_TIMER;
|
||||
int32 UnderWaterTime = sWorld->getIntConfig(CONFIG_WATER_BREATH_TIMER);
|
||||
AuraEffectList const& mModWaterBreathing = GetAuraEffectsByType(SPELL_AURA_MOD_WATER_BREATHING);
|
||||
for (AuraEffectList::const_iterator i = mModWaterBreathing.begin(); i != mModWaterBreathing.end(); ++i)
|
||||
AddPct(UnderWaterTime, (*i)->GetAmount());
|
||||
UnderWaterTime *= GetTotalAuraMultiplier(SPELL_AURA_MOD_WATER_BREATHING);
|
||||
return UnderWaterTime;
|
||||
}
|
||||
case FIRE_TIMER:
|
||||
@@ -1922,10 +1922,7 @@ void Player::Regenerate(Powers power)
|
||||
// Mana regen calculated in Player::UpdateManaRegen(), energy regen calculated in Player::UpdateEnergyRegen()
|
||||
if (power != POWER_MANA && power != POWER_ENERGY)
|
||||
{
|
||||
AuraEffectList const& ModPowerRegenPCTAuras = GetAuraEffectsByType(SPELL_AURA_MOD_POWER_REGEN_PERCENT);
|
||||
for (AuraEffectList::const_iterator i = ModPowerRegenPCTAuras.begin(); i != ModPowerRegenPCTAuras.end(); ++i)
|
||||
if (Powers((*i)->GetMiscValue()) == power)
|
||||
AddPct(addvalue, (*i)->GetAmount());
|
||||
addvalue *= GetTotalAuraMultiplierByMiscValue(SPELL_AURA_MOD_POWER_REGEN_PERCENT, power);
|
||||
|
||||
// Butchery requires combat for this effect
|
||||
if (power != POWER_RUNIC_POWER || IsInCombat())
|
||||
@@ -2008,11 +2005,7 @@ void Player::RegenerateHealth()
|
||||
addvalue *= 1.33f;
|
||||
}
|
||||
|
||||
AuraEffectList const& mModHealthRegenPct = GetAuraEffectsByType(SPELL_AURA_MOD_HEALTH_REGEN_PERCENT);
|
||||
for (AuraEffectList::const_iterator i = mModHealthRegenPct.begin(); i != mModHealthRegenPct.end(); ++i)
|
||||
{
|
||||
AddPct(addvalue, (*i)->GetAmount());
|
||||
}
|
||||
addvalue *= GetTotalAuraMultiplier(SPELL_AURA_MOD_HEALTH_REGEN_PERCENT);
|
||||
|
||||
if (!IsInCombat())
|
||||
{
|
||||
@@ -2666,14 +2659,14 @@ void Player::InitStatsForLevel(bool reapplyMods)
|
||||
|
||||
// set armor (resistance 0) to original value (create_agility*2)
|
||||
SetArmor(int32(m_createStats[STAT_AGILITY] * 2));
|
||||
SetResistanceBuffMods(SpellSchools(0), true, 0.0f);
|
||||
SetResistanceBuffMods(SpellSchools(0), false, 0.0f);
|
||||
SetFloatValue(UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE + AsUnderlyingType(SPELL_SCHOOL_NORMAL), 0.0f);
|
||||
SetFloatValue(UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE + AsUnderlyingType(SPELL_SCHOOL_NORMAL), 0.0f);
|
||||
// set other resistance to original value (0)
|
||||
for (uint8 i = 1; i < MAX_SPELL_SCHOOL; ++i)
|
||||
{
|
||||
SetResistance(SpellSchools(i), 0);
|
||||
SetResistanceBuffMods(SpellSchools(i), true, 0.0f);
|
||||
SetResistanceBuffMods(SpellSchools(i), false, 0.0f);
|
||||
SetFloatValue(UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE + i, 0.0f);
|
||||
SetFloatValue(UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE + i, 0.0f);
|
||||
}
|
||||
|
||||
SetUInt32Value(PLAYER_FIELD_MOD_TARGET_RESISTANCE, 0);
|
||||
@@ -5012,24 +5005,107 @@ void Player::ClearChannelWatch()
|
||||
(*itr)->RemoveWatching(this);
|
||||
}
|
||||
|
||||
void Player::HandleBaseModValue(BaseModGroup modGroup, BaseModType modType, float amount, bool apply)
|
||||
void Player::HandleBaseModFlatValue(BaseModGroup modGroup, float amount, bool apply)
|
||||
{
|
||||
if (modGroup >= BASEMOD_END)
|
||||
{
|
||||
LOG_ERROR("entities.player", "ERROR in HandleBaseModValue(): non existed BaseModGroup!");
|
||||
LOG_ERROR("entities.player", "Player::HandleBaseModFlatValue: Invalid BaseModGroup/BaseModType ({}/{}) for player '{}' ({})",
|
||||
modGroup, FLAT_MOD, GetName(), GetGUID().ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
switch (modType)
|
||||
m_auraBaseFlatMod[modGroup] += apply ? amount : -amount;
|
||||
UpdateBaseModGroup(modGroup);
|
||||
}
|
||||
|
||||
void Player::ApplyBaseModPctValue(BaseModGroup modGroup, float pct)
|
||||
{
|
||||
if (modGroup >= BASEMOD_END)
|
||||
{
|
||||
case FLAT_MOD:
|
||||
m_auraBaseMod[modGroup][modType] += apply ? amount : -amount;
|
||||
LOG_ERROR("entities.player", "Player::ApplyBaseModPctValue: Invalid BaseModGroup/BaseModType ({}/{}) for player '{}' ({})",
|
||||
modGroup, PCT_MOD, GetName(), GetGUID().ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
m_auraBasePctMod[modGroup] += CalculatePct(1.0f, pct);
|
||||
UpdateBaseModGroup(modGroup);
|
||||
}
|
||||
|
||||
void Player::SetBaseModFlatValue(BaseModGroup modGroup, float val)
|
||||
{
|
||||
if (m_auraBaseFlatMod[modGroup] == val)
|
||||
return;
|
||||
|
||||
m_auraBaseFlatMod[modGroup] = val;
|
||||
UpdateBaseModGroup(modGroup);
|
||||
}
|
||||
|
||||
void Player::SetBaseModPctValue(BaseModGroup modGroup, float val)
|
||||
{
|
||||
if (m_auraBasePctMod[modGroup] == val)
|
||||
return;
|
||||
|
||||
m_auraBasePctMod[modGroup] = val;
|
||||
UpdateBaseModGroup(modGroup);
|
||||
}
|
||||
|
||||
void Player::UpdateDamageDoneMods(WeaponAttackType attackType, int32 skipEnchantSlot /*= -1*/)
|
||||
{
|
||||
Unit::UpdateDamageDoneMods(attackType, skipEnchantSlot);
|
||||
|
||||
UnitMods unitMod;
|
||||
switch (attackType)
|
||||
{
|
||||
case BASE_ATTACK:
|
||||
unitMod = UNIT_MOD_DAMAGE_MAINHAND;
|
||||
break;
|
||||
case PCT_MOD:
|
||||
ApplyPercentModFloatVar(m_auraBaseMod[modGroup][modType], amount, apply);
|
||||
case OFF_ATTACK:
|
||||
unitMod = UNIT_MOD_DAMAGE_OFFHAND;
|
||||
break;
|
||||
case RANGED_ATTACK:
|
||||
unitMod = UNIT_MOD_DAMAGE_RANGED;
|
||||
break;
|
||||
default:
|
||||
ABORT();
|
||||
break;
|
||||
}
|
||||
|
||||
float amount = 0.0f;
|
||||
Item* item = GetWeaponForAttack(attackType, true);
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
for (uint8 slot = 0; slot < MAX_ENCHANTMENT_SLOT; ++slot)
|
||||
{
|
||||
if (skipEnchantSlot == slot)
|
||||
continue;
|
||||
|
||||
SpellItemEnchantmentEntry const* enchantmentEntry = sSpellItemEnchantmentStore.LookupEntry(item->GetEnchantmentId(EnchantmentSlot(slot)));
|
||||
if (!enchantmentEntry)
|
||||
continue;
|
||||
|
||||
for (uint8 i = 0; i < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++i)
|
||||
{
|
||||
switch (enchantmentEntry->type[i])
|
||||
{
|
||||
case ITEM_ENCHANTMENT_TYPE_DAMAGE:
|
||||
amount += enchantmentEntry->amount[i];
|
||||
break;
|
||||
case ITEM_ENCHANTMENT_TYPE_TOTEM:
|
||||
if (IsClass(CLASS_SHAMAN, CLASS_CONTEXT_ABILITY))
|
||||
amount += enchantmentEntry->amount[i] * item->GetTemplate()->Delay / 1000.0f;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HandleStatFlatModifier(unitMod, TOTAL_VALUE, amount, true);
|
||||
}
|
||||
|
||||
void Player::UpdateBaseModGroup(BaseModGroup modGroup)
|
||||
{
|
||||
if (!CanModifyStats())
|
||||
return;
|
||||
|
||||
@@ -5060,10 +5136,7 @@ float Player::GetBaseModValue(BaseModGroup modGroup, BaseModType modType) const
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
if (modType == PCT_MOD && m_auraBaseMod[modGroup][PCT_MOD] <= 0.0f)
|
||||
return 0.0f;
|
||||
|
||||
return m_auraBaseMod[modGroup][modType];
|
||||
return (modType == FLAT_MOD ? m_auraBaseFlatMod[modGroup] : m_auraBasePctMod[modGroup]);
|
||||
}
|
||||
|
||||
float Player::GetTotalBaseModValue(BaseModGroup modGroup) const
|
||||
@@ -5074,15 +5147,15 @@ float Player::GetTotalBaseModValue(BaseModGroup modGroup) const
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
if (m_auraBaseMod[modGroup][PCT_MOD] <= 0.0f)
|
||||
if (m_auraBasePctMod[modGroup] <= 0.0f)
|
||||
return 0.0f;
|
||||
|
||||
return m_auraBaseMod[modGroup][FLAT_MOD] * m_auraBaseMod[modGroup][PCT_MOD];
|
||||
return m_auraBaseFlatMod[modGroup] * m_auraBasePctMod[modGroup];
|
||||
}
|
||||
|
||||
uint32 Player::GetShieldBlockValue() const
|
||||
{
|
||||
float value = (m_auraBaseMod[SHIELD_BLOCK_VALUE][FLAT_MOD] + GetStat(STAT_STRENGTH) * 0.5f - 10) * m_auraBaseMod[SHIELD_BLOCK_VALUE][PCT_MOD];
|
||||
float value = (m_auraBaseFlatMod[SHIELD_BLOCK_VALUE] + GetStat(STAT_STRENGTH) * 0.5f - 10) * m_auraBasePctMod[SHIELD_BLOCK_VALUE];
|
||||
|
||||
value = (value < 0) ? 0 : value;
|
||||
|
||||
@@ -5151,7 +5224,7 @@ void Player::GetDodgeFromAgility(float& diminishing, float& nondiminishing)
|
||||
return;
|
||||
|
||||
/// @todo: research if talents/effects that increase total agility by x% should increase non-diminishing part
|
||||
float base_agility = GetCreateStat(STAT_AGILITY) * m_auraModifiersGroup[UNIT_MOD_STAT_START + static_cast<uint16>(STAT_AGILITY)][BASE_PCT];
|
||||
float base_agility = GetCreateStat(STAT_AGILITY) * GetPctModifierValue(UnitMods(UNIT_MOD_STAT_START + AsUnderlyingType(STAT_AGILITY)), BASE_PCT);
|
||||
float bonus_agility = GetStat(STAT_AGILITY) - base_agility;
|
||||
|
||||
// calculate diminishing (green in char screen) and non-diminishing (white) contribution
|
||||
@@ -6574,20 +6647,22 @@ void Player::_ApplyItemMods(Item* item, uint8 slot, bool apply)
|
||||
|
||||
LOG_DEBUG("entities.player", "applying mods for item {} ", item->GetGUID().ToString());
|
||||
|
||||
WeaponAttackType attacktype = Player::GetAttackBySlot(slot);
|
||||
|
||||
if (item->HasSocket()) //only (un)equipping of items with sockets can influence metagems, so no need to waste time with normal items
|
||||
CorrectMetaGemEnchants(slot, apply);
|
||||
|
||||
if (attacktype < MAX_ATTACK)
|
||||
_ApplyWeaponDependentAuraMods(item, attacktype, apply);
|
||||
|
||||
_ApplyItemBonuses(proto, slot, apply);
|
||||
|
||||
if (slot == EQUIPMENT_SLOT_RANGED)
|
||||
_ApplyAmmoBonuses();
|
||||
|
||||
ApplyItemEquipSpell(item, apply);
|
||||
|
||||
ApplyItemDependentAuras(item, apply);
|
||||
|
||||
WeaponAttackType const attackType = Player::GetAttackBySlot(slot);
|
||||
if (attackType != MAX_ATTACK)
|
||||
UpdateWeaponDependentAuras(attackType);
|
||||
|
||||
ApplyEnchantment(item, apply);
|
||||
|
||||
LOG_DEBUG("entities.player.items", "_ApplyItemMods complete.");
|
||||
@@ -6658,30 +6733,30 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply
|
||||
switch (statType)
|
||||
{
|
||||
case ITEM_MOD_MANA:
|
||||
HandleStatModifier(UNIT_MOD_MANA, BASE_VALUE, float(val), apply);
|
||||
HandleStatFlatModifier(UNIT_MOD_MANA, BASE_VALUE, float(val), apply);
|
||||
break;
|
||||
case ITEM_MOD_HEALTH: // modify HP
|
||||
HandleStatModifier(UNIT_MOD_HEALTH, BASE_VALUE, float(val), apply);
|
||||
HandleStatFlatModifier(UNIT_MOD_HEALTH, BASE_VALUE, float(val), apply);
|
||||
break;
|
||||
case ITEM_MOD_AGILITY: // modify agility
|
||||
HandleStatModifier(UNIT_MOD_STAT_AGILITY, BASE_VALUE, float(val), apply);
|
||||
ApplyStatBuffMod(STAT_AGILITY, float(val), apply);
|
||||
HandleStatFlatModifier(UNIT_MOD_STAT_AGILITY, BASE_VALUE, float(val), apply);
|
||||
UpdateStatBuffMod(STAT_AGILITY);
|
||||
break;
|
||||
case ITEM_MOD_STRENGTH: //modify strength
|
||||
HandleStatModifier(UNIT_MOD_STAT_STRENGTH, BASE_VALUE, float(val), apply);
|
||||
ApplyStatBuffMod(STAT_STRENGTH, float(val), apply);
|
||||
HandleStatFlatModifier(UNIT_MOD_STAT_STRENGTH, BASE_VALUE, float(val), apply);
|
||||
UpdateStatBuffMod(STAT_STRENGTH);
|
||||
break;
|
||||
case ITEM_MOD_INTELLECT: //modify intellect
|
||||
HandleStatModifier(UNIT_MOD_STAT_INTELLECT, BASE_VALUE, float(val), apply);
|
||||
ApplyStatBuffMod(STAT_INTELLECT, float(val), apply);
|
||||
HandleStatFlatModifier(UNIT_MOD_STAT_INTELLECT, BASE_VALUE, float(val), apply);
|
||||
UpdateStatBuffMod(STAT_INTELLECT);
|
||||
break;
|
||||
case ITEM_MOD_SPIRIT: //modify spirit
|
||||
HandleStatModifier(UNIT_MOD_STAT_SPIRIT, BASE_VALUE, float(val), apply);
|
||||
ApplyStatBuffMod(STAT_SPIRIT, float(val), apply);
|
||||
HandleStatFlatModifier(UNIT_MOD_STAT_SPIRIT, BASE_VALUE, float(val), apply);
|
||||
UpdateStatBuffMod(STAT_SPIRIT);
|
||||
break;
|
||||
case ITEM_MOD_STAMINA: //modify stamina
|
||||
HandleStatModifier(UNIT_MOD_STAT_STAMINA, BASE_VALUE, float(val), apply);
|
||||
ApplyStatBuffMod(STAT_STAMINA, float(val), apply);
|
||||
HandleStatFlatModifier(UNIT_MOD_STAT_STAMINA, BASE_VALUE, float(val), apply);
|
||||
UpdateStatBuffMod(STAT_STAMINA);
|
||||
break;
|
||||
case ITEM_MOD_DEFENSE_SKILL_RATING:
|
||||
ApplyRatingMod(CR_DEFENSE_SKILL, int32(val), apply);
|
||||
@@ -6770,11 +6845,11 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply
|
||||
ApplyRatingMod(CR_EXPERTISE, int32(val), apply);
|
||||
break;
|
||||
case ITEM_MOD_ATTACK_POWER:
|
||||
HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(val), apply);
|
||||
HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(val), apply);
|
||||
HandleStatFlatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(val), apply);
|
||||
HandleStatFlatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(val), apply);
|
||||
break;
|
||||
case ITEM_MOD_RANGED_ATTACK_POWER:
|
||||
HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(val), apply);
|
||||
HandleStatFlatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(val), apply);
|
||||
break;
|
||||
// case ITEM_MOD_FERAL_ATTACK_POWER:
|
||||
// ApplyFeralAPBonus(int32(val), apply);
|
||||
@@ -6795,7 +6870,7 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply
|
||||
ApplySpellPenetrationBonus(val, apply);
|
||||
break;
|
||||
case ITEM_MOD_BLOCK_VALUE:
|
||||
HandleBaseModValue(SHIELD_BLOCK_VALUE, FLAT_MOD, float(val), apply);
|
||||
HandleBaseModFlatValue(SHIELD_BLOCK_VALUE, float(val), apply);
|
||||
break;
|
||||
/// @deprecated item mods
|
||||
case ITEM_MOD_SPELL_HEALING_DONE:
|
||||
@@ -6825,7 +6900,7 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply
|
||||
|
||||
if (armor)
|
||||
{
|
||||
UnitModifierType modType = TOTAL_VALUE;
|
||||
UnitModifierFlatType modType = TOTAL_VALUE;
|
||||
if (proto->Class == ITEM_CLASS_ARMOR)
|
||||
{
|
||||
switch (proto->SubClass)
|
||||
@@ -6839,33 +6914,33 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply
|
||||
break;
|
||||
}
|
||||
}
|
||||
HandleStatModifier(UNIT_MOD_ARMOR, modType, float(armor), apply);
|
||||
HandleStatFlatModifier(UNIT_MOD_ARMOR, modType, float(armor), apply);
|
||||
}
|
||||
|
||||
// Add armor bonus from ArmorDamageModifier if > 0
|
||||
if (proto->ArmorDamageModifier > 0 && sScriptMgr->OnPlayerCanArmorDamageModifier(this))
|
||||
HandleStatModifier(UNIT_MOD_ARMOR, TOTAL_VALUE, float(proto->ArmorDamageModifier), apply);
|
||||
HandleStatFlatModifier(UNIT_MOD_ARMOR, TOTAL_VALUE, float(proto->ArmorDamageModifier), apply);
|
||||
|
||||
if (proto->Block)
|
||||
HandleBaseModValue(SHIELD_BLOCK_VALUE, FLAT_MOD, float(proto->Block), apply);
|
||||
HandleBaseModFlatValue(SHIELD_BLOCK_VALUE, float(proto->Block), apply);
|
||||
|
||||
if (proto->HolyRes)
|
||||
HandleStatModifier(UNIT_MOD_RESISTANCE_HOLY, BASE_VALUE, float(proto->HolyRes), apply);
|
||||
HandleStatFlatModifier(UNIT_MOD_RESISTANCE_HOLY, BASE_VALUE, float(proto->HolyRes), apply);
|
||||
|
||||
if (proto->FireRes)
|
||||
HandleStatModifier(UNIT_MOD_RESISTANCE_FIRE, BASE_VALUE, float(proto->FireRes), apply);
|
||||
HandleStatFlatModifier(UNIT_MOD_RESISTANCE_FIRE, BASE_VALUE, float(proto->FireRes), apply);
|
||||
|
||||
if (proto->NatureRes)
|
||||
HandleStatModifier(UNIT_MOD_RESISTANCE_NATURE, BASE_VALUE, float(proto->NatureRes), apply);
|
||||
HandleStatFlatModifier(UNIT_MOD_RESISTANCE_NATURE, BASE_VALUE, float(proto->NatureRes), apply);
|
||||
|
||||
if (proto->FrostRes)
|
||||
HandleStatModifier(UNIT_MOD_RESISTANCE_FROST, BASE_VALUE, float(proto->FrostRes), apply);
|
||||
HandleStatFlatModifier(UNIT_MOD_RESISTANCE_FROST, BASE_VALUE, float(proto->FrostRes), apply);
|
||||
|
||||
if (proto->ShadowRes)
|
||||
HandleStatModifier(UNIT_MOD_RESISTANCE_SHADOW, BASE_VALUE, float(proto->ShadowRes), apply);
|
||||
HandleStatFlatModifier(UNIT_MOD_RESISTANCE_SHADOW, BASE_VALUE, float(proto->ShadowRes), apply);
|
||||
|
||||
if (proto->ArcaneRes)
|
||||
HandleStatModifier(UNIT_MOD_RESISTANCE_ARCANE, BASE_VALUE, float(proto->ArcaneRes), apply);
|
||||
HandleStatFlatModifier(UNIT_MOD_RESISTANCE_ARCANE, BASE_VALUE, float(proto->ArcaneRes), apply);
|
||||
|
||||
WeaponAttackType attType = Player::GetAttackBySlot(slot);
|
||||
if (attType != MAX_ATTACK)
|
||||
@@ -7036,6 +7111,84 @@ void Player::UpdateItemObtainSpells(Item* item, uint8 bag, uint8 slot)
|
||||
ApplyItemObtainSpells(item, true);
|
||||
}
|
||||
|
||||
// this one rechecks weapon auras and stores them in BaseModGroup container
|
||||
// needed for things like axe specialization applying only to axe weapons in case of dual-wield
|
||||
void Player::UpdateWeaponDependentCritAuras(WeaponAttackType attackType)
|
||||
{
|
||||
BaseModGroup modGroup;
|
||||
switch (attackType)
|
||||
{
|
||||
case BASE_ATTACK:
|
||||
modGroup = CRIT_PERCENTAGE;
|
||||
break;
|
||||
case OFF_ATTACK:
|
||||
modGroup = OFFHAND_CRIT_PERCENTAGE;
|
||||
break;
|
||||
case RANGED_ATTACK:
|
||||
modGroup = RANGED_CRIT_PERCENTAGE;
|
||||
break;
|
||||
default:
|
||||
ABORT();
|
||||
break;
|
||||
}
|
||||
|
||||
float amount = 0.0f;
|
||||
amount += GetTotalAuraModifier(SPELL_AURA_MOD_WEAPON_CRIT_PERCENT, std::bind(&Unit::CheckAttackFitToAuraRequirement, this, attackType, std::placeholders::_1));
|
||||
|
||||
// these auras don't have item requirement (only Combat Expertise in 3.3.5a)
|
||||
amount += GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_PCT);
|
||||
|
||||
SetBaseModFlatValue(modGroup, amount);
|
||||
}
|
||||
|
||||
void Player::UpdateAllWeaponDependentCritAuras()
|
||||
{
|
||||
for (uint8 i = BASE_ATTACK; i < MAX_ATTACK; ++i)
|
||||
UpdateWeaponDependentCritAuras(WeaponAttackType(i));
|
||||
}
|
||||
|
||||
void Player::UpdateWeaponDependentAuras(WeaponAttackType attackType)
|
||||
{
|
||||
UpdateWeaponDependentCritAuras(attackType);
|
||||
UpdateDamageDoneMods(attackType);
|
||||
UpdateDamagePctDoneMods(attackType);
|
||||
}
|
||||
|
||||
void Player::ApplyItemDependentAuras(Item* item, bool apply)
|
||||
{
|
||||
if (apply)
|
||||
{
|
||||
PlayerSpellMap const& spells = GetSpellMap();
|
||||
for (auto itr = spells.begin(); itr != spells.end(); ++itr)
|
||||
{
|
||||
if (itr->second->State == PLAYERSPELL_REMOVED)
|
||||
continue;
|
||||
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first);
|
||||
if (!spellInfo || !spellInfo->IsPassive() || spellInfo->EquippedItemClass < 0)
|
||||
continue;
|
||||
|
||||
if (!HasAura(itr->first) && HasItemFitToSpellRequirements(spellInfo))
|
||||
AddAura(itr->first, this); // no SMSG_SPELL_GO in sniff found
|
||||
}
|
||||
}
|
||||
else
|
||||
RemoveItemDependentAurasAndCasts(item);
|
||||
}
|
||||
|
||||
bool Player::CheckAttackFitToAuraRequirement(WeaponAttackType attackType, AuraEffect const* aurEff) const
|
||||
{
|
||||
SpellInfo const* spellInfo = aurEff->GetSpellInfo();
|
||||
if (spellInfo->EquippedItemClass == -1)
|
||||
return true;
|
||||
|
||||
Item* item = GetWeaponForAttack(attackType, true);
|
||||
if (!item || !item->IsFitToSpellRequirements(spellInfo))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SpellSchoolMask Player::GetMeleeDamageSchoolMask(WeaponAttackType attackType /*= BASE_ATTACK*/, uint8 damageIndex /*= 0*/) const
|
||||
{
|
||||
if (Item const* weapon = GetWeaponForAttack(attackType, true))
|
||||
@@ -7046,110 +7199,6 @@ SpellSchoolMask Player::GetMeleeDamageSchoolMask(WeaponAttackType attackType /*=
|
||||
return SPELL_SCHOOL_MASK_NORMAL;
|
||||
}
|
||||
|
||||
void Player::_ApplyWeaponDependentAuraMods(Item* item, WeaponAttackType attackType, bool apply)
|
||||
{
|
||||
AuraEffectList const& auraCritList = GetAuraEffectsByType(SPELL_AURA_MOD_WEAPON_CRIT_PERCENT);
|
||||
for (AuraEffectList::const_iterator itr = auraCritList.begin(); itr != auraCritList.end(); ++itr)
|
||||
_ApplyWeaponDependentAuraCritMod(item, attackType, *itr, apply);
|
||||
|
||||
AuraEffectList const& auraDamageFlatList = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_DONE);
|
||||
for (AuraEffectList::const_iterator itr = auraDamageFlatList.begin(); itr != auraDamageFlatList.end(); ++itr)
|
||||
_ApplyWeaponDependentAuraDamageMod(item, attackType, *itr, apply);
|
||||
|
||||
AuraEffectList const& auraDamagePctList = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
|
||||
for (AuraEffectList::const_iterator itr = auraDamagePctList.begin(); itr != auraDamagePctList.end(); ++itr)
|
||||
_ApplyWeaponDependentAuraDamageMod(item, attackType, *itr, apply);
|
||||
}
|
||||
|
||||
void Player::_ApplyWeaponDependentAuraCritMod(Item* item, WeaponAttackType attackType, AuraEffect const* aura, bool apply)
|
||||
{
|
||||
// don't apply mod if item is broken or cannot be used
|
||||
if (item->IsBroken() || !CanUseAttackType(attackType))
|
||||
return;
|
||||
|
||||
// generic not weapon specific case processes in aura code
|
||||
if (aura->GetSpellInfo()->EquippedItemClass == -1)
|
||||
return;
|
||||
|
||||
if (!sScriptMgr->OnPlayerCanApplyWeaponDependentAuraDamageMod(this, item, attackType, aura, apply))
|
||||
return;
|
||||
|
||||
BaseModGroup mod = BASEMOD_END;
|
||||
switch (attackType)
|
||||
{
|
||||
case BASE_ATTACK:
|
||||
mod = CRIT_PERCENTAGE;
|
||||
break;
|
||||
case OFF_ATTACK:
|
||||
mod = OFFHAND_CRIT_PERCENTAGE;
|
||||
break;
|
||||
case RANGED_ATTACK:
|
||||
mod = RANGED_CRIT_PERCENTAGE;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (item->IsFitToSpellRequirements(aura->GetSpellInfo()))
|
||||
HandleBaseModValue(mod, FLAT_MOD, float (aura->GetAmount()), apply);
|
||||
}
|
||||
|
||||
void Player::_ApplyWeaponDependentAuraDamageMod(Item* item, WeaponAttackType attackType, AuraEffect const* aura, bool apply)
|
||||
{
|
||||
// don't apply mod if item is broken or cannot be used
|
||||
if (item->IsBroken() || !CanUseAttackType(attackType))
|
||||
return;
|
||||
|
||||
// ignore spell mods for not wands
|
||||
if ((aura->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL) == 0 && (getClassMask() & CLASSMASK_WAND_USERS) == 0)
|
||||
return;
|
||||
|
||||
// generic not weapon specific case processes in aura code
|
||||
if (aura->GetSpellInfo()->EquippedItemClass == -1)
|
||||
return;
|
||||
|
||||
UnitMods unitMod = UNIT_MOD_END;
|
||||
switch (attackType)
|
||||
{
|
||||
case BASE_ATTACK:
|
||||
unitMod = UNIT_MOD_DAMAGE_MAINHAND;
|
||||
break;
|
||||
case OFF_ATTACK:
|
||||
unitMod = UNIT_MOD_DAMAGE_OFFHAND;
|
||||
break;
|
||||
case RANGED_ATTACK:
|
||||
unitMod = UNIT_MOD_DAMAGE_RANGED;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
UnitModifierType unitModType = TOTAL_VALUE;
|
||||
switch (aura->GetAuraType())
|
||||
{
|
||||
case SPELL_AURA_MOD_DAMAGE_DONE:
|
||||
unitModType = TOTAL_VALUE;
|
||||
break;
|
||||
case SPELL_AURA_MOD_DAMAGE_PERCENT_DONE:
|
||||
unitModType = TOTAL_PCT;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (item->IsFitToSpellRequirements(aura->GetSpellInfo()))
|
||||
{
|
||||
HandleStatModifier(unitMod, unitModType, float(aura->GetAmount()), apply);
|
||||
if (unitModType == TOTAL_VALUE)
|
||||
{
|
||||
if (aura->GetAmount() > 0)
|
||||
ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS, aura->GetAmount(), apply);
|
||||
else
|
||||
ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG, aura->GetAmount(), apply);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Player::ApplyItemEquipSpell(Item* item, bool apply, bool form_change)
|
||||
{
|
||||
if (!item)
|
||||
@@ -7464,12 +7513,6 @@ void Player::CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!spellInfo->CheckElixirStacking(this))
|
||||
{
|
||||
Spell::SendCastResult(this, spellInfo, cast_count, SPELL_FAILED_AURA_BOUNCED);
|
||||
continue;
|
||||
}
|
||||
|
||||
Spell* spell = new Spell(this, spellInfo, (count > 0) ? TRIGGERED_FULL_MASK : TRIGGERED_NONE);
|
||||
spell->m_CastItem = item;
|
||||
spell->m_cast_count = cast_count; // set count of casts
|
||||
@@ -7578,10 +7621,7 @@ void Player::_RemoveAllItemMods()
|
||||
if (!proto)
|
||||
continue;
|
||||
|
||||
WeaponAttackType attacktype = Player::GetAttackBySlot(i);
|
||||
if (attacktype < MAX_ATTACK)
|
||||
_ApplyWeaponDependentAuraMods(m_items[i], attacktype, false);
|
||||
|
||||
ApplyItemDependentAuras(m_items[i], false);
|
||||
_ApplyItemBonuses(proto, i, false);
|
||||
|
||||
if (i == EQUIPMENT_SLOT_RANGED)
|
||||
@@ -7607,12 +7647,13 @@ void Player::_ApplyAllItemMods()
|
||||
if (!proto)
|
||||
continue;
|
||||
|
||||
WeaponAttackType attacktype = Player::GetAttackBySlot(i);
|
||||
if (attacktype < MAX_ATTACK)
|
||||
_ApplyWeaponDependentAuraMods(m_items[i], attacktype, true);
|
||||
|
||||
ApplyItemDependentAuras(m_items[i], false);
|
||||
_ApplyItemBonuses(proto, i, true);
|
||||
|
||||
WeaponAttackType const attackType = Player::GetAttackBySlot(i);
|
||||
if (attackType != MAX_ATTACK)
|
||||
UpdateWeaponDependentAuras(attackType);
|
||||
|
||||
if (i == EQUIPMENT_SLOT_RANGED)
|
||||
_ApplyAmmoBonuses();
|
||||
}
|
||||
@@ -12583,9 +12624,9 @@ void Player::RemoveItemDependentAurasAndCasts(Item* pItem)
|
||||
{
|
||||
Aura* aura = itr->second;
|
||||
|
||||
// skip passive (passive item dependent spells work in another way) and not self applied auras
|
||||
// skip not self applied auras
|
||||
SpellInfo const* spellInfo = aura->GetSpellInfo();
|
||||
if (aura->IsPassive() || aura->GetCasterGUID() != GetGUID())
|
||||
if (aura->GetCasterGUID() != GetGUID())
|
||||
{
|
||||
++itr;
|
||||
continue;
|
||||
|
||||
@@ -1334,7 +1334,7 @@ public:
|
||||
{
|
||||
return StoreItem(dest, pItem, update);
|
||||
}
|
||||
void RemoveItem(uint8 bag, uint8 slot, bool update, bool swap = false);
|
||||
void RemoveItem(uint8 bag, uint8 slot, bool update);
|
||||
void MoveItemFromInventory(uint8 bag, uint8 slot, bool update);
|
||||
// in trade, auction, guild bank, mail....
|
||||
void MoveItemToInventory(ItemPosCountVec const& dest, Item* pItem, bool update, bool in_characterInventoryDB = false);
|
||||
@@ -2187,11 +2187,19 @@ public:
|
||||
[[nodiscard]] bool CanTameExoticPets() const { return IsGameMaster() || HasAuraType(SPELL_AURA_ALLOW_TAME_PET_TYPE); }
|
||||
|
||||
void SetRegularAttackTime();
|
||||
void SetBaseModValue(BaseModGroup modGroup, BaseModType modType, float value) { m_auraBaseMod[modGroup][modType] = value; }
|
||||
void HandleBaseModValue(BaseModGroup modGroup, BaseModType modType, float amount, bool apply);
|
||||
|
||||
void HandleBaseModFlatValue(BaseModGroup modGroup, float amount, bool apply);
|
||||
void ApplyBaseModPctValue(BaseModGroup modGroup, float pct);
|
||||
|
||||
void SetBaseModFlatValue(BaseModGroup modGroup, float val);
|
||||
void SetBaseModPctValue(BaseModGroup modGroup, float val);
|
||||
|
||||
void UpdateDamageDoneMods(WeaponAttackType attackType, int32 skipEnchantSlot = -1) override;
|
||||
void UpdateBaseModGroup(BaseModGroup modGroup);
|
||||
|
||||
[[nodiscard]] float GetBaseModValue(BaseModGroup modGroup, BaseModType modType) const;
|
||||
[[nodiscard]] float GetTotalBaseModValue(BaseModGroup modGroup) const;
|
||||
[[nodiscard]] float GetTotalPercentageModValue(BaseModGroup modGroup) const { return m_auraBaseMod[modGroup][FLAT_MOD] + m_auraBaseMod[modGroup][PCT_MOD]; }
|
||||
|
||||
void _ApplyAllStatBonuses();
|
||||
void _RemoveAllStatBonuses();
|
||||
|
||||
@@ -2203,9 +2211,13 @@ public:
|
||||
|
||||
SpellSchoolMask GetMeleeDamageSchoolMask(WeaponAttackType attackType = BASE_ATTACK, uint8 damageIndex = 0) const override;
|
||||
|
||||
void _ApplyWeaponDependentAuraMods(Item* item, WeaponAttackType attackType, bool apply);
|
||||
void _ApplyWeaponDependentAuraCritMod(Item* item, WeaponAttackType attackType, AuraEffect const* aura, bool apply);
|
||||
void _ApplyWeaponDependentAuraDamageMod(Item* item, WeaponAttackType attackType, AuraEffect const* aura, bool apply);
|
||||
void UpdateWeaponDependentAuras(WeaponAttackType attackType);
|
||||
void ApplyItemDependentAuras(Item* item, bool apply);
|
||||
|
||||
bool CheckAttackFitToAuraRequirement(WeaponAttackType attackType, AuraEffect const* aurEff) const override;
|
||||
|
||||
void UpdateWeaponDependentCritAuras(WeaponAttackType attackType);
|
||||
void UpdateAllWeaponDependentCritAuras();
|
||||
|
||||
void _ApplyItemMods(Item* item, uint8 slot, bool apply);
|
||||
void _RemoveAllItemMods();
|
||||
@@ -2829,7 +2841,8 @@ protected:
|
||||
|
||||
ActionButtonList m_actionButtons;
|
||||
|
||||
float m_auraBaseMod[BASEMOD_END][MOD_END];
|
||||
float m_auraBaseFlatMod[BASEMOD_END];
|
||||
float m_auraBasePctMod[BASEMOD_END];
|
||||
int32 m_baseRatingValue[MAX_COMBAT_RATING];
|
||||
uint32 m_baseSpellPower;
|
||||
uint32 m_baseSpellDamage;
|
||||
|
||||
@@ -1405,9 +1405,7 @@ uint32 Player::CalculateQuestRewardXP(Quest const* quest)
|
||||
uint32 xp = uint32(quest->XPValue(GetLevel()) * GetQuestRate(quest->IsDFQuest()));
|
||||
|
||||
// handle SPELL_AURA_MOD_XP_QUEST_PCT auras
|
||||
Unit::AuraEffectList const& ModXPPctAuras = GetAuraEffectsByType(SPELL_AURA_MOD_XP_QUEST_PCT);
|
||||
for (Unit::AuraEffectList::const_iterator i = ModXPPctAuras.begin(); i != ModXPPctAuras.end(); ++i)
|
||||
AddPct(xp, (*i)->GetAmount());
|
||||
xp *= GetTotalAuraMultiplier(SPELL_AURA_MOD_XP_QUEST_PCT);
|
||||
|
||||
return xp;
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
#include "StringConvert.h"
|
||||
#include "Tokenize.h"
|
||||
#include "Transport.h"
|
||||
#include "Unit.h"
|
||||
#include "UpdateFieldFlags.h"
|
||||
#include "Util.h"
|
||||
#include "World.h"
|
||||
@@ -2896,7 +2897,7 @@ void Player::VisualizeItem(uint8 slot, Item* pItem)
|
||||
pItem->SetState(ITEM_CHANGED, this);
|
||||
}
|
||||
|
||||
void Player::RemoveItem(uint8 bag, uint8 slot, bool update, bool swap)
|
||||
void Player::RemoveItem(uint8 bag, uint8 slot, bool update)
|
||||
{
|
||||
// note: removeitem does not actually change the item
|
||||
// it only takes the item out of storage temporarily
|
||||
@@ -2931,12 +2932,6 @@ void Player::RemoveItem(uint8 bag, uint8 slot, bool update, bool swap)
|
||||
// remove item dependent auras and casts (only weapon and armor slots)
|
||||
if (slot < INVENTORY_SLOT_BAG_END && slot < EQUIPMENT_SLOT_END)
|
||||
{
|
||||
// Xinef: Ensure that this function is called for places with swap=true
|
||||
if (!swap)
|
||||
{
|
||||
RemoveItemDependentAurasAndCasts(pItem);
|
||||
}
|
||||
|
||||
// remove held enchantments, update expertise
|
||||
if (slot == EQUIPMENT_SLOT_MAINHAND)
|
||||
{
|
||||
@@ -3071,9 +3066,6 @@ void Player::DestroyItem(uint8 bag, uint8 slot, bool update)
|
||||
|
||||
if (slot < EQUIPMENT_SLOT_END)
|
||||
{
|
||||
// remove item dependent auras and casts (only weapon and armor slots)
|
||||
RemoveItemDependentAurasAndCasts(pItem);
|
||||
|
||||
// update expertise and armor penetration - passive auras may need it
|
||||
switch (slot)
|
||||
{
|
||||
@@ -3865,8 +3857,8 @@ void Player::SwapItem(uint16 src, uint16 dst)
|
||||
}
|
||||
|
||||
// now do moves, remove...
|
||||
RemoveItem(dstbag, dstslot, false, true);
|
||||
RemoveItem(srcbag, srcslot, false, true);
|
||||
RemoveItem(dstbag, dstslot, false);
|
||||
RemoveItem(srcbag, srcslot, false);
|
||||
|
||||
// add to dest
|
||||
if (IsInventoryPos(dst))
|
||||
@@ -4355,13 +4347,12 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
|
||||
// processed in Player::CastItemCombatSpell
|
||||
break;
|
||||
case ITEM_ENCHANTMENT_TYPE_DAMAGE:
|
||||
if (item->GetSlot() == EQUIPMENT_SLOT_MAINHAND)
|
||||
HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_VALUE, float(enchant_amount), apply);
|
||||
else if (item->GetSlot() == EQUIPMENT_SLOT_OFFHAND)
|
||||
HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_VALUE, float(enchant_amount), apply);
|
||||
else if (item->GetSlot() == EQUIPMENT_SLOT_RANGED)
|
||||
HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_VALUE, float(enchant_amount), apply);
|
||||
{
|
||||
WeaponAttackType const attackType = Player::GetAttackBySlot(item->GetSlot());
|
||||
if (attackType != MAX_ATTACK)
|
||||
UpdateDamageDoneMods(attackType, apply ? -1 : slot);
|
||||
break;
|
||||
}
|
||||
case ITEM_ENCHANTMENT_TYPE_EQUIP_SPELL:
|
||||
if (enchant_spell_id)
|
||||
{
|
||||
@@ -4412,7 +4403,7 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
|
||||
}
|
||||
}
|
||||
|
||||
HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + enchant_spell_id), TOTAL_VALUE, float(enchant_amount), apply);
|
||||
HandleStatFlatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + enchant_spell_id), TOTAL_VALUE, float(enchant_amount), apply);
|
||||
break;
|
||||
case ITEM_ENCHANTMENT_TYPE_STAT:
|
||||
{
|
||||
@@ -4439,36 +4430,36 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
|
||||
{
|
||||
case ITEM_MOD_MANA:
|
||||
LOG_DEBUG("entities.player.items", "+ {} MANA", enchant_amount);
|
||||
HandleStatModifier(UNIT_MOD_MANA, BASE_VALUE, float(enchant_amount), apply);
|
||||
HandleStatFlatModifier(UNIT_MOD_MANA, BASE_VALUE, float(enchant_amount), apply);
|
||||
break;
|
||||
case ITEM_MOD_HEALTH:
|
||||
LOG_DEBUG("entities.player.items", "+ {} HEALTH", enchant_amount);
|
||||
HandleStatModifier(UNIT_MOD_HEALTH, BASE_VALUE, float(enchant_amount), apply);
|
||||
HandleStatFlatModifier(UNIT_MOD_HEALTH, BASE_VALUE, float(enchant_amount), apply);
|
||||
break;
|
||||
case ITEM_MOD_AGILITY:
|
||||
LOG_DEBUG("entities.player.items", "+ {} AGILITY", enchant_amount);
|
||||
HandleStatModifier(UNIT_MOD_STAT_AGILITY, TOTAL_VALUE, float(enchant_amount), apply);
|
||||
ApplyStatBuffMod(STAT_AGILITY, (float)enchant_amount, apply);
|
||||
HandleStatFlatModifier(UNIT_MOD_STAT_AGILITY, TOTAL_VALUE, float(enchant_amount), apply);
|
||||
UpdateStatBuffMod(STAT_AGILITY);
|
||||
break;
|
||||
case ITEM_MOD_STRENGTH:
|
||||
LOG_DEBUG("entities.player.items", "+ {} STRENGTH", enchant_amount);
|
||||
HandleStatModifier(UNIT_MOD_STAT_STRENGTH, TOTAL_VALUE, float(enchant_amount), apply);
|
||||
ApplyStatBuffMod(STAT_STRENGTH, (float)enchant_amount, apply);
|
||||
HandleStatFlatModifier(UNIT_MOD_STAT_STRENGTH, TOTAL_VALUE, float(enchant_amount), apply);
|
||||
UpdateStatBuffMod(STAT_STRENGTH);
|
||||
break;
|
||||
case ITEM_MOD_INTELLECT:
|
||||
LOG_DEBUG("entities.player.items", "+ {} INTELLECT", enchant_amount);
|
||||
HandleStatModifier(UNIT_MOD_STAT_INTELLECT, TOTAL_VALUE, float(enchant_amount), apply);
|
||||
ApplyStatBuffMod(STAT_INTELLECT, (float)enchant_amount, apply);
|
||||
HandleStatFlatModifier(UNIT_MOD_STAT_INTELLECT, TOTAL_VALUE, float(enchant_amount), apply);
|
||||
UpdateStatBuffMod(STAT_INTELLECT);
|
||||
break;
|
||||
case ITEM_MOD_SPIRIT:
|
||||
LOG_DEBUG("entities.player.items", "+ {} SPIRIT", enchant_amount);
|
||||
HandleStatModifier(UNIT_MOD_STAT_SPIRIT, TOTAL_VALUE, float(enchant_amount), apply);
|
||||
ApplyStatBuffMod(STAT_SPIRIT, (float)enchant_amount, apply);
|
||||
HandleStatFlatModifier(UNIT_MOD_STAT_SPIRIT, TOTAL_VALUE, float(enchant_amount), apply);
|
||||
UpdateStatBuffMod(STAT_SPIRIT);
|
||||
break;
|
||||
case ITEM_MOD_STAMINA:
|
||||
LOG_DEBUG("entities.player.items", "+ {} STAMINA", enchant_amount);
|
||||
HandleStatModifier(UNIT_MOD_STAT_STAMINA, TOTAL_VALUE, float(enchant_amount), apply);
|
||||
ApplyStatBuffMod(STAT_STAMINA, (float)enchant_amount, apply);
|
||||
HandleStatFlatModifier(UNIT_MOD_STAT_STAMINA, TOTAL_VALUE, float(enchant_amount), apply);
|
||||
UpdateStatBuffMod(STAT_STAMINA);
|
||||
break;
|
||||
case ITEM_MOD_DEFENSE_SKILL_RATING:
|
||||
ApplyRatingMod(CR_DEFENSE_SKILL, enchant_amount, apply);
|
||||
@@ -4579,12 +4570,12 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
|
||||
LOG_DEBUG("entities.player.items", "+ {} EXPERTISE", enchant_amount);
|
||||
break;
|
||||
case ITEM_MOD_ATTACK_POWER:
|
||||
HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(enchant_amount), apply);
|
||||
HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(enchant_amount), apply);
|
||||
HandleStatFlatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(enchant_amount), apply);
|
||||
HandleStatFlatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(enchant_amount), apply);
|
||||
LOG_DEBUG("entities.player.items", "+ {} ATTACK_POWER", enchant_amount);
|
||||
break;
|
||||
case ITEM_MOD_RANGED_ATTACK_POWER:
|
||||
HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(enchant_amount), apply);
|
||||
HandleStatFlatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(enchant_amount), apply);
|
||||
LOG_DEBUG("entities.player.items", "+ {} RANGED_ATTACK_POWER", enchant_amount);
|
||||
break;
|
||||
// case ITEM_MOD_FERAL_ATTACK_POWER:
|
||||
@@ -4612,7 +4603,7 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
|
||||
LOG_DEBUG("entities.player.items", "+ {} SPELL_PENETRATION", enchant_amount);
|
||||
break;
|
||||
case ITEM_MOD_BLOCK_VALUE:
|
||||
HandleBaseModValue(SHIELD_BLOCK_VALUE, FLAT_MOD, float(enchant_amount), apply);
|
||||
HandleBaseModFlatValue(SHIELD_BLOCK_VALUE, float(enchant_amount), apply);
|
||||
LOG_DEBUG("entities.player.items", "+ {} BLOCK_VALUE", enchant_amount);
|
||||
break;
|
||||
/// @deprecated item mods
|
||||
@@ -4631,20 +4622,9 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
|
||||
}
|
||||
case ITEM_ENCHANTMENT_TYPE_TOTEM: // Shaman Rockbiter Weapon
|
||||
{
|
||||
if (IsClass(CLASS_SHAMAN, CLASS_CONTEXT_ABILITY))
|
||||
{
|
||||
float addValue = 0.0f;
|
||||
if (item->GetSlot() == EQUIPMENT_SLOT_MAINHAND)
|
||||
{
|
||||
addValue = float(enchant_amount * item->GetTemplate()->Delay / 1000.0f);
|
||||
HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_VALUE, addValue, apply);
|
||||
}
|
||||
else if (item->GetSlot() == EQUIPMENT_SLOT_OFFHAND)
|
||||
{
|
||||
addValue = float(enchant_amount * item->GetTemplate()->Delay / 1000.0f);
|
||||
HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_VALUE, addValue, apply);
|
||||
}
|
||||
}
|
||||
WeaponAttackType const attackType = Player::GetAttackBySlot(item->GetSlot());
|
||||
if (attackType != MAX_ATTACK)
|
||||
UpdateDamageDoneMods(attackType);
|
||||
break;
|
||||
}
|
||||
case ITEM_ENCHANTMENT_TYPE_USE_SPELL:
|
||||
|
||||
@@ -701,7 +701,7 @@ void Player::UpdateRating(CombatRating cr)
|
||||
|
||||
void Player::UpdateAllRatings()
|
||||
{
|
||||
for (int cr = 0; cr < MAX_COMBAT_RATING; ++cr)
|
||||
for (uint cr = 0; cr < MAX_COMBAT_RATING; ++cr)
|
||||
UpdateRating(CombatRating(cr));
|
||||
}
|
||||
|
||||
|
||||
@@ -204,7 +204,7 @@ void Player::UpdateSpellDamageAndHealingBonus()
|
||||
|
||||
bool Player::UpdateAllStats()
|
||||
{
|
||||
for (int8 i = STAT_STRENGTH; i < MAX_STATS; ++i)
|
||||
for (uint8 i = STAT_STRENGTH; i < MAX_STATS; ++i)
|
||||
{
|
||||
float value = GetTotalStatValue(Stats(i));
|
||||
SetStat(Stats(i), int32(value));
|
||||
@@ -247,9 +247,9 @@ void Player::UpdateResistances(uint32 school)
|
||||
float value = 0.0f;
|
||||
UnitMods unitMod = UnitMods(UNIT_MOD_RESISTANCE_START + school);
|
||||
|
||||
value = GetModifierValue(unitMod, BASE_VALUE);
|
||||
value *= GetModifierValue(unitMod, BASE_PCT);
|
||||
value += GetModifierValue(unitMod, TOTAL_VALUE);
|
||||
value = GetFlatModifierValue(unitMod, BASE_VALUE);
|
||||
value *= GetPctModifierValue(unitMod, BASE_PCT);
|
||||
value += GetFlatModifierValue(unitMod, TOTAL_VALUE);
|
||||
|
||||
AuraEffectList const& mResbyIntellect = GetAuraEffectsByType(SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT);
|
||||
for(AuraEffectList::const_iterator i = mResbyIntellect.begin(); i != mResbyIntellect.end(); ++i)
|
||||
@@ -258,7 +258,7 @@ void Player::UpdateResistances(uint32 school)
|
||||
value += int32(GetStat(Stats((*i)->GetMiscValueB())) * (*i)->GetAmount() / 100.0f);
|
||||
}
|
||||
|
||||
value *= GetModifierValue(unitMod, TOTAL_PCT);
|
||||
value *= GetPctModifierValue(unitMod, TOTAL_PCT);
|
||||
|
||||
SetResistance(SpellSchools(school), int32(value));
|
||||
}
|
||||
@@ -270,10 +270,10 @@ void Player::UpdateArmor()
|
||||
{
|
||||
UnitMods unitMod = UNIT_MOD_ARMOR;
|
||||
|
||||
float value = GetModifierValue(unitMod, BASE_VALUE); // base armor (from items)
|
||||
value *= GetModifierValue(unitMod, BASE_PCT); // armor percent from items
|
||||
float value = GetFlatModifierValue(unitMod, BASE_VALUE); // base armor (from items)
|
||||
value *= GetPctModifierValue(unitMod, BASE_PCT); // armor percent from items
|
||||
value += GetStat(STAT_AGILITY) * 2.0f; // armor bonus from stats
|
||||
value += GetModifierValue(unitMod, TOTAL_VALUE);
|
||||
value += GetFlatModifierValue(unitMod, TOTAL_VALUE);
|
||||
|
||||
//add dynamic flat mods
|
||||
AuraEffectList const& mResbyIntellect = GetAuraEffectsByType(SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT);
|
||||
@@ -283,7 +283,7 @@ void Player::UpdateArmor()
|
||||
value += CalculatePct(GetStat(Stats((*i)->GetMiscValueB())), (*i)->GetAmount());
|
||||
}
|
||||
|
||||
value *= GetModifierValue(unitMod, TOTAL_PCT);
|
||||
value *= GetPctModifierValue(unitMod, TOTAL_PCT);
|
||||
|
||||
SetArmor(int32(value));
|
||||
|
||||
@@ -314,10 +314,10 @@ void Player::UpdateMaxHealth()
|
||||
{
|
||||
UnitMods unitMod = UNIT_MOD_HEALTH;
|
||||
|
||||
float value = GetModifierValue(unitMod, BASE_VALUE) + GetCreateHealth();
|
||||
value *= GetModifierValue(unitMod, BASE_PCT);
|
||||
value += GetModifierValue(unitMod, TOTAL_VALUE) + GetHealthBonusFromStamina();
|
||||
value *= GetModifierValue(unitMod, TOTAL_PCT);
|
||||
float value = GetFlatModifierValue(unitMod, BASE_VALUE) + GetCreateHealth();
|
||||
value *= GetPctModifierValue(unitMod, BASE_PCT);
|
||||
value += GetFlatModifierValue(unitMod, TOTAL_VALUE) + GetHealthBonusFromStamina();
|
||||
value *= GetPctModifierValue(unitMod, TOTAL_PCT);
|
||||
|
||||
sScriptMgr->OnPlayerAfterUpdateMaxHealth(this, value);
|
||||
SetMaxHealth((uint32)value);
|
||||
@@ -329,10 +329,10 @@ void Player::UpdateMaxPower(Powers power)
|
||||
|
||||
float bonusPower = (power == POWER_MANA && GetCreatePowers(power) > 0) ? GetManaBonusFromIntellect() : 0;
|
||||
|
||||
float value = GetModifierValue(unitMod, BASE_VALUE) + GetCreatePowers(power);
|
||||
value *= GetModifierValue(unitMod, BASE_PCT);
|
||||
value += GetModifierValue(unitMod, TOTAL_VALUE) + bonusPower;
|
||||
value *= GetModifierValue(unitMod, TOTAL_PCT);
|
||||
float value = GetFlatModifierValue(unitMod, BASE_VALUE) + GetCreatePowers(power);
|
||||
value *= GetPctModifierValue(unitMod, BASE_PCT);
|
||||
value += GetFlatModifierValue(unitMod, TOTAL_VALUE) + bonusPower;
|
||||
value *= GetPctModifierValue(unitMod, TOTAL_PCT);
|
||||
|
||||
sScriptMgr->OnPlayerAfterUpdateMaxPower(this, power, value);
|
||||
SetMaxPower(power, uint32(value));
|
||||
@@ -487,10 +487,10 @@ void Player::UpdateAttackPowerAndDamage(bool ranged)
|
||||
}
|
||||
}
|
||||
|
||||
SetModifierValue(unitMod, BASE_VALUE, val2);
|
||||
SetStatFlatModifier(unitMod, BASE_VALUE, val2);
|
||||
|
||||
float base_attPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT);
|
||||
float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE);
|
||||
float base_attPower = GetFlatModifierValue(unitMod, BASE_VALUE) * GetPctModifierValue(unitMod, BASE_PCT);
|
||||
float attPowerMod = GetFlatModifierValue(unitMod, TOTAL_VALUE);
|
||||
|
||||
//add dynamic flat mods
|
||||
if (ranged)
|
||||
@@ -514,7 +514,7 @@ void Player::UpdateAttackPowerAndDamage(bool ranged)
|
||||
attPowerMod += int32(GetArmor() / (*iter)->GetAmount());
|
||||
}
|
||||
|
||||
float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f;
|
||||
float attPowerMultiplier = GetPctModifierValue(unitMod, TOTAL_PCT) - 1.0f;
|
||||
|
||||
sScriptMgr->OnPlayerAfterUpdateAttackPowerAndDamage(this, level, base_attPower, attPowerMod, attPowerMultiplier, ranged);
|
||||
SetInt32Value(index, (uint32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field
|
||||
@@ -576,10 +576,10 @@ void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bo
|
||||
|
||||
float attackSpeedMod = GetAPMultiplier(attType, normalized);
|
||||
|
||||
float baseValue = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType) / 14.0f * attackSpeedMod;
|
||||
float basePct = GetModifierValue(unitMod, BASE_PCT);
|
||||
float totalValue = GetModifierValue(unitMod, TOTAL_VALUE);
|
||||
float totalPct = addTotalPct ? GetModifierValue(unitMod, TOTAL_PCT) : 1.0f;
|
||||
float baseValue = GetFlatModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType) / 14.0f * attackSpeedMod;
|
||||
float basePct = GetPctModifierValue(unitMod, BASE_PCT);
|
||||
float totalValue = GetFlatModifierValue(unitMod, TOTAL_VALUE);
|
||||
float totalPct = addTotalPct ? GetPctModifierValue(unitMod, TOTAL_PCT) : 1.0f;
|
||||
|
||||
float weaponMinDamage = GetWeaponDamageRange(attType, MINDAMAGE);
|
||||
float weaponMaxDamage = GetWeaponDamageRange(attType, MAXDAMAGE);
|
||||
@@ -681,7 +681,8 @@ void Player::UpdateCritPercentage(WeaponAttackType attType)
|
||||
break;
|
||||
}
|
||||
|
||||
float value = GetTotalPercentageModValue(modGroup) + GetRatingBonusValue(cr);
|
||||
// flat = bonus from crit auras, pct = bonus from agility, combat rating = mods from items
|
||||
float value = GetBaseModValue(modGroup, FLAT_MOD) + GetBaseModValue(modGroup, PCT_MOD) + GetRatingBonusValue(cr);
|
||||
// Modify crit from weapon skill and maximized defense skill of same level victim difference
|
||||
value += (int32(GetWeaponSkillValue(attType)) - int32(GetMaxSkillValueForLevel())) * 0.04f;
|
||||
|
||||
@@ -698,9 +699,9 @@ void Player::UpdateAllCritPercentages()
|
||||
{
|
||||
float value = GetMeleeCritFromAgility();
|
||||
|
||||
SetBaseModValue(CRIT_PERCENTAGE, PCT_MOD, value);
|
||||
SetBaseModValue(OFFHAND_CRIT_PERCENTAGE, PCT_MOD, value);
|
||||
SetBaseModValue(RANGED_CRIT_PERCENTAGE, PCT_MOD, value);
|
||||
SetBaseModPctValue(CRIT_PERCENTAGE, value);
|
||||
SetBaseModPctValue(OFFHAND_CRIT_PERCENTAGE, value);
|
||||
SetBaseModPctValue(RANGED_CRIT_PERCENTAGE, value);
|
||||
|
||||
UpdateCritPercentage(BASE_ATTACK);
|
||||
UpdateCritPercentage(OFF_ATTACK);
|
||||
@@ -849,7 +850,7 @@ void Player::UpdateSpellCritChance(uint32 school)
|
||||
// Crit from Intellect
|
||||
crit += GetSpellCritFromIntellect();
|
||||
// Increase crit from SPELL_AURA_MOD_SPELL_CRIT_CHANCE
|
||||
crit += GetTotalAuraModifierAreaExclusive(SPELL_AURA_MOD_SPELL_CRIT_CHANCE);
|
||||
crit += GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_CRIT_CHANCE);
|
||||
// Increase crit from SPELL_AURA_MOD_CRIT_PCT
|
||||
crit += GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_PCT);
|
||||
// Increase crit by school from SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL
|
||||
@@ -900,16 +901,11 @@ void Player::UpdateExpertise(WeaponAttackType attack)
|
||||
|
||||
Item* weapon = GetWeaponForAttack(attack, true);
|
||||
|
||||
AuraEffectList const& expAuras = GetAuraEffectsByType(SPELL_AURA_MOD_EXPERTISE);
|
||||
for (AuraEffectList::const_iterator itr = expAuras.begin(); itr != expAuras.end(); ++itr)
|
||||
expertise += GetTotalAuraModifier(SPELL_AURA_MOD_EXPERTISE, [weapon](AuraEffect const* aurEff)
|
||||
{
|
||||
// item neutral spell
|
||||
if ((*itr)->GetSpellInfo()->EquippedItemClass == -1)
|
||||
expertise += (*itr)->GetAmount();
|
||||
// item dependent spell
|
||||
else if (weapon && weapon->IsFitToSpellRequirements((*itr)->GetSpellInfo()))
|
||||
expertise += (*itr)->GetAmount();
|
||||
}
|
||||
return aurEff->GetSpellInfo()->EquippedItemClass == -1 || // item neutral spell
|
||||
(weapon && weapon->IsFitToSpellRequirements(aurEff->GetSpellInfo())); // item dependent spell
|
||||
});
|
||||
|
||||
if (expertise < 0)
|
||||
expertise = 0;
|
||||
@@ -1100,9 +1096,9 @@ void Creature::UpdateAttackPowerAndDamage(bool ranged)
|
||||
indexMulti = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER;
|
||||
}
|
||||
|
||||
float baseAttackPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT);
|
||||
float attackPowerMod = GetModifierValue(unitMod, TOTAL_VALUE);
|
||||
float attackPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f;
|
||||
float baseAttackPower = GetFlatModifierValue(unitMod, BASE_VALUE) * GetPctModifierValue(unitMod, BASE_PCT);
|
||||
float attackPowerMod = GetFlatModifierValue(unitMod, TOTAL_VALUE);
|
||||
float attackPowerMultiplier = GetPctModifierValue(unitMod, TOTAL_PCT) - 1.0f;
|
||||
|
||||
SetInt32Value(index, uint32(baseAttackPower)); // UNIT_FIELD_(RANGED)_ATTACK_POWER
|
||||
SetInt32Value(indexMod, uint32(attackPowerMod)); // UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS
|
||||
@@ -1166,10 +1162,10 @@ void Creature::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized,
|
||||
|
||||
float attackPower = GetTotalAttackPowerValue(attType);
|
||||
float attackSpeedMulti = GetAPMultiplier(attType, normalized);
|
||||
float baseValue = GetModifierValue(unitMod, BASE_VALUE) + (attackPower / 14.0f) * variance;
|
||||
float basePct = GetModifierValue(unitMod, BASE_PCT) * attackSpeedMulti;
|
||||
float totalValue = GetModifierValue(unitMod, TOTAL_VALUE);
|
||||
float totalPct = addTotalPct ? GetModifierValue(unitMod, TOTAL_PCT) : 1.0f;
|
||||
float baseValue = GetFlatModifierValue(unitMod, BASE_VALUE) + (attackPower / 14.0f) * variance;
|
||||
float basePct = GetPctModifierValue(unitMod, BASE_PCT) * attackSpeedMulti;
|
||||
float totalValue = GetFlatModifierValue(unitMod, TOTAL_VALUE);
|
||||
float totalPct = addTotalPct ? GetPctModifierValue(unitMod, TOTAL_PCT) : 1.0f;
|
||||
float dmgMultiplier = GetCreatureTemplate()->DamageModifier; // = DamageModifier * _GetDamageMod(rank);
|
||||
|
||||
minDamage = ((weaponMinDamage + baseValue) * dmgMultiplier * basePct + totalValue) * totalPct;
|
||||
@@ -1233,11 +1229,11 @@ bool Guardian::UpdateAllStats()
|
||||
|
||||
void Guardian::UpdateArmor()
|
||||
{
|
||||
float value = GetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE);
|
||||
value *= GetModifierValue(UNIT_MOD_ARMOR, BASE_PCT);
|
||||
float value = GetFlatModifierValue(UNIT_MOD_ARMOR, BASE_VALUE);
|
||||
value *= GetPctModifierValue(UNIT_MOD_ARMOR, BASE_PCT);
|
||||
value += std::max<float>(GetStat(STAT_AGILITY) - GetCreateStat(STAT_AGILITY), 0.0f) * 2.0f;
|
||||
value += GetModifierValue(UNIT_MOD_ARMOR, TOTAL_VALUE);
|
||||
value *= GetModifierValue(UNIT_MOD_ARMOR, TOTAL_PCT);
|
||||
value += GetFlatModifierValue(UNIT_MOD_ARMOR, TOTAL_VALUE);
|
||||
value *= GetPctModifierValue(UNIT_MOD_ARMOR, TOTAL_PCT);
|
||||
SetArmor(int32(value));
|
||||
}
|
||||
|
||||
@@ -1278,10 +1274,10 @@ void Guardian::UpdateMaxHealth()
|
||||
break;
|
||||
}
|
||||
|
||||
float value = GetModifierValue(unitMod, BASE_VALUE);// xinef: Do NOT add base health TWICE + GetCreateHealth();
|
||||
value *= GetModifierValue(unitMod, BASE_PCT);
|
||||
value += GetModifierValue(unitMod, TOTAL_VALUE) + stamina * multiplicator;
|
||||
value *= GetModifierValue(unitMod, TOTAL_PCT);
|
||||
float value = GetFlatModifierValue(unitMod, BASE_VALUE);// xinef: Do NOT add base health TWICE + GetCreateHealth();
|
||||
value *= GetPctModifierValue(unitMod, BASE_PCT);
|
||||
value += GetFlatModifierValue(unitMod, TOTAL_VALUE) + stamina * multiplicator;
|
||||
value *= GetPctModifierValue(unitMod, TOTAL_PCT);
|
||||
|
||||
SetMaxHealth((uint32)value);
|
||||
}
|
||||
@@ -1311,11 +1307,11 @@ void Guardian::UpdateMaxPower(Powers power)
|
||||
break;
|
||||
}
|
||||
|
||||
// xinef: Do NOT add base mana TWICE
|
||||
float value = GetModifierValue(unitMod, BASE_VALUE) + (power != POWER_MANA ? GetCreatePowers(power) : 0);
|
||||
value *= GetModifierValue(unitMod, BASE_PCT);
|
||||
value += GetModifierValue(unitMod, TOTAL_VALUE) + addValue * multiplicator;
|
||||
value *= GetModifierValue(unitMod, TOTAL_PCT);
|
||||
// Do NOT add base mana TWICE
|
||||
float value = GetFlatModifierValue(unitMod, BASE_VALUE) + (power != POWER_MANA ? GetCreatePowers(power) : 0);
|
||||
value *= GetPctModifierValue(unitMod, BASE_PCT);
|
||||
value += GetFlatModifierValue(unitMod, TOTAL_VALUE) + addValue * multiplicator;
|
||||
value *= GetPctModifierValue(unitMod, TOTAL_PCT);
|
||||
|
||||
SetMaxPower(power, uint32(value));
|
||||
}
|
||||
@@ -1335,12 +1331,12 @@ void Guardian::UpdateAttackPowerAndDamage(bool ranged)
|
||||
else
|
||||
val = 2 * GetStat(STAT_STRENGTH) - 20.0f;
|
||||
|
||||
SetModifierValue(unitMod, BASE_VALUE, val);
|
||||
SetStatFlatModifier(unitMod, BASE_VALUE, val);
|
||||
|
||||
//in BASE_VALUE of UNIT_MOD_ATTACK_POWER for creatures we store data of meleeattackpower field in DB
|
||||
float base_attPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT);
|
||||
float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE);
|
||||
float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f;
|
||||
float base_attPower = GetFlatModifierValue(unitMod, BASE_VALUE) * GetPctModifierValue(unitMod, BASE_PCT);
|
||||
float attPowerMod = GetFlatModifierValue(unitMod, TOTAL_VALUE);
|
||||
float attPowerMultiplier = GetPctModifierValue(unitMod, TOTAL_PCT) - 1.0f;
|
||||
|
||||
//UNIT_FIELD_(RANGED)_ATTACK_POWER field
|
||||
SetInt32Value(UNIT_FIELD_ATTACK_POWER, (int32)base_attPower);
|
||||
@@ -1362,10 +1358,10 @@ void Guardian::UpdateDamagePhysical(WeaponAttackType attType)
|
||||
|
||||
float att_speed = float(GetAttackTime(BASE_ATTACK)) / 1000.0f;
|
||||
|
||||
float base_value = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType) / 14.0f * att_speed;
|
||||
float base_pct = GetModifierValue(unitMod, BASE_PCT);
|
||||
float total_value = GetModifierValue(unitMod, TOTAL_VALUE);
|
||||
float total_pct = GetModifierValue(unitMod, TOTAL_PCT);
|
||||
float base_value = GetFlatModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType) / 14.0f * att_speed;
|
||||
float base_pct = GetPctModifierValue(unitMod, BASE_PCT);
|
||||
float total_value = GetFlatModifierValue(unitMod, TOTAL_VALUE);
|
||||
float total_pct = GetPctModifierValue(unitMod, TOTAL_PCT);
|
||||
|
||||
float weapon_mindamage = GetWeaponDamageRange(BASE_ATTACK, MINDAMAGE);
|
||||
float weapon_maxdamage = GetWeaponDamageRange(BASE_ATTACK, MAXDAMAGE);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -123,13 +123,18 @@ enum HitInfo
|
||||
HITINFO_FAKE_DAMAGE = 0x01000000 // enables damage animation even if no damage done, set only if no damage
|
||||
};
|
||||
|
||||
enum UnitModifierType
|
||||
enum UnitModifierFlatType
|
||||
{
|
||||
BASE_VALUE = 0,
|
||||
BASE_PCT = 1,
|
||||
TOTAL_VALUE = 2,
|
||||
TOTAL_PCT = 3,
|
||||
MODIFIER_TYPE_END = 4
|
||||
TOTAL_VALUE = 1,
|
||||
MODIFIER_TYPE_FLAT_END = 3
|
||||
};
|
||||
|
||||
enum UnitModifierPctType
|
||||
{
|
||||
BASE_PCT = 0,
|
||||
TOTAL_PCT = 1,
|
||||
MODIFIER_TYPE_PCT_END = 2
|
||||
};
|
||||
|
||||
enum WeaponDamageRange
|
||||
@@ -1050,16 +1055,32 @@ public:
|
||||
for (uint8 i = STAT_STRENGTH; i < MAX_STATS; ++i) SetFloatValue(static_cast<uint16>(UNIT_FIELD_NEGSTAT0) + i, 0);
|
||||
}
|
||||
|
||||
bool HandleStatModifier(UnitMods unitMod, UnitModifierType modifierType, float amount, bool apply);
|
||||
void SetModifierValue(UnitMods unitMod, UnitModifierType modifierType, float value) { m_auraModifiersGroup[unitMod][modifierType] = value; }
|
||||
[[nodiscard]] float GetModifierValue(UnitMods unitMod, UnitModifierType modifierType) const;
|
||||
bool HandleStatFlatModifier(UnitMods unitMod, UnitModifierFlatType modifierType, float amount, bool apply);
|
||||
void ApplyStatPctModifier(UnitMods unitMod, UnitModifierPctType modifierType, float amount);
|
||||
|
||||
void SetStatFlatModifier(UnitMods unitMod, UnitModifierFlatType modifierType, float val);
|
||||
void SetStatPctModifier(UnitMods unitMod, UnitModifierPctType modifierType, float val);
|
||||
|
||||
[[nodiscard]] float GetFlatModifierValue(UnitMods unitMod, UnitModifierFlatType modifierType) const;
|
||||
[[nodiscard]] float GetPctModifierValue(UnitMods unitMod, UnitModifierPctType modifierType) const;
|
||||
|
||||
void UpdateUnitMod(UnitMods unitMod);
|
||||
|
||||
// only players have item requirements
|
||||
[[nodiscard]] virtual bool CheckAttackFitToAuraRequirement(WeaponAttackType /*attackType*/, AuraEffect const* /*aurEff*/) const { return true; }
|
||||
|
||||
virtual void UpdateDamageDoneMods(WeaponAttackType attackType, int32 skipEnchantSlot = -1);
|
||||
void UpdateAllDamageDoneMods();
|
||||
|
||||
void UpdateDamagePctDoneMods(WeaponAttackType attackType);
|
||||
void UpdateAllDamagePctDoneMods();
|
||||
|
||||
[[nodiscard]] float GetTotalStatValue(Stats stat, float additionalValue = 0.0f) const;
|
||||
|
||||
void SetCanModifyStats(bool modifyStats) { m_canModifyStats = modifyStats; }
|
||||
[[nodiscard]] bool CanModifyStats() const { return m_canModifyStats; }
|
||||
|
||||
void ApplyStatBuffMod(Stats stat, float val, bool apply) { ApplyModSignedFloatValue((val > 0 ? static_cast<uint16>(UNIT_FIELD_POSSTAT0) + stat : static_cast<uint16>(UNIT_FIELD_NEGSTAT0) + stat), val, apply); }
|
||||
void ApplyStatPercentBuffMod(Stats stat, float val, bool apply);
|
||||
void UpdateStatBuffMod(Stats stat);
|
||||
|
||||
// Unit level methods
|
||||
[[nodiscard]] uint8 GetLevel() const { return uint8(GetUInt32Value(UNIT_FIELD_LEVEL)); }
|
||||
@@ -1104,7 +1125,6 @@ public:
|
||||
void SetMaxPower(Powers power, uint32 val);
|
||||
|
||||
int32 ModifyPower(Powers power, int32 val, bool withPowerUpdate = true);
|
||||
int32 ModifyPowerPct(Powers power, float pct, bool apply = true);
|
||||
|
||||
void RewardRage(uint32 damage, uint32 weaponSpeedHitFactor, bool attacker);
|
||||
|
||||
@@ -1159,13 +1179,9 @@ public:
|
||||
[[nodiscard]] uint32 GetResistance(SpellSchoolMask mask) const;
|
||||
[[nodiscard]] uint32 GetResistance(SpellSchools school) const { return GetUInt32Value(static_cast<uint16>(UNIT_FIELD_RESISTANCES) + school); }
|
||||
static float GetEffectiveResistChance(Unit const* owner, SpellSchoolMask schoolMask, Unit const* victim);
|
||||
[[nodiscard]] float GetResistanceBuffMods(SpellSchools school, bool positive) const { return GetFloatValue(positive ? static_cast<uint16>(UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE) + school : static_cast<uint16>(UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE) + + school); }
|
||||
|
||||
void SetResistance(SpellSchools school, int32 val) { SetStatInt32Value(static_cast<uint16>(UNIT_FIELD_RESISTANCES) + school, val); }
|
||||
void SetResistanceBuffMods(SpellSchools school, bool positive, float val) { SetFloatValue(positive ? static_cast<uint16>(UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE) + school : static_cast<uint16>(UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE) + + school, val); }
|
||||
|
||||
void ApplyResistanceBuffModsMod(SpellSchools school, bool positive, float val, bool apply) { ApplyModSignedFloatValue(positive ? static_cast<uint16>(UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE) + school : static_cast<uint16>(UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE) + + school, val, apply); }
|
||||
void ApplyResistanceBuffModsPercentMod(SpellSchools school, bool positive, float val, bool apply) { ApplyPercentModFloatValue(positive ? static_cast<uint16>(UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE) + school : static_cast<uint16>(UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE) + + school, val, apply); }
|
||||
void UpdateResistanceBuffModsMod(SpellSchools school);
|
||||
|
||||
//////////// Need triage ////////////////
|
||||
uint16 GetMaxSkillValueForLevel(Unit const* target = nullptr) const { return (target ? getLevelForTarget(target) : GetLevel()) * 5; }
|
||||
@@ -1319,6 +1335,10 @@ public:
|
||||
|
||||
void SetAuraStack(uint32 spellId, Unit* target, uint32 stack);
|
||||
|
||||
int32 GetHighestExclusiveSameEffectSpellGroupValue(AuraEffect const* aurEff, AuraType auraType, bool checkMiscValue = false, int32 miscValue = 0) const;
|
||||
bool IsHighestExclusiveAura(Aura const* aura, bool removeOtherAuraApplications = false);
|
||||
bool IsHighestExclusiveAuraEffect(SpellInfo const* spellInfo, AuraType auraType, int32 effectAmount, uint8 auraEffectMask, bool removeOtherAuraApplications = false);
|
||||
|
||||
// aura apply/remove helpers - you should better not use these
|
||||
Aura* _TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8 effMask, Unit* caster, int32* baseAmount = nullptr, Item* castItem = nullptr, ObjectGuid casterGUID = ObjectGuid::Empty, bool periodicReset = false);
|
||||
void _AddAura(UnitAura* aura, Unit* caster);
|
||||
@@ -1328,7 +1348,7 @@ public:
|
||||
void _UnapplyAura(AuraApplicationMap::iterator& i, AuraRemoveMode removeMode);
|
||||
void _UnapplyAura(AuraApplication* aurApp, AuraRemoveMode removeMode);
|
||||
void _RemoveNoStackAuraApplicationsDueToAura(Aura* aura);
|
||||
void _RemoveNoStackAurasDueToAura(Aura* aura);
|
||||
void _RemoveNoStackAurasDueToAura(Aura* aura, bool owned);
|
||||
bool _IsNoStackAuraDueToAura(Aura* appliedAura, Aura* existingAura) const;
|
||||
void _RegisterAuraEffect(AuraEffect* aurEff, bool apply);
|
||||
|
||||
@@ -1474,15 +1494,19 @@ public:
|
||||
uint32 GetDiseasesByCaster(ObjectGuid casterGUID, uint8 mode = 0);
|
||||
[[nodiscard]] uint32 GetDoTsByCaster(ObjectGuid casterGUID) const;
|
||||
|
||||
[[nodiscard]] int32 GetTotalAuraModifierAreaExclusive(AuraType auratype) const;
|
||||
[[nodiscard]] int32 GetTotalAuraModifier(AuraType auratype) const;
|
||||
[[nodiscard]] float GetTotalAuraMultiplier(AuraType auratype) const;
|
||||
int32 GetMaxPositiveAuraModifier(AuraType auratype);
|
||||
[[nodiscard]] int32 GetMaxPositiveAuraModifier(AuraType auratype) const;
|
||||
[[nodiscard]] int32 GetMaxNegativeAuraModifier(AuraType auratype) const;
|
||||
|
||||
[[nodiscard]] int32 GetTotalAuraModifier(AuraType auratype, std::function<bool(AuraEffect const*)> const& predicate) const;
|
||||
[[nodiscard]] float GetTotalAuraMultiplier(AuraType auraType, std::function<bool(AuraEffect const*)> const& predicate) const;
|
||||
[[nodiscard]] int32 GetMaxPositiveAuraModifier(AuraType auraType, std::function<bool(AuraEffect const*)> const& predicate) const;
|
||||
[[nodiscard]] int32 GetMaxNegativeAuraModifier(AuraType auraType, std::function<bool(AuraEffect const*)> const& predicate) const;
|
||||
|
||||
[[nodiscard]] int32 GetTotalAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const;
|
||||
[[nodiscard]] float GetTotalAuraMultiplierByMiscMask(AuraType auratype, uint32 misc_mask) const;
|
||||
int32 GetMaxPositiveAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask, const AuraEffect* except = nullptr) const;
|
||||
[[nodiscard]] int32 GetMaxPositiveAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask, const AuraEffect* except = nullptr) const;
|
||||
[[nodiscard]] int32 GetMaxNegativeAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const;
|
||||
|
||||
[[nodiscard]] int32 GetTotalAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const;
|
||||
@@ -1581,7 +1605,6 @@ public:
|
||||
int32 HealBySpell(HealInfo& healInfo, bool critical = false);
|
||||
|
||||
int32 SpellBaseHealingBonusDone(SpellSchoolMask schoolMask);
|
||||
int32 SpellBaseHealingBonusTaken(SpellSchoolMask schoolMask);
|
||||
float SpellPctHealingModsDone(Unit* victim, SpellInfo const* spellProto, DamageEffectType damagetype);
|
||||
uint32 SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint8 effIndex, float TotalMod = 0.0f, uint32 stack = 1);
|
||||
uint32 SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack = 1);
|
||||
@@ -2132,7 +2155,8 @@ protected:
|
||||
AuraStateAurasMap m_auraStateAuras; // Used for improve performance of aura state checks on aura apply/remove
|
||||
uint32 m_interruptMask;
|
||||
|
||||
float m_auraModifiersGroup[UNIT_MOD_END][MODIFIER_TYPE_END];
|
||||
float m_auraFlatModifiersGroup[UNIT_MOD_END][MODIFIER_TYPE_FLAT_END];
|
||||
float m_auraPctModifiersGroup[UNIT_MOD_END][MODIFIER_TYPE_PCT_END];
|
||||
float m_weaponDamage[MAX_ATTACK][MAX_WEAPON_DAMAGE_RANGE][MAX_ITEM_PROTO_DAMAGES];
|
||||
bool m_canModifyStats;
|
||||
VisibleAuraMap m_visibleAuras;
|
||||
|
||||
Reference in New Issue
Block a user