update debuff duration systems

This commit is contained in:
Jrc13245
2025-12-28 08:32:06 -05:00
parent de427be595
commit 723cbb0642
4 changed files with 461 additions and 75 deletions
+152 -4
View File
@@ -16,8 +16,10 @@ CleveRoids.ComboPointTracking = CleveRoids.ComboPointTracking or {}
CleveRoids_ComboDurations = CleveRoids_ComboDurations or {}
-- Storage for last Rip cast (for Carnage talent mechanic)
-- Carnage talent: Ferocious Bite at 5 CP refreshes Rip and Rake back to their original duration
-- Carnage talent: When Ferocious Bite procs Carnage, it refreshes Rip and Rake to their original duration
-- Detection: When combo points don't drop to 0 after FB (they stay at 1 = Carnage proc)
-- Talent Position: Tab 2 (Feral Combat), Talent 17
-- Rank 1: 10% per CP, Rank 2: 20% per CP
CleveRoids.lastRipCast = CleveRoids.lastRipCast or {
duration = nil,
targetGUID = nil,
@@ -56,7 +58,8 @@ CleveRoids.ComboScalingSpellsByID = {
}
-- Ferocious Bite spell IDs (for Carnage talent mechanic)
-- Carnage talent: Ferocious Bite at 5 CP refreshes Rip and Rake back to their original duration
-- Carnage talent: When FB procs Carnage, refreshes Rip and Rake back to their original duration
-- Proc detection: combo points stay at 1 after FB instead of dropping to 0
-- Talent Position: Tab 2 (Feral Combat), Talent 17
CleveRoids.FerociousBiteSpellIDs = {
[22557] = true, -- Rank 1
@@ -67,7 +70,7 @@ CleveRoids.FerociousBiteSpellIDs = {
[31018] = true, -- Rank 6
}
-- Rip spell IDs (for Carnage talent - refreshed by Ferocious Bite at 5 CP)
-- Rip spell IDs (for Carnage talent - refreshed when Carnage procs)
CleveRoids.RipSpellIDs = {
[1079] = true, -- Rank 1
[9492] = true, -- Rank 2
@@ -77,7 +80,7 @@ CleveRoids.RipSpellIDs = {
[9896] = true, -- Rank 6
}
-- Rake spell IDs (for Carnage talent - refreshed by Ferocious Bite at 5 CP)
-- Rake spell IDs (for Carnage talent - refreshed when Carnage procs)
CleveRoids.RakeSpellIDs = {
[1822] = true, -- Rank 1
[1823] = true, -- Rank 2
@@ -85,6 +88,102 @@ CleveRoids.RakeSpellIDs = {
[9904] = true, -- Rank 4
}
-- =============================================================================
-- SHAMAN: Molten Blast → Flame Shock Refresh (TWoW Custom)
-- When Molten Blast hits, it refreshes Flame Shock duration on the target
-- Detection: Monitor combat log for Molten Blast damage, then refresh Flame Shock
-- =============================================================================
CleveRoids.MoltenBlastSpellIDs = {
[36916] = true, -- Rank 1
[36917] = true, -- Rank 2
[36918] = true, -- Rank 3
[36919] = true, -- Rank 4
[36920] = true, -- Rank 5
[36921] = true, -- Rank 6
}
CleveRoids.FlameShockSpellIDs = {
[8050] = true, -- Rank 1
[8052] = true, -- Rank 2
[8053] = true, -- Rank 3
[10447] = true, -- Rank 4
[10448] = true, -- Rank 5
[29228] = true, -- Rank 6
}
-- =============================================================================
-- WARLOCK: Conflagrate → Immolate Duration Reduction
-- When Conflagrate is cast, it reduces Immolate duration by 3 seconds
-- =============================================================================
CleveRoids.ConflagrateSpellIDs = {
[17962] = true, -- Rank 1
[18930] = true, -- Rank 2
[18931] = true, -- Rank 3
[18932] = true, -- Rank 4
}
CleveRoids.ImmolateSpellIDs = {
[348] = true, -- Rank 1
[707] = true, -- Rank 2
[1094] = true, -- Rank 3
[2941] = true, -- Rank 4
[11665] = true, -- Rank 5
[11667] = true, -- Rank 6
[11668] = true, -- Rank 7
[25309] = true, -- Rank 8
}
-- =============================================================================
-- WARLOCK: Dark Harvest Duration Acceleration (TWoW Custom)
-- Channeled spell that accelerates DoT tick rate by 30% while channeling
-- Complex tracking: debuff expires 30% faster while Dark Harvest is active
-- =============================================================================
CleveRoids.DarkHarvestSpellIDs = {
[52550] = true, -- Rank 1
[52551] = true, -- Rank 2
[52552] = true, -- Rank 3
}
-- =============================================================================
-- DRUID: Rake Debuff Cap Boss Whitelist
-- These bosses are likely to hit the 48 debuff cap, causing Rake to get pushed off
-- For mobs NOT in this list, we verify Rake is actually on the target before tracking
-- Prevents false tracking when debuffs get pushed off at cap
-- =============================================================================
CleveRoids.MobsThatBleed = {
-- Karazhan Crypts / TWoW Custom
["0xF13000F1F3276A33"] = true, -- Keeper Gnarlmoon
["0xF13000F1FA276A32"] = true, -- Ley-Watcher Incantagos
["0xF13000EA3F276C05"] = true, -- King
["0xF13000EA31279058"] = true, -- Queen
["0xF13000EA43276C06"] = true, -- Bishop
["0xF13000EA44279044"] = true, -- Pawn
["0xF13000EA42276C07"] = true, -- Rook
["0xF13000EA4D05DA44"] = true, -- Sanv Tas'dal
["0xF13000EA57276C04"] = true, -- Kruul
["0xF130016C95276DAF"] = true, -- Mephistroth
-- Naxxramas
["0xF130003E5401591A"] = true, -- Anub'Rekhan
["0xF130003E510159B0"] = true, -- Grand Widow Faerlina
["0xF130003E500159A3"] = true, -- Maexxna
["0xF130003EBD01598C"] = true, -- Razuvious
["0xF130003EBC01599F"] = true, -- Gothik
["0xF130003EBF015AB2"] = true, -- Zeliek
["0xF130003EBE015AB3"] = true, -- Mograine
["0xF130003EC1015AB1"] = true, -- Blaumeux
["0xF130003EC0015AB0"] = true, -- Thane
["0xF130003E52015824"] = true, -- Noth
["0xF130003E4001588D"] = true, -- Heigan
["0xF130003E8B0158A2"] = true, -- Loatheb
["0xF130003E9C0158EA"] = true, -- Patchwerk
["0xF130003E3B0158EF"] = true, -- Grobbulus
["0xF130003E3C0158F0"] = true, -- Gluth
["0xF130003E380159A0"] = true, -- Thaddius
["0xF130003E75015AB4"] = true, -- Sapphiron
["0xF130003E76015AED"] = true, -- Kel'Thuzad
}
-- Legacy name-based table for backwards compatibility
CleveRoids.ComboScalingSpells = {
["Rupture"] = { base_duration = 8, increment = 2, all_ranks = true },
@@ -652,6 +751,55 @@ end
function Extension.OnComboPointsChanged()
CleveRoids.UpdateComboPoints()
-- CARNAGE PROC DETECTION (Cursive-style)
-- When Ferocious Bite is used, combo points should drop to 0
-- If Carnage procs, combo points will be 1 instead (the Carnage-granted combo point)
-- Check: After Ferocious Bite (within 0.5s), if combo points > 0, Carnage procced
if CleveRoids.lastFerociousBiteTime and CleveRoids.lastFerociousBiteTargetGUID then
local timeSinceBite = GetTime() - CleveRoids.lastFerociousBiteTime
if timeSinceBite < 0.5 then
local currentCP = CleveRoids.GetComboPoints()
if currentCP > 0 then
-- Carnage procced! Combo points didn't drop to 0 (or rose back to 1)
if CleveRoids.debug then
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cffff00ff[Carnage]|r PROC DETECTED! CP=%d after Ferocious Bite (%.2fs ago)",
currentCP, timeSinceBite)
)
end
-- Apply the Carnage refresh to Rip and Rake
local targetGUID = CleveRoids.lastFerociousBiteTargetGUID
local targetName = CleveRoids.lastFerociousBiteTargetName or "Unknown"
local biteSpellID = CleveRoids.lastFerociousBiteSpellID
-- Call the Carnage refresh function in Utility.lua
if CleveRoids.libdebuff and CleveRoids.libdebuff.ApplyCarnageRefresh then
CleveRoids.libdebuff.ApplyCarnageRefresh(targetGUID, targetName, biteSpellID)
end
-- Clear the tracking to prevent multiple refreshes
CleveRoids.lastFerociousBiteTime = nil
CleveRoids.lastFerociousBiteTargetGUID = nil
CleveRoids.lastFerociousBiteTargetName = nil
CleveRoids.lastFerociousBiteSpellID = nil
end
else
-- Time window expired, clear tracking
if CleveRoids.lastFerociousBiteTime then
if CleveRoids.debug then
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cffff00ff[Carnage]|r No proc - time window expired (%.2fs)", timeSinceBite)
)
end
CleveRoids.lastFerociousBiteTime = nil
CleveRoids.lastFerociousBiteTargetGUID = nil
CleveRoids.lastFerociousBiteTargetName = nil
CleveRoids.lastFerociousBiteSpellID = nil
end
end
end
end
-- Event handlers
+20
View File
@@ -4240,6 +4240,26 @@ function CleveRoids.Frame:SPELLCAST_CHANNEL_STOP()
CleveRoids.CurrentSpell.spellName = ""
CleveRoids.CurrentSpell.castingSpellId = nil
-- WARLOCK DARK HARVEST: Mark channeling as ended
-- Credits: Pepopo / Cursive addon
if CleveRoids.darkHarvestData and CleveRoids.darkHarvestData.isActive then
CleveRoids.darkHarvestData.isActive = false
CleveRoids.darkHarvestData.endTime = GetTime()
-- Apply Dark Harvest end to all DoTs on target (finalizes reduction)
if CleveRoids.libdebuff and CleveRoids.libdebuff.ApplyDarkHarvestEnd then
CleveRoids.libdebuff.ApplyDarkHarvestEnd(CleveRoids.darkHarvestData.targetGUID)
end
if CleveRoids.debug then
local activeTime = CleveRoids.darkHarvestData.endTime - CleveRoids.darkHarvestData.startTime
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cff9482c9[Dark Harvest]|r Channel ended after %.1fs (DoT acceleration stopped)",
activeTime)
)
end
end
-- Force immediate action update
CleveRoids.TestForAllActiveActions()
end
+49 -3
View File
@@ -273,6 +273,7 @@ Macro 1 shows Macro 2's icon when out of combat:
---
## Debuff Timer System
*Credits: yani9o*
Built-in debuff tracking using SuperWoW's advanced features.
@@ -370,13 +371,58 @@ Rupture with 5 CP and Taste for Blood 3/3:
3. Talent: 16s + (3×2) = **22s final**
### Carnage (Druid - TWoW Custom)
Ferocious Bite at 5 CP refreshes Rip/Rake to original duration.
*Credits: Pepopo / Cursive addon*
When Ferocious Bite procs Carnage, it refreshes Rip/Rake to their original duration.
**Talent Details:**
- Rank 1: 10% chance per combo point to proc
- Rank 2: 20% chance per combo point to proc
**How Detection Works:**
- Uses Cursive-style proc detection via PLAYER_COMBO_POINTS event
- After Ferocious Bite, combo points should drop to 0
- If Carnage procs, combo points will be 1 (the Carnage-granted point)
- Detection triggers only when the proc actually occurs
**Requirements:**
- Carnage talent rank 2+
- Ferocious Bite with exactly 5 CP
- Carnage talent (any rank)
- Rip/Rake active on target
### Rake Debuff Cap Verification (Druid)
*Credits: Pepopo / Cursive addon*
In high-debuff scenarios (Naxxramas, etc.), Rake may get pushed off the target at the 48 debuff cap. For non-whitelisted mobs, the addon verifies Rake is actually present on the target before tracking.
**Whitelisted Bosses:**
- All Naxxramas bosses
- Karazhan Crypts bosses
- Kruul, Mephistroth
### Molten Blast → Flame Shock Refresh (Shaman - TWoW Custom)
*Credits: Pepopo / Cursive addon*
When Molten Blast hits a target, it refreshes any active Flame Shock to its full duration.
**How Detection Works:**
- Monitors combat log for Molten Blast damage
- On hit confirmation, resets Flame Shock timer to full duration
### Conflagrate → Immolate Reduction (Warlock)
*Credits: Pepopo / Cursive addon*
When Conflagrate is cast, it reduces the remaining Immolate duration by 3 seconds.
### Dark Harvest Duration Acceleration (Warlock - TWoW Custom)
*Credits: Pepopo / Cursive addon*
Dark Harvest is a channeled spell that accelerates all DoT tick rates on the target by 30%.
**How It Works:**
- While channeling Dark Harvest, all DoTs on the target tick 30% faster
- Debuff timers account for this acceleration
- When channel ends, the acceleration stops but accumulated reduction is preserved
---
## Equipment Modifiers
+240 -68
View File
@@ -1702,18 +1702,88 @@ local function SeedUnit(unit)
end
end
-- Carnage pending refresh system
-- Stores pending Carnage refreshes to be applied after verifying the Ferocious Bite hit
-- Format: { timestamp = GetTime(), targetGUID = guid, targetName = name, biteSpellID = id }
lib.pendingCarnageRefresh = nil
-- Carnage refresh system
-- NOTE: Carnage proc detection is now handled in ComboPointTracker.lua via PLAYER_COMBO_POINTS event
-- When Carnage procs, combo points don't drop to 0 after Ferocious Bite (they stay at 1)
-- The ApplyCarnageRefresh function below is called from ComboPointTracker when a proc is detected
-- =============================================================================
-- WARLOCK DARK HARVEST: Duration Acceleration System (TWoW Custom)
-- Credits: Pepopo / Cursive addon
-- Dark Harvest is a channeled spell that accelerates DoT tick rate by 30%
-- While channeling, DoTs on the target expire 30% faster
-- =============================================================================
-- Calculate Dark Harvest reduction for a debuff record
-- Returns the amount of time to subtract from remaining duration
function lib.GetDarkHarvestReduction(rec)
if not rec or not rec.dhStartTime then
return 0
end
local endTime = rec.dhEndTime or GetTime()
local dhActiveTime = endTime - rec.dhStartTime
if dhActiveTime > 0 then
return dhActiveTime * 0.3 -- 30% acceleration
end
return 0
end
-- Track Dark Harvest start for all DoTs on target
function lib.ApplyDarkHarvestStart(targetGUID)
if not lib.objects[targetGUID] then return end
local now = GetTime()
for spellID, rec in pairs(lib.objects[targetGUID]) do
if type(rec) == "table" and rec.duration and rec.start then
-- Only affect DoTs (debuffs with duration > 0 that tick)
-- Skip if already has dhStartTime (avoid double-tracking)
if not rec.dhStartTime then
rec.dhStartTime = now
rec.dhEndTime = nil -- Clear any previous end time
end
end
end
if CleveRoids.debug then
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cff9482c9[Dark Harvest]|r Started accelerating DoTs on %s",
lib.guidToName[targetGUID] or "Unknown")
)
end
end
-- Track Dark Harvest end for all DoTs on target
function lib.ApplyDarkHarvestEnd(targetGUID)
if not lib.objects[targetGUID] then return end
local now = GetTime()
for spellID, rec in pairs(lib.objects[targetGUID]) do
if type(rec) == "table" and rec.dhStartTime and not rec.dhEndTime then
rec.dhEndTime = now
end
end
end
-- Get time remaining for a debuff, accounting for Dark Harvest acceleration
function lib.GetTimeRemainingWithDarkHarvest(rec)
if not rec or not rec.duration or not rec.start then
return 0
end
local baseRemaining = rec.duration + rec.start - GetTime()
local dhReduction = lib.GetDarkHarvestReduction(rec)
return baseRemaining - dhReduction
end
-- Personal debuff pending tracking system
-- Stores personal debuffs to be added after 0.5s delay (to verify they weren't dodged/parried/blocked)
-- Format: { [index] = { timestamp = GetTime(), targetGUID = guid, targetName = name, spellID = id, duration = X, comboPoints = CP } }
lib.pendingPersonalDebuffs = lib.pendingPersonalDebuffs or {}
-- Function to apply Carnage refresh (extracted for delayed execution)
local function ApplyCarnageRefresh(targetGUID, targetName, biteSpellID)
-- Function to apply Carnage refresh (exposed for ComboPointTracker to call on proc detection)
function lib.ApplyCarnageRefresh(targetGUID, targetName, biteSpellID)
if CleveRoids.debug then
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cffff00ff[Carnage]|r ApplyCarnageRefresh called for %s", targetName or "Unknown")
@@ -1899,31 +1969,10 @@ local function ApplyCarnageRefresh(targetGUID, targetName, biteSpellID)
end
end
-- Frame for delayed Carnage refresh and personal debuff tracking
-- Frame for delayed personal debuff tracking and judgement scanning
-- NOTE: Carnage refresh is now handled via PLAYER_COMBO_POINTS event in ComboPointTracker.lua
local delayedTrackingFrame = CreateFrame("Frame", "CleveRoidsDelayedTrackingFrame", UIParent)
delayedTrackingFrame:SetScript("OnUpdate", function()
-- Process pending Carnage refresh
if lib.pendingCarnageRefresh then
local pending = lib.pendingCarnageRefresh
local elapsed = GetTime() - pending.timestamp
-- Apply refresh after 0.3 second delay (enough time for dodge/parry/block messages)
if elapsed >= 0.3 then
-- Apply the Carnage refresh
ApplyCarnageRefresh(pending.targetGUID, pending.targetName, pending.biteSpellID)
if CleveRoids.debug then
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cffff00ff[Carnage]|r Applied delayed refresh for Ferocious Bite on %s",
pending.targetName or "Unknown")
)
end
-- Clear the pending refresh
lib.pendingCarnageRefresh = nil
end
end
-- Process pending judgement scans to detect actual debuff IDs
if lib.pendingJudgements then
local toRemove = {}
@@ -2058,6 +2107,32 @@ ev:SetScript("OnEvent", function()
end
end
end
-- WARLOCK DARK HARVEST: Track channeling for DoT acceleration (TWoW Custom)
-- Credits: Pepopo / Cursive addon
-- Dark Harvest accelerates DoT tick rate by 30% while channeling
if eventType == "CHANNEL" and CleveRoids.DarkHarvestSpellIDs and CleveRoids.DarkHarvestSpellIDs[spellID] then
-- Get channel duration from tooltip or use base duration (8 seconds)
local channelDuration = 8 -- Base Dark Harvest duration
CleveRoids.darkHarvestData = {
targetGUID = targetGUID,
spellID = spellID,
startTime = GetTime(),
channelDuration = channelDuration,
isActive = true
}
-- Apply Dark Harvest acceleration to all existing DoTs on target
lib.ApplyDarkHarvestStart(targetGUID)
if CleveRoids.debug then
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cff9482c9[Dark Harvest]|r Started channeling on %s (DoTs will tick 30%% faster)",
lib.guidToName[targetGUID] or "Unknown")
)
end
end
end
end
@@ -2065,20 +2140,16 @@ 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
-- Schedule a delayed refresh to allow dodge/parry/block detection
-- DRUID CARNAGE TALENT: Track Ferocious Bite cast for proc detection
-- Carnage proc is detected in ComboPointTracker via PLAYER_COMBO_POINTS event
-- When Carnage procs, combo points don't decrease (or increase by 1)
if CleveRoids.FerociousBiteSpellIDs and CleveRoids.FerociousBiteSpellIDs[spellID] then
-- Get combo points used (captured before consumption)
local biteComboPoints = CleveRoids.lastComboPoints or 0
-- Check if player has Carnage talent at rank 2
-- Check if player has Carnage talent (any rank)
-- Carnage: Tab 2 (Feral Combat), Talent 17
local carnageRank = 0
local _, _, _, _, rank = GetTalentInfo(2, 17)
carnageRank = tonumber(rank) or 0
local carnageRank = tonumber(rank) or 0
-- Carnage 2/2+: Ferocious Bite at 5 CP schedules a refresh (applied only if spell hits)
if carnageRank >= 2 and biteComboPoints == 5 then
if carnageRank >= 1 then
local targetName = lib.guidToName[targetGUID]
if not targetName then
local _, currentTargetGUID = UnitExists("target")
@@ -2091,23 +2162,60 @@ ev:SetScript("OnEvent", function()
end
end
-- Schedule the Carnage refresh (will be applied after 0.5s if not cancelled)
lib.pendingCarnageRefresh = {
timestamp = GetTime(),
targetGUID = targetGUID,
targetName = targetName,
biteSpellID = spellID
}
-- Track Ferocious Bite cast for Carnage proc detection (via PLAYER_COMBO_POINTS)
-- Unlike the old system, we don't schedule a refresh here - we wait for the proc
CleveRoids.lastFerociousBiteTime = GetTime()
CleveRoids.lastFerociousBiteTargetGUID = targetGUID
CleveRoids.lastFerociousBiteTargetName = targetName
CleveRoids.lastFerociousBiteSpellID = spellID
if CleveRoids.debug then
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cffff00ff[Carnage]|r Scheduled refresh for Ferocious Bite on %s (will apply if hit)",
string.format("|cffff00ff[Carnage]|r Tracking Ferocious Bite on %s (waiting for proc detection)",
targetName or "Unknown")
)
end
end
end
-- SHAMAN MOLTEN BLAST: Track for Flame Shock refresh detection (TWoW Custom)
-- Credits: Pepopo / Cursive addon
if CleveRoids.MoltenBlastSpellIDs and CleveRoids.MoltenBlastSpellIDs[spellID] then
CleveRoids.lastMoltenBlastTime = GetTime()
CleveRoids.lastMoltenBlastTargetGUID = targetGUID
if CleveRoids.debug then
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cff0070dd[Molten Blast]|r Tracking cast on %s (waiting for hit confirmation)",
lib.guidToName[targetGUID] or "Unknown")
)
end
end
-- WARLOCK CONFLAGRATE: Reduces Immolate duration by 3 seconds
-- Credits: Pepopo / Cursive addon
if CleveRoids.ConflagrateSpellIDs and CleveRoids.ConflagrateSpellIDs[spellID] then
-- Find active Immolate on target and reduce its duration
if lib.objects[targetGUID] then
for immolateID, _ in pairs(CleveRoids.ImmolateSpellIDs or {}) do
local rec = lib.objects[targetGUID][immolateID]
if rec and rec.duration and rec.start then
local remaining = rec.duration + rec.start - GetTime()
if remaining > 0 then
-- Reduce duration by 3 seconds
rec.duration = rec.duration - 3
if CleveRoids.debug then
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cff9482c9[Conflagrate]|r Reduced Immolate duration by 3s (now %.1fs remaining)",
rec.duration + rec.start - GetTime())
)
end
break
end
end
end
end
end
-- Check if this is a combo point scaling spell first
local duration = nil
local comboPoints = nil
@@ -2340,8 +2448,35 @@ ev:SetScript("OnEvent", function()
end
-- DRUID CARNAGE TALENT: Save Rake cast duration for later refresh by Ferocious Bite
-- Also includes debuff cap verification (Credits: Pepopo / Cursive addon)
if CleveRoids.RakeSpellIDs and CleveRoids.RakeSpellIDs[spellID] then
if CleveRoids.lastRakeCast then
-- Check if mob is in bleed whitelist (high-debuff scenarios)
local isWhitelisted = CleveRoids.MobsThatBleed and CleveRoids.MobsThatBleed[targetGUID]
local rakeVerified = true
if not isWhitelisted and CleveRoids.hasSuperwow then
-- Verify Rake is actually on the target (may have been pushed off at debuff cap)
rakeVerified = false
for slot = 1, 48 do
local _, _, _, debuffSpellID = UnitDebuff(targetGUID, slot)
if not debuffSpellID then
if slot <= 16 then break end -- Regular debuffs are dense, overflow continues on nil
elseif debuffSpellID == spellID then
rakeVerified = true
break
end
end
if not rakeVerified and CleveRoids.debug then
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cffff6600[Rake Debuff Cap]|r Rake not found on %s - likely pushed off at debuff cap",
targetName or "Unknown")
)
end
end
-- Only save Rake cast data if verified (or can't verify)
if rakeVerified and CleveRoids.lastRakeCast then
CleveRoids.lastRakeCast.spellID = spellID
CleveRoids.lastRakeCast.duration = duration
CleveRoids.lastRakeCast.targetGUID = targetGUID
@@ -2429,8 +2564,9 @@ evLearn:SetScript("OnEvent", function()
end
if spellName and targetName then
-- CARNAGE: Cancel pending refresh if Ferocious Bite was dodged/parried/blocked
if lib.pendingCarnageRefresh then
-- CARNAGE: Clear Ferocious Bite tracking if it was dodged/parried/blocked
-- This prevents false proc detection in edge cases
if CleveRoids.lastFerociousBiteTime then
-- Check if the failed spell is Ferocious Bite
local isFerociousBite = false
if CleveRoids.FerociousBiteSpellIDs then
@@ -2448,27 +2584,18 @@ evLearn:SetScript("OnEvent", function()
end
if isFerociousBite then
-- Cancel the pending Carnage refresh
if CleveRoids.debug and lib.pendingCarnageRefresh then
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cffff00ff[Carnage]|r Cancelling pending refresh (time since cast: %.2fs)",
GetTime() - lib.pendingCarnageRefresh.timestamp)
)
end
lib.pendingCarnageRefresh = nil
-- Clear any stale Carnage duration overrides to prevent pfUI from using old data
if CleveRoids.carnageDurationOverrides then
CleveRoids.carnageDurationOverrides = {}
end
if CleveRoids.debug then
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cffff00ff[Carnage]|r Cancelled refresh - Ferocious Bite was avoided by %s",
string.format("|cffff00ff[Carnage]|r Ferocious Bite avoided by %s - clearing tracking",
targetName or "Unknown")
)
end
-- Clear Ferocious Bite tracking (no proc possible since it was avoided)
CleveRoids.lastFerociousBiteTime = nil
CleveRoids.lastFerociousBiteTargetGUID = nil
CleveRoids.lastFerociousBiteTargetName = nil
CleveRoids.lastFerociousBiteSpellID = nil
end
end
@@ -2595,6 +2722,50 @@ evLearn:SetScript("OnEvent", function()
end
end
-- SHAMAN MOLTEN BLAST: Check for damage hit to trigger Flame Shock refresh (TWoW Custom)
-- Credits: Pepopo / Cursive addon
-- Pattern: "Your Molten Blast hits/crits X for Y Fire damage"
if CleveRoids.lastMoltenBlastTime and CleveRoids.lastMoltenBlastTargetGUID then
local timeSinceCast = GetTime() - CleveRoids.lastMoltenBlastTime
-- Check within 1 second of cast
if timeSinceCast < 1.0 then
-- Check if message mentions Molten Blast damage
if find(message, "Molten Blast") and find(message, "Fire damage") then
local targetGUID = CleveRoids.lastMoltenBlastTargetGUID
-- Find active Flame Shock on target and refresh it
if lib.objects[targetGUID] then
for flameShockID, _ in pairs(CleveRoids.FlameShockSpellIDs or {}) do
local rec = lib.objects[targetGUID][flameShockID]
-- Only refresh player's own Flame Shock, not other shamans'
if rec and rec.duration and rec.start and rec.caster == "player" then
local remaining = rec.duration + rec.start - GetTime()
if remaining > 0 then
-- Refresh: reset start time to now
rec.start = GetTime()
if CleveRoids.debug then
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cff0070dd[Molten Blast]|r Refreshed Flame Shock to %.1fs on %s",
rec.duration, lib.guidToName[targetGUID] or "Unknown")
)
end
break
end
end
end
end
-- Clear tracking
CleveRoids.lastMoltenBlastTime = nil
CleveRoids.lastMoltenBlastTargetGUID = nil
end
else
-- Time window expired
CleveRoids.lastMoltenBlastTime = nil
CleveRoids.lastMoltenBlastTargetGUID = nil
end
end
elseif event == "RAW_COMBATLOG" then
local raw = arg2
-- PERFORMANCE: Quick length check before string search
@@ -2964,8 +3135,9 @@ CleveRoids.talentModifiers[9823] = { tab = 2, id = 4, talent = "Brutal Impact",
CleveRoids.talentModifiers[9827] = { tab = 2, id = 4, talent = "Brutal Impact", modifier = function(base, rank) return base + (rank * 0.5) end } -- Pounce Rank 3
-- 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)
-- Carnage is a refresh mechanic: When Ferocious Bite procs Carnage, it refreshes Rip/Rake to original duration
-- Proc detection: Combo points stay at 1 after FB instead of dropping to 0
-- This is handled in ComboPointTracker.lua via PLAYER_COMBO_POINTS event
-- WARRIOR talent modifiers
-- Booming Voice: Increases duration of Battle Shout and Demoralizing Shout by 12% per rank (5 ranks max)