dpslog: damage shield spell ID, unique chat handlers
- DAMAGE_SHIELD now resolves spell ID by scanning the victim's (shield owner's) aura descriptors for SPELL_AURA_DAMAGE_SHIELD (effect 15) matching the packet school. Uses new deferred cleuDamageShieldSpell buffer entry resolved lazily at CombatLogGetCurrentEventInfo time. - Fix: scan victim's auras, not attacker's — the shield aura (Thorns, Retribution Aura) is on the unit being hit, not the one hitting. - DPSLog addon: every unique subevent now has its own chat handler with correct name. Factory functions replace shared handlers that were printing wrong subevent names (e.g. "SPELL_DAMAGE" for all damage types). - Remove CombatLogGetCurrentEventInfo rdtsc profiling (measured ~12k cycles/call = ~4us, negligible).
This commit is contained in:
@@ -46,112 +46,110 @@ local function displayName(name, guid)
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
-- Arg position constants -- WotLK CLEU parity
|
||||
-- Arg position constants -- CombatLogGetCurrentEventInfo() layout
|
||||
-- ============================================================================
|
||||
|
||||
-- Base: arg1=subevent, arg2=srcGUID, arg3=srcName, arg4=dstGUID, arg5=dstName
|
||||
-- Spell prefix events: arg6=spellId, arg7=spellName, arg8=spellSchool
|
||||
-- Suffix starts at arg9 for spell-prefix events
|
||||
-- Swing events: suffix starts at arg6 (no prefix)
|
||||
-- Env events: arg6=envType, suffix starts at arg7
|
||||
|
||||
-- _DAMAGE suffix (9 fields): amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing
|
||||
-- Spell damage: arg6-8=prefix, arg9-17=suffix
|
||||
-- Swing damage: arg6-14=suffix
|
||||
-- Env damage: arg6=envType, arg7-15=suffix
|
||||
|
||||
-- CombatLogGetCurrentEventInfo() returns:
|
||||
-- sub, srcGUID, srcName, srcFlags, srcRaidFlags,
|
||||
-- dstGUID, dstName, dstFlags, dstRaidFlags, p1, p2, p3, ...
|
||||
--
|
||||
-- p1.. positions (after 9 base fields):
|
||||
-- Spell prefix: p1=spellId, p2=spellName, p3=spellSchool, p4+=suffix
|
||||
-- Swing prefix: (none) p1+=suffix
|
||||
-- Env prefix: p1=envType, p2+=suffix
|
||||
--
|
||||
-- _DAMAGE suffix: amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing
|
||||
-- Spell: p4-p12 Swing: p1-p9 Env: p2-p10
|
||||
-- _MISSED suffix: missType, amountMissed
|
||||
-- Spell missed: arg6-8=prefix, arg9=missType, arg10=amountMissed
|
||||
-- Swing missed: arg6=missType, arg7=amountMissed
|
||||
|
||||
-- Spell: p4-p5 Swing: p1-p2
|
||||
-- _HEAL suffix: amount, overheal, absorbed, critical
|
||||
-- arg6-8=prefix, arg9-12=suffix
|
||||
|
||||
-- Spell: p4-p7
|
||||
-- _ENERGIZE suffix: amount, powerType
|
||||
-- arg6-8=prefix, arg9-10=suffix
|
||||
|
||||
-- Spell: p4-p5
|
||||
-- _LEECH/_DRAIN suffix: amount, powerType, extraAmount
|
||||
-- arg6-8=prefix, arg9-11=suffix
|
||||
|
||||
-- Spell: p4-p6
|
||||
-- _EXTRA_ATTACKS suffix: amount
|
||||
-- arg6-8=prefix, arg9=amount
|
||||
|
||||
-- Spell: p4
|
||||
-- _INTERRUPT/_DISPEL_FAILED suffix: extraSpellId, extraSpellName, extraSchool
|
||||
-- arg6-8=prefix, arg9-11=suffix
|
||||
|
||||
-- _DISPEL/_STOLEN/_AURA_BROKEN_SPELL suffix: extraSpellId, extraSpellName, extraSchool, auraType
|
||||
-- arg6-8=prefix, arg9-12=suffix
|
||||
|
||||
-- Spell: p4-p6
|
||||
-- _DISPEL/_AURA_BROKEN_SPELL suffix: extraSpellId, extraSpellName, extraSchool, auraType
|
||||
-- Spell: p4-p7
|
||||
-- _AURA_APPLIED/REMOVED/REFRESH/BROKEN: auraType
|
||||
-- arg6-8=prefix, arg9=auraType
|
||||
|
||||
-- Spell: p4
|
||||
-- _AURA_DOSE: auraType, amount
|
||||
-- arg6-8=prefix, arg9=auraType, arg10=amount
|
||||
|
||||
-- Spell: p4-p5
|
||||
-- _CAST_FAILED: failedType
|
||||
-- arg6-8=prefix, arg9=failedType
|
||||
-- Spell: p4
|
||||
|
||||
-- ============================================================================
|
||||
-- Subevent definitions -- variant checklist
|
||||
-- ============================================================================
|
||||
|
||||
-- { displayName, subevent, [variantField], [variantValue] }
|
||||
-- Variant field indices are positions in the full CombatLogGetCurrentEventInfo() return:
|
||||
-- 1=sub, 2=srcGUID, 3=srcName, 4=srcFlags, 5=srcRaidFlags,
|
||||
-- 6=dstGUID, 7=dstName, 8=dstFlags, 9=dstRaidFlags,
|
||||
-- 10=p1, 11=p2, 12=p3, 13=p4, 14=p5, 15=p6, 16=p7, 17=p8, 18=p9, ...
|
||||
-- Spell prefix: p1(10)=spellId, p2(11)=spellName, p3(12)=spellSchool
|
||||
-- Swing prefix: (none), p1(10) is first suffix field
|
||||
-- Env prefix: p1(10)=envType
|
||||
|
||||
local SUBEVENTS = {
|
||||
-- Damage (spell prefix: arg9=amount ... arg15=critical, arg16=glancing, arg17=crushing)
|
||||
-- Spell damage: p10(19)=critical
|
||||
{ "SPELL_DAMAGE", "SPELL_DAMAGE" },
|
||||
{ "SPELL_DAMAGE (crit)", "SPELL_DAMAGE", 15, 1 },
|
||||
{ "SPELL_DAMAGE (crit)", "SPELL_DAMAGE", 19 }, -- p10=critical (truthy)
|
||||
{ "RANGE_DAMAGE", "RANGE_DAMAGE" },
|
||||
{ "RANGE_DAMAGE (crit)", "RANGE_DAMAGE", 15, 1 },
|
||||
{ "RANGE_DAMAGE (crit)", "RANGE_DAMAGE", 19 },
|
||||
{ "SPELL_PERIODIC_DAMAGE", "SPELL_PERIODIC_DAMAGE" },
|
||||
{ "DAMAGE_SHIELD", "DAMAGE_SHIELD" },
|
||||
{ "DAMAGE_SPLIT", "DAMAGE_SPLIT" },
|
||||
-- Swing damage: arg6=amount ... arg12=critical, arg13=glancing, arg14=crushing
|
||||
-- Swing damage: p7(16)=critical, p8(17)=glancing, p9(18)=crushing
|
||||
{ "SWING_DAMAGE", "SWING_DAMAGE" },
|
||||
{ "SWING_DAMAGE (crit)", "SWING_DAMAGE", 12, 1 },
|
||||
{ "SWING_DAMAGE (glancing)", "SWING_DAMAGE", 13, 1 },
|
||||
{ "SWING_DAMAGE (crushing)", "SWING_DAMAGE", 14, 1 },
|
||||
-- Env damage: arg6=envType, arg7=amount ... arg15=crushing
|
||||
{ "ENVIRONMENTAL (DROWNING)", "ENVIRONMENTAL_DAMAGE", 6, "DROWNING" },
|
||||
{ "ENVIRONMENTAL (FALLING)", "ENVIRONMENTAL_DAMAGE", 6, "FALLING" },
|
||||
{ "ENVIRONMENTAL (LAVA)", "ENVIRONMENTAL_DAMAGE", 6, "LAVA" },
|
||||
{ "ENVIRONMENTAL (SLIME)", "ENVIRONMENTAL_DAMAGE", 6, "SLIME" },
|
||||
{ "ENVIRONMENTAL (FIRE)", "ENVIRONMENTAL_DAMAGE", 6, "FIRE" },
|
||||
{ "ENVIRONMENTAL (EXHAUSTED)", "ENVIRONMENTAL_DAMAGE", 6, "EXHAUSTED" }, -- twow: no fatigue
|
||||
-- Misses -- swing: arg6=missType
|
||||
{ "SWING_MISSED (MISS)", "SWING_MISSED", 6, "MISS" },
|
||||
{ "SWING_MISSED (DODGE)", "SWING_MISSED", 6, "DODGE" },
|
||||
{ "SWING_MISSED (PARRY)", "SWING_MISSED", 6, "PARRY" },
|
||||
{ "SWING_MISSED (BLOCK)", "SWING_MISSED", 6, "BLOCK" },
|
||||
{ "SWING_MISSED (EVADE)", "SWING_MISSED", 6, "EVADE" },
|
||||
{ "SWING_MISSED (IMMUNE)", "SWING_MISSED", 6, "IMMUNE" },
|
||||
{ "SWING_MISSED (RESIST)", "SWING_MISSED", 6, "RESIST" },
|
||||
{ "SWING_MISSED (ABSORB)", "SWING_MISSED", 6, "ABSORB" },
|
||||
-- Misses -- spell: arg9=missType (after prefix)
|
||||
{ "SPELL_MISSED (MISS)", "SPELL_MISSED", 9, "MISS" },
|
||||
{ "SPELL_MISSED (DODGE)", "SPELL_MISSED", 9, "DODGE" },
|
||||
{ "SPELL_MISSED (PARRY)", "SPELL_MISSED", 9, "PARRY" },
|
||||
{ "SPELL_MISSED (IMMUNE)", "SPELL_MISSED", 9, "IMMUNE" },
|
||||
{ "SPELL_MISSED (RESIST)", "SPELL_MISSED", 9, "RESIST" },
|
||||
{ "SPELL_MISSED (ABSORB)", "SPELL_MISSED", 9, "ABSORB" },
|
||||
{ "SPELL_MISSED (DEFLECT)", "SPELL_MISSED", 9, "DEFLECT" }, -- dead in vanilla
|
||||
{ "SPELL_MISSED (REFLECT)", "SPELL_MISSED", 9, "REFLECT" },
|
||||
{ "SWING_DAMAGE (crit)", "SWING_DAMAGE", 16 },
|
||||
{ "SWING_DAMAGE (glancing)", "SWING_DAMAGE", 17 },
|
||||
{ "SWING_DAMAGE (crushing)", "SWING_DAMAGE", 18 },
|
||||
-- Env damage: p1(10)=envType
|
||||
{ "ENVIRONMENTAL (DROWNING)", "ENVIRONMENTAL_DAMAGE", 10, "DROWNING" },
|
||||
{ "ENVIRONMENTAL (FALLING)", "ENVIRONMENTAL_DAMAGE", 10, "FALLING" },
|
||||
{ "ENVIRONMENTAL (LAVA)", "ENVIRONMENTAL_DAMAGE", 10, "LAVA" },
|
||||
{ "ENVIRONMENTAL (SLIME)", "ENVIRONMENTAL_DAMAGE", 10, "SLIME" },
|
||||
{ "ENVIRONMENTAL (FIRE)", "ENVIRONMENTAL_DAMAGE", 10, "FIRE" },
|
||||
{ "ENVIRONMENTAL (EXHAUSTED)", "ENVIRONMENTAL_DAMAGE", 10, "EXHAUSTED" },
|
||||
-- Swing missed: p1(10)=missType
|
||||
{ "SWING_MISSED (MISS)", "SWING_MISSED", 10, "MISS" },
|
||||
{ "SWING_MISSED (DODGE)", "SWING_MISSED", 10, "DODGE" },
|
||||
{ "SWING_MISSED (PARRY)", "SWING_MISSED", 10, "PARRY" },
|
||||
{ "SWING_MISSED (BLOCK)", "SWING_MISSED", 10, "BLOCK" },
|
||||
{ "SWING_MISSED (EVADE)", "SWING_MISSED", 10, "EVADE" },
|
||||
{ "SWING_MISSED (IMMUNE)", "SWING_MISSED", 10, "IMMUNE" },
|
||||
{ "SWING_MISSED (RESIST)", "SWING_MISSED", 10, "RESIST" },
|
||||
{ "SWING_MISSED (ABSORB)", "SWING_MISSED", 10, "ABSORB" },
|
||||
-- Spell missed: p4(13)=missType
|
||||
{ "SPELL_MISSED (MISS)", "SPELL_MISSED", 13, "MISS" },
|
||||
{ "SPELL_MISSED (DODGE)", "SPELL_MISSED", 13, "DODGE" },
|
||||
{ "SPELL_MISSED (PARRY)", "SPELL_MISSED", 13, "PARRY" },
|
||||
{ "SPELL_MISSED (IMMUNE)", "SPELL_MISSED", 13, "IMMUNE" },
|
||||
{ "SPELL_MISSED (RESIST)", "SPELL_MISSED", 13, "RESIST" },
|
||||
{ "SPELL_MISSED (ABSORB)", "SPELL_MISSED", 13, "ABSORB" },
|
||||
{ "SPELL_MISSED (DEFLECT)", "SPELL_MISSED", 13, "DEFLECT" },
|
||||
{ "SPELL_MISSED (REFLECT)", "SPELL_MISSED", 13, "REFLECT" },
|
||||
{ "RANGE_MISSED", "RANGE_MISSED" },
|
||||
{ "SPELL_PERIODIC_MISSED", "SPELL_PERIODIC_MISSED" },
|
||||
{ "DAMAGE_SHIELD_MISSED", "DAMAGE_SHIELD_MISSED" },
|
||||
-- Heals: arg9=amount, arg10=overheal, arg11=absorbed, arg12=critical
|
||||
-- Heals: p7(16)=critical
|
||||
{ "SPELL_HEAL", "SPELL_HEAL" },
|
||||
{ "SPELL_HEAL (crit)", "SPELL_HEAL", 12, 1 },
|
||||
{ "SPELL_HEAL (crit)", "SPELL_HEAL", 16 },
|
||||
{ "SPELL_PERIODIC_HEAL", "SPELL_PERIODIC_HEAL" },
|
||||
-- Power: arg9=amount, arg10=powerType
|
||||
-- Power
|
||||
{ "SPELL_ENERGIZE", "SPELL_ENERGIZE" },
|
||||
{ "SPELL_PERIODIC_ENERGIZE", "SPELL_PERIODIC_ENERGIZE" },
|
||||
{ "SPELL_PERIODIC_DRAIN", "SPELL_PERIODIC_DRAIN" },
|
||||
{ "SPELL_PERIODIC_LEECH", "SPELL_PERIODIC_LEECH" },
|
||||
-- Auras: arg9=auraType
|
||||
{ "SPELL_AURA_APPLIED (BUFF)", "SPELL_AURA_APPLIED", 9, "BUFF" },
|
||||
{ "SPELL_AURA_APPLIED (DEBUFF)", "SPELL_AURA_APPLIED", 9, "DEBUFF" },
|
||||
{ "SPELL_AURA_REMOVED (BUFF)", "SPELL_AURA_REMOVED", 9, "BUFF" },
|
||||
{ "SPELL_AURA_REMOVED (DEBUFF)", "SPELL_AURA_REMOVED", 9, "DEBUFF" },
|
||||
-- Auras: p4(13)=auraType
|
||||
{ "SPELL_AURA_APPLIED (BUFF)", "SPELL_AURA_APPLIED", 13, "BUFF" },
|
||||
{ "SPELL_AURA_APPLIED (DEBUFF)", "SPELL_AURA_APPLIED", 13, "DEBUFF" },
|
||||
{ "SPELL_AURA_REMOVED (BUFF)", "SPELL_AURA_REMOVED", 13, "BUFF" },
|
||||
{ "SPELL_AURA_REMOVED (DEBUFF)", "SPELL_AURA_REMOVED", 13, "DEBUFF" },
|
||||
{ "SPELL_AURA_APPLIED_DOSE", "SPELL_AURA_APPLIED_DOSE" },
|
||||
{ "SPELL_AURA_REMOVED_DOSE", "SPELL_AURA_REMOVED_DOSE" },
|
||||
{ "SPELL_AURA_REFRESH", "SPELL_AURA_REFRESH" },
|
||||
@@ -193,118 +191,108 @@ local seenCount = 0
|
||||
-- ============================================================================
|
||||
-- Arg formatters (summary string for tracker display)
|
||||
-- ============================================================================
|
||||
-- Formatters receive args starting from arg6 (after base: sub, srcGUID, srcName, dstGUID, dstName)
|
||||
-- Formatters receive p1..p12 (fields after the 9-field base from CombatLogGetCurrentEventInfo)
|
||||
|
||||
-- Spell-prefix damage: spellId, spellName, spellSchool, amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing
|
||||
local function fmtSpellDmg(spellId, spellName, spellSchool, amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing)
|
||||
local c = (critical == 1) and " CRIT" or ""
|
||||
local ok = (overkill and overkill >= 0) and format(" OK=%s", s(overkill)) or ""
|
||||
local g = (glancing == 1) and " GLANC" or ""
|
||||
local cr = (crushing == 1) and " CRUSH" or ""
|
||||
return format("[%s] %s amt=%s %s res=%s blk=%s abs=%s%s%s%s%s",
|
||||
s(spellId), s(spellName), s(amount), schoolName(school or 0), s(resisted), s(blocked), s(absorbed), c, ok, g, cr)
|
||||
end
|
||||
|
||||
-- Swing damage: amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing
|
||||
local function fmtSwingDmg(amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing)
|
||||
local c = (critical == 1) and " CRIT" or ""
|
||||
local ok = (overkill and overkill >= 0) and format(" OK=%s", s(overkill)) or ""
|
||||
local g = (glancing == 1) and " GLANC" or ""
|
||||
local cr = (crushing == 1) and " CRUSH" or ""
|
||||
return format("amt=%s %s res=%s blk=%s abs=%s%s%s%s%s",
|
||||
s(amount), schoolName(school or 0), s(resisted), s(blocked), s(absorbed), c, ok, g, cr)
|
||||
end
|
||||
|
||||
-- Spell prefix helper
|
||||
local function spellPrefix(spellId, spellName, spellSchool)
|
||||
return format("[%s] %s %s", s(spellId), s(spellName), schoolName(spellSchool or 0))
|
||||
end
|
||||
|
||||
local function fmtBool(v) return v and "Y" or "" end
|
||||
|
||||
local argFormatters = {}
|
||||
|
||||
-- Spell-prefix damage (args start at a6=spellId)
|
||||
argFormatters["SPELL_DAMAGE"] = function(...) return fmtSpellDmg(arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],arg[7],arg[8],arg[9],arg[10],arg[11],arg[12]) end
|
||||
-- Spell-prefix damage: p1=spellId, p2=spellName, p3=spellSchool, p4=amount, p5=overkill, p6=school, p7=resisted, p8=blocked, p9=absorbed, p10=critical, p11=glancing, p12=crushing
|
||||
argFormatters["SPELL_DAMAGE"] = function(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12)
|
||||
local ok = (p5 and p5 >= 0) and format(" OK=%s", s(p5)) or ""
|
||||
return format("%s amt=%s %s res=%s blk=%s abs=%s%s%s%s%s",
|
||||
spellPrefix(p1,p2,p3), s(p4), schoolName(p6 or 0), s(p7), s(p8), s(p9),
|
||||
p10 and " CRIT" or "", ok, p11 and " GLANC" or "", p12 and " CRUSH" or "")
|
||||
end
|
||||
argFormatters["RANGE_DAMAGE"] = argFormatters["SPELL_DAMAGE"]
|
||||
argFormatters["SPELL_PERIODIC_DAMAGE"] = argFormatters["SPELL_DAMAGE"]
|
||||
argFormatters["DAMAGE_SHIELD"] = argFormatters["SPELL_DAMAGE"]
|
||||
argFormatters["DAMAGE_SPLIT"] = argFormatters["SPELL_DAMAGE"]
|
||||
|
||||
-- Swing damage (no prefix, args start at a6=amount)
|
||||
argFormatters["SWING_DAMAGE"] = function(...) return fmtSwingDmg(arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],arg[7],arg[8],arg[9]) end
|
||||
|
||||
-- Env damage: a6=envType, a7-a15=damage suffix
|
||||
argFormatters["ENVIRONMENTAL_DAMAGE"] = function(...)
|
||||
local ok = (arg[3] and arg[3] >= 0) and format(" OK=%s", s(arg[3])) or ""
|
||||
return format("env=%s amt=%s %s abs=%s%s", s(arg[1]), s(arg[2]), schoolName(arg[4] or 0), s(arg[7]), ok)
|
||||
-- Swing damage: p1=amount, p2=overkill, p3=school, p4=resisted, p5=blocked, p6=absorbed, p7=critical, p8=glancing, p9=crushing
|
||||
argFormatters["SWING_DAMAGE"] = function(p1,p2,p3,p4,p5,p6,p7,p8,p9)
|
||||
local ok = (p2 and p2 >= 0) and format(" OK=%s", s(p2)) or ""
|
||||
return format("amt=%s %s res=%s blk=%s abs=%s%s%s%s%s",
|
||||
s(p1), schoolName(p3 or 0), s(p4), s(p5), s(p6),
|
||||
p7 and " CRIT" or "", ok, p8 and " GLANC" or "", p9 and " CRUSH" or "")
|
||||
end
|
||||
|
||||
-- Swing missed: a6=missType, a7=amountMissed
|
||||
argFormatters["SWING_MISSED"] = function(...) return format("%s amt=%s", s(arg[1]), s(arg[2])) end
|
||||
-- Env damage: p1=envType, p2=amount, p3=overkill, p4=school, p5=resisted, p6=blocked, p7=absorbed
|
||||
argFormatters["ENVIRONMENTAL_DAMAGE"] = function(p1,p2,p3,p4,p5,p6,p7)
|
||||
local ok = (p3 and p3 >= 0) and format(" OK=%s", s(p3)) or ""
|
||||
return format("env=%s amt=%s %s abs=%s%s", s(p1), s(p2), schoolName(p4 or 0), s(p7), ok)
|
||||
end
|
||||
|
||||
-- Spell missed: a6-a8=prefix, a9=missType, a10=amountMissed
|
||||
argFormatters["SPELL_MISSED"] = function(...) return format("%s %s amt=%s", spellPrefix(arg[1],arg[2],arg[3]), s(arg[4]), s(arg[5])) end
|
||||
-- Swing missed: p1=missType, p2=amountMissed
|
||||
argFormatters["SWING_MISSED"] = function(p1,p2) return format("%s amt=%s", s(p1), s(p2)) end
|
||||
|
||||
-- Spell missed: p1-p3=prefix, p4=missType, p5=amountMissed
|
||||
argFormatters["SPELL_MISSED"] = function(p1,p2,p3,p4,p5) return format("%s %s amt=%s", spellPrefix(p1,p2,p3), s(p4), s(p5)) end
|
||||
argFormatters["SPELL_PERIODIC_MISSED"] = argFormatters["SPELL_MISSED"]
|
||||
argFormatters["DAMAGE_SHIELD_MISSED"] = argFormatters["SPELL_MISSED"]
|
||||
argFormatters["RANGE_MISSED"] = argFormatters["SPELL_MISSED"]
|
||||
|
||||
-- Spell heal: a6-a8=prefix, a9=amount, a10=overheal, a11=absorbed, a12=critical
|
||||
argFormatters["SPELL_HEAL"] = function(...)
|
||||
local c = (arg[7] == 1) and " CRIT" or ""
|
||||
local oh = (arg[5] and arg[5] > 0) and format(" OH=%s", s(arg[5])) or ""
|
||||
return format("%s amt=%s abs=%s%s%s", spellPrefix(arg[1],arg[2],arg[3]), s(arg[4]), s(arg[6]), c, oh)
|
||||
-- Spell heal: p1-p3=prefix, p4=amount, p5=overheal, p6=absorbed, p7=critical
|
||||
argFormatters["SPELL_HEAL"] = function(p1,p2,p3,p4,p5,p6,p7)
|
||||
local oh = (p5 and p5 > 0) and format(" OH=%s", s(p5)) or ""
|
||||
return format("%s amt=%s abs=%s%s%s", spellPrefix(p1,p2,p3), s(p4), s(p6), p7 and " CRIT" or "", oh)
|
||||
end
|
||||
argFormatters["SPELL_PERIODIC_HEAL"] = argFormatters["SPELL_HEAL"]
|
||||
|
||||
-- Spell energize: a6-a8=prefix, a9=amount, a10=powerType
|
||||
argFormatters["SPELL_ENERGIZE"] = function(...)
|
||||
return format("%s amt=%s type=%s", spellPrefix(arg[1],arg[2],arg[3]), s(arg[4]), powerNames[arg[5]] or s(arg[5]))
|
||||
-- Energize: p1-p3=prefix, p4=amount, p5=powerType
|
||||
argFormatters["SPELL_ENERGIZE"] = function(p1,p2,p3,p4,p5)
|
||||
return format("%s amt=%s type=%s", spellPrefix(p1,p2,p3), s(p4), powerNames[p5] or s(p5))
|
||||
end
|
||||
argFormatters["SPELL_PERIODIC_ENERGIZE"] = argFormatters["SPELL_ENERGIZE"]
|
||||
|
||||
-- Spell leech/drain: a6-a8=prefix, a9=amount, a10=powerType, a11=extraAmount
|
||||
argFormatters["SPELL_PERIODIC_LEECH"] = function(...)
|
||||
return format("%s amt=%s type=%s gain=%s", spellPrefix(arg[1],arg[2],arg[3]), s(arg[4]), s(arg[5]), s(arg[6]))
|
||||
-- Leech/drain: p1-p3=prefix, p4=amount, p5=powerType, p6=extraAmount
|
||||
argFormatters["SPELL_PERIODIC_LEECH"] = function(p1,p2,p3,p4,p5,p6)
|
||||
return format("%s amt=%s type=%s gain=%s", spellPrefix(p1,p2,p3), s(p4), s(p5), s(p6))
|
||||
end
|
||||
argFormatters["SPELL_PERIODIC_DRAIN"] = argFormatters["SPELL_PERIODIC_LEECH"]
|
||||
|
||||
-- Extra attacks: a6-a8=prefix, a9=amount
|
||||
argFormatters["SPELL_EXTRA_ATTACKS"] = function(...)
|
||||
return format("%s amt=%s", spellPrefix(arg[1],arg[2],arg[3]), s(arg[4]))
|
||||
-- Extra attacks: p1-p3=prefix, p4=amount
|
||||
argFormatters["SPELL_EXTRA_ATTACKS"] = function(p1,p2,p3,p4)
|
||||
return format("%s amt=%s", spellPrefix(p1,p2,p3), s(p4))
|
||||
end
|
||||
|
||||
-- Aura applied/removed/refresh/broken: a6-a8=prefix, a9=auraType
|
||||
argFormatters["SPELL_AURA_APPLIED"] = function(...) return format("%s %s", spellPrefix(arg[1],arg[2],arg[3]), s(arg[4])) end
|
||||
-- Aura: p1-p3=prefix, p4=auraType
|
||||
argFormatters["SPELL_AURA_APPLIED"] = function(p1,p2,p3,p4) return format("%s %s", spellPrefix(p1,p2,p3), s(p4)) end
|
||||
argFormatters["SPELL_AURA_REMOVED"] = argFormatters["SPELL_AURA_APPLIED"]
|
||||
argFormatters["SPELL_AURA_REFRESH"] = argFormatters["SPELL_AURA_APPLIED"]
|
||||
argFormatters["SPELL_AURA_BROKEN"] = argFormatters["SPELL_AURA_APPLIED"]
|
||||
|
||||
-- Aura dose: a6-a8=prefix, a9=auraType, a10=amount
|
||||
argFormatters["SPELL_AURA_APPLIED_DOSE"] = function(...) return format("%s %s x%s", spellPrefix(arg[1],arg[2],arg[3]), s(arg[4]), s(arg[5])) end
|
||||
-- Aura dose: p1-p3=prefix, p4=auraType, p5=stacks
|
||||
argFormatters["SPELL_AURA_APPLIED_DOSE"] = function(p1,p2,p3,p4,p5) return format("%s %s x%s", spellPrefix(p1,p2,p3), s(p4), s(p5)) end
|
||||
argFormatters["SPELL_AURA_REMOVED_DOSE"] = argFormatters["SPELL_AURA_APPLIED_DOSE"]
|
||||
|
||||
-- Cast: a6-a8=prefix only
|
||||
argFormatters["SPELL_CAST_START"] = function(...) return spellPrefix(arg[1],arg[2],arg[3]) end
|
||||
-- Cast: p1-p3=prefix only
|
||||
argFormatters["SPELL_CAST_START"] = function(p1,p2,p3) return spellPrefix(p1,p2,p3) end
|
||||
argFormatters["SPELL_CAST_SUCCESS"] = argFormatters["SPELL_CAST_START"]
|
||||
argFormatters["SPELL_SUMMON"] = argFormatters["SPELL_CAST_START"]
|
||||
argFormatters["SPELL_RESURRECT"] = argFormatters["SPELL_CAST_START"]
|
||||
argFormatters["SPELL_INSTAKILL"] = argFormatters["SPELL_CAST_START"]
|
||||
|
||||
-- Cast failed: a6-a8=prefix, a9=failedType
|
||||
argFormatters["SPELL_CAST_FAILED"] = function(...) return format("%s reason=%s", spellPrefix(arg[1],arg[2],arg[3]), s(arg[4])) end
|
||||
-- Cast failed: p1-p3=prefix, p4=failedType
|
||||
argFormatters["SPELL_CAST_FAILED"] = function(p1,p2,p3,p4) return format("%s reason=%s", spellPrefix(p1,p2,p3), s(p4)) end
|
||||
|
||||
-- Interrupt/dispel_failed: a6-a8=prefix, a9=extraSpellId, a10=extraSpellName, a11=extraSchool
|
||||
argFormatters["SPELL_INTERRUPT"] = function(...)
|
||||
return format("%s -> extra=[%s] %s %s", spellPrefix(arg[1],arg[2],arg[3]), s(arg[4]), s(arg[5]), schoolName(arg[6] or 0))
|
||||
-- Interrupt/dispel_failed: p1-p3=prefix, p4=extraSpellId, p5=extraSpellName, p6=extraSchool
|
||||
argFormatters["SPELL_INTERRUPT"] = function(p1,p2,p3,p4,p5,p6)
|
||||
return format("%s -> extra=[%s] %s %s", spellPrefix(p1,p2,p3), s(p4), s(p5), schoolName(p6 or 0))
|
||||
end
|
||||
argFormatters["SPELL_DISPEL_FAILED"] = argFormatters["SPELL_INTERRUPT"]
|
||||
|
||||
-- Dispel/stolen/aura_broken_spell: a6-a8=prefix, a9=extraSpellId, a10=extraSpellName, a11=extraSchool, a12=auraType
|
||||
argFormatters["SPELL_DISPEL"] = function(...)
|
||||
return format("%s -> extra=[%s] %s %s %s", spellPrefix(arg[1],arg[2],arg[3]), s(arg[4]), s(arg[5]), schoolName(arg[6] or 0), s(arg[7]))
|
||||
-- Dispel/aura_broken_spell: p1-p3=prefix, p4=extraSpellId, p5=extraSpellName, p6=extraSchool, p7=auraType
|
||||
argFormatters["SPELL_DISPEL"] = function(p1,p2,p3,p4,p5,p6,p7)
|
||||
return format("%s -> extra=[%s] %s %s %s", spellPrefix(p1,p2,p3), s(p4), s(p5), schoolName(p6 or 0), s(p7))
|
||||
end
|
||||
argFormatters["SPELL_AURA_BROKEN_SPELL"] = argFormatters["SPELL_DISPEL"]
|
||||
|
||||
-- Base (no args)
|
||||
-- Base (no suffix args)
|
||||
argFormatters["UNIT_DIED"] = function() return "" end
|
||||
argFormatters["PARTY_KILL"] = function() return "" end
|
||||
argFormatters["UNIT_DESTROYED"] = function() return "" end
|
||||
@@ -314,157 +302,159 @@ argFormatters["UNIT_DESTROYED"] = function() return "" end
|
||||
-- ============================================================================
|
||||
-- All chatHandlers receive: (src, srcName, dst, dstName, ...) where ... starts at arg6
|
||||
|
||||
-- chatHandlers receive: (srcName, dstName, p1, p2, ...) where p1.. are the suffix fields from CombatLogGetCurrentEventInfo
|
||||
|
||||
local chatHandlers = {}
|
||||
|
||||
-- Spell damage: src, srcName, dst, dstName, spellId, spellName, spellSchool, amount, overkill, school, resisted, blocked, absorbed, critical
|
||||
chatHandlers["SPELL_DAMAGE"] = function(src, srcName, dst, dstName, spellId, spellName, spellSchool, amount, overkill, school, resisted, blocked, absorbed, critical)
|
||||
local crit = critical == 1 and " (CRIT)" or ""
|
||||
local ok = (overkill and overkill >= 0) and format(" (OK %d)", overkill) or ""
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffff0000SPELL_DAMAGE|r %s -> %s: %s[%d] for %d %s%s%s", displayName(srcName, src), displayName(dstName, dst), spellName or "", spellId, amount, schoolName(school), crit, ok))
|
||||
-- Spell damage: p1=spellId, p2=spellName, p3=spellSchool, p4=amount, p5=overkill, p6=school, ..., p10=critical
|
||||
local function spellDamageChatHandler(sub)
|
||||
return function(srcName, dstName, p1,p2,p3,p4,p5,p6,p7,p8,p9,p10)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffff0000%s|r %s -> %s: %s[%d] for %d %s%s%s",
|
||||
sub, srcName, dstName, p2 or "", p1, p4, schoolName(p6), p10 and " (CRIT)" or "",
|
||||
(p5 and p5 >= 0) and format(" (OK %d)", p5) or ""))
|
||||
end
|
||||
end
|
||||
chatHandlers["RANGE_DAMAGE"] = chatHandlers["SPELL_DAMAGE"]
|
||||
chatHandlers["DAMAGE_SPLIT"] = chatHandlers["SPELL_DAMAGE"]
|
||||
chatHandlers["SPELL_DAMAGE"] = spellDamageChatHandler("SPELL_DAMAGE")
|
||||
chatHandlers["RANGE_DAMAGE"] = spellDamageChatHandler("RANGE_DAMAGE")
|
||||
chatHandlers["DAMAGE_SPLIT"] = spellDamageChatHandler("DAMAGE_SPLIT")
|
||||
chatHandlers["SPELL_PERIODIC_DAMAGE"] = spellDamageChatHandler("SPELL_PERIODIC_DAMAGE")
|
||||
chatHandlers["DAMAGE_SHIELD"] = spellDamageChatHandler("DAMAGE_SHIELD")
|
||||
|
||||
chatHandlers["SPELL_PERIODIC_DAMAGE"] = function(src, srcName, dst, dstName, spellId, spellName, spellSchool, amount, overkill, school)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffcc0000SPELL_PERIODIC_DAMAGE|r %s -> %s: %s[%d] for %d %s", displayName(srcName, src), displayName(dstName, dst), spellName or "", spellId, amount, schoolName(school)))
|
||||
end
|
||||
|
||||
chatHandlers["DAMAGE_SHIELD"] = function(src, srcName, dst, dstName, spellId, spellName, spellSchool, amount, overkill, school)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffff4400DAMAGE_SHIELD|r %s -> %s: %d %s", displayName(srcName, src), displayName(dstName, dst), amount, schoolName(school)))
|
||||
end
|
||||
|
||||
-- Swing damage: src, srcName, dst, dstName, amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing
|
||||
chatHandlers["SWING_DAMAGE"] = function(src, srcName, dst, dstName, amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing)
|
||||
-- Swing damage: p1=amount, p2=overkill, p3=school, ..., p7=critical, p8=glancing, p9=crushing
|
||||
chatHandlers["SWING_DAMAGE"] = function(srcName, dstName, p1,p2,p3,p4,p5,p6,p7,p8,p9)
|
||||
local extra = ""
|
||||
if critical == 1 then extra = extra .. " CRIT" end
|
||||
if overkill and overkill >= 0 then extra = extra .. format(" OK=%d", overkill) end
|
||||
if glancing == 1 then extra = extra .. " GLANCING" end
|
||||
if crushing == 1 then extra = extra .. " CRUSHING" end
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffff0000SWING_DAMAGE|r %s -> %s: %d%s", displayName(srcName, src), displayName(dstName, dst), amount, extra))
|
||||
if p7 then extra = extra .. " CRIT" end
|
||||
if p2 and p2 >= 0 then extra = extra .. format(" OK=%d", p2) end
|
||||
if p8 then extra = extra .. " GLANCING" end
|
||||
if p9 then extra = extra .. " CRUSHING" end
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffff0000SWING_DAMAGE|r %s -> %s: %d%s", srcName, dstName, p1, extra))
|
||||
end
|
||||
|
||||
-- Swing missed: src, srcName, dst, dstName, missType, amountMissed
|
||||
chatHandlers["SWING_MISSED"] = function(src, srcName, dst, dstName, missType, amountMissed)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffaaaaaaSWING_MISSED|r %s -> %s: %s", displayName(srcName, src), displayName(dstName, dst), missType))
|
||||
-- Swing missed: p1=missType
|
||||
chatHandlers["SWING_MISSED"] = function(srcName, dstName, p1)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffaaaaaaSWING_MISSED|r %s -> %s: %s", srcName, dstName, p1))
|
||||
end
|
||||
|
||||
-- Spell missed: src, srcName, dst, dstName, spellId, spellName, spellSchool, missType, amountMissed
|
||||
chatHandlers["SPELL_MISSED"] = function(src, srcName, dst, dstName, spellId, spellName, spellSchool, missType, amountMissed)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffaaaaaaSPELL_MISSED|r %s -> %s: %s[%d] %s", displayName(srcName, src), displayName(dstName, dst), spellName or "", spellId, missType))
|
||||
-- Spell missed: p1-p3=prefix, p4=missType
|
||||
local function spellMissedChatHandler(sub)
|
||||
return function(srcName, dstName, p1,p2,p3,p4)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffa0a0a0%s|r %s -> %s: %s[%d] %s", sub, srcName, dstName, p2 or "", p1, p4))
|
||||
end
|
||||
end
|
||||
chatHandlers["RANGE_MISSED"] = chatHandlers["SPELL_MISSED"]
|
||||
chatHandlers["SPELL_PERIODIC_MISSED"] = chatHandlers["SPELL_MISSED"]
|
||||
chatHandlers["DAMAGE_SHIELD_MISSED"] = chatHandlers["SPELL_MISSED"]
|
||||
chatHandlers["SPELL_MISSED"] = spellMissedChatHandler("SPELL_MISSED")
|
||||
chatHandlers["RANGE_MISSED"] = spellMissedChatHandler("RANGE_MISSED")
|
||||
chatHandlers["SPELL_PERIODIC_MISSED"] = spellMissedChatHandler("SPELL_PERIODIC_MISSED")
|
||||
chatHandlers["DAMAGE_SHIELD_MISSED"] = spellMissedChatHandler("DAMAGE_SHIELD_MISSED")
|
||||
|
||||
-- Env damage: src, srcName, dst, dstName, envType, amount, overkill, school, resisted, blocked, absorbed
|
||||
chatHandlers["ENVIRONMENTAL_DAMAGE"] = function(src, srcName, dst, dstName, envType, amount)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffff8800ENVIRONMENTAL_DAMAGE|r %s: %s for %d", displayName(dstName, dst), envType, amount))
|
||||
-- Env damage: p1=envType, p2=amount
|
||||
chatHandlers["ENVIRONMENTAL_DAMAGE"] = function(srcName, dstName, p1,p2)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffff8800ENVIRONMENTAL_DAMAGE|r %s: %s for %d", dstName, p1, p2))
|
||||
end
|
||||
|
||||
-- Spell heal: src, srcName, dst, dstName, spellId, spellName, spellSchool, amount, overheal, absorbed, critical
|
||||
chatHandlers["SPELL_HEAL"] = function(src, srcName, dst, dstName, spellId, spellName, spellSchool, amount, overheal, absorbed, critical)
|
||||
local crit = critical == 1 and " (CRIT)" or ""
|
||||
local oh = (overheal and overheal > 0) and format(" (OH %d)", overheal) or ""
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff00ff00SPELL_HEAL|r %s -> %s: %s[%d] for %d%s%s", displayName(srcName, src), displayName(dstName, dst), spellName or "", spellId, amount, crit, oh))
|
||||
-- Spell heal: p1-p3=prefix, p4=amount, p5=overheal, p6=absorbed, p7=critical
|
||||
local function spellHealChatHandler(sub)
|
||||
return function(srcName, dstName, p1,p2,p3,p4,p5,p6,p7)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff00ff00%s|r %s -> %s: %s[%d] for %d%s%s",
|
||||
sub, srcName, dstName, p2 or "", p1, p4, p7 and " (CRIT)" or "",
|
||||
(p5 and p5 > 0) and format(" (OH %d)", p5) or ""))
|
||||
end
|
||||
end
|
||||
chatHandlers["SPELL_PERIODIC_HEAL"] = function(src, srcName, dst, dstName, spellId, spellName, spellSchool, amount, overheal)
|
||||
local oh = (overheal and overheal > 0) and format(" (OH %d)", overheal) or ""
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff00cc00SPELL_PERIODIC_HEAL|r %s -> %s: %s[%d] for %d%s", displayName(srcName, src), displayName(dstName, dst), spellName or "", spellId, amount, oh))
|
||||
chatHandlers["SPELL_HEAL"] = spellHealChatHandler("SPELL_HEAL")
|
||||
chatHandlers["SPELL_PERIODIC_HEAL"] = spellHealChatHandler("SPELL_PERIODIC_HEAL")
|
||||
|
||||
-- Energize: p1-p3=prefix, p4=amount, p5=powerType
|
||||
local function spellEnergizeChatHandler(sub)
|
||||
return function(srcName, dstName, p1,p2,p3,p4,p5)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff4488ff%s|r %s -> %s: %s[%d] +%d %s", sub, srcName, dstName, p2 or "", p1, p4, powerNames[p5] or "?"))
|
||||
end
|
||||
end
|
||||
chatHandlers["SPELL_ENERGIZE"] = spellEnergizeChatHandler("SPELL_ENERGIZE")
|
||||
chatHandlers["SPELL_PERIODIC_ENERGIZE"] = spellEnergizeChatHandler("SPELL_PERIODIC_ENERGIZE")
|
||||
|
||||
-- Leech: p1-p3=prefix, p4=amount, p5=powerType, p6=extraAmount
|
||||
chatHandlers["SPELL_PERIODIC_LEECH"] = function(srcName, dstName, p1,p2,p3,p4,p5,p6)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff8844ffSPELL_PERIODIC_LEECH|r %s -> %s: %s[%d] drained %d, gained %d", srcName, dstName, p2 or "", p1, p4, p6 or 0))
|
||||
end
|
||||
|
||||
-- Energize: src, srcName, dst, dstName, spellId, spellName, spellSchool, amount, powerType
|
||||
chatHandlers["SPELL_ENERGIZE"] = function(src, srcName, dst, dstName, spellId, spellName, spellSchool, amount, powerType)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff4488ffSPELL_ENERGIZE|r %s -> %s: %s[%d] +%d %s", displayName(srcName, src), displayName(dstName, dst), spellName or "", spellId, amount, powerNames[powerType] or "?"))
|
||||
end
|
||||
chatHandlers["SPELL_PERIODIC_ENERGIZE"] = function(src, srcName, dst, dstName, spellId, spellName, spellSchool, amount, powerType)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff4488ffSPELL_PERIODIC_ENERGIZE|r %s -> %s: %s[%d] +%d %s", displayName(srcName, src), displayName(dstName, dst), spellName or "", spellId, amount, powerNames[powerType] or "?"))
|
||||
-- Drain: p1-p3=prefix, p4=amount, p5=powerType
|
||||
chatHandlers["SPELL_PERIODIC_DRAIN"] = function(srcName, dstName, p1,p2,p3,p4,p5)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff8844ffSPELL_PERIODIC_DRAIN|r %s -> %s: %s[%d] drained %d %s", srcName, dstName, p2 or "", p1, p4, powerNames[p5] or "?"))
|
||||
end
|
||||
|
||||
-- Leech: src, srcName, dst, dstName, spellId, spellName, spellSchool, amount, powerType, extraAmount
|
||||
chatHandlers["SPELL_PERIODIC_LEECH"] = function(src, srcName, dst, dstName, spellId, spellName, spellSchool, amount, powerType, extraAmount)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff8844ffSPELL_PERIODIC_LEECH|r %s -> %s: %s[%d] drained %d, gained %d", displayName(srcName, src), displayName(dstName, dst), spellName or "", spellId, amount, extraAmount or 0))
|
||||
-- Aura: p1-p3=prefix, p4=auraType
|
||||
chatHandlers["SPELL_AURA_APPLIED"] = function(srcName, dstName, p1,p2,p3,p4)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff8888ffSPELL_AURA_APPLIED|r %s: %s[%d] (%s)", dstName, p2 or "", p1, p4))
|
||||
end
|
||||
chatHandlers["SPELL_AURA_REMOVED"] = function(srcName, dstName, p1,p2,p3,p4)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff6666ccSPELL_AURA_REMOVED|r %s: %s[%d] (%s)", dstName, p2 or "", p1, p4))
|
||||
end
|
||||
chatHandlers["SPELL_AURA_REFRESH"] = function(srcName, dstName, p1,p2,p3,p4)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff7777ddSPELL_AURA_REFRESH|r %s: %s[%d] (%s)", dstName, p2 or "", p1, p4))
|
||||
end
|
||||
chatHandlers["SPELL_AURA_BROKEN"] = function(srcName, dstName, p1,p2,p3,p4)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffff8800SPELL_AURA_BROKEN|r %s -> %s: %s[%d] broken (%s)", srcName, dstName, p2 or "", p1, p4))
|
||||
end
|
||||
chatHandlers["SPELL_AURA_APPLIED_DOSE"] = function(srcName, dstName, p1,p2,p3,p4,p5)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff8888ffSPELL_AURA_APPLIED_DOSE|r %s: %s[%d] x%d (%s)", dstName, p2 or "", p1, p5, p4))
|
||||
end
|
||||
chatHandlers["SPELL_AURA_REMOVED_DOSE"] = function(srcName, dstName, p1,p2,p3,p4,p5)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff6666ccSPELL_AURA_REMOVED_DOSE|r %s: %s[%d] x%d (%s)", dstName, p2 or "", p1, p5, p4))
|
||||
end
|
||||
chatHandlers["SPELL_AURA_BROKEN_SPELL"] = function(srcName, dstName, p1,p2,p3,p4,p5,p6,p7)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffff8800SPELL_AURA_BROKEN_SPELL|r %s -> %s: %s[%d] broken by %s[%d]", srcName, dstName, p2 or "", p1, p5 or "", p4))
|
||||
end
|
||||
|
||||
-- Drain: src, srcName, dst, dstName, spellId, spellName, spellSchool, amount, powerType, extraAmount
|
||||
chatHandlers["SPELL_PERIODIC_DRAIN"] = function(src, srcName, dst, dstName, spellId, spellName, spellSchool, amount, powerType, extraAmount)
|
||||
local pname = powerNames[powerType] or "?"
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff8844ffSPELL_PERIODIC_DRAIN|r %s -> %s: %s[%d] drained %d %s", displayName(srcName, src), displayName(dstName, dst), spellName or "", spellId, amount, pname))
|
||||
-- Cast: p1-p3=prefix
|
||||
chatHandlers["SPELL_CAST_START"] = function(srcName, dstName, p1,p2)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffffff00SPELL_CAST_START|r %s: %s[%d]", srcName, p2 or "", p1))
|
||||
end
|
||||
chatHandlers["SPELL_CAST_SUCCESS"] = function(srcName, dstName, p1,p2)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffffff00SPELL_CAST_SUCCESS|r %s: %s[%d]", srcName, p2 or "", p1))
|
||||
end
|
||||
chatHandlers["SPELL_CAST_FAILED"] = function(srcName, dstName, p1,p2,p3,p4)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffff4444SPELL_CAST_FAILED|r %s: %s[%d] (%s)", srcName, p2 or "", p1, p4))
|
||||
end
|
||||
|
||||
-- Aura: src, srcName, dst, dstName, spellId, spellName, spellSchool, auraType
|
||||
chatHandlers["SPELL_AURA_APPLIED"] = function(src, srcName, dst, dstName, spellId, spellName, spellSchool, auraType)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff8888ffSPELL_AURA_APPLIED|r %s: %s[%d] (%s)", displayName(dstName, dst), spellName or "", spellId, auraType))
|
||||
end
|
||||
chatHandlers["SPELL_AURA_REMOVED"] = function(src, srcName, dst, dstName, spellId, spellName, spellSchool, auraType)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff6666ccSPELL_AURA_REMOVED|r %s: %s[%d] (%s)", displayName(dstName, dst), spellName or "", spellId, auraType))
|
||||
end
|
||||
chatHandlers["SPELL_AURA_REFRESH"] = function(src, srcName, dst, dstName, spellId, spellName, spellSchool, auraType)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff7777ddSPELL_AURA_REFRESH|r %s: %s[%d] (%s)", displayName(dstName, dst), spellName or "", spellId, auraType))
|
||||
end
|
||||
chatHandlers["SPELL_AURA_BROKEN"] = function(src, srcName, dst, dstName, spellId, spellName, spellSchool, auraType)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffff8800SPELL_AURA_BROKEN|r %s -> %s: %s[%d] broken (%s)", displayName(srcName, src), displayName(dstName, dst), spellName or "", spellId, auraType))
|
||||
end
|
||||
chatHandlers["SPELL_AURA_APPLIED_DOSE"] = function(src, srcName, dst, dstName, spellId, spellName, spellSchool, auraType, stacks)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff8888ffSPELL_AURA_APPLIED_DOSE|r %s: %s[%d] x%d (%s)", displayName(dstName, dst), spellName or "", spellId, stacks, auraType))
|
||||
end
|
||||
chatHandlers["SPELL_AURA_REMOVED_DOSE"] = function(src, srcName, dst, dstName, spellId, spellName, spellSchool, auraType, stacks)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff6666ccSPELL_AURA_REMOVED_DOSE|r %s: %s[%d] x%d (%s)", displayName(dstName, dst), spellName or "", spellId, stacks, auraType))
|
||||
end
|
||||
chatHandlers["SPELL_AURA_BROKEN_SPELL"] = function(src, srcName, dst, dstName, spellId, spellName, spellSchool, extraSpellId, extraSpellName, extraSchool, auraType)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffff8800SPELL_AURA_BROKEN_SPELL|r %s -> %s: %s[%d] broken by %s[%d]", displayName(srcName, src), displayName(dstName, dst), spellName or "", spellId, extraSpellName or "", extraSpellId))
|
||||
-- Interrupt: p1-p3=prefix, p4=extraSpellId, p5=extraSpellName
|
||||
chatHandlers["SPELL_INTERRUPT"] = function(srcName, dstName, p1,p2,p3,p4,p5)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffff8800SPELL_INTERRUPT|r %s interrupted %s: %s[%d]", srcName, dstName, p5 or "", p4))
|
||||
end
|
||||
|
||||
-- Cast
|
||||
chatHandlers["SPELL_CAST_START"] = function(src, srcName, dst, dstName, spellId, spellName, spellSchool)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffffff00SPELL_CAST_START|r %s: %s[%d]", displayName(srcName, src), spellName or "", spellId))
|
||||
end
|
||||
chatHandlers["SPELL_CAST_SUCCESS"] = function(src, srcName, dst, dstName, spellId, spellName)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffffff00SPELL_CAST_SUCCESS|r %s: %s[%d]", displayName(srcName, src), spellName or "", spellId))
|
||||
end
|
||||
chatHandlers["SPELL_CAST_FAILED"] = function(src, srcName, dst, dstName, spellId, spellName, spellSchool, failedType)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffff4444SPELL_CAST_FAILED|r %s: %s[%d] (%s)", displayName(srcName, src), spellName or "", spellId, failedType))
|
||||
-- Dispel: p1-p3=prefix, p4=extraSpellId, p5=extraSpellName, p6=extraSchool, p7=auraType
|
||||
chatHandlers["SPELL_DISPEL"] = function(srcName, dstName, p1,p2,p3,p4,p5,p6,p7)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff88ffffSPELL_DISPEL|r %s dispelled %s: %s[%d] (%s)", srcName, dstName, p5 or "", p4, p7))
|
||||
end
|
||||
|
||||
-- Interrupt: src, srcName, dst, dstName, spellId, spellName, spellSchool, extraSpellId, extraSpellName, extraSchool
|
||||
chatHandlers["SPELL_INTERRUPT"] = function(src, srcName, dst, dstName, spellId, spellName, spellSchool, extraSpellId, extraSpellName, extraSchool)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffff8800SPELL_INTERRUPT|r %s interrupted %s: %s[%d]", displayName(srcName, src), displayName(dstName, dst), extraSpellName or "", extraSpellId))
|
||||
-- Dispel failed: p1-p3=prefix, p4=extraSpellId, p5=extraSpellName
|
||||
chatHandlers["SPELL_DISPEL_FAILED"] = function(srcName, dstName, p1,p2,p3,p4,p5)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff888888SPELL_DISPEL_FAILED|r %s -> %s: %s[%d] resisted", srcName, dstName, p5 or "", p4))
|
||||
end
|
||||
|
||||
-- Dispel: src, srcName, dst, dstName, spellId, spellName, spellSchool, extraSpellId, extraSpellName, extraSchool, auraType
|
||||
chatHandlers["SPELL_DISPEL"] = function(src, srcName, dst, dstName, spellId, spellName, spellSchool, extraSpellId, extraSpellName, extraSchool, auraType)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff88ffffSPELL_DISPEL|r %s dispelled %s: %s[%d] (%s)", displayName(srcName, src), displayName(dstName, dst), extraSpellName or "", extraSpellId, auraType))
|
||||
-- Extra attacks: p1-p3=prefix, p4=amount
|
||||
chatHandlers["SPELL_EXTRA_ATTACKS"] = function(srcName, dstName, p1,p2,p3,p4)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffff8800SPELL_EXTRA_ATTACKS|r %s: %s[%d] x%d", srcName, p2 or "", p1, p4))
|
||||
end
|
||||
|
||||
-- Dispel failed: src, srcName, dst, dstName, spellId, spellName, spellSchool, extraSpellId, extraSpellName, extraSchool
|
||||
chatHandlers["SPELL_DISPEL_FAILED"] = function(src, srcName, dst, dstName, spellId, spellName, spellSchool, extraSpellId, extraSpellName, extraSchool)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff888888SPELL_DISPEL_FAILED|r %s -> %s: %s[%d] resisted", displayName(srcName, src), displayName(dstName, dst), extraSpellName or "", extraSpellId))
|
||||
-- Summon/resurrect/instakill: p1-p3=prefix
|
||||
chatHandlers["SPELL_SUMMON"] = function(srcName, dstName, p1,p2)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff88ff88SPELL_SUMMON|r %s summoned %s: %s[%d]", srcName, dstName, p2 or "", p1))
|
||||
end
|
||||
|
||||
-- Extra attacks: src, srcName, dst, dstName, spellId, spellName, spellSchool, amount
|
||||
chatHandlers["SPELL_EXTRA_ATTACKS"] = function(src, srcName, dst, dstName, spellId, spellName, spellSchool, amount)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffff8800SPELL_EXTRA_ATTACKS|r %s: %s[%d] x%d", displayName(srcName, src), spellName or "", spellId, amount))
|
||||
chatHandlers["SPELL_RESURRECT"] = function(srcName, dstName, p1,p2)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff88ff88SPELL_RESURRECT|r %s resurrected %s: %s[%d]", srcName, dstName, p2 or "", p1))
|
||||
end
|
||||
|
||||
-- Summon/resurrect/instakill
|
||||
chatHandlers["SPELL_SUMMON"] = function(src, srcName, dst, dstName, spellId, spellName)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff88ff88SPELL_SUMMON|r %s summoned %s: %s[%d]", displayName(srcName, src), displayName(dstName, dst), spellName or "", spellId))
|
||||
end
|
||||
chatHandlers["SPELL_RESURRECT"] = function(src, srcName, dst, dstName, spellId, spellName)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff88ff88SPELL_RESURRECT|r %s resurrected %s: %s[%d]", displayName(srcName, src), displayName(dstName, dst), spellName or "", spellId))
|
||||
end
|
||||
chatHandlers["SPELL_INSTAKILL"] = function(src, srcName, dst, dstName, spellId, spellName)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffff0000SPELL_INSTAKILL|r %s killed %s: %s[%d]", displayName(srcName, src), displayName(dstName, dst), spellName or "", spellId))
|
||||
chatHandlers["SPELL_INSTAKILL"] = function(srcName, dstName, p1,p2)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffff0000SPELL_INSTAKILL|r %s killed %s: %s[%d]", srcName, dstName, p2 or "", p1))
|
||||
end
|
||||
|
||||
-- Deaths
|
||||
chatHandlers["UNIT_DIED"] = function(src, srcName, dst, dstName)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff888888UNIT_DIED|r %s", displayName(dstName, dst)))
|
||||
chatHandlers["UNIT_DIED"] = function(srcName, dstName)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff888888UNIT_DIED|r %s", dstName))
|
||||
end
|
||||
chatHandlers["PARTY_KILL"] = function(src, srcName, dst, dstName)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffff8800PARTY_KILL|r %s killed %s", displayName(srcName, src), displayName(dstName, dst)))
|
||||
chatHandlers["PARTY_KILL"] = function(srcName, dstName)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cffff8800PARTY_KILL|r %s killed %s", srcName, dstName))
|
||||
end
|
||||
chatHandlers["UNIT_DESTROYED"] = function(src, srcName, dst, dstName)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff666666UNIT_DESTROYED|r %s", displayName(dstName, dst)))
|
||||
chatHandlers["UNIT_DESTROYED"] = function(srcName, dstName)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(format("|cff666666UNIT_DESTROYED|r %s", dstName))
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
@@ -589,20 +579,28 @@ end)
|
||||
-- Event dispatcher
|
||||
-- ============================================================================
|
||||
|
||||
-- Expand args table to handle up to 17 args (spell damage has the most: 5 base + 3 prefix + 9 suffix)
|
||||
local eventFrame = CreateFrame("Frame")
|
||||
eventFrame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
|
||||
|
||||
eventFrame:SetScript("OnEvent", function()
|
||||
local subevent = arg1
|
||||
if not subevent then return end
|
||||
if not CombatLogGetCurrentEventInfo then return end
|
||||
local sub, srcGUID, srcName, srcFlags, srcRaidFlags,
|
||||
dstGUID, dstName, dstFlags, dstRaidFlags,
|
||||
p1, p2, p3, p4, p5, p6, p7, p8, p9,
|
||||
p10, p11, p12 = CombatLogGetCurrentEventInfo()
|
||||
if not sub then return end
|
||||
|
||||
local args = { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,
|
||||
arg11, arg12, arg13, arg14, arg15, arg16, arg17 }
|
||||
if not srcName or srcName == "" then srcName = "Unknown" end
|
||||
if not dstName or dstName == "" then dstName = "Unknown" end
|
||||
|
||||
local indices = subeventIndices[subevent]
|
||||
local indices = subeventIndices[sub]
|
||||
if not indices then return end
|
||||
|
||||
-- Build full args array for variant field checks (1-based, matching CombatLogGetCurrentEventInfo positions)
|
||||
local args = { sub, srcGUID, srcName, srcFlags, srcRaidFlags,
|
||||
dstGUID, dstName, dstFlags, dstRaidFlags,
|
||||
p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12 }
|
||||
|
||||
local any_new = false
|
||||
for _, idx in ipairs(indices) do
|
||||
if not seen[idx] then
|
||||
@@ -612,26 +610,28 @@ eventFrame:SetScript("OnEvent", function()
|
||||
|
||||
local matches = true
|
||||
if varField then
|
||||
matches = (args[varField] == varValue)
|
||||
if varValue then
|
||||
matches = (args[varField] == varValue)
|
||||
else
|
||||
-- Boolean check (truthy): critical, glancing, crushing
|
||||
matches = (args[varField] ~= nil)
|
||||
end
|
||||
end
|
||||
|
||||
if matches then
|
||||
seen[idx] = true
|
||||
seenCount = seenCount + 1
|
||||
local formatter = argFormatters[subevent]
|
||||
local formatter = argFormatters[sub]
|
||||
if formatter then
|
||||
-- Pass args starting from arg6 (after base: sub, srcGUID, srcName, dstGUID, dstName)
|
||||
seenArgs[idx] = formatter(arg6, arg7, arg8, arg9, arg10, arg11, arg12,
|
||||
arg13, arg14, arg15, arg16, arg17)
|
||||
seenArgs[idx] = formatter(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12)
|
||||
else
|
||||
seenArgs[idx] = ""
|
||||
end
|
||||
any_new = true
|
||||
|
||||
local chatHandler = chatHandlers[subevent]
|
||||
local chatHandler = chatHandlers[sub]
|
||||
if chatHandler then
|
||||
chatHandler(arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,
|
||||
arg11, arg12, arg13, arg14, arg15, arg16, arg17)
|
||||
chatHandler(srcName, dstName, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
+72
-5
@@ -148,6 +148,46 @@ fn clearAuraCaster(unit: u64, slot: u32) void {
|
||||
}
|
||||
}
|
||||
|
||||
/// Scan a unit's aura slots for a damage shield spell matching the given school.
|
||||
/// Returns the spell ID or 0 if not found.
|
||||
/// SPELL_AURA_DAMAGE_SHIELD = 15 in EffectApplyAuraName.
|
||||
const AURA_DAMAGE_SHIELD: u32 = 15;
|
||||
const EFFECT_APPLY_AURA_NAME_BASE: u32 = 0x16C; // EffectApplyAuraName[0] in SpellRec
|
||||
|
||||
fn findDamageShieldSpell(attacker_guid: u64, school: u32) u32 {
|
||||
// Need the attacker's object to read aura descriptors.
|
||||
// This runs during packet handler processing (not aura callbacks),
|
||||
// but name resolution is deferred. We can safely look up the object here
|
||||
// since this is a table-swapped handler (object manager is stable).
|
||||
const obj = wow.getObjectByGUID(attacker_guid);
|
||||
if (obj == 0) return 0;
|
||||
const desc = wow.getDescriptor(obj);
|
||||
if (desc == 0) return 0;
|
||||
|
||||
// UNIT_FIELD_AURA: 48 spell IDs at descriptor offset 0xA4 (index 0x29 from OBJECT_END=0x06)
|
||||
const AURA_BASE: u32 = 0xA4;
|
||||
var slot: u32 = 0;
|
||||
while (slot < 48) : (slot += 1) {
|
||||
const spell_id = hook.readMem(u32, desc + AURA_BASE + slot * 4);
|
||||
if (spell_id == 0) continue;
|
||||
|
||||
// Check if this spell has a DAMAGE_SHIELD aura effect matching the school
|
||||
if (getSpellRecord(spell_id)) |rec| {
|
||||
const spell_school = hook.readMem(u32, rec + 0x04); // SpellRec.School
|
||||
// School match: packet school should match the spell's school
|
||||
if (spell_school & school != 0 or spell_school == school) {
|
||||
// Check EffectApplyAuraName[0..2] for DAMAGE_SHIELD (15)
|
||||
var eff: u32 = 0;
|
||||
while (eff < 3) : (eff += 1) {
|
||||
const aura_name = hook.readMem(u32, rec + EFFECT_APPLY_AURA_NAME_BASE + eff * 4);
|
||||
if (aura_name == AURA_DAMAGE_SHIELD) return spell_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// SpellRec AuraInterruptFlags offset and damage-break bits.
|
||||
const SPELL_AURA_INTERRUPT_FLAGS_OFFSET: u32 = 0x58;
|
||||
const AURA_INTERRUPT_FLAG_DAMAGE: u32 = 0x02;
|
||||
@@ -663,12 +703,18 @@ fn boolToLua(val: u32) u32 {
|
||||
// and spell lookups happen lazily in luaCombatLogGetCurrentEventInfo() when
|
||||
// addons request the data — at which point the object manager is stable.
|
||||
|
||||
const CLEUArgType = enum { str, num, bool_val, nil, guid, spell_id };
|
||||
const CLEUArgType = enum { str, num, bool_val, nil, guid, spell_id, damage_shield_spell };
|
||||
|
||||
const DamageShieldKey = struct {
|
||||
attacker_guid: u64,
|
||||
school: u32,
|
||||
};
|
||||
|
||||
const CLEUArg = union {
|
||||
str: [*:0]const u8,
|
||||
num: u32,
|
||||
guid: u64, // resolved to GUID string + name + flags + raidFlags (4 pushes)
|
||||
guid: u64,
|
||||
ds_key: DamageShieldKey,
|
||||
nil: void,
|
||||
};
|
||||
|
||||
@@ -723,6 +769,15 @@ fn cleuSpellId(id: u32) void {
|
||||
g_cleu_count += 1;
|
||||
}
|
||||
|
||||
/// Store a damage shield spell lookup key. At request time, scans attacker's
|
||||
/// auras for a DAMAGE_SHIELD effect matching the school, then pushes:
|
||||
/// spellId, spellName, spellSchool (3 values)
|
||||
fn cleuDamageShieldSpell(attacker_guid: u64, school: u32) void {
|
||||
if (g_cleu_count >= MAX_CLEU_ARGS) return;
|
||||
g_cleu_args[g_cleu_count] = .{ .arg = .{ .ds_key = .{ .attacker_guid = attacker_guid, .school = school } }, .typ = .damage_shield_spell };
|
||||
g_cleu_count += 1;
|
||||
}
|
||||
|
||||
/// Store base args: subevent, srcGUID (deferred), dstGUID (deferred)
|
||||
fn cleuBase(sub: [*:0]const u8, src_guid: u64, dst_guid: u64) void {
|
||||
cleuReset();
|
||||
@@ -783,6 +838,15 @@ pub fn luaCombatLogGetCurrentEventInfo(L: usize) callconv(hook.cc.fastcall) u32
|
||||
lua.pushnumber(state, @floatFromInt(getSpellSchool(id)));
|
||||
push_count += 3;
|
||||
},
|
||||
.damage_shield_spell => {
|
||||
// Deferred damage shield: scan attacker auras, push spellId, spellName, spellSchool
|
||||
const key = entry.arg.ds_key;
|
||||
const id = findDamageShieldSpell(key.attacker_guid, key.school);
|
||||
lua.pushnumber(state, @floatFromInt(id));
|
||||
lua.pushstring(state, getSpellName(id));
|
||||
lua.pushnumber(state, @floatFromInt(if (id != 0) getSpellSchool(id) else key.school));
|
||||
push_count += 3;
|
||||
},
|
||||
}
|
||||
}
|
||||
return push_count;
|
||||
@@ -1463,9 +1527,12 @@ fn damageShieldDetour(unk: u32, opcode: u32, unk2: u32, cds: u32) callconv(hook.
|
||||
victim_guid.? != 0 and attacker_guid.? != 0)
|
||||
{
|
||||
const overkill = computeOverkill(victim_guid.?, damage.?);
|
||||
log.fmt("DAMAGE_SHIELD: dmg={d} school={d}\n", .{ damage.?, school.? });
|
||||
// No spellId in SMSG_SPELLDAMAGESHIELD packet — pass 0
|
||||
fireSpellDamage(SUB_DAMAGE_SHIELD, attacker_guid.?, victim_guid.?, 0, damage.?, overkill, school.?, 0, 0, 0, 0, 0, 0);
|
||||
// Build CLEU buffer directly — spell prefix is deferred via damage_shield_spell
|
||||
cleuBase(SUB_DAMAGE_SHIELD, attacker_guid.?, victim_guid.?);
|
||||
cleuDamageShieldSpell(victim_guid.?, school.?);
|
||||
cleuNum(damage.?); cleuNum(overkill); cleuNum(school.?); cleuNum(0);
|
||||
cleuNum(0); cleuNum(0); cleuBool(0); cleuBool(0); cleuBool(0);
|
||||
signalEvent();
|
||||
}
|
||||
|
||||
return callOriginalHandler(0x24F, unk, opcode, unk2, cds);
|
||||
|
||||
Reference in New Issue
Block a user