From 46b48cdfa0119796833b72248ea9b61b67567b89 Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Tue, 10 Mar 2026 22:09:26 -0300 Subject: [PATCH] fix(Core/Spells): Implement spell_jump_distance (#25023) Co-authored-by: Claude Sonnet 4.6 --- .../pending_db_world/rev_1772885471981.sql | 11 ++++++ src/server/game/Spells/Spell.cpp | 4 +++ src/server/game/Spells/SpellInfo.cpp | 1 + src/server/game/Spells/SpellInfo.h | 1 + src/server/game/Spells/SpellMgr.cpp | 36 +++++++++++++++++++ src/server/game/Spells/SpellMgr.h | 1 + src/server/game/World/World.cpp | 3 ++ 7 files changed, 57 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1772885471981.sql diff --git a/data/sql/updates/pending_db_world/rev_1772885471981.sql b/data/sql/updates/pending_db_world/rev_1772885471981.sql new file mode 100644 index 000000000..db9f5cbd4 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1772885471981.sql @@ -0,0 +1,11 @@ +-- +CREATE TABLE IF NOT EXISTS `spell_jump_distance` ( + `ID` int unsigned NOT NULL COMMENT 'spell id', + `JumpDistance` float NOT NULL DEFAULT '0' COMMENT 'max hop distance in yards', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Per-spell chain jump distance override'; + +DELETE FROM `spell_jump_distance` WHERE `ID` IN (62131, 64390); +INSERT INTO `spell_jump_distance` (`ID`, `JumpDistance`) VALUES +(62131, 5.0), +(64390, 5.0); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 858df76c1..73ee8e153 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -2126,6 +2126,10 @@ void Spell::SearchChainTargets(std::list& targets, uint32 chainTar break; } + // per-spell override from spell_jump_distance table + if (m_spellInfo->JumpDistance > 0.0f) + jumpRadius = m_spellInfo->JumpDistance; + // chain lightning/heal spells and similar - allow to jump at larger distance and go out of los bool isBouncingFar = (m_spellInfo->HasAttribute(SPELL_ATTR4_BOUNCY_CHAIN_MISSILES) || m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_NONE diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 3b96e673e..f075b59d4 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -861,6 +861,7 @@ SpellInfo::SpellInfo(SpellEntry const* spellEntry) _isSpellValid = true; _isCritCapable = false; _requireCooldownInfo = false; + JumpDistance = 0.0f; } SpellInfo::~SpellInfo() diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index 131471937..00462fe66 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -401,6 +401,7 @@ public: bool _isSpellValid; bool _isCritCapable; bool _requireCooldownInfo; + float JumpDistance; SpellInfo(SpellEntry const* spellEntry); ~SpellInfo(); diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 6efda7bed..42bf4ed7d 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -2957,6 +2957,42 @@ void SpellMgr::LoadSpellSpecificAndAuraState() LOG_INFO("server.loading", " "); } +void SpellMgr::LoadSpellJumpDistances() +{ + uint32 oldMSTime = getMSTime(); + + QueryResult result = WorldDatabase.Query("SELECT ID, JumpDistance FROM spell_jump_distance"); + + if (!result) + { + LOG_WARN("server.loading", ">> Loaded 0 spell jump distances. DB table `spell_jump_distance` is empty."); + LOG_INFO("server.loading", " "); + return; + } + + uint32 count = 0; + do + { + Field const* fields = result->Fetch(); + + uint32 const spellId = fields[0].Get(); + float const jumpDistance = fields[1].Get(); + + SpellInfo* spellInfo = _GetSpellInfo(spellId); + if (!spellInfo) + { + LOG_ERROR("sql.sql", "Table `spell_jump_distance` has wrong spell (spell_id: {}), ignored.", spellId); + continue; + } + + spellInfo->JumpDistance = jumpDistance; + ++count; + } while (result->NextRow()); + + LOG_INFO("server.loading", ">> Loaded {} spell jump distances in {} ms", count, GetMSTimeDiffToNow(oldMSTime)); + LOG_INFO("server.loading", " "); +} + void SpellMgr::LoadSpellInfoCustomAttributes() { uint32 const oldMSTime = getMSTime(); diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index a56ec9145..ccedf1bff 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -778,6 +778,7 @@ public: void LoadSpellInfoCustomAttributes(); void LoadSpellInfoCorrections(); void LoadSpellSpecificAndAuraState(); + void LoadSpellJumpDistances(); private: SpellDifficultySearcherMap mSpellDifficultySearcherMap; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 042da7585..0db7ffd3c 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -433,6 +433,9 @@ void World::SetInitialWorldSettings() LOG_INFO("server.loading", "Loading SpellInfo Custom Attributes..."); sSpellMgr->LoadSpellInfoCustomAttributes(); + LOG_INFO("server.loading", "Loading Spell Jump Distances..."); + sSpellMgr->LoadSpellJumpDistances(); + LOG_INFO("server.loading", "Loading Player Totem models..."); sObjectMgr->LoadPlayerTotemModels();