dpslog: handler table swaps, CombatLogGetCurrentEventInfo, unit flags, boolean fix

Major architectural changes:

- Migrate 12 packet handlers from JMP-patching Detours to NetClient opcode
  handler table pointer swaps. No code bytes modified — only heap pointers.
  Invisible to Warden memory scans. Hook InitializeGameEngine (0x401570,
  __thiscall) to install swaps after all handlers are registered.

- Implement CombatLogGetCurrentEventInfo() — WotLK-style lazy arg retrieval.
  Event fires with no args; addons call the function to get all fields from
  a C-side buffer. No arg count limit (bypasses ExecuteLuaCallback 19-arg cap).
  Includes unit flags, raid flags, and all suffix fields.

- Compute COMBATLOG_OBJECT_* unit flags: affiliation (MINE/PARTY/RAID/OUTSIDER),
  reaction (FRIENDLY/NEUTRAL/HOSTILE via UnitReaction), control (PLAYER/NPC),
  type (PLAYER/NPC/PET/GUARDIAN/OBJECT via SUMMONEDBY check), special (TARGET),
  and raid target markers.

- Fix boolean fields (critical/glancing/crushing): changed from %d (Lua number 0,
  which is TRUTHY) to nil/"1" via boolToLua(). Details addon was counting every
  hit as critical because it uses truthiness checks.

- SPELL_INSTAKILL now fires from SPELLLOGEXECUTE (has caster GUID).
  Standalone SMSG_SPELLINSTAKILLLOG handler is pass-through only.

- SPELL_EXTRA_ATTACKS now uses target GUID from packet (was discarded).

- SPELL_CAST_START/SUCCESS now parse spell target from packet.

- SPELL_DRAIN subevent added for instant power drain effects.

- Rename event from COMBAT_LOG_EVENT to COMBAT_LOG_EVENT_UNFILTERED.

- Update DPSMate and WSBT CLEU adapters to use CombatLogGetCurrentEventInfo().

