更新发送到功能

更新仇恨计算方式 还在开发
更新其他细节
This commit is contained in:
rucky
2026-03-23 10:26:31 +08:00
commit 5c3f2243c4
26 changed files with 6080 additions and 0 deletions

465
ParserVanilla.lua Normal file
View File

@@ -0,0 +1,465 @@
local NanamiDPS = NanamiDPS
local Parser = NanamiDPS.Parser
-- Pattern utility functions (from ShaguDPS)
local sanitize_cache = {}
local function sanitize(pattern)
if not sanitize_cache[pattern] then
local ret = pattern
ret = gsub(ret, "([%+%-%*%(%)%?%[%]%^])", "%%%1")
ret = gsub(ret, "%d%$", "")
ret = gsub(ret, "(%%%a)", "%(%1+%)")
ret = gsub(ret, "%%s%+", ".+")
ret = gsub(ret, "%(.%+%)%(%%d%+%)", "%(.-%)%(%%d%+%)")
sanitize_cache[pattern] = ret
end
return sanitize_cache[pattern]
end
local capture_cache = {}
local function captures(pat)
local r = capture_cache
if not r[pat] then
r[pat] = { nil, nil, nil, nil, nil }
for a, b, c, d, e in string.gfind(gsub(pat, "%((.+)%)", "%1"), gsub(pat, "%d%$", "%%(.-)$")) do
r[pat][1] = tonumber(a)
r[pat][2] = tonumber(b)
r[pat][3] = tonumber(c)
r[pat][4] = tonumber(d)
r[pat][5] = tonumber(e)
end
end
return r[pat][1], r[pat][2], r[pat][3], r[pat][4], r[pat][5]
end
local ra, rb, rc, rd, re, a, b, c, d, e, match, num, va, vb, vc, vd, ve
local function cfind(str, pat)
a, b, c, d, e = captures(pat)
match, num, va, vb, vc, vd, ve = string.find(str, sanitize(pat))
ra = e == 1 and ve or d == 1 and vd or c == 1 and vc or b == 1 and vb or va
rb = e == 2 and ve or d == 2 and vd or c == 2 and vc or a == 2 and va or vb
rc = e == 3 and ve or d == 3 and vd or a == 3 and va or b == 3 and vb or vc
rd = e == 4 and ve or a == 4 and va or c == 4 and vc or b == 4 and vb or vd
re = a == 5 and va or d == 5 and vd or c == 5 and vc or b == 5 and vb or ve
return match, num, ra, rb, rc, rd, re
end
-----------------------------------------------------------------------
-- Combat log string groups
-----------------------------------------------------------------------
local combatlog_strings = {
-- Damage: melee
["Hit Damage (self vs. other)"] = {
COMBATHITSELFOTHER, COMBATHITSCHOOLSELFOTHER,
COMBATHITCRITSELFOTHER, COMBATHITCRITSCHOOLSELFOTHER,
},
["Hit Damage (other vs. self)"] = {
COMBATHITOTHERSELF, COMBATHITCRITOTHERSELF,
COMBATHITSCHOOLOTHERSELF, COMBATHITCRITSCHOOLOTHERSELF,
},
["Hit Damage (other vs. other)"] = {
COMBATHITOTHEROTHER, COMBATHITCRITOTHEROTHER,
COMBATHITSCHOOLOTHEROTHER, COMBATHITCRITSCHOOLOTHEROTHER,
},
-- Damage: spell
["Spell Damage (self vs. self/other)"] = {
SPELLLOGSCHOOLSELFSELF, SPELLLOGCRITSCHOOLSELFSELF,
SPELLLOGSELFSELF, SPELLLOGCRITSELFSELF,
SPELLLOGSCHOOLSELFOTHER, SPELLLOGCRITSCHOOLSELFOTHER,
SPELLLOGSELFOTHER, SPELLLOGCRITSELFOTHER,
},
["Spell Damage (other vs. self)"] = {
SPELLLOGSCHOOLOTHERSELF, SPELLLOGCRITSCHOOLOTHERSELF,
SPELLLOGOTHERSELF, SPELLLOGCRITOTHERSELF,
},
["Spell Damage (other vs. other)"] = {
SPELLLOGSCHOOLOTHEROTHER, SPELLLOGCRITSCHOOLOTHEROTHER,
SPELLLOGOTHEROTHER, SPELLLOGCRITOTHEROTHER,
},
-- Damage: shields
["Shield Damage (self vs. other)"] = {
DAMAGESHIELDSELFOTHER,
},
["Shield Damage (other vs. self/other)"] = {
DAMAGESHIELDOTHERSELF, DAMAGESHIELDOTHEROTHER,
},
-- Damage: periodic
["Periodic Damage (self/other vs. other)"] = {
PERIODICAURADAMAGESELFOTHER, PERIODICAURADAMAGEOTHEROTHER,
},
["Periodic Damage (self/other vs. self)"] = {
PERIODICAURADAMAGESELFSELF, PERIODICAURADAMAGEOTHERSELF,
},
-- Healing
["Heal (self vs. self/other)"] = {
HEALEDCRITSELFSELF, HEALEDSELFSELF,
HEALEDCRITSELFOTHER, HEALEDSELFOTHER,
},
["Heal (other vs. self/other)"] = {
HEALEDCRITOTHERSELF, HEALEDOTHERSELF,
HEALEDCRITOTHEROTHER, HEALEDOTHEROTHER,
},
["Periodic Heal (self/other vs. other)"] = {
PERIODICAURAHEALSELFOTHER, PERIODICAURAHEALOTHEROTHER,
},
["Periodic Heal (other vs. self/other)"] = {
PERIODICAURAHEALSELFSELF, PERIODICAURAHEALOTHERSELF,
},
}
-----------------------------------------------------------------------
-- Event -> pattern mapping
-----------------------------------------------------------------------
local combatlog_events = {
-- Damage: melee
["CHAT_MSG_COMBAT_SELF_HITS"] = combatlog_strings["Hit Damage (self vs. other)"],
["CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS"] = combatlog_strings["Hit Damage (other vs. self)"],
["CHAT_MSG_COMBAT_PARTY_HITS"] = combatlog_strings["Hit Damage (other vs. other)"],
["CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS"] = combatlog_strings["Hit Damage (other vs. other)"],
["CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS"] = combatlog_strings["Hit Damage (other vs. other)"],
["CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_HITS"] = combatlog_strings["Hit Damage (other vs. other)"],
["CHAT_MSG_COMBAT_CREATURE_VS_PARTY_HITS"] = combatlog_strings["Hit Damage (other vs. other)"],
["CHAT_MSG_COMBAT_PET_HITS"] = combatlog_strings["Hit Damage (other vs. other)"],
-- Damage: spell
["CHAT_MSG_SPELL_SELF_DAMAGE"] = combatlog_strings["Spell Damage (self vs. self/other)"],
["CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE"] = combatlog_strings["Spell Damage (other vs. self)"],
["CHAT_MSG_SPELL_PARTY_DAMAGE"] = combatlog_strings["Spell Damage (other vs. other)"],
["CHAT_MSG_SPELL_FRIENDLYPLAYER_DAMAGE"] = combatlog_strings["Spell Damage (other vs. other)"],
["CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE"] = combatlog_strings["Spell Damage (other vs. other)"],
["CHAT_MSG_SPELL_CREATURE_VS_CREATURE_DAMAGE"] = combatlog_strings["Spell Damage (other vs. other)"],
["CHAT_MSG_SPELL_CREATURE_VS_PARTY_DAMAGE"] = combatlog_strings["Spell Damage (other vs. other)"],
["CHAT_MSG_SPELL_PET_DAMAGE"] = combatlog_strings["Spell Damage (other vs. other)"],
-- Damage: shields
["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF"] = combatlog_strings["Shield Damage (self vs. other)"],
["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS"] = combatlog_strings["Shield Damage (other vs. self/other)"],
-- Damage: periodic
["CHAT_MSG_SPELL_PERIODIC_PARTY_DAMAGE"] = combatlog_strings["Periodic Damage (self/other vs. other)"],
["CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE"] = combatlog_strings["Periodic Damage (self/other vs. other)"],
["CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_DAMAGE"] = combatlog_strings["Periodic Damage (self/other vs. other)"],
["CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE"] = combatlog_strings["Periodic Damage (self/other vs. other)"],
["CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE"] = combatlog_strings["Periodic Damage (self/other vs. self)"],
-- Healing
["CHAT_MSG_SPELL_SELF_BUFF"] = combatlog_strings["Heal (self vs. self/other)"],
["CHAT_MSG_SPELL_FRIENDLYPLAYER_BUFF"] = combatlog_strings["Heal (other vs. self/other)"],
["CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF"] = combatlog_strings["Heal (other vs. self/other)"],
["CHAT_MSG_SPELL_PARTY_BUFF"] = combatlog_strings["Heal (other vs. self/other)"],
["CHAT_MSG_SPELL_PERIODIC_PARTY_BUFFS"] = combatlog_strings["Periodic Heal (self/other vs. other)"],
["CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS"] = combatlog_strings["Periodic Heal (self/other vs. other)"],
["CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS"] = combatlog_strings["Periodic Heal (self/other vs. other)"],
["CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS"] = combatlog_strings["Periodic Heal (other vs. self/other)"],
}
-----------------------------------------------------------------------
-- Pattern -> parser function mapping
-----------------------------------------------------------------------
local combatlog_parser = {
-- Spell damage: self vs self
[SPELLLOGSCHOOLSELFSELF] = function(d, attack, value, school)
return d.source, attack, d.target, value, school, "damage"
end,
[SPELLLOGCRITSCHOOLSELFSELF] = function(d, attack, value, school)
return d.source, attack, d.target, value, school, "damage"
end,
[SPELLLOGSELFSELF] = function(d, attack, value)
return d.source, attack, d.target, value, d.school, "damage"
end,
[SPELLLOGCRITSELFSELF] = function(d, attack, value)
return d.source, attack, d.target, value, d.school, "damage"
end,
[PERIODICAURADAMAGESELFSELF] = function(d, value, school, attack)
return d.source, attack, d.target, value, school, "damage"
end,
-- Spell damage: self vs other
[SPELLLOGSCHOOLSELFOTHER] = function(d, attack, target, value, school)
return d.source, attack, target, value, school, "damage"
end,
[SPELLLOGCRITSCHOOLSELFOTHER] = function(d, attack, target, value, school)
return d.source, attack, target, value, school, "damage"
end,
[SPELLLOGSELFOTHER] = function(d, attack, target, value)
return d.source, attack, target, value, d.school, "damage"
end,
[SPELLLOGCRITSELFOTHER] = function(d, attack, target, value)
return d.source, attack, target, value, d.school, "damage"
end,
[PERIODICAURADAMAGESELFOTHER] = function(d, target, value, school, attack)
return d.source, attack, target, value, school, "damage"
end,
-- Melee damage: self vs other
[COMBATHITSELFOTHER] = function(d, target, value)
return d.source, d.attack, target, value, d.school, "damage"
end,
[COMBATHITCRITSELFOTHER] = function(d, target, value)
return d.source, d.attack, target, value, d.school, "damage"
end,
[COMBATHITSCHOOLSELFOTHER] = function(d, target, value, school)
return d.source, d.attack, target, value, school, "damage"
end,
[COMBATHITCRITSCHOOLSELFOTHER] = function(d, target, value, school)
return d.source, d.attack, target, value, school, "damage"
end,
-- Shield damage: self vs other
[DAMAGESHIELDSELFOTHER] = function(d, value, school, target)
return d.source, "Reflect (" .. school .. ")", target, value, school, "damage"
end,
-- Spell damage: other vs self
[SPELLLOGSCHOOLOTHERSELF] = function(d, source, attack, value, school)
return source, attack, d.target, value, school, "damage"
end,
[SPELLLOGCRITSCHOOLOTHERSELF] = function(d, source, attack, value, school)
return source, attack, d.target, value, school, "damage"
end,
[SPELLLOGOTHERSELF] = function(d, source, attack, value)
return source, attack, d.target, value, d.school, "damage"
end,
[SPELLLOGCRITOTHERSELF] = function(d, source, attack, value)
return source, attack, d.target, value, d.school, "damage"
end,
[PERIODICAURADAMAGEOTHERSELF] = function(d, value, school, source, attack)
return source, attack, d.target, value, school, "damage"
end,
-- Melee damage: other vs self
[COMBATHITOTHERSELF] = function(d, source, value)
return source, d.attack, d.target, value, d.school, "damage"
end,
[COMBATHITCRITOTHERSELF] = function(d, source, value)
return source, d.attack, d.target, value, d.school, "damage"
end,
[COMBATHITSCHOOLOTHERSELF] = function(d, source, value, school)
return source, d.attack, d.target, value, school, "damage"
end,
[COMBATHITCRITSCHOOLOTHERSELF] = function(d, source, value, school)
return source, d.attack, d.target, value, school, "damage"
end,
-- Spell damage: other vs other
[SPELLLOGSCHOOLOTHEROTHER] = function(d, source, attack, target, value, school)
return source, attack, target, value, school, "damage"
end,
[SPELLLOGCRITSCHOOLOTHEROTHER] = function(d, source, attack, target, value, school)
return source, attack, target, value, school, "damage"
end,
[SPELLLOGOTHEROTHER] = function(d, source, attack, target, value)
return source, attack, target, value, d.school, "damage"
end,
[SPELLLOGCRITOTHEROTHER] = function(d, source, attack, target, value, school)
return source, attack, target, value, school, "damage"
end,
[PERIODICAURADAMAGEOTHEROTHER] = function(d, target, value, school, source, attack)
return source, attack, target, value, school, "damage"
end,
-- Melee damage: other vs other
[COMBATHITOTHEROTHER] = function(d, source, target, value)
return source, d.attack, target, value, d.school, "damage"
end,
[COMBATHITCRITOTHEROTHER] = function(d, source, target, value)
return source, d.attack, target, value, d.school, "damage"
end,
[COMBATHITSCHOOLOTHEROTHER] = function(d, source, target, value, school)
return source, d.attack, target, value, school, "damage"
end,
[COMBATHITCRITSCHOOLOTHEROTHER] = function(d, source, target, value, school)
return source, d.attack, target, value, school, "damage"
end,
-- Shield damage: other
[DAMAGESHIELDOTHERSELF] = function(d, source, value, school)
return source, "Reflect (" .. school .. ")", d.target, value, school, "damage"
end,
[DAMAGESHIELDOTHEROTHER] = function(d, source, value, school, target)
return source, "Reflect (" .. school .. ")", target, value, school, "damage"
end,
-- Healing: other vs self
[HEALEDCRITOTHERSELF] = function(d, source, spell, value)
return source, spell, d.target, value, d.school, "heal"
end,
[HEALEDOTHERSELF] = function(d, source, spell, value)
return source, spell, d.target, value, d.school, "heal"
end,
[PERIODICAURAHEALOTHERSELF] = function(d, value, source, spell)
return source, spell, d.target, value, d.school, "heal"
end,
-- Healing: self vs self
[HEALEDCRITSELFSELF] = function(d, spell, value)
return d.source, spell, d.target, value, d.school, "heal"
end,
[HEALEDSELFSELF] = function(d, spell, value)
return d.source, spell, d.target, value, d.school, "heal"
end,
[PERIODICAURAHEALSELFSELF] = function(d, value, spell)
return d.source, spell, d.target, value, d.school, "heal"
end,
-- Healing: self vs other
[HEALEDCRITSELFOTHER] = function(d, spell, target, value)
return d.source, spell, target, value, d.school, "heal"
end,
[HEALEDSELFOTHER] = function(d, spell, target, value)
return d.source, spell, target, value, d.school, "heal"
end,
[PERIODICAURAHEALSELFOTHER] = function(d, target, value, spell)
return d.source, spell, target, value, d.school, "heal"
end,
-- Healing: other vs other
[HEALEDCRITOTHEROTHER] = function(d, source, spell, target, value)
return source, spell, target, value, d.school, "heal"
end,
[HEALEDOTHEROTHER] = function(d, source, spell, target, value)
return source, spell, target, value, d.school, "heal"
end,
[PERIODICAURAHEALOTHEROTHER] = function(d, target, value, source, spell)
return source, spell, target, value, d.school, "heal"
end,
}
-----------------------------------------------------------------------
-- Register combat log events
-----------------------------------------------------------------------
for evt in pairs(combatlog_events) do
Parser:RegisterEvent(evt)
end
-- Preload patterns
for pattern in pairs(combatlog_parser) do
sanitize(pattern)
end
-----------------------------------------------------------------------
-- Death events
-----------------------------------------------------------------------
Parser:RegisterEvent("CHAT_MSG_COMBAT_FRIENDLY_DEATH")
Parser:RegisterEvent("CHAT_MSG_COMBAT_HOSTILE_DEATH")
-----------------------------------------------------------------------
-- Interrupt patterns
-----------------------------------------------------------------------
local interrupt_strings = {}
if SPELLINTERRUPTSELFOTHER then
table.insert(interrupt_strings, SPELLINTERRUPTSELFOTHER)
end
if SPELLINTERRUPTOTHERSELF then
table.insert(interrupt_strings, SPELLINTERRUPTOTHERSELF)
end
if SPELLINTERRUPTOTHEROTHER then
table.insert(interrupt_strings, SPELLINTERRUPTOTHEROTHER)
end
local interrupt_parser = {}
if SPELLINTERRUPTSELFOTHER then
interrupt_parser[SPELLINTERRUPTSELFOTHER] = function(d, spell, target, interrupted)
return d.source, spell, target, interrupted
end
end
if SPELLINTERRUPTOTHERSELF then
interrupt_parser[SPELLINTERRUPTOTHERSELF] = function(d, source, spell, interrupted)
return source, spell, d.target, interrupted
end
end
if SPELLINTERRUPTOTHEROTHER then
interrupt_parser[SPELLINTERRUPTOTHEROTHER] = function(d, source, spell, target, interrupted)
return source, spell, target, interrupted
end
end
for pat in pairs(interrupt_parser) do
sanitize(pat)
end
-----------------------------------------------------------------------
-- Dispel patterns
-----------------------------------------------------------------------
local dispel_strings = {}
local dispel_parser = {}
if AURADISPELSELF2 then
table.insert(dispel_strings, AURADISPELSELF2)
dispel_parser[AURADISPELSELF2] = function(d, spell, aura)
return d.source, spell, d.target, aura
end
end
if AURADISPELOTHER2 then
table.insert(dispel_strings, AURADISPELOTHER2)
dispel_parser[AURADISPELOTHER2] = function(d, source, spell, target, aura)
return source, spell, target, aura
end
end
for pat in pairs(dispel_parser) do
sanitize(pat)
end
-----------------------------------------------------------------------
-- Main event handler
-----------------------------------------------------------------------
local defaults = {}
local absorb = ABSORB_TRAILER and sanitize(ABSORB_TRAILER) or nil
local resist = RESIST_TRAILER and sanitize(RESIST_TRAILER) or nil
local empty, physical, autohit = "", "physical", "Auto Hit"
local player = UnitName("player")
Parser:SetScript("OnEvent", function()
if not arg1 then return end
-- Death events
if event == "CHAT_MSG_COMBAT_FRIENDLY_DEATH" or event == "CHAT_MSG_COMBAT_HOSTILE_DEATH" then
if UNITDIESOTHER then
local deathPat = sanitize(UNITDIESOTHER)
local _, _, deadName = string.find(arg1, deathPat)
if deadName then
Parser:ProcessDeath(deadName)
end
end
if UNITDIESSELF then
local selfPat = sanitize(UNITDIESSELF)
if string.find(arg1, selfPat) then
Parser:ProcessDeath(player)
end
end
return
end
-- Strip absorb/resist suffixes
if absorb then arg1 = string.gsub(arg1, absorb, empty) end
if resist then arg1 = string.gsub(arg1, resist, empty) end
defaults.source = player
defaults.target = player
defaults.school = physical
defaults.attack = autohit
defaults.spell = UNKNOWN or "Unknown"
defaults.value = 0
-- Check interrupt patterns first (they share spell damage events)
for _, pat in ipairs(interrupt_strings) do
local result, num, a1, a2, a3, a4, a5 = cfind(arg1, pat)
if result then
local src, spell, tgt, interrupted = interrupt_parser[pat](defaults, a1, a2, a3, a4, a5)
Parser:ProcessInterrupt(src, spell, tgt, interrupted)
return
end
end
-- Check dispel patterns
for _, pat in ipairs(dispel_strings) do
local result, num, a1, a2, a3, a4, a5 = cfind(arg1, pat)
if result then
local src, spell, tgt, aura = dispel_parser[pat](defaults, a1, a2, a3, a4, a5)
Parser:ProcessDispel(src, spell, tgt, aura)
return
end
end
-- Standard combat log patterns
local patterns = combatlog_events[event]
if not patterns then return end
for _, pattern in pairs(patterns) do
local result, num, a1, a2, a3, a4, a5 = cfind(arg1, pattern)
if result then
local source, spell, target, value, school, dtype = combatlog_parser[pattern](defaults, a1, a2, a3, a4, a5)
if dtype == "damage" then
Parser:ProcessDamage(source, spell, target, value, school)
elseif dtype == "heal" then
Parser:ProcessHealing(source, spell, target, value, school)
end
return
end
end
end)