Files
Brues a5e46a62b8 Change nampower school table to sequential index keys
nampowerSchoolToType now uses sequential keys (0=Physical, then implicit 1-6 for Holy/Fire/Nature/Frost/Shadow/Arcane) instead of the previous power-of-two bitmask keys (0,1,2,4,8,16,32).
2026-06-23 13:25:13 -05:00

4999 lines
174 KiB
Lua
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-------------------------------------------------------------------------------------
-- Title: Mik's Combat Event Helper
-- Author: Mik
-- Maintainer: Athene
-------------------------------------------------------------------------------------
-- Create "namespace."
MikCEH = {};
-- Upvalue caches for frequently called functions.
local string_find, string_gsub = string.find, string.gsub
local string_len, string_sub, string_gfind = string.len, string.sub, string.gfind
local table_insert, table_getn, table_setn = table.insert, table.getn, table.setn
local GetTime, UnitHealth, UnitHealthMax = GetTime, UnitHealth, UnitHealthMax
local UnitMana, UnitManaMax, UnitName = UnitMana, UnitManaMax, UnitName
local UnitIsPlayer, UnitIsFriend, UnitExists = UnitIsPlayer, UnitIsFriend, UnitExists
local GetNumRaidMembers, GetNumPartyMembers = GetNumRaidMembers, GetNumPartyMembers
local pairs, tonumber, type, pcall = pairs, tonumber, type, pcall
-------------------------------------------------------------------------------------
-- Public constants.
-------------------------------------------------------------------------------------
-- Event types.
MikCEH.EVENTTYPE_DAMAGE = 1;
MikCEH.EVENTTYPE_HEAL = 2;
MikCEH.EVENTTYPE_NOTIFICATION = 3;
-- Direction types.
MikCEH.DIRECTIONTYPE_PLAYER_INCOMING = 1;
MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING = 2;
MikCEH.DIRECTIONTYPE_PET_OUTGOING = 3;
MikCEH.DIRECTIONTYPE_PET_INCOMING = 4;
-- Action types.
MikCEH.ACTIONTYPE_HIT = 1;
MikCEH.ACTIONTYPE_MISS = 2;
MikCEH.ACTIONTYPE_DODGE = 3;
MikCEH.ACTIONTYPE_PARRY = 4;
MikCEH.ACTIONTYPE_BLOCK = 5;
MikCEH.ACTIONTYPE_RESIST = 6;
MikCEH.ACTIONTYPE_ABSORB = 7;
MikCEH.ACTIONTYPE_IMMUNE = 8;
MikCEH.ACTIONTYPE_EVADE = 9;
MikCEH.ACTIONTYPE_REFLECT = 10;
MikCEH.ACTIONTYPE_DROWNING = 11;
MikCEH.ACTIONTYPE_FALLING = 12;
MikCEH.ACTIONTYPE_FATIGUE = 13;
MikCEH.ACTIONTYPE_FIRE = 14;
MikCEH.ACTIONTYPE_LAVA = 15;
MikCEH.ACTIONTYPE_SLIME = 16;
-- Hit types.
MikCEH.HITTYPE_NORMAL = 1;
MikCEH.HITTYPE_CRIT = 2;
MikCEH.HITTYPE_OVER_TIME = 3;
-- Damage types.
MikCEH.DAMAGETYPE_PHYSICAL = 1;
MikCEH.DAMAGETYPE_HOLY = 2;
MikCEH.DAMAGETYPE_NATURE = 3;
MikCEH.DAMAGETYPE_FIRE = 4;
MikCEH.DAMAGETYPE_FROST = 5;
MikCEH.DAMAGETYPE_SHADOW = 6;
MikCEH.DAMAGETYPE_ARCANE = 7;
MikCEH.DAMAGETYPE_UNKNOWN = 999;
-- Partial action types.
MikCEH.PARTIALACTIONTYPE_ABSORB = 1;
MikCEH.PARTIALACTIONTYPE_BLOCK = 2;
MikCEH.PARTIALACTIONTYPE_RESIST = 3;
MikCEH.PARTIALACTIONTYPE_VULNERABLE = 4;
MikCEH.PARTIALACTIONTYPE_CRUSHING = 5;
MikCEH.PARTIALACTIONTYPE_GLANCING = 6;
MikCEH.PARTIALACTIONTYPE_OVERHEAL = 7;
-- Heal types.
MikCEH.HEALTYPE_NORMAL = 1;
MikCEH.HEALTYPE_CRIT = 2;
MikCEH.HEALTYPE_OVER_TIME = 3;
-- Notification types.
MikCEH.NOTIFICATIONTYPE_DEBUFF = 1;
MikCEH.NOTIFICATIONTYPE_BUFF = 2;
MikCEH.NOTIFICATIONTYPE_ITEM_BUFF = 3;
MikCEH.NOTIFICATIONTYPE_BUFF_FADE = 4;
MikCEH.NOTIFICATIONTYPE_COMBAT_ENTER = 5;
MikCEH.NOTIFICATIONTYPE_COMBAT_LEAVE = 6;
MikCEH.NOTIFICATIONTYPE_POWER_GAIN = 7;
MikCEH.NOTIFICATIONTYPE_POWER_LOSS = 8;
MikCEH.NOTIFICATIONTYPE_CP_GAIN = 9;
MikCEH.NOTIFICATIONTYPE_HONOR_GAIN = 10;
MikCEH.NOTIFICATIONTYPE_REP_GAIN = 11;
MikCEH.NOTIFICATIONTYPE_REP_LOSS = 12;
MikCEH.NOTIFICATIONTYPE_SKILL_GAIN = 13;
MikCEH.NOTIFICATIONTYPE_EXPERIENCE_GAIN = 14;
MikCEH.NOTIFICATIONTYPE_PC_KILLING_BLOW = 15;
MikCEH.NOTIFICATIONTYPE_NPC_KILLING_BLOW = 16;
-- Trigger types.
MikCEH.TRIGGERTYPE_SELF_HEALTH = 1;
MikCEH.TRIGGERTYPE_SELF_MANA = 2;
MikCEH.TRIGGERTYPE_PET_HEALTH = 3;
MikCEH.TRIGGERTYPE_ENEMY_HEALTH = 4;
MikCEH.TRIGGERTYPE_FRIENDLY_HEALTH = 5;
MikCEH.TRIGGERTYPE_SEARCH_PATTERN = 6;
-------------------------------------------------------------------------------------
-- Public variables.
-------------------------------------------------------------------------------------
-- Hold combat event data.
MikCEH.CombatEventData = {};
-- Hold trigger event data.
MikCEH.TriggerEventData = {};
-------------------------------------------------------------------------------------
-- Private constants.
-------------------------------------------------------------------------------------
-- Amount of time to delay between selected player list updates and how long
-- to hold a recently selected player in cache.
local RECENTLY_SELECTED_PLAYERS_UPDATE_INTERVAL = 1;
local RECENTLY_SELECTED_PLAYERS_HOLD_TIME = 45;
-------------------------------------------------------------------------------------
-- Private variables.
-------------------------------------------------------------------------------------
-- Holds the events the helper is interested in receiving.
local listenEvents = {};
-- Holds formatted global strings.
local globalStringInfoArray = {};
-- Holds the name and class of the player.
local playerName;
local playerClass;
-- Cached pet name, updated once per event dispatch.
local cachedPetName;
-- Tables to hold ordered/unordered captured data.
local orderedCaptureData = {};
local unorderedCaptureData = {};
-- Holds whether or not event searching mode is active and the pattern for it.
local searchMode = false;
local searchModePattern;
-- Tables to hold the triggers in a format optimized for searching.
local selfHealthTriggers = {};
local selfManaTriggers = {};
local petHealthTriggers = {};
local enemyHealthTriggers = {};
local friendlyHealthTriggers = {};
local searchPatternTriggers = {};
-- Holds previous health and mana values.
local lastSelfHealthPercentage = 0;
local lastSelfManaPercentage = 0;
local lastSelfManaAmount = UnitMana("player");
local lastPetHealthPercentage = 0;
local lastEnemyHealthPercentage = 0;
local lastFriendlyHealthPercentage = 0;
-- Holds a list of recently selected hostile players.
local recentlySelectedPlayers = {};
local elapsedTime = 0;
-- Feature detection flags for enhanced combat event mods.
local hasNampower = false
local hasSuperWoW = false
local hasUnitXP = false
-- Runtime detection flags for Nampower events.
-- These start false and flip true on first invocation of the corresponding handler,
-- so CHAT_MSG parsing remains active until the Nampower events actually fire.
local nampowerHealsActive = false
local nampowerAutoAttackActive = false
local nampowerEnergizeActive = false
local nampowerSpellDamageActive = false
local nampowerBuffsActive = false
local nampowerPetAutoAttackActive = false
local nampowerPetSpellDamageActive = false
-- Cached player GUID for Nampower event handlers (set in Init when SuperWoW/Nampower present).
local playerGUID = nil
-- Event throttling for trigger checks.
local TRIGGER_THROTTLE_INTERVAL = 0.15
local lastTriggerCheckTime = 0
-- Nampower event frame and dispatch table (initialized in SetupNampowerEvents).
local nampowerEventFrame = nil
local nampowerHandlers = {}
-- Spell name cache for spellId lookups.
local spellNameCache = {}
-- Name→unitID cache for avoiding O(n) raid/party iteration.
local nameToUnitIDCache = {}
local nameToUnitIDCacheDirty = true
local function RebuildNameToUnitIDCache()
nameToUnitIDCache = {}
local numRaid = GetNumRaidMembers()
if numRaid > 0 then
for i = 1, numRaid do
local ruid = "raid" .. i
local rname = UnitName(ruid)
if rname then nameToUnitIDCache[rname] = ruid end
local rpuid = "raidpet" .. i
local rpname = UnitName(rpuid)
if rpname then nameToUnitIDCache[rpname] = rpuid end
end
else
local numParty = GetNumPartyMembers()
for i = 1, numParty do
local puid = "party" .. i
local pname = UnitName(puid)
if pname then nameToUnitIDCache[pname] = puid end
local ppuid = "partypet" .. i
local ppname = UnitName(ppuid)
if ppname then nameToUnitIDCache[ppname] = ppuid end
end
end
nameToUnitIDCacheDirty = false
end
-------------------------------------------------------------------------------------
-- Core event handlers.
-------------------------------------------------------------------------------------
-- **********************************************************************************
-- Registers all of the events the helper is interested in.
-- **********************************************************************************
function MikCEH.RegisterEvents()
-- Register the events we are interested in receiving.
for k, v in listenEvents do
MCEHEventFrame:RegisterEvent(v);
end
end
-- **********************************************************************************
-- Unregisters all of the event the helper registered for.
-- **********************************************************************************
function MikCEH.UnregisterEvents()
-- Register the events we are interested in receiving.
for k, v in listenEvents do
MCEHEventFrame:UnregisterEvent(v);
end
end
-- **********************************************************************************
-- Called when the helper's event frame is loaded.
-- **********************************************************************************
function MikCEH.OnLoad()
-- Load up the listen events table with the events the helper is interested in.
table_insert(listenEvents, "CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS"); -- Incoming Melee Hits/Crits
table_insert(listenEvents, "CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS"); -- Incoming Melee Hits/Crits
table_insert(listenEvents, "CHAT_MSG_COMBAT_PARTY_HITS"); -- Incoming Melee Hits/Crits
table_insert(listenEvents, "CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES"); -- Incoming Melee Misses, Dodges, Parries, Blocks, Absorbs, Immunes
table_insert(listenEvents, "CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES"); -- Incoming Melee Misses, Dodges, Parries, Blocks, Absorbs, Immunes
table_insert(listenEvents, "CHAT_MSG_COMBAT_PARTY_MISSES"); -- Incoming Melee Misses, Dodges, Parries, Blocks, Absorbs, Immunes
table_insert(listenEvents, "CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE"); -- Incoming Spell/Ability Damage, Misses, Dodges, Parries, Blocks, Absorbs, Resists, Immunes, Power Losses
table_insert(listenEvents, "CHAT_MSG_SPELL_CREATURE_VS_CREATURE_DAMAGE"); -- Incoming Spell/Ability Damage, Misses, Dodges, Parries, Blocks, Absorbs, Resists, Immunes, Power Losses -- athenne add
table_insert(listenEvents, "CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE"); -- Incoming Spell/Ability Damage, Misses, Dodges, Parries, Blocks, Absorbs, Resists, Immunes, Power Losses
table_insert(listenEvents, "CHAT_MSG_SPELL_PARTY_DAMAGE"); -- Incoming Spell/Ability Damage, Misses, Dodges, Parries, Blocks, Absorbs, Resists, Immunes, Power Losses
table_insert(listenEvents, "CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS"); -- Incoming damage from shields
table_insert(listenEvents, "CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF"); -- Incoming Heals
table_insert(listenEvents, "CHAT_MSG_SPELL_CREATURE_VS_SELF_BUFF"); -- Incoming Heals
table_insert(listenEvents, "CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE"); -- Incoming Debuffs, DoTs, Power Gains
table_insert(listenEvents, "CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS"); -- Incoming Buffs, HoTs, Power Gains
table_insert(listenEvents, "CHAT_MSG_COMBAT_SELF_HITS"); -- Outgoing Melee Hits/Crits, Environmental Damage
table_insert(listenEvents, "CHAT_MSG_COMBAT_SELF_MISSES"); -- Outgoing Melee Misses, Dodges, Parries, Blocks, Absorbs, Immunes, Evades
table_insert(listenEvents, "CHAT_MSG_SPELL_SELF_DAMAGE"); -- Outgoing Spell/Ability Damage, Misses, Dodges, Parries, Blocks, Absorbs, Resists, Immunes, Evades
table_insert(listenEvents, "CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF"); -- Outgoing damage from shields
table_insert(listenEvents, "CHAT_MSG_SPELL_SELF_BUFF"); -- Outgoing Heals, Power Gains, Dispel/Purge Resists
table_insert(listenEvents, "CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS"); -- Outgoing HoTs
table_insert(listenEvents, "CHAT_MSG_SPELL_PERIODIC_PARTY_BUFFS"); -- Outgoing HoTs
table_insert(listenEvents, "CHAT_MSG_SPELL_PERIODIC_CREATURE_BUFFS");
table_insert(listenEvents, "CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE"); -- Outgoing DoTs
table_insert(listenEvents, "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE"); -- Outgoing DoTs, Power Losses
table_insert(listenEvents, "CHAT_MSG_COMBAT_PET_HITS"); -- Outgoing Pet Melee Hits/Crits
table_insert(listenEvents, "CHAT_MSG_COMBAT_PET_MISSES"); -- Outgoing Pet Melee Misses
table_insert(listenEvents, "CHAT_MSG_SPELL_PET_DAMAGE"); -- Outgoing Pet Spell/Ability Damage, Misses, Dodges, Parries, Blocks, Absorbs, Resists, Immunes, Evades
table_insert(listenEvents, "CHAT_MSG_SPELL_ITEM_ENCHANTMENTS"); -- Item Buffs
table_insert(listenEvents, "CHAT_MSG_SPELL_AURA_GONE_SELF"); -- Buff Fades
table_insert(listenEvents, "CHAT_MSG_COMBAT_HONOR_GAIN"); -- Honor Gains
table_insert(listenEvents, "CHAT_MSG_COMBAT_FACTION_CHANGE"); -- Reputation Gains/Losses
table_insert(listenEvents, "CHAT_MSG_SKILL"); -- Skill Gains
table_insert(listenEvents, "CHAT_MSG_COMBAT_XP_GAIN"); -- Experience Gains
table_insert(listenEvents, "CHAT_MSG_COMBAT_HOSTILE_DEATH"); -- Killing Blows
-- table_insert(listenEvents, "CHAT_MSG_SYSTEM"); -- Created Items
table_insert(listenEvents, "PLAYER_REGEN_ENABLED"); -- Leave Combat
table_insert(listenEvents, "PLAYER_REGEN_DISABLED"); -- Enter Combat
table_insert(listenEvents, "PLAYER_COMBO_POINTS"); -- Combo Point Gains
table_insert(listenEvents, "UNIT_HEALTH"); -- Health changes.
table_insert(listenEvents, "UNIT_MANA"); -- Mana changes.
table_insert(listenEvents, "PLAYER_TARGET_CHANGED"); -- Target changes.
table_insert(listenEvents, "RAID_ROSTER_UPDATE"); -- Roster cache invalidation.
table_insert(listenEvents, "PARTY_MEMBERS_CHANGED"); -- Roster cache invalidation.
-- If Nampower is available, set up Nampower events and filter redundant CHAT_MSG events.
if (GetNampowerVersion ~= nil) then
MikCEH.SetupNampowerEvents();
end
-- Register for the ADDON_LOADED and PLAYER_ENTERING_WORLD events.
MCEHEventFrame:RegisterEvent("ADDON_LOADED");
MCEHEventFrame:RegisterEvent("PLAYER_ENTERING_WORLD");
end
-- **********************************************************************************
-- Called when the events the helper registered for occur.
-- **********************************************************************************
function MikCEH.OnEvent()
-- When an addon is loaded.
if (event == "ADDON_LOADED") then
-- Make sure it's the right addon.
if (arg1 == MikSBT.MOD_NAME) then
-- Don't get notification for other addons being loaded.
this:UnregisterEvent("ADDON_LOADED");
-- Register for the events the helper is interested in receiving.
MikCEH.RegisterEvents();
-- Initialize the helper object.
MikCEH.Init();
end
-- Retry playerGUID initialization when the player fully enters the world.
elseif (event == "PLAYER_ENTERING_WORLD") then
this:UnregisterEvent("PLAYER_ENTERING_WORLD");
if not playerGUID then
if hasSuperWoW and UnitExists("player") then
local _, _, guid = pcall(UnitExists, "player")
if guid then playerGUID = guid end
elseif hasNampower and UnitGUID then
local ok, guid = pcall(UnitGUID, "player")
if ok and guid then playerGUID = guid end
end
end
-- Leave Combat
elseif (event == "PLAYER_REGEN_ENABLED") then
local eventData = MikCEH.GetNotificationEventData(MikCEH.NOTIFICATIONTYPE_COMBAT_LEAVE, nil, nil);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Enter Combat
elseif (event == "PLAYER_REGEN_DISABLED") then
local eventData = MikCEH.GetNotificationEventData(MikCEH.NOTIFICATIONTYPE_COMBAT_ENTER, nil, nil);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Combo Point Gains
elseif (event == "PLAYER_COMBO_POINTS") then
local numCP = GetComboPoints();
-- Make sure the number of combo points is more than one.
if (numCP ~= 0) then
local eventData = MikCEH.GetNotificationEventData(MikCEH.NOTIFICATIONTYPE_CP_GAIN, numCP, nil);
-- Send the event.
MikCEH.SendEvent(eventData);
end
-- Health changes (throttled to reduce CPU in heavy combat)
elseif (event == "UNIT_HEALTH") then
local now = GetTime()
if (now - lastTriggerCheckTime >= TRIGGER_THROTTLE_INTERVAL) then
lastTriggerCheckTime = now
if (arg1 == "player") then
MikCEH.ParseSelfHealthTriggers();
elseif (arg1 == "target") then
if (not UnitIsFriend("player", "target")) then
MikCEH.ParseEnemyHealthTriggers();
else
MikCEH.ParseFriendlyHealthTriggers();
end
elseif (arg1 == "pet") then
MikCEH.ParsePetHealthTriggers();
end
end
-- Mana changes (throttled)
elseif (event == "UNIT_MANA") then
local now = GetTime()
if (now - lastTriggerCheckTime >= TRIGGER_THROTTLE_INTERVAL) then
lastTriggerCheckTime = now
if (arg1 == "player") then
MikCEH.ParseSelfManaTriggers();
end
end
-- Roster changes — invalidate name→unitID cache.
elseif (event == "RAID_ROSTER_UPDATE" or event == "PARTY_MEMBERS_CHANGED") then
nameToUnitIDCacheDirty = true
-- Target changes
elseif (event == "PLAYER_TARGET_CHANGED") then
-- Make sure a unit is selected, is a player and is hostile.
if (UnitExists("target") and UnitIsPlayer("target") and not UnitIsFriend("player", "target")) then
-- Get the unit's name and make sure it's valid before adding it to the recently selected player's list.
local targetName = UnitName("target");
if (targetName) then
recentlySelectedPlayers[targetName] = 0;
end
end
-- Chat message combat events.
else
MikCEH.ParseSearchPatternTriggers(event, arg1);
MikCEH.ParseCombatEvents(event, arg1);
end
end
-- **********************************************************************************
-- This function parses the chat message combat events.
-- **********************************************************************************
function MikCEH.OnUpdate()
-- Increment the amount of time passed since the last update.
elapsedTime = elapsedTime + arg1;
-- Check if it's time for an update.
if (elapsedTime >= RECENTLY_SELECTED_PLAYERS_UPDATE_INTERVAL) then
-- Loop through all of the recently selected players.
for playerName, lastSeen in recentlySelectedPlayers do
-- Increment the amount of time since the player was last seen.
recentlySelectedPlayers[playerName] = lastSeen + elapsedTime;
-- Check if enough time has passed and remove the player from the list.
if (lastSeen + elapsedTime >= RECENTLY_SELECTED_PLAYERS_HOLD_TIME) then
recentlySelectedPlayers[playerName] = nil;
end
end
-- Reset the elapsed time.
elapsedTime = 0;
end
end
-- **********************************************************************************
-- Combat event dispatch table. Maps event names to handler functions.
-- Replaces the if/elseif chain for O(1) dispatch.
-- **********************************************************************************
local combatEventDispatch = {}
-- Incoming Melee Hits/Crits (CVar-gated: AUTO_ATTACK_OTHER)
local function handleIncomingMeleeHits(msg)
if nampowerAutoAttackActive then return end
MikCEH.ParseForIncomingHits(msg)
end
combatEventDispatch["CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS"] = handleIncomingMeleeHits
combatEventDispatch["CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS"] = handleIncomingMeleeHits
combatEventDispatch["CHAT_MSG_COMBAT_PARTY_HITS"] = handleIncomingMeleeHits
-- Incoming Melee Misses, Dodges, Parries, Blocks, Absorbs, Immunes (CVar-gated: AUTO_ATTACK_OTHER)
local function handleIncomingMeleeMisses(msg)
if nampowerAutoAttackActive then return end
MikCEH.ParseForIncomingMisses(msg)
end
combatEventDispatch["CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES"] = handleIncomingMeleeMisses
combatEventDispatch["CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES"] = handleIncomingMeleeMisses
combatEventDispatch["CHAT_MSG_COMBAT_PARTY_MISSES"] = handleIncomingMeleeMisses
-- Incoming Spell/Ability Damage + Power Losses (Nampower: SPELL_DAMAGE_EVENT_OTHER)
local function handleIncomingSpellDamage(msg)
if not nampowerSpellDamageActive then
MikCEH.ParseForIncomingSpellHitsAndMisses(msg)
end
MikCEH.ParseForPowerLosses(msg)
end
combatEventDispatch["CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE"] = handleIncomingSpellDamage
combatEventDispatch["CHAT_MSG_SPELL_CREATURE_VS_CREATURE_DAMAGE"] = handleIncomingSpellDamage
combatEventDispatch["CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE"] = handleIncomingSpellDamage
combatEventDispatch["CHAT_MSG_SPELL_PARTY_DAMAGE"] = handleIncomingSpellDamage
-- Incoming damage from shields (Nampower: SPELL_DAMAGE_EVENT_OTHER)
combatEventDispatch["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS"] = function(msg)
if nampowerSpellDamageActive then return end
MikCEH.ParseForIncomingDamageShieldDamage(msg)
end
-- Incoming Heals (CVar-gated: SPELL_HEAL_ON_SELF)
local function handleIncomingSpellHeals(msg)
if nampowerHealsActive then return end
MikCEH.ParseForIncomingSpellHeals(msg)
end
combatEventDispatch["CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF"] = handleIncomingSpellHeals
combatEventDispatch["CHAT_MSG_SPELL_CREATURE_VS_SELF_BUFF"] = handleIncomingSpellHeals
-- Incoming Debuffs, DoTs, Power Gains
combatEventDispatch["CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE"] = function(msg)
if not nampowerBuffsActive and not nampowerSpellDamageActive then
MikCEH.ParseForIncomingDebuffs(msg)
end
if not nampowerEnergizeActive then
MikCEH.ParseForPowerGains(msg)
end
end
-- Incoming Buffs, HoTs, Power Gains
combatEventDispatch["CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS"] = function(msg)
if not nampowerHealsActive then
if not MikCEH.ParseForIncomingSpellHeals(msg) then
if not nampowerBuffsActive and not nampowerSpellDamageActive then
MikCEH.ParseForIncomingBuffs(msg)
end
MikCEH.ParseForOutgoingHoTs(msg)
end
end
end
-- Outgoing Melee Hits/Crits, Environmental Damage (CVar-gated: AUTO_ATTACK_SELF)
combatEventDispatch["CHAT_MSG_COMBAT_SELF_HITS"] = function(msg)
if not MikCEH.ParseForEnvironmentalDamage(msg) then
if not nampowerAutoAttackActive then
MikCEH.ParseForOutgoingHits(msg)
end
end
end
-- Outgoing Melee Misses (CVar-gated: AUTO_ATTACK_SELF)
combatEventDispatch["CHAT_MSG_COMBAT_SELF_MISSES"] = function(msg)
if nampowerAutoAttackActive then return end
MikCEH.ParseForOutgoingMisses(msg)
end
-- Outgoing Spell/Ability Damage (Nampower: SPELL_DAMAGE_EVENT_SELF)
combatEventDispatch["CHAT_MSG_SPELL_SELF_DAMAGE"] = function(msg)
if nampowerSpellDamageActive then return end
MikCEH.ParseForOutgoingSpellHitsAndMisses(msg)
end
-- Outgoing damage from shields (Nampower: SPELL_DAMAGE_EVENT_SELF)
combatEventDispatch["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF"] = function(msg)
if nampowerSpellDamageActive then return end
MikCEH.ParseForOutgoingDamageShieldDamage(msg)
end
-- Outgoing Heals, Power Gains, Dispel/Purge Resists (CVar-gated: SPELL_HEAL_BY_SELF, SPELL_ENERGIZE_ON_SELF)
combatEventDispatch["CHAT_MSG_SPELL_SELF_BUFF"] = function(msg)
if not nampowerEnergizeActive then
if MikCEH.ParseForPowerGains(msg) then return end
end
if not nampowerHealsActive then
MikCEH.ParseForOutgoingSpellHeals(msg)
MikCEH.ParseForOutgoingDispelResists(msg)
end
end
-- Outgoing HoTs (CVar-gated: SPELL_HEAL_BY_SELF)
local function handleOutgoingHoTs(msg)
if nampowerHealsActive then return end
MikCEH.ParseForOutgoingHoTs(msg)
end
combatEventDispatch["CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS"] = handleOutgoingHoTs
combatEventDispatch["CHAT_MSG_SPELL_PERIODIC_PARTY_BUFFS"] = handleOutgoingHoTs
combatEventDispatch["CHAT_MSG_SPELL_PERIODIC_CREATURE_BUFFS"] = handleOutgoingHoTs
-- Outgoing DoTs, Power Losses (Nampower: SPELL_DAMAGE_EVENT_SELF with DoT flag)
local function handleOutgoingDoTs(msg)
if not nampowerSpellDamageActive then
MikCEH.ParseForOutgoingDoTs(msg)
end
MikCEH.ParseForPowerLosses(msg)
end
combatEventDispatch["CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE"] = handleOutgoingDoTs
combatEventDispatch["CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE"] = handleOutgoingDoTs
-- Outgoing Pet Hits/Crits (CVar-gated: AUTO_ATTACK_SELF with pet GUID)
combatEventDispatch["CHAT_MSG_COMBAT_PET_HITS"] = function(msg)
if nampowerPetAutoAttackActive then return end
MikCEH.ParseForOutgoingPetHits(msg)
end
-- Outgoing Pet Melee Misses (CVar-gated: AUTO_ATTACK_SELF with pet GUID)
combatEventDispatch["CHAT_MSG_COMBAT_PET_MISSES"] = function(msg)
if nampowerPetAutoAttackActive then return end
MikCEH.ParseForOutgoingPetMisses(msg)
end
-- Outgoing Pet Spell/Ability Damage (Nampower: SPELL_DAMAGE_EVENT_SELF with pet GUID)
combatEventDispatch["CHAT_MSG_SPELL_PET_DAMAGE"] = function(msg)
if nampowerPetSpellDamageActive then return end
MikCEH.ParseForOutgoingPetSpellHitsAndMisses(msg)
end
-- Item Buffs
combatEventDispatch["CHAT_MSG_SPELL_ITEM_ENCHANTMENTS"] = function(msg)
MikCEH.ParseForIncomingItemBuffs(msg)
end
-- Buff Fades
combatEventDispatch["CHAT_MSG_SPELL_AURA_GONE_SELF"] = function(msg)
MikCEH.ParseForBuffFades(msg)
end
-- Honor Gains
combatEventDispatch["CHAT_MSG_COMBAT_HONOR_GAIN"] = function(msg)
MikCEH.ParseForHonorGains(msg)
end
-- Reputation Gains/Losses
combatEventDispatch["CHAT_MSG_COMBAT_FACTION_CHANGE"] = function(msg)
MikCEH.ParseForReputationGainsAndLosses(msg)
end
-- Skill Gains
combatEventDispatch["CHAT_MSG_SKILL"] = function(msg)
MikCEH.ParseForSkillGains(msg)
end
-- Experience Gains
combatEventDispatch["CHAT_MSG_COMBAT_XP_GAIN"] = function(msg)
MikCEH.ParseForExperienceGains(msg)
end
-- Killing Blows
combatEventDispatch["CHAT_MSG_COMBAT_HOSTILE_DEATH"] = function(msg)
MikCEH.ParseForKillingBlows(msg)
end
-- **********************************************************************************
-- This function parses the chat message combat events using the dispatch table.
-- **********************************************************************************
function MikCEH.ParseCombatEvents(event, combatMessage)
cachedPetName = UnitName("pet");
local handler = combatEventDispatch[event]
if handler then handler(combatMessage) end
end
-- **********************************************************************************
-- Called when the helper is fully loaded.
-- **********************************************************************************
function MikCEH.Init()
-- Get the name of the player and the player's class.
playerName = UnitName("player");
_, playerClass = UnitClass("player");
-- Detect enhanced combat event mods.
hasNampower = (GetNampowerVersion ~= nil)
hasSuperWoW = (SUPERWOW_VERSION ~= nil) or (SetAutoloot ~= nil and SpellInfo ~= nil)
hasUnitXP = pcall(UnitXP, "nop", "nop")
MikCEH.hasNampower = hasNampower
MikCEH.hasSuperWoW = hasSuperWoW
MikCEH.hasUnitXP = hasUnitXP
MikCEH.nampowerHealsActive = false
MikCEH.nampowerAutoAttackActive = false
MikCEH.nampowerEnergizeActive = false
MikCEH.nampowerSpellDamageActive = false
MikCEH.nampowerBuffsActive = false
MikCEH.nampowerPetAutoAttackActive = false
MikCEH.nampowerPetSpellDamageActive = false
-- Check Nampower version — v2.33.0+ required for correct event support.
if not hasNampower then
MikSBT.Print("Nampower not detected. Please install Nampower v2.33.0+ for full combat text support.", 1, 0.5, 0)
else
local ok, major, minor, patch = pcall(GetNampowerVersion)
if ok and major and minor then
if major < 2 or (major == 2 and minor < 33) then
MikSBT.Print("Nampower v" .. major .. "." .. minor .. "." .. (patch or 0) .. " detected. Please update to v2.33.0+ for full combat text support.", 1, 0.5, 0)
end
end
end
-- Cache the player GUID when SuperWoW or Nampower is available.
if hasSuperWoW and UnitExists("player") then
local _, _, guid = pcall(UnitExists, "player")
if guid then playerGUID = guid end
elseif hasNampower and UnitGUID then
local ok, guid = pcall(UnitGUID, "player")
if ok and guid then playerGUID = guid end
end
end
-------------------------------------------------------------------------------------
-- Nampower / SuperWoW / UnitXP Infrastructure.
-------------------------------------------------------------------------------------
-- Spell school index (Nampower) to MikCEH damage type mapping.
-- Nampower reports the school as a sequential index (0 = Physical, 1 = Holy,
-- 2 = Fire, ...), not the power-of-two bitmask the comment previously assumed.
local nampowerSchoolToType = {
[0] = MikCEH.DAMAGETYPE_PHYSICAL,
MikCEH.DAMAGETYPE_HOLY,
MikCEH.DAMAGETYPE_FIRE,
MikCEH.DAMAGETYPE_NATURE,
MikCEH.DAMAGETYPE_FROST,
MikCEH.DAMAGETYPE_SHADOW,
MikCEH.DAMAGETYPE_ARCANE,
}
-- Nampower SpellMissInfo to MikCEH action type mapping.
local nampowerMissToAction = {
-- [0] = SPELL_MISS_NONE (should not appear)
[1] = MikCEH.ACTIONTYPE_MISS, -- SPELL_MISS_MISS
[2] = MikCEH.ACTIONTYPE_RESIST, -- SPELL_MISS_RESIST
[3] = MikCEH.ACTIONTYPE_DODGE, -- SPELL_MISS_DODGE
[4] = MikCEH.ACTIONTYPE_PARRY, -- SPELL_MISS_PARRY
[5] = MikCEH.ACTIONTYPE_BLOCK, -- SPELL_MISS_BLOCK
[6] = MikCEH.ACTIONTYPE_EVADE, -- SPELL_MISS_EVADE
[7] = MikCEH.ACTIONTYPE_IMMUNE, -- SPELL_MISS_IMMUNE
[8] = MikCEH.ACTIONTYPE_IMMUNE, -- SPELL_MISS_IMMUNE2
-- [9] = SPELL_MISS_DEFLECT (no equivalent)
[10] = MikCEH.ACTIONTYPE_ABSORB, -- SPELL_MISS_ABSORB
[11] = MikCEH.ACTIONTYPE_REFLECT, -- SPELL_MISS_REFLECT
}
-- Nampower victimState to MikCEH action type mapping (for auto attacks).
local nampowerVictimStateToAction = {
[0] = MikCEH.ACTIONTYPE_MISS, -- VICTIMSTATE_UNAFFECTED (seen with HITINFO_MISS)
[1] = MikCEH.ACTIONTYPE_HIT, -- VICTIMSTATE_NORMAL
[2] = MikCEH.ACTIONTYPE_DODGE, -- VICTIMSTATE_DODGE
[3] = MikCEH.ACTIONTYPE_PARRY, -- VICTIMSTATE_PARRY
[4] = MikCEH.ACTIONTYPE_HIT, -- VICTIMSTATE_INTERRUPT (treat as hit)
[5] = MikCEH.ACTIONTYPE_BLOCK, -- VICTIMSTATE_BLOCKS
[6] = MikCEH.ACTIONTYPE_EVADE, -- VICTIMSTATE_EVADES
[7] = MikCEH.ACTIONTYPE_IMMUNE, -- VICTIMSTATE_IS_IMMUNE
[8] = MikCEH.ACTIONTYPE_HIT, -- VICTIMSTATE_DEFLECTS (treat as hit)
}
-- HitInfo bitmask constants.
local HITINFO_MISS = 16
local HITINFO_CRITICALHIT = 128
local HITINFO_GLANCING = 16384
local HITINFO_CRUSHING = 32768
-- Nampower power type to localized string mapping.
local nampowerPowerTypeToString = {
[0] = MANA,
[1] = RAGE,
[3] = ENERGY,
}
-- **********************************************************************************
-- Resolves a name from a GUID using SuperWoW or Nampower APIs.
-- **********************************************************************************
local function GetNameFromGUID(guid)
if not guid then return nil end
if hasSuperWoW then
local ok, exists, uid = pcall(UnitExists, guid)
if ok and exists then return UnitName(uid) end
end
if hasNampower and GetUnitField then
local ok, name = pcall(GetUnitField, guid, "name")
if ok and name then return name end
end
return nil
end
-- **********************************************************************************
-- Checks if the given GUID belongs to the player.
-- **********************************************************************************
local function IsPlayerGUID(guid)
return playerGUID and guid == playerGUID
end
-- **********************************************************************************
-- Checks if the given GUID belongs to the player's pet.
-- **********************************************************************************
local function IsPetGUID(guid)
if not guid or not UnitExists("pet") then return false end
if hasSuperWoW then
local ok, exists, uid = pcall(UnitExists, guid)
if ok and exists then return uid == "pet" or UnitName(uid) == UnitName("pet") end
end
if hasNampower and UnitGUID then
local ok, petGuid = pcall(UnitGUID, "pet")
if ok and petGuid then return guid == petGuid end
end
return false
end
-- **********************************************************************************
-- Converts a Nampower spell school index to a MikCEH damage type.
-- **********************************************************************************
local function SchoolToDamageType(school)
if not school then return MikCEH.DAMAGETYPE_PHYSICAL end
return nampowerSchoolToType[school] or MikCEH.DAMAGETYPE_PHYSICAL
end
-- **********************************************************************************
-- Gets a spell name from a spellId, using SuperWoW or Nampower APIs with caching.
-- **********************************************************************************
local function GetSpellNameFromId(spellId)
if not spellId or spellId == 0 then return nil end
if spellNameCache[spellId] then return spellNameCache[spellId] end
local name
if hasSuperWoW and SpellInfo then
local ok, n = pcall(SpellInfo, spellId)
if ok and n then name = n end
end
if not name and hasNampower and GetSpellNameAndRankForId then
local ok, n = pcall(GetSpellNameAndRankForId, spellId)
if ok and n then name = n end
end
if name then spellNameCache[spellId] = name end
return name
end
-- **********************************************************************************
-- Parses Nampower mitigation string ("absorb,block,resist") into partial actions.
-- **********************************************************************************
local function ParseNampowerMitigation(mitigationStr, eventData)
if not mitigationStr or mitigationStr == "" then return end
-- Format: "absorbAmount,blockAmount,resistAmount"
local _, _, a, b, r = string_find(mitigationStr, "^([^,]*),([^,]*),([^,]*)$")
local absorb = tonumber(a)
local block = tonumber(b)
local resist = tonumber(r)
-- Set the first non-zero mitigation as the partial action.
if absorb and absorb > 0 then
eventData.PartialActionType = MikCEH.PARTIALACTIONTYPE_ABSORB
eventData.PartialAmount = absorb
elseif block and block > 0 then
eventData.PartialActionType = MikCEH.PARTIALACTIONTYPE_BLOCK
eventData.PartialAmount = block
elseif resist and resist > 0 then
eventData.PartialActionType = MikCEH.PARTIALACTIONTYPE_RESIST
eventData.PartialAmount = resist
end
end
-- **********************************************************************************
-- Ensures playerGUID is set. Called lazily by Nampower event handlers since
-- UnitGUID may not be available during ADDON_LOADED for some users.
-- **********************************************************************************
local function EnsurePlayerGUID()
if playerGUID then return true end
if hasSuperWoW and UnitExists("player") then
local _, _, guid = pcall(UnitExists, "player")
if guid then playerGUID = guid; return true end
end
if hasNampower and UnitGUID then
local ok, guid = pcall(UnitGUID, "player")
if ok and guid then playerGUID = guid; return true end
end
return false
end
-- **********************************************************************************
-- Nampower event dispatcher — called by the Nampower event frame's OnEvent.
-- **********************************************************************************
function MikCEH.OnNampowerEvent()
EnsurePlayerGUID()
local handler = nampowerHandlers[event]
if handler then handler() end
end
-------------------------------------------------------------------------------------
-- Nampower Event Handlers.
-------------------------------------------------------------------------------------
-- **********************************************************************************
-- SPELL_DAMAGE_EVENT_SELF: Outgoing spell damage (player and pet).
-- Args: targetGuid, casterGuid, spellId, amount, mitigationStr, hitInfo, spellSchool, effectAuraStr
-- **********************************************************************************
nampowerHandlers["SPELL_DAMAGE_EVENT_SELF"] = function()
local targetGuid, casterGuid = arg1, arg2
local spellId = arg3
local damage = arg4
local mitigationStr = arg5
local hitInfo = arg6
local spellSchool = arg7
local effectAuraStr = arg8
-- Determine direction: player outgoing, or pet outgoing.
-- Special case: if the player is both caster and target (e.g. Hellfire self-damage,
-- spell reflects), route as incoming since the player is taking damage.
local directionType
if IsPlayerGUID(casterGuid) then
if IsPlayerGUID(targetGuid) then
directionType = MikCEH.DIRECTIONTYPE_PLAYER_INCOMING
else
directionType = MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING
end
nampowerSpellDamageActive = true
elseif IsPetGUID(casterGuid) then
directionType = MikCEH.DIRECTIONTYPE_PET_OUTGOING
nampowerPetSpellDamageActive = true
else
return -- Not from player or pet, ignore.
end
local spellName = GetSpellNameFromId(spellId)
local damageType = SchoolToDamageType(spellSchool)
local targetName = GetNameFromGUID(targetGuid)
-- Check if this is a DoT (periodic aura effect).
-- effectAuraStr format: "effect1,effect2,effect3,auraType"
local isDoT = false
if effectAuraStr then
local _, _, auraTypeStr = string_find(effectAuraStr, "%d+,%d+,%d+,(%d+)")
local auraType = tonumber(auraTypeStr)
if auraType == 3 or auraType == 89 then isDoT = true end
end
local hitType
if isDoT then
hitType = MikCEH.HITTYPE_OVER_TIME
elseif hitInfo and hitInfo ~= 0 then
hitType = MikCEH.HITTYPE_CRIT
else
hitType = MikCEH.HITTYPE_NORMAL
end
local eventData = MikCEH.GetDamageEventData(directionType, MikCEH.ACTIONTYPE_HIT, hitType, damageType, damage, spellName, targetName)
eventData.SpellId = spellId
-- Parse mitigation string for partial actions.
ParseNampowerMitigation(mitigationStr, eventData)
MikCEH.SendEvent(eventData)
end
-- **********************************************************************************
-- SPELL_DAMAGE_EVENT_OTHER: Incoming spell damage (to player or pet).
-- Args: targetGuid, casterGuid, spellId, amount, mitigationStr, hitInfo, spellSchool, effectAuraStr
-- **********************************************************************************
nampowerHandlers["SPELL_DAMAGE_EVENT_OTHER"] = function()
local targetGuid, casterGuid = arg1, arg2
local spellId = arg3
local damage = arg4
local mitigationStr = arg5
local hitInfo = arg6
local spellSchool = arg7
local effectAuraStr = arg8
-- Only process if target is player or pet.
local directionType
if IsPlayerGUID(targetGuid) then
directionType = MikCEH.DIRECTIONTYPE_PLAYER_INCOMING
elseif IsPetGUID(targetGuid) then
directionType = MikCEH.DIRECTIONTYPE_PET_INCOMING
else
return
end
local spellName = GetSpellNameFromId(spellId)
local damageType = SchoolToDamageType(spellSchool)
local casterName = GetNameFromGUID(casterGuid)
-- effectAuraStr format: "effect1,effect2,effect3,auraType"
local isDoT = false
if effectAuraStr then
local _, _, auraTypeStr = string_find(effectAuraStr, "%d+,%d+,%d+,(%d+)")
local auraType = tonumber(auraTypeStr)
if auraType == 3 or auraType == 89 then isDoT = true end
end
local hitType
if isDoT then
hitType = MikCEH.HITTYPE_OVER_TIME
elseif hitInfo and hitInfo ~= 0 then
hitType = MikCEH.HITTYPE_CRIT
else
hitType = MikCEH.HITTYPE_NORMAL
end
local eventData = MikCEH.GetDamageEventData(directionType, MikCEH.ACTIONTYPE_HIT, hitType, damageType, damage, spellName, casterName)
eventData.SpellId = spellId
ParseNampowerMitigation(mitigationStr, eventData)
MikCEH.SendEvent(eventData)
end
-- **********************************************************************************
-- AUTO_ATTACK_SELF: Outgoing melee auto-attacks.
-- Args: attackerGuid, targetGuid, totalDamage, hitInfo, victimState, subDamageCount, blockedAmount, totalAbsorb, totalResist
-- **********************************************************************************
nampowerHandlers["AUTO_ATTACK_SELF"] = function()
local casterGuid, targetGuid = arg1, arg2
local damage = arg3
local hitInfo = arg4
local victimState = arg5
-- arg6 = subDamageCount (not needed)
local blockedDmg = arg7 or 0
local absorbedDmg = arg8 or 0
local resistedDmg = arg9 or 0
local directionType
if IsPlayerGUID(casterGuid) then
directionType = MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING
nampowerAutoAttackActive = true
elseif IsPetGUID(casterGuid) then
directionType = MikCEH.DIRECTIONTYPE_PET_OUTGOING
nampowerPetAutoAttackActive = true
else
return
end
local targetName = GetNameFromGUID(targetGuid)
local actionType = nampowerVictimStateToAction[victimState] or MikCEH.ACTIONTYPE_HIT
-- If victimState indicates a full miss/dodge/parry/etc with no damage, send as miss event.
if actionType ~= MikCEH.ACTIONTYPE_HIT then
local eventData = MikCEH.GetDamageEventData(directionType, actionType, nil, nil, nil, nil, targetName)
MikCEH.SendEvent(eventData)
return
end
-- Determine hit type from hitInfo bitmask.
local hitType = MikCEH.HITTYPE_NORMAL
if hitInfo and bit and bit.band then
if bit.band(hitInfo, HITINFO_CRITICALHIT) ~= 0 then
hitType = MikCEH.HITTYPE_CRIT
end
end
local eventData = MikCEH.GetDamageEventData(directionType, MikCEH.ACTIONTYPE_HIT, hitType, MikCEH.DAMAGETYPE_PHYSICAL, damage, nil, targetName)
-- Set partial actions from hitInfo and mitigation values.
if hitInfo and bit and bit.band then
if bit.band(hitInfo, HITINFO_CRUSHING) ~= 0 then
eventData.PartialActionType = MikCEH.PARTIALACTIONTYPE_CRUSHING
elseif bit.band(hitInfo, HITINFO_GLANCING) ~= 0 then
eventData.PartialActionType = MikCEH.PARTIALACTIONTYPE_GLANCING
end
end
-- If no crushing/glancing, check mitigation values.
if not eventData.PartialActionType then
if absorbedDmg > 0 then
eventData.PartialActionType = MikCEH.PARTIALACTIONTYPE_ABSORB
eventData.PartialAmount = absorbedDmg
elseif blockedDmg > 0 then
eventData.PartialActionType = MikCEH.PARTIALACTIONTYPE_BLOCK
eventData.PartialAmount = blockedDmg
elseif resistedDmg > 0 then
eventData.PartialActionType = MikCEH.PARTIALACTIONTYPE_RESIST
eventData.PartialAmount = resistedDmg
end
end
MikCEH.SendEvent(eventData)
end
-- **********************************************************************************
-- AUTO_ATTACK_OTHER: Incoming melee auto-attacks (to player or pet).
-- Args: attackerGuid, targetGuid, totalDamage, hitInfo, victimState, subDamageCount, blockedAmount, totalAbsorb, totalResist
-- **********************************************************************************
nampowerHandlers["AUTO_ATTACK_OTHER"] = function()
local casterGuid, targetGuid = arg1, arg2
local damage = arg3
local hitInfo = arg4
local victimState = arg5
-- arg6 = subDamageCount (not needed)
local blockedDmg = arg7 or 0
local absorbedDmg = arg8 or 0
local resistedDmg = arg9 or 0
local directionType
if IsPlayerGUID(targetGuid) then
directionType = MikCEH.DIRECTIONTYPE_PLAYER_INCOMING
nampowerAutoAttackActive = true
elseif IsPetGUID(targetGuid) then
directionType = MikCEH.DIRECTIONTYPE_PET_INCOMING
else
return
end
local casterName = GetNameFromGUID(casterGuid)
local actionType = nampowerVictimStateToAction[victimState] or MikCEH.ACTIONTYPE_HIT
if actionType ~= MikCEH.ACTIONTYPE_HIT then
local eventData = MikCEH.GetDamageEventData(directionType, actionType, nil, nil, nil, nil, casterName)
MikCEH.SendEvent(eventData)
return
end
local hitType = MikCEH.HITTYPE_NORMAL
if hitInfo and bit and bit.band then
if bit.band(hitInfo, HITINFO_CRITICALHIT) ~= 0 then
hitType = MikCEH.HITTYPE_CRIT
end
end
local eventData = MikCEH.GetDamageEventData(directionType, MikCEH.ACTIONTYPE_HIT, hitType, MikCEH.DAMAGETYPE_PHYSICAL, damage, nil, casterName)
if hitInfo and bit and bit.band then
if bit.band(hitInfo, HITINFO_CRUSHING) ~= 0 then
eventData.PartialActionType = MikCEH.PARTIALACTIONTYPE_CRUSHING
elseif bit.band(hitInfo, HITINFO_GLANCING) ~= 0 then
eventData.PartialActionType = MikCEH.PARTIALACTIONTYPE_GLANCING
end
end
if not eventData.PartialActionType then
if absorbedDmg > 0 then
eventData.PartialActionType = MikCEH.PARTIALACTIONTYPE_ABSORB
eventData.PartialAmount = absorbedDmg
elseif blockedDmg > 0 then
eventData.PartialActionType = MikCEH.PARTIALACTIONTYPE_BLOCK
eventData.PartialAmount = blockedDmg
elseif resistedDmg > 0 then
eventData.PartialActionType = MikCEH.PARTIALACTIONTYPE_RESIST
eventData.PartialAmount = resistedDmg
end
end
MikCEH.SendEvent(eventData)
end
-- **********************************************************************************
-- SPELL_HEAL_ON_SELF: Incoming heals (heals landing on the player).
-- Args: targetGuid, casterGuid, spellId, amount, critical, periodic
-- **********************************************************************************
nampowerHandlers["SPELL_HEAL_ON_SELF"] = function()
local targetGuid, casterGuid = arg1, arg2
local spellId = arg3
local healAmount = arg4
local isCrit = arg5
local isHot = arg6
-- Only for player.
if not IsPlayerGUID(targetGuid) then return end
-- Only disable CHAT_MSG fallback after we've confirmed playerGUID works.
nampowerHealsActive = true
local spellName = GetSpellNameFromId(spellId)
local casterName = GetNameFromGUID(casterGuid)
local healType
if isHot and isHot ~= 0 then
healType = MikCEH.HEALTYPE_OVER_TIME
elseif isCrit and isCrit ~= 0 then
healType = MikCEH.HEALTYPE_CRIT
else
healType = MikCEH.HEALTYPE_NORMAL
end
local eventData = MikCEH.GetHealEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, healType, healAmount, spellName, casterName)
eventData.SpellId = spellId
-- Populate overheal data.
eventData.Name = playerName
MikCEH.PopulateOverhealData(eventData)
eventData.Name = casterName
MikCEH.SendEvent(eventData)
end
-- **********************************************************************************
-- SPELL_HEAL_BY_SELF: Outgoing heals (heals cast by the player).
-- Args: targetGuid, casterGuid, spellId, amount, critical, periodic
-- **********************************************************************************
nampowerHandlers["SPELL_HEAL_BY_SELF"] = function()
local targetGuid, casterGuid = arg1, arg2
local spellId = arg3
local healAmount = arg4
local isCrit = arg5
local isHot = arg6
-- Skip self-heals (handled by SPELL_HEAL_ON_SELF).
-- When playerGUID is nil, we can't identify self-heals, so bail out
-- and let the CHAT_MSG fallback handle it.
if not playerGUID then return end
if IsPlayerGUID(targetGuid) then return end
-- Only disable CHAT_MSG fallback after we've confirmed playerGUID works.
nampowerHealsActive = true
local spellName = GetSpellNameFromId(spellId)
local targetName = GetNameFromGUID(targetGuid)
local healType
if isHot and isHot ~= 0 then
healType = MikCEH.HEALTYPE_OVER_TIME
elseif isCrit and isCrit ~= 0 then
healType = MikCEH.HEALTYPE_CRIT
else
healType = MikCEH.HEALTYPE_NORMAL
end
local eventData = MikCEH.GetHealEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, healType, healAmount, spellName, targetName)
eventData.SpellId = spellId
-- Populate overheal data.
MikCEH.PopulateOverhealData(eventData)
MikCEH.SendEvent(eventData)
end
-- **********************************************************************************
-- SPELL_ENERGIZE_ON_SELF: Power gains on the player (mana, rage, energy).
-- Args: targetGuid, casterGuid, spellId, powerType, amount, periodic
-- **********************************************************************************
nampowerHandlers["SPELL_ENERGIZE_ON_SELF"] = function()
local spellId = arg3
local powerType = arg4
local amount = arg5
local powerTypeStr = nampowerPowerTypeToString[powerType]
if not powerTypeStr then return end
-- Only disable CHAT_MSG fallback after we've confirmed this handler works.
nampowerEnergizeActive = true
local spellName = GetSpellNameFromId(spellId)
local eventData = MikCEH.GetNotificationEventData(MikCEH.NOTIFICATIONTYPE_POWER_GAIN, amount, powerTypeStr, spellName)
eventData.SpellId = spellId
MikCEH.SendEvent(eventData)
end
-- **********************************************************************************
-- SPELL_MISS_SELF: Outgoing spell misses (player's spell missed).
-- Args: casterGuid, targetGuid, spellId, missInfo
-- **********************************************************************************
nampowerHandlers["SPELL_MISS_SELF"] = function()
local casterGuid, targetGuid = arg1, arg2
local spellId = arg3
local missInfo = arg4
local directionType
if IsPlayerGUID(casterGuid) then
directionType = MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING
nampowerSpellDamageActive = true
elseif IsPetGUID(casterGuid) then
directionType = MikCEH.DIRECTIONTYPE_PET_OUTGOING
nampowerPetSpellDamageActive = true
else
return
end
local spellName = GetSpellNameFromId(spellId)
local targetName = GetNameFromGUID(targetGuid)
local actionType = nampowerMissToAction[missInfo] or MikCEH.ACTIONTYPE_MISS
local eventData = MikCEH.GetDamageEventData(directionType, actionType, nil, nil, nil, spellName, targetName)
eventData.SpellId = spellId
MikCEH.SendEvent(eventData)
end
-- **********************************************************************************
-- SPELL_MISS_OTHER: Incoming spell misses (enemy's spell missed the player).
-- Args: casterGuid, targetGuid, spellId, missInfo
-- **********************************************************************************
nampowerHandlers["SPELL_MISS_OTHER"] = function()
local casterGuid, targetGuid = arg1, arg2
local spellId = arg3
local missInfo = arg4
-- Only process if target is player or pet.
local directionType
if IsPlayerGUID(targetGuid) then
directionType = MikCEH.DIRECTIONTYPE_PLAYER_INCOMING
elseif IsPetGUID(targetGuid) then
directionType = MikCEH.DIRECTIONTYPE_PET_INCOMING
else
return
end
local spellName = GetSpellNameFromId(spellId)
local casterName = GetNameFromGUID(casterGuid)
local actionType = nampowerMissToAction[missInfo] or MikCEH.ACTIONTYPE_MISS
local eventData = MikCEH.GetDamageEventData(directionType, actionType, nil, nil, nil, spellName, casterName)
eventData.SpellId = spellId
MikCEH.SendEvent(eventData)
end
-- **********************************************************************************
-- BUFF_ADDED_SELF: Buff gained by the player.
-- Args: guid, luaSlot, spellId, stackCount, auraLevel, auraSlot, state
-- **********************************************************************************
nampowerHandlers["BUFF_ADDED_SELF"] = function()
local unitGuid = arg1
local spellId = arg3
local state = arg7
-- Only for player.
if not IsPlayerGUID(unitGuid) then return end
nampowerBuffsActive = true
-- Only notify for newly added buffs (state 0), not stack changes (state 2).
if state ~= 0 then return end
local spellName = GetSpellNameFromId(spellId)
if not spellName then return end
local eventData = MikCEH.GetNotificationEventData(MikCEH.NOTIFICATIONTYPE_BUFF, nil, spellName)
eventData.SpellId = spellId
MikCEH.SendEvent(eventData)
end
-- **********************************************************************************
-- DEBUFF_ADDED_SELF: Debuff gained by the player.
-- Args: guid, luaSlot, spellId, stackCount, auraLevel, auraSlot, state
-- **********************************************************************************
nampowerHandlers["DEBUFF_ADDED_SELF"] = function()
local unitGuid = arg1
local spellId = arg3
local state = arg7
-- Only for player.
if not IsPlayerGUID(unitGuid) then return end
nampowerBuffsActive = true
-- Only notify for newly added debuffs (state 0), not stack changes (state 2).
if state ~= 0 then return end
local spellName = GetSpellNameFromId(spellId)
if not spellName then return end
local eventData = MikCEH.GetNotificationEventData(MikCEH.NOTIFICATIONTYPE_DEBUFF, nil, spellName)
eventData.SpellId = spellId
MikCEH.SendEvent(eventData)
end
-- **********************************************************************************
-- BUFF_REMOVED_SELF: Buff faded from the player.
-- Args: guid, luaSlot, spellId, stackCount, auraLevel, auraSlot, state
-- **********************************************************************************
nampowerHandlers["BUFF_REMOVED_SELF"] = function()
local unitGuid = arg1
local spellId = arg3
-- Only for player.
if not IsPlayerGUID(unitGuid) then return end
local spellName = GetSpellNameFromId(spellId)
if not spellName then return end
local eventData = MikCEH.GetNotificationEventData(MikCEH.NOTIFICATIONTYPE_BUFF_FADE, nil, spellName)
eventData.SpellId = spellId
MikCEH.SendEvent(eventData)
end
-- **********************************************************************************
-- DEBUFF_REMOVED_SELF: Debuff faded from the player.
-- Args: guid, luaSlot, spellId, stackCount, auraLevel, auraSlot, state
-- **********************************************************************************
nampowerHandlers["DEBUFF_REMOVED_SELF"] = function()
local unitGuid = arg1
local spellId = arg3
-- Only for player.
if not IsPlayerGUID(unitGuid) then return end
local spellName = GetSpellNameFromId(spellId)
if not spellName then return end
local eventData = MikCEH.GetNotificationEventData(MikCEH.NOTIFICATIONTYPE_BUFF_FADE, nil, spellName)
eventData.SpellId = spellId
MikCEH.SendEvent(eventData)
end
-------------------------------------------------------------------------------------
-- Nampower Event Setup.
-------------------------------------------------------------------------------------
-- **********************************************************************************
-- Sets up Nampower event listeners and removes redundant CHAT_MSG events.
-- Called from OnLoad when Nampower is detected.
-- **********************************************************************************
function MikCEH.SetupNampowerEvents()
-- Enable Nampower CVars required for the events we depend on.
-- These are disabled by default but we suppress CHAT_MSG events they replace.
if SetCVar then
SetCVar("NP_EnableAutoAttackEvents", "1")
SetCVar("NP_EnableSpellHealEvents", "1")
SetCVar("NP_EnableSpellEnergizeEvents", "1")
end
-- All Nampower event equivalents now use runtime detection flags
-- (nampowerSpellDamageActive, nampowerAutoAttackActive, etc.) instead of
-- permanently unregistering CHAT_MSG events. This ensures fallback to CHAT_MSG
-- parsing if a Nampower event doesn't fire for certain targets (e.g. NPCs).
-- Only CHAT_MSG_SPELL_AURA_GONE_SELF is safe to remove (covered by BUFF/DEBUFF_REMOVED_SELF).
local nampowerCoveredEvents = {
["CHAT_MSG_SPELL_AURA_GONE_SELF"] = true,
}
-- Events to keep despite Nampower — these have partial or no Nampower equivalent.
-- CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE: Keep for power gains (no Nampower equivalent for all gain types)
-- CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS: Keep for power gains (buff parsing gated by nampowerBuffsActive)
-- CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE: Keep for power losses (ParseForPowerLosses)
-- CHAT_MSG_SPELL_CREATURE_VS_CREATURE_DAMAGE: Keep for power losses
-- CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE: Keep for power losses
-- CHAT_MSG_SPELL_PARTY_DAMAGE: Keep for power losses
-- CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE: Keep for power losses
-- CHAT_MSG_COMBAT_SELF_HITS: Keep for environmental damage only
-- CHAT_MSG_SPELL_ITEM_ENCHANTMENTS, CHAT_MSG_COMBAT_HONOR_GAIN, etc.: No Nampower equivalent
-- Filter out covered events from listenEvents.
local filteredEvents = {}
for _, eventName in listenEvents do
if not nampowerCoveredEvents[eventName] then
table_insert(filteredEvents, eventName)
end
end
-- Replace listenEvents with filtered list.
-- Clear and repopulate to maintain the same table reference.
for i = table_getn(listenEvents), 1, -1 do
listenEvents[i] = nil
end
table_setn(listenEvents, 0)
for _, eventName in filteredEvents do
table_insert(listenEvents, eventName)
end
-- Create the Nampower event frame and register for Nampower events.
nampowerEventFrame = CreateFrame("Frame")
nampowerEventFrame:SetScript("OnEvent", MikCEH.OnNampowerEvent)
nampowerEventFrame:RegisterEvent("SPELL_DAMAGE_EVENT_SELF")
nampowerEventFrame:RegisterEvent("SPELL_DAMAGE_EVENT_OTHER")
nampowerEventFrame:RegisterEvent("AUTO_ATTACK_SELF")
nampowerEventFrame:RegisterEvent("AUTO_ATTACK_OTHER")
nampowerEventFrame:RegisterEvent("SPELL_HEAL_BY_SELF")
nampowerEventFrame:RegisterEvent("SPELL_HEAL_ON_SELF")
nampowerEventFrame:RegisterEvent("SPELL_ENERGIZE_ON_SELF")
nampowerEventFrame:RegisterEvent("SPELL_MISS_SELF")
nampowerEventFrame:RegisterEvent("SPELL_MISS_OTHER")
nampowerEventFrame:RegisterEvent("BUFF_ADDED_SELF")
nampowerEventFrame:RegisterEvent("BUFF_REMOVED_SELF")
nampowerEventFrame:RegisterEvent("DEBUFF_ADDED_SELF")
nampowerEventFrame:RegisterEvent("DEBUFF_REMOVED_SELF")
end
-------------------------------------------------------------------------------------
-- Combat Parse Functions.
-------------------------------------------------------------------------------------
-- **********************************************************************************
-- Parses the passed combat message for an incoming hit message.
-- **********************************************************************************
function MikCEH.ParseForIncomingHits(combatMessage)
-- Look for a normal hit.
local capturedData = MikCEH.GetCapturedData(combatMessage, "COMBATHITOTHERSELF", {"%n", "%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_NORMAL, MikCEH.DAMAGETYPE_PHYSICAL, capturedData.Amount, nil, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a crit.
local capturedData = MikCEH.GetCapturedData(combatMessage, "COMBATHITCRITOTHERSELF", {"%n", "%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_CRIT, MikCEH.DAMAGETYPE_PHYSICAL, capturedData.Amount, nil, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a normal hit from an elemental.
local capturedData = MikCEH.GetCapturedData(combatMessage, "COMBATHITSCHOOLOTHERSELF", {"%n", "%a", "%t"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_NORMAL, capturedData.DamageType, capturedData.Amount, nil, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a crit from an elemental.
local capturedData = MikCEH.GetCapturedData(combatMessage, "COMBATHITCRITSCHOOLOTHERSELF", {"%n", "%a", "%t"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_CRIT, capturedData.DamageType, capturedData.Amount, nil, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a normal hit on your pet
local capturedData = MikCEH.GetCapturedData(combatMessage, "COMBATHITOTHEROTHER", {"%n", "%s", "%a"});
-- If a match was found.
if (capturedData ~= nil and cachedPetName and string_find(combatMessage, cachedPetName)) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_INCOMING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_NORMAL, MikCEH.DAMAGETYPE_PHYSICAL, capturedData.Amount, nil, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a crit on your pet.
local capturedData = MikCEH.GetCapturedData(combatMessage, "COMBATHITCRITOTHEROTHER", {"%n", "%s", "%a"});
-- If a match was found.
if (capturedData ~= nil and cachedPetName and string_find(combatMessage, cachedPetName)) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_INCOMING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_CRIT, MikCEH.DAMAGETYPE_PHYSICAL, capturedData.Amount, nil, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Return the parse was NOT successful.
return false;
end
-- **********************************************************************************
-- Parses the passed combat message for an incoming miss message.
-- **********************************************************************************
function MikCEH.ParseForIncomingMisses(combatMessage)
-- Look for a normal miss.
local capturedData = MikCEH.GetCapturedData(combatMessage, "MISSEDOTHERSELF", {"%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_MISS, nil, nil, nil, nil, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a dodge.
local capturedData = MikCEH.GetCapturedData(combatMessage, "VSDODGEOTHERSELF", {"%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_DODGE, nil, nil, nil, nil, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a parry.
local capturedData = MikCEH.GetCapturedData(combatMessage, "VSPARRYOTHERSELF", {"%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_PARRY, nil, nil, nil, nil, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a block.
local capturedData = MikCEH.GetCapturedData(combatMessage, "VSBLOCKOTHERSELF", {"%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_BLOCK, nil, nil, nil, nil, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an absorb.
local capturedData = MikCEH.GetCapturedData(combatMessage, "VSABSORBOTHERSELF", {"%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_ABSORB, nil, nil, nil, nil, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an immune.
local capturedData = MikCEH.GetCapturedData(combatMessage, "VSIMMUNEOTHERSELF", {"%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_IMMUNE, nil, nil, nil, nil, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a normal Pet miss.
local capturedData = MikCEH.GetCapturedData(combatMessage, "MISSEDOTHEROTHER", {"%n", "%s"});
-- If a match was found.
if (capturedData ~= nil and cachedPetName and string_find(combatMessage, cachedPetName)) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_INCOMING, MikCEH.ACTIONTYPE_MISS, nil, nil, nil, nil, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a Pet dodge.
local capturedData = MikCEH.GetCapturedData(combatMessage, "VSDODGEOTHEROTHER", {"%n", "%s"});
-- If a match was found.
if (capturedData ~= nil and cachedPetName and string_find(combatMessage, cachedPetName)) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_INCOMING, MikCEH.ACTIONTYPE_DODGE, nil, nil, nil, nil, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a Pet parry.
local capturedData = MikCEH.GetCapturedData(combatMessage, "VSPARRYOTHEROTHER", {"%n", "%s"});
-- If a match was found.
if (capturedData ~= nil and cachedPetName and string_find(combatMessage, cachedPetName)) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_INCOMING, MikCEH.ACTIONTYPE_PARRY, nil, nil, nil, nil, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a Pet block.
local capturedData = MikCEH.GetCapturedData(combatMessage, "VSBLOCKOTHEROTHER", {"%n", "%s"});
-- If a match was found.
if (capturedData ~= nil and cachedPetName and string_find(combatMessage, cachedPetName)) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_INCOMING, MikCEH.ACTIONTYPE_BLOCK, nil, nil, nil, nil, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an Pet absorb.
local capturedData = MikCEH.GetCapturedData(combatMessage, "VSABSORBOTHEROTHER", {"%n", "%s"});
-- If a match was found.
if (capturedData ~= nil and cachedPetName and string_find(combatMessage, cachedPetName)) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_INCOMING, MikCEH.ACTIONTYPE_ABSORB, nil, nil, nil, nil, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an Pet immune.
local capturedData = MikCEH.GetCapturedData(combatMessage, "VSIMMUNEOTHEROTHER", {"%n", "%s"});
-- If a match was found.
if (capturedData ~= nil and cachedPetName and string_find(combatMessage, cachedPetName)) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_INCOMING, MikCEH.ACTIONTYPE_IMMUNE, nil, nil, nil, nil, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Return the parse was NOT successful.
return false;
end
-- **********************************************************************************
-- Parses the passed combat message for an incoming spell hit/miss message.
-- **********************************************************************************
function MikCEH.ParseForIncomingSpellHitsAndMisses(combatMessage)
-- Look for an ability hit.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLLOGOTHERSELF", {"%n", "%s", "%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_NORMAL, MikCEH.DAMAGETYPE_PHYSICAL, capturedData.Amount, capturedData.SpellName, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an ability crit.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLLOGCRITOTHERSELF", {"%n", "%s", "%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_CRIT, MikCEH.DAMAGETYPE_PHYSICAL, capturedData.Amount, capturedData.SpellName, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a spell hit.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLLOGSCHOOLOTHERSELF", {"%n", "%s", "%a", "%t"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_NORMAL, capturedData.DamageType, capturedData.Amount, capturedData.SpellName, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a spell crit.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLLOGCRITSCHOOLOTHERSELF", {"%n", "%s", "%a", "%t"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_CRIT, capturedData.DamageType, capturedData.Amount, capturedData.SpellName, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a miss.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLMISSOTHERSELF", {"%n", "%s"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_MISS, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a dodge.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLDODGEDOTHERSELF", {"%n", "%s"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_DODGE, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a parry.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLPARRIEDOTHERSELF", {"%n", "%s"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_PARRY, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a block.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLBLOCKEDOTHERSELF", {"%n", "%s"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_BLOCK, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a resist.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLRESISTOTHERSELF", {"%n", "%s"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_RESIST, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an absorb.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLLOGABSORBOTHERSELF", {"%n", "%s"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_ABSORB, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an immune.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLIMMUNEOTHERSELF", {"%n", "%s"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_IMMUNE, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a reflect.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLREFLECTOTHERSELF", {"%n", "%s"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_REFLECT, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an ability hit on your pet.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLLOGOTHEROTHER", {"%n", "%s", "%c", "%a"});
-- If a match was found.
if (capturedData ~= nil and cachedPetName and string_find(combatMessage, cachedPetName)) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_INCOMING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_NORMAL, MikCEH.DAMAGETYPE_PHYSICAL, capturedData.Amount, capturedData.SpellName, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an ability crit on your pet.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLLOGCRITOTHEROTHER", {"%n", "%s", "%a"});
-- If a match was found.
if (capturedData ~= nil and cachedPetName and string_find(combatMessage, cachedPetName)) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_INCOMING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_CRIT, MikCEH.DAMAGETYPE_PHYSICAL, capturedData.Amount, capturedData.SpellName, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a spell hit on your pet.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLLOGSCHOOLOTHEROTHER", {"%n", "%s", "%c", "%a", "%t"});
-- If a match was found.
if (capturedData ~= nil and cachedPetName and string_find(combatMessage, cachedPetName)) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_INCOMING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_NORMAL, capturedData.DamageType, capturedData.Amount, capturedData.SpellName, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a spell crit on your pet.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLLOGCRITSCHOOLOTHEROTHER", {"%n", "%s", "%c", "%a", "%t"});
-- If a match was found.
if (capturedData ~= nil and cachedPetName and string_find(combatMessage, cachedPetName)) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_INCOMING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_CRIT, capturedData.DamageType, capturedData.Amount, capturedData.SpellName, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a miss on your pet.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLMISSOTHEROTHER", {"%n", "%s", "%c"});
-- If a match was found.
if (capturedData ~= nil and cachedPetName and string_find(combatMessage, cachedPetName)) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_INCOMING, MikCEH.ACTIONTYPE_MISS, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a dodge on your pet.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLDODGEDOTHEROTHER", {"%c", "%n", "%s"});
-- If a match was found.
if (capturedData ~= nil and cachedPetName and string_find(combatMessage, cachedPetName)) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_INCOMING, MikCEH.ACTIONTYPE_DODGE, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a parry on your pet.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLPARRIEDOTHEROTHER", {"%c", "%n", "%s"});
-- If a match was found.
if (capturedData ~= nil and cachedPetName and string_find(combatMessage, cachedPetName)) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_INCOMING, MikCEH.ACTIONTYPE_PARRY, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a block on your pet.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLBLOCKEDOTHEROTHER", {"%c", "%s", "%n"});
-- If a match was found.
if (capturedData ~= nil and cachedPetName and string_find(combatMessage, cachedPetName)) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_INCOMING, MikCEH.ACTIONTYPE_BLOCK, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a resist on your pet.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLRESISTOTHEROTHER", {"%n", "%s", "%c"});
-- If a match was found.
if (capturedData ~= nil and cachedPetName and string_find(combatMessage, cachedPetName)) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_INCOMING, MikCEH.ACTIONTYPE_RESIST, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an absorb on your pet.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLLOGABSORBOTHEROTHER", {"%n", "%s", "%c"});
-- If a match was found.
if (capturedData ~= nil and cachedPetName and string_find(combatMessage, cachedPetName)) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_INCOMING, MikCEH.ACTIONTYPE_ABSORB, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an immune on your pet.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLIMMUNEOTHEROTHER", {"%n", "%s", "%c"});
-- If a match was found.
if (capturedData ~= nil and cachedPetName and string_find(combatMessage, cachedPetName)) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_INCOMING, MikCEH.ACTIONTYPE_IMMUNE, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Return the parse was NOT successful.
return false;
end
-- **********************************************************************************
-- Parse the passed combat message for incoming damage shield damage.
-- **********************************************************************************
function MikCEH.ParseForIncomingDamageShieldDamage(combatMessage)
local capturedData = MikCEH.GetCapturedData(combatMessage, "DAMAGESHIELDOTHERSELF", {"%n", "%a", "%t"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_NORMAL, capturedData.DamageType, capturedData.Amount, nil, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a resist.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLRESISTOTHERSELF", {"%n", "%s"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_RESIST, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a miss.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLMISSOTHERSELF", {"%n", "%s"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_MISS, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a dodge.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLDODGEDOTHERSELF", {"%n", "%s"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_DODGE, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a parry.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLPARRIEDOTHERSELF", {"%n", "%s"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_PARRY, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a block.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLBLOCKEDOTHERSELF", {"%n", "%s"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_BLOCK, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an absorb.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLLOGABSORBOTHERSELF", {"%n", "%s"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_ABSORB, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an immune.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLIMMUNEOTHERSELF", {"%n", "%s"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_IMMUNE, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a reflect.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLREFLECTOTHERSELF", {"%n", "%s"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_REFLECT, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Return the parse was NOT successful.
return false;
end
-- **********************************************************************************
-- Parses the passed combat message for incoming heal info.
-- **********************************************************************************
function MikCEH.ParseForIncomingSpellHeals(combatMessage)
-- Look for a critical heal from another player / creature.
local capturedData = MikCEH.GetCapturedData(combatMessage, "HEALEDCRITOTHERSELF", {"%n", "%s", "%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetHealEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.HEALTYPE_CRIT, capturedData.Amount, capturedData.SpellName, capturedData.Name);
-- Get overheal info.
eventData.Name = playerName
MikCEH.PopulateOverhealData(eventData); --athenne add
eventData.Name = capturedData.Name
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a heal from another player / creature.
local capturedData = MikCEH.GetCapturedData(combatMessage, "HEALEDOTHERSELF", {"%n", "%s", "%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetHealEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.HEALTYPE_NORMAL, capturedData.Amount, capturedData.SpellName, capturedData.Name);
-- Get overheal info.
eventData.Name = playerName
MikCEH.PopulateOverhealData(eventData); --athenne add
eventData.Name = capturedData.Name
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a HoT from someone else.
local capturedData = MikCEH.GetCapturedData(combatMessage, "PERIODICAURAHEALOTHERSELF", {"%a", "%n", "%s"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetHealEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.HEALTYPE_OVER_TIME, capturedData.Amount, capturedData.SpellName, capturedData.Name);
-- Get overheal info.
eventData.Name = playerName
if GetLocale() ~= "zhCN" then -- edge case for chinese client (unable to show overheal amount for hot casted on self by other)
MikCEH.PopulateOverhealData(eventData); -- athenne add
end
eventData.Name = capturedData.Name
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a HoT from yourself.
local capturedData = MikCEH.GetCapturedData(combatMessage, "PERIODICAURAHEALSELFSELF", {"%a", "%s"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetHealEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.HEALTYPE_OVER_TIME, capturedData.Amount, capturedData.SpellName, playerName);
-- Get overheal info.
MikCEH.PopulateOverhealData(eventData); --athenne add
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a critical heal from another player / creature on your pet.
local capturedData = MikCEH.GetCapturedData(combatMessage, "HEALEDCRITOTHEROTHER", {"%n", "%s", "%c", "%a"});
-- If a match was found.
if (capturedData ~= nil and cachedPetName and string_find(combatMessage, cachedPetName)) then
local eventData = MikCEH.GetHealEventData(MikCEH.DIRECTIONTYPE_PET_INCOMING, MikCEH.HEALTYPE_CRIT, capturedData.Amount, capturedData.SpellName, capturedData.Name);
-- Get overheal info.
eventData.Name = cachedPetName
MikCEH.PopulateOverhealData(eventData); -- athenne add
eventData.Name = capturedData.Name
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a heal from another player / creature on your pet.
local capturedData = MikCEH.GetCapturedData(combatMessage, "HEALEDOTHEROTHER", {"%n", "%s", "%c", "%a"});
-- If a match was found.
if (capturedData ~= nil and cachedPetName and string_find(combatMessage, cachedPetName)) then
local eventData = MikCEH.GetHealEventData(MikCEH.DIRECTIONTYPE_PET_INCOMING, MikCEH.HEALTYPE_NORMAL, capturedData.Amount, capturedData.SpellName, capturedData.Name);
-- Get overheal info.
eventData.Name = cachedPetName
MikCEH.PopulateOverhealData(eventData); -- athenne add
eventData.Name = capturedData.Name
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a HoT from someone else on your pet.
local capturedData = MikCEH.GetCapturedData(combatMessage, "PERIODICAURAHEALOTHEROTHER", {"%c", "%a", "%n", "%s"});
-- If a match was found.
if (capturedData ~= nil and cachedPetName and string_find(combatMessage, cachedPetName)) then
local eventData = MikCEH.GetHealEventData(MikCEH.DIRECTIONTYPE_PET_INCOMING, MikCEH.HEALTYPE_OVER_TIME, capturedData.Amount, capturedData.SpellName, capturedData.Name);
-- Get overheal info.
eventData.Name = cachedPetName
if GetLocale() ~= "zhCN" then -- edge case for chinese client (unable to show overheal amount for hot casted on your pet by other)
MikCEH.PopulateOverhealData(eventData); -- athenne add
end
eventData.Name = capturedData.Name
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Return the parse was NOT successful.
return false;
end
-- **********************************************************************************
-- Parses the passed combat message for incoming debuff info.
-- **********************************************************************************
function MikCEH.ParseForIncomingDebuffs(combatMessage)
-- Look for a debuff.
local capturedData = MikCEH.GetCapturedData(combatMessage, "AURAADDEDSELFHARMFUL", {"%b"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetNotificationEventData(MikCEH.NOTIFICATIONTYPE_DEBUFF, capturedData.Amount, capturedData.BuffName);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for damage from a debuff.
if (GetLocale() == "frFR") then
capturedData = MikCEH.GetCapturedData(combatMessage, "PERIODICAURADAMAGEOTHERSELF", {"%t", "%a", "%s", "%n"});
else
capturedData = MikCEH.GetCapturedData(combatMessage, "PERIODICAURADAMAGEOTHERSELF", {"%a", "%t", "%n", "%s"});
end
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_OVER_TIME, capturedData.DamageType, capturedData.Amount, capturedData.SpellName, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for damage from a self debuff.
local capturedData = MikCEH.GetCapturedData(combatMessage, "PERIODICAURADAMAGESELFSELF", {"%a", "%t", "%s"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_OVER_TIME, capturedData.DamageType, capturedData.Amount, capturedData.SpellName, nil);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for absorbed damage from a self debuff.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLLOGABSORBSELFSELF", {"%s"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_ABSORB, nil, nil, nil, capturedData.SpellName, nil);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for absorbed damage from a debuff.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLLOGABSORBOTHERSELF", {"%n", "%s"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_ABSORB, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Return the parse was NOT successful.
return false;
end
-- **********************************************************************************
-- Parses for power gains.
-- **********************************************************************************
function MikCEH.ParseForPowerGains(combatMessage)
local capturedData = nil
-- Look for power gains from others.
local capturedData = MikCEH.GetCapturedData(combatMessage, "POWERGAINOTHERSELF", {"%p", "%a", "%s", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
-- Make sure it's mana, rage, or energy.
if (capturedData.PowerType == MANA or capturedData.PowerType == RAGE or capturedData.PowerType == ENERGY) then
local eventData = MikCEH.GetNotificationEventData(MikCEH.NOTIFICATIONTYPE_POWER_GAIN, capturedData.Amount, capturedData.PowerType, capturedData.SpellName);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
end
-- Look for self power gains.
if (GetLocale() == "frFR") then
capturedData = MikCEH.GetCapturedData(combatMessage, "POWERGAINSELFSELF", {"%p", "%s", "%a"});
else
capturedData = MikCEH.GetCapturedData(combatMessage, "POWERGAINSELFSELF", {"%a", "%p", "%s"});
end
-- If a match was found.
if (capturedData ~= nil) then
-- Make sure it's mana, rage, or energy.
if (capturedData.PowerType == MANA or capturedData.PowerType == RAGE or capturedData.PowerType == ENERGY) then
local eventData = MikCEH.GetNotificationEventData(MikCEH.NOTIFICATIONTYPE_POWER_GAIN, capturedData.Amount, capturedData.PowerType, capturedData.SpellName);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
end
-- Look for power gains from draining others.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLPOWERLEECHSELFOTHER", {"%s", "%a", "%p", "%n", "", "", ""});
-- If a match was found.
if (capturedData ~= nil) then
-- Make sure it's mana, rage, or energy.
if (capturedData.PowerType == MANA or capturedData.PowerType == RAGE or capturedData.PowerType == ENERGY) then
local eventData = MikCEH.GetNotificationEventData(MikCEH.NOTIFICATIONTYPE_POWER_GAIN, capturedData.Amount, capturedData.PowerType, capturedData.SpellName);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
end
-- Return the parse was NOT successful.
return false;
end
-- **********************************************************************************
-- Parses for power losses.
-- **********************************************************************************
function MikCEH.ParseForPowerLosses(combatMessage)
-- Look for a power leech.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLPOWERLEECHOTHERSELF", {"%n", "%s", "%a", "%p", "", "", ""});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetNotificationEventData(MikCEH.NOTIFICATIONTYPE_POWER_LOSS, capturedData.Amount, capturedData.PowerType, capturedData.SpellName);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a power drain.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLPOWERDRAINOTHERSELF", {"%n", "%s", "%a", "%p"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetNotificationEventData(MikCEH.NOTIFICATIONTYPE_POWER_LOSS, capturedData.Amount, capturedData.PowerType, capturedData.SpellName);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Return the parse was NOT successful.
return false;
end
-- **********************************************************************************
-- Parses the passed combat message for incoming buff and power gain info.
-- **********************************************************************************
function MikCEH.ParseForIncomingBuffs(combatMessage)
-- Parse for power gains.
if (MikCEH.ParseForPowerGains(combatMessage)) then
-- Return the parse was successful.
return true;
end
-- Look for a buff.
local capturedData = MikCEH.GetCapturedData(combatMessage, "AURAADDEDSELFHELPFUL", {"%s"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetNotificationEventData(MikCEH.NOTIFICATIONTYPE_BUFF, nil, capturedData.SpellName);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a self mana drain.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLPOWERDRAINSELFSELF", {"%s", "%a", "%p"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetNotificationEventData(MikCEH.NOTIFICATIONTYPE_POWER_LOSS, capturedData.Amount, capturedData.PowerType, capturedData.SpellName);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Return the parse was NOT successful.
return false;
end
-- **********************************************************************************
-- Parses the passed combat message for environmental damage.
-- **********************************************************************************
function MikCEH.ParseForEnvironmentalDamage(combatMessage)
-- Look for drowning damage.
local capturedData = MikCEH.GetCapturedData(combatMessage, "VSENVIRONMENTALDAMAGE_DROWNING_SELF", {"%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_DROWNING, nil, MikCEH.DAMAGETYPE_PHYSICAL, capturedData.Amount, nil, nil);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for falling damage.
local capturedData = MikCEH.GetCapturedData(combatMessage, "VSENVIRONMENTALDAMAGE_FALLING_SELF", {"%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_FALLING, nil, MikCEH.DAMAGETYPE_PHYSICAL, capturedData.Amount, nil, nil);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for fatigue damage.
local capturedData = MikCEH.GetCapturedData(combatMessage, "VSENVIRONMENTALDAMAGE_FATIGUE_SELF", {"%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_FATIGUE, nil, MikCEH.DAMAGETYPE_PHYSICAL, capturedData.Amount, nil, nil);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for fire damage.
local capturedData = MikCEH.GetCapturedData(combatMessage, "VSENVIRONMENTALDAMAGE_FIRE_SELF", {"%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_FIRE, nil, MikCEH.DAMAGETYPE_PHYSICAL, capturedData.Amount, nil, nil);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for lava damage.
local capturedData = MikCEH.GetCapturedData(combatMessage, "VSENVIRONMENTALDAMAGE_LAVA_SELF", {"%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_LAVA, nil, MikCEH.DAMAGETYPE_PHYSICAL, capturedData.Amount, nil, nil);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for slime damage.
local capturedData = MikCEH.GetCapturedData(combatMessage, "VSENVIRONMENTALDAMAGE_SLIME_SELF", {"%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_SLIME, nil, MikCEH.DAMAGETYPE_PHYSICAL, capturedData.Amount, nil, nil);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Return the parse was NOT successful.
return false;
end
-- **********************************************************************************
-- Parses the passed combat message for outgoing hits.
-- **********************************************************************************
function MikCEH.ParseForOutgoingHits(combatMessage)
-- Look for a normal hit.
local capturedData = MikCEH.GetCapturedData(combatMessage, "COMBATHITSELFOTHER", {"%n", "%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_NORMAL, MikCEH.DAMAGETYPE_PHYSICAL, capturedData.Amount, nil, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a crit.
local capturedData = MikCEH.GetCapturedData(combatMessage, "COMBATHITCRITSELFOTHER", {"%n", "%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_CRIT, MikCEH.DAMAGETYPE_PHYSICAL, capturedData.Amount, nil, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Return the parse was NOT successful.
return false;
end
-- **********************************************************************************
-- Parses the passed combat message for outgoing hits.
-- **********************************************************************************
function MikCEL_ParseForOutgoingHits(combatMessage)
-- Look for a normal hit.
local capturedData = MikCEH.GetCapturedData(combatMessage, "COMBATHITSELFOTHER", {"%n", "%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_NORMAL, MikCEH.DAMAGETYPE_PHYSICAL, capturedData.Amount, nil, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a crit.
local capturedData = MikCEH.GetCapturedData(combatMessage, "COMBATHITCRITSELFOTHER", {"%n", "%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_CRIT, MikCEH.DAMAGETYPE_PHYSICAL, capturedData.Amount, nil, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Return the parse was NOT successful.
return false;
end
-- **********************************************************************************
-- Parse the passed combat message for an outgoing miss message.
-- **********************************************************************************
function MikCEH.ParseForOutgoingMisses(combatMessage)
-- Look for a normal miss.
local capturedData = MikCEH.GetCapturedData(combatMessage, "MISSEDSELFOTHER", {"%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_MISS, nil, nil, nil, nil, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a dodge.
local capturedData = MikCEH.GetCapturedData(combatMessage, "VSDODGESELFOTHER", {"%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_DODGE, nil, nil, nil, nil, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a parry.
local capturedData = MikCEH.GetCapturedData(combatMessage, "VSPARRYSELFOTHER", {"%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_PARRY, nil, nil, nil, nil, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a block.
local capturedData = MikCEH.GetCapturedData(combatMessage, "VSBLOCKSELFOTHER", {"%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_BLOCK, nil, nil, nil, nil, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an absorb.
local capturedData = MikCEH.GetCapturedData(combatMessage, "VSABSORBSELFOTHER", {"%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_ABSORB, nil, nil, nil, nil, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an immune.
local capturedData = MikCEH.GetCapturedData(combatMessage, "VSIMMUNESELFOTHER", {"%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_IMMUNE, nil, nil, nil, nil, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an evade.
local capturedData = MikCEH.GetCapturedData(combatMessage, "VSEVADESELFOTHER", {"%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_EVADE, nil, nil, nil, nil, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Return the parse was NOT successful.
return false;
end
-- **********************************************************************************
-- Parse the passed combat message for outgoing spell/ability hits and misses.
-- **********************************************************************************
function MikCEH.ParseForOutgoingSpellHitsAndMisses(combatMessage)
-- Look for an ability crit.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLLOGCRITSELFOTHER", {"%s", "%n", "%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_CRIT, MikCEH.DAMAGETYPE_PHYSICAL, capturedData.Amount, capturedData.SpellName, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an ability hit.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLLOGSELFOTHER", {"%s", "%n", "%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_NORMAL, MikCEH.DAMAGETYPE_PHYSICAL, capturedData.Amount, capturedData.SpellName, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a spell crit to yourself.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLLOGCRITSCHOOLSELFSELF", {"%s", "%a", "%t"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_CRIT, capturedData.DamageType, capturedData.Amount, capturedData.SpellName, playerName);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a spell hit to yourself.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLLOGSCHOOLSELFSELF", {"%s", "%a", "%t"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_NORMAL, capturedData.DamageType, capturedData.Amount, capturedData.SpellName, playerName);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for spell crit.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLLOGCRITSCHOOLSELFOTHER", {"%s", "%n", "%a", "%t"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_CRIT, capturedData.DamageType, capturedData.Amount, capturedData.SpellName, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a spell hit.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLLOGSCHOOLSELFOTHER", {"%s", "%n", "%a", "%t"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_NORMAL, capturedData.DamageType, capturedData.Amount, capturedData.SpellName, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a miss.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLMISSSELFOTHER", {"%s", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_MISS, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a dodge.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLDODGEDSELFOTHER", {"%s", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_DODGE, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a parry.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLPARRIEDSELFOTHER", {"%s", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_PARRY, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a block.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLBLOCKEDSELFOTHER", {"%s", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_BLOCK, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a resist.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLRESISTSELFOTHER", {"%s", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_RESIST, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an absorb.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLLOGABSORBSELFOTHER", {"%s", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_ABSORB, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an immune.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLIMMUNESELFOTHER", {"%s", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_IMMUNE, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a reflect.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLREFLECTSELFOTHER", {"%s", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_REFLECT, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an evade
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLEVADEDSELFOTHER", {"%s", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_EVADE, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Return the parse was NOT successful.
return false;
end
-- **********************************************************************************
-- Parse the passed combat message for outgoing damage shield damage.
-- **********************************************************************************
function MikCEH.ParseForOutgoingDamageShieldDamage(combatMessage)
local capturedData = MikCEH.GetCapturedData(combatMessage, "DAMAGESHIELDSELFOTHER", {"%a", "%t", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData
if capturedData.DamageType == 2 and capturedData.Amount == "20" then
eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_NORMAL, capturedData.DamageType, capturedData.Amount, "Aura de vindicte", capturedData.Name);
else
eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_NORMAL, capturedData.DamageType, capturedData.Amount, nil, capturedData.Name);
end
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a resist.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLRESISTSELFOTHER", {"%s", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_RESIST, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an immune.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLIMMUNESELFOTHER", {"%s", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_IMMUNE, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an evade
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLEVADEDSELFOTHER", {"%s", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_EVADE, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a miss.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLMISSSELFOTHER", {"%s", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_MISS, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a dodge.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLDODGEDSELFOTHER", {"%s", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_DODGE, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a parry.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLPARRIEDSELFOTHER", {"%s", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_PARRY, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a block.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLBLOCKEDSELFOTHER", {"%s", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_BLOCK, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Return the parse was NOT successful.
return false;
end
-- **********************************************************************************
-- Parse the passed combat message for outgoing heal info.
-- **********************************************************************************
function MikCEH.ParseForOutgoingSpellHeals(combatMessage)
-- Look for a critical heal to yourself.
local capturedData = MikCEH.GetCapturedData(combatMessage, "HEALEDCRITSELFSELF", {"%s", "%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetHealEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.HEALTYPE_CRIT, capturedData.Amount, capturedData.SpellName, playerName);
-- Get overheal info.
MikCEH.PopulateOverhealData(eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a heal to yourself.
local capturedData = MikCEH.GetCapturedData(combatMessage, "HEALEDSELFSELF", {"%s", "%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetHealEventData(MikCEH.DIRECTIONTYPE_PLAYER_INCOMING, MikCEH.HEALTYPE_NORMAL, capturedData.Amount, capturedData.SpellName, playerName);
-- Get overheal info.
MikCEH.PopulateOverhealData(eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a critical heal to someone else.
local capturedData = MikCEH.GetCapturedData(combatMessage, "HEALEDCRITSELFOTHER", {"%s", "%n", "%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetHealEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.HEALTYPE_CRIT, capturedData.Amount, capturedData.SpellName, capturedData.Name);
-- Get overheal info.
MikCEH.PopulateOverhealData(eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a heal to someone else.
local capturedData = MikCEH.GetCapturedData(combatMessage, "HEALEDSELFOTHER", {"%s", "%n", "%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetHealEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.HEALTYPE_NORMAL, capturedData.Amount, capturedData.SpellName, capturedData.Name);
-- Get overheal info.
MikCEH.PopulateOverhealData(eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Return the parse was NOT successful.
return false;
end
-- **********************************************************************************
-- Parses the passed combat message for outgoing dispel/purge resists.
-- **********************************************************************************
function MikCEH.ParseForOutgoingDispelResists(combatMessage)
-- Look for a resist.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLRESISTSELFOTHER", {"%s", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_RESIST, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Return the parse was NOT successful.
return false;
end
-- **********************************************************************************
-- Parses the passed combat message for outgoing Heals over time.
-- **********************************************************************************
function MikCEH.ParseForOutgoingHoTs(combatMessage)
-- Look for a HoT to someone else.
local capturedData = MikCEH.GetCapturedData(combatMessage, "PERIODICAURAHEALSELFOTHER", {"%n", "%a", "%s"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetHealEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.HEALTYPE_OVER_TIME, capturedData.Amount, capturedData.SpellName, capturedData.Name);
-- Get overheal info.
MikCEH.PopulateOverhealData(eventData); --athenne add
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Return the parse was NOT successful.
return false;
end
-- **********************************************************************************
-- Parses the passed combat message for outgoing DoTs.
-- **********************************************************************************
function MikCEH.ParseForOutgoingDoTs(combatMessage)
-- Look for damage from a DoT.
local capturedData = MikCEH.GetCapturedData(combatMessage, "PERIODICAURADAMAGESELFOTHER", {"%n", "%a", "%t", "%s"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_OVER_TIME, capturedData.DamageType, capturedData.Amount, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for absorbed damage from a DoT.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLLOGABSORBSELFOTHER", {"%s", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_ABSORB, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Return the parse was NOT successful.
return false;
end
-- **********************************************************************************
-- Parse the passed combat message for outgoing pet hits.
-- **********************************************************************************
function MikCEH.ParseForOutgoingPetHits(combatMessage)
-- Look for a normal pet hit.
local capturedData = MikCEH.GetCapturedData(combatMessage, "COMBATHITOTHEROTHER", {"%c", "%n", "%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_OUTGOING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_NORMAL, MikCEH.DAMAGETYPE_PHYSICAL, capturedData.Amount, nil, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a pet crit.
local capturedData = MikCEH.GetCapturedData(combatMessage, "COMBATHITCRITOTHEROTHER", {"%c", "%n", "%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_OUTGOING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_CRIT, MikCEH.DAMAGETYPE_PHYSICAL, capturedData.Amount, nil, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a pet elemental hit.
local capturedData = MikCEH.GetCapturedData(combatMessage, "COMBATHITSCHOOLOTHEROTHER", {"%c", "%n", "%a", "%t"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_OUTGOING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_NORMAL, capturedData.DamageType, capturedData.Amount, nil, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a pet elemental crit.
local capturedData = MikCEH.GetCapturedData(combatMessage, "COMBATHITCRITSCHOOLOTHEROTHER", {"%c", "%n", "%a", "%t"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_OUTGOING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_CRIT, capturedData.DamageType, capturedData.Amount, nil, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Return the parse was NOT successful.
return false;
end
-- **********************************************************************************
-- Parse the passed combat message for outgoing pet misses.
-- **********************************************************************************
function MikCEH.ParseForOutgoingPetMisses(combatMessage)
-- Look for a normal miss.
local capturedData = MikCEH.GetCapturedData(combatMessage, "MISSEDOTHEROTHER", {"%c", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_OUTGOING, MikCEH.ACTIONTYPE_MISS, nil, nil, nil, nil, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a dodge.
local capturedData = MikCEH.GetCapturedData(combatMessage, "VSDODGEOTHEROTHER", {"%c", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_OUTGOING, MikCEH.ACTIONTYPE_DODGE, nil, nil, nil, nil, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a parry.
local capturedData = MikCEH.GetCapturedData(combatMessage, "VSPARRYOTHEROTHER", {"%c", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_OUTGOING, MikCEH.ACTIONTYPE_PARRY, nil, nil, nil, nil, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a block.
local capturedData = MikCEH.GetCapturedData(combatMessage, "VSBLOCKOTHEROTHER", {"%c", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_OUTGOING, MikCEH.ACTIONTYPE_BLOCK, nil, nil, nil, nil, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an absorb.
local capturedData = MikCEH.GetCapturedData(combatMessage, "VSABSORBOTHEROTHER", {"%c", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_OUTGOING, MikCEH.ACTIONTYPE_ABSORB, nil, nil, nil, nil, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an immune.
local capturedData = MikCEH.GetCapturedData(combatMessage, "VSIMMUNEOTHEROTHER", {"%c", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_OUTGOING, MikCEH.ACTIONTYPE_IMMUNE, nil, nil, nil, nil, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an evade.
local capturedData = MikCEH.GetCapturedData(combatMessage, "VSEVADEOTHEROTHER", {"%c", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_OUTGOING, MikCEH.ACTIONTYPE_EVADE, nil, nil, nil, nil, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Return the parse was NOT successful.
return false;
end
-- **********************************************************************************
-- Parse the passed combat message for outgoing pet spell hits and misses.
-- **********************************************************************************
function MikCEH.ParseForOutgoingPetSpellHitsAndMisses(combatMessage)
-- Look for an ability hit.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLLOGOTHEROTHER", {"%c", "%s", "%n", "%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_OUTGOING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_NORMAL, MikCEH.DAMAGETYPE_PHYSICAL, capturedData.Amount, capturedData.SpellName, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an ability crit.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLLOGCRITOTHEROTHER", {"%c", "%s", "%n", "%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_OUTGOING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_CRIT, MikCEH.DAMAGETYPE_PHYSICAL, capturedData.Amount, capturedData.SpellName, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a spell hit.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLLOGSCHOOLOTHEROTHER", {"%c", "%s", "%n", "%a", "%t"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_OUTGOING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_NORMAL, capturedData.DamageType, capturedData.Amount, capturedData.SpellName, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for spell crit.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLLOGCRITSCHOOLOTHEROTHER", {"%c", "%s", "%n", "%a", "%t"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_OUTGOING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_CRIT, capturedData.DamageType, capturedData.Amount, capturedData.SpellName, capturedData.Name);
-- Look for any partial actions and populate them into the event data.
MikCEH.ParseForPartialActions(combatMessage, eventData);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a miss.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLMISSOTHEROTHER", {"%c", "%s", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_OUTGOING, MikCEH.ACTIONTYPE_MISS, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a dodge.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLDODGEDOTHEROTHER", {"%c", "%s", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_OUTGOING, MikCEH.ACTIONTYPE_DODGE, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a parry.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLPARRIEDOTHEROTHER", {"%c", "%s", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_OUTGOING, MikCEH.ACTIONTYPE_PARRY, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a block.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLBLOCKEDOTHEROTHER", {"%c", "%s", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_OUTGOING, MikCEH.ACTIONTYPE_BLOCK, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a resist.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLRESISTOTHEROTHER", {"%c", "%s", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_OUTGOING, MikCEH.ACTIONTYPE_RESIST, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an absorb.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLLOGABSORBOTHEROTHER", {"%c", "%s", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_OUTGOING, MikCEH.ACTIONTYPE_ABSORB, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an immune.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLIMMUNEOTHEROTHER", {"%c", "%s", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_OUTGOING, MikCEH.ACTIONTYPE_IMMUNE, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an evade
local capturedData = MikCEH.GetCapturedData(combatMessage, "SPELLEVADEDOTHEROTHER", {"%c", "%s", "%n"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PET_OUTGOING, MikCEH.ACTIONTYPE_EVADE, nil, nil, nil, capturedData.SpellName, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Return the parse was NOT successful.
return false;
end
-- **********************************************************************************
-- Parses the passed combat message for incoming item buff info.
-- **********************************************************************************
function MikCEH.ParseForIncomingItemBuffs(combatMessage)
-- Look for an item buff from yourself.
local capturedData = MikCEH.GetCapturedData(combatMessage, "ITEMENCHANTMENTADDSELFSELF", {"%b"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetNotificationEventData(MikCEH.NOTIFICATIONTYPE_ITEM_BUFF, nil, capturedData.BuffName);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for an item buff from someone else.
local capturedData = MikCEH.GetCapturedData(combatMessage, "ITEMENCHANTMENTADDOTHERSELF", {"%n", "%b"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetNotificationEventData(MikCEH.NOTIFICATIONTYPE_ITEM_BUFF, nil, capturedData.BuffName);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Return the parse was NOT successful.
return false;
end
-- **********************************************************************************
-- Parses the passed combat message for buff fades.
-- **********************************************************************************
function MikCEH.ParseForBuffFades(combatMessage)
-- Look for a buff fade due to wearing off.
local capturedData = MikCEH.GetCapturedData(combatMessage, "AURAREMOVEDSELF", {"%b"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetNotificationEventData(MikCEH.NOTIFICATIONTYPE_BUFF_FADE, nil, capturedData.BuffName);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Return the parse was NOT successful.
return false;
end
-- **********************************************************************************
-- Parses the passed combat message for honor gains.
-- **********************************************************************************
function MikCEH.ParseForHonorGains(combatMessage)
-- Look for an estimated honor gain from a kill.
local capturedData = MikCEH.GetCapturedData(combatMessage, "COMBATLOG_HONORGAIN", {"%n", "", "%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetNotificationEventData(MikCEH.NOTIFICATIONTYPE_HONOR_GAIN, capturedData.Amount, nil);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for awarded honor.
local capturedData = MikCEH.GetCapturedData(combatMessage, "COMBATLOG_HONORAWARD", {"%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetNotificationEventData(MikCEH.NOTIFICATIONTYPE_HONOR_GAIN, capturedData.Amount, nil);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Return the parse was NOT successful.
return false;
end
-- **********************************************************************************
-- Parses the passed combat message for reputation gains/losses.
-- **********************************************************************************
function MikCEH.ParseForReputationGainsAndLosses(combatMessage)
-- Look for a rep increase.
local capturedData = MikCEH.GetCapturedData(combatMessage, "FACTION_STANDING_INCREASED", {"%f", "%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetNotificationEventData(MikCEH.NOTIFICATIONTYPE_REP_GAIN, capturedData.Amount, capturedData.FactionName);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Look for a rep loss.
local capturedData = MikCEH.GetCapturedData(combatMessage, "FACTION_STANDING_DECREASED", {"%f", "%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetNotificationEventData(MikCEH.NOTIFICATIONTYPE_REP_LOSS, capturedData.Amount, capturedData.FactionName);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Return the parse was NOT successful.
return false;
end
-- **********************************************************************************
-- Parses the passed combat message for skill gains.
-- **********************************************************************************
function MikCEH.ParseForSkillGains(combatMessage)
-- Look for a skill gain.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SKILL_RANK_UP", {"%k", "%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetNotificationEventData(MikCEH.NOTIFICATIONTYPE_SKILL_GAIN, capturedData.Amount, capturedData.SkillName);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Return the parse was NOT successful.
return false;
end
-- **********************************************************************************
-- Parses the passed combat message for experience gains.
-- **********************************************************************************
function MikCEH.ParseForExperienceGains(combatMessage)
-- Look for an experience gain.
local capturedData = MikCEH.GetCapturedData(combatMessage, "COMBATLOG_XPGAIN_FIRSTPERSON", {"%n", "%a"});
-- If a match was found.
if (capturedData ~= nil) then
local eventData = MikCEH.GetNotificationEventData(MikCEH.NOTIFICATIONTYPE_EXPERIENCE_GAIN, capturedData.Amount, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Return the parse was NOT successful.
return false;
end
-- **********************************************************************************
-- Parses the passed combat message for killing blows.
-- **********************************************************************************
function MikCEH.ParseForKillingBlows(combatMessage)
-- Look for a killing blow.
local capturedData = MikCEH.GetCapturedData(combatMessage, "SELFKILLOTHER", {"%n"});
-- If a match was found.
if (capturedData ~= nil) then
-- Hold the notification type.
local notificationType = MikCEH.NOTIFICATIONTYPE_NPC_KILLING_BLOW;
-- Check if the current target is the slain enemy and is a player, or the slain target is on the recently
-- selected players list.
if ((UnitExists("target") and (UnitName("target") == capturedData.Name) and UnitIsPlayer("target")) or
(recentlySelectedPlayers[capturedData.Name] ~= nil)) then
notificationType = MikCEH.NOTIFICATIONTYPE_PC_KILLING_BLOW;
end
-- Create the event.
local eventData = MikCEH.GetNotificationEventData(notificationType, nil, capturedData.Name);
-- Send the event.
MikCEH.SendEvent(eventData);
-- Return the parse was successful.
return true;
end
-- Return the parse was NOT successful.
return false;
end
-- **********************************************************************************
-- Parse the passed combat message for partial actions and populate the info
-- from any actions found into the passed event data.
-- **********************************************************************************
function MikCEH.ParseForPartialActions(combatMessage, eventData)
-- Look for a partial absorb.
local capturedData = MikCEH.GetCapturedData(combatMessage, "ABSORB_TRAILER", {"%a"});
-- If a match was found.
if (capturedData ~= nil) then
eventData.PartialActionType = MikCEH.PARTIALACTIONTYPE_ABSORB;
eventData.PartialAmount = capturedData.Amount;
-- Return that partial action information was found.
return true;
end
-- Look for a partial block.
local capturedData = MikCEH.GetCapturedData(combatMessage, "BLOCK_TRAILER", {"%a"});
-- If a match was found.
if (capturedData ~= nil) then
eventData.PartialActionType = MikCEH.PARTIALACTIONTYPE_BLOCK;
eventData.PartialAmount = capturedData.Amount;
-- Return that partial effect information was found.
return true;
end
-- Look for a partial resist.
local capturedData = MikCEH.GetCapturedData(combatMessage, "RESIST_TRAILER", {"%a"});
-- If a match was found.
if (capturedData ~= nil) then
eventData.PartialActionType = MikCEH.PARTIALACTIONTYPE_RESIST;
eventData.PartialAmount = capturedData.Amount;
-- Return that partial action information was found.
return true;
end
-- Look for a vulnerability bonus.
local capturedData = MikCEH.GetCapturedData(combatMessage, "VULNERABLE_TRAILER", {"%a"});
-- If a match was found.
if (capturedData ~= nil) then
eventData.PartialActionType = MikCEH.PARTIALACTIONTYPE_VULNERABLE;
eventData.PartialAmount = capturedData.Amount;
-- Return that partial action information was found.
return true;
end
-- Look for a crushing blow.
local capturedData = MikCEH.GetCapturedData(combatMessage, "CRUSHING_TRAILER", {});
-- If a match was found.
if (capturedData ~= nil) then
eventData.PartialActionType = MikCEH.PARTIALACTIONTYPE_CRUSHING;
-- Return that partial action information was found.
return true;
end
-- Look for a glancing blow.
local capturedData = MikCEH.GetCapturedData(combatMessage, "GLANCING_TRAILER", {});
-- If a match was found.
if (capturedData ~= nil) then
eventData.PartialActionType = MikCEH.PARTIALACTIONTYPE_GLANCING;
-- Return that partial action information was found.
return true;
end
-- Return that no partial action information was found.
return false;
end
-------------------------------------------------------------------------------------
-- Utility functions.
-------------------------------------------------------------------------------------
-- **********************************************************************************
-- Get a lua compatible search string and the argument order from a global string
-- provided by blizzard.
-- **********************************************************************************
function MikCEH.GetGlobalStringInfo(globalStringName)
-- Check if the passed global string does not exist.
local globalString = getglobal(globalStringName);
if (globalString == nil) then
return;
end
-- Check if the global string info doesn't already exist for the passed global string name.
if (globalStringInfoArray[globalStringName] == nil) then
local searchString = "";
local currentChar;
local formatCode;
local argumentNumber = 0;
local argumentOrder = {};
-- Loop through all of the characters in the passed string.
local stringLength = string_len(globalString);
for index = 0, stringLength do
-- Get the current character.
currentChar = string_sub(globalString, index, index);
-- Check if we aren't in a formatting code.
if (formatCode == nil) then
-- Check if the current character is the start of a formatting code.
if (currentChar == "%") then
formatCode = currentChar;
else
-- Check if the character is one of the magic characters and escape it.
if (string_find(currentChar, "[%^%$%(%)%.%[%]%*%-%+%?]")) then
searchString = searchString .. "%" .. currentChar;
-- Normal character so just add it to the formatted string.
else
searchString = searchString .. currentChar;
end
end
-- We are in a formatting code.
else
-- Add the current character to the format code.
formatCode = formatCode .. currentChar;
-- Check if the % character is being escaped.
if (formatCode == "%%") then
-- Add the % to the search string.
searchString = searchString .. "%%";
-- Clear the format code.
formatCode = nil;
-- Check if it's a digit, a period, or a $ and do nothing so we loop to the next character in the format code.
elseif (string_find(currentChar, "[%$%.%d]")) then
-- Do nothing.
-- Check for one of the types that need a string.
elseif (string_find(currentChar, "[cEefgGiouXxqs]")) then
-- Replace the format code with lua capture string syntax.
if GetLocale() == "zhCN" and globalStringName == "HEALEDSELFOTHER" then -- edge for outgoing heals on others case for zhCN client
searchString = searchString .. "([^0-9.]+)"
else
searchString = searchString .. "(.+)";
end
-- Increment the argument number.
argumentNumber = argumentNumber + 1;
-- Check if there is an argument position specified.
local _, _, argumentPosition = string_find(formatCode, "(%d+)%$");
if (argumentPosition) then
argumentOrder[argumentNumber] = tonumber(argumentPosition);
else
argumentOrder[argumentNumber] = argumentNumber;
end
-- Clear the format code.
formatCode = nil;
-- Check if it's the type that needs a number.
elseif (currentChar == "d") then
-- Replace the format code with lua capture digits syntax.
searchString = searchString .. "(%d+)";
-- Increment the argument number.
argumentNumber = argumentNumber + 1;
-- Check if there is an argument position specified.
local _, _, argumentPosition = string_find(formatCode, "(%d+)%$");
if (argumentPosition) then
argumentOrder[argumentNumber] = tonumber(argumentPosition);
else
argumentOrder[argumentNumber] = argumentNumber;
end
-- Clear the format code.
formatCode = nil;
else
-- Clear the format code.
formatCode = nil;
end
end
end
-- Cache the global string info for later retrieval.
globalStringInfoArray[globalStringName] = {Search=searchString, ArgumentOrder=argumentOrder};
end
-- Return the format info for the global string.
return globalStringInfoArray[globalStringName];
end
-- **********************************************************************************
-- This function returns the captured data table with all the captured data in fields.
-- If the pattern wasn't found then nil is returned.
-- Capture order keys.
-- %a = amount
-- %b = name of a buff/debuff
-- %c = name of creature (pet)
-- %f = name of the faction
-- %k = name of the skill
-- %n = name of enemy/player
-- %p = power type (mana, rage, energy)
-- %s = name of the ability/spell
-- %t = damage type
-- **********************************************************************************
function MikCEH.GetCapturedData(combatMessage, globalStringName, captureOrder)
-- Check if the passed global string does not exist.
if (getglobal(globalStringName) == nil) then
-- Print out a debug message.
MikSBT.PrintDebug("Unable to find global string: " .. globalStringName, 1, 0, 0);
return;
end
-- Format the global string into a lua compatible search string.
local globalStringInfo = MikCEH.GetGlobalStringInfo(globalStringName);
-- Whether or not the search pattern was found.
local stringFound = false;
-- Erase old captured data.
MikCEH.EraseTable(orderedCaptureData);
-- Get the unordered capture data.
local tempCapturedData = MikCEH.GetUnorderedCaptureDataTable(string_gfind(combatMessage, globalStringInfo.Search)());
-- If a match was found.
if (table_getn(tempCapturedData) ~= 0) then
-- Loop through all of the values in the passed capture order table.
for argNum, substituteValue in captureOrder do
local captureString = tempCapturedData[globalStringInfo.ArgumentOrder[argNum]];
if (substituteValue == "%a") then
orderedCaptureData.Amount = captureString;
elseif (substituteValue == "%b") then
orderedCaptureData.BuffName = captureString;
elseif (substituteValue == "%c") then
orderedCaptureData.PetName = captureString;
elseif (substituteValue == "%f") then
orderedCaptureData.FactionName = captureString;
elseif (substituteValue == "%k") then
orderedCaptureData.SkillName = captureString;
elseif (substituteValue == "%n") then
orderedCaptureData.Name = captureString;
elseif (substituteValue == "%p") then
orderedCaptureData.PowerType = captureString;
elseif (substituteValue == "%s") then
orderedCaptureData.SpellName = captureString;
elseif (substituteValue == "%t") then
orderedCaptureData.DamageType = MikCEH.GetDamageTypeNumber(captureString);
end
end
-- Return the captured data.
return orderedCaptureData;
end
-- Return nil value.
return nil;
end
-- **********************************************************************************
-- This function populates the unordered capture data table with all of the
-- parameters passed.
-- **********************************************************************************
function MikCEH.GetUnorderedCaptureDataTable(c1, c2, c3, c4, c5, c6, c7, c8, c9)
-- Assign directly by index instead of EraseTable + table_insert.
unorderedCaptureData[1] = c1;
unorderedCaptureData[2] = c2;
unorderedCaptureData[3] = c3;
unorderedCaptureData[4] = c4;
unorderedCaptureData[5] = c5;
unorderedCaptureData[6] = c6;
unorderedCaptureData[7] = c7;
unorderedCaptureData[8] = c8;
unorderedCaptureData[9] = c9;
-- Clear any leftover slots beyond 9.
local i = 10;
while unorderedCaptureData[i] do unorderedCaptureData[i] = nil; i = i + 1; end
-- Return the populated unordered capture data table.
return unorderedCaptureData;
end
-- **********************************************************************************
-- Gets the damage type number for the given string.
-- **********************************************************************************
function MikCEH.GetDamageTypeNumber(damageTypeString)
-- Return the correct damage type number for the passed string.
if (damageTypeString == SPELL_SCHOOL0_CAP) then
return MikCEH.DAMAGETYPE_PHYSICAL;
elseif (damageTypeString == SPELL_SCHOOL1_CAP) then
return MikCEH.DAMAGETYPE_HOLY;
elseif (damageTypeString == SPELL_SCHOOL2_CAP) then
return MikCEH.DAMAGETYPE_FIRE;
elseif (damageTypeString == SPELL_SCHOOL3_CAP) then
return MikCEH.DAMAGETYPE_NATURE;
elseif (damageTypeString == SPELL_SCHOOL4_CAP) then
return MikCEH.DAMAGETYPE_FROST;
elseif (damageTypeString == SPELL_SCHOOL5_CAP) then
return MikCEH.DAMAGETYPE_SHADOW;
elseif (damageTypeString == SPELL_SCHOOL6_CAP) then
return MikCEH.DAMAGETYPE_ARCANE;
elseif (damageTypeString == "Arcane") then
return MikCEH.DAMAGETYPE_ARCANE;
end
-- Return the unknown damage type.
return MikCEH.DAMAGETYPE_UNKNOWN;
end
-- **********************************************************************************
-- Get a string for the passed damage type.
-- **********************************************************************************
function MikCEH.GetDamageTypeString(damageType)
-- Return the correct damage type string for the passed number.
if (damageType == MikCEH.DAMAGETYPE_PHYSICAL) then
return SPELL_SCHOOL0_CAP;
elseif (damageType == MikCEH.DAMAGETYPE_HOLY) then
return SPELL_SCHOOL1_CAP;
elseif (damageType == MikCEH.DAMAGETYPE_FIRE) then
return SPELL_SCHOOL2_CAP;
elseif (damageType == MikCEH.DAMAGETYPE_NATURE) then
return SPELL_SCHOOL3_CAP;
elseif (damageType == MikCEH.DAMAGETYPE_FROST) then
return SPELL_SCHOOL4_CAP;
elseif (damageType == MikCEH.DAMAGETYPE_SHADOW) then
return SPELL_SCHOOL5_CAP;
elseif (damageType == MikCEH.DAMAGETYPE_ARCANE) then
return SPELL_SCHOOL6_CAP;
end
-- Return the unknown damage type string.
return UNKNOWN;
end
-- **********************************************************************************
-- Populates the combat event data table for a damage event with the passed info.
-- **********************************************************************************
function MikCEH.GetDamageEventData(directionType, actionType, hitType, damageType, amount, effectName, name)
-- Get the global combat event data table.
local eventData = MikCEH.CombatEventData;
-- Erase the combat event data table.
MikCEH.EraseTable(eventData);
-- Populate the event data fields.
eventData.EventType = MikCEH.EVENTTYPE_DAMAGE;
eventData.DirectionType = directionType;
eventData.ActionType = actionType;
eventData.HitType = hitType;
eventData.DamageType = damageType;
eventData.Amount = amount;
eventData.EffectName = effectName;
eventData.Name = name;
-- Return the event data.
return eventData;
end
-- **********************************************************************************
-- Populates the combat event data table for a heal event with the passed info.
-- **********************************************************************************
function MikCEH.GetHealEventData(directionType, healType, amount, effectName, name)
-- Get the global combat event data table.
local eventData = MikCEH.CombatEventData;
-- Erase the combat event data table.
MikCEH.EraseTable(eventData);
-- Populate the event data fields.
eventData.EventType = MikCEH.EVENTTYPE_HEAL;
eventData.DirectionType = directionType;
eventData.HealType = healType;
eventData.Amount = amount;
eventData.EffectName = effectName;
eventData.Name = name;
-- Return the event data.
return eventData;
end
-- **********************************************************************************
-- Populates the combat event data table for a notification event with the passed
-- info.
-- **********************************************************************************
function MikCEH.GetNotificationEventData(notificationType, amount, effectName, SpellName)
-- Get the global combat event data table.
local eventData = MikCEH.CombatEventData;
-- Erase the combat event data table.
MikCEH.EraseTable(eventData);
-- Populate the event data fields.
eventData.EventType = MikCEH.EVENTTYPE_NOTIFICATION;
eventData.NotificationType = notificationType;
eventData.Amount = amount;
if effectName == MANA or effectName == RAGE or effectName == ENERGY then
eventData.Amount = amount.." "..effectName;
eventData.EffectName = SpellName;
else
eventData.EffectName = effectName;
end
-- Return the event data.
return eventData;
end
-- **********************************************************************************
-- Gets a unit id for the name.
-- **********************************************************************************
function MikCEH.GetUnitIDFromName(uName)
local unitID, unitName;
-- SuperWoW fast path: O(1) unit lookup by name.
if hasSuperWoW then
local ok, exist, uid = pcall(UnitExists, uName)
if ok and exist then return uid, UnitName(uid) end
elseif LoggingCombat and LoggingCombat("RAW") == 1 then
local _, exist, uid = pcall(UnitExists, uName)
if _ and exist then
unitName = UnitName(uid)
return uid, unitName
end
end
-- Check if the name is the player.
if (uName == playerName) then
unitID = "player";
-- Check if the name is the pet.
elseif (uName == UnitName("pet")) then
unitID = "pet";
-- Check if the name is one of the player's raid or party members (cached).
else
if nameToUnitIDCacheDirty then RebuildNameToUnitIDCache() end
unitID = nameToUnitIDCache[uName]
end
if unitID then
unitName = UnitName(unitID)
-- Return the unit id.
return unitID, unitName
else
return nil, nil
end
end
-- **********************************************************************************
-- Populates the passed event data with overheal info.
-- **********************************************************************************
function MikCEH.PopulateOverhealData(eventData)
-- Get the appropriate unit id for the unit being checked for overheals.
local unitID, uName = MikCEH.GetUnitIDFromName(eventData.Name);
if not unitID then
if UnitName("target") == eventData.Name then
unitID = "target";
end
end
-- Make sure it's a valid unit id.
if (unitID) then
local healthMissing = UnitHealthMax(unitID) - UnitHealth(unitID);
local overhealAmount = eventData.Amount - healthMissing;
-- Check if any overhealing occured note threshold is 100 because heals on non-group members
-- will show show max health 100 instead of the proper maximum health of the target)
if (overhealAmount > 0 and UnitHealthMax(unitID) ~= 100) then
eventData.PartialActionType = MikCEH.PARTIALACTIONTYPE_OVERHEAL;
eventData.PartialAmount = overhealAmount;
end
end
end
-- **********************************************************************************
-- Sends the event to MSBT's combat events handler function.
-- **********************************************************************************
function MikCEH.SendEvent(eventData)
-- Make sure MSBT's combat events handler function is defined.
if (MikSBT.CombatEventsHandler ~= nil) then
MikSBT.CombatEventsHandler(eventData);
end
end
-- **********************************************************************************
-- Erases the passed table without losing the reference to the original memory.
-- This helps prevent GC churn.
-- **********************************************************************************
function MikCEH.EraseTable(t)
-- Loop through all the keys in the table and clear it.
for key in pairs(t) do
t[key] = nil;
end
-- Set the length of the table to 0.
table_setn(t, 0);
end
-------------------------------------------------------------------------------------
-- Trigger utility functions.
-------------------------------------------------------------------------------------
-- **********************************************************************************
-- Enables event searching mode. The passed pattern will be used to only show event
-- types where the combat message contains the pattern.
-- **********************************************************************************
function MikCEH.EnableEventSearching(pattern)
-- Enable the event searching mode flag and set the search pattern
-- to the passed pattern.
searchMode = true;
searchModePattern = pattern;
end
-- **********************************************************************************
-- Disables event searching mode.
-- **********************************************************************************
function MikCEH.DisableEventSearching()
-- Clear the event searching mode flag and search pattern.
searchMode = false;
searchModePattern = nil;
end
-- **********************************************************************************
-- Sends the trigger to MSBT's trigger events handler function.
-- **********************************************************************************
function MikCEH.SendTriggerEvent(eventData)
-- Make sure MSBT's trigger handler function is defined.
if (MikSBT.TriggerHandler ~= nil) then
MikSBT.TriggerHandler(eventData);
end
end
-- **********************************************************************************
-- Populates the trigger event data table using the passed info
-- **********************************************************************************
function MikCEH.GetSearchTriggerEventData(triggerKey, capturedData)
-- Get the common trigger event data table.
local eventData = MikCEH.TriggerEventData;
-- Erase the trigger event data table.
MikCEH.EraseTable(eventData);
-- Populate the trigger event data fields.
eventData.TriggerKey = triggerKey;
eventData.NumCaptures = table_getn(capturedData);
-- Loop through each captured data entry and set a corresponding field in
-- the trigger event.
for i = 1, eventData.NumCaptures do
eventData["CapturedData" .. i] = capturedData[i];
end
-- Return the event data.
return eventData;
end
-- **********************************************************************************
-- Populates the trigger event data table using the passed info
-- **********************************************************************************
function MikCEH.GetThresholdTriggerEventData(triggerKey, triggerAmount)
-- Get the common trigger event data table.
local eventData = MikCEH.TriggerEventData;
-- Erase the trigger event data table.
MikCEH.EraseTable(eventData);
-- Populate the trigger event data fields.
eventData.TriggerKey = triggerKey;
eventData.NumCaptures = 1;
eventData.CapturedData1 = triggerAmount;
-- Return the event data.
return eventData;
end
-------------------------------------------------------------------------------------
-- Trigger functions.
-------------------------------------------------------------------------------------
-- **********************************************************************************
-- Registers the passed trigger key with the passed trigger settings.
-- **********************************************************************************
function MikCEH.RegisterTrigger(triggerKey, triggerSettings)
-- Check if the trigger is for the player's class.
if (not triggerSettings.Classes or triggerSettings.Classes[playerClass]) then
-- Add to various arrays of triggers to check. This is done so time is not wasted on
-- checking for triggers that don't apply.
-- Self Health.
if (triggerSettings.TriggerType == MikCEH.TRIGGERTYPE_SELF_HEALTH) then
selfHealthTriggers[triggerKey] = triggerSettings;
-- Self Mana.
elseif (triggerSettings.TriggerType == MikCEH.TRIGGERTYPE_SELF_MANA) then
selfManaTriggers[triggerKey] = triggerSettings;
-- Pet Health.
elseif (triggerSettings.TriggerType == MikCEH.TRIGGERTYPE_PET_HEALTH) then
petHealthTriggers[triggerKey] = triggerSettings;
-- Enemy Health.
elseif (triggerSettings.TriggerType == MikCEH.TRIGGERTYPE_ENEMY_HEALTH) then
enemyHealthTriggers[triggerKey] = triggerSettings;
-- Friendly Health.
elseif (triggerSettings.TriggerType == MikCEH.TRIGGERTYPE_FRIENDLY_HEALTH) then
friendlyHealthTriggers[triggerKey] = triggerSettings;
-- Search Pattern.
elseif (triggerSettings.TriggerType == MikCEH.TRIGGERTYPE_SEARCH_PATTERN) then
-- Loop through all of the trigger events.
for _, triggerEvent in triggerSettings.TriggerEvents do
-- Check if there is not already a table for the trigger event and create one.
if (not searchPatternTriggers[triggerEvent]) then
searchPatternTriggers[triggerEvent] = {};
end
-- Add the trigger to the search pattern array for the event.
searchPatternTriggers[triggerEvent][triggerKey] = triggerSettings;
end
end
end -- Is trigger for class?
end
-- **********************************************************************************
-- Unregisters all of the triggers.
-- **********************************************************************************
function MikCEH.UnregisterAllTriggers()
-- Erase the trigger arrays.
MikCEH.EraseTable(selfHealthTriggers);
MikCEH.EraseTable(selfManaTriggers);
MikCEH.EraseTable(petHealthTriggers);
MikCEH.EraseTable(enemyHealthTriggers);
MikCEH.EraseTable(friendlyHealthTriggers);
MikCEH.EraseTable(searchPatternTriggers);
end
-- **********************************************************************************
-- Parses the self health triggers.
-- **********************************************************************************
function MikCEH.ParseSelfHealthTriggers()
local healthAmount = UnitHealth("player");
local healthPercentage = healthAmount / UnitHealthMax("player");
-- Loop through self health triggers.
for triggerKey, triggerSettings in selfHealthTriggers do
-- Check if we just crossed the trigger's threshold.
if (healthPercentage < triggerSettings.Threshold/100 and lastSelfHealthPercentage >= triggerSettings.Threshold/100) then
-- Get trigger event data and call the trigger handler.
local eventData = MikCEH.GetThresholdTriggerEventData(triggerKey, healthAmount);
MikCEH.SendTriggerEvent(eventData);
if MikSBT.CurrentProfile.LowHealthSound then
PlaySoundFile("Interface\\AddOns\\MikScrollingBattleText\\sounds\\LowHealth.mp3");
end
end
end
-- Update the last health percentage.
lastSelfHealthPercentage = healthPercentage;
end
-- **********************************************************************************
-- Parses the self mana triggers.
-- **********************************************************************************
function MikCEH.ParseSelfManaTriggers()
-- Make sure we're dealing with mana.
if (UnitPowerType("player") == 0) then
local manaAmount = UnitMana("player");
local manaPercentage = manaAmount / UnitManaMax("player");
-- Mana per Five Ticks
local manaDiff = manaAmount - lastSelfManaAmount;
if ( manaDiff > 0 and MikSBT.CurrentProfile.ShowAllManaGains) then
local eventData = MikCEH.GetNotificationEventData(MikCEH.NOTIFICATIONTYPE_POWER_GAIN, manaDiff.." "..MANA, 0);
MikCEH.SendEvent(eventData);
end
-- Loop through self mana triggers.
for triggerKey, triggerSettings in selfManaTriggers do
-- Check if we just crossed the trigger's threshold.
if (manaPercentage < triggerSettings.Threshold/100 and lastSelfManaPercentage >= triggerSettings.Threshold/100) then
-- Get trigger event data and call the trigger handler.
local eventData = MikCEH.GetThresholdTriggerEventData(triggerKey, manaAmount);
MikCEH.SendTriggerEvent(eventData);
if MikSBT.CurrentProfile.LowManaSound then
PlaySoundFile("Interface\\AddOns\\MikScrollingBattleText\\sounds\\LowMana.mp3");
end
end
end
-- Update the last mana percentage.
lastSelfManaPercentage = manaPercentage;
lastSelfManaAmount = manaAmount;
end
end
-- **********************************************************************************
-- Parses the pet health triggers.
-- **********************************************************************************
function MikCEH.ParsePetHealthTriggers()
local healthAmount = UnitHealth("pet");
local maxHealth = UnitHealthMax("pet");
if (not maxHealth or maxHealth == 0) then return end
local healthPercentage = healthAmount / maxHealth;
-- Loop through pet health triggers.
for triggerKey, triggerSettings in petHealthTriggers do
-- Check if we just crossed the trigger's threshold.
if (healthPercentage < triggerSettings.Threshold/100 and lastPetHealthPercentage >= triggerSettings.Threshold/100) then
-- Get trigger event data and call the trigger handler.
local eventData = MikCEH.GetThresholdTriggerEventData(triggerKey, healthAmount);
MikCEH.SendTriggerEvent(eventData)
end
end
-- Update the last health percentage.
lastPetHealthPercentage = healthPercentage;
end
-- **********************************************************************************
-- Parses the enemy health triggers.
-- **********************************************************************************
function MikCEH.ParseEnemyHealthTriggers()
local healthAmount = UnitHealth("target");
local maxHealth = UnitHealthMax("target");
if (not maxHealth or maxHealth == 0) then return end
local healthPercentage = healthAmount / maxHealth;
-- Loop through self health triggers.
for triggerKey, triggerSettings in enemyHealthTriggers do
-- Check if we just crossed the trigger's threshold.
if (healthPercentage < triggerSettings.Threshold/100 and lastEnemyHealthPercentage >= triggerSettings.Threshold/100) then
-- Get trigger event data and call the trigger handler.
local eventData = MikCEH.GetThresholdTriggerEventData(triggerKey, healthAmount);
MikCEH.SendTriggerEvent(eventData)
end
end
-- Update the last health percentage.
lastEnemyHealthPercentage = healthPercentage;
end
-- **********************************************************************************
-- Parses the friendly health triggers.
-- **********************************************************************************
function MikCEH.ParseFriendlyHealthTriggers()
local healthAmount = UnitHealth("target");
local maxHealth = UnitHealthMax("target");
if (not maxHealth or maxHealth == 0) then return end
local healthPercentage = healthAmount / maxHealth;
-- Loop through self health triggers.
for triggerKey, triggerSettings in friendlyHealthTriggers do
-- Check if we just crossed the trigger's threshold.
if (healthPercentage < triggerSettings.Threshold/100 and lastFriendlyHealthPercentage >= triggerSettings.Threshold/100) then
-- Get trigger event data and call the trigger handler.
local eventData = MikCEH.GetThresholdTriggerEventData(triggerKey, healthAmount);
MikCEH.SendTriggerEvent(eventData)
end
end
-- Update the last health percentage.
lastFriendlyHealthPercentage = healthPercentage;
end
-- **********************************************************************************
-- Parses the search pattern triggers for a match with the passed combat message
-- and event.
-- **********************************************************************************
function MikCEH.ParseSearchPatternTriggers(event, combatMessage)
-- Check if event search mode is enabled.
if (searchMode) then
-- Check if the pattern is in the combat message.
if (string_find(combatMessage, searchModePattern)) then
-- Print out the event type and the combat message.
MikSBT.Print(event .. " - " .. combatMessage, 0, 1, 0);
end
end
-- Check if there are no triggers for the event type and bail.
if (not searchPatternTriggers[event]) then
return;
end
-- Loop through all triggers for the event.
for triggerKey, triggerSettings in searchPatternTriggers[event] do
-- Loop through all of the search patterns for the trigger.
for _, searchPattern in triggerSettings.SearchPatterns do
-- Check if the search pattern is a global string.
if (getglobal(searchPattern) ~= nil) then
-- Format the global string into a lua compatible search string.
local globalStringInfo = MikCEH.GetGlobalStringInfo(searchPattern);
-- Replace the search pattern with the lua compatible search string.
searchPattern = globalStringInfo.Search;
end
-- Get capture data.
local capturedData = MikCEH.GetUnorderedCaptureDataTable(string_gfind(combatMessage, searchPattern)());
-- Check if a match was found.
if (table_getn(capturedData) ~= 0) then
-- Get trigger event data and call the trigger handler.
local eventData = MikCEH.GetSearchTriggerEventData(triggerKey, capturedData);
MikCEH.SendTriggerEvent(eventData);
break;
end
end -- Loop through search patterns.
end -- Loop through triggers.
end