- Remove unnecessary `or 0` guards on numeric fields (always non-nil from C).
This commit is contained in:
MarcelineVQ
2026-03-18 16:55:27 -07:00
parent fc762ac200
commit d84f723539
6 changed files with 559 additions and 313 deletions
+16 -4
View File
@@ -169,16 +169,28 @@ Provides WotLK 3.3.5-style `COMBAT_LOG_EVENT_UNFILTERED` for the vanilla client.
37 subevents covering all combat interactions: damage (spell, melee, periodic, environmental, damage shield, damage split), healing (direct, periodic, overheal tracking), misses (all types), auras (applied, removed, refreshed, broken, dose changes), casts (start, success, failed, interrupted), power (energize, drain, leech), dispels, extra attacks, deaths, and kills.
Each event includes source/destination names and GUIDs, spell names, school bitmasks, overkill/overheal amounts, and all WotLK-standard fields.
Each event includes source/destination GUIDs, names, unit flags, raid flags, spell info, and all WotLK-standard suffix fields. Booleans (critical, glancing, crushing) use WotLK semantics: `nil` for false, `"1"` for true.
Also provides `GetSpellInfo(spellId)` -- the TBC/WotLK spell lookup API that doesn't exist in vanilla:
Also provides:
- `CombatLogGetCurrentEventInfo()` -- WotLK-style lazy arg retrieval (call from event handler):
```lua
local f = CreateFrame("Frame")
f:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
f:SetScript("OnEvent", function()
local sub, srcGUID, srcName, srcFlags, srcRaidFlags,
dstGUID, dstName, dstFlags, dstRaidFlags = CombatLogGetCurrentEventInfo()
-- suffix args follow (spellId, spellName, etc.) -- see wiki for full layout
end)
```
- `GetSpellInfo(spellId)` -- the TBC/WotLK spell lookup API:
```lua
local name, rank, icon, castTime, minRange, maxRange, spellId = GetSpellInfo(133)
```
Includes an embedded tracker addon (`/dpslog`) for verifying event coverage.
See the [DPSLog wiki page](https://codeberg.org/gwenael/WeirdUtils/wiki/DPSLog) for full event reference and addon developer guide.
**DLL:** `dpslog.dll`
+8
View File
@@ -592,6 +592,14 @@ All in the 0x51xxxx addon/UI system. Zeroing/overwriting these corrupts game sta
- Known limitations: false positives if damage + unrelated aura removal happen in same batch;
no coverage for SPELL_AURA_BROKEN (without spell — melee break) since we pass spellId=0 for melee
### Future — Custom Extensions (beyond WotLK spec)
- [ ] **RESURRECT_ACCEPTED**: Current SPELL_RESURRECT fires on cast/effect (ProcessSpellEffect),
not when the target accepts. Detect via outgoing CMSG_RESURRECT_RESPONSE (0x15C) or
SMSG_UPDATE_OBJECT alive state change. Related: SMSG_RESURRECT_REQUEST (0x15B),
SMSG_RESURRECT_FAILED (0x252).
- [ ] **UNIT_POSITION**: Periodic or event-driven unit position data in combat log events.
Useful for replay/analysis tools.
### Completed reference
- [x] RANGE_MISSED: Detected via spell ID check (75/5019) in ProcessSpellCombatResult hook.
- [x] SPELL_SUMMON / SPELL_RESURRECT / SPELL_ENERGIZE: Hook ProcessSpellEffect (0x62ACE0),
+43 -52
View File
@@ -3,7 +3,8 @@
-- Toggle: /wsbtcleu (switches between CLEU adapter and original string parser)
-- Requires: DPSLog module (provides COMBAT_LOG_EVENT_UNFILTERED)
-- Wait for MikCEH to be initialized
-- Require DPSLog module and MikCEH
if not GetWeirdUtilsVersion or not GetWeirdUtilsVersion("dpslog") then return end
if not MikCEH or not MikCEH.SendEvent then return end
local CEH = MikCEH
@@ -203,31 +204,28 @@ local envActionMap = {
local cleuHandler
cleuHandler = function()
local sub = arg1
if not CombatLogGetCurrentEventInfo then return end
local sub, srcGUID, srcName, srcFlags, srcRaidFlags,
dstGUID, dstName, dstFlags, dstRaidFlags = CombatLogGetCurrentEventInfo()
if not sub then return end
local srcName = arg3
local dstName = arg5
if not srcName or srcName == "" then srcName = "Unknown" end
if not dstName or dstName == "" then dstName = "Unknown" end
-- ========================================================================
-- SWING_DAMAGE
-- args: amount(6), overkill(7), school(8), resisted(9), blocked(10),
-- absorbed(11), critical(12), glancing(13), crushing(14)
-- (base 9), amount, overkill, school, resisted, blocked,
-- absorbed, critical, glancing, crushing
-- ========================================================================
if sub == "SWING_DAMAGE" then
local dir, name = getDirection(srcName, dstName)
if not dir then return end
local amount = arg6 or 0
local resisted = arg9 or 0
local blocked = arg10 or 0
local absorbed = arg11 or 0
local critical = arg12 == 1
local glancing = arg13 == 1 and 1 or 0
local crushing = arg14 == 1 and 1 or 0
local _, _, _, _, _, _, _, _, _,
amount, overkill, school, resisted, blocked, absorbed,
critical, glancing, crushing = CombatLogGetCurrentEventInfo()
glancing = glancing and 1 or 0
crushing = crushing and 1 or 0
local hitType = critical and HIT_CRIT or HIT_NORMAL
local data = GetDamageData(dir, HIT, hitType, DMG_PHYSICAL, amount, nil, name)
@@ -242,7 +240,8 @@ cleuHandler = function()
elseif sub == "SWING_MISSED" then
local dir, name = getDirection(srcName, dstName)
if not dir then return end
local action = missActionMap[arg6] or MISS
local _, _, _, _, _, _, _, _, _, missType = CombatLogGetCurrentEventInfo()
local action = missActionMap[missType] or MISS
local data = GetDamageData(dir, action, nil, nil, nil, nil, name)
SendEvent(data)
@@ -257,14 +256,11 @@ cleuHandler = function()
or sub == "DAMAGE_SPLIT" then
local dir, name = getDirection(srcName, dstName)
if not dir then return end
local spellName = arg7
local amount = arg9 or 0
local school = arg11
local resisted = arg12 or 0
local blocked = arg13 or 0
local absorbed = arg14 or 0
local critical = arg15 == 1
local crushing = arg17 == 1 and 1 or 0
local _, _, _, _, _, _, _, _, _,
spellId, spellName, spellSchool,
amount, overkill, school, resisted, blocked, absorbed,
critical, glancing, crushing = CombatLogGetCurrentEventInfo()
crushing = crushing and 1 or 0
local hitType = critical and HIT_CRIT or HIT_NORMAL
local dmgType = schoolToDamageType(school)
@@ -275,11 +271,10 @@ cleuHandler = function()
elseif sub == "SPELL_PERIODIC_DAMAGE" then
local dir, name = getDirection(srcName, dstName)
if not dir then return end
local spellName = arg7
local amount = arg9 or 0
local school = arg11
local resisted = arg12 or 0
local absorbed = arg14 or 0
local _, _, _, _, _, _, _, _, _,
spellId, spellName, spellSchool,
amount, overkill, school, resisted, blocked, absorbed = CombatLogGetCurrentEventInfo()
-- numbers always non-nil from CombatLogGetCurrentEventInfo
local dmgType = schoolToDamageType(school)
local data = GetDamageData(dir, HIT, HIT_DOT, dmgType, amount, spellName, name)
@@ -296,8 +291,9 @@ cleuHandler = function()
or sub == "SPELL_PERIODIC_MISSED" or sub == "DAMAGE_SHIELD_MISSED" then
local dir, name = getDirection(srcName, dstName)
if not dir then return end
local spellName = arg7
local action = missActionMap[arg9] or MISS
local _, _, _, _, _, _, _, _, _,
spellId, spellName, spellSchool, missType = CombatLogGetCurrentEventInfo()
local action = missActionMap[missType] or MISS
local data = GetDamageData(dir, action, nil, nil, nil, spellName, name)
SendEvent(data)
@@ -309,8 +305,7 @@ cleuHandler = function()
elseif sub == "ENVIRONMENTAL_DAMAGE" then
if dstName ~= playerName then return end
local envType = arg6
local amount = arg7 or 0
local _, _, _, _, _, _, _, _, _, envType, amount = CombatLogGetCurrentEventInfo()
local action = envActionMap[envType] or HIT
local data = GetDamageData(INCOMING, action, HIT_NORMAL, DMG_PHYSICAL, amount, nil, envType or "Environment")
SendEvent(data)
@@ -324,10 +319,9 @@ cleuHandler = function()
elseif sub == "SPELL_HEAL" or sub == "SPELL_PERIODIC_HEAL" then
local dir, name = getDirection(srcName, dstName)
if not dir then return end
local spellName = arg7
local amount = arg9 or 0
local overheal = arg10 or 0
local critical = arg12 == 1
local _, _, _, _, _, _, _, _, _,
spellId, spellName, spellSchool,
amount, overheal, absorbed, critical = CombatLogGetCurrentEventInfo()
local isPeriodic = (sub == "SPELL_PERIODIC_HEAL")
local healType
@@ -358,9 +352,8 @@ cleuHandler = function()
elseif sub == "SPELL_ENERGIZE" or sub == "SPELL_PERIODIC_ENERGIZE" then
if dstName ~= playerName then return end
local spellName = arg7
local amount = arg9 or 0
local powerType = arg10 or 0
local _, _, _, _, _, _, _, _, _,
spellId, spellName, spellSchool, amount, powerType = CombatLogGetCurrentEventInfo()
local powerName = powerTypeNames[powerType] or "Mana"
local data = GetNotifData(NOTIF_POWER_GAIN, amount .. " " .. powerName, spellName)
SendEvent(data)
@@ -373,21 +366,18 @@ cleuHandler = function()
elseif sub == "SPELL_PERIODIC_DRAIN" then
if dstName ~= playerName then return end
local spellName = arg7
local amount = arg9 or 0
local powerType = arg10 or 0
local _, _, _, _, _, _, _, _, _,
spellId, spellName, spellSchool, amount, powerType = CombatLogGetCurrentEventInfo()
local powerName = powerTypeNames[powerType] or "Mana"
local data = GetNotifData(NOTIF_POWER_LOSS, amount .. " " .. powerName, spellName)
SendEvent(data)
elseif sub == "SPELL_PERIODIC_LEECH" then
-- Leech = damage to target + heal to source
-- Show as damage taken if we're the target
local dir, name = getDirection(srcName, dstName)
if not dir then return end
local spellName = arg7
local amount = arg9 or 0
local dmgType = schoolToDamageType(arg8)
local _, _, _, _, _, _, _, _, _,
spellId, spellName, spellSchool, amount = CombatLogGetCurrentEventInfo()
local dmgType = schoolToDamageType(spellSchool)
local data = GetDamageData(dir, HIT, HIT_DOT, dmgType, amount, spellName, name)
SendEvent(data)
@@ -399,8 +389,8 @@ cleuHandler = function()
elseif sub == "SPELL_AURA_APPLIED" then
if dstName ~= playerName then return end
local spellName = arg7
local auraType = arg9
local _, _, _, _, _, _, _, _, _,
spellId, spellName, spellSchool, auraType = CombatLogGetCurrentEventInfo()
if auraType == "DEBUFF" then
local data = GetNotifData(NOTIF_DEBUFF, nil, spellName)
SendEvent(data)
@@ -411,7 +401,7 @@ cleuHandler = function()
elseif sub == "SPELL_AURA_REMOVED" then
if dstName ~= playerName then return end
local spellName = arg7
local _, _, _, _, _, _, _, _, _, spellId, spellName = CombatLogGetCurrentEventInfo()
local data = GetNotifData(NOTIF_BUFF_FADE, nil, spellName)
SendEvent(data)
@@ -462,8 +452,9 @@ local cleuEventsSkipped = 0
local function measuredCLEUHandler()
if profiling and profCurrent == profCLEU then
-- Quick relevance check: is player or pet involved?
local srcName = arg3 or ""
local dstName = arg5 or ""
local _, _, srcName, _, _, _, dstName = CombatLogGetCurrentEventInfo()
srcName = srcName or ""
dstName = dstName or ""
local relevant = (srcName == playerName or dstName == playerName
or (petName and (srcName == petName or dstName == petName)))
+76 -68
View File
@@ -7,6 +7,7 @@
-- Requires: DPSLog module (provides COMBAT_LOG_EVENT_UNFILTERED + GetSpellInfo)
if not DPSMate or not DPSMate.DB then return end
if not GetWeirdUtilsVersion or not GetWeirdUtilsVersion("dpslog") then return end
local DB = DPSMate.DB
local Parser = DPSMate.Parser
@@ -278,44 +279,43 @@ local FailDT = DPSMate.Parser.FailDT
local FailDB = DPSMate.Parser.FailDB
cleuHandler = function()
local sub = arg1
if not CombatLogGetCurrentEventInfo then return end
local sub, srcGUID, srcName, srcFlags, srcRaidFlags,
dstGUID, dstName, dstFlags, dstRaidFlags = CombatLogGetCurrentEventInfo()
if not sub then return end
local srcGUID = arg2
local srcName = arg3
local dstGUID = arg4
local dstName = arg5
if not srcName or srcName == "" then srcName = "Unknown" end
if not dstName or dstName == "" then dstName = "Unknown" end
-- ========================================================================
-- DAMAGE events
-- ========================================================================
-- SWING_DAMAGE args: amount(6), overkill(7), school(8), resisted(9),
-- blocked(10), absorbed(11), critical(12), glancing(13), crushing(14)
-- SWING_DAMAGE: (base 9), amount, overkill, school, resisted,
-- blocked, absorbed, critical, glancing, crushing
if sub == "SWING_DAMAGE" then
local amount = arg6 or 0
local absorbed = arg11 or 0
local critical = arg12 == 1 and 1 or 0
local glancing = arg13 == 1 and 1 or 0
local crushing = arg14 == 1 and 1 or 0
local hit = (critical == 0 and glancing == 0 and crushing == 0) and 1 or 0
local _, _, _, _, _, _, _, _, _,
amount, overkill, school, resisted, blocked, absorbed,
critical, glancing, crushing = CombatLogGetCurrentEventInfo()
-- numbers always non-nil from CombatLogGetCurrentEventInfo
local crit = critical and 1 or 0
local glanc = glancing and 1 or 0
local crush = crushing and 1 or 0
local hit = (crit == 0 and glanc == 0 and crush == 0) and 1 or 0
DB:DamageDone(srcName, AAttack, hit, critical, 0, 0, 0, 0, amount, glancing, 0)
DB:DamageTaken(dstName, AAttack, hit, critical, 0, 0, 0, 0, amount, srcName, crushing, 0)
DB:EnemyDamage(1, DPSMateEDT, dstName, AAttack, hit, critical, 0, 0, 0, 0, amount, srcName, 0, crushing)
DB:EnemyDamage(2, DPSMateEDD, srcName, AAttack, hit, critical, 0, 0, 0, 0, amount, dstName, 0, 0)
DB:DeathHistory(dstName, srcName, AAttack, amount, hit, critical, "hit", crushing)
-- Partial absorb on a hit
DB:DamageDone(srcName, AAttack, hit, crit, 0, 0, 0, 0, amount, glanc, 0)
DB:DamageTaken(dstName, AAttack, hit, crit, 0, 0, 0, 0, amount, srcName, crush, 0)
DB:EnemyDamage(1, DPSMateEDT, dstName, AAttack, hit, crit, 0, 0, 0, 0, amount, srcName, 0, crush)
DB:EnemyDamage(2, DPSMateEDD, srcName, AAttack, hit, crit, 0, 0, 0, 0, amount, dstName, 0, 0)
DB:DeathHistory(dstName, srcName, AAttack, amount, hit, crit, "hit", crush)
if absorbed > 0 then
DB:SetUnregisterVariables(absorbed, AAttack, srcName)
DB:Absorb(AAttack, dstName, srcName)
end
elseif sub == "SWING_MISSED" then
local missType = arg6
local _, _, _, _, _, _, _, _, _,
missType = CombatLogGetCurrentEventInfo()
local miss = (missType == "MISS") and 1 or 0
local parry = (missType == "PARRY") and 1 or 0
local dodge = (missType == "DODGE") and 1 or 0
@@ -325,46 +325,47 @@ cleuHandler = function()
DB:DamageDone(srcName, AAttack, 0, 0, miss + absorb, parry, dodge, resist, 0, 0, block)
DB:DamageTaken(dstName, AAttack, 0, 0, miss + absorb, parry, dodge, resist, 0, srcName, 0, block)
-- Full absorb
if absorb == 1 then
DB:Absorb(AAttack, dstName, srcName)
end
-- SPELL_DAMAGE args (after prefix): amount(9), overkill(10), school(11),
-- resisted(12), blocked(13), absorbed(14), critical(15), glancing(16), crushing(17)
-- SPELL_DAMAGE: (base 9), spellId, spellName, spellSchool,
-- amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing
elseif sub == "SPELL_DAMAGE" or sub == "RANGE_DAMAGE" or sub == "SPELL_PERIODIC_DAMAGE"
or sub == "DAMAGE_SHIELD" or sub == "DAMAGE_SPLIT" then
local spellName = arg7 or "Unknown"
local amount = arg9 or 0
local school = arg11
local absorbed = arg14 or 0
local critical = arg15 == 1 and 1 or 0
local glancing = arg16 == 1 and 1 or 0
local crushing = arg17 == 1 and 1 or 0
local hit = (critical == 0 and glancing == 0 and crushing == 0) and 1 or 0
local _, _, _, _, _, _, _, _, _,
spellId, spellName, spellSchool,
amount, overkill, school, resisted, blocked, absorbed,
critical, glancing, crushing = CombatLogGetCurrentEventInfo()
spellName = spellName or "Unknown"
-- numbers always non-nil from CombatLogGetCurrentEventInfo
local crit = critical and 1 or 0
local glanc = glancing and 1 or 0
local crush = crushing and 1 or 0
local hit = (crit == 0 and glanc == 0 and crush == 0) and 1 or 0
local abilityName = (sub == "SPELL_PERIODIC_DAMAGE") and (spellName .. "(Periodic)") or spellName
DB:DamageDone(srcName, abilityName, hit, critical, 0, 0, 0, 0, amount, glancing, 0)
DB:DamageTaken(dstName, abilityName, hit, critical, 0, 0, 0, 0, amount, srcName, crushing, 0)
DB:EnemyDamage(1, DPSMateEDT, dstName, abilityName, hit, critical, 0, 0, 0, 0, amount, srcName, 0, crushing)
DB:EnemyDamage(2, DPSMateEDD, srcName, abilityName, hit, critical, 0, 0, 0, 0, amount, dstName, 0, 0)
DB:DeathHistory(dstName, srcName, abilityName, amount, hit, critical, "hit", crushing)
if school then DB:AddSpellSchool(abilityName, school) end
-- Partial absorb on a hit
DB:DamageDone(srcName, abilityName, hit, crit, 0, 0, 0, 0, amount, glanc, 0)
DB:DamageTaken(dstName, abilityName, hit, crit, 0, 0, 0, 0, amount, srcName, crush, 0)
DB:EnemyDamage(1, DPSMateEDT, dstName, abilityName, hit, crit, 0, 0, 0, 0, amount, srcName, 0, crush)
DB:EnemyDamage(2, DPSMateEDD, srcName, abilityName, hit, crit, 0, 0, 0, 0, amount, dstName, 0, 0)
DB:DeathHistory(dstName, srcName, abilityName, amount, hit, crit, "hit", crush)
if spellSchool then DB:AddSpellSchool(abilityName, spellSchool) end
if absorbed > 0 then
DB:SetUnregisterVariables(absorbed, abilityName, srcName)
DB:Absorb(abilityName, dstName, srcName)
end
-- Avoidable damage taken (fire, void zones, etc.)
if FailDT and FailDT[spellName] then
DB:BuildFail(2, srcName, dstName, abilityName, amount)
end
elseif sub == "SPELL_MISSED" or sub == "RANGE_MISSED"
or sub == "SPELL_PERIODIC_MISSED" or sub == "DAMAGE_SHIELD_MISSED" then
local spellName = arg7 or "Unknown"
local missType = arg9
local _, _, _, _, _, _, _, _, _,
spellId, spellName, spellSchool,
missType = CombatLogGetCurrentEventInfo()
spellName = spellName or "Unknown"
local miss = (missType == "MISS") and 1 or 0
local parry = (missType == "PARRY") and 1 or 0
local dodge = (missType == "DODGE") and 1 or 0
@@ -376,14 +377,13 @@ cleuHandler = function()
DB:DamageDone(srcName, abilityName, 0, 0, miss + absorb, parry, dodge, resist, 0, 0, block)
DB:DamageTaken(dstName, abilityName, 0, 0, miss + absorb, parry, dodge, resist, 0, srcName, 0, block)
-- Full absorb
if absorb == 1 then
DB:Absorb(abilityName, dstName, srcName)
end
elseif sub == "ENVIRONMENTAL_DAMAGE" then
local envType = arg6
local amount = arg7 or 0
local _, _, _, _, _, _, _, _, _,
envType, amount = CombatLogGetCurrentEventInfo()
DB:DamageTaken(dstName, envType or "Environment", 1, 0, 0, 0, 0, 0, amount, envType or "Environment", 0, 0)
DB:DeathHistory(dstName, envType or "Environment", envType or "Environment", amount, 1, 0, "hit", 0)
@@ -392,58 +392,59 @@ cleuHandler = function()
-- ========================================================================
elseif sub == "SPELL_HEAL" or sub == "SPELL_PERIODIC_HEAL" then
local spellName = arg7 or "Unknown"
local amount = arg9 or 0
local overheal = arg10 or 0
local critical = arg12 == 1 and 1 or 0
local hit = critical == 0 and 1 or 0
local _, _, _, _, _, _, _, _, _,
spellId, spellName, spellSchool,
amount, overheal, absorbed, critical = CombatLogGetCurrentEventInfo()
local crit = critical and 1 or 0
local hit = crit == 0 and 1 or 0
local effective = amount - overheal
if effective < 0 then effective = 0 end
DB:Healing(1, DPSMateHealingTaken, srcName, spellName, hit, critical, effective)
DB:Healing(2, DPSMateOverhealing, srcName, spellName, hit, critical, overheal)
DB:HealingTaken(1, DPSMateHealingTaken, srcName, spellName, hit, critical, effective, dstName)
DB:DeathHistory(dstName, srcName, spellName, effective, hit, critical, "heal", 0)
DB:Healing(1, DPSMateHealingTaken, srcName, spellName, hit, crit, effective)
DB:Healing(2, DPSMateOverhealing, srcName, spellName, hit, crit, overheal)
DB:HealingTaken(1, DPSMateHealingTaken, srcName, spellName, hit, crit, effective, dstName)
DB:DeathHistory(dstName, srcName, spellName, effective, hit, crit, "heal", 0)
-- ========================================================================
-- AURA events (+ absorb shield lifecycle)
-- ========================================================================
elseif sub == "SPELL_AURA_APPLIED" then
local spellName = arg7 or "Unknown"
local auraType = arg9
local _, _, _, _, _, _, _, _, _,
spellId, spellName, spellSchool, auraType = CombatLogGetCurrentEventInfo()
spellName = spellName or "Unknown"
if auraType == "DEBUFF" then
DB:BuildBuffs(srcName, dstName, spellName, false)
if Parser.CC[spellName] then
DB:BuildActiveCC(dstName, spellName)
end
-- Avoidable debuff application
if FailDB and FailDB[spellName] then
DB:BuildFail(3, "Environment", dstName, spellName, 0)
end
else
DB:BuildBuffs(srcName, dstName, spellName, true)
-- Absorb shield applied
if ShieldFlags[spellName] then
DB:ConfirmAbsorbApplication(spellName, dstName, GT())
end
end
elseif sub == "SPELL_AURA_REMOVED" then
local spellName = arg7 or "Unknown"
local _, _, _, _, _, _, _, _, _,
spellId, spellName, spellSchool, auraType = CombatLogGetCurrentEventInfo()
spellName = spellName or "Unknown"
DB:DestroyBuffs(dstName, spellName)
local auraType = arg9
if auraType == "DEBUFF" then
DB:RemoveActiveCC(dstName, spellName)
else
-- Absorb shield removed
if ShieldFlags[spellName] then
DB:UnregisterAbsorb(spellName, dstName)
end
end
elseif sub == "SPELL_AURA_BROKEN_SPELL" or sub == "SPELL_AURA_BROKEN" then
local spellName = arg7 or "Unknown"
local _, _, _, _, _, _, _, _, _,
spellId, spellName = CombatLogGetCurrentEventInfo()
spellName = spellName or "Unknown"
DB:RemoveActiveCC(dstName, spellName)
if Parser.CC[spellName] then
DB:CCBreaker(dstName, spellName, srcName)
@@ -454,11 +455,12 @@ cleuHandler = function()
-- ========================================================================
elseif sub == "SPELL_CAST_SUCCESS" then
local spellName = arg7 or "Unknown"
local _, _, _, _, _, _, _, _, _,
spellId, spellName = CombatLogGetCurrentEventInfo()
spellName = spellName or "Unknown"
if Parser.Kicks and Parser.Kicks[spellName] then
DB:RegisterPotentialKick(srcName, spellName, GT())
end
-- Shield cast → await confirmation via SPELL_AURA_APPLIED
if ShieldFlags[spellName] then
DB:AwaitingAbsorbConfirmation(srcName, spellName, dstName, GT())
end
@@ -468,13 +470,19 @@ cleuHandler = function()
-- ========================================================================
elseif sub == "SPELL_INTERRUPT" then
local spellName = arg7 or "Unknown"
local extraSpellName = arg10 or "Unknown"
local _, _, _, _, _, _, _, _, _,
spellId, spellName, spellSchool,
extraSpellId, extraSpellName = CombatLogGetCurrentEventInfo()
spellName = spellName or "Unknown"
extraSpellName = extraSpellName or "Unknown"
DB:Kick(srcName, dstName, spellName, extraSpellName)
elseif sub == "SPELL_DISPEL" then
local spellName = arg7 or "Unknown"
local extraSpellName = arg10 or "Unknown"
local _, _, _, _, _, _, _, _, _,
spellId, spellName, spellSchool,
extraSpellId, extraSpellName = CombatLogGetCurrentEventInfo()
spellName = spellName or "Unknown"
extraSpellName = extraSpellName or "Unknown"
if isGroupMember(srcName) then
DB:Dispels(srcName, spellName, dstName, extraSpellName)
end
+415 -189
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -111,6 +111,7 @@ fn registerLuaFunctions() void {
}
if (build_opts.dpslog) {
registerFunction("GetSpellInfo", @intFromPtr(&dpslog.luaGetSpellInfo));
registerFunction("CombatLogGetCurrentEventInfo", @intFromPtr(&dpslog.luaCombatLogGetCurrentEventInfo));
}
if (build_opts.addonperf) {
registerFunction("GetAddOnMemoryUsage", @intFromPtr(&addonperf.luaGetAddOnMemoryUsage));