aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/world/master/2022_01_06_36_world_2020_06_03_00_world.sql4
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp12
-rw-r--r--src/server/game/Entities/Unit/Unit.h4
-rw-r--r--src/server/game/Spells/Spell.cpp15
-rw-r--r--src/server/game/Spells/Spell.h2
-rw-r--r--src/server/game/Spells/SpellMgr.cpp7
-rw-r--r--src/server/game/Spells/SpellScript.cpp10
-rw-r--r--src/server/game/Spells/SpellScript.h22
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp22
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp18
10 files changed, 90 insertions, 26 deletions
diff --git a/sql/updates/world/master/2022_01_06_36_world_2020_06_03_00_world.sql b/sql/updates/world/master/2022_01_06_36_world_2020_06_03_00_world.sql
new file mode 100644
index 00000000000..92978b2d024
--- /dev/null
+++ b/sql/updates/world/master/2022_01_06_36_world_2020_06_03_00_world.sql
@@ -0,0 +1,4 @@
+--
+DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_blood_queen_twilight_bloodbolt';
+INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
+(71446,'spell_blood_queen_twilight_bloodbolt');
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index ce14d9385da..20fb86d4c05 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -1046,7 +1046,7 @@ void Unit::CastStop(uint32 except_spellid)
InterruptSpell(CurrentSpellTypes(i), false);
}
-void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType, bool crit)
+void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType, bool crit, Spell* spell /*= nullptr*/)
{
if (damage < 0)
return;
@@ -1151,7 +1151,7 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
damageInfo->damage = damage;
damageInfo->originalDamage = damage;
DamageInfo dmgInfo(*damageInfo, SPELL_DIRECT_DAMAGE, BASE_ATTACK, PROC_HIT_NONE);
- Unit::CalcAbsorbResist(dmgInfo);
+ Unit::CalcAbsorbResist(dmgInfo, spell);
damageInfo->absorb = dmgInfo.GetAbsorb();
damageInfo->resist = dmgInfo.GetResist();
@@ -1718,13 +1718,12 @@ void Unit::HandleEmoteCommand(uint32 emoteId, Player* target /*=nullptr*/, Trini
return victimResistance / (victimResistance + resistanceConstant);
}
-/*static*/ void Unit::CalcAbsorbResist(DamageInfo& damageInfo)
+/*static*/ void Unit::CalcAbsorbResist(DamageInfo& damageInfo, Spell* spell /*= nullptr*/)
{
if (!damageInfo.GetVictim() || !damageInfo.GetVictim()->IsAlive() || !damageInfo.GetDamage())
return;
uint32 resistedDamage = Unit::CalcSpellResistedDamage(damageInfo.GetAttacker(), damageInfo.GetVictim(), damageInfo.GetDamage(), damageInfo.GetSchoolMask(), damageInfo.GetSpellInfo());
- damageInfo.ResistDamage(resistedDamage);
// Ignore Absorption Auras
float auraAbsorbMod = 0.f;
@@ -1734,6 +1733,11 @@ void Unit::HandleEmoteCommand(uint32 emoteId, Player* target /*=nullptr*/, Trini
RoundToInterval(auraAbsorbMod, 0.0f, 100.0f);
int32 absorbIgnoringDamage = CalculatePct(damageInfo.GetDamage(), auraAbsorbMod);
+
+ if (spell)
+ spell->CallScriptOnResistAbsorbCalculateHandlers(damageInfo, resistedDamage, absorbIgnoringDamage);
+
+ damageInfo.ResistDamage(resistedDamage);
damageInfo.ModifyDamage(-absorbIgnoringDamage);
// We're going to call functions which can modify content of the list during iteration over it's elements
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index a3446114b44..a3b4861ea20 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1045,7 +1045,7 @@ class TC_GAME_API Unit : public WorldObject
void DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss);
void HandleProcExtraAttackFor(Unit* victim);
- void CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType = BASE_ATTACK, bool crit = false);
+ void CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType = BASE_ATTACK, bool crit = false, Spell* spell = nullptr);
void DealSpellDamage(SpellNonMeleeDamage const* damageInfo, bool durabilityLoss);
// player or player's pet resilience (-1%)
@@ -1702,7 +1702,7 @@ class TC_GAME_API Unit : public WorldObject
static bool IsDamageReducedByArmor(SpellSchoolMask damageSchoolMask, SpellInfo const* spellInfo = nullptr);
static uint32 CalcArmorReducedDamage(Unit const* attacker, Unit* victim, uint32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType = MAX_ATTACK, uint8 attackerLevel = 0);
static uint32 CalcSpellResistedDamage(Unit const* attacker, Unit* victim, uint32 damage, SpellSchoolMask schoolMask, SpellInfo const* spellInfo);
- static void CalcAbsorbResist(DamageInfo& damageInfo);
+ static void CalcAbsorbResist(DamageInfo& damageInfo, Spell* spell = nullptr);
static void CalcHealAbsorb(HealInfo& healInfo);
void UpdateSpeed(UnitMoveType mtype);
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index af14b186ce2..4690176be01 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -2609,7 +2609,7 @@ void Spell::TargetInfo::DoDamageAndTriggers(Spell* spell)
else
{
// Add bonuses and fill damageInfo struct
- caster->CalculateSpellDamageTaken(&damageInfo, spell->m_damage, spell->m_spellInfo, spell->m_attackType, IsCrit);
+ caster->CalculateSpellDamageTaken(&damageInfo, spell->m_damage, spell->m_spellInfo, spell->m_attackType, IsCrit, spell);
Unit::DealDamageMods(damageInfo.attacker, damageInfo.target, damageInfo.damage, &damageInfo.absorb);
hitMask |= createProcHitMask(&damageInfo, MissCondition);
@@ -8387,6 +8387,19 @@ std::string Spell::GetDebugInfo() const
return sstr.str();
}
+void Spell::CallScriptOnResistAbsorbCalculateHandlers(DamageInfo const& damageInfo, uint32& resistAmount, int32& absorbAmount)
+{
+ for (auto scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
+ {
+ (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_ON_RESIST_ABSORB_CALCULATION);
+ auto hookItrEnd = (*scritr)->OnCalculateResistAbsorb.end(), hookItr = (*scritr)->OnCalculateResistAbsorb.begin();
+ for (; hookItr != hookItrEnd; ++hookItr)
+ hookItr->Call(*scritr, damageInfo, resistAmount, absorbAmount);
+
+ (*scritr)->_FinishScriptCall();
+ }
+}
+
namespace Trinity
{
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index 8601e1d5042..e8c3df6bb5f 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -40,6 +40,7 @@ class Aura;
class AuraEffect;
class BasicEvent;
class Corpse;
+class DamageInfo;
class DynamicObject;
class DynObjAura;
class GameObject;
@@ -629,6 +630,7 @@ class TC_GAME_API Spell
int64 GetItemTargetCountForEffect(SpellEffIndex effect) const;
std::string GetDebugInfo() const;
+ void CallScriptOnResistAbsorbCalculateHandlers(DamageInfo const& damageInfo, uint32& resistAmount, int32& absorbAmount);
protected:
bool HasGlobalCooldown() const;
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index 7c69542359c..cc830ac492a 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -4268,13 +4268,6 @@ void SpellMgr::LoadSpellInfoCorrections()
});
});
- // Mutated Transformation (Professor Putricide)
- ApplySpellFix({ 70402 }, [](SpellInfo* spellInfo)
- {
- // Resistance is calculated inside of SpellScript
- spellInfo->AttributesEx4 |= SPELL_ATTR4_IGNORE_RESISTANCES;
- });
-
// Empowered Flare (Blood Prince Council)
ApplySpellFix({ 71708 }, [](SpellInfo* spellInfo)
{
diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp
index 671ea468227..60b25458bf3 100644
--- a/src/server/game/Spells/SpellScript.cpp
+++ b/src/server/game/Spells/SpellScript.cpp
@@ -191,6 +191,16 @@ SpellCastResult SpellScript::CheckCastHandler::Call(SpellScript* spellScript)
return (spellScript->*_checkCastHandlerScript)();
}
+SpellScript::OnCalculateResistAbsorbHandler::OnCalculateResistAbsorbHandler(SpellOnResistAbsorbCalculateFnType onResistAbsorbCalculateHandlerScript)
+{
+ pOnCalculateResistAbsorbHandlerScript = onResistAbsorbCalculateHandlerScript;
+}
+
+void SpellScript::OnCalculateResistAbsorbHandler::Call(SpellScript* spellScript, DamageInfo const& damageInfo, uint32& resistAmount, int32& absorbAmount)
+{
+ return (spellScript->*pOnCalculateResistAbsorbHandlerScript)(damageInfo, resistAmount, absorbAmount);
+}
+
SpellScript::EffectHandler::EffectHandler(SpellEffectFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName)
: _SpellScript::EffectNameCheck(_effName), _SpellScript::EffectHook(_effIndex)
{
diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h
index 665be327fbc..1c5ee34f7f8 100644
--- a/src/server/game/Spells/SpellScript.h
+++ b/src/server/game/Spells/SpellScript.h
@@ -189,6 +189,7 @@ enum SpellScriptHookType
SPELL_SCRIPT_HOOK_CHECK_CAST,
SPELL_SCRIPT_HOOK_BEFORE_CAST,
SPELL_SCRIPT_HOOK_ON_CAST,
+ SPELL_SCRIPT_HOOK_ON_RESIST_ABSORB_CALCULATION,
SPELL_SCRIPT_HOOK_AFTER_CAST,
SPELL_SCRIPT_HOOK_CALC_CRIT_CHANCE
};
@@ -208,6 +209,7 @@ class TC_GAME_API SpellScript : public _SpellScript
typedef void(CLASSNAME::*SpellHitFnType)(); \
typedef void(CLASSNAME::*SpellCastFnType)(); \
typedef void(CLASSNAME::*SpellOnCalcCritChanceFnType)(Unit const* victim, float& chance); \
+ typedef void(CLASSNAME::*SpellOnResistAbsorbCalculateFnType)(DamageInfo const& damageInfo, uint32& resistAmount, int32& absorbAmount); \
typedef void(CLASSNAME::*SpellObjectAreaTargetSelectFnType)(std::list<WorldObject*>&); \
typedef void(CLASSNAME::*SpellObjectTargetSelectFnType)(WorldObject*&); \
typedef void(CLASSNAME::*SpellDestinationTargetSelectFnType)(SpellDestination&);
@@ -310,6 +312,15 @@ class TC_GAME_API SpellScript : public _SpellScript
SpellDestinationTargetSelectFnType DestinationTargetSelectHandlerScript;
};
+ class TC_GAME_API OnCalculateResistAbsorbHandler
+ {
+ public:
+ OnCalculateResistAbsorbHandler(SpellOnResistAbsorbCalculateFnType _pOnCalculateResistAbsorbHandlerScript);
+ void Call(SpellScript* spellScript, DamageInfo const& damageInfo, uint32& resistAmount, int32& absorbAmount);
+ private:
+ SpellOnResistAbsorbCalculateFnType pOnCalculateResistAbsorbHandlerScript;
+ };
+
#define SPELLSCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME) \
class CastHandlerFunction : public SpellScript::CastHandler { public: CastHandlerFunction(SpellCastFnType _pCastHandlerScript) : SpellScript::CastHandler((SpellScript::SpellCastFnType)_pCastHandlerScript) { } }; \
class CheckCastHandlerFunction : public SpellScript::CheckCastHandler { public: CheckCastHandlerFunction(SpellCheckCastFnType _checkCastHandlerScript) : SpellScript::CheckCastHandler((SpellScript::SpellCheckCastFnType)_checkCastHandlerScript) { } }; \
@@ -317,6 +328,7 @@ class TC_GAME_API SpellScript : public _SpellScript
class HitHandlerFunction : public SpellScript::HitHandler { public: HitHandlerFunction(SpellHitFnType _pHitHandlerScript) : SpellScript::HitHandler((SpellScript::SpellHitFnType)_pHitHandlerScript) { } }; \
class BeforeHitHandlerFunction : public SpellScript::BeforeHitHandler { public: BeforeHitHandlerFunction(SpellBeforeHitFnType pBeforeHitHandlerScript) : SpellScript::BeforeHitHandler((SpellScript::SpellBeforeHitFnType)pBeforeHitHandlerScript) { } }; \
class OnCalcCritChanceHandlerFunction : public SpellScript::OnCalcCritChanceHandler { public: OnCalcCritChanceHandlerFunction(SpellOnCalcCritChanceFnType onCalcCritChanceHandlerScript) : SpellScript::OnCalcCritChanceHandler((SpellScript::SpellOnCalcCritChanceFnType)onCalcCritChanceHandlerScript) {} }; \
+ class OnCalculateResistAbsorbHandlerFunction : public SpellScript::OnCalculateResistAbsorbHandler { public: OnCalculateResistAbsorbHandlerFunction(SpellOnResistAbsorbCalculateFnType _onCalculateResistAbsorbScript) : SpellScript::OnCalculateResistAbsorbHandler((SpellScript::SpellOnResistAbsorbCalculateFnType)_onCalculateResistAbsorbScript) { } }; \
class ObjectAreaTargetSelectHandlerFunction : public SpellScript::ObjectAreaTargetSelectHandler { public: ObjectAreaTargetSelectHandlerFunction(SpellObjectAreaTargetSelectFnType _pObjectAreaTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::ObjectAreaTargetSelectHandler((SpellScript::SpellObjectAreaTargetSelectFnType)_pObjectAreaTargetSelectHandlerScript, _effIndex, _targetType) { } }; \
class ObjectTargetSelectHandlerFunction : public SpellScript::ObjectTargetSelectHandler { public: ObjectTargetSelectHandlerFunction(SpellObjectTargetSelectFnType _pObjectTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::ObjectTargetSelectHandler((SpellScript::SpellObjectTargetSelectFnType)_pObjectTargetSelectHandlerScript, _effIndex, _targetType) { } }; \
class DestinationTargetSelectHandlerFunction : public SpellScript::DestinationTargetSelectHandler { public: DestinationTargetSelectHandlerFunction(SpellDestinationTargetSelectFnType _DestinationTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::DestinationTargetSelectHandler((SpellScript::SpellDestinationTargetSelectFnType)_DestinationTargetSelectHandlerScript, _effIndex, _targetType) { } };
@@ -358,6 +370,11 @@ class TC_GAME_API SpellScript : public _SpellScript
HookList<CheckCastHandler> OnCheckCast;
#define SpellCheckCastFn(F) CheckCastHandlerFunction(&F)
+ // example: OnCalculateResistAbsorb += SpellOnResistAbsorbCalculateFn(class::function);
+ // where function is void function(DamageInfo const& damageInfo, uint32& resistAmount, int32& absorbAmount)
+ HookList<OnCalculateResistAbsorbHandler> OnCalculateResistAbsorb;
+ #define SpellOnResistAbsorbCalculateFn(F) OnCalculateResistAbsorbHandlerFunction(&F)
+
// example: OnEffect**** += SpellEffectFn(class::function, EffectIndexSpecifier, EffectNameSpecifier);
// where function is void function(SpellEffIndex effIndex)
HookList<EffectHandler> OnEffectLaunch;
@@ -410,8 +427,9 @@ class TC_GAME_API SpellScript : public _SpellScript
// 6. OnEffectLaunch - executed just before specified effect handler call - when spell missile is launched
// 7. OnEffectLaunchTarget - executed just before specified effect handler call - when spell missile is launched - called for each target from spell target map
// 8. OnCalcCritChance - executed just after specified effect handler call - when spell missile is launched - called for each target from spell target map
- // 9. OnEffectHit - executed just before specified effect handler call - when spell missile hits dest
- // 10. BeforeHit - executed just before spell hits a target - called for each target from spell target map
+ // 9. OnCalculateResistAbsorb - executed when damage resist/absorbs is calculated - before spell hit target
+ // 10. OnEffectHit - executed just before specified effect handler call - when spell missile hits dest
+ // 11. BeforeHit - executed just before spell hits a target - called for each target from spell target map
// 12. OnEffectHitTarget - executed just before specified effect handler call - called for each target from spell target map
// 13. OnHit - executed just before spell deals damage and procs auras - when spell hits target - called for each target from spell target map
// 14. AfterHit - executed just after spell finishes all it's jobs for target - called for each target from spell target map
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
index 758c45b13b5..f4f01d78fff 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
@@ -860,6 +860,27 @@ class spell_blood_queen_pact_of_the_darkfallen_dmg_target : public SpellScriptLo
}
};
+// 71446, 71478, 71479, 71480 - Twilight Bloodbolt
+class spell_blood_queen_twilight_bloodbolt : public SpellScript
+{
+ PrepareSpellScript(spell_blood_queen_twilight_bloodbolt);
+
+ void HandleResistance(DamageInfo const& damageInfo, uint32& resistAmount, int32& /*absorbAmount*/)
+ {
+ Unit* caster = damageInfo.GetAttacker();;
+ Unit* target = damageInfo.GetVictim();
+ uint32 damage = damageInfo.GetDamage();
+ uint32 resistedDamage = Unit::CalcSpellResistedDamage(caster, target, damage, SPELL_SCHOOL_MASK_SHADOW, nullptr);
+ resistedDamage += Unit::CalcSpellResistedDamage(caster, target, damage, SPELL_SCHOOL_MASK_ARCANE, nullptr);
+ resistAmount = resistedDamage;
+ }
+
+ void Register() override
+ {
+ OnCalculateResistAbsorb += SpellOnResistAbsorbCalculateFn(spell_blood_queen_twilight_bloodbolt::HandleResistance);
+ }
+};
+
class achievement_once_bitten_twice_shy_n : public AchievementCriteriaScript
{
public:
@@ -902,6 +923,7 @@ void AddSC_boss_blood_queen_lana_thel()
new spell_blood_queen_pact_of_the_darkfallen();
new spell_blood_queen_pact_of_the_darkfallen_dmg();
new spell_blood_queen_pact_of_the_darkfallen_dmg_target();
+ RegisterSpellScript(spell_blood_queen_twilight_bloodbolt);
new achievement_once_bitten_twice_shy_n();
new achievement_once_bitten_twice_shy_v();
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
index 0a3939e8046..94717c7dbd2 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
@@ -1665,21 +1665,19 @@ class spell_abomination_mutated_transformation : public SpellScript
{
PrepareSpellScript(spell_abomination_mutated_transformation);
- /* Resist system always pick the min resist value for spells with multiple schools.
- But following some combat logs of retail, this spell is a exception and need get the sum of both schools. */
- void HandleResistance(SpellEffIndex /*effIndex*/)
+ void HandleResistance(DamageInfo const& damageInfo, uint32& resistAmount, int32& /*absorbAmount*/)
{
- Unit* caster = GetCaster();
- uint32 damage = GetHitDamage();
- Unit* target = GetHitUnit();
- damage -= Unit::CalcSpellResistedDamage(caster, target, GetHitDamage(), SPELL_SCHOOL_MASK_SHADOW, nullptr);
- damage -= Unit::CalcSpellResistedDamage(caster, target, GetHitDamage(), SPELL_SCHOOL_MASK_NATURE, nullptr);
- SetHitDamage(damage);
+ Unit* caster = damageInfo.GetAttacker();;
+ Unit* target = damageInfo.GetVictim();
+ uint32 damage = damageInfo.GetDamage();
+ uint32 resistedDamage = Unit::CalcSpellResistedDamage(caster, target, damage, SPELL_SCHOOL_MASK_SHADOW, nullptr);
+ resistedDamage += Unit::CalcSpellResistedDamage(caster, target, damage, SPELL_SCHOOL_MASK_NATURE, nullptr);
+ resistAmount = resistedDamage;
}
void Register() override
{
- OnEffectHitTarget += SpellEffectFn(spell_abomination_mutated_transformation::HandleResistance, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
+ OnCalculateResistAbsorb += SpellOnResistAbsorbCalculateFn(spell_abomination_mutated_transformation::HandleResistance);
}
};