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:
+16
-4
@@ -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`
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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)))
|
||||
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user