fix fallback movement conditional and update nampower support to 2_38

This commit is contained in:
Jrc13245
2026-02-18 17:18:48 -05:00
parent ec43a636d6
commit 15091a867b
4 changed files with 81 additions and 23 deletions
+9 -16
View File
@@ -2664,25 +2664,18 @@ function CleveRoids.IsPlayerMoving()
local headIdx = CleveRoids._posHistoryIndex or 0
if history and count >= 2 then
-- Iterate consecutive pairs in circular buffer order (oldest to newest)
-- Head is the most recent entry, walk backwards through the ring
local samplesAvail = count
for i = 1, samplesAvail - 1 do
-- prevIdx and currIdx walk from oldest to newest
local currOffset = samplesAvail - i -- e.g., 3,2,1,0 for count=4
local prevOffset = samplesAvail - i + 1 -- e.g., 4,3,2,1
local currIdx = math.mod((headIdx - currOffset - 1 + 4), 4) + 1
local prevIdx = math.mod((headIdx - prevOffset - 1 + 4), 4) + 1
local prev = history[prevIdx]
local curr = history[currIdx]
-- Compare the most recent pair: headIdx (newest) vs. the slot before it.
-- Use (headIdx - 2 + 4) mod 4 to safely wrap backwards in the 1-based ring.
-- This avoids Lua 5.0 math.mod returning negative values for negative inputs.
local prevIdx = math.mod((headIdx - 2 + 4), 4) + 1
local curr = history[headIdx]
local prev = history[prevIdx]
if curr and prev then
local dx = curr.x - prev.x
local dy = curr.y - prev.y
local dist = math.sqrt(dx * dx + dy * dy)
if dist > 0.001 then
return true -- Any movement in recent history = moving
end
return math.sqrt(dx * dx + dy * dy) > 0.001
end
return false -- No movement in any recent sample = stopped
return false
end
-- Legacy fallback for code that might not have history yet
+12
View File
@@ -5208,6 +5208,18 @@ function CleveRoids.Frame:SPELLCAST_CHANNEL_START()
end
end
-- v2.38+: Override channelDuration with the accurate server-provided value stored by
-- SPELL_START_SELF (which fires before this event). This beats the tooltip scan or
-- UNIT_CASTEVENT cast_time fallback, because the server already applied all modifiers.
if CleveRoids._v238ChannelDuration then
if not spellId or not CleveRoids._v238ChannelSpellId
or CleveRoids._v238ChannelSpellId == spellId then
CleveRoids.channelDuration = CleveRoids._v238ChannelDuration
end
CleveRoids._v238ChannelDuration = nil
CleveRoids._v238ChannelSpellId = nil
end
-- Force immediate action update
CleveRoids.TestForAllActiveActions()
end
+34 -1
View File
@@ -109,7 +109,19 @@
- SetMouseoverUnit(unitToken) - Programmatically set the mouseover unit.
Previously only available via SuperWoW; now also provided by Nampower.
Current version: v2.37.0
Spell Duration & Enhanced SPELL_START (v2.38+):
- GetSpellDuration(spellId, [ignoreModifiers]) - Returns duration in ms.
For channeling spells: channel duration. For others: first aura effect duration.
Pass ignoreModifiers=1 to get base duration (ignores talents/buffs).
Returns 0 if spell has no duration, nil if spellId invalid.
- SPELL_START_SELF / SPELL_START_OTHER now include two new parameters:
arg7 = duration (ms) - channel duration for channeling spells, 0 otherwise
arg8 = spellType - 0=Normal, 1=Channeling, 2=Autorepeating
Use spellType to distinguish channeling spells (SPELL_START_OTHER carries both
cast-time and channeling spells since there is no separate SPELL_CHANNEL_START
packet for other players).
Current version: v2.38.0
]]
local _G = _G or getfenv(0)
@@ -283,6 +295,10 @@ API.VERSION_REQUIREMENTS = {
-- v2.37+ - Unit token cast support and SetMouseoverUnit
["CastSpellByNameUnitToken"]= { 2, 37, 0 }, -- CastSpellByName accepts unit token strings as 2nd param
["SetMouseoverUnit"] = { 2, 37, 0, "SetMouseoverUnit" },
-- v2.38+ - GetSpellDuration and enhanced SPELL_START parameters
["GetSpellDuration"] = { 2, 38, 0, "GetSpellDuration" },
["SpellStartSpellType"] = { 2, 38, 0 }, -- duration + spellType params added to SPELL_START events
}
-- Check if a specific feature is available
@@ -440,6 +456,10 @@ local function InitializeFeatures()
f.hasCastSpellByNameUnitToken = API.HasFeature("CastSpellByNameUnitToken")
f.hasSetMouseoverUnit = API.HasFeature("SetMouseoverUnit")
-- v2.38+ GetSpellDuration and enhanced SPELL_START parameters
f.hasGetSpellDuration = API.HasFeature("GetSpellDuration")
f.hasSpellStartSpellType = API.HasFeature("SpellStartSpellType")
-- Runtime detection for enhanced spell functions (verify by testing)
if f.hasEnhancedSpellFunctions and GetSpellTexture then
local success, result = pcall(function()
@@ -3040,6 +3060,19 @@ function API.GetSpellPower(mode)
return _G.GetSpellPower(mode)
end
-- Get duration of a spell in milliseconds (v2.38+)
-- For channeling spells: returns the channel duration.
-- For non-channeling spells: returns the first aura effect duration.
-- spellId: spell ID to look up
-- ignoreModifiers: pass 1 to ignore talent/buff modifiers (returns base duration)
-- Returns: duration in ms (0 if spell has no duration), or nil if spellId invalid
function API.GetSpellDuration(spellId, ignoreModifiers)
if not API.features.hasGetSpellDuration or not _G.GetSpellDuration then
return nil
end
return _G.GetSpellDuration(spellId, ignoreModifiers)
end
--------------------------------------------------------------------------------
-- AURA CANCEL FUNCTIONS (v2.34+)
--------------------------------------------------------------------------------
+26 -6
View File
@@ -754,12 +754,12 @@ function lib:HasPfUI76()
if v.major < 7 then return false end
if v.major == 7 and (v.minor or 0) < 6 then return false end
-- Verify Nampower v2.37.0+ (pfUI 7.6+ hard requirement)
-- Verify Nampower v2.38.0+ (pfUI 7.6+ hard requirement, bumped from 2.37 in pfUI update 2026-02-18)
if not GetNampowerVersion then return false end
local npMajor, npMinor, npPatch = GetNampowerVersion()
npPatch = npPatch or 0
if npMajor < 2 then return false end
if npMajor == 2 and npMinor < 37 then return false end
if npMajor == 2 and npMinor < 38 then return false end
-- Verify the new tables exist
if not pfUI.libdebuff_casts then return false end
@@ -4450,19 +4450,38 @@ ev:SetScript("OnEvent", function()
-- and these handlers return early (pfUI handles it).
elseif event == "SPELL_START_SELF" or event == "SPELL_START_OTHER" then
-- v2.38+: For player's own channeling spells, pre-store the accurate server channel duration
-- BEFORE the pfUI early-return so SPELLCAST_CHANNEL_START (which fires later) can use it.
-- arg8 == 1 means spellType=Channeling; arg7 is the channel duration in ms.
if event == "SPELL_START_SELF" and arg8 == 1 and arg7 and arg7 > 0 then
CleveRoids._v238ChannelDuration = arg7 / 1000
CleveRoids._v238ChannelSpellId = arg2
end
-- pfUI 7.6 manages castTracking via its own SPELL_START handler
if lib.hasPfUI76 then return end
local spellId = arg2
local casterGuid = arg3
local castTime = arg6 -- milliseconds
local castTime = arg6 -- cast time in milliseconds
-- v2.38+: arg7 = channel duration (ms, channeling spells only), arg8 = spellType (0=Normal,1=Channeling,2=Autorepeating)
local channelDuration = arg7
local spellType = arg8
if not casterGuid or not spellId then return end
local spellName = SpellInfo and SpellInfo(spellId)
local icon = lib:GetCachedIcon(spellId)
local now = GetTime()
local durationSec = castTime and (castTime / 1000) or 0
-- For channeling spells (v2.38+: spellType==1), use the channel duration.
-- For normal cast-time spells, use castTime. Fall back to castTime if params unavailable.
local durationMs
if spellType == 1 and channelDuration and channelDuration > 0 then
durationMs = channelDuration
else
durationMs = castTime or 0
end
local durationSec = durationMs / 1000
CleveRoids.castTracking[casterGuid] = {
spellID = spellId,
@@ -4474,9 +4493,10 @@ ev:SetScript("OnEvent", function()
}
if CleveRoids.debug then
local typeStr = spellType == 1 and "channel" or (spellType == 2 and "auto" or "cast")
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cff00ccff[SPELL_START]|r %s (ID:%d) cast by %s - %.1fs",
spellName or "Unknown", spellId, casterGuid, durationSec)
string.format("|cff00ccff[SPELL_START]|r %s (ID:%d) cast by %s - %.1fs [%s]",
spellName or "Unknown", spellId, casterGuid, durationSec, typeStr)
)
end