From 52873a7072ceb1f88d9caeefdda6084e6bb1d4af Mon Sep 17 00:00:00 2001 From: ariel- Date: Sun, 11 Feb 2018 22:22:04 -0300 Subject: Core/Spells: calculate crit chance only for spells that do damage/healing Refs #18813 --- src/server/game/Entities/Unit/Unit.cpp | 8 ++--- src/server/game/Entities/Unit/Unit.h | 4 +-- src/server/game/Spells/Auras/SpellAuraEffects.cpp | 7 ++++- src/server/game/Spells/Auras/SpellAuras.cpp | 5 ++- src/server/game/Spells/SpellInfo.h | 1 + src/server/game/Spells/SpellMgr.cpp | 38 ++++++++++++++++++----- 6 files changed, 47 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index aafef41809a..34838bd3f67 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -7374,14 +7374,14 @@ int32 Unit::SpellBaseDamageBonusTaken(SpellSchoolMask schoolMask) const return GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_DAMAGE_TAKEN, schoolMask); } -float Unit::SpellCritChanceDone(SpellInfo const* spellInfo, SpellSchoolMask schoolMask, WeaponAttackType attackType /*= BASE_ATTACK*/) const +float Unit::SpellCritChanceDone(SpellInfo const* spellInfo, SpellSchoolMask schoolMask, WeaponAttackType attackType /*= BASE_ATTACK*/, bool isPeriodic /*= false*/) const { //! Mobs can't crit with spells. (Except player controlled) if (GetTypeId() == TYPEID_UNIT && !GetSpellModOwner()) return 0.0f; // not critting spell - if (spellInfo->HasAttribute(SPELL_ATTR2_CANT_CRIT)) + if (!isPeriodic && !spellInfo->HasAttribute(SPELL_ATTR0_CU_CAN_CRIT)) return 0.0f; float crit_chance = 0.0f; @@ -7420,10 +7420,10 @@ float Unit::SpellCritChanceDone(SpellInfo const* spellInfo, SpellSchoolMask scho return std::max(crit_chance, 0.0f); } -float Unit::SpellCritChanceTaken(Unit const* caster, SpellInfo const* spellInfo, SpellSchoolMask schoolMask, float doneChance, WeaponAttackType attackType /*= BASE_ATTACK*/) const +float Unit::SpellCritChanceTaken(Unit const* caster, SpellInfo const* spellInfo, SpellSchoolMask schoolMask, float doneChance, WeaponAttackType attackType /*= BASE_ATTACK*/, bool isPeriodic /*= false*/) const { // not critting spell - if (spellInfo->HasAttribute(SPELL_ATTR2_CANT_CRIT)) + if (!isPeriodic && !spellInfo->HasAttribute(SPELL_ATTR0_CU_CAN_CRIT)) return 0.0f; float crit_chance = doneChance; diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index c05c84dc6d0..56883760971 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1529,8 +1529,8 @@ class TC_GAME_API Unit : public WorldObject bool isSpellBlocked(Unit* victim, SpellInfo const* spellProto, WeaponAttackType attackType = BASE_ATTACK); bool isBlockCritical(); - float SpellCritChanceDone(SpellInfo const* spellInfo, SpellSchoolMask schoolMask, WeaponAttackType attackType = BASE_ATTACK) const; - float SpellCritChanceTaken(Unit const* caster, SpellInfo const* spellInfo, SpellSchoolMask schoolMask, float doneChance, WeaponAttackType attackType = BASE_ATTACK) const; + float SpellCritChanceDone(SpellInfo const* spellInfo, SpellSchoolMask schoolMask, WeaponAttackType attackType = BASE_ATTACK, bool isPeriodic = false) const; + float SpellCritChanceTaken(Unit const* caster, SpellInfo const* spellInfo, SpellSchoolMask schoolMask, float doneChance, WeaponAttackType attackType = BASE_ATTACK, bool isPeriodic = false) const; static uint32 SpellCriticalDamageBonus(Unit const* caster, SpellInfo const* spellProto, uint32 damage, Unit* victim); static uint32 SpellCriticalHealingBonus(Unit const* caster, SpellInfo const* spellProto, uint32 damage, Unit* victim); diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 1efc9da2a58..b7ced522b18 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -818,7 +818,7 @@ void AuraEffect::Update(uint32 diff, Unit* caster) float AuraEffect::GetCritChanceFor(Unit const* caster, Unit const* target) const { - return target->SpellCritChanceTaken(caster, GetSpellInfo(), GetSpellInfo()->GetSchoolMask(), GetBase()->GetCritChance(), GetSpellInfo()->GetAttackType()); + return target->SpellCritChanceTaken(caster, GetSpellInfo(), GetSpellInfo()->GetSchoolMask(), GetBase()->GetCritChance(), GetSpellInfo()->GetAttackType(), true); } bool AuraEffect::IsAffectedOnSpell(SpellInfo const* spell) const @@ -959,6 +959,11 @@ bool AuraEffect::CheckEffectProc(AuraApplication* aurApp, ProcEventInfo& eventIn return false; break; } + case SPELL_AURA_MOD_SPELL_CRIT_CHANCE: + // skip spells that can't crit + if (!spellInfo || !spellInfo->HasAttribute(SPELL_ATTR0_CU_CAN_CRIT)) + return false; + break; default: break; } diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 857a985f0e5..f59c19360c8 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -389,6 +389,9 @@ void Aura::_InitEffects(uint8 effMask, Unit* caster, int32 *baseAmount) bool Aura::CanPeriodicTickCrit(Unit const* caster) const { + if (GetSpellInfo()->HasAttribute(SPELL_ATTR2_CANT_CRIT)) + return false; + if (caster->HasAuraTypeWithAffectMask(SPELL_AURA_ABILITY_PERIODIC_CRIT, GetSpellInfo())) return true; @@ -405,7 +408,7 @@ float Aura::CalcPeriodicCritChance(Unit const* caster) const if (!modOwner || !CanPeriodicTickCrit(modOwner)) return 0.f; - float critChance = modOwner->SpellCritChanceDone(GetSpellInfo(), GetSpellInfo()->GetSchoolMask(), GetSpellInfo()->GetAttackType()); + float critChance = modOwner->SpellCritChanceDone(GetSpellInfo(), GetSpellInfo()->GetSchoolMask(), GetSpellInfo()->GetAttackType(), true); return std::max(0.f, critChance); } diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index 37371cb6fbf..e117319a7f1 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -182,6 +182,7 @@ enum SpellCustomAttributes SPELL_ATTR0_CU_NO_INITIAL_THREAT = 0x00000010, SPELL_ATTR0_CU_AURA_CC = 0x00000020, SPELL_ATTR0_CU_DONT_BREAK_STEALTH = 0x00000040, + SPELL_ATTR0_CU_CAN_CRIT = 0x00000080, SPELL_ATTR0_CU_DIRECT_DAMAGE = 0x00000100, SPELL_ATTR0_CU_CHARGE = 0x00000200, SPELL_ATTR0_CU_PICKPOCKET = 0x00000400, diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index d42dfdd5b2a..a1e47697481 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -2645,6 +2645,22 @@ void SpellMgr::LoadSpellInfoCustomAttributes() break; } + switch (spellInfo->Effects[j].Effect) + { + case SPELL_EFFECT_SCHOOL_DAMAGE: + case SPELL_EFFECT_HEALTH_LEECH: + case SPELL_EFFECT_HEAL: + case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL: + case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE: + case SPELL_EFFECT_WEAPON_DAMAGE: + case SPELL_EFFECT_POWER_BURN: + case SPELL_EFFECT_HEAL_MECHANICAL: + case SPELL_EFFECT_NORMALIZED_WEAPON_DMG: + case SPELL_EFFECT_HEAL_PCT: + spellInfo->AttributesCu |= SPELL_ATTR0_CU_CAN_CRIT; + break; + } + switch (spellInfo->Effects[j].Effect) { case SPELL_EFFECT_SCHOOL_DAMAGE: @@ -2862,6 +2878,20 @@ void SpellMgr::LoadSpellInfoCustomAttributes() spellInfo->AttributesCu &= ~SPELL_ATTR0_CU_BINARY_SPELL; } + // remove attribute from spells that can't crit + for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i) + { + spellInfo = mSpellInfoMap[i]; + if (!spellInfo) + continue; + + if (!spellInfo->HasAttribute(SPELL_ATTR0_CU_CAN_CRIT)) + continue; + + if (spellInfo->HasAttribute(SPELL_ATTR2_CANT_CRIT)) + spellInfo->AttributesCu &= ~SPELL_ATTR0_CU_CAN_CRIT; + } + TC_LOG_INFO("server.loading", ">> Loaded SpellInfo custom attributes in %u ms", GetMSTimeDiffToNow(oldMSTime)); } @@ -3186,14 +3216,6 @@ void SpellMgr::LoadSpellInfoCorrections() spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_20_YARDS); }); - // Arcane Potency - ApplySpellFix({ 57529, 57531 }, [](SpellInfo* spellInfo) - { - spellInfo->Effects[EFFECT_0].SpellClassMask = flag96(); - spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_ADD_FLAT_MODIFIER; - spellInfo->Effects[EFFECT_0].MiscValue = SPELLMOD_CRITICAL_CHANCE; - }); - ApplySpellFix({ 44978, // Wild Magic 45001, // Wild Magic -- cgit v1.2.3