aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/world/3.3.5/2020_06_03_00_world.sql7
-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.h28
-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, 96 insertions, 29 deletions
diff --git a/sql/updates/world/3.3.5/2020_06_03_00_world.sql b/sql/updates/world/3.3.5/2020_06_03_00_world.sql
new file mode 100644
index 00000000000..6141210bad9
--- /dev/null
+++ b/sql/updates/world/3.3.5/2020_06_03_00_world.sql
@@ -0,0 +1,7 @@
+--
+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'),
+(71478,'spell_blood_queen_twilight_bloodbolt'),
+(71479,'spell_blood_queen_twilight_bloodbolt'),
+(71480,'spell_blood_queen_twilight_bloodbolt');
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 37783c46ac6..acb4f7f5458 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -951,7 +951,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;
@@ -1064,7 +1064,7 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
damageInfo->damage = 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();
@@ -1729,13 +1729,12 @@ void Unit::HandleEmoteCommand(uint32 emoteId)
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;
@@ -1757,6 +1756,11 @@ void Unit::HandleEmoteCommand(uint32 emoteId)
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 ab4d013aafa..47bf4e2766a 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -956,7 +956,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* damageInfo, bool durabilityLoss);
// player or player's pet resilience (-1%)
@@ -1529,7 +1529,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 272e9aa21ee..c75e60f6bd3 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -2450,7 +2450,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.target, damageInfo.damage, &damageInfo.absorb);
// Send log damage message to client
@@ -8079,6 +8079,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 cf5b34dee19..dddeddf2f71 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -38,6 +38,7 @@ namespace WorldPackets
class Aura;
class AuraEffect;
class Corpse;
+class DamageInfo;
class DynamicObject;
class DynObjAura;
class GameObject;
@@ -562,6 +563,7 @@ class TC_GAME_API Spell
Spell** m_selfContainer; // pointer to our spell container (if applicable)
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 300d9a81bc4..f491957cadb 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -4367,13 +4367,6 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
});
- // Mutated Transformation (Professor Putricide)
- ApplySpellFix({ 70402, 72511, 72512, 72513 }, [](SpellInfo* spellInfo)
- {
- // Resistance is calculated inside of SpellScript
- spellInfo->AttributesEx4 |= SPELL_ATTR4_IGNORE_RESISTANCES;
- });
-
ApplySpellFix({
71518, // Unholy Infusion Quest Credit (Professor Putricide)
72934, // Blood Infusion Quest Credit (Blood-Queen Lana'thel)
diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp
index 246b5c6263c..b2257796b9b 100644
--- a/src/server/game/Spells/SpellScript.cpp
+++ b/src/server/game/Spells/SpellScript.cpp
@@ -199,6 +199,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 341d8b398df..e4356e8835e 100644
--- a/src/server/game/Spells/SpellScript.h
+++ b/src/server/game/Spells/SpellScript.h
@@ -172,6 +172,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
};
@@ -192,6 +193,7 @@ class TC_GAME_API SpellScript : public _SpellScript
typedef void(CLASSNAME::*SpellBeforeHitFnType)(SpellMissInfo missInfo); \
typedef void(CLASSNAME::*SpellHitFnType)(); \
typedef void(CLASSNAME::*SpellCastFnType)(); \
+ 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&);
@@ -285,12 +287,22 @@ 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) { } }; \
class EffectHandlerFunction : public SpellScript::EffectHandler { public: EffectHandlerFunction(SpellEffectFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName) : SpellScript::EffectHandler((SpellScript::SpellEffectFnType)_pEffectHandlerScript, _effIndex, _effName) { } }; \
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 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) { } }
@@ -331,6 +343,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;
@@ -377,11 +394,12 @@ class TC_GAME_API SpellScript : public _SpellScript
// 5. AfterCast - executed after spell missile is launched and immediate spell actions are done
// 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. OnEffectHit - executed just before specified effect handler call - when spell missile hits dest
- // 9. BeforeHit - executed just before spell hits a target - called for each target from spell target map
- // 10. OnEffectHitTarget - executed just before specified effect handler call - called for each target from spell target map
- // 11. OnHit - executed just before spell deals damage and procs auras - when spell hits target - called for each target from spell target map
- // 12. AfterHit - executed just after spell finishes all it's jobs for target - called for each target from spell target map
+ // 8. OnCalculateResistAbsorb - executed when damage resist/absorbs is calculated - before spell hit target
+ // 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
+ // 11. OnEffectHitTarget - executed just before specified effect handler call - called for each target from spell target map
+ // 12. OnHit - executed just before spell deals damage and procs auras - when spell hits target - called for each target from spell target map
+ // 13. AfterHit - executed just after spell finishes all it's jobs for target - called for each target from spell target map
// this hook is only executed after a successful dispel of any aura
// OnEffectSuccessfulDispel - executed just after effect successfully dispelled aura(s)
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 d686ca8ba38..d215a21cf40 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
@@ -862,6 +862,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:
@@ -904,6 +925,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 364a4dbb6c9..8c7d8527012 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
@@ -1669,21 +1669,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);
}
};