add lua addon from old sources
This commit is contained in:
parent
9068d39139
commit
b18176b85e
7
VWoWRLAHelper/VWoWRLAHelper.toc
Normal file
7
VWoWRLAHelper/VWoWRLAHelper.toc
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
## Interface:11200
|
||||||
|
## Title: Vanilla World of Warcraft Raid Log Analysis Helper Addon
|
||||||
|
## Notes: Provides support for taking buff/debuff snapshots of the entire raid at the beginning of raid encounters, to supplement the data analysis done on raid combat logs.
|
||||||
|
## OptionalDeps:
|
||||||
|
## Dependencies:
|
||||||
|
## SavedVariables: vwowrla_raid_snapshots
|
||||||
|
VWoWRLAHelper.xml
|
20
VWoWRLAHelper/VWoWRLAHelper.xml
Normal file
20
VWoWRLAHelper/VWoWRLAHelper.xml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ C:\Program%20Files\World%20of%20Warcraft\UI.xsd">
|
||||||
|
<Script file="data_lists.lua"/>
|
||||||
|
<Script file="utils.lua"/>
|
||||||
|
<Script file="matchers.lua"/>
|
||||||
|
<Script file="event_handler.lua"/>
|
||||||
|
<Script file="core.lua"/>
|
||||||
|
|
||||||
|
<GameTooltip name="VWoWRLA_tooltip" frameStrata="TOOLTIP" hidden="true" parent="UIParent" inherits="GameTooltipTemplate"/>
|
||||||
|
|
||||||
|
<Frame name="VWoWRLA_events">
|
||||||
|
<Scripts>
|
||||||
|
<OnLoad>
|
||||||
|
VWoWRLA_on_load()
|
||||||
|
</OnLoad>
|
||||||
|
<OnEvent>
|
||||||
|
VWoWRLA_on_event()
|
||||||
|
</OnEvent>
|
||||||
|
</Scripts>
|
||||||
|
</Frame>
|
||||||
|
</Ui>
|
122
VWoWRLAHelper/core.lua
Normal file
122
VWoWRLAHelper/core.lua
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
vwowrla = {}
|
||||||
|
|
||||||
|
vwowrla_raid_snapshots = {} -- saved data
|
||||||
|
|
||||||
|
function get_buff_name(target, idx)
|
||||||
|
VWoWRLA_tooltip:ClearLines()
|
||||||
|
VWoWRLA_tooltip:SetOwner(UIParent,"ANCHOR_NONE")
|
||||||
|
VWoWRLA_tooltip:SetUnitBuff(target, idx)
|
||||||
|
return VWoWRLA_tooltipTextLeft1:GetText()
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_debuff_name(target, idx)
|
||||||
|
VWoWRLA_tooltip:ClearLines()
|
||||||
|
VWoWRLA_tooltip:SetOwner(UIParent,"ANCHOR_NONE")
|
||||||
|
VWoWRLA_tooltip:SetUnitDebuff(target, idx)
|
||||||
|
return VWoWRLA_tooltipTextLeft1:GetText()
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_all_unit_buffs(target)
|
||||||
|
local buffs = {}
|
||||||
|
local i = 1
|
||||||
|
local buff = UnitBuff(target, i)
|
||||||
|
while buff do
|
||||||
|
table.insert(buffs, get_buff_name(target, i))
|
||||||
|
i = i + 1
|
||||||
|
buff = UnitBuff(target, i)
|
||||||
|
end
|
||||||
|
return buffs;
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_all_unit_debuffs(target)
|
||||||
|
local debuffs = {}
|
||||||
|
local i = 1
|
||||||
|
local debuff = UnitDebuff(target, i)
|
||||||
|
while debuff do
|
||||||
|
table.insert(debuffs, get_debuff_name(target, i))
|
||||||
|
i = i + 1
|
||||||
|
debuff = UnitDebuff(target, i)
|
||||||
|
end
|
||||||
|
return debuffs;
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_party_member_info(unit)
|
||||||
|
local buffs = get_all_unit_buffs(unit)
|
||||||
|
local debuffs = get_all_unit_debuffs(unit)
|
||||||
|
local localizedClass, englishClass = UnitClass(unit);
|
||||||
|
local level = UnitLevel(unit);
|
||||||
|
local online = UnitIsConnected(unit);
|
||||||
|
return {buffs = buffs, debuffs = debuffs, class = englishClass, level = level, online = online}
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_all_raid_member_status()
|
||||||
|
local status = {}
|
||||||
|
local unit, name, buffs, debuffs, localizedClass, englishClass, level
|
||||||
|
for i = 1, GetNumRaidMembers() do
|
||||||
|
unit = "raid" .. i
|
||||||
|
name = UnitName(unit)
|
||||||
|
if name then
|
||||||
|
status[name] = get_party_member_info(unit)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for i = 1, GetNumPartyMembers() do
|
||||||
|
unit = "party" .. i
|
||||||
|
name = UnitName(unit)
|
||||||
|
if name then
|
||||||
|
status[name] = get_party_member_info(unit)
|
||||||
|
end
|
||||||
|
|
||||||
|
unit = "player"
|
||||||
|
name = UnitName(unit)
|
||||||
|
status[name] = get_party_member_info(unit)
|
||||||
|
end
|
||||||
|
|
||||||
|
return status
|
||||||
|
end
|
||||||
|
|
||||||
|
function take_raid_buff_snapshot(encounter_name)
|
||||||
|
print("Taking snapshot of all raid member buffs/debuffs.")
|
||||||
|
local snapshot = get_all_raid_member_status()
|
||||||
|
if not vwowrla_raid_snapshots then
|
||||||
|
vwowrla_raid_snapshots = {}
|
||||||
|
end
|
||||||
|
table.insert(vwowrla_raid_snapshots, {
|
||||||
|
date = date(),
|
||||||
|
encounter = encounter_name,
|
||||||
|
snapshot = snapshot
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
function VWoWRLA_on_load()
|
||||||
|
this:RegisterEvent("VARIABLES_LOADED")
|
||||||
|
this:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||||
|
this:RegisterEvent("ZONE_CHANGED_NEW_AREA")
|
||||||
|
|
||||||
|
print("Combat Log Parser Helper -- Loaded")
|
||||||
|
if not vwowrla_raid_snapshots then
|
||||||
|
print("vwowrla_raid_snapshots is nil")
|
||||||
|
vwowrla_raid_snapshots = {}
|
||||||
|
else
|
||||||
|
print("vwowrla_raid_snapshots is not nil")
|
||||||
|
end
|
||||||
|
|
||||||
|
if not vwowrla.Loaded then
|
||||||
|
print("Combat Log Parser Helper -- Registering for events.")
|
||||||
|
VWoWRLA_register_events()
|
||||||
|
vwowrla.Loaded = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function VWoWRLA_on_event()
|
||||||
|
if not arg1 then return end
|
||||||
|
|
||||||
|
--print("event:", event, arg1, arg2, arg3, arg4, arg5, arg6)
|
||||||
|
|
||||||
|
vwowrla_process_combat_event(arg1)
|
||||||
|
end
|
||||||
|
|
||||||
|
function VWoWRLA_register_events()
|
||||||
|
for i, name in ipairs(vwowrla_events_to_register) do
|
||||||
|
VWoWRLA_events:RegisterEvent(name)
|
||||||
|
end
|
||||||
|
end
|
230
VWoWRLAHelper/data_lists.lua
Normal file
230
VWoWRLAHelper/data_lists.lua
Normal file
|
@ -0,0 +1,230 @@
|
||||||
|
defined_encounters = {
|
||||||
|
["Lucifron"] = {
|
||||||
|
entities = {
|
||||||
|
["Lucifron"] = {count = 1},
|
||||||
|
["Flamewaker Protector"] = {count = 2}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
["Magmadar"] = {
|
||||||
|
entities = {
|
||||||
|
["Magmadar"] = {count = 1}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
["Gehennas"] = {
|
||||||
|
entities = {
|
||||||
|
["Gehennas"] = {count = 1},
|
||||||
|
["Flamewaker"] = {count = 2}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
["Garr"] = {
|
||||||
|
entities = {
|
||||||
|
["Garr"] = {count = 1},
|
||||||
|
["Firesworn"] = {count = 8}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
["Baron Geddon"] = {
|
||||||
|
entities = {
|
||||||
|
["Baron Geddon"] = {count = 1}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
["Shazzrah"] = {
|
||||||
|
entities = {
|
||||||
|
["Shazzrah"] = {count = 1}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
["Sulfuron Harbinger"] = {
|
||||||
|
entities = {
|
||||||
|
["Sulfuron Harbinger"] = {count = 1},
|
||||||
|
["Flamewaker Priest"] = {count = 4}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
["Golemagg the Incinerator"] = {
|
||||||
|
entities = {
|
||||||
|
["Golemagg the Incinerator"] = {count = 1},
|
||||||
|
["Core Rager"] = {count = 2}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
["Majordomo Executus"] = {
|
||||||
|
entities = {
|
||||||
|
["Majordomo Executus"] = {count = 1, must_kill_count = 0},
|
||||||
|
["Flamewaker Healer"] = {count = 4},
|
||||||
|
["Flamewaker Elite"] = {count = 4}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
["Ragnaros"] = {
|
||||||
|
entities = {
|
||||||
|
["Ragnaros"] = {count = 1}
|
||||||
|
},
|
||||||
|
trigger_on_attack = true
|
||||||
|
},
|
||||||
|
["Onyxia"] = {
|
||||||
|
entities = {
|
||||||
|
["Onyxia"] = {count = 1}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
non_combat_starting_auras = {
|
||||||
|
"Hunter's Mark",
|
||||||
|
"Detect Magic",
|
||||||
|
"Mind Soothe",
|
||||||
|
"Distract"
|
||||||
|
}
|
||||||
|
|
||||||
|
vwowrla_events_to_register = {
|
||||||
|
"CHAT_MSG_SPELL_AURA_GONE_OTHER",
|
||||||
|
"CHAT_MSG_SPELL_AURA_GONE_PARTY",
|
||||||
|
"CHAT_MSG_SPELL_AURA_GONE_SELF",
|
||||||
|
"CHAT_MSG_SPELL_BREAK_AURA",
|
||||||
|
"CHAT_MSG_SPELL_CREATURE_VS_CREATURE_BUFF",
|
||||||
|
"CHAT_MSG_SPELL_CREATURE_VS_CREATURE_DAMAGE",
|
||||||
|
"CHAT_MSG_SPELL_CREATURE_VS_PARTY_BUFF",
|
||||||
|
"CHAT_MSG_SPELL_CREATURE_VS_PARTY_DAMAGE",
|
||||||
|
"CHAT_MSG_SPELL_CREATURE_VS_SELF_BUFF",
|
||||||
|
"CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE",
|
||||||
|
"CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS",
|
||||||
|
"CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF",
|
||||||
|
"CHAT_MSG_SPELL_FRIENDLYPLAYER_BUFF",
|
||||||
|
"CHAT_MSG_SPELL_FRIENDLYPLAYER_DAMAGE",
|
||||||
|
"CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF",
|
||||||
|
"CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE",
|
||||||
|
"CHAT_MSG_SPELL_ITEM_ENCHANTMENTS",
|
||||||
|
"CHAT_MSG_SPELL_PARTY_BUFF",
|
||||||
|
"CHAT_MSG_SPELL_PARTY_DAMAGE",
|
||||||
|
"CHAT_MSG_SPELL_PERIODIC_CREATURE_BUFFS",
|
||||||
|
"CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE",
|
||||||
|
"CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS",
|
||||||
|
"CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_DAMAGE",
|
||||||
|
"CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS",
|
||||||
|
"CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE",
|
||||||
|
"CHAT_MSG_SPELL_PERIODIC_PARTY_BUFFS",
|
||||||
|
"CHAT_MSG_SPELL_PERIODIC_PARTY_DAMAGE",
|
||||||
|
"CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS",
|
||||||
|
"CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE",
|
||||||
|
"CHAT_MSG_SPELL_PET_BUFF",
|
||||||
|
"CHAT_MSG_SPELL_PET_DAMAGE",
|
||||||
|
"CHAT_MSG_SPELL_SELF_BUFF",
|
||||||
|
"CHAT_MSG_SPELL_SELF_DAMAGE",
|
||||||
|
"CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_HITS",
|
||||||
|
"CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_MISSES",
|
||||||
|
"CHAT_MSG_COMBAT_CREATURE_VS_PARTY_HITS",
|
||||||
|
"CHAT_MSG_COMBAT_CREATURE_VS_PARTY_MISSES",
|
||||||
|
"CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS",
|
||||||
|
"CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES",
|
||||||
|
"CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS",
|
||||||
|
"CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES",
|
||||||
|
"CHAT_MSG_COMBAT_FRIENDLY_DEATH",
|
||||||
|
"CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS",
|
||||||
|
"CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES",
|
||||||
|
"CHAT_MSG_COMBAT_HOSTILE_DEATH",
|
||||||
|
"CHAT_MSG_COMBAT_MISC_INFO",
|
||||||
|
"CHAT_MSG_COMBAT_PARTY_HITS",
|
||||||
|
"CHAT_MSG_COMBAT_PARTY_MISSES",
|
||||||
|
"CHAT_MSG_COMBAT_PET_HITS",
|
||||||
|
"CHAT_MSG_COMBAT_PET_MISSES",
|
||||||
|
"CHAT_MSG_COMBAT_SELF_HITS",
|
||||||
|
"CHAT_MSG_COMBAT_SELF_MISSES"
|
||||||
|
};
|
||||||
|
|
||||||
|
problem_entity_names = {
|
||||||
|
"\"Plucky\" Johnson's Human Form",
|
||||||
|
"Alzzin's Minion",
|
||||||
|
"Antu'sul",
|
||||||
|
"Anub'shiah",
|
||||||
|
"Arin'sor",
|
||||||
|
"Arugal's Voidwalker",
|
||||||
|
"Atal'ai Deathwalker's Spirit",
|
||||||
|
"Chok'sul",
|
||||||
|
"Commander Gor'shak",
|
||||||
|
"Darkreaver's Fallen Charger",
|
||||||
|
"Death's Head Acolyte",
|
||||||
|
"Death's Head Adept",
|
||||||
|
"Death's Head Cultist",
|
||||||
|
"Death's Head Geomancer",
|
||||||
|
"Death's Head Necromancer",
|
||||||
|
"Death's Head Priest",
|
||||||
|
"Death's Head Sage",
|
||||||
|
"Death's Head Seer",
|
||||||
|
"Death's Head Ward Keeper",
|
||||||
|
"Doctor Weavil's Flying Machine",
|
||||||
|
"Dreka'Sur",
|
||||||
|
"Eliza's Guard",
|
||||||
|
"Faldreas Goeth'Shael",
|
||||||
|
"Father Winter's Helper",
|
||||||
|
"Fellicent's Shade",
|
||||||
|
"Flik's Frog",
|
||||||
|
"Franclorn's Spirit",
|
||||||
|
"Gizlock's Dummy",
|
||||||
|
"Great-father Winter's Helper",
|
||||||
|
"Greatfather Winter's Helper",
|
||||||
|
"Gunther's Visage",
|
||||||
|
"Guse's War Rider",
|
||||||
|
"Hammertoe's Spirit",
|
||||||
|
"Helcular's Remains",
|
||||||
|
"Hukku's Imp",
|
||||||
|
"Hukku's Succubus",
|
||||||
|
"Hukku's Voidwalker",
|
||||||
|
"Ichman's Gryphon",
|
||||||
|
"Jen'shan",
|
||||||
|
"Jezelle's Felhunter",
|
||||||
|
"Jezelle's Felsteed",
|
||||||
|
"Jezelle's Imp",
|
||||||
|
"Jezelle's Succubus",
|
||||||
|
"Jezelle's Voidwalker",
|
||||||
|
"Jeztor's War Rider",
|
||||||
|
"Jin'sora",
|
||||||
|
"Jugkar Grim'rod's Image",
|
||||||
|
"Krakle's Thermometer",
|
||||||
|
"Kurzen's Agent",
|
||||||
|
"Lord Azrethoc's Image",
|
||||||
|
"Maiden's Virtue Crewman",
|
||||||
|
"Merithra's Wake",
|
||||||
|
"Mulverick's War Rider",
|
||||||
|
"Nefarian's Troops",
|
||||||
|
"Nijel's Point Guard",
|
||||||
|
"Noxxion's Spawn",
|
||||||
|
"Officer Vu'Shalay",
|
||||||
|
"Onyxia's Elite Guard",
|
||||||
|
"Rak'shiri",
|
||||||
|
"Ralo'shan the Eternal Watcher",
|
||||||
|
"Ribbly's Crony",
|
||||||
|
"Ryson's Eye in the Sky",
|
||||||
|
"Sartura's Royal Guard",
|
||||||
|
"Sentinel Glynda Nal'Shea",
|
||||||
|
"Sergeant Ba'sha",
|
||||||
|
"Servant of Antu'sul",
|
||||||
|
"Sharpbeak's Father",
|
||||||
|
"Sharpbeak's Mother",
|
||||||
|
"Slidore's Gryphon",
|
||||||
|
"Slim's Friend",
|
||||||
|
"Sneed's Shredder",
|
||||||
|
"Sri'skulk",
|
||||||
|
"The Master's Eye",
|
||||||
|
"Twilight's Hammer Ambassador",
|
||||||
|
"Twilight's Hammer Executioner",
|
||||||
|
"Twilight's Hammer Torturer",
|
||||||
|
"Tyrion's Spybot",
|
||||||
|
"Umi's Mechanical Yeti",
|
||||||
|
"Varo'then's Ghost",
|
||||||
|
"Vipore's Gryphon",
|
||||||
|
"Warug's Bodyguard",
|
||||||
|
"Warug's Target Dummy",
|
||||||
|
"Winna's Kitten",
|
||||||
|
"Winter's Little Helper",
|
||||||
|
"Wizzlecrank's Shredder",
|
||||||
|
"Wrenix's Gizmotronic Apparatus",
|
||||||
|
"Xiggs Fuselighter's Flyingmachine",
|
||||||
|
"Ysida's Trigger",
|
||||||
|
"Zaetar's Spirit"
|
||||||
|
}
|
||||||
|
|
||||||
|
problem_entity_name_to_fixed_name = {
|
||||||
|
problem_to_fixed = {},
|
||||||
|
fixed_to_problem = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, problem_name in ipairs(problem_entity_names) do
|
||||||
|
local fixed_name = string.gsub(problem_name, "'s", "s")
|
||||||
|
problem_entity_name_to_fixed_name.problem_to_fixed[problem_name] = fixed_name
|
||||||
|
problem_entity_name_to_fixed_name.fixed_to_problem[fixed_name] = problem_name
|
||||||
|
end
|
260
VWoWRLAHelper/event_handler.lua
Normal file
260
VWoWRLAHelper/event_handler.lua
Normal file
|
@ -0,0 +1,260 @@
|
||||||
|
wipe_or_timeout_period = 60
|
||||||
|
|
||||||
|
active_encounter = {}
|
||||||
|
previous_successful_encounters = {}
|
||||||
|
|
||||||
|
function undo_swstats_fixlogstring(combat_log_line)
|
||||||
|
return string.gsub(combat_log_line, " 's", "'s")
|
||||||
|
end
|
||||||
|
|
||||||
|
function sanitize_entity_name(entity_name)
|
||||||
|
local fixed_name = problem_entity_name_to_fixed_name.problem_to_fixed[entity_name]
|
||||||
|
if fixed_name then
|
||||||
|
return fixed_name
|
||||||
|
else
|
||||||
|
return entity_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_original_entity_name(fixed_entity_name)
|
||||||
|
local original_name = problem_entity_name_to_fixed_name.fixed_to_problem[fixed_entity_name]
|
||||||
|
if original_name then
|
||||||
|
return original_name
|
||||||
|
else
|
||||||
|
return fixed_entity_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function sanitize_entity_names(combat_log_line)
|
||||||
|
local fixed_line = combat_log_line
|
||||||
|
for problem_name, fixed_name in pairs(problem_entity_name_to_fixed_name.problem_to_fixed) do
|
||||||
|
fixed_line = string.gsub(fixed_line, problem_name, fixed_name)
|
||||||
|
end
|
||||||
|
return fixed_line
|
||||||
|
end
|
||||||
|
|
||||||
|
function parse_combat_log_line(combat_log_line)
|
||||||
|
local found_matcher, match
|
||||||
|
for i, matcher in ipairs(vwowrla_combat_log_patterns) do
|
||||||
|
for j, pattern in ipairs(matcher.pattern) do
|
||||||
|
local _, _, m1, m2, m3, m4, m5, m6 = string.find(combat_log_line, pattern)
|
||||||
|
if m1 then
|
||||||
|
-- found a matching line. dont need to test anymore patterns.
|
||||||
|
-- if fn does not exist, don't worry, just return nil (it's probably an ignored pattern)
|
||||||
|
if matcher.fn then
|
||||||
|
local result = matcher.fn({m1, m2, m3, m4, m5, m6})
|
||||||
|
result.event = matcher.event
|
||||||
|
result.line = combat_log_line
|
||||||
|
result.timestamp = time()
|
||||||
|
return result
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- no match found
|
||||||
|
print("*** UNRECOGNIZED LINE***")
|
||||||
|
print(" >", event, combat_log_line)
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function process_parsed_combat_log_line(parsed_line)
|
||||||
|
if parsed_line.source_name then
|
||||||
|
parsed_line.source_name = get_original_entity_name(parsed_line.source_name)
|
||||||
|
end
|
||||||
|
if parsed_line.source then
|
||||||
|
parsed_line.source = get_original_entity_name(parsed_line.source)
|
||||||
|
end
|
||||||
|
if parsed_line.target_name then
|
||||||
|
parsed_line.target_name = get_original_entity_name(parsed_line.target_name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function in_active_encounter()
|
||||||
|
return not (active_encounter.name == nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
function touch_entity(entity_name, timestamp)
|
||||||
|
if not active_encounter.entities[entity_name] then
|
||||||
|
active_encounter.entities[entity_name] = {
|
||||||
|
last_activity_at = timestamp,
|
||||||
|
deaths = {},
|
||||||
|
resurrections = {}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
active_encounter.entities[entity_name].last_activity_at = timestamp
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function kill_entity(entity_name, timestamp)
|
||||||
|
active_encounter.entities[entity_name].last_activity_at = timestamp
|
||||||
|
table.insert(active_encounter.entities[entity_name].deaths, timestamp)
|
||||||
|
end
|
||||||
|
|
||||||
|
function handle_line(parsed_line)
|
||||||
|
local ev = parsed_line.event
|
||||||
|
|
||||||
|
if ev == "ignored" or ev == "other-damage" then
|
||||||
|
-- nop
|
||||||
|
elseif ev == "death" then
|
||||||
|
kill_entity(parsed_line.source_name, parsed_line.timestamp)
|
||||||
|
else
|
||||||
|
if parsed_line.source_name then touch_entity(parsed_line.source_name, parsed_line.timestamp) end
|
||||||
|
if parsed_line.target_name then touch_entity(parsed_line.target_name, parsed_line.timestamp) end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function count_dead(entity_name)
|
||||||
|
local entity = active_encounter.entities[entity_name]
|
||||||
|
if entity then
|
||||||
|
local num_deaths = table.getn(entity.deaths)
|
||||||
|
local num_resurrects = table.getn(entity.resurrections)
|
||||||
|
return num_deaths - num_resurrects
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function find_defined_encounter(entity_name)
|
||||||
|
for encounter_name, encounter in pairs(defined_encounters) do
|
||||||
|
for encounter_entity, entity_props in pairs(encounter.entities) do
|
||||||
|
if entity_name == encounter_entity then return encounter_name end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function determine_encounter_from_combat_event(parsed_line)
|
||||||
|
local encounter_name
|
||||||
|
encounter_name = find_defined_encounter(parsed_line.source_name)
|
||||||
|
if not encounter_name then encounter_name = find_defined_encounter(parsed_line.target_name) end
|
||||||
|
return encounter_name
|
||||||
|
end
|
||||||
|
|
||||||
|
function has_previous_successful_encounter(encounter_name)
|
||||||
|
if not encounter_name then return false end
|
||||||
|
for i, name in ipairs(previous_successful_encounters) do
|
||||||
|
if name == encounter_name then return true end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function aura_is_non_combat_starting(aura_name)
|
||||||
|
if not aura_name then return false end
|
||||||
|
for i, name in ipairs(non_combat_starting_auras) do
|
||||||
|
if name == aura_name then return true end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function detect_encounter_triggered(parsed_line)
|
||||||
|
local encounter_name = determine_encounter_from_combat_event(parsed_line)
|
||||||
|
if not encounter_name then return nil end
|
||||||
|
|
||||||
|
if (not has_previous_successful_encounter(encounter_name)) and (not aura_is_non_combat_starting(parsed_line.aura_name)) then
|
||||||
|
local encounter = defined_encounters[encounter_name]
|
||||||
|
if encounter.trigger_on_attack then
|
||||||
|
if parsed_line.attack then return encounter_name end
|
||||||
|
else
|
||||||
|
return encounter_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function are_all_encounter_mobs_dead()
|
||||||
|
local encounter = defined_encounters[active_encounter.name]
|
||||||
|
for entity_name, props in pairs(encounter.entities) do
|
||||||
|
local num_dead = count_dead(entity_name)
|
||||||
|
if props.must_kill_count then
|
||||||
|
if num_dead < props.must_kill_count then return false end
|
||||||
|
else
|
||||||
|
if num_dead < props.count then return false end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function has_active_encounter_wiped_or_timed_out(parsed_line)
|
||||||
|
local timestamp = parsed_line.timestamp
|
||||||
|
local encounter = defined_encounters[active_encounter.name]
|
||||||
|
for entity_name, props in pairs(encounter.entities) do
|
||||||
|
local entity = active_encounter.entities[entity_name]
|
||||||
|
if entity then
|
||||||
|
if (timestamp - entity.last_activity_at) < wipe_or_timeout_period then return false end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function detect_encounter_end(parsed_line)
|
||||||
|
if are_all_encounter_mobs_dead() then
|
||||||
|
return "killed"
|
||||||
|
elseif has_active_encounter_wiped_or_timed_out(parsed_line) then
|
||||||
|
return "wipe-or-timeout"
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function begin_encounter(encounter_name, parsed_line)
|
||||||
|
local datetime = date()
|
||||||
|
active_encounter = {
|
||||||
|
name = encounter_name,
|
||||||
|
entities = {},
|
||||||
|
started_at = datetime,
|
||||||
|
started_at_timestamp = parsed_line.timestamp
|
||||||
|
}
|
||||||
|
print("Beginning encounter \"" .. encounter_name .. "\" detected on line: " .. parsed_line.line)
|
||||||
|
take_raid_buff_snapshot(encounter_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
function end_encounter(parsed_line, end_reason)
|
||||||
|
local wipe_or_timeout = (end_reason == "wipe-or-timeout")
|
||||||
|
print("Ending encounter \"" .. active_encounter.name .. "\" detected on line: " .. parsed_line.line)
|
||||||
|
if wipe_or_timeout then
|
||||||
|
print("Encounter ending due to wipe or trigger entity activity timeout (unsuccessful encounter kill attempt).")
|
||||||
|
end
|
||||||
|
|
||||||
|
if not wipe_or_timeout then
|
||||||
|
table.insert(previous_successful_encounters, active_encounter.name);
|
||||||
|
end
|
||||||
|
|
||||||
|
active_encounter = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
function active_encounter_processing(parsed_line)
|
||||||
|
handle_line(parsed_line)
|
||||||
|
local end_reason = detect_encounter_end(parsed_line)
|
||||||
|
if end_reason then
|
||||||
|
end_encounter(parsed_line, end_reason)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function out_of_encounter_processing(parsed_line)
|
||||||
|
local encounter_name = detect_encounter_triggered(parsed_line)
|
||||||
|
if encounter_name then
|
||||||
|
begin_encounter(encounter_name, parsed_line)
|
||||||
|
handle_line(parsed_line)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function vwowrla_process_combat_event(combat_log_line)
|
||||||
|
if not combat_log_line then return end
|
||||||
|
|
||||||
|
combat_log_line = undo_swstats_fixlogstring(sanitize_entity_names(combat_log_line))
|
||||||
|
|
||||||
|
local parsed = parse_combat_log_line(combat_log_line)
|
||||||
|
if parsed then
|
||||||
|
process_parsed_combat_log_line(parsed)
|
||||||
|
if in_active_encounter() then
|
||||||
|
active_encounter_processing(parsed)
|
||||||
|
else
|
||||||
|
out_of_encounter_processing(parsed)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
581
VWoWRLAHelper/matchers.lua
Normal file
581
VWoWRLAHelper/matchers.lua
Normal file
|
@ -0,0 +1,581 @@
|
||||||
|
-- these patterns copied from the full set of combat log regex patterns located in
|
||||||
|
-- the server app code under vwowrla.core.events.matchers/regex-matchers and
|
||||||
|
-- "dumbed-down" / converted to lua patterns. lua patterns are not as complex as regular
|
||||||
|
-- expressions, so there's a bit more repetition to get around things like missing support
|
||||||
|
-- for optional substring matching (e.g. "(hits|crits)", "(?:missed|misses)", etc ...).
|
||||||
|
|
||||||
|
-- event types have been "compacted" somewhat. we only care about types of events in a
|
||||||
|
-- fairly broad sense and don't need to be really, really specific.
|
||||||
|
|
||||||
|
-- additionally, for the purposes of this addon, there are some bits of info in certain
|
||||||
|
-- more complicated combat log strings that we don't care about and so support for matching
|
||||||
|
-- them has just been dropped out of the appropriate patterns. things such as glancing/crushing
|
||||||
|
-- blows and partial absorbs/resists... all we are using these matchers for is to correctly
|
||||||
|
-- parse out 1) the type of event, 2) the names of the entities involved, and finally 3) the
|
||||||
|
-- name of any skill being used by the source on a target.
|
||||||
|
|
||||||
|
vwowrla_combat_log_patterns = {
|
||||||
|
------------------------------------------------------------------------------------------------
|
||||||
|
-- IGNORED EVENTS
|
||||||
|
-- these are only here to prevent "unrecognized" errors for combat log events that we
|
||||||
|
-- do not care about. we list them first so they are matched first (and not perhaps mistaken
|
||||||
|
-- for another type of event) and then ignored by the event handler.
|
||||||
|
{
|
||||||
|
event = "ignored",
|
||||||
|
pattern = {
|
||||||
|
"^You fail to cast (.+): (.+)%.$",
|
||||||
|
"^You fail to perform (.+): (.+)%.$",
|
||||||
|
"^You have slain (.+)!$",
|
||||||
|
"^(.+) is slain by (.+)!$",
|
||||||
|
"^(.+) create(%a?) (.+)%.$",
|
||||||
|
"^Your pet begins eating a (.+)%.$",
|
||||||
|
"^(.-)'s pet begins eating a (.+)%.$",
|
||||||
|
"^Your (.+) is reflected back by (.+)%.$",
|
||||||
|
"^(.-)'s (.+) is reflected back by (.+)%.$",
|
||||||
|
"^(.+) is destroyed%.$",
|
||||||
|
"^Your (.+) reputation has increased by (%d+)%.$",
|
||||||
|
"^Your equipped items suffer a (.+) durability loss%.$",
|
||||||
|
"^(.+) dies, honorable kill (.+)$",
|
||||||
|
"^(.+) is killed by (.+)%.$"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------------------------
|
||||||
|
-- SKILL/SPELL DAMAGE
|
||||||
|
{
|
||||||
|
event = "skill-damage-to-target",
|
||||||
|
pattern = {
|
||||||
|
"^Your (.+) hits (.+) for (%d+) (.+) damage%.(.*)$",
|
||||||
|
"^Your (.+) crits (.+) for (%d+) (.+) damage%.(.*)$",
|
||||||
|
"^Your (.+) hits (.+) for (%d+) damage%.(.*)$",
|
||||||
|
"^Your (.+) crits (.+) for (%d+) damage%.(.*)$",
|
||||||
|
"^Your (.+) hits (.+) for (%d+) (.+)%.(.*)$",
|
||||||
|
"^Your (.+) crits (.+) for (%d+) (.+)%.(.*)$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
skill = matches[1],
|
||||||
|
target_name = matches[2],
|
||||||
|
source_name = "you",
|
||||||
|
attack = true
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
|
event = "skill-damage-to-target",
|
||||||
|
pattern = {
|
||||||
|
"^(.-)'s (.+) hits (.+) for (%d+) (.+) damage%.(.*)$",
|
||||||
|
"^(.-)'s (.+) crits (.+) for (%d+) (.+) damage%.(.*)$",
|
||||||
|
"^(.-)'s (.+) hits (.+) for (%d+) damage%.(.*)$",
|
||||||
|
"^(.-)'s (.+) crits (.+) for (%d+) damage%.(.*)$",
|
||||||
|
"^(.-)'s (.+) hits (.+) for (%d+)%.(.*)$",
|
||||||
|
"^(.-)'s (.+) crits (.+) for (%d+)%.(.*)$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
source_name = matches[1],
|
||||||
|
skill = matches[2],
|
||||||
|
target_name = matches[3],
|
||||||
|
attack = true
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------------------------
|
||||||
|
-- SKILL/SPELL MISSES / FULL ABSORBS/RESISTS
|
||||||
|
{
|
||||||
|
event = "skill-avoided-by-target",
|
||||||
|
pattern = {
|
||||||
|
"^Your (.+) missed (.+)%.$",
|
||||||
|
"^Your (.+) was parried by (.+)%.$",
|
||||||
|
"^Your (.+) was blocked by (.+)%.$",
|
||||||
|
"^Your (.+) was dodged by (.+)%.$",
|
||||||
|
"^Your (.+) was evaded by (.+)%.$",
|
||||||
|
"^Your (.+) is absorbed by (.+)%.$",
|
||||||
|
"^Your (.+) was resisted by (.+)%.$",
|
||||||
|
"^Your (.+) failed%. (.+) is immune%.$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
skill = matches[1],
|
||||||
|
target_name = matches[2],
|
||||||
|
source_name = "you",
|
||||||
|
attack = true
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
|
event = "skill-avoided-by-target",
|
||||||
|
pattern = {
|
||||||
|
"^(.+) resists your (.+)%.$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
target_name = matches[1],
|
||||||
|
skill = matches[2],
|
||||||
|
source_name = "you",
|
||||||
|
attack = true
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
|
event = "skill-avoided-by-target",
|
||||||
|
pattern = {
|
||||||
|
"^(.-)'s (.+) was parried%.$",
|
||||||
|
"^(.-)'s (.+) was dodged%.$",
|
||||||
|
"^(.-)'s (.+) was resisted%.$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
source_name = matches[1],
|
||||||
|
skill = matches[2],
|
||||||
|
target_name = "you",
|
||||||
|
attack = true
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
|
event = "skill-avoided-by-target",
|
||||||
|
pattern = {
|
||||||
|
"^(.-)'s (.+) misses (.+)%.$",
|
||||||
|
"^(.-)'s (.+) missed (.+)%.$",
|
||||||
|
"^(.-)'s (.+) was parried by (.+)%.$",
|
||||||
|
"^(.-)'s (.+) was blocked by (.+)%.$",
|
||||||
|
"^(.-)'s (.+) was dodged by (.+)%.$",
|
||||||
|
"^(.-)'s (.+) was evaded by (.+)%.$",
|
||||||
|
"^(.-)'s (.+) is absorbed by (.+)%.$",
|
||||||
|
"^(.-)'s (.+) was resisted by (.+)%.$",
|
||||||
|
"^(.-)'s (.+) fails%. (.+) is immune%.$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
source_name = matches[1],
|
||||||
|
skill = matches[2],
|
||||||
|
target_name = matches[3],
|
||||||
|
attack = true
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
|
event = "skill-avoided-by-target",
|
||||||
|
pattern = {
|
||||||
|
"^(.+) resists? (.-)'s (.+)%.$",
|
||||||
|
"^(.+) absorbs? (.-)'s (.+)%.$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
target_name = matches[1],
|
||||||
|
source_name = matches[2],
|
||||||
|
skill = matches[3],
|
||||||
|
attack = true
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------------------------
|
||||||
|
-- REFLECTED DAMAGE
|
||||||
|
{
|
||||||
|
event = "damage-reflected",
|
||||||
|
pattern = {
|
||||||
|
"^(.+) reflects? (%d+) (.+) damage to (.+)%.$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
source_name = matches[1],
|
||||||
|
target_name = matches[4],
|
||||||
|
attack = true
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------------------------
|
||||||
|
-- MELEE DAMAGE
|
||||||
|
{
|
||||||
|
event = "melee-damage-to-target",
|
||||||
|
pattern = {
|
||||||
|
"^(.+) hits? (.+) for (%d+)%.(.*)$",
|
||||||
|
"^(.+) crits? (.+) for (%d+)%.(.*)$",
|
||||||
|
"^(.+) hits? (.+) for (%d+) (.+) damage%.(.*)$",
|
||||||
|
"^(.+) crits? (.+) for (%d+) (.+) damage%.(.*)$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
source_name = matches[1],
|
||||||
|
target_name = matches[2],
|
||||||
|
attack = true
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------------------------
|
||||||
|
-- MELEE DAMAGE AVOIDANCE (ABSORB/RESIST/MISS/BLOCK/DODGE/PARRY/EVADE)
|
||||||
|
{
|
||||||
|
event = "melee-avoided-by-target",
|
||||||
|
pattern = {
|
||||||
|
"^(.+) attacks?%. (.+) absorbs? all the damage%.$",
|
||||||
|
"^(.+) attacks?%. (.+) resists? all the damage%.$",
|
||||||
|
"^(.+) misses (.+)%.$",
|
||||||
|
"^(.+) miss (.+)%.$",
|
||||||
|
"^(.+) attacks?%. (.+) parry%.$",
|
||||||
|
"^(.+) attacks?%. (.+) parries%.$",
|
||||||
|
"^(.+) attacks?%. (.+) dodges?%.$",
|
||||||
|
"^(.+) attacks?%. (.+) blocks?%.$",
|
||||||
|
"^(.+) attacks?%. (.+) evades?%.$",
|
||||||
|
"^(.+) attacks? but (.+) is immune%.$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
source_name = matches[1],
|
||||||
|
target_name = matches[2],
|
||||||
|
attack = true
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------------------------
|
||||||
|
-- SKILL INTERRUPTION
|
||||||
|
{
|
||||||
|
event = "skill-interrupted-by-target",
|
||||||
|
pattern = {
|
||||||
|
"^(.+) interrupts? your (.+)%.$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
source_name = matches[1],
|
||||||
|
skill = matches[2],
|
||||||
|
target_name = "you",
|
||||||
|
attack = true
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
|
event = "skill-interrupted-by-target",
|
||||||
|
pattern = {
|
||||||
|
"^(.+) interrupts? (.-)'s (.+)%.$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
source_name = matches[1],
|
||||||
|
target_name = matches[2],
|
||||||
|
skill = matches[3],
|
||||||
|
attack = true
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------------------------
|
||||||
|
-- DAMAGE OVER TIME (DOT)
|
||||||
|
{
|
||||||
|
event = "dot-damages-target",
|
||||||
|
pattern = {
|
||||||
|
"^(.+) suffers? (%d+) (.+) damage from your (.+)%.(.*)$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
target_name = matches[1],
|
||||||
|
skill = matches[4],
|
||||||
|
source_name = "you",
|
||||||
|
attack = true
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
|
event = "dot-damages-target",
|
||||||
|
pattern = {
|
||||||
|
"^(.+) suffers? (%d+) (.+) damage from (.-)'s (.+)%.(.*)$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
target_name = matches[1],
|
||||||
|
source_name = matches[4],
|
||||||
|
skill = matches[5],
|
||||||
|
attack = true
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------------------------
|
||||||
|
-- CAST NOTIFICATION / INSTANT CAST ABILITIES PERFORMED
|
||||||
|
{
|
||||||
|
event = "cast-begins",
|
||||||
|
pattern = {
|
||||||
|
"^(.+) begins? to perform (.+)%.$",
|
||||||
|
"^(.+) begins? to cast (.+)%.$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
source_name = matches[1],
|
||||||
|
skill = matches[2]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
|
event = "skill-performed-on-target",
|
||||||
|
pattern = {
|
||||||
|
"^(.+) casts? (.+) on (.+): (.+)%.$",
|
||||||
|
"^(.+) performs? (.+) on (.+): (.+)%.$",
|
||||||
|
"^(.+) casts? (.+) on (.+)%.$",
|
||||||
|
"^(.+) performs? (.+) on (.+)%.$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
source_name = matches[1],
|
||||||
|
skill = matches[2],
|
||||||
|
target_name = matches[3]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
|
event = "cast",
|
||||||
|
pattern = {
|
||||||
|
"^(.+) casts? (.+)%.$",
|
||||||
|
"^(.+) performs? (.+)%.$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
source_name = matches[1],
|
||||||
|
skill = matches[2]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------------------------
|
||||||
|
-- DIRECT HEALING FROM SKILLS
|
||||||
|
{
|
||||||
|
event = "skill-heals-target",
|
||||||
|
pattern = {
|
||||||
|
"^Your (.+) critically heals (.+) for (%d+)%.$",
|
||||||
|
"^Your (.+) heals (.+) for (%d+)%.$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
skill = matches[1],
|
||||||
|
target_name = matches[2],
|
||||||
|
source_name = "you"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
|
event = "skill-heals-target",
|
||||||
|
pattern = {
|
||||||
|
"^(.-)'s (.+) critically heals (.+) for (%d+)%.$",
|
||||||
|
"^(.-)'s (.+) heals (.+) for (%d+)%.$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
source_name = matches[1],
|
||||||
|
skill = matches[2],
|
||||||
|
target_name = matches[3]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------------------------
|
||||||
|
-- RESOURCE (HEALTH/MANA/RAGE/ENERGY/HAPPINESS) GAIN / LOSS
|
||||||
|
{
|
||||||
|
event = "resource-gained",
|
||||||
|
pattern = {
|
||||||
|
"^(.+) gains? (%d+) (.+) from your (.+)%.$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
target_name = matches[1],
|
||||||
|
resource_type = string.lower(matches[3]),
|
||||||
|
skill = matches[4],
|
||||||
|
source_name = "you"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
|
event = "resource-gained",
|
||||||
|
pattern = {
|
||||||
|
"^(.+) gains? (%d+) (.+) from (.-)'s (.+)%.$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
target_name = matches[1],
|
||||||
|
resource_type = string.lower(matches[3]),
|
||||||
|
source_name = matches[4],
|
||||||
|
skill = matches[5]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
|
event = "resource-gained",
|
||||||
|
pattern = {
|
||||||
|
"^(.+) gains? (%d+) (.+) from (.+)%.$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
target_name = matches[1],
|
||||||
|
resource_type = string.lower(matches[3]),
|
||||||
|
skill = matches[4],
|
||||||
|
source_name = matches[1]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
|
event = "resource-lost",
|
||||||
|
pattern = {
|
||||||
|
"^Your (.+) drains (%d+) (.+) from (.+)%.$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
skill = matches[1],
|
||||||
|
resource_type = string.lower(matches[3]),
|
||||||
|
target_name = matches[4],
|
||||||
|
source_name = "you"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
|
event = "resource-lost",
|
||||||
|
pattern = {
|
||||||
|
"^(.-)'s (.+) drains (%d+) (.+) from (.+)%.$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
source_name = matches[1],
|
||||||
|
skill = matches[2],
|
||||||
|
resource_type = string.lower(matches[4]),
|
||||||
|
target_name = matches[5]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------------------------
|
||||||
|
-- OTHER SPECIAL ABILITY GAINS
|
||||||
|
{
|
||||||
|
event = "special-gained",
|
||||||
|
pattern = {
|
||||||
|
"^(.+) gains? (.+) through (.+)%.$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
target_name = matches[1],
|
||||||
|
special = matches[2],
|
||||||
|
source = matches[3] -- not an entity name
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------------------------
|
||||||
|
-- BUFF/DEBUFF
|
||||||
|
{
|
||||||
|
event = "aura-gained",
|
||||||
|
pattern = {
|
||||||
|
"^(.+) gains? (.+) %((%d+)%)%.$",
|
||||||
|
"^(.+) gains? (.+)%.$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
target_name = matches[1],
|
||||||
|
aura_name = matches[2],
|
||||||
|
aura_type = "buff"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
|
event = "aura-gained",
|
||||||
|
pattern = {
|
||||||
|
"^(.+) is afflicted by (.+) %((%d+)%)%.$",
|
||||||
|
"^(.+) are afflicted by (.+) %((%d+)%)%.$",
|
||||||
|
"^(.+) is afflicted by (.+)%.$",
|
||||||
|
"^(.+) are afflicted by (.+)%.$",
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
target_name = matches[1],
|
||||||
|
aura_name = matches[2],
|
||||||
|
aura_type = "debuff",
|
||||||
|
attack = true
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
|
event = "aura-lost",
|
||||||
|
pattern = {
|
||||||
|
"^(.+) fades from (.+)%.$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
aura_name = matches[1],
|
||||||
|
target_name = matches[2],
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
|
event = "aura-lost",
|
||||||
|
pattern = {
|
||||||
|
"^Your (.+) is removed%.$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
aura_name = matches[1],
|
||||||
|
target_name = "you",
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
|
event = "aura-lost",
|
||||||
|
pattern = {
|
||||||
|
"^(.-)'s (.+) is removed%.$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
target_name = matches[1],
|
||||||
|
aura_name = matches[2],
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------------------------
|
||||||
|
-- ENVIRONMENTAL / OTHER DAMAGE
|
||||||
|
{
|
||||||
|
event = "other-damage",
|
||||||
|
pattern = {
|
||||||
|
"^(.+) suffers? (%d+) points of (.+) damage%.(.*)$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
target_name = matches[1],
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
|
event = "other-damage",
|
||||||
|
pattern = {
|
||||||
|
"^(.+) loses? (%d+) health for swimming in lava%.(.*)$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
target_name = matches[1],
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
|
event = "other-damage",
|
||||||
|
pattern = {
|
||||||
|
"^(.+) falls? and loses? (%d+) health%.$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
target_name = matches[1],
|
||||||
|
}
|
||||||
|
end
|
||||||
|
},
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------------------------
|
||||||
|
-- DEATH
|
||||||
|
{
|
||||||
|
event = "death",
|
||||||
|
pattern = {
|
||||||
|
"^(.+) dies?%.$"
|
||||||
|
},
|
||||||
|
fn = function(matches)
|
||||||
|
return {
|
||||||
|
source_name = matches[1],
|
||||||
|
}
|
||||||
|
end
|
||||||
|
}
|
||||||
|
};
|
66
VWoWRLAHelper/utils.lua
Normal file
66
VWoWRLAHelper/utils.lua
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
function obj_copy(obj, seen)
|
||||||
|
if type(obj) ~= 'table' then return obj end
|
||||||
|
if seen and seen[obj] then return seen[obj] end
|
||||||
|
local s = seen or {}
|
||||||
|
local res = setmetatable({}, getmetatable(obj))
|
||||||
|
s[obj] = res
|
||||||
|
for k, v in pairs(obj) do res[obj_copy(k, s)] = obj_copy(v, s) end
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
function dump_var(var, indent)
|
||||||
|
print("<", type(var), ">")
|
||||||
|
if not indent then indent = 0 end
|
||||||
|
if type(var) == "table" then
|
||||||
|
for k, v in pairs(var) do
|
||||||
|
formatting = string.rep(" ", indent) .. k .. ": "
|
||||||
|
if type(v) == "table" then
|
||||||
|
print(formatting)
|
||||||
|
dump_var(v, indent+1)
|
||||||
|
elseif type(v) == 'boolean' then
|
||||||
|
print(formatting .. tostring(v))
|
||||||
|
else
|
||||||
|
print(formatting .. v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif type(var) == "boolean" then
|
||||||
|
formatting = string.rep(" ", indent)
|
||||||
|
print(formatting .. tostring(var))
|
||||||
|
else
|
||||||
|
formatting = string.rep(" ", indent)
|
||||||
|
print(formatting .. tostring(var))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--function explode(sep, str, limit)
|
||||||
|
-- if not sep or sep == "" then return false end
|
||||||
|
-- if not str then return false end
|
||||||
|
-- limit = limit or mhuge
|
||||||
|
-- if limit == 0 or limit == 1 then return {str},1 end
|
||||||
|
--
|
||||||
|
-- local r = {}
|
||||||
|
-- local n, init = 0, 1
|
||||||
|
--
|
||||||
|
-- while true do
|
||||||
|
-- local s,e = strfind(str, sep, init, true)
|
||||||
|
-- if not s then break end
|
||||||
|
-- r[#r+1] = strsub(str, init, s - 1)
|
||||||
|
-- init = e + 1
|
||||||
|
-- n = n + 1
|
||||||
|
-- if n == limit - 1 then break end
|
||||||
|
-- end
|
||||||
|
--
|
||||||
|
-- if init <= strlen(str) then
|
||||||
|
-- r[#r+1] = strsub(str, init)
|
||||||
|
-- else
|
||||||
|
-- r[#r+1] = ""
|
||||||
|
-- end
|
||||||
|
-- n = n + 1
|
||||||
|
--
|
||||||
|
-- if limit < 0 then
|
||||||
|
-- for i=n, n + limit + 1, -1 do r[i] = nil end
|
||||||
|
-- n = n + limit
|
||||||
|
-- end
|
||||||
|
--
|
||||||
|
-- return r, n
|
||||||
|
--end
|
Reference in a new issue