From 9038e3a2ff3ecf5a3d3a0893a03b2b4a757cb20c Mon Sep 17 00:00:00 2001 From: Emagi Date: Thu, 12 Jun 2025 14:46:17 -0400 Subject: [PATCH] Fixed a deadlock if a spell ward had redirect damage for self, it kept looping into CheckWards on the victim --- source/WorldServer/Combat.cpp | 5 +++-- source/WorldServer/Entity.cpp | 2 +- source/WorldServer/Entity.h | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/source/WorldServer/Combat.cpp b/source/WorldServer/Combat.cpp index fe7ca00..6a55284 100644 --- a/source/WorldServer/Combat.cpp +++ b/source/WorldServer/Combat.cpp @@ -1047,7 +1047,7 @@ Skill* Entity::GetSkillByWeaponType(int8 type, int8 damage_type, bool update) { return 0; } -bool Entity::DamageSpawn(Entity* victim, int8 type, int8 damage_type, int32 low_damage, int32 high_damage, const char* spell_name, int8 crit_mod, bool is_tick, bool no_calcs, bool ignore_attacker, bool take_power, LuaSpell* spell) { +bool Entity::DamageSpawn(Entity* victim, int8 type, int8 damage_type, int32 low_damage, int32 high_damage, const char* spell_name, int8 crit_mod, bool is_tick, bool no_calcs, bool ignore_attacker, bool take_power, LuaSpell* spell, bool skip_check_wards) { if(spell) { spell->is_damage_spell = true; } @@ -1162,7 +1162,8 @@ bool Entity::DamageSpawn(Entity* victim, int8 type, int8 damage_type, int32 low_ if(damage) { int32 prevDmg = damage; - damage = victim->CheckWards(this, damage, damage_type); + if(!skip_check_wards) + damage = victim->CheckWards(this, damage, damage_type); if (damage < (sint64)prevDmg) useWards = true; diff --git a/source/WorldServer/Entity.cpp b/source/WorldServer/Entity.cpp index 30b54c4..1a6baba 100644 --- a/source/WorldServer/Entity.cpp +++ b/source/WorldServer/Entity.cpp @@ -2387,7 +2387,7 @@ int32 Entity::CheckWards(Entity* attacker, int32 damage, int8 damage_type) { } if (attacker && spell->caster) - attacker->DamageSpawn(spell->caster, DAMAGE_PACKET_TYPE_SPELL_DAMAGE, damage_type, redirectDamage, redirectDamage, 0, 0, false, false, false, false, spell); + attacker->DamageSpawn(spell->caster, DAMAGE_PACKET_TYPE_SPELL_DAMAGE, damage_type, redirectDamage, redirectDamage, 0, 0, false, false, false, false, spell, true); } bool shouldRemoveSpell = false; diff --git a/source/WorldServer/Entity.h b/source/WorldServer/Entity.h index e92a7f3..1f80982 100644 --- a/source/WorldServer/Entity.h +++ b/source/WorldServer/Entity.h @@ -1558,7 +1558,7 @@ public: int8 DetermineHit(Spawn* victim, int8 type, int8 damage_type, float ToHitBonus, bool is_caster_spell, LuaSpell* lua_spell = nullptr); float GetDamageTypeResistPercentage(int8 damage_type); Skill* GetSkillByWeaponType(int8 type, int8 damage_type, bool update); - bool DamageSpawn(Entity* victim, int8 type, int8 damage_type, int32 low_damage, int32 high_damage, const char* spell_name, int8 crit_mod = 0, bool is_tick = false, bool no_damage_calcs = false, bool ignore_attacker = false, bool take_power = false, LuaSpell* spell = 0); + bool DamageSpawn(Entity* victim, int8 type, int8 damage_type, int32 low_damage, int32 high_damage, const char* spell_name, int8 crit_mod = 0, bool is_tick = false, bool no_damage_calcs = false, bool ignore_attacker = false, bool take_power = false, LuaSpell* spell = 0, bool skip_check_wards = false); float CalculateMitigation(int8 type = DAMAGE_PACKET_TYPE_SIMPLE_DAMAGE, int8 damage_type = 0, int16 attacker_level = 0, bool for_pvp = false); void AddHate(Entity* attacker, sint32 hate, bool ignore_pet_behavior = false); bool CheckInterruptSpell(Entity* attacker);