From 274475a3123b0432cc864a0ba49c75c90bda8feb Mon Sep 17 00:00:00 2001 From: Jrc13245 Date: Tue, 18 Nov 2025 19:39:07 -0500 Subject: [PATCH] add carnage talent refreshing rip and rake if using ferocious bite at 5 combo points when debuffs are up --- ComboPointTracker.lua | 44 +++++++++++++++++ Core.lua | 20 ++++---- Utility.lua | 109 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 163 insertions(+), 10 deletions(-) diff --git a/ComboPointTracker.lua b/ComboPointTracker.lua index 98aee8d..53b44af 100644 --- a/ComboPointTracker.lua +++ b/ComboPointTracker.lua @@ -15,6 +15,21 @@ CleveRoids.ComboPointTracking = CleveRoids.ComboPointTracking or {} -- Structure: CleveRoids_ComboDurations[spellID][comboPoints] = duration 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) +CleveRoids.lastRipCast = CleveRoids.lastRipCast or { + duration = nil, + targetGUID = nil, + timestamp = 0 +} + +CleveRoids.lastRakeCast = CleveRoids.lastRakeCast or { + duration = nil, + targetGUID = nil, + timestamp = 0 +} + -- Define spells that scale with combo points by SPELL ID and their duration formulas -- Duration = base + (combo_points - 1) * increment CleveRoids.ComboScalingSpellsByID = { @@ -40,6 +55,35 @@ CleveRoids.ComboScalingSpellsByID = { [9896] = { base = 10, increment = 2, name = "Rip" }, -- Rank 6 } +-- 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) +CleveRoids.FerociousBiteSpellIDs = { + [22557] = true, -- Rank 1 + [22568] = true, -- Rank 2 + [22827] = true, -- Rank 3 + [22828] = true, -- Rank 4 + [22829] = true, -- Rank 5 +} + +-- Rip spell IDs (for Carnage talent - refreshed by Ferocious Bite at 5 CP) +CleveRoids.RipSpellIDs = { + [1079] = true, -- Rank 1 + [9492] = true, -- Rank 2 + [9493] = true, -- Rank 3 + [9752] = true, -- Rank 4 + [9894] = true, -- Rank 5 + [9896] = true, -- Rank 6 +} + +-- Rake spell IDs (for Carnage talent - refreshed by Ferocious Bite at 5 CP) +CleveRoids.RakeSpellIDs = { + [1822] = true, -- Rank 1 + [1823] = true, -- Rank 2 + [1824] = true, -- Rank 3 + [9904] = true, -- Rank 4 +} + -- Legacy name-based table for backwards compatibility CleveRoids.ComboScalingSpells = { ["Rupture"] = { base_duration = 8, increment = 2, all_ranks = true }, diff --git a/Core.lua b/Core.lua index 309b2bf..6693a7f 100644 --- a/Core.lua +++ b/Core.lua @@ -471,17 +471,21 @@ function CleveRoids.TestForActiveAction(actions) -- First pass: find first action with conditionals that passes for _, action in ipairs(actions.list) do local result = CleveRoids.TestAction(action.cmd, action.args) - + -- Check if action has conditionals local _, conditionals = CleveRoids.GetParsedMsg(action.args) - - if not conditionals and not firstUnconditional then - -- Track first unconditional action as fallback + + -- Skip this action for icon display if it has the '?' prefix + -- Note: CleveRoids._ignoretooltip is a side-effect flag set by GetParsedMsg + local shouldSkipForIcon = CleveRoids._ignoretooltip == 1 + + if not conditionals and not firstUnconditional and not shouldSkipForIcon then + -- Track first unconditional action as fallback (unless it has '?' prefix) firstUnconditional = action end - - -- break on first action that passes tests - if result then + + -- break on first action that passes tests (unless it should be skipped for icon) + if result and not shouldSkipForIcon then hasActive = true if action.sequence then newSequence = action.sequence @@ -493,7 +497,7 @@ function CleveRoids.TestForActiveAction(actions) if hasActive then break end end end - + -- If no conditional action passed, use first unconditional action if not hasActive and firstUnconditional then hasActive = true diff --git a/Utility.lua b/Utility.lua index 39142d2..66e4e1e 100644 --- a/Utility.lua +++ b/Utility.lua @@ -1096,8 +1096,11 @@ ev:SetScript("OnEvent", function() if (eventType == "START" or eventType == "CHANNEL") and spellID then local _, playerGUID = UnitExists("player") if casterGUID == playerGUID and targetGUID then - -- If this is a combo scaling spell, capture combo points NOW (before consumption) - if CleveRoids.IsComboScalingSpellID and CleveRoids.IsComboScalingSpellID(spellID) then + -- If this is a combo scaling spell OR Ferocious Bite, capture combo points NOW (before consumption) + local isComboSpell = CleveRoids.IsComboScalingSpellID and CleveRoids.IsComboScalingSpellID(spellID) + local isFerociousBite = CleveRoids.FerociousBiteSpellIDs and CleveRoids.FerociousBiteSpellIDs[spellID] + + if isComboSpell or isFerociousBite then local currentCP = CleveRoids.GetComboPoints() if currentCP and currentCP > 0 then CleveRoids.lastComboPoints = currentCP @@ -1117,6 +1120,78 @@ ev:SetScript("OnEvent", function() local _, playerGUID = UnitExists("player") if casterGUID == playerGUID and targetGUID then + -- DRUID CARNAGE TALENT: Check if this is Ferocious Bite with 5 CP + -- If so, refresh the last Rip and Rake durations (only if debuffs are active) + if CleveRoids.FerociousBiteSpellIDs and CleveRoids.FerociousBiteSpellIDs[spellID] then + -- Get combo points used (capture before consumption) + local biteComboPoints = CleveRoids.lastComboPoints or 0 + + -- Check if player has Carnage talent at rank 2 + local carnageRank = 0 + if CleveRoids.GetTalentRank then + carnageRank = CleveRoids.GetTalentRank("Carnage") + end + + -- Carnage 2/2: Ferocious Bite with 5 CP refreshes Rip and Rake durations + if carnageRank >= 2 and biteComboPoints == 5 then + local targetName = lib.guidToName[targetGUID] + if not targetName then + local _, currentTargetGUID = UnitExists("target") + if currentTargetGUID == targetGUID then + targetName = UnitName("target") + lib.guidToName[targetGUID] = targetName + else + targetName = "Unknown" + end + end + + -- Only refresh debuffs if they're currently active on the target + if lib.debuffs[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 + -- Found an active Rip, refresh it with the saved duration + local ripDuration = CleveRoids.lastRipCast.duration + lib:AddEffect(targetGUID, targetName, ripSpellID, ripDuration, 0, "player") + + if CleveRoids.debug then + DEFAULT_CHAT_FRAME:AddMessage( + string.format("|cffff00ff[Carnage]|r Ferocious Bite (5 CP) refreshed Rip: %ds duration on %s", + ripDuration, targetName or "Unknown") + ) + end + break + end + end + end + + -- Try to refresh Rake + if CleveRoids.lastRakeCast and CleveRoids.lastRakeCast.duration and + 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 + -- Found an active Rake, refresh it with the saved duration + local rakeDuration = CleveRoids.lastRakeCast.duration + lib:AddEffect(targetGUID, targetName, rakeSpellID, rakeDuration, 0, "player") + + if CleveRoids.debug then + DEFAULT_CHAT_FRAME:AddMessage( + string.format("|cffff00ff[Carnage]|r Ferocious Bite (5 CP) refreshed Rake: %ds duration on %s", + rakeDuration, targetName or "Unknown") + ) + end + break + end + end + end + end + end + end + -- Check if this is a combo point scaling spell first local duration = nil local comboPoints = nil @@ -1203,6 +1278,36 @@ ev:SetScript("OnEvent", function() lib:AddEffect(targetGUID, targetName, spellID, duration, 0, "player") + -- DRUID CARNAGE TALENT: Save Rip cast duration for later refresh by Ferocious Bite + if CleveRoids.RipSpellIDs and CleveRoids.RipSpellIDs[spellID] then + if CleveRoids.lastRipCast then + CleveRoids.lastRipCast.duration = duration + CleveRoids.lastRipCast.targetGUID = targetGUID + 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") + ) + end + end + end + + -- DRUID CARNAGE TALENT: Save Rake cast duration for later refresh by Ferocious Bite + if CleveRoids.RakeSpellIDs and CleveRoids.RakeSpellIDs[spellID] then + if CleveRoids.lastRakeCast then + CleveRoids.lastRakeCast.duration = duration + CleveRoids.lastRakeCast.targetGUID = targetGUID + 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") + ) + end + end + end + -- Sync combo duration to pfUI if it's loaded if comboPoints and CleveRoids.Compatibility_pfUI and CleveRoids.Compatibility_pfUI.SyncComboDurationToPfUI then