mirror of
https://github.com/brues-code/SuperCleveRoidMacros.git
synced 2026-09-16 03:38:00 +00:00
fix icon issue and fix carnage talent duration refreshers updating visually for pfui
This commit is contained in:
@@ -16,8 +16,8 @@ CleveRoids.ComboPointTracking = CleveRoids.ComboPointTracking or {}
|
||||
CleveRoids_ComboDurations = CleveRoids_ComboDurations or {}
|
||||
|
||||
-- Storage for last Rip cast (for Carnage talent mechanic)
|
||||
-- Carnage talent: Ferocious Bite with 5 CP refreshes Rip and Rake durations
|
||||
-- Talent Spell IDs: 16998 (Rank 1), 16999 (Rank 2)
|
||||
-- Carnage talent: Ferocious Bite at 5 CP refreshes Rip and Rake back to their original duration
|
||||
-- Talent Position: Tab 2 (Feral Combat), Talent 17
|
||||
CleveRoids.lastRipCast = CleveRoids.lastRipCast or {
|
||||
duration = nil,
|
||||
targetGUID = nil,
|
||||
@@ -56,14 +56,15 @@ CleveRoids.ComboScalingSpellsByID = {
|
||||
}
|
||||
|
||||
-- Ferocious Bite spell IDs (for Carnage talent mechanic)
|
||||
-- Carnage talent: Ferocious Bite with 5 CP refreshes Rip and Rake durations
|
||||
-- Talent Spell IDs: 16998 (Rank 1), 16999 (Rank 2)
|
||||
-- Carnage talent: Ferocious Bite at 5 CP refreshes Rip and Rake back to their original duration
|
||||
-- Talent Position: Tab 2 (Feral Combat), Talent 17
|
||||
CleveRoids.FerociousBiteSpellIDs = {
|
||||
[22557] = true, -- Rank 1
|
||||
[22568] = true, -- Rank 2
|
||||
[22827] = true, -- Rank 3
|
||||
[22828] = true, -- Rank 4
|
||||
[22829] = true, -- Rank 5
|
||||
[31018] = true, -- Rank 6
|
||||
}
|
||||
|
||||
-- Rip spell IDs (for Carnage talent - refreshed by Ferocious Bite at 5 CP)
|
||||
|
||||
+93
-60
@@ -91,6 +91,27 @@ function Extension.HandleSendChatMessageHook()
|
||||
end
|
||||
end
|
||||
|
||||
-- Helper function to check for Carnage duration override
|
||||
-- Returns override duration and timeleft if found, nil otherwise
|
||||
local function GetCarnageOverride(effect)
|
||||
if not effect or not CleveRoids.carnageDurationOverrides then
|
||||
return nil, nil
|
||||
end
|
||||
|
||||
for spellID, override in pairs(CleveRoids.carnageDurationOverrides) do
|
||||
local spellName = SpellInfo(spellID)
|
||||
if spellName then
|
||||
local baseName = string.gsub(spellName, "%s*%(Rank %d+%)", "")
|
||||
if baseName == effect and override.timestamp and (GetTime() - override.timestamp) < 5 then
|
||||
local timeleft = override.duration - (GetTime() - override.timestamp)
|
||||
if timeleft < 0 then timeleft = 0 end
|
||||
return override.duration, timeleft
|
||||
end
|
||||
end
|
||||
end
|
||||
return nil, nil
|
||||
end
|
||||
|
||||
-- Hook pfUI's libdebuff to use our combo-aware durations
|
||||
function Extension.HookPfUILibdebuff()
|
||||
if not pfUI or not pfUI.api or not pfUI.api.libdebuff then
|
||||
@@ -100,48 +121,30 @@ function Extension.HookPfUILibdebuff()
|
||||
local pflib = pfUI.api.libdebuff
|
||||
|
||||
-- Hook GetDuration if it exists
|
||||
-- pfUI's GetDuration signature: function(effect, rank) where effect is spell NAME
|
||||
if pflib.GetDuration and not Extension.pfLibDebuffHooked then
|
||||
local originalGetDuration = pflib.GetDuration
|
||||
|
||||
pflib.GetDuration = function(self, spellID, casterGUID, comboPoints)
|
||||
-- Check if this is a combo scaling spell first
|
||||
if CleveRoids.IsComboScalingSpellID and CleveRoids.IsComboScalingSpellID(spellID) then
|
||||
-- If combo points provided, check learned combo durations
|
||||
if comboPoints and CleveRoids_ComboDurations and CleveRoids_ComboDurations[spellID] then
|
||||
local comboDur = CleveRoids_ComboDurations[spellID][comboPoints]
|
||||
if comboDur and comboDur > 0 then
|
||||
if CleveRoids.debug then
|
||||
DEFAULT_CHAT_FRAME:AddMessage(
|
||||
string.format("|cff00ff00[pfUI Hook]|r Returning %ds for spell %d at %d CP",
|
||||
comboDur, spellID, comboPoints)
|
||||
)
|
||||
end
|
||||
return comboDur
|
||||
end
|
||||
end
|
||||
pflib.GetDuration = function(self, effect, rank)
|
||||
-- Check for Carnage duration overrides first (highest priority)
|
||||
local carnageDuration = GetCarnageOverride(effect)
|
||||
if carnageDuration then
|
||||
return carnageDuration
|
||||
end
|
||||
|
||||
-- Fallback: check for highest learned combo duration
|
||||
if CleveRoids_ComboDurations and CleveRoids_ComboDurations[spellID] then
|
||||
for cp = 5, 1, -1 do
|
||||
if CleveRoids_ComboDurations[spellID][cp] then
|
||||
if CleveRoids.debug then
|
||||
DEFAULT_CHAT_FRAME:AddMessage(
|
||||
string.format("|cff00ff00[pfUI Hook]|r Returning %ds for spell %d (fallback %d CP)",
|
||||
CleveRoids_ComboDurations[spellID][cp], spellID, cp)
|
||||
)
|
||||
end
|
||||
return CleveRoids_ComboDurations[spellID][cp]
|
||||
end
|
||||
end
|
||||
-- Check name-based tracking for fresh combo casts
|
||||
if CleveRoids.ComboPointTracking and CleveRoids.ComboPointTracking[effect] then
|
||||
local tracking = CleveRoids.ComboPointTracking[effect]
|
||||
if tracking.duration and tracking.confirmed and (GetTime() - tracking.cast_time) < 0.5 then
|
||||
return tracking.duration
|
||||
end
|
||||
end
|
||||
|
||||
-- Not a combo spell or no learned duration, use original
|
||||
return originalGetDuration(self, spellID, casterGUID, comboPoints)
|
||||
return originalGetDuration(self, effect, rank)
|
||||
end
|
||||
|
||||
Extension.pfLibDebuffHooked = true
|
||||
Extension.DLOG("Hooked pfUI.api.libdebuff.GetDuration for combo duration support")
|
||||
Extension.DLOG("Hooked pfUI.api.libdebuff.GetDuration for Carnage and combo duration support")
|
||||
end
|
||||
|
||||
-- Hook AddEffect if it exists to inject combo-aware durations
|
||||
@@ -149,41 +152,21 @@ function Extension.HookPfUILibdebuff()
|
||||
local originalAddEffect = pflib.AddEffect
|
||||
|
||||
pflib.AddEffect = function(self, unit, unitlevel, effect, duration, caster)
|
||||
-- effect is a spell name, not ID
|
||||
if CleveRoids.debug then
|
||||
DEFAULT_CHAT_FRAME:AddMessage(
|
||||
string.format("|cffcccccc[pfUI AddEffect]|r Called for '%s' on %s, duration=%s",
|
||||
effect, unit or "unknown", tostring(duration))
|
||||
)
|
||||
-- Check for Carnage duration overrides FIRST (highest priority)
|
||||
local carnageDuration = GetCarnageOverride(effect)
|
||||
if carnageDuration then
|
||||
duration = duration or carnageDuration
|
||||
caster = caster or "player" -- Ensure caster is set for UnitOwnDebuff filtering
|
||||
end
|
||||
|
||||
-- Check if this is a combo scaling spell by name
|
||||
if CleveRoids.IsComboScalingSpell and CleveRoids.IsComboScalingSpell(effect) then
|
||||
-- Use name-based tracking which is populated BEFORE pfUI's AddEffect
|
||||
if not duration and CleveRoids.IsComboScalingSpell and CleveRoids.IsComboScalingSpell(effect) then
|
||||
if CleveRoids.ComboPointTracking and CleveRoids.ComboPointTracking[effect] then
|
||||
local tracking = CleveRoids.ComboPointTracking[effect]
|
||||
-- Only use tracking if it's confirmed (actual cast, not just evaluation)
|
||||
if tracking.duration and tracking.confirmed and (GetTime() - tracking.cast_time) < 0.5 then
|
||||
duration = tracking.duration
|
||||
-- Don't clear confirmed flag - let time-based expiry handle it
|
||||
-- pfUI may call AddEffect multiple times for the same spell
|
||||
if CleveRoids.debug then
|
||||
DEFAULT_CHAT_FRAME:AddMessage(
|
||||
string.format("|cff00ff00[pfUI AddEffect Hook]|r Overriding %s duration to %ds (from confirmed tracking)",
|
||||
effect, duration)
|
||||
)
|
||||
end
|
||||
elseif CleveRoids.debug and tracking.duration and not tracking.confirmed and (GetTime() - tracking.cast_time) < 0.5 then
|
||||
DEFAULT_CHAT_FRAME:AddMessage(
|
||||
string.format("|cffaaaa00[pfUI AddEffect Hook]|r Ignoring %s tracking (not confirmed - evaluation only)",
|
||||
effect)
|
||||
)
|
||||
caster = caster or "player"
|
||||
end
|
||||
elseif CleveRoids.debug then
|
||||
DEFAULT_CHAT_FRAME:AddMessage(
|
||||
string.format("|cffff9900[pfUI AddEffect]|r No tracking found for '%s'",
|
||||
effect)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -194,7 +177,57 @@ function Extension.HookPfUILibdebuff()
|
||||
Extension.DLOG("Hooked pfUI.api.libdebuff.AddEffect for combo duration support")
|
||||
end
|
||||
|
||||
return Extension.pfLibDebuffHooked or Extension.pfLibAddEffectHooked
|
||||
-- Hook UnitDebuff to return Carnage override duration to display code
|
||||
if pflib.UnitDebuff and not Extension.pfLibUnitDebuffHooked then
|
||||
local originalUnitDebuff = pflib.UnitDebuff
|
||||
|
||||
pflib.UnitDebuff = function(self, unit, id)
|
||||
local effect, rank, texture, stacks, dtype, duration, timeleft, caster = originalUnitDebuff(self, unit, id)
|
||||
|
||||
local carnageDuration, carnageTimeleft = GetCarnageOverride(effect)
|
||||
if carnageDuration then
|
||||
duration = carnageDuration
|
||||
timeleft = carnageTimeleft
|
||||
end
|
||||
|
||||
return effect, rank, texture, stacks, dtype, duration, timeleft, caster
|
||||
end
|
||||
|
||||
Extension.pfLibUnitDebuffHooked = true
|
||||
Extension.DLOG("Hooked pfUI.api.libdebuff.UnitDebuff for Carnage duration display")
|
||||
end
|
||||
|
||||
-- Hook UnitOwnDebuff to return Carnage override duration when selfdebuff is enabled
|
||||
if pflib.UnitOwnDebuff and not Extension.pfLibUnitOwnDebuffHooked then
|
||||
local originalUnitOwnDebuff = pflib.UnitOwnDebuff
|
||||
|
||||
pflib.UnitOwnDebuff = function(self, unit, id)
|
||||
local effect, rank, texture, stacks, dtype, duration, timeleft, caster = originalUnitOwnDebuff(self, unit, id)
|
||||
|
||||
local carnageDuration, carnageTimeleft = GetCarnageOverride(effect)
|
||||
if carnageDuration then
|
||||
duration = carnageDuration
|
||||
timeleft = carnageTimeleft
|
||||
-- If UnitOwnDebuff returned nil but we have a Carnage override, synthesize from UnitDebuff
|
||||
elseif not effect and CleveRoids.carnageDurationOverrides then
|
||||
-- Use pflib:UnitDebuff which includes our Carnage override hook
|
||||
local baseEffect, baseRank, baseTex, baseStacks, baseDtype, baseDur, baseLeft, _ = pflib:UnitDebuff(unit, id)
|
||||
if baseEffect then
|
||||
carnageDuration, carnageTimeleft = GetCarnageOverride(baseEffect)
|
||||
if carnageDuration then
|
||||
return baseEffect, baseRank, baseTex, baseStacks, baseDtype, carnageDuration, carnageTimeleft, "player"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return effect, rank, texture, stacks, dtype, duration, timeleft, caster
|
||||
end
|
||||
|
||||
Extension.pfLibUnitOwnDebuffHooked = true
|
||||
Extension.DLOG("Hooked pfUI.api.libdebuff.UnitOwnDebuff for Carnage duration display (selfdebuff mode)")
|
||||
end
|
||||
|
||||
return Extension.pfLibDebuffHooked or Extension.pfLibAddEffectHooked or Extension.pfLibUnitDebuffHooked or Extension.pfLibUnitOwnDebuffHooked
|
||||
end
|
||||
|
||||
-- Synchronize combo durations to pfUI's libdebuff objects
|
||||
|
||||
@@ -2473,15 +2473,14 @@ function GetActionTexture(slot)
|
||||
end
|
||||
end
|
||||
|
||||
-- Prefer tooltip texture if it exists, otherwise use macro icon
|
||||
if actions.tooltip and actions.tooltip.texture then
|
||||
return actions.tooltip.texture
|
||||
elseif macroTexture then
|
||||
-- When no conditionals pass, use macro icon (not first action's icon)
|
||||
-- The actions.tooltip is just the first action which didn't pass conditionals
|
||||
if macroTexture then
|
||||
return macroTexture
|
||||
end
|
||||
|
||||
-- Should never reach here, but return macro texture or unknown as last resort
|
||||
return macroTexture or CleveRoids.unknownTexture
|
||||
-- Should never reach here, but return unknown as last resort
|
||||
return CleveRoids.unknownTexture
|
||||
end
|
||||
|
||||
-- Prioritize active action, fall back to tooltip
|
||||
@@ -3221,8 +3220,11 @@ SlashCmdList["CLEVEROID"] = function(msg)
|
||||
DEFAULT_CHAT_FRAME:AddMessage('/cleveroid comboclear - Clear combo tracking data')
|
||||
DEFAULT_CHAT_FRAME:AddMessage('/cleveroid combolearn - Show learned combo durations (per CP)')
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cffffaa00Talent Modifiers:|r")
|
||||
DEFAULT_CHAT_FRAME:AddMessage('/cleveroid talenttabs - Show talent tab IDs for your class')
|
||||
DEFAULT_CHAT_FRAME:AddMessage('/cleveroid listtab <tab> - List all talents in a tab with their IDs')
|
||||
DEFAULT_CHAT_FRAME:AddMessage('/cleveroid talents - Show current talent ranks')
|
||||
DEFAULT_CHAT_FRAME:AddMessage('/cleveroid testtalent <spellID> - Test talent modifier for a spell')
|
||||
DEFAULT_CHAT_FRAME:AddMessage('/cleveroid diagnosetalent <spellID> - Diagnose talent modifier issues')
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cffffaa00Equipment Modifiers:|r")
|
||||
DEFAULT_CHAT_FRAME:AddMessage('/cleveroid testequip <spellID> - Test equipment modifier for a spell')
|
||||
return
|
||||
@@ -3407,6 +3409,40 @@ SlashCmdList["CLEVEROID"] = function(msg)
|
||||
return
|
||||
end
|
||||
|
||||
-- talenttabs (show talent tab IDs)
|
||||
if cmd == "talenttabs" or cmd == "tabs" then
|
||||
CleveRoids.Print("=== Talent Tabs ===")
|
||||
for i = 1, GetNumTalentTabs() do
|
||||
local name, _, pointsSpent = GetTalentTabInfo(i)
|
||||
CleveRoids.Print("Tab " .. i .. ": " .. name .. " (" .. pointsSpent .. " points)")
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- listtab (show all talents in a specific tab with their IDs)
|
||||
if cmd == "listtab" or cmd == "tab" then
|
||||
local tabNum = tonumber(val)
|
||||
if not tabNum or tabNum < 1 or tabNum > GetNumTalentTabs() then
|
||||
CleveRoids.Print("Usage: /cleveroid listtab <tab number>")
|
||||
CleveRoids.Print("Example: /cleveroid listtab 2")
|
||||
CleveRoids.Print("Use /cleveroid talenttabs to see your tab numbers")
|
||||
return
|
||||
end
|
||||
|
||||
local tabName = GetTalentTabInfo(tabNum)
|
||||
CleveRoids.Print("=== " .. tabName .. " (Tab " .. tabNum .. ") ===")
|
||||
|
||||
local numTalents = GetNumTalents(tabNum)
|
||||
for i = 1, numTalents do
|
||||
local name, _, _, _, rank, maxRank = GetTalentInfo(tabNum, i)
|
||||
if name then
|
||||
local rankText = rank .. "/" .. maxRank
|
||||
CleveRoids.Print("ID " .. i .. ": " .. name .. " [" .. rankText .. "]")
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- talents (show current talent ranks)
|
||||
if cmd == "talents" or cmd == "talent" then
|
||||
CleveRoids.Print("=== Current Talents ===")
|
||||
@@ -3434,6 +3470,74 @@ SlashCmdList["CLEVEROID"] = function(msg)
|
||||
return
|
||||
end
|
||||
|
||||
-- diagnosetalent (comprehensive diagnostic for talent modifier)
|
||||
if cmd == "diagnosetalent" or cmd == "diagtalent" then
|
||||
local spellID = tonumber(val)
|
||||
if not spellID then
|
||||
CleveRoids.Print("Usage: /cleveroid diagnosetalent <spellID>")
|
||||
CleveRoids.Print("Example: /cleveroid diagnosetalent 1943 (Rupture Rank 1)")
|
||||
return
|
||||
end
|
||||
|
||||
-- Inline diagnostic
|
||||
local baseDuration = 10
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00=== Talent Modifier Diagnostic ===|r")
|
||||
|
||||
local spellName = SpellInfo(spellID)
|
||||
if not spellName then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cffff0000ERROR: Invalid spell ID " .. tostring(spellID) .. "|r")
|
||||
return
|
||||
end
|
||||
DEFAULT_CHAT_FRAME:AddMessage("Spell: " .. spellName .. " (ID: " .. spellID .. ")")
|
||||
|
||||
local modifier = CleveRoids.talentModifiers and CleveRoids.talentModifiers[spellID]
|
||||
if not modifier then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cffff0000No talent modifier registered for this spell|r")
|
||||
return
|
||||
end
|
||||
|
||||
local talentDesc = modifier.talent or ("Tab " .. tostring(modifier.tab) .. " ID " .. tostring(modifier.id))
|
||||
DEFAULT_CHAT_FRAME:AddMessage("Modifier registered: " .. talentDesc)
|
||||
|
||||
-- Test position-based lookup
|
||||
local talentRank = 0
|
||||
local lookupMethod = "none"
|
||||
|
||||
if modifier.tab and modifier.id then
|
||||
local _, name, _, _, rank = GetTalentInfo(modifier.tab, modifier.id)
|
||||
talentRank = tonumber(rank) or 0
|
||||
lookupMethod = "position"
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00Position lookup (Tab " .. modifier.tab .. ", ID " .. modifier.id .. "):|r")
|
||||
DEFAULT_CHAT_FRAME:AddMessage(" Talent name: " .. tostring(name))
|
||||
DEFAULT_CHAT_FRAME:AddMessage(" Rank: " .. talentRank)
|
||||
end
|
||||
|
||||
if modifier.talent and CleveRoids.GetTalentRank then
|
||||
local nameRank = CleveRoids.GetTalentRank(modifier.talent)
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cffaaaa00Name lookup (" .. modifier.talent .. "):|r")
|
||||
DEFAULT_CHAT_FRAME:AddMessage(" Rank: " .. nameRank)
|
||||
if talentRank == 0 and nameRank > 0 then
|
||||
talentRank = nameRank
|
||||
lookupMethod = "name"
|
||||
end
|
||||
end
|
||||
|
||||
DEFAULT_CHAT_FRAME:AddMessage("Final rank: " .. talentRank .. " (via " .. lookupMethod .. ")")
|
||||
|
||||
if talentRank > 0 then
|
||||
local modifiedDuration = modifier.modifier(baseDuration, talentRank)
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00Test calculation:|r")
|
||||
DEFAULT_CHAT_FRAME:AddMessage(" Base: " .. baseDuration .. "s")
|
||||
DEFAULT_CHAT_FRAME:AddMessage(" Modified: " .. modifiedDuration .. "s")
|
||||
DEFAULT_CHAT_FRAME:AddMessage(" Bonus: +" .. (modifiedDuration - baseDuration) .. "s")
|
||||
else
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cffff0000You don't have " .. talentDesc .. "!|r")
|
||||
end
|
||||
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00=== End Diagnostic ===|r")
|
||||
return
|
||||
end
|
||||
|
||||
-- testtalent (test talent modifier for a spell)
|
||||
if cmd == "testtalent" or cmd == "talenttest" then
|
||||
local spellID = tonumber(val)
|
||||
@@ -3451,12 +3555,30 @@ SlashCmdList["CLEVEROID"] = function(msg)
|
||||
return
|
||||
end
|
||||
|
||||
local talentRank = CleveRoids.GetTalentRank and CleveRoids.GetTalentRank(modifier.talent) or 0
|
||||
-- Get talent rank using position-based or name-based lookup
|
||||
local talentRank = 0
|
||||
local maxRank = 3
|
||||
local talentName = modifier.talent or ("Tab " .. tostring(modifier.tab) .. " ID " .. tostring(modifier.id))
|
||||
|
||||
-- Position-based lookup (preferred)
|
||||
if modifier.tab and modifier.id then
|
||||
local _, name, _, _, rank, max = GetTalentInfo(modifier.tab, modifier.id)
|
||||
talentRank = tonumber(rank) or 0
|
||||
maxRank = tonumber(max) or 3
|
||||
if name then
|
||||
talentName = name
|
||||
end
|
||||
end
|
||||
|
||||
-- Name-based fallback
|
||||
if talentRank == 0 and modifier.talent and CleveRoids.GetTalentRank then
|
||||
talentRank = CleveRoids.GetTalentRank(modifier.talent)
|
||||
end
|
||||
|
||||
CleveRoids.Print("=== Talent Modifier Test ===")
|
||||
CleveRoids.Print("Spell: " .. spellName .. " (ID:" .. spellID .. ")")
|
||||
CleveRoids.Print("Talent: " .. modifier.talent)
|
||||
CleveRoids.Print("Your Rank: " .. talentRank .. "/3")
|
||||
CleveRoids.Print("Talent: " .. talentName)
|
||||
CleveRoids.Print("Your Rank: " .. talentRank .. "/" .. maxRank)
|
||||
|
||||
if talentRank == 0 then
|
||||
CleveRoids.Print("|cffff0000You don't have this talent!|r")
|
||||
|
||||
+344
-47
@@ -1127,12 +1127,12 @@ ev:SetScript("OnEvent", function()
|
||||
local biteComboPoints = CleveRoids.lastComboPoints or 0
|
||||
|
||||
-- Check if player has Carnage talent at rank 2
|
||||
-- Carnage: Tab 2 (Feral Combat), Talent 17
|
||||
local carnageRank = 0
|
||||
if CleveRoids.GetTalentRank then
|
||||
carnageRank = CleveRoids.GetTalentRank("Carnage")
|
||||
end
|
||||
local _, _, _, _, rank = GetTalentInfo(2, 17)
|
||||
carnageRank = tonumber(rank) or 0
|
||||
|
||||
-- Carnage 2/2: Ferocious Bite with 5 CP refreshes Rip and Rake durations
|
||||
-- Carnage 2/2+: Ferocious Bite at 5 CP refreshes Rip and Rake back to their original duration
|
||||
if carnageRank >= 2 and biteComboPoints == 5 then
|
||||
local targetName = lib.guidToName[targetGUID]
|
||||
if not targetName then
|
||||
@@ -1146,20 +1146,91 @@ ev:SetScript("OnEvent", function()
|
||||
end
|
||||
|
||||
-- Only refresh debuffs if they're currently active on the target
|
||||
if lib.debuffs[targetGUID] then
|
||||
if lib.objects[targetGUID] then
|
||||
-- Try to refresh Rip
|
||||
if CleveRoids.lastRipCast and CleveRoids.lastRipCast.duration and
|
||||
CleveRoids.lastRipCast.targetGUID == targetGUID then
|
||||
-- Find which Rip rank is currently active
|
||||
for ripSpellID, _ in pairs(CleveRoids.RipSpellIDs) do
|
||||
if lib.debuffs[targetGUID][ripSpellID] then
|
||||
if lib.objects[targetGUID][ripSpellID] then
|
||||
-- Found an active Rip, refresh it with the saved duration
|
||||
local ripDuration = CleveRoids.lastRipCast.duration
|
||||
lib:AddEffect(targetGUID, targetName, ripSpellID, ripDuration, 0, "player")
|
||||
local ripComboPoints = CleveRoids.lastRipCast.comboPoints or 5
|
||||
|
||||
-- Get spell name for pfUI
|
||||
local ripSpellName = SpellInfo(ripSpellID)
|
||||
local baseName = ripSpellName and string.gsub(ripSpellName, "%s*%(Rank %d+%)", "") or "Rip"
|
||||
|
||||
-- Update tracking tables for pfUI hooks
|
||||
if CleveRoids.ComboPointTracking then
|
||||
CleveRoids.ComboPointTracking[baseName] = {
|
||||
combo_points = ripComboPoints,
|
||||
duration = ripDuration,
|
||||
cast_time = GetTime(),
|
||||
target = targetName,
|
||||
confirmed = true
|
||||
}
|
||||
end
|
||||
|
||||
-- Store duration override for pfUI hooks
|
||||
if not CleveRoids.carnageDurationOverrides then
|
||||
CleveRoids.carnageDurationOverrides = {}
|
||||
end
|
||||
CleveRoids.carnageDurationOverrides[ripSpellID] = {
|
||||
duration = ripDuration,
|
||||
timestamp = GetTime(),
|
||||
targetGUID = targetGUID
|
||||
}
|
||||
|
||||
-- Update pfUI's debuff timer directly
|
||||
if pfUI and pfUI.api and pfUI.api.libdebuff then
|
||||
local pflib = pfUI.api.libdebuff
|
||||
if pflib.objects and pflib.objects[targetName] then
|
||||
local updated = false
|
||||
local currentLevel = UnitLevel("target") or 0
|
||||
|
||||
-- Update at all levels where the debuff exists
|
||||
for level, effects in pairs(pflib.objects[targetName]) do
|
||||
if type(effects) == "table" and effects[baseName] then
|
||||
local entry = effects[baseName]
|
||||
entry.duration = ripDuration
|
||||
entry.start = GetTime()
|
||||
entry.caster = "player"
|
||||
if entry.tick then entry.tick = GetTime() end
|
||||
updated = true
|
||||
end
|
||||
end
|
||||
|
||||
-- Ensure entry exists at current UnitLevel
|
||||
if updated then
|
||||
if not pflib.objects[targetName][currentLevel] then
|
||||
pflib.objects[targetName][currentLevel] = {}
|
||||
end
|
||||
if not pflib.objects[targetName][currentLevel][baseName] then
|
||||
pflib.objects[targetName][currentLevel][baseName] = {
|
||||
effect = baseName,
|
||||
duration = ripDuration,
|
||||
start = GetTime(),
|
||||
caster = "player"
|
||||
}
|
||||
end
|
||||
if pflib.UpdateUnits then pflib:UpdateUnits() end
|
||||
elseif pflib.AddEffect then
|
||||
pflib:AddEffect(targetName, currentLevel, baseName, ripDuration, "player")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Update internal tracker
|
||||
if lib.objects[targetGUID] and lib.objects[targetGUID][ripSpellID] then
|
||||
lib.objects[targetGUID][ripSpellID].duration = ripDuration
|
||||
lib.objects[targetGUID][ripSpellID].start = GetTime()
|
||||
lib.objects[targetGUID][ripSpellID].expiry = GetTime() + ripDuration
|
||||
end
|
||||
|
||||
if CleveRoids.debug then
|
||||
DEFAULT_CHAT_FRAME:AddMessage(
|
||||
string.format("|cffff00ff[Carnage]|r Ferocious Bite (5 CP) refreshed Rip: %ds duration on %s",
|
||||
string.format("|cffff00ff[Carnage]|r Refreshed Rip: %ds on %s",
|
||||
ripDuration, targetName or "Unknown")
|
||||
)
|
||||
end
|
||||
@@ -1173,14 +1244,85 @@ ev:SetScript("OnEvent", function()
|
||||
CleveRoids.lastRakeCast.targetGUID == targetGUID then
|
||||
-- Find which Rake rank is currently active
|
||||
for rakeSpellID, _ in pairs(CleveRoids.RakeSpellIDs) do
|
||||
if lib.debuffs[targetGUID][rakeSpellID] then
|
||||
if lib.objects[targetGUID][rakeSpellID] then
|
||||
-- Found an active Rake, refresh it with the saved duration
|
||||
local rakeDuration = CleveRoids.lastRakeCast.duration
|
||||
lib:AddEffect(targetGUID, targetName, rakeSpellID, rakeDuration, 0, "player")
|
||||
local rakeComboPoints = CleveRoids.lastRakeCast.comboPoints or 5
|
||||
|
||||
-- Get spell name for pfUI
|
||||
local rakeSpellName = SpellInfo(rakeSpellID)
|
||||
local baseName = rakeSpellName and string.gsub(rakeSpellName, "%s*%(Rank %d+%)", "") or "Rake"
|
||||
|
||||
-- Update tracking tables for pfUI hooks
|
||||
if CleveRoids.ComboPointTracking then
|
||||
CleveRoids.ComboPointTracking[baseName] = {
|
||||
combo_points = rakeComboPoints,
|
||||
duration = rakeDuration,
|
||||
cast_time = GetTime(),
|
||||
target = targetName,
|
||||
confirmed = true
|
||||
}
|
||||
end
|
||||
|
||||
-- Store duration override for pfUI hooks
|
||||
if not CleveRoids.carnageDurationOverrides then
|
||||
CleveRoids.carnageDurationOverrides = {}
|
||||
end
|
||||
CleveRoids.carnageDurationOverrides[rakeSpellID] = {
|
||||
duration = rakeDuration,
|
||||
timestamp = GetTime(),
|
||||
targetGUID = targetGUID
|
||||
}
|
||||
|
||||
-- Update pfUI's debuff timer directly
|
||||
if pfUI and pfUI.api and pfUI.api.libdebuff then
|
||||
local pflib = pfUI.api.libdebuff
|
||||
if pflib.objects and pflib.objects[targetName] then
|
||||
local updated = false
|
||||
local currentLevel = UnitLevel("target") or 0
|
||||
|
||||
-- Update at all levels where the debuff exists
|
||||
for level, effects in pairs(pflib.objects[targetName]) do
|
||||
if type(effects) == "table" and effects[baseName] then
|
||||
local entry = effects[baseName]
|
||||
entry.duration = rakeDuration
|
||||
entry.start = GetTime()
|
||||
entry.caster = "player"
|
||||
if entry.tick then entry.tick = GetTime() end
|
||||
updated = true
|
||||
end
|
||||
end
|
||||
|
||||
-- Ensure entry exists at current UnitLevel
|
||||
if updated then
|
||||
if not pflib.objects[targetName][currentLevel] then
|
||||
pflib.objects[targetName][currentLevel] = {}
|
||||
end
|
||||
if not pflib.objects[targetName][currentLevel][baseName] then
|
||||
pflib.objects[targetName][currentLevel][baseName] = {
|
||||
effect = baseName,
|
||||
duration = rakeDuration,
|
||||
start = GetTime(),
|
||||
caster = "player"
|
||||
}
|
||||
end
|
||||
if pflib.UpdateUnits then pflib:UpdateUnits() end
|
||||
elseif pflib.AddEffect then
|
||||
pflib:AddEffect(targetName, currentLevel, baseName, rakeDuration, "player")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Update internal tracker
|
||||
if lib.objects[targetGUID] and lib.objects[targetGUID][rakeSpellID] then
|
||||
lib.objects[targetGUID][rakeSpellID].duration = rakeDuration
|
||||
lib.objects[targetGUID][rakeSpellID].start = GetTime()
|
||||
lib.objects[targetGUID][rakeSpellID].expiry = GetTime() + rakeDuration
|
||||
end
|
||||
|
||||
if CleveRoids.debug then
|
||||
DEFAULT_CHAT_FRAME:AddMessage(
|
||||
string.format("|cffff00ff[Carnage]|r Ferocious Bite (5 CP) refreshed Rake: %ds duration on %s",
|
||||
string.format("|cffff00ff[Carnage]|r Refreshed Rake: %ds on %s",
|
||||
rakeDuration, targetName or "Unknown")
|
||||
)
|
||||
end
|
||||
@@ -1283,11 +1425,12 @@ ev:SetScript("OnEvent", function()
|
||||
if CleveRoids.lastRipCast then
|
||||
CleveRoids.lastRipCast.duration = duration
|
||||
CleveRoids.lastRipCast.targetGUID = targetGUID
|
||||
CleveRoids.lastRipCast.comboPoints = comboPoints or 0
|
||||
CleveRoids.lastRipCast.timestamp = GetTime()
|
||||
if CleveRoids.debug then
|
||||
DEFAULT_CHAT_FRAME:AddMessage(
|
||||
string.format("|cff00ff00[Carnage]|r Saved Rip cast: %ds duration on target %s",
|
||||
duration, targetName or "Unknown")
|
||||
string.format("|cff00ff00[Carnage]|r Saved Rip cast: %ds duration (%d CP) on target %s",
|
||||
duration, comboPoints or 0, targetName or "Unknown")
|
||||
)
|
||||
end
|
||||
end
|
||||
@@ -1298,11 +1441,12 @@ ev:SetScript("OnEvent", function()
|
||||
if CleveRoids.lastRakeCast then
|
||||
CleveRoids.lastRakeCast.duration = duration
|
||||
CleveRoids.lastRakeCast.targetGUID = targetGUID
|
||||
CleveRoids.lastRakeCast.comboPoints = comboPoints or 0
|
||||
CleveRoids.lastRakeCast.timestamp = GetTime()
|
||||
if CleveRoids.debug then
|
||||
DEFAULT_CHAT_FRAME:AddMessage(
|
||||
string.format("|cff00ff00[Carnage]|r Saved Rake cast: %ds duration on target %s",
|
||||
duration, targetName or "Unknown")
|
||||
string.format("|cff00ff00[Carnage]|r Saved Rake cast: %ds duration (%d CP) on target %s",
|
||||
duration, comboPoints or 0, targetName or "Unknown")
|
||||
)
|
||||
end
|
||||
end
|
||||
@@ -1492,53 +1636,76 @@ end)
|
||||
-- ============================================================================
|
||||
|
||||
-- Database of talent modifiers for debuff durations
|
||||
-- Structure: [spellID] = { talent = "Talent Name", modifier = function(baseDuration, talentRank) }
|
||||
-- Structure: [spellID] = {
|
||||
-- talent = "Talent Name" (optional, for name-based lookup),
|
||||
-- tab = talentTab (preferred, for direct position lookup),
|
||||
-- id = talentID (preferred, for direct position lookup),
|
||||
-- modifier = function(baseDuration, talentRank)
|
||||
-- }
|
||||
CleveRoids.talentModifiers = CleveRoids.talentModifiers or {}
|
||||
|
||||
-- ROGUE talent modifiers
|
||||
-- Taste for Blood: Increases Rupture duration by 2 seconds per rank (3 ranks max)
|
||||
-- Talent Position: Tab 1, Talent 10 (Assassination tree)
|
||||
-- Talent Spell IDs: 14174 (Rank 1), 14175 (Rank 2), 14176 (Rank 3)
|
||||
CleveRoids.talentModifiers[1943] = { talent = "Taste for Blood", modifier = function(base, rank) return base + (rank * 2) end } -- Rupture Rank 1
|
||||
CleveRoids.talentModifiers[8639] = { talent = "Taste for Blood", modifier = function(base, rank) return base + (rank * 2) end } -- Rupture Rank 2
|
||||
CleveRoids.talentModifiers[8640] = { talent = "Taste for Blood", modifier = function(base, rank) return base + (rank * 2) end } -- Rupture Rank 3
|
||||
CleveRoids.talentModifiers[11273] = { talent = "Taste for Blood", modifier = function(base, rank) return base + (rank * 2) end } -- Rupture Rank 4
|
||||
CleveRoids.talentModifiers[11274] = { talent = "Taste for Blood", modifier = function(base, rank) return base + (rank * 2) end } -- Rupture Rank 5
|
||||
CleveRoids.talentModifiers[11275] = { talent = "Taste for Blood", modifier = function(base, rank) return base + (rank * 2) end } -- Rupture Rank 6
|
||||
CleveRoids.talentModifiers[1943] = { tab = 1, id = 10, talent = "Taste for Blood", modifier = function(base, rank) return base + (rank * 2) end } -- Rupture Rank 1
|
||||
CleveRoids.talentModifiers[8639] = { tab = 1, id = 10, talent = "Taste for Blood", modifier = function(base, rank) return base + (rank * 2) end } -- Rupture Rank 2
|
||||
CleveRoids.talentModifiers[8640] = { tab = 1, id = 10, talent = "Taste for Blood", modifier = function(base, rank) return base + (rank * 2) end } -- Rupture Rank 3
|
||||
CleveRoids.talentModifiers[11273] = { tab = 1, id = 10, talent = "Taste for Blood", modifier = function(base, rank) return base + (rank * 2) end } -- Rupture Rank 4
|
||||
CleveRoids.talentModifiers[11274] = { tab = 1, id = 10, talent = "Taste for Blood", modifier = function(base, rank) return base + (rank * 2) end } -- Rupture Rank 5
|
||||
CleveRoids.talentModifiers[11275] = { tab = 1, id = 10, talent = "Taste for Blood", modifier = function(base, rank) return base + (rank * 2) end } -- Rupture Rank 6
|
||||
|
||||
-- Improved Gouge: Increases Gouge duration by 0.5 seconds per rank (3 ranks max)
|
||||
-- Talent Position: Tab 3, Talent 3 (Subtlety tree)
|
||||
-- Talent Spell IDs: 13741 (Rank 1), 13793 (Rank 2), 13792 (Rank 3)
|
||||
CleveRoids.talentModifiers[1776] = { talent = "Improved Gouge", modifier = function(base, rank) return base + (rank * 0.5) end } -- Gouge Rank 1
|
||||
CleveRoids.talentModifiers[1777] = { talent = "Improved Gouge", modifier = function(base, rank) return base + (rank * 0.5) end } -- Gouge Rank 2
|
||||
CleveRoids.talentModifiers[8629] = { talent = "Improved Gouge", modifier = function(base, rank) return base + (rank * 0.5) end } -- Gouge Rank 3
|
||||
CleveRoids.talentModifiers[11285] = { talent = "Improved Gouge", modifier = function(base, rank) return base + (rank * 0.5) end } -- Gouge Rank 4
|
||||
CleveRoids.talentModifiers[11286] = { talent = "Improved Gouge", modifier = function(base, rank) return base + (rank * 0.5) end } -- Gouge Rank 5
|
||||
CleveRoids.talentModifiers[1776] = { tab = 3, id = 3, talent = "Improved Gouge", modifier = function(base, rank) return base + (rank * 0.5) end } -- Gouge Rank 1
|
||||
CleveRoids.talentModifiers[1777] = { tab = 3, id = 3, talent = "Improved Gouge", modifier = function(base, rank) return base + (rank * 0.5) end } -- Gouge Rank 2
|
||||
CleveRoids.talentModifiers[8629] = { tab = 3, id = 3, talent = "Improved Gouge", modifier = function(base, rank) return base + (rank * 0.5) end } -- Gouge Rank 3
|
||||
CleveRoids.talentModifiers[11285] = { tab = 3, id = 3, talent = "Improved Gouge", modifier = function(base, rank) return base + (rank * 0.5) end } -- Gouge Rank 4
|
||||
CleveRoids.talentModifiers[11286] = { tab = 3, id = 3, talent = "Improved Gouge", modifier = function(base, rank) return base + (rank * 0.5) end } -- Gouge Rank 5
|
||||
|
||||
-- PRIEST talent modifiers
|
||||
-- Improved Shadow Word: Pain: Increases SW:P duration by 3 seconds per rank (2 ranks max)
|
||||
-- Talent Position: Tab 3 (Shadow), Talent 4
|
||||
-- Talent Spell IDs: 15275 (Rank 1), 15317 (Rank 2)
|
||||
CleveRoids.talentModifiers[589] = { talent = "Improved Shadow Word: Pain", modifier = function(base, rank) return base + (rank * 3) end } -- SW:P Rank 1
|
||||
CleveRoids.talentModifiers[594] = { talent = "Improved Shadow Word: Pain", modifier = function(base, rank) return base + (rank * 3) end } -- SW:P Rank 2
|
||||
CleveRoids.talentModifiers[970] = { talent = "Improved Shadow Word: Pain", modifier = function(base, rank) return base + (rank * 3) end } -- SW:P Rank 3
|
||||
CleveRoids.talentModifiers[992] = { talent = "Improved Shadow Word: Pain", modifier = function(base, rank) return base + (rank * 3) end } -- SW:P Rank 4
|
||||
CleveRoids.talentModifiers[2767] = { talent = "Improved Shadow Word: Pain", modifier = function(base, rank) return base + (rank * 3) end } -- SW:P Rank 5
|
||||
CleveRoids.talentModifiers[10892] = { talent = "Improved Shadow Word: Pain", modifier = function(base, rank) return base + (rank * 3) end } -- SW:P Rank 6
|
||||
CleveRoids.talentModifiers[10893] = { talent = "Improved Shadow Word: Pain", modifier = function(base, rank) return base + (rank * 3) end } -- SW:P Rank 7
|
||||
CleveRoids.talentModifiers[10894] = { talent = "Improved Shadow Word: Pain", modifier = function(base, rank) return base + (rank * 3) end } -- SW:P Rank 8
|
||||
CleveRoids.talentModifiers[589] = { tab = 3, id = 4, talent = "Improved Shadow Word: Pain", modifier = function(base, rank) return base + (rank * 3) end } -- SW:P Rank 1
|
||||
CleveRoids.talentModifiers[594] = { tab = 3, id = 4, talent = "Improved Shadow Word: Pain", modifier = function(base, rank) return base + (rank * 3) end } -- SW:P Rank 2
|
||||
CleveRoids.talentModifiers[970] = { tab = 3, id = 4, talent = "Improved Shadow Word: Pain", modifier = function(base, rank) return base + (rank * 3) end } -- SW:P Rank 3
|
||||
CleveRoids.talentModifiers[992] = { tab = 3, id = 4, talent = "Improved Shadow Word: Pain", modifier = function(base, rank) return base + (rank * 3) end } -- SW:P Rank 4
|
||||
CleveRoids.talentModifiers[2767] = { tab = 3, id = 4, talent = "Improved Shadow Word: Pain", modifier = function(base, rank) return base + (rank * 3) end } -- SW:P Rank 5
|
||||
CleveRoids.talentModifiers[10892] = { tab = 3, id = 4, talent = "Improved Shadow Word: Pain", modifier = function(base, rank) return base + (rank * 3) end } -- SW:P Rank 6
|
||||
CleveRoids.talentModifiers[10893] = { tab = 3, id = 4, talent = "Improved Shadow Word: Pain", modifier = function(base, rank) return base + (rank * 3) end } -- SW:P Rank 7
|
||||
CleveRoids.talentModifiers[10894] = { tab = 3, id = 4, talent = "Improved Shadow Word: Pain", modifier = function(base, rank) return base + (rank * 3) end } -- SW:P Rank 8
|
||||
|
||||
-- DRUID talent modifiers
|
||||
-- Brutal Impact: Increases Bash and Pounce stun duration by 0.5 seconds per rank (2 ranks max)
|
||||
-- Talent Position: Tab 2 (Feral Combat), Talent 4
|
||||
-- Talent Spell IDs: 16940 (Rank 1), 16941 (Rank 2)
|
||||
CleveRoids.talentModifiers[5211] = { talent = "Brutal Impact", modifier = function(base, rank) return base + (rank * 0.5) end } -- Bash Rank 1
|
||||
CleveRoids.talentModifiers[6798] = { talent = "Brutal Impact", modifier = function(base, rank) return base + (rank * 0.5) end } -- Bash Rank 2
|
||||
CleveRoids.talentModifiers[8983] = { talent = "Brutal Impact", modifier = function(base, rank) return base + (rank * 0.5) end } -- Bash Rank 3
|
||||
CleveRoids.talentModifiers[5211] = { tab = 2, id = 4, talent = "Brutal Impact", modifier = function(base, rank) return base + (rank * 0.5) end } -- Bash Rank 1
|
||||
CleveRoids.talentModifiers[6798] = { tab = 2, id = 4, talent = "Brutal Impact", modifier = function(base, rank) return base + (rank * 0.5) end } -- Bash Rank 2
|
||||
CleveRoids.talentModifiers[8983] = { tab = 2, id = 4, talent = "Brutal Impact", modifier = function(base, rank) return base + (rank * 0.5) end } -- Bash Rank 3
|
||||
|
||||
CleveRoids.talentModifiers[9005] = { talent = "Brutal Impact", modifier = function(base, rank) return base + (rank * 0.5) end } -- Pounce Rank 1
|
||||
CleveRoids.talentModifiers[9823] = { talent = "Brutal Impact", modifier = function(base, rank) return base + (rank * 0.5) end } -- Pounce Rank 2
|
||||
CleveRoids.talentModifiers[9827] = { talent = "Brutal Impact", modifier = function(base, rank) return base + (rank * 0.5) end } -- Pounce Rank 3
|
||||
CleveRoids.talentModifiers[9005] = { tab = 2, id = 4, talent = "Brutal Impact", modifier = function(base, rank) return base + (rank * 0.5) end } -- Pounce Rank 1
|
||||
CleveRoids.talentModifiers[9823] = { tab = 2, id = 4, talent = "Brutal Impact", modifier = function(base, rank) return base + (rank * 0.5) end } -- Pounce Rank 2
|
||||
CleveRoids.talentModifiers[9827] = { tab = 2, id = 4, talent = "Brutal Impact", modifier = function(base, rank) return base + (rank * 0.5) end } -- Pounce Rank 3
|
||||
|
||||
-- Function to get talent rank for a talent by name
|
||||
-- Returns 0 if talent not found or not learned
|
||||
function CleveRoids.GetTalentRank(talentName)
|
||||
-- NOTE: Carnage talent (Tab 2, ID 17) is NOT a duration modifier!
|
||||
-- Carnage is a refresh mechanic: Ferocious Bite at 5 CP refreshes Rip/Rake to their original duration
|
||||
-- This is handled separately in the Carnage refresh logic (lines 1125-1192)
|
||||
|
||||
-- Function to get talent rank
|
||||
-- Supports both position-based (tab, id) and name-based lookup
|
||||
-- Position-based is preferred as it's more reliable and locale-independent (like Cursive addon)
|
||||
-- Parameters: talentName OR (tab, id)
|
||||
-- Returns: Talent rank (0 if not found or not learned)
|
||||
function CleveRoids.GetTalentRank(talentName, tab, id)
|
||||
-- Method 1: Direct position lookup (preferred, like Cursive)
|
||||
if tab and id then
|
||||
local _, _, _, _, rank = GetTalentInfo(tab, id)
|
||||
return tonumber(rank) or 0
|
||||
end
|
||||
|
||||
-- Method 2: Name-based lookup (fallback for backwards compatibility)
|
||||
if not talentName then return 0 end
|
||||
|
||||
-- Ensure talents are indexed
|
||||
@@ -1567,7 +1734,26 @@ function CleveRoids.ApplyTalentModifier(spellID, baseDuration)
|
||||
return baseDuration
|
||||
end
|
||||
|
||||
local talentRank = CleveRoids.GetTalentRank(modifier.talent)
|
||||
local talentRank = 0
|
||||
local lookupMethod = "none"
|
||||
|
||||
-- Method 1: Position-based lookup (preferred, locale-independent)
|
||||
if modifier.tab and modifier.id then
|
||||
local _, _, _, _, rank = GetTalentInfo(modifier.tab, modifier.id)
|
||||
talentRank = tonumber(rank) or 0
|
||||
if talentRank > 0 then
|
||||
lookupMethod = "position"
|
||||
end
|
||||
end
|
||||
|
||||
-- Method 2: Name-based lookup (fallback for backwards compatibility)
|
||||
if talentRank == 0 and modifier.talent then
|
||||
talentRank = CleveRoids.GetTalentRank(modifier.talent)
|
||||
if talentRank > 0 then
|
||||
lookupMethod = "name"
|
||||
end
|
||||
end
|
||||
|
||||
if talentRank == 0 then
|
||||
return baseDuration
|
||||
end
|
||||
@@ -1575,10 +1761,11 @@ function CleveRoids.ApplyTalentModifier(spellID, baseDuration)
|
||||
local modifiedDuration = modifier.modifier(baseDuration, talentRank)
|
||||
|
||||
if CleveRoids.debug then
|
||||
local talentName = modifier.talent or ("Tab " .. modifier.tab .. " ID " .. modifier.id)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(
|
||||
string.format("|cffff00ff[Talent Modifier]|r %s (ID:%d): %ds -> %ds (talent: %s rank %d)",
|
||||
string.format("|cffff00ff[Talent Modifier]|r %s (ID:%d): %ds -> %ds (talent: %s rank %d, %s)",
|
||||
SpellInfo(spellID) or "Unknown", spellID, baseDuration, modifiedDuration,
|
||||
modifier.talent, talentRank)
|
||||
talentName, talentRank, lookupMethod)
|
||||
)
|
||||
end
|
||||
|
||||
@@ -1600,6 +1787,116 @@ function CleveRoids.RegisterTalentModifier(spellID, talentName, modifierFunc)
|
||||
return true
|
||||
end
|
||||
|
||||
-- Diagnostic function to check talent modifier system
|
||||
-- Usage: CleveRoids.DiagnoseTalentModifier(spellID, baseDuration)
|
||||
function CleveRoids.DiagnoseTalentModifier(spellID, baseDuration)
|
||||
baseDuration = baseDuration or 10 -- Default test duration
|
||||
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00=== Talent Modifier Diagnostic ===|r")
|
||||
|
||||
-- Check if spellID is valid
|
||||
local spellName = SpellInfo(spellID)
|
||||
if not spellName then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cffff0000ERROR: Invalid spell ID " .. tostring(spellID) .. "|r")
|
||||
return
|
||||
end
|
||||
DEFAULT_CHAT_FRAME:AddMessage("Spell: " .. spellName .. " (ID: " .. spellID .. ")")
|
||||
|
||||
-- Check if talents are indexed
|
||||
if not CleveRoids.Talents then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cffff0000ERROR: Talents table doesn't exist!|r")
|
||||
DEFAULT_CHAT_FRAME:AddMessage("Attempting to index talents...")
|
||||
if CleveRoids.IndexTalents then
|
||||
CleveRoids.IndexTalents()
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00Talents indexed.|r")
|
||||
else
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cffff0000ERROR: IndexTalents function not found!|r")
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local talentCount = 0
|
||||
for k, v in pairs(CleveRoids.Talents) do
|
||||
if type(k) == "string" and type(v) == "number" and v > 0 then
|
||||
talentCount = talentCount + 1
|
||||
end
|
||||
end
|
||||
DEFAULT_CHAT_FRAME:AddMessage("Talents indexed: " .. talentCount .. " talents found")
|
||||
|
||||
-- Check if modifier is registered
|
||||
local modifier = CleveRoids.talentModifiers[spellID]
|
||||
if not modifier then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cffff0000No talent modifier registered for this spell|r")
|
||||
return
|
||||
end
|
||||
|
||||
local talentDesc = modifier.talent or ("Tab " .. tostring(modifier.tab) .. " ID " .. tostring(modifier.id))
|
||||
DEFAULT_CHAT_FRAME:AddMessage("Modifier registered: " .. talentDesc)
|
||||
|
||||
-- Check talent rank using BOTH methods
|
||||
local talentRank = 0
|
||||
local lookupMethod = "none"
|
||||
|
||||
if modifier.tab and modifier.id then
|
||||
-- Position-based lookup (preferred)
|
||||
local _, name, _, _, rank = GetTalentInfo(modifier.tab, modifier.id)
|
||||
talentRank = tonumber(rank) or 0
|
||||
lookupMethod = "position"
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00Position lookup (Tab " .. modifier.tab .. ", ID " .. modifier.id .. "):|r")
|
||||
DEFAULT_CHAT_FRAME:AddMessage(" Talent name: " .. tostring(name))
|
||||
DEFAULT_CHAT_FRAME:AddMessage(" Rank: " .. talentRank)
|
||||
end
|
||||
|
||||
if modifier.talent then
|
||||
-- Name-based lookup (fallback)
|
||||
local nameRank = CleveRoids.GetTalentRank(modifier.talent)
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cffaaaa00Name lookup (" .. modifier.talent .. "):|r")
|
||||
DEFAULT_CHAT_FRAME:AddMessage(" Rank: " .. nameRank)
|
||||
|
||||
-- Use name rank if position didn't work
|
||||
if talentRank == 0 and nameRank > 0 then
|
||||
talentRank = nameRank
|
||||
lookupMethod = "name"
|
||||
end
|
||||
|
||||
-- Check if talent exists in table
|
||||
local directLookup = CleveRoids.Talents[modifier.talent]
|
||||
DEFAULT_CHAT_FRAME:AddMessage(" Direct table lookup: " .. tostring(directLookup))
|
||||
end
|
||||
|
||||
DEFAULT_CHAT_FRAME:AddMessage("Final rank: " .. talentRank .. " (via " .. lookupMethod .. ")")
|
||||
|
||||
if talentRank == 0 then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cffff0000You don't have " .. talentDesc .. "!|r")
|
||||
-- Show available talents for debugging
|
||||
DEFAULT_CHAT_FRAME:AddMessage("Available talents with ranks:")
|
||||
local shown = 0
|
||||
for name, rank in pairs(CleveRoids.Talents) do
|
||||
if type(name) == "string" and type(rank) == "number" and rank > 0 then
|
||||
DEFAULT_CHAT_FRAME:AddMessage(" - " .. name .. ": " .. rank)
|
||||
shown = shown + 1
|
||||
if shown >= 10 then
|
||||
DEFAULT_CHAT_FRAME:AddMessage(" ... (showing first 10)")
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
-- Test the modifier
|
||||
local modifiedDuration = modifier.modifier(baseDuration, talentRank)
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00Test calculation:|r")
|
||||
DEFAULT_CHAT_FRAME:AddMessage(" Base: " .. baseDuration .. "s")
|
||||
DEFAULT_CHAT_FRAME:AddMessage(" Modified: " .. modifiedDuration .. "s")
|
||||
DEFAULT_CHAT_FRAME:AddMessage(" Bonus: +" .. (modifiedDuration - baseDuration) .. "s")
|
||||
|
||||
-- Test actual application
|
||||
local applied = CleveRoids.ApplyTalentModifier(spellID, baseDuration)
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00Via ApplyTalentModifier:|r " .. applied .. "s")
|
||||
end
|
||||
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00=== End Diagnostic ===|r")
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
-- EQUIPMENT MODIFIER SYSTEM
|
||||
-- ============================================================================
|
||||
|
||||
Reference in New Issue
Block a user