From b4022e39986ba06e20986d8f1045d69fb32a9f1d Mon Sep 17 00:00:00 2001 From: bo Date: Sat, 3 Jan 2026 01:14:51 -0600 Subject: [PATCH] Bot spell actions use actual DBC range instead of global spellDistance Looks up each spell's true max range from SpellRangeEntry at construction. getPrerequisites() early-exits if already in range, avoiding movement when unnecessary. spellDistance config remains a backstop for engagement distance. --- .../strategy/actions/GenericSpellActions.h | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/modules/Bots/playerbot/strategy/actions/GenericSpellActions.h b/src/modules/Bots/playerbot/strategy/actions/GenericSpellActions.h index 71824f49c..34b290689 100644 --- a/src/modules/Bots/playerbot/strategy/actions/GenericSpellActions.h +++ b/src/modules/Bots/playerbot/strategy/actions/GenericSpellActions.h @@ -51,6 +51,22 @@ namespace ai range(sPlayerbotAIConfig.spellDistance) { this->spell = spell; + // Clamp range to actual spell's min/max range from DBC + uint32 spellId = AI_VALUE2(uint32, "spell id", spell); + if (spellId) + { + const SpellEntry* pSpellInfo = sSpellStore.LookupEntry(spellId); + if (pSpellInfo) + { + SpellRangeEntry const* spellRange = sSpellRangeStore.LookupEntry(pSpellInfo->rangeIndex); + if (spellRange) + { + float actualMaxRange = GetSpellMaxRange(spellRange); + if (actualMaxRange > 0) // Only clamp if spell has a defined range + range = actualMaxRange; + } + } + } } virtual string GetTargetName() { return "current target"; }; @@ -61,6 +77,20 @@ namespace ai virtual NextAction** getPrerequisites() { + float currentDistance = AI_VALUE2(float, "distance", GetTargetName()); + + if (currentDistance <= range) + { + if (range > ATTACK_DISTANCE) + { + return Action::getPrerequisites(); + } + else + { + return NextAction::merge(NextAction::array(0, new NextAction("reach melee"), NULL), Action::getPrerequisites()); + } + } + if (range > sPlayerbotAIConfig.spellDistance) { return NULL;