From ca50bb5b556aadfaa1ed440d9d4da2fb3997c3a5 Mon Sep 17 00:00:00 2001 From: Jrc13245 Date: Mon, 22 Dec 2025 12:05:20 -0500 Subject: [PATCH] fix icon out of range on self cast spells and nil check for combodurations --- ComboPointTracker.lua | 3 +++ Conditionals.lua | 37 +++++++++++--------------------- Core.lua | 49 +++++++++++++++++++++++++++---------------- NampowerAPI.lua | 25 +++++++++++----------- 4 files changed, 58 insertions(+), 56 deletions(-) diff --git a/ComboPointTracker.lua b/ComboPointTracker.lua index d06b857..8dd05b8 100644 --- a/ComboPointTracker.lua +++ b/ComboPointTracker.lua @@ -195,6 +195,9 @@ end -- NEW: Get learned duration for specific combo point count function CleveRoids.GetLearnedComboDuration(spellID, comboPoints) + if not CleveRoids_ComboDurations then + CleveRoids_ComboDurations = {} + end if CleveRoids_ComboDurations[spellID] and CleveRoids_ComboDurations[spellID][comboPoints] then return CleveRoids_ComboDurations[spellID][comboPoints] end diff --git a/Conditionals.lua b/Conditionals.lua index 247416c..de6262f 100644 --- a/Conditionals.lua +++ b/Conditionals.lua @@ -3288,53 +3288,40 @@ CleveRoids.Keywords = { inrange = function(conditionals) if not IsSpellInRange then return end + local API = CleveRoids.NampowerAPI return Multi(conditionals.inrange, function(spellName) local target = conditionals.target or "target" local checkValue = spellName or conditionals.action - -- Try to convert spell name to ID for better accuracy (Nampower) - if type(checkValue) == "string" and GetSpellIdForName then - local spellId = GetSpellIdForName(checkValue) - if spellId and spellId > 0 then - checkValue = spellId - end - end - - return IsSpellInRange(checkValue, target) == 1 + -- Use API wrapper which handles self-cast spells correctly + local result = API.IsSpellInRange(checkValue, target) + return result == 1 end, conditionals, "inrange") end, noinrange = function(conditionals) if not IsSpellInRange then return end + local API = CleveRoids.NampowerAPI return NegatedMulti(conditionals.noinrange, function(spellName) local target = conditionals.target or "target" local checkValue = spellName or conditionals.action - if type(checkValue) == "string" and GetSpellIdForName then - local spellId = GetSpellIdForName(checkValue) - if spellId and spellId > 0 then - checkValue = spellId - end - end - - return IsSpellInRange(checkValue, target) == 0 + -- Use API wrapper which handles self-cast spells correctly + local result = API.IsSpellInRange(checkValue, target) + return result == 0 end, conditionals, "noinrange") end, outrange = function(conditionals) if not IsSpellInRange then return end + local API = CleveRoids.NampowerAPI return Multi(conditionals.outrange, function(spellName) local target = conditionals.target or "target" local checkValue = spellName or conditionals.action - if type(checkValue) == "string" and GetSpellIdForName then - local spellId = GetSpellIdForName(checkValue) - if spellId and spellId > 0 then - checkValue = spellId - end - end - - return IsSpellInRange(checkValue, target) == 0 + -- Use API wrapper which handles self-cast spells correctly + local result = API.IsSpellInRange(checkValue, target) + return result == 0 end, conditionals, "outrange") end, diff --git a/Core.lua b/Core.lua index 3f576f8..a64be16 100644 --- a/Core.lua +++ b/Core.lua @@ -860,30 +860,43 @@ function CleveRoids.TestForActiveAction(actions) end end - if UnitExists(unit) then - -- PERFORMANCE: Try to get spell ID with caching - local checkValue = castName - if GetSpellIdForName then - -- Check cache first - local cachedId = CleveRoids.spellIdCache[castName] - if cachedId then - checkValue = cachedId - else - local spellId = GetSpellIdForName(castName) - if spellId and spellId > 0 then - checkValue = spellId - CleveRoids.spellIdCache[castName] = spellId - end + -- PERFORMANCE: Try to get spell ID with caching + local spellId = nil + if GetSpellIdForName then + -- Check cache first + local cachedId = CleveRoids.spellIdCache[castName] + if cachedId then + spellId = cachedId + else + spellId = GetSpellIdForName(castName) + if spellId and spellId > 0 then + CleveRoids.spellIdCache[castName] = spellId end end + end - -- Use API wrapper which has UnitXP fallback for channeled spells - local r = CleveRoids.NampowerAPI.IsSpellInRange(checkValue, unit) + -- Check for self-cast spells first (always in range regardless of target) + local API = CleveRoids.NampowerAPI + if spellId and spellId > 0 and API.GetSpellField then + local rangeIndex = API.GetSpellField(spellId, "rangeIndex") + -- rangeIndex 0 = Self Only, 14 = Self Only (alternate), 23 = Touch + if rangeIndex == 0 or rangeIndex == 14 or rangeIndex == 23 then + actions.active.inRange = 1 -- Self-targeted spells are always in range + elseif UnitExists(unit) then + -- Use API wrapper which has UnitXP fallback for channeled spells + local r = API.IsSpellInRange(spellId, unit) + if r ~= nil then + -- Got a definitive answer (0 = out of range, 1 = in range) + actions.active.inRange = r + end + -- If r is nil, inRange stays at -1 (unknown) and we'll use proxy/original + end + elseif UnitExists(unit) then + -- Fallback: use API wrapper with spell name if no spell ID + local r = API.IsSpellInRange(castName, unit) if r ~= nil then - -- Got a definitive answer (0 = out of range, 1 = in range) actions.active.inRange = r end - -- If r is nil, inRange stays at -1 (unknown) and we'll use proxy/original end end diff --git a/NampowerAPI.lua b/NampowerAPI.lua index 6e9ef0c..a65bebe 100644 --- a/NampowerAPI.lua +++ b/NampowerAPI.lua @@ -1539,25 +1539,24 @@ function API.IsSpellInRange(spellIdentifier, unit) spellId = spellIdentifier end - -- Try native IsSpellInRange first + -- Check for self-cast spells FIRST before native range check + -- Self-targeted spells are always in range regardless of what IsSpellInRange returns + if spellId and spellId > 0 then + local rangeIndex = API.GetSpellField(spellId, "rangeIndex") + -- rangeIndex 0 = Self Only, 14 = Self Only (alternate), 23 = Touch + if rangeIndex == 0 or rangeIndex == 14 or rangeIndex == 23 then + return 1 -- Self-targeted spells are always in range + end + end + + -- Try native IsSpellInRange for non-self spells if IsSpellInRange then local result = IsSpellInRange(checkValue, unit) -- result == 1 (in range), 0 (out of range), -1 (invalid/non-unit-targeted), nil (error) - -- Only use native result for definitive answers (0 or 1) if result == 0 or result == 1 then return result end - - -- For -1 (non-unit-targeted), check if it's a self-only spell - -- Self-targeted spells (rangeIndex 0) should always be considered in range - if result == -1 and spellId and spellId > 0 then - local rangeIndex = API.GetSpellField(spellId, "rangeIndex") - -- rangeIndex 0 = Self Only, 14 = Self Only (alternate), 23 = Touch - if rangeIndex == 0 or rangeIndex == 14 or rangeIndex == 23 then - return 1 -- Self-targeted spells are always in range - end - -- For other -1 cases (ground-targeted like Blizzard), fall through to UnitXP - end + -- For -1 (ground-targeted like Blizzard), fall through to UnitXP fallback end -- Fallback: Use spell range from record + UnitXP distance check