update for nampower errors

This commit is contained in:
Jrc13245
2025-12-27 14:38:24 -05:00
parent 8d39ae75c2
commit 370167b3a7
6 changed files with 250 additions and 58 deletions
+11 -8
View File
@@ -224,14 +224,17 @@ function CleveRoids.CalculateComboScaledDurationByID(spellID, comboPoints)
baseDuration = data.base + (comboPoints - 1) * data.increment
end
-- Apply talent modifiers (e.g., Taste for Blood) - additive
if CleveRoids.ApplyTalentModifier then
baseDuration = CleveRoids.ApplyTalentModifier(spellID, baseDuration)
end
-- Apply equipment modifiers (e.g., Black Morass Idol) - multiplicative
if CleveRoids.ApplyEquipmentModifier then
baseDuration = CleveRoids.ApplyEquipmentModifier(spellID, baseDuration)
-- Apply all duration modifiers (Nampower, talents, equipment, set bonuses)
if CleveRoids.ApplyAllDurationModifiers then
baseDuration = CleveRoids.ApplyAllDurationModifiers(spellID, baseDuration)
else
-- Fallback for load order (ApplyAllDurationModifiers not yet defined)
if CleveRoids.ApplyTalentModifier then
baseDuration = CleveRoids.ApplyTalentModifier(spellID, baseDuration)
end
if CleveRoids.ApplyEquipmentModifier then
baseDuration = CleveRoids.ApplyEquipmentModifier(spellID, baseDuration)
end
end
return baseDuration
+24 -5
View File
@@ -154,6 +154,9 @@ local _equippedItemIDs = {} -- [slot] = itemID (number)
local _equippedItemNames = {} -- [slot] = itemName (lowercase string)
local _equipmentCacheValid = false
-- Track if we've warned about GetEquippedItems errors (warn once per session)
local _getEquippedItemsErrorWarned = false
local function BuildEquipmentCache()
if _equipmentCacheValid then return end
_equipmentCacheValid = true
@@ -168,11 +171,28 @@ local function BuildEquipmentCache()
local string_lower = string.lower
-- Try Nampower v2.18+ GetEquippedItems for faster enumeration
if GetEquippedItems then
local items = GetEquippedItems("player")
if items and type(items) == "table" then
-- Requires version check because the function may exist but be broken in older versions
local API = CleveRoids.NampowerAPI
local hasValidNampower = API and API.HasMinimumVersion and API.HasMinimumVersion(2, 18, 0)
if hasValidNampower and GetEquippedItems then
-- Use pcall to catch any internal Nampower errors and fall back gracefully
local success, result = pcall(GetEquippedItems, "player")
if not success then
-- Log the error once per session for debugging
if not _getEquippedItemsErrorWarned then
_getEquippedItemsErrorWarned = true
local errMsg = tostring(result)
if CleveRoids.Print then
CleveRoids.Print("|cffff6600Warning:|r GetEquippedItems failed: " .. errMsg)
CleveRoids.Print("Using fallback equipment detection. Consider updating Nampower.")
end
end
-- Fall through to manual enumeration
elseif result and type(result) == "table" then
local usedNampower = false
for nampowerSlot, itemInfo in pairs(items) do
for nampowerSlot, itemInfo in pairs(result) do
-- Nampower uses 0-indexed slots, WoW API uses 1-indexed
-- tonumber() handles both string and numeric keys from different Nampower versions
local slot = tonumber(nampowerSlot) + 1
@@ -182,7 +202,6 @@ local function BuildEquipmentCache()
usedNampower = true
-- Get item name via Nampower API or GetItemInfo
local API = CleveRoids.NampowerAPI
local itemName = API and API.GetItemName and API.GetItemName(itemInfo.itemId)
if not itemName then
itemName = GetItemInfo(itemInfo.itemId)
+65 -26
View File
@@ -3570,19 +3570,26 @@ function IsCurrentAction(slot)
name = actionToCheck.spell.name..(rank and ("("..rank..")"))
-- Check if this spell is currently queued or being cast via Nampower
if GetCurrentCastingInfo then
local castId, visId, autoId, casting, channeling, onswing, autoattack = GetCurrentCastingInfo()
-- Get spell ID for comparison
local spellId = actionToCheck.spell.id
if not spellId and GetSpellIdForName then
spellId = GetSpellIdForName(name)
end
-- Get spell ID for comparison
local spellId = actionToCheck.spell.id
if not spellId and GetSpellIdForName then
spellId = GetSpellIdForName(name)
if spellId then
-- Prefer GetCastInfo (Nampower 2.18+) for cleaner API
if GetCastInfo then
local info = GetCastInfo()
if info and info.spellId == spellId then
-- Spell is actively being cast/channeled
return true
end
end
-- Only show glow if spell is actively casting, channeling, or queued
-- castId matches when spell is queued or being cast
-- visId matches during channeling
if spellId then
-- Also check GetCurrentCastingInfo for queued spell detection
if GetCurrentCastingInfo then
local castId, visId, autoId, casting, channeling = GetCurrentCastingInfo()
-- Show glow if actively casting/channeling this spell
if (casting == 1 and castId == spellId) or (channeling == 1 and visId == spellId) then
return true
@@ -4196,15 +4203,30 @@ function CleveRoids.Frame:SPELLCAST_CHANNEL_START()
-- Duration is captured by UNIT_CASTEVENT which fires earlier
CleveRoids.CurrentSpell.type = "channeled"
-- Try to get spell name from GetCurrentCastingInfo if available
if GetCurrentCastingInfo then
local castId, visId, autoId, casting, channeling, onswing, autoattack = GetCurrentCastingInfo()
-- Try to get spell info - prefer GetCastInfo (Nampower 2.18+) for better data
local spellId = nil
if GetCastInfo then
local info = GetCastInfo()
if info and info.spellId and info.spellId > 0 then
spellId = info.spellId
-- Also capture timing data
CleveRoids.CurrentSpell.castRemainingMs = info.castRemainingMs
CleveRoids.CurrentSpell.castEndTime = info.castEndS
end
end
-- Fallback to GetCurrentCastingInfo for older Nampower
if not spellId and GetCurrentCastingInfo then
local _, visId = GetCurrentCastingInfo()
if visId and visId > 0 then
CleveRoids.CurrentSpell.castingSpellId = visId
local spellName = SpellInfo(visId)
if spellName then
CleveRoids.CurrentSpell.spellName = spellName
end
spellId = visId
end
end
-- Update spell info
if spellId then
CleveRoids.CurrentSpell.castingSpellId = spellId
local spellName = SpellInfo(spellId)
if spellName then
CleveRoids.CurrentSpell.spellName = spellName
end
end
@@ -4227,15 +4249,32 @@ function CleveRoids.Frame:SPELLCAST_START()
-- Duration is captured by UNIT_CASTEVENT which fires earlier
CleveRoids.CurrentSpell.type = "cast"
-- Try to get spell name from GetCurrentCastingInfo if available
if GetCurrentCastingInfo then
local castId, visId, autoId, casting, channeling, onswing, autoattack = GetCurrentCastingInfo()
-- Try to get spell info - prefer GetCastInfo (Nampower 2.18+) for better data
local spellId = nil
if GetCastInfo then
local info = GetCastInfo()
if info and info.spellId and info.spellId > 0 then
spellId = info.spellId
-- Also capture timing data
CleveRoids.CurrentSpell.castRemainingMs = info.castRemainingMs
CleveRoids.CurrentSpell.castEndTime = info.castEndS
CleveRoids.CurrentSpell.gcdRemainingMs = info.gcdRemainingMs
CleveRoids.CurrentSpell.gcdEndTime = info.gcdEndS
end
end
-- Fallback to GetCurrentCastingInfo for older Nampower
if not spellId and GetCurrentCastingInfo then
local castId = GetCurrentCastingInfo()
if castId and castId > 0 then
CleveRoids.CurrentSpell.castingSpellId = castId
local spellName = SpellInfo(castId)
if spellName then
CleveRoids.CurrentSpell.spellName = spellName
end
spellId = castId
end
end
-- Update spell info
if spellId then
CleveRoids.CurrentSpell.castingSpellId = spellId
local spellName = SpellInfo(spellId)
if spellName then
CleveRoids.CurrentSpell.spellName = spellName
end
end
+17 -1
View File
@@ -79,12 +79,28 @@ CleveRoids.UpdateCastingState = function()
end
-- DO NOT touch channel state here - events handle it
-- Always update metadata
-- Always update metadata from GetCurrentCastingInfo (onswing/autoattack only here)
CleveRoids.CurrentSpell.autoAttack = (autoattack == 1)
CleveRoids.CurrentSpell.onSwingPending = (onswing == 1)
CleveRoids.CurrentSpell.visualSpellId = visId
CleveRoids.CurrentSpell.autoRepeatSpellId = autoId
-- Enhanced timing data from GetCastInfo (Nampower 2.18+)
if GetCastInfo then
local info = GetCastInfo()
if info then
CleveRoids.CurrentSpell.castRemainingMs = info.castRemainingMs
CleveRoids.CurrentSpell.castEndTime = info.castEndS
CleveRoids.CurrentSpell.gcdRemainingMs = info.gcdRemainingMs
CleveRoids.CurrentSpell.gcdEndTime = info.gcdEndS
else
CleveRoids.CurrentSpell.castRemainingMs = nil
CleveRoids.CurrentSpell.castEndTime = nil
CleveRoids.CurrentSpell.gcdRemainingMs = nil
CleveRoids.CurrentSpell.gcdEndTime = nil
end
end
return true
end
+40 -3
View File
@@ -32,9 +32,14 @@
- Pass 1 to get independent copy safe for storage
- Without copy, table references are reused - extract values immediately!
Utility Functions (v2.22+):
- DisenchantAll - Auto-disenchant items by ID/name or quality
Settings Integration:
- Reads from NampowerSettings addon when available
- Falls back to CVars when addon not present
Current version: v2.22.0
]]
local _G = _G or getfenv(0)
@@ -114,6 +119,9 @@ API.features = {
hasGetTrinketCooldown = (GetTrinketCooldown ~= nil),
hasUseTrinket = (UseTrinket ~= nil),
hasUseItemIdOrName = (UseItemIdOrName ~= nil),
-- v2.22+ APIs (utility functions)
hasDisenchantAll = (DisenchantAll ~= nil),
}
-- Detect if enhanced spell functions are available (accept name/spellId:number)
@@ -1337,10 +1345,13 @@ function API.GetTrinkets(copy)
local _, _, name = string.find(link, "|h%[(.-)%]|h")
local texture = GetInventoryItemTexture("player", slot)
if itemId then
local numItemId = tonumber(itemId)
local itemLevel = API.GetItemLevel(numItemId)
trinkets[index] = {
itemId = tonumber(itemId),
itemId = numItemId,
trinketName = name or "Unknown",
texture = texture,
itemLevel = itemLevel,
bagIndex = nil, -- nil means equipped
slotIndex = slot == 13 and 1 or 2,
}
@@ -1357,14 +1368,17 @@ function API.GetTrinkets(copy)
if link then
local _, _, itemId = string.find(link, "item:(%d+)")
if itemId then
local invType = API.GetItemInventoryType(tonumber(itemId))
local numItemId = tonumber(itemId)
local invType = API.GetItemInventoryType(numItemId)
if invType == 12 then -- Trinket
local _, _, name = string.find(link, "|h%[(.-)%]|h")
local texture = GetContainerItemInfo(bag, slot)
local itemLevel = API.GetItemLevel(numItemId)
trinkets[index] = {
itemId = tonumber(itemId),
itemId = numItemId,
trinketName = name or "Unknown",
texture = texture,
itemLevel = itemLevel,
bagIndex = bag,
slotIndex = slot,
}
@@ -1521,6 +1535,29 @@ function API.UseItemIdOrName(itemIdOrName, target)
return 0
end
--------------------------------------------------------------------------------
-- DISENCHANT API (v2.22+)
--------------------------------------------------------------------------------
-- Automatically disenchant items in inventory
-- Mode 1: DisenchantAll(itemIdOrName, [includeSoulbound]) - specific item by ID/name
-- Mode 2: DisenchantAll(quality, [includeSoulbound]) - "greens" or "blues"
-- includeSoulbound: pass 1 to include soulbound items (default: 0)
-- Returns: 1 if first disenchant succeeded, 0 if no items found or failed
--
-- WARNING: This function WILL disenchant items without confirmation!
-- Quest items are always protected. Soulbound items protected by default.
-- Only affects bags 0-4 (not bank).
function API.DisenchantAll(itemIdOrNameOrQuality, includeSoulbound)
-- Use native function if available (v2.22+)
if DisenchantAll then
return DisenchantAll(itemIdOrNameOrQuality, includeSoulbound)
end
-- No fallback available - requires Nampower 2.22+
return 0
end
--------------------------------------------------------------------------------
-- EVENT CONSTANTS (v2.18+, updated v2.20)
--------------------------------------------------------------------------------
+93 -15
View File
@@ -2124,21 +2124,10 @@ ev:SetScript("OnEvent", function()
if not duration then
duration = lib:GetDuration(spellID, casterGUID)
-- Apply talent modifiers for non-combo spells
-- (combo spells already have talent modifiers applied in CalculateComboScaledDurationByID)
if duration and CleveRoids.ApplyTalentModifier then
duration = CleveRoids.ApplyTalentModifier(spellID, duration)
end
-- Apply equipment modifiers for non-combo spells
-- (combo spells already have equipment modifiers applied in CalculateComboScaledDurationByID)
if duration and CleveRoids.ApplyEquipmentModifier then
duration = CleveRoids.ApplyEquipmentModifier(spellID, duration)
end
-- Apply set bonus modifiers for non-combo spells
if duration and CleveRoids.ApplySetBonusModifier then
duration = CleveRoids.ApplySetBonusModifier(spellID, duration)
-- Apply all duration modifiers (Nampower, talents, equipment, set bonuses)
-- (combo spells already have modifiers applied in CalculateComboScaledDurationByID)
if duration and CleveRoids.ApplyAllDurationModifiers then
duration = CleveRoids.ApplyAllDurationModifiers(spellID, duration)
end
end
@@ -3289,6 +3278,95 @@ function CleveRoids.RegisterEquipmentModifier(spellID, slotID, modifierFunc)
return true
end
-- ============================================================================
-- NAMPOWER SPELL MODIFIERS INTEGRATION (v2.18+)
-- ============================================================================
-- Try to get duration modifiers from Nampower's GetSpellModifiers
-- This function supplements (not replaces) the talent/equipment modifier system
-- Returns: Modified duration, or nil if no Nampower modifier applies
-- Parameters:
-- spellID: The spell ID
-- baseDuration: The base duration before modifiers
function CleveRoids.ApplyNampowerDurationModifier(spellID, baseDuration)
if not spellID or not baseDuration then
return nil
end
-- Check if Nampower API is available with GetSpellModifiers
local API = CleveRoids.NampowerAPI
if not API or not GetSpellModifiers then
return nil
end
-- MODIFIER_DURATION = 1
local flat, percent, hasModifier = GetSpellModifiers(spellID, 1)
if not hasModifier or (flat == 0 and percent == 0) then
return nil
end
-- Apply flat modifier first, then percentage (same as API.GetModifiedDuration)
local modified = baseDuration + (flat or 0)
if percent and percent ~= 0 then
modified = modified * (1 + percent / 100)
end
if CleveRoids.debug then
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cffff00ff[Nampower Duration Modifier]|r %s (ID:%d): %ds -> %ds (flat: %+d, percent: %+d%%)",
SpellInfo(spellID) or "Unknown", spellID, baseDuration, modified,
flat or 0, percent or 0)
)
end
return modified
end
-- Comprehensive duration modifier function that combines all sources
-- Order of application:
-- 1. Nampower GetSpellModifiers (if available and has data)
-- 2. Manual talent modifiers (fallback/supplement)
-- 3. Equipment modifiers
-- 4. Set bonus modifiers
-- Parameters:
-- spellID: The spell ID
-- baseDuration: The base duration (after combo points if applicable)
-- Returns: Fully modified duration
function CleveRoids.ApplyAllDurationModifiers(spellID, baseDuration)
if not spellID or not baseDuration then
return baseDuration
end
local duration = baseDuration
-- Try Nampower's GetSpellModifiers first (includes dynamic modifiers from buffs/talents)
local nampowerDuration = CleveRoids.ApplyNampowerDurationModifier(spellID, duration)
if nampowerDuration then
-- Nampower handled the talent modifiers, now apply equipment
duration = nampowerDuration
-- Still apply equipment modifiers (Nampower may not know about specific idols)
if CleveRoids.ApplyEquipmentModifier then
duration = CleveRoids.ApplyEquipmentModifier(spellID, duration)
end
else
-- Fallback: use manual talent and equipment modifiers
if CleveRoids.ApplyTalentModifier then
duration = CleveRoids.ApplyTalentModifier(spellID, duration)
end
if CleveRoids.ApplyEquipmentModifier then
duration = CleveRoids.ApplyEquipmentModifier(spellID, duration)
end
end
-- Always apply set bonus modifiers last
if CleveRoids.ApplySetBonusModifier then
duration = CleveRoids.ApplySetBonusModifier(spellID, duration)
end
return duration
end
-- ============================================================================
-- SET BONUS MODIFIER SYSTEM
-- ============================================================================