mirror of
https://github.com/brues-code/SuperCleveRoidMacros.git
synced 2026-09-16 03:38:00 +00:00
update debuff duration systems
This commit is contained in:
+152
-4
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user