From 77da8695b092d20e415663ae6c542ca91adfb317 Mon Sep 17 00:00:00 2001 From: MantisLord Date: Mon, 19 Feb 2024 21:41:48 -0500 Subject: [PATCH] [z2817] Use bonus coefficient data from spell_template/DBC --- sql/base/mangos.sql | 2 +- .../mangos/z2817_01_mangos_spell_template.sql | 8 + src/game/Chat/Chat.cpp | 1 - src/game/Chat/Chat.h | 1 - src/game/Chat/Level3.cpp | 9 -- src/game/Chat/debugcmds.cpp | 6 +- src/game/Entities/Unit.cpp | 60 +++----- src/game/Entities/Unit.h | 16 +- src/game/Server/DBCStructure.h | 5 +- src/game/Server/SQLStorages.cpp | 2 +- .../Scripting/ClassScripts/Warlock.cpp | 4 +- src/game/Spells/Spell.cpp | 10 +- src/game/Spells/Spell.h | 2 +- src/game/Spells/SpellAuras.cpp | 26 ++-- src/game/Spells/SpellEffects.cpp | 22 +-- src/game/Spells/SpellMgr.cpp | 143 ------------------ src/game/Spells/SpellMgr.h | 23 --- src/game/Spells/UnitAuraProcHandler.cpp | 2 +- src/game/World/World.cpp | 3 - src/shared/revision_sql.h | 2 +- 20 files changed, 82 insertions(+), 265 deletions(-) create mode 100644 sql/updates/mangos/z2817_01_mangos_spell_template.sql diff --git a/sql/base/mangos.sql b/sql/base/mangos.sql index 5caad1b78c..d324f3c881 100644 --- a/sql/base/mangos.sql +++ b/sql/base/mangos.sql @@ -23,7 +23,7 @@ DROP TABLE IF EXISTS `db_version`; CREATE TABLE `db_version` ( `version` varchar(120) DEFAULT NULL, `creature_ai_version` varchar(120) DEFAULT NULL, - `required_z2816_01_mangos_precision_decimal` bit(1) DEFAULT NULL + `required_z2817_01_mangos_spell_template` bit(1) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Used DB version notes'; -- diff --git a/sql/updates/mangos/z2817_01_mangos_spell_template.sql b/sql/updates/mangos/z2817_01_mangos_spell_template.sql new file mode 100644 index 0000000000..decfe7df2b --- /dev/null +++ b/sql/updates/mangos/z2817_01_mangos_spell_template.sql @@ -0,0 +1,8 @@ +ALTER TABLE db_version CHANGE COLUMN required_z2816_01_mangos_precision_decimal required_z2817_01_mangos_spell_template bit; + +ALTER TABLE `spell_template` + ADD COLUMN `EffectBonusCoefficient1` FLOAT NOT NULL DEFAULT '0' AFTER `RequiredAuraVision`, + ADD COLUMN `EffectBonusCoefficient2` FLOAT NOT NULL DEFAULT '0' AFTER `EffectBonusCoefficient1`, + ADD COLUMN `EffectBonusCoefficient3` FLOAT NOT NULL DEFAULT '0' AFTER `EffectBonusCoefficient2`; + +DROP TABLE `spell_bonus_data`; diff --git a/src/game/Chat/Chat.cpp b/src/game/Chat/Chat.cpp index a302382eb5..f184d3c266 100644 --- a/src/game/Chat/Chat.cpp +++ b/src/game/Chat/Chat.cpp @@ -673,7 +673,6 @@ ChatCommand* ChatHandler::getCommandTable() { "spam_records", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadExpectedSpamRecords, "", nullptr }, { "spell_affect", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellAffectCommand, "", nullptr }, { "spell_area", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellAreaCommand, "", nullptr }, - { "spell_bonus_data", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellBonusesCommand, "", nullptr }, { "spell_chain", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellChainCommand, "", nullptr }, { "spell_elixir", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellElixirCommand, "", nullptr }, { "spell_learn_spell", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellLearnSpellCommand, "", nullptr }, diff --git a/src/game/Chat/Chat.h b/src/game/Chat/Chat.h index f0a063d9b0..196fb02181 100644 --- a/src/game/Chat/Chat.h +++ b/src/game/Chat/Chat.h @@ -593,7 +593,6 @@ class ChatHandler bool HandleReloadSkillFishingBaseLevelCommand(char* args); bool HandleReloadSpellAffectCommand(char* args); bool HandleReloadSpellAreaCommand(char* args); - bool HandleReloadSpellBonusesCommand(char* args); bool HandleReloadSpellChainCommand(char* args); bool HandleReloadSpellElixirCommand(char* args); bool HandleReloadSpellLearnSpellCommand(char* args); diff --git a/src/game/Chat/Level3.cpp b/src/game/Chat/Level3.cpp index b8cbdd4b63..d865b07895 100644 --- a/src/game/Chat/Level3.cpp +++ b/src/game/Chat/Level3.cpp @@ -270,7 +270,6 @@ bool ChatHandler::HandleReloadAllSpellCommand(char* /*args*/) HandleReloadSpellElixirCommand((char*)"a"); HandleReloadSpellLearnSpellCommand((char*)"a"); HandleReloadSpellProcEventCommand((char*)"a"); - HandleReloadSpellBonusesCommand((char*)"a"); HandleReloadSpellProcItemEnchantCommand((char*)"a"); HandleReloadSpellScriptTargetCommand((char*)"a"); HandleReloadSpellTargetPositionCommand((char*)"a"); @@ -647,14 +646,6 @@ bool ChatHandler::HandleReloadSpellAreaCommand(char* /*args*/) return true; } -bool ChatHandler::HandleReloadSpellBonusesCommand(char* /*args*/) -{ - sLog.outString("Re-Loading Spell Bonus Data..."); - sSpellMgr.LoadSpellBonuses(); - SendGlobalSysMessage("DB table `spell_bonus_data` (spell damage/healing coefficients) reloaded."); - return true; -} - bool ChatHandler::HandleReloadSpellChainCommand(char* /*args*/) { sLog.outString("Re-Loading Spell Chain Data... "); diff --git a/src/game/Chat/debugcmds.cpp b/src/game/Chat/debugcmds.cpp index b41f149adf..bfc10a6286 100644 --- a/src/game/Chat/debugcmds.cpp +++ b/src/game/Chat/debugcmds.cpp @@ -1289,8 +1289,6 @@ bool ChatHandler::HandleDebugSpellCoefsCommand(char* args) if (!spellEntry) return false; - SpellBonusEntry const* bonus = sSpellMgr.GetSpellBonusData(spellid); - float direct_calc = CalculateDefaultCoefficient(spellEntry, SPELL_DIRECT_DAMAGE); float dot_calc = CalculateDefaultCoefficient(spellEntry, DOT); @@ -1323,9 +1321,9 @@ bool ChatHandler::HandleDebugSpellCoefsCommand(char* args) char const* dotDamageStr = GetMangosString(LANG_DOT_DAMAGE); PSendSysMessage(LANG_SPELLCOEFS, spellid, isDirectHeal ? directHealStr : directDamageStr, - direct_calc, direct_calc * 1.88f, bonus ? bonus->direct_damage : 0.0f, bonus ? bonus->ap_bonus : 0.0f); + direct_calc, direct_calc * 1.88f, spellEntry->effectBonusCoefficient[0], 0.0f); PSendSysMessage(LANG_SPELLCOEFS, spellid, isDotHeal ? dotHealStr : dotDamageStr, - dot_calc, dot_calc * 1.88f, bonus ? bonus->dot_damage : 0.0f, bonus ? bonus->ap_dot_bonus : 0.0f); + dot_calc, dot_calc * 1.88f, spellEntry->effectBonusCoefficient[0], 0.0f); return true; } diff --git a/src/game/Entities/Unit.cpp b/src/game/Entities/Unit.cpp index aa0242924d..e2ebf03efa 100644 --- a/src/game/Entities/Unit.cpp +++ b/src/game/Entities/Unit.cpp @@ -1730,7 +1730,7 @@ uint32 Unit::SpellNonMeleeDamageLog(Unit* pVictim, uint32 spellID, uint32 damage { SpellEntry const* spellInfo = sSpellTemplate.LookupEntry(spellID); SpellNonMeleeDamage spellDamageInfo(this, pVictim, spellInfo->Id, SpellSchools(spellInfo->School)); - CalculateSpellDamage(&spellDamageInfo, damage, spellInfo); + CalculateSpellDamage(&spellDamageInfo, damage, spellInfo, EFFECT_INDEX_0); spellDamageInfo.target->CalculateAbsorbResistBlock(this, &spellDamageInfo, spellInfo); Unit::DealDamageMods(this, spellDamageInfo.target, spellDamageInfo.damage, &spellDamageInfo.absorb, SPELL_DIRECT_DAMAGE); SendSpellNonMeleeDamageLog(&spellDamageInfo); @@ -1738,7 +1738,7 @@ uint32 Unit::SpellNonMeleeDamageLog(Unit* pVictim, uint32 spellID, uint32 damage return spellDamageInfo.damage; } -void Unit::CalculateSpellDamage(SpellNonMeleeDamage* spellDamageInfo, int32 damage, SpellEntry const* spellInfo, WeaponAttackType attackType) +void Unit::CalculateSpellDamage(SpellNonMeleeDamage* spellDamageInfo, int32 damage, SpellEntry const* spellInfo, SpellEffectIndex effectIndex, WeaponAttackType attackType) { SpellSchoolMask damageSchoolMask = GetSchoolMask(spellDamageInfo->school); Unit* pVictim = spellDamageInfo->target; @@ -1760,8 +1760,8 @@ void Unit::CalculateSpellDamage(SpellNonMeleeDamage* spellDamageInfo, int32 dama case SPELL_DAMAGE_CLASS_MELEE: { // Calculate damage bonus - damage = MeleeDamageBonusDone(pVictim, damage, attackType, damageSchoolMask, spellInfo, SPELL_DIRECT_DAMAGE); - damage = pVictim->MeleeDamageBonusTaken(this, damage, attackType, damageSchoolMask, spellInfo, SPELL_DIRECT_DAMAGE); + damage = MeleeDamageBonusDone(pVictim, damage, attackType, damageSchoolMask, spellInfo, effectIndex, SPELL_DIRECT_DAMAGE); + damage = pVictim->MeleeDamageBonusTaken(this, damage, attackType, damageSchoolMask, spellInfo, effectIndex, SPELL_DIRECT_DAMAGE); } break; // Magical Attacks @@ -1769,8 +1769,8 @@ void Unit::CalculateSpellDamage(SpellNonMeleeDamage* spellDamageInfo, int32 dama case SPELL_DAMAGE_CLASS_MAGIC: { // Calculate damage bonus - damage = SpellDamageBonusDone(pVictim, damageSchoolMask, spellInfo, damage, SPELL_DIRECT_DAMAGE); - damage = pVictim->SpellDamageBonusTaken(this, damageSchoolMask, spellInfo, damage, SPELL_DIRECT_DAMAGE); + damage = SpellDamageBonusDone(pVictim, damageSchoolMask, spellInfo, effectIndex, damage, SPELL_DIRECT_DAMAGE); + damage = pVictim->SpellDamageBonusTaken(this, damageSchoolMask, spellInfo, effectIndex, damage, SPELL_DIRECT_DAMAGE); } break; } @@ -1883,8 +1883,8 @@ void Unit::CalculateMeleeDamage(Unit* pVictim, CalcDamageInfo* calcDamageInfo, W subDamage->damage = CalculateDamage(calcDamageInfo->attackType, false, i); // Add melee damage bonus - subDamage->damage = MeleeDamageBonusDone(calcDamageInfo->target, subDamage->damage, calcDamageInfo->attackType, subDamage->damageSchoolMask, nullptr, DIRECT_DAMAGE, 1, i == 0); - subDamage->damage = calcDamageInfo->target->MeleeDamageBonusTaken(this, subDamage->damage, calcDamageInfo->attackType, subDamage->damageSchoolMask, nullptr, DIRECT_DAMAGE, 1, i == 0); + subDamage->damage = MeleeDamageBonusDone(calcDamageInfo->target, subDamage->damage, calcDamageInfo->attackType, subDamage->damageSchoolMask, nullptr, EFFECT_INDEX_0, DIRECT_DAMAGE, 1, i == 0); + subDamage->damage = calcDamageInfo->target->MeleeDamageBonusTaken(this, subDamage->damage, calcDamageInfo->attackType, subDamage->damageSchoolMask, nullptr, EFFECT_INDEX_0, DIRECT_DAMAGE, 1, i == 0); // Calculate armor reduction if (subDamage->damageSchoolMask == SPELL_SCHOOL_MASK_NORMAL) @@ -6887,7 +6887,7 @@ void Unit::EnergizeBySpell(Unit* victim, SpellEntry const* spellInfo, uint32 dam * @param damagetype what kind of damage * @param donePart calculate for done or taken */ -int32 Unit::SpellBonusWithCoeffs(SpellEntry const* spellProto, int32 total, int32 benefit, int32 ap_benefit, DamageEffectType damagetype, bool donePart) +int32 Unit::SpellBonusWithCoeffs(SpellEntry const* spellProto, SpellEffectIndex effectIndex, int32 total, int32 benefit, int32 ap_benefit, DamageEffectType damagetype, bool donePart) { // Distribute Damage over multiple effects, reduce by AoE float coeff = 1.0f; @@ -6896,18 +6896,8 @@ int32 Unit::SpellBonusWithCoeffs(SpellEntry const* spellProto, int32 total, int3 if (GetTypeId() == TYPEID_UNIT && !((Creature*)this)->IsPet()) coeff = 1.0f; // Check for table values - else if (SpellBonusEntry const* bonus = sSpellMgr.GetSpellBonusData(spellProto->Id)) - { - coeff = damagetype == DOT ? bonus->dot_damage : bonus->direct_damage; - - // apply ap bonus at done part calculation only (it flat total mod so common with taken) - if (donePart && (bonus->ap_bonus || bonus->ap_dot_bonus)) - { - float ap_bonus = damagetype == DOT ? bonus->ap_dot_bonus : bonus->ap_bonus; - - total += int32(ap_bonus * (GetTotalAttackPowerValue(IsSpellRequiresRangedAP(spellProto) ? RANGED_ATTACK : BASE_ATTACK) + ap_benefit)); - } - } + if (spellProto->effectBonusCoefficient[effectIndex] > 0) + coeff = spellProto->effectBonusCoefficient[effectIndex]; // Default calculation else if (benefit) coeff = CalculateDefaultCoefficient(spellProto, damagetype); @@ -6937,7 +6927,7 @@ int32 Unit::SpellBonusWithCoeffs(SpellEntry const* spellProto, int32 total, int3 * Calculates caster part of spellInfo damage bonuses, * also includes different bonuses dependent from target auras */ -uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellSchoolMask schoolMask, SpellEntry const* spellInfo, uint32 pdamage, DamageEffectType damagetype, uint32 stack) +uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellSchoolMask schoolMask, SpellEntry const* spellInfo, SpellEffectIndex effectIndex, uint32 pdamage, DamageEffectType damagetype, uint32 stack) { if (!spellInfo || !victim || damagetype == DIRECT_DAMAGE) return pdamage; @@ -6950,7 +6940,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellSchoolMask schoolMask, Spel if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->IsTotem() && ((Totem*)this)->GetTotemType() != TOTEM_STATUE) { if (Unit* owner = GetOwner()) - return owner->SpellDamageBonusDone(victim, schoolMask, spellInfo, pdamage, damagetype); + return owner->SpellDamageBonusDone(victim, schoolMask, spellInfo, effectIndex, pdamage, damagetype); } uint32 creatureTypeMask = victim->GetCreatureTypeMask(); @@ -7004,7 +6994,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellSchoolMask schoolMask, Spel DoneAdvertisedBenefit += ((Pet*)this)->GetBonusDamage(); // apply ap bonus and benefit affected by spellInfo power implicit coeffs and spellInfo level penalties - DoneTotal = SpellBonusWithCoeffs(spellInfo, DoneTotal, DoneAdvertisedBenefit, 0, damagetype, true); + DoneTotal = SpellBonusWithCoeffs(spellInfo, effectIndex, DoneTotal, DoneAdvertisedBenefit, 0, damagetype, true); float tmpDamage = (int32(pdamage) + DoneTotal * int32(stack)) * DoneTotalMod; // apply spellmod to Done damage (flat and pct) @@ -7018,7 +7008,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellSchoolMask schoolMask, Spel * Calculates target part of spellInfo damage bonuses, * will be called on each tick for periodic damage over time auras */ -uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellSchoolMask schoolMask, SpellEntry const* spellInfo, uint32 pdamage, DamageEffectType damagetype, uint32 stack) +uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellSchoolMask schoolMask, SpellEntry const* spellInfo, SpellEffectIndex effectIndex, uint32 pdamage, DamageEffectType damagetype, uint32 stack) { if (!spellInfo || damagetype == DIRECT_DAMAGE || spellInfo->HasAttribute(SPELL_ATTR_EX4_IGNORE_DAMAGE_TAKEN_MODIFIERS)) return pdamage; @@ -7042,7 +7032,7 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellSchoolMask schoolMask, Spe // apply benefit affected by spellInfo power implicit coeffs and spellInfo level penalties if (caster) - TakenTotal = caster->SpellBonusWithCoeffs(spellInfo, TakenTotal, TakenAdvertisedBenefit, 0, damagetype, false); + TakenTotal = caster->SpellBonusWithCoeffs(spellInfo, effectIndex, TakenTotal, TakenAdvertisedBenefit, 0, damagetype, false); float tmpDamage = (int32(pdamage) + TakenTotal * int32(stack)) * TakenTotalMod; @@ -7099,7 +7089,7 @@ int32 Unit::SpellBaseDamageBonusTaken(SpellSchoolMask schoolMask) const * Calculates caster part of healing spellInfo bonuses, * also includes different bonuses dependent from target auras */ -uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellEntry const* spellInfo, int32 healamount, DamageEffectType damagetype, uint32 stack) +uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellEntry const* spellInfo, SpellEffectIndex effectIndex, int32 healamount, DamageEffectType damagetype, uint32 stack) { // Some spells don't benefit from done mods if (spellInfo->HasAttribute(SPELL_ATTR_EX3_IGNORE_CASTER_MODIFIERS)) @@ -7108,7 +7098,7 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellEntry const* spellInfo, in // For totems get healing bonus from owner (statue isn't totem in fact) if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->IsTotem() && ((Totem*)this)->GetTotemType() != TOTEM_STATUE) if (Unit* owner = GetOwner()) - return owner->SpellHealingBonusDone(victim, spellInfo, healamount, damagetype, stack); + return owner->SpellHealingBonusDone(victim, spellInfo, effectIndex, healamount, damagetype, stack); // No heal amount for this class spells if (spellInfo->DmgClass == SPELL_DAMAGE_CLASS_NONE) @@ -7139,7 +7129,7 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellEntry const* spellInfo, in } // apply ap bonus and benefit affected by spellInfo power implicit coeffs and spellInfo level penalties - DoneTotal = SpellBonusWithCoeffs(spellInfo, DoneTotal, DoneAdvertisedBenefit, 0, damagetype, true); + DoneTotal = SpellBonusWithCoeffs(spellInfo, effectIndex, DoneTotal, DoneAdvertisedBenefit, 0, damagetype, true); // use float as more appropriate for negative values and percent applying float heal = (healamount + DoneTotal * int32(stack)) * DoneTotalMod; @@ -7154,7 +7144,7 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellEntry const* spellInfo, in * Calculates target part of healing spellInfo bonuses, * will be called on each tick for periodic damage over time auras */ -uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellEntry const* spellInfo, int32 healamount, DamageEffectType damagetype, uint32 stack) +uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellEntry const* spellInfo, SpellEffectIndex effectIndex, int32 healamount, DamageEffectType damagetype, uint32 stack) { float TakenTotalMod = 1.0f; @@ -7189,7 +7179,7 @@ uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellEntry const* spellInfo, i } // apply benefit affected by spellInfo power implicit coeffs and spellInfo level penalties - TakenTotal = caster->SpellBonusWithCoeffs(spellInfo, TakenTotal, TakenAdvertisedBenefit, 0, damagetype, false); + TakenTotal = caster->SpellBonusWithCoeffs(spellInfo, effectIndex, TakenTotal, TakenAdvertisedBenefit, 0, damagetype, false); // use float as more appropriate for negative values and percent applying float heal = (healamount + TakenTotal * int32(stack)) * TakenTotalMod; @@ -7345,7 +7335,7 @@ bool Unit::IsImmuneToSchool(SpellEntry const* spellInfo, uint8 effectMask) const * Calculates caster part of melee damage bonuses, * also includes different bonuses dependent from target auras */ -uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType attType, SpellSchoolMask schoolMask, SpellEntry const* spellInfo, DamageEffectType damagetype, uint32 stack, bool flat) +uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType attType, SpellSchoolMask schoolMask, SpellEntry const* spellInfo, SpellEffectIndex effectIndex, DamageEffectType damagetype, uint32 stack, bool flat) { if (!victim || pdamage == 0) return pdamage; @@ -7472,7 +7462,7 @@ uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType if (!isWeaponDamageBasedSpell || (spellInfo && (schoolMask &~ SPELL_SCHOOL_MASK_NORMAL) !=0)) { // apply ap bonus and benefit affected by spellInfo power implicit coeffs and spellInfo level penalties - DoneTotal = SpellBonusWithCoeffs(spellInfo, DoneTotal, DoneFlat, APbonus, damagetype, true); + DoneTotal = SpellBonusWithCoeffs(spellInfo, effectIndex, DoneTotal, DoneFlat, APbonus, damagetype, true); } // weapon damage based spells else if (isWeaponDamageBasedSpell && (APbonus || DoneFlat)) @@ -7517,7 +7507,7 @@ uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType * Calculates target part of melee damage bonuses, * will be called on each tick for periodic damage over time auras */ -uint32 Unit::MeleeDamageBonusTaken(Unit* caster, uint32 pdamage, WeaponAttackType attType, SpellSchoolMask schoolMask, SpellEntry const* spellInfo, DamageEffectType damagetype, uint32 stack, bool flat) +uint32 Unit::MeleeDamageBonusTaken(Unit* caster, uint32 pdamage, WeaponAttackType attType, SpellSchoolMask schoolMask, SpellEntry const* spellInfo, SpellEffectIndex effectIndex, DamageEffectType damagetype, uint32 stack, bool flat) { if (pdamage == 0) return pdamage; @@ -7574,7 +7564,7 @@ uint32 Unit::MeleeDamageBonusTaken(Unit* caster, uint32 pdamage, WeaponAttackTyp { // apply benefit affected by spellInfo power implicit coeffs and spellInfo level penalties if (caster) - TakenAdvertisedBenefit = caster->SpellBonusWithCoeffs(spellInfo, 0, TakenAdvertisedBenefit, 0, damagetype, false); + TakenAdvertisedBenefit = caster->SpellBonusWithCoeffs(spellInfo, effectIndex, 0, TakenAdvertisedBenefit, 0, damagetype, false); } if (!flat) diff --git a/src/game/Entities/Unit.h b/src/game/Entities/Unit.h index ce81a31200..c752ff2d17 100644 --- a/src/game/Entities/Unit.h +++ b/src/game/Entities/Unit.h @@ -1472,7 +1472,7 @@ class Unit : public WorldObject void CalculateMeleeDamage(Unit* pVictim, CalcDamageInfo* calcDamageInfo, WeaponAttackType attackType = BASE_ATTACK); void DealMeleeDamage(CalcDamageInfo* calcDamageInfo, bool durabilityLoss); - void CalculateSpellDamage(SpellNonMeleeDamage* spellDamageInfo, int32 damage, SpellEntry const* spellInfo, WeaponAttackType attackType = BASE_ATTACK); + void CalculateSpellDamage(SpellNonMeleeDamage* spellDamageInfo, int32 damage, SpellEntry const* spellInfo, SpellEffectIndex effectIndex, WeaponAttackType attackType = BASE_ATTACK); static void DealSpellDamage(Unit* affectiveCaster, SpellNonMeleeDamage* spellDamageInfo, bool durabilityLoss, bool resetLeash); SpellMissInfo MeleeSpellHitResult(Unit* pVictim, SpellEntry const* spell, uint32* heartbeatResistChance = nullptr); @@ -2130,17 +2130,17 @@ class Unit : public WorldObject void UnsummonAllTotems() const; Unit* SelectMagnetTarget(Unit* victim, Spell* spell = nullptr); - int32 SpellBonusWithCoeffs(SpellEntry const* spellProto, int32 total, int32 benefit, int32 ap_benefit, DamageEffectType damagetype, bool donePart); + int32 SpellBonusWithCoeffs(SpellEntry const* spellProto, SpellEffectIndex effectIndex, int32 total, int32 benefit, int32 ap_benefit, DamageEffectType damagetype, bool donePart); int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask); int32 SpellBaseDamageBonusTaken(SpellSchoolMask schoolMask) const; - uint32 SpellDamageBonusDone(Unit* victim, SpellSchoolMask schoolMask, SpellEntry const* spellInfo, uint32 pdamage, DamageEffectType damagetype, uint32 stack = 1); - uint32 SpellDamageBonusTaken(Unit* caster, SpellSchoolMask schoolMask, SpellEntry const* spellInfo, uint32 pdamage, DamageEffectType damagetype, uint32 stack = 1); + uint32 SpellDamageBonusDone(Unit* victim, SpellSchoolMask schoolMask, SpellEntry const* spellInfo, SpellEffectIndex effectIndex, uint32 pdamage, DamageEffectType damagetype, uint32 stack = 1); + uint32 SpellDamageBonusTaken(Unit* caster, SpellSchoolMask schoolMask, SpellEntry const* spellInfo, SpellEffectIndex effectIndex, uint32 pdamage, DamageEffectType damagetype, uint32 stack = 1); int32 SpellBaseHealingBonusDone(SpellSchoolMask schoolMask); int32 SpellBaseHealingBonusTaken(SpellSchoolMask schoolMask) const; - uint32 SpellHealingBonusDone(Unit* victim, SpellEntry const* spellInfo, int32 healamount, DamageEffectType damagetype, uint32 stack = 1); - uint32 SpellHealingBonusTaken(Unit* caster, SpellEntry const* spellInfo, int32 healamount, DamageEffectType damagetype, uint32 stack = 1); - uint32 MeleeDamageBonusDone(Unit* victim, uint32 damage, WeaponAttackType attType, SpellSchoolMask schoolMask, SpellEntry const* spellInfo = nullptr, DamageEffectType damagetype = DIRECT_DAMAGE, uint32 stack = 1, bool flat = true); - uint32 MeleeDamageBonusTaken(Unit* caster, uint32 pdamage, WeaponAttackType attType, SpellSchoolMask schoolMask, SpellEntry const* spellInfo = nullptr, DamageEffectType damagetype = DIRECT_DAMAGE, uint32 stack = 1, bool flat = true); + uint32 SpellHealingBonusDone(Unit* victim, SpellEntry const* spellInfo, SpellEffectIndex effectIndex, int32 healamount, DamageEffectType damagetype, uint32 stack = 1); + uint32 SpellHealingBonusTaken(Unit* caster, SpellEntry const* spellInfo, SpellEffectIndex effectIndex, int32 healamount, DamageEffectType damagetype, uint32 stack = 1); + uint32 MeleeDamageBonusDone(Unit* victim, uint32 damage, WeaponAttackType attType, SpellSchoolMask schoolMask, SpellEntry const* spellInfo = nullptr, SpellEffectIndex effectIndex = EFFECT_INDEX_0, DamageEffectType damagetype = DIRECT_DAMAGE, uint32 stack = 1, bool flat = true); + uint32 MeleeDamageBonusTaken(Unit* caster, uint32 pdamage, WeaponAttackType attType, SpellSchoolMask schoolMask, SpellEntry const* spellInfo = nullptr, SpellEffectIndex effectIndex = EFFECT_INDEX_0, DamageEffectType damagetype = DIRECT_DAMAGE, uint32 stack = 1, bool flat = true); enum class SpellProcEventTriggerCheck { diff --git a/src/game/Server/DBCStructure.h b/src/game/Server/DBCStructure.h index 0ff009bedb..1be3836052 100644 --- a/src/game/Server/DBCStructure.h +++ b/src/game/Server/DBCStructure.h @@ -785,10 +785,11 @@ struct SpellEntry uint32 MinFactionId; // 170 not used, and 0 in 2.4.2 uint32 MinReputation; // 171 not used, and 0 in 2.4.2 uint32 RequiredAuraVision; // 172 not used + float effectBonusCoefficient[MAX_EFFECT_INDEX]; // 173-175 (filled from SpellEffects.db2) // custom - uint32 IsServerSide; // 173 - uint32 AttributesServerside; // 174 + uint32 IsServerSide; // 176 + uint32 AttributesServerside; // 177 // helpers int32 CalculateSimpleValue(SpellEffectIndex eff) const { return EffectBasePoints[eff] + int32(EffectBaseDice[eff]); } diff --git a/src/game/Server/SQLStorages.cpp b/src/game/Server/SQLStorages.cpp index a82faf31a0..bafd3a28c9 100644 --- a/src/game/Server/SQLStorages.cpp +++ b/src/game/Server/SQLStorages.cpp @@ -37,7 +37,7 @@ const char WorldTemplatesrcfmt[] = "is"; const char WorldTemplatedstfmt[] = "ii"; const char ConditionsFmt[] = "iiiiiiix"; const char SpellScriptTargetFmt[] = "iiii"; -const char SpellEntryfmt[] = "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffffffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiifffiiiissssssssssssssssiiiiiLiiiifffiiiii"; +const char SpellEntryfmt[] = "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffffffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiifffiiiissssssssssssssssiiiiiLiiiifffiiifffii"; const char SpellConefmt[] = "ii"; const char DungeonEncounterFmt[] = "iiiiiissssssssssssssssii"; const char WorldSafeLocsFmt[] = "iiffffs"; diff --git a/src/game/Spells/Scripts/Scripting/ClassScripts/Warlock.cpp b/src/game/Spells/Scripts/Scripting/ClassScripts/Warlock.cpp index abe8fe6b9c..56df804b78 100644 --- a/src/game/Spells/Scripts/Scripting/ClassScripts/Warlock.cpp +++ b/src/game/Spells/Scripts/Scripting/ClassScripts/Warlock.cpp @@ -44,8 +44,8 @@ struct LifeTap : public SpellScript if (Player* modOwner = caster->GetSpellModOwner()) modOwner->ApplySpellMod(spell->m_spellInfo->Id, SPELLMOD_COST, cost); - int32 dmg = caster->SpellDamageBonusDone(caster, GetSpellSchoolMask(spell->m_spellInfo), spell->m_spellInfo, uint32(cost > 0 ? cost : 0), SPELL_DIRECT_DAMAGE); - dmg = caster->SpellDamageBonusTaken(caster, GetSpellSchoolMask(spell->m_spellInfo), spell->m_spellInfo, dmg, SPELL_DIRECT_DAMAGE); + int32 dmg = caster->SpellDamageBonusDone(caster, GetSpellSchoolMask(spell->m_spellInfo), spell->m_spellInfo, EFFECT_INDEX_0, uint32(cost > 0 ? cost : 0), SPELL_DIRECT_DAMAGE); + dmg = caster->SpellDamageBonusTaken(caster, GetSpellSchoolMask(spell->m_spellInfo), spell->m_spellInfo, EFFECT_INDEX_0, dmg, SPELL_DIRECT_DAMAGE); spell->SetScriptValue(dmg); } diff --git a/src/game/Spells/Spell.cpp b/src/game/Spells/Spell.cpp index 9f54f7dbdd..82b9791632 100644 --- a/src/game/Spells/Spell.cpp +++ b/src/game/Spells/Spell.cpp @@ -6263,7 +6263,7 @@ SpellCastResult Spell::CheckRange(bool strict) return SPELL_CAST_OK; } -int32 Spell::CalculateSpellEffectDamage(Unit* unitTarget, int32 damage, float damageDoneMod) +int32 Spell::CalculateSpellEffectDamage(Unit* unitTarget, int32 damage, float damageDoneMod, SpellEffectIndex effectIndex) { // damage bonus (per damage class) switch (m_spellInfo->DmgClass) @@ -6274,9 +6274,9 @@ int32 Spell::CalculateSpellEffectDamage(Unit* unitTarget, int32 damage, float da { // Calculate damage bonus if (!m_trueCaster->IsGameObject()) - damage = m_caster->MeleeDamageBonusDone(unitTarget, damage, m_attackType, m_spellSchoolMask, m_spellInfo, SPELL_DIRECT_DAMAGE); + damage = m_caster->MeleeDamageBonusDone(unitTarget, damage, m_attackType, m_spellSchoolMask, m_spellInfo, effectIndex, SPELL_DIRECT_DAMAGE); damage *= damageDoneMod; - damage = unitTarget->MeleeDamageBonusTaken(m_trueCaster->IsGameObject() ? nullptr : m_caster, damage, m_attackType, m_spellSchoolMask, m_spellInfo, SPELL_DIRECT_DAMAGE); + damage = unitTarget->MeleeDamageBonusTaken(m_trueCaster->IsGameObject() ? nullptr : m_caster, damage, m_attackType, m_spellSchoolMask, m_spellInfo, effectIndex, SPELL_DIRECT_DAMAGE); } break; // Magical Attacks @@ -6285,9 +6285,9 @@ int32 Spell::CalculateSpellEffectDamage(Unit* unitTarget, int32 damage, float da { // Calculate damage bonus if (!m_trueCaster->IsGameObject()) - damage = m_caster->SpellDamageBonusDone(unitTarget, m_spellSchoolMask, m_spellInfo, damage, SPELL_DIRECT_DAMAGE); + damage = m_caster->SpellDamageBonusDone(unitTarget, m_spellSchoolMask, m_spellInfo, effectIndex, damage, SPELL_DIRECT_DAMAGE); damage *= damageDoneMod; - damage = unitTarget->SpellDamageBonusTaken(m_trueCaster->IsGameObject() ? nullptr : m_caster, m_spellSchoolMask, m_spellInfo, damage, SPELL_DIRECT_DAMAGE); + damage = unitTarget->SpellDamageBonusTaken(m_trueCaster->IsGameObject() ? nullptr : m_caster, m_spellSchoolMask, m_spellInfo, effectIndex, damage, SPELL_DIRECT_DAMAGE); } break; } diff --git a/src/game/Spells/Spell.h b/src/game/Spells/Spell.h index 85b1e5eb44..ac4c67cef4 100644 --- a/src/game/Spells/Spell.h +++ b/src/game/Spells/Spell.h @@ -476,7 +476,7 @@ class Spell int32 CalculateSpellEffectValue(SpellEffectIndex i, Unit* target, bool maximum = false, bool finalUse = true) { return m_trueCaster->CalculateSpellEffectValue(target, m_spellInfo, i, &m_currentBasePoints[i], maximum, finalUse); } - int32 CalculateSpellEffectDamage(Unit* unitTarget, int32 damage, float damageDoneMod); + int32 CalculateSpellEffectDamage(Unit* unitTarget, int32 damage, float damageDoneMod, SpellEffectIndex effectIndex); static uint32 CalculatePowerCost(SpellEntry const* spellInfo, Unit* caster, Spell* spell = nullptr, Item* castItem = nullptr, bool finalUse = false); bool HaveTargetsForEffect(SpellEffectIndex effect) const; diff --git a/src/game/Spells/SpellAuras.cpp b/src/game/Spells/SpellAuras.cpp index bc0cf6b42e..796ac0a8d3 100644 --- a/src/game/Spells/SpellAuras.cpp +++ b/src/game/Spells/SpellAuras.cpp @@ -3207,7 +3207,7 @@ void Aura::HandlePeriodicHeal(bool apply, bool /*Real*/) switch (GetSpellProto()->Id) { case 12939: m_modifier.m_amount = target->GetMaxHealth() / 10; break; // Polymorph Heal Effect - default: m_modifier.m_amount = caster->SpellHealingBonusDone(target, GetSpellProto(), m_modifier.m_amount, DOT, GetStackAmount()); break; + default: m_modifier.m_amount = caster->SpellHealingBonusDone(target, GetSpellProto(), GetEffIndex(), m_modifier.m_amount, DOT, GetStackAmount()); break; } } } @@ -3276,12 +3276,12 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real) { // SpellDamageBonusDone for magic spells if (spellProto->DmgClass == SPELL_DAMAGE_CLASS_NONE || spellProto->DmgClass == SPELL_DAMAGE_CLASS_MAGIC) - m_modifier.m_amount = caster->SpellDamageBonusDone(target, GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), m_modifier.m_amount, DOT, GetStackAmount()); + m_modifier.m_amount = caster->SpellDamageBonusDone(target, GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), GetEffIndex(), m_modifier.m_amount, DOT, GetStackAmount()); // MeleeDamagebonusDone for weapon based spells else { WeaponAttackType attackType = GetWeaponAttackType(GetSpellProto()); - m_modifier.m_amount = caster->MeleeDamageBonusDone(target, m_modifier.m_amount, attackType, GetSpellSchoolMask(spellProto), spellProto, DOT, GetStackAmount()); + m_modifier.m_amount = caster->MeleeDamageBonusDone(target, m_modifier.m_amount, attackType, GetSpellSchoolMask(spellProto), spellProto, GetEffIndex(), DOT, GetStackAmount()); } } } @@ -3320,7 +3320,7 @@ void Aura::HandlePeriodicLeech(bool apply, bool /*Real*/) if (!caster) return; - m_modifier.m_amount = caster->SpellDamageBonusDone(GetTarget(), GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), m_modifier.m_amount, DOT, GetStackAmount()); + m_modifier.m_amount = caster->SpellDamageBonusDone(GetTarget(), GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), GetEffIndex(), m_modifier.m_amount, DOT, GetStackAmount()); } } @@ -3358,7 +3358,7 @@ void Aura::HandlePeriodicHealthFunnel(bool apply, bool /*Real*/) if (!caster) return; - m_modifier.m_amount = caster->SpellDamageBonusDone(GetTarget(), GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), m_modifier.m_amount, DOT, GetStackAmount()); + m_modifier.m_amount = caster->SpellDamageBonusDone(GetTarget(), GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), GetEffIndex(), m_modifier.m_amount, DOT, GetStackAmount()); } } @@ -4581,12 +4581,12 @@ void Aura::PeriodicTick() bool isNotBleed = GetEffectMechanic(spellProto, m_effIndex) != MECHANIC_BLEED; // SpellDamageBonus for magic spells if ((spellProto->DmgClass == SPELL_DAMAGE_CLASS_NONE && isNotBleed) || spellProto->DmgClass == SPELL_DAMAGE_CLASS_MAGIC) - pdamage = target->SpellDamageBonusTaken(caster, GetSpellSchoolMask(spellProto), spellProto, pdamage, DOT, GetStackAmount()); + pdamage = target->SpellDamageBonusTaken(caster, GetSpellSchoolMask(spellProto), spellProto, GetEffIndex(), pdamage, DOT, GetStackAmount()); // MeleeDamagebonus for weapon based spells else { WeaponAttackType attackType = GetWeaponAttackType(spellProto); - pdamage = target->MeleeDamageBonusTaken(caster, pdamage, attackType, GetSpellSchoolMask(spellProto), spellProto, DOT, GetStackAmount()); + pdamage = target->MeleeDamageBonusTaken(caster, pdamage, attackType, GetSpellSchoolMask(spellProto), spellProto, GetEffIndex(), DOT, GetStackAmount()); } target->CalculateDamageAbsorbAndResist(caster, GetSpellSchoolMask(spellProto), DOT, pdamage, &absorb, &resist, IsReflectableSpell(spellProto), IsResistableSpell(spellProto)); @@ -4654,7 +4654,7 @@ void Aura::PeriodicTick() uint32 absorb = 0; int32 resist = 0; - pdamage = target->SpellDamageBonusTaken(pCaster, GetSpellSchoolMask(spellProto), spellProto, pdamage, DOT, GetStackAmount()); + pdamage = target->SpellDamageBonusTaken(pCaster, GetSpellSchoolMask(spellProto), spellProto, GetEffIndex(), pdamage, DOT, GetStackAmount()); target->CalculateDamageAbsorbAndResist(pCaster, GetSpellSchoolMask(spellProto), DOT, pdamage, &absorb, &resist, IsReflectableSpell(spellProto), IsResistableSpell(spellProto)); @@ -4697,7 +4697,7 @@ void Aura::PeriodicTick() modOwner->ApplySpellMod(GetId(), SPELLMOD_MULTIPLE_VALUE, multiplier); } - uint32 heal = pCaster->SpellHealingBonusTaken(pCaster, spellProto, int32(new_damage * multiplier), DOT, GetStackAmount()); + uint32 heal = pCaster->SpellHealingBonusTaken(pCaster, spellProto, GetEffIndex(), int32(new_damage * multiplier), DOT, GetStackAmount()); int32 gain = pCaster->DealHeal(pCaster, heal, spellProto); // Health Leech effects do not generate healing aggro @@ -4740,7 +4740,7 @@ void Aura::PeriodicTick() break; } - pdamage = target->SpellHealingBonusTaken(pCaster, spellProto, pdamage, DOT, GetStackAmount()); + pdamage = target->SpellHealingBonusTaken(pCaster, spellProto, GetEffIndex(), pdamage, DOT, GetStackAmount()); DETAIL_FILTER_LOG(LOG_FILTER_PERIODIC_AFFECTS, "PeriodicTick: %s heal of %s for %u health inflicted by %u", GetCasterGuid().GetString().c_str(), target->GetGuidStr().c_str(), pdamage, GetId()); @@ -4948,7 +4948,7 @@ void Aura::PeriodicTick() SpellNonMeleeDamage spellDamageInfo(pCaster, target, spellProto->Id, SpellSchools(spellProto->School)); spellDamageInfo.periodicLog = true; - pCaster->CalculateSpellDamage(&spellDamageInfo, gain, spellProto); + pCaster->CalculateSpellDamage(&spellDamageInfo, gain, spellProto, GetEffIndex()); spellDamageInfo.target->CalculateAbsorbResistBlock(pCaster, &spellDamageInfo, spellProto); @@ -6079,9 +6079,9 @@ uint32 Aura::CalculateAuraEffectValue(Unit* caster, Unit* target, SpellEntry con case SPELL_AURA_SCHOOL_ABSORB: { float DoneActualBenefit = 0.0f; - if (SpellBonusEntry const* bonus = sSpellMgr.GetSpellBonusData(spellProto->Id)) + if (spellProto->effectBonusCoefficient[effIdx] > 0) { - DoneActualBenefit = caster->SpellBaseHealingBonusDone(GetSpellSchoolMask(spellProto)) * bonus->direct_damage; + DoneActualBenefit = caster->SpellBaseHealingBonusDone(GetSpellSchoolMask(spellProto)) * spellProto->effectBonusCoefficient[effIdx]; DoneActualBenefit *= caster->CalculateLevelPenalty(spellProto); value += (int32)DoneActualBenefit; diff --git a/src/game/Spells/SpellEffects.cpp b/src/game/Spells/SpellEffects.cpp index afa665d260..2ca5031a3d 100644 --- a/src/game/Spells/SpellEffects.cpp +++ b/src/game/Spells/SpellEffects.cpp @@ -354,7 +354,7 @@ void Spell::EffectSchoolDMG(SpellEffectIndex eff_idx) } if (damage >= 0) - m_damagePerEffect[eff_idx] = CalculateSpellEffectDamage(unitTarget, damage, m_damageDoneMultiplier[eff_idx]); + m_damagePerEffect[eff_idx] = CalculateSpellEffectDamage(unitTarget, damage, m_damageDoneMultiplier[eff_idx], eff_idx); } } @@ -1557,7 +1557,7 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) + unitTarget->SpellBaseDamageBonusTaken(GetSpellSchoolMask(m_spellInfo)); // Does Amplify Magic/Dampen Magic influence flametongue? If not, the above addition must be removed. float weaponSpeed = float(m_CastItem->GetProto()->Delay) / IN_MILLISECONDS; - bonusDamage = m_caster->SpellBonusWithCoeffs(m_spellInfo, 0, bonusDamage, 0, SPELL_DIRECT_DAMAGE, false); // apply spell coeff + bonusDamage = m_caster->SpellBonusWithCoeffs(m_spellInfo, eff_idx, 0, bonusDamage, 0, SPELL_DIRECT_DAMAGE, false); // apply spell coeff int32 totalDamage = (damage * 0.01 * weaponSpeed) + bonusDamage; m_caster->CastCustomSpell(unitTarget, 10444, &totalDamage, nullptr, nullptr, TRIGGERED_OLD_TRIGGERED, m_CastItem); @@ -1883,8 +1883,8 @@ void Spell::EffectPowerDrain(SpellEffectIndex eff_idx) uint32 curPower = unitTarget->GetPower(powerType); // add spell damage bonus - damage = m_caster->SpellDamageBonusDone(unitTarget, m_spellSchoolMask, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE); - damage = unitTarget->SpellDamageBonusTaken(m_caster, m_spellSchoolMask, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE); + damage = m_caster->SpellDamageBonusDone(unitTarget, m_spellSchoolMask, m_spellInfo, eff_idx, uint32(damage), SPELL_DIRECT_DAMAGE); + damage = unitTarget->SpellDamageBonusTaken(m_caster, m_spellSchoolMask, m_spellInfo, eff_idx, uint32(damage), SPELL_DIRECT_DAMAGE); int32 new_damage; if (curPower < uint32(damage)) // damage should not be under zero at this point (checked above) @@ -1945,7 +1945,7 @@ void Spell::EffectPowerBurn(SpellEffectIndex eff_idx) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_MULTIPLE_VALUE, multiplier); new_damage = int32(new_damage * multiplier); - m_damagePerEffect[eff_idx] = CalculateSpellEffectDamage(unitTarget, new_damage, m_damageDoneMultiplier[eff_idx]); + m_damagePerEffect[eff_idx] = CalculateSpellEffectDamage(unitTarget, new_damage, m_damageDoneMultiplier[eff_idx], eff_idx); // should use here effect POWER_DRAIN because POWER_BURN is not implemented on client m_spellLog.AddLog(uint32(SPELL_EFFECT_POWER_DRAIN), unitTarget->GetObjectGuid(), new_damage, uint32(powertype), multiplier); @@ -2000,9 +2000,9 @@ void Spell::EffectHeal(SpellEffectIndex eff_idx) addhealth += tickheal * tickcount; } - addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL); + addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, eff_idx, addhealth, HEAL); addhealth *= m_damageDoneMultiplier[eff_idx]; - addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL); + addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, eff_idx, addhealth, HEAL); m_healingPerEffect[eff_idx] = addhealth; } @@ -2018,8 +2018,8 @@ void Spell::EffectHealMechanical(SpellEffectIndex eff_idx) if (!caster) return; - uint32 addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, damage, HEAL); - addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL); + uint32 addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, eff_idx, damage, HEAL); + addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, eff_idx, addhealth, HEAL); m_healingPerEffect[eff_idx] = addhealth; } @@ -2050,7 +2050,7 @@ void Spell::EffectHealthLeech(SpellEffectIndex eff_idx) uint32 heal = uint32(damage * multiplier); if (m_caster->IsAlive()) { - heal = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, heal, HEAL); + heal = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, eff_idx, heal, HEAL); // TODO: at hit need to schedule a (delayed) heal effect execution on caster // order of packets for death coil - start, go, delay, dmg log, delay, heal log @@ -3732,7 +3732,7 @@ void Spell::EffectWeaponDmg(SpellEffectIndex eff_idx) bonus = int32(bonus * totalDamagePercentMod); // prevent negative damage - m_damagePerEffect[eff_idx] = CalculateSpellEffectDamage(unitTarget, bonus, m_damageDoneMultiplier[eff_idx]); + m_damagePerEffect[eff_idx] = CalculateSpellEffectDamage(unitTarget, bonus, m_damageDoneMultiplier[eff_idx], eff_idx); // Mangle (Cat): CP if (m_spellInfo->IsFitToFamily(SPELLFAMILY_DRUID, uint64(0x0000040000000000))) diff --git a/src/game/Spells/SpellMgr.cpp b/src/game/Spells/SpellMgr.cpp index a90d2b8492..c4d05a5410 100644 --- a/src/game/Spells/SpellMgr.cpp +++ b/src/game/Spells/SpellMgr.cpp @@ -946,149 +946,6 @@ bool IsCastEndProcModifierAura(SpellEntry const* spellInfo, SpellEffectIndex eff } } -struct DoSpellBonuses -{ - DoSpellBonuses(SpellBonusMap& _spellBonusMap, SpellBonusEntry const& _spellBonus) : spellBonusMap(_spellBonusMap), spellBonus(_spellBonus) {} - void operator()(uint32 spell_id) { spellBonusMap[spell_id] = spellBonus; } - - SpellBonusMap& spellBonusMap; - SpellBonusEntry const& spellBonus; -}; - -void SpellMgr::LoadSpellBonuses() -{ - mSpellBonusMap.clear(); // need for reload case - uint32 count = 0; - // 0 1 2 3 - auto queryResult = WorldDatabase.Query("SELECT entry, direct_bonus, dot_bonus, ap_bonus, ap_dot_bonus FROM spell_bonus_data"); - if (!queryResult) - { - BarGoLink bar(1); - bar.step(); - sLog.outString(">> Loaded %u spell bonus data", count); - sLog.outString(); - return; - } - - BarGoLink bar(queryResult->GetRowCount()); - do - { - Field* fields = queryResult->Fetch(); - bar.step(); - uint32 entry = fields[0].GetUInt32(); - - SpellEntry const* spell = sSpellTemplate.LookupEntry(entry); - if (!spell) - { - sLog.outErrorDb("Spell %u listed in `spell_bonus_data` does not exist", entry); - continue; - } - - uint32 first_id = GetFirstSpellInChain(entry); - - if (first_id != entry) - { - sLog.outErrorDb("Spell %u listed in `spell_bonus_data` is not first rank (%u) in chain", entry, first_id); - // prevent loading since it won't have an effect anyway - continue; - } - - SpellBonusEntry sbe; - - sbe.direct_damage = fields[1].GetFloat(); - sbe.dot_damage = fields[2].GetFloat(); - sbe.ap_bonus = fields[3].GetFloat(); - sbe.ap_dot_bonus = fields[4].GetFloat(); - - bool need_dot = false; - bool need_direct = false; - uint32 x = 0; // count all, including empty, meaning: not all existing effect is DoTs/HoTs - for (int i = 0; i < MAX_EFFECT_INDEX; ++i) - { - if (!spell->Effect[i]) - { - ++x; - continue; - } - - // DoTs/HoTs - switch (spell->EffectApplyAuraName[i]) - { - case SPELL_AURA_PERIODIC_DAMAGE: - case SPELL_AURA_PERIODIC_DAMAGE_PERCENT: - case SPELL_AURA_PERIODIC_LEECH: - case SPELL_AURA_PERIODIC_HEAL: - case SPELL_AURA_OBS_MOD_HEALTH: - case SPELL_AURA_PERIODIC_MANA_LEECH: - case SPELL_AURA_OBS_MOD_MANA: - case SPELL_AURA_POWER_BURN_MANA: - need_dot = true; - ++x; - break; - default: - break; - } - } - - // TODO: maybe add explicit list possible direct damage spell effects... - if (x < MAX_EFFECT_INDEX) - need_direct = true; - - // Check if direct_bonus is needed in `spell_bonus_data` - float direct_calc = 0.0f; - float direct_diff = 1000.0f; // for have big diff if no DB field value - if (sbe.direct_damage) - { - direct_calc = CalculateDefaultCoefficient(spell, SPELL_DIRECT_DAMAGE); - direct_diff = std::abs(sbe.direct_damage - direct_calc); - } - - // Check if dot_bonus is needed in `spell_bonus_data` - float dot_calc = 0.0f; - float dot_diff = 1000.0f; // for have big diff if no DB field value - if (sbe.dot_damage) - { - dot_calc = CalculateDefaultCoefficient(spell, DOT); - dot_diff = std::abs(sbe.dot_damage - dot_calc); - } - - if (direct_diff < 0.02f && !need_dot && !sbe.ap_bonus && !sbe.ap_dot_bonus) - sLog.outErrorDb("`spell_bonus_data` entry for spell %u `direct_bonus` not needed (data from table: %f, calculated %f, difference of %f) and `dot_bonus` also not used", - entry, sbe.direct_damage, direct_calc, direct_diff); - else if (direct_diff < 0.02f && dot_diff < 0.02f && !sbe.ap_bonus && !sbe.ap_dot_bonus) - { - sLog.outErrorDb("`spell_bonus_data` entry for spell %u `direct_bonus` not needed (data from table: %f, calculated %f, difference of %f) and ", - entry, sbe.direct_damage, direct_calc, direct_diff); - sLog.outErrorDb(" ... `dot_bonus` not needed (data from table: %f, calculated %f, difference of %f)", - sbe.dot_damage, dot_calc, dot_diff); - } - else if (!need_direct && dot_diff < 0.02f && !sbe.ap_bonus && !sbe.ap_dot_bonus) - sLog.outErrorDb("`spell_bonus_data` entry for spell %u `dot_bonus` not needed (data from table: %f, calculated %f, difference of %f) and direct also not used", - entry, sbe.dot_damage, dot_calc, dot_diff); - else if (!need_direct && sbe.direct_damage) - sLog.outErrorDb("`spell_bonus_data` entry for spell %u `direct_bonus` not used (spell not have non-periodic affects)", entry); - else if (!need_dot && sbe.dot_damage) - sLog.outErrorDb("`spell_bonus_data` entry for spell %u `dot_bonus` not used (spell not have periodic affects)", entry); - - if (!need_direct && sbe.ap_bonus) - sLog.outErrorDb("`spell_bonus_data` entry for spell %u `ap_bonus` not used (spell not have non-periodic affects)", entry); - else if (!need_dot && sbe.ap_dot_bonus) - sLog.outErrorDb("`spell_bonus_data` entry for spell %u `ap_dot_bonus` not used (spell not have periodic affects)", entry); - - mSpellBonusMap[entry] = sbe; - - // also add to high ranks - DoSpellBonuses worker(mSpellBonusMap, sbe); - doForHighRanks(entry, worker); - - ++count; - } - while (queryResult->NextRow()); - - sLog.outString(">> Loaded %u extra spell bonus data", count); - sLog.outString(); -} - bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellProcEvent, uint32 EventProcFlag, SpellEntry const* spellInfo, uint32 procFlags, uint32 procExtra) { // No extra req need diff --git a/src/game/Spells/SpellMgr.h b/src/game/Spells/SpellMgr.h index 32b00560f3..13a9bad947 100644 --- a/src/game/Spells/SpellMgr.h +++ b/src/game/Spells/SpellMgr.h @@ -2088,16 +2088,7 @@ struct SpellProcEventEntry uint32 cooldown; // hidden cooldown used for some spell proc events, applied to _triggered_spell_ }; -struct SpellBonusEntry -{ - float direct_damage; - float dot_damage; - float ap_bonus; - float ap_dot_bonus; -}; - typedef std::unordered_map SpellProcEventMap; -typedef std::unordered_map SpellBonusMap; #define ELIXIR_FLASK_MASK 0x03 // 2 bit mask for batter compatibility with more recent client version, flaks must have both bits set #define ELIXIR_WELL_FED 0x10 // Some foods have SPELLFAMILY_POTION @@ -2284,7 +2275,6 @@ typedef std::map SpellFacingFlagMap; class SpellMgr { - friend struct DoSpellBonuses; friend struct DoSpellProcEvent; friend struct DoSpellProcItemEnchant; @@ -2537,17 +2527,6 @@ class SpellMgr static bool IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellProcEvent, uint32 EventProcFlag, SpellEntry const* spellInfo, uint32 procFlags, uint32 procExtra); - // Spell bonus data - SpellBonusEntry const* GetSpellBonusData(uint32 spellId) const - { - // Lookup data - SpellBonusMap::const_iterator itr = mSpellBonusMap.find(spellId); - if (itr != mSpellBonusMap.end()) - return &itr->second; - - return nullptr; - } - uint32 GetSpellFacingFlag(uint32 spellId) const { SpellFacingFlagMap::const_iterator itr = mSpellFacingFlagMap.find(spellId); @@ -2866,7 +2845,6 @@ class SpellMgr void LoadSpellElixirs(); void LoadSpellProcEvents(); void LoadSpellProcItemEnchant(); - void LoadSpellBonuses(); void LoadSpellTargetPositions(); void LoadSpellThreats(); void LoadSkillLineAbilityMaps(); @@ -2886,7 +2864,6 @@ class SpellMgr SpellThreatMap mSpellThreatMap; SpellProcEventMap mSpellProcEventMap; SpellProcItemEnchantMap mSpellProcItemEnchantMap; - SpellBonusMap mSpellBonusMap; SkillLineAbilityMap mSkillLineAbilityMapBySpellId; SkillLineAbilityMap mSkillLineAbilityMapBySkillId; SkillRaceClassInfoMap mSkillRaceClassInfoMap; diff --git a/src/game/Spells/UnitAuraProcHandler.cpp b/src/game/Spells/UnitAuraProcHandler.cpp index 2b7df4819b..dd7235d225 100644 --- a/src/game/Spells/UnitAuraProcHandler.cpp +++ b/src/game/Spells/UnitAuraProcHandler.cpp @@ -1548,7 +1548,7 @@ SpellAuraProcResult Unit::HandleProcTriggerDamageAuraProc(ProcExecutionData& dat triggeredByAura->GetHolder()->SetProcCooldown(std::chrono::seconds(cooldown), GetMap()->GetCurrentClockTime()); SpellNonMeleeDamage spellDamageInfo(this, victim, spellInfo->Id, SpellSchools(spellInfo->School)); - CalculateSpellDamage(&spellDamageInfo, triggeredByAura->GetModifier()->m_amount, spellInfo); + CalculateSpellDamage(&spellDamageInfo, triggeredByAura->GetModifier()->m_amount, spellInfo, triggeredByAura->GetEffIndex()); spellDamageInfo.target->CalculateAbsorbResistBlock(this, &spellDamageInfo, spellInfo); Unit::DealDamageMods(this, spellDamageInfo.target, spellDamageInfo.damage, &spellDamageInfo.absorb, SPELL_DIRECT_DAMAGE); SendSpellNonMeleeDamageLog(&spellDamageInfo); diff --git a/src/game/World/World.cpp b/src/game/World/World.cpp index af1a8092ef..4270c4c9e1 100644 --- a/src/game/World/World.cpp +++ b/src/game/World/World.cpp @@ -944,9 +944,6 @@ void World::SetInitialWorldSettings() sLog.outString("Loading Spell Proc Event conditions..."); sSpellMgr.LoadSpellProcEvents(); - sLog.outString("Loading Spell Bonus Data..."); - sSpellMgr.LoadSpellBonuses(); - sLog.outString("Loading Spell Proc Item Enchant..."); sSpellMgr.LoadSpellProcItemEnchant(); // must be after LoadSpellChains diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index 503ad2eb94..c0099b0ab5 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -3,5 +3,5 @@ #define REVISION_DB_REALMD "required_z2800_01_realmd_platform" #define REVISION_DB_LOGS "required_z2778_01_logs_anticheat" #define REVISION_DB_CHARACTERS "required_z2799_01_characters_account_data" - #define REVISION_DB_MANGOS "required_z2816_01_mangos_precision_decimal" + #define REVISION_DB_MANGOS "required_z2817_01_mangos_spell_template" #endif // __REVISION_SQL_H__