Add learned combo duration system - saves actual durations per CP

Major enhancement: System now learns actual combo finisher durations and
saves them per combo point level (1-5 CP).

**New SavedVariable:**
- CleveRoids_ComboDurations[spellID][comboPoints] = duration
- Persists between sessions
- Uses learned durations before calculated formulas

**ComboPointTracker.lua:**
- Added GetLearnedComboDuration(spellID, cp) - fetch learned duration
- Updated CalculateComboScaledDurationByID to check learned first
- Falls back to formula if not learned yet

**Utility.lua (libdebuff):**
- UNIT_CASTEVENT handler stores combo points in learnCastTimers
- RAW_COMBATLOG fade handler learns combo durations when spells expire
- Stores learned duration keyed by [spellID][comboPoints]
- Debug message shows "Learned combo spell X at Y CP = Zs"

**Core.lua:**
- New command: /cleveroid combolearn - Show all learned combo durations
- Lists each spell with all learned CP levels (1-5)
- Shows which durations have been learned vs not yet

**Benefits:**
- Debuff conditionals like [debuff:Rip<4] now use ACTUAL max duration
- Accounts for talents that modify finisher durations
- Learns different durations per rank
- More accurate than formulas for edge cases

**Example:**
After casting Rip with 5 CP and letting it expire, system learns:
CleveRoids_ComboDurations[1079][5] = 28
Future casts use 28s instead of calculated 12+4*4
This commit is contained in:
Claude
2025-11-16 16:49:30 +00:00
parent e07afa32d0
commit 1172e3377b
4 changed files with 67 additions and 8 deletions
+25 -6
View File
@@ -838,8 +838,14 @@ ev:SetScript("OnEvent", function()
-- Check if this is a combo point scaling spell first
local duration = nil
local comboPoints = nil
if CleveRoids.TrackComboPointCastByID then
duration = CleveRoids.TrackComboPointCastByID(spellID, targetGUID)
-- Get combo points used from tracking
if CleveRoids.ComboPointTracking and CleveRoids.ComboPointTracking.byID and
CleveRoids.ComboPointTracking.byID[spellID] then
comboPoints = CleveRoids.ComboPointTracking.byID[spellID].combo_points
end
end
-- If not a combo scaling spell, use normal duration lookup
@@ -860,6 +866,16 @@ ev:SetScript("OnEvent", function()
end
lib:AddEffect(targetGUID, targetName, spellID, duration, 0, "player")
-- ALWAYS set up learning for combo spells (even if we have calculated duration)
if comboPoints then
lib.learnCastTimers[targetGUID] = lib.learnCastTimers[targetGUID] or {}
lib.learnCastTimers[targetGUID][spellID] = {
start = GetTime(),
caster = casterGUID,
comboPoints = comboPoints -- Store CP count for learning
}
end
else
lib.learnCastTimers[targetGUID] = lib.learnCastTimers[targetGUID] or {}
lib.learnCastTimers[targetGUID][spellID] = {
@@ -915,18 +931,21 @@ evLearn:SetScript("OnEvent", function()
local actualDuration = timestamp - castTime
-- Check if this is a combo point spell - if so, learn it with combo point context
local isComboSpell = false
if CleveRoids.IsComboScalingSpellID and CleveRoids.IsComboScalingSpellID(spellID) then
isComboSpell = true
local comboPoints = lib.learnCastTimers[targetGUID][spellID].comboPoints
if comboPoints and CleveRoids.IsComboScalingSpellID and CleveRoids.IsComboScalingSpellID(spellID) then
-- Learn combo spell duration
CleveRoids_ComboDurations = CleveRoids_ComboDurations or {}
CleveRoids_ComboDurations[spellID] = CleveRoids_ComboDurations[spellID] or {}
CleveRoids_ComboDurations[spellID][comboPoints] = floor(actualDuration + 0.5)
if CleveRoids.debug then
local comboData = CleveRoids.ComboPointTracking.byID and CleveRoids.ComboPointTracking.byID[spellID]
local cpUsed = comboData and comboData.combo_points or "?"
DEFAULT_CHAT_FRAME:AddMessage(
"|cff4b7dccCleveRoids:|r Learned combo spell " .. spellName ..
" (ID:" .. spellID .. ") with " .. cpUsed .. " CP = " .. floor(actualDuration + 0.5) .. "s"
" (ID:" .. spellID .. ") at " .. comboPoints .. " CP = " .. floor(actualDuration + 0.5) .. "s"
)
end
else
-- Learn normal spell duration
CleveRoids_LearnedDurations[spellID] = CleveRoids_LearnedDurations[spellID] or {}
CleveRoids_LearnedDurations[spellID][casterGUID] = floor(actualDuration + 0.5)