commit 73212ebe33c2a5bc364314f18eff7c77850c123d Author: Athene Date: Fri May 29 23:25:35 2015 +0200 Initial Release Clean MSBT 3.01 from Mik's diff --git a/MikScrollingBattleText/Artwork/PlainBackdrop.tga b/MikScrollingBattleText/Artwork/PlainBackdrop.tga new file mode 100644 index 0000000..035352b Binary files /dev/null and b/MikScrollingBattleText/Artwork/PlainBackdrop.tga differ diff --git a/MikScrollingBattleText/Fonts/adventure.ttf b/MikScrollingBattleText/Fonts/adventure.ttf new file mode 100644 index 0000000..964ab3c Binary files /dev/null and b/MikScrollingBattleText/Fonts/adventure.ttf differ diff --git a/MikScrollingBattleText/Fonts/backsplatter.ttf b/MikScrollingBattleText/Fonts/backsplatter.ttf new file mode 100644 index 0000000..ab7ca25 Binary files /dev/null and b/MikScrollingBattleText/Fonts/backsplatter.ttf differ diff --git a/MikScrollingBattleText/Fonts/budhand.ttf b/MikScrollingBattleText/Fonts/budhand.ttf new file mode 100644 index 0000000..47098e1 Binary files /dev/null and b/MikScrollingBattleText/Fonts/budhand.ttf differ diff --git a/MikScrollingBattleText/Fonts/comic.ttf b/MikScrollingBattleText/Fonts/comic.ttf new file mode 100644 index 0000000..d17e1be Binary files /dev/null and b/MikScrollingBattleText/Fonts/comic.ttf differ diff --git a/MikScrollingBattleText/Fonts/creeper.ttf b/MikScrollingBattleText/Fonts/creeper.ttf new file mode 100644 index 0000000..8bccc58 Binary files /dev/null and b/MikScrollingBattleText/Fonts/creeper.ttf differ diff --git a/MikScrollingBattleText/Fonts/porky.ttf b/MikScrollingBattleText/Fonts/porky.ttf new file mode 100644 index 0000000..00bb1b6 Binary files /dev/null and b/MikScrollingBattleText/Fonts/porky.ttf differ diff --git a/MikScrollingBattleText/Fonts/signature.ttf b/MikScrollingBattleText/Fonts/signature.ttf new file mode 100644 index 0000000..c173b83 Binary files /dev/null and b/MikScrollingBattleText/Fonts/signature.ttf differ diff --git a/MikScrollingBattleText/MikCombatEventHelper.lua b/MikScrollingBattleText/MikCombatEventHelper.lua new file mode 100644 index 0000000..9752e4d --- /dev/null +++ b/MikScrollingBattleText/MikCombatEventHelper.lua @@ -0,0 +1,3277 @@ +------------------------------------------------------------------------------------- +-- Title: Mik's Combat Event Helper +-- Author: Mik +------------------------------------------------------------------------------------- + +-- Create "namespace." +MikCEH = {}; + +------------------------------------------------------------------------------------- +-- 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; + +-- 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; + +-- 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 lastPetHealthPercentage = 0; +local lastEnemyHealthPercentage = 0; +local lastFriendlyHealthPercentage = 0; + +-- Holds a list of recently selected hostile players. +local recentlySelectedPlayers = {}; +local elapsedTime = 0; + + +------------------------------------------------------------------------------------- +-- 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_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_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. + + -- Register for the ADDON_LOADED event. + MCEHEventFrame:RegisterEvent("ADDON_LOADED"); +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 + + -- 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 + elseif (event == "UNIT_HEALTH") then + if (arg1 == "player") then + MikCEH.ParseSelfHealthTriggers(); + elseif (arg1 == "target") then + -- Check if the target is an enemy. + if (not UnitIsFriend("player", "target")) then + MikCEH.ParseEnemyHealthTriggers(); + -- Target is not an enemy. + else + MikCEH.ParseFriendlyHealthTriggers(); + end + elseif (arg1 == "pet") then + MikCEH.ParsePetHealthTriggers(); + end + + -- Mana changes + elseif (event == "UNIT_MANA") then + if (arg1 == "player") then + MikCEH.ParseSelfManaTriggers(); + end + + -- 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 playerName = UnitName("target"); + if (playerName) then + recentlySelectedPlayers[playerName] = 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 + + +-- ********************************************************************************** +-- This function parses the chat message combat events. +-- ********************************************************************************** +function MikCEH.ParseCombatEvents(event, combatMessage) + -- Incoming Melee Hits/Crits + if (event == "CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS" or + event == "CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS" or + event == "CHAT_MSG_COMBAT_PARTY_HITS") then + MikCEH.ParseForIncomingHits(combatMessage); + + -- Incoming Melee Misses, Dodges, Parries, Blocks, Absorbs, Immunes + elseif (event == "CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES" or + event == "CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES" or + event == "CHAT_MSG_COMBAT_PARTY_MISSES") then + MikCEH.ParseForIncomingMisses(combatMessage); + + -- Incoming Spell/Ability Damage, Misses, Dodges, Parries, Blocks, Absorbs, Resists, Immunes, Power Losses + elseif (event == "CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE" or + event == "CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE" or + event == "CHAT_MSG_SPELL_PARTY_DAMAGE") then + MikCEH.ParseForIncomingSpellHitsAndMisses(combatMessage); + MikCEH.ParseForPowerLosses(combatMessage); + + -- Incoming damage from shields + elseif (event == "CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS") then + MikCEH.ParseForIncomingDamageShieldDamage(combatMessage); + + -- Incoming Heals + elseif (event == "CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF" or + event == "CHAT_MSG_SPELL_CREATURE_VS_SELF_BUFF") then + MikCEH.ParseForIncomingSpellHeals(combatMessage); + + -- Incoming Debuffs, DoTs, Power Gains + elseif (event == "CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE") then + MikCEH.ParseForIncomingDebuffs(combatMessage); + MikCEH.ParseForPowerGains(combatMessage); + + -- Incoming Buffs, HoTs, Power Gains + elseif (event == "CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS") then + if (not MikCEH.ParseForIncomingSpellHeals(combatMessage)) then + MikCEH.ParseForIncomingBuffs(combatMessage); + MikCEH.ParseForOutgoingHoTs(combatMessage); + end + + + + -- Outgoing Melee Hits/Crits, Environmental Damage + elseif (event == "CHAT_MSG_COMBAT_SELF_HITS") then + if (not MikCEH.ParseForEnvironmentalDamage(combatMessage)) then + MikCEH.ParseForOutgoingHits(combatMessage); + end + + -- Outgoing Melee Misses, Dodges, Parries, Blocks, Absorbs, Immunes, Evades + elseif (event == "CHAT_MSG_COMBAT_SELF_MISSES") then + MikCEH.ParseForOutgoingMisses(combatMessage); + + -- Outgoing Spell/Ability Damage, Misses, Dodges, Parries, Blocks, Absorbs, Resists, Immunes, Evades + elseif (event == "CHAT_MSG_SPELL_SELF_DAMAGE") then + MikCEH.ParseForOutgoingSpellHitsAndMisses(combatMessage); + + -- Outgoing damage from shields + elseif (event == "CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF") then + MikCEH.ParseForOutgoingDamageShieldDamage(combatMessage); + + -- Outgoing Heals, Power Gains, Dispel/Purge Resists + elseif (event == "CHAT_MSG_SPELL_SELF_BUFF") then + if (not MikCEH.ParseForPowerGains(combatMessage)) then + MikCEH.ParseForOutgoingSpellHeals(combatMessage); + MikCEH.ParseForOutgoingDispelResists(combatMessage); + end + + -- Outgoing HoTs + elseif (event == "CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS" or + event == "CHAT_MSG_SPELL_PERIODIC_PARTY_BUFFS") then + MikCEH.ParseForOutgoingHoTs(combatMessage); + + -- Outgoing DoTs, Power Losses + elseif (event == "CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE" or + event == "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE") then + MikCEH.ParseForOutgoingDoTs(combatMessage); + MikCEH.ParseForPowerLosses(combatMessage); + + -- Outgoing Pet Hits/Crits + elseif (event == "CHAT_MSG_COMBAT_PET_HITS") then + MikCEH.ParseForOutgoingPetHits(combatMessage); + + -- Outgoing Pet Melee Misses + elseif(event == "CHAT_MSG_COMBAT_PET_MISSES") then + MikCEH.ParseForOutgoingPetMisses(combatMessage); + + -- Outgoing Pet Spell/Ability Damage, Misses, Dodges, Parries, Blocks, Absorbs, Resists, Immunes, Evades + elseif(event == "CHAT_MSG_SPELL_PET_DAMAGE") then + MikCEH.ParseForOutgoingPetSpellHitsAndMisses(combatMessage); + + + + -- Item Buffs + elseif (event == "CHAT_MSG_SPELL_ITEM_ENCHANTMENTS") then + MikCEH.ParseForIncomingItemBuffs(combatMessage); + + -- Buff Fades + elseif (event == "CHAT_MSG_SPELL_AURA_GONE_SELF") then + MikCEH.ParseForBuffFades(combatMessage); + + -- Honor Gains + elseif (event == "CHAT_MSG_COMBAT_HONOR_GAIN") then + MikCEH.ParseForHonorGains(combatMessage); + + -- Reputation Gains/Losses + elseif (event == "CHAT_MSG_COMBAT_FACTION_CHANGE") then + MikCEH.ParseForReputationGainsAndLosses(combatMessage); + + -- Skill Gains + elseif (event == "CHAT_MSG_SKILL") then + MikCEH.ParseForSkillGains(combatMessage); + + -- Experience Gains + elseif (event == "CHAT_MSG_COMBAT_XP_GAIN") then + MikCEH.ParseForExperienceGains(combatMessage); + + -- Killing Blows + elseif (event == "CHAT_MSG_COMBAT_HOSTILE_DEATH") then + MikCEH.ParseForKillingBlows(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"); +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 + + + -- 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 + + -- 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 + + + -- 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 + + -- 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); + + -- 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); + + -- 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); + + -- 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); + + -- 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. + local capturedData = MikCEH.GetCapturedData(combatMessage, "PERIODICAURADAMAGEOTHERSELF", {"%a", "%t", "%n", "%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, 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 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) + -- Look for self power gains. + local capturedData = MikCEH.GetCapturedData(combatMessage, "POWERGAINSELFSELF", {"%a", "%p", "%s"}); + + -- 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); + + -- Send the event. + MikCEH.SendEvent(eventData); + + -- Return the parse was successful. + return true; + end + end + + -- Look for power gains from others. + local capturedData = MikCEH.GetCapturedData(combatMessage, "POWERGAINOTHERSELF", {"%a", "%p", "%n", "%s"}); + + -- 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); + + -- 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); + + -- 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); + + -- 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); + + -- 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 + + -- 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 = MikCEH.GetDamageEventData(MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING, MikCEH.ACTIONTYPE_HIT, MikCEH.HITTYPE_NORMAL, capturedData.DamageType, capturedData.Amount, 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 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); + + -- 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 + + + -- 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. + searchString = searchString .. "(.+)"; + + -- 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) + -- Erase old unorderd capture data. + MikCEH.EraseTable(unorderedCaptureData); + + if (c1 ~= nil) then table.insert(unorderedCaptureData, c1); end + if (c2 ~= nil) then table.insert(unorderedCaptureData, c2); end + if (c3 ~= nil) then table.insert(unorderedCaptureData, c3); end + if (c4 ~= nil) then table.insert(unorderedCaptureData, c4); end + if (c5 ~= nil) then table.insert(unorderedCaptureData, c5); end + if (c6 ~= nil) then table.insert(unorderedCaptureData, c6); end + if (c7 ~= nil) then table.insert(unorderedCaptureData, c7); end + if (c8 ~= nil) then table.insert(unorderedCaptureData, c8); end + if (c9 ~= nil) then table.insert(unorderedCaptureData, c9); 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; + 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) + -- 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; + eventData.EffectName = effectName; + + -- Return the event data. + return eventData; +end + + +-- ********************************************************************************** +-- Gets a unit id for the name. +-- ********************************************************************************** +function MikCEH.GetUnitIDFromName(uName) + local unitID; + + -- Check if the name is the player. + if (uName == playerName) then + unitID = "player"; + + -- Check if the name is one of the player's raid or party members. + else + -- Loop through all of the raid members. + local numRaidMembers = GetNumRaidMembers(); + for i = 1, numRaidMembers do + if (uName == UnitName("raid" .. i)) then + unitID = "raid" .. i; + end + end + + -- Check if the unit ID was not already found. + if (not unitID) then + -- Loop through all of the party members. + local numPartyMembers = GetNumPartyMembers(); + for i = 1, numPartyMembers do + if (uName == UnitName("party" .. i)) then + unitID = "party" .. i; + end + end + end + + end + + -- Return the unit id. + return unitID; +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 = MikCEH.GetUnitIDFromName(eventData.Name); + + -- 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. + if (overhealAmount > 0) 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) + 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"); + + -- 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) + end + end + + -- Update the last mana percentage. + lastSelfManaPercentage = manaPercentage; + end +end + + +-- ********************************************************************************** +-- Parses the pet health triggers. +-- ********************************************************************************** +function MikCEH.ParsePetHealthTriggers() + local healthAmount = UnitHealth("pet"); + local healthPercentage = healthAmount / UnitHealthMax("pet"); + + -- 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 healthPercentage = healthAmount / UnitHealthMax("target"); + + -- 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 healthPercentage = healthAmount / UnitHealthMax("target"); + + -- 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 \ No newline at end of file diff --git a/MikScrollingBattleText/MikCombatEventHelper.xml b/MikScrollingBattleText/MikCombatEventHelper.xml new file mode 100644 index 0000000..f36ffe2 --- /dev/null +++ b/MikScrollingBattleText/MikCombatEventHelper.xml @@ -0,0 +1,13 @@ + + + + + + MikCEH.OnEvent(); + MikCEH.OnLoad(); + MikCEH.OnUpdate(); + + + \ No newline at end of file diff --git a/MikScrollingBattleText/MikScrollingBattleText.lua b/MikScrollingBattleText/MikScrollingBattleText.lua new file mode 100644 index 0000000..940e471 --- /dev/null +++ b/MikScrollingBattleText/MikScrollingBattleText.lua @@ -0,0 +1,2242 @@ +------------------------------------------------------------------------------------- +-- Title: Mik's Scrolling Battle Text +-- Author: Mik +------------------------------------------------------------------------------------- + +------------------------------------------------------------------------------------- +-- Public Constants. +------------------------------------------------------------------------------------- + +-- Display types for incoming, outgoing, and notification events. +MikSBT.DISPLAYTYPE_INCOMING = 1; +MikSBT.DISPLAYTYPE_OUTGOING = 2; +MikSBT.DISPLAYTYPE_NOTIFICATION = 3; + + +------------------------------------------------------------------------------------- +-- Public Variables. +------------------------------------------------------------------------------------- + +-- Holds the current profile. +MikSBT.CurrentProfile = nil; + + +------------------------------------------------------------------------------------- +-- Private constants. +------------------------------------------------------------------------------------- + +-- Number of font strings. +local NUM_FONT_STRINGS = 15; + +-- Animation values for incoming and outgoing events. +local MIN_VERTICAL_SPACING = 8; + +-- How long to wait before showing events so that merges may happen. +local MERGE_DELAY_TIME = 0.3; + +-- How long to show stickies before they are faded. +local STICKY_FADE_IN_TIME = 0.15; +local STICKY_DISPLAY_TIME = 2; +local STICKY_FADE_OUT_TIME = 0.5; + +-- The animation speed. +local ANIMATION_SPEED = 0.015; + +-- Scroll directions +local SCROLL_DIRECTION_UP = 1; +local SCROLL_DIRECTION_DOWN = 2; + +-- Animation Styles +local ANIMATION_STYLE_STRAIGHT = 1; +local ANIMATION_STYLE_LEFT_PARABOLA = 2; +local ANIMATION_STYLE_RIGHT_PARABOLA = 3; + +-- Max number of combo points. +local MAX_COMBO_POINTS = 5; + + +------------------------------------------------------------------------------------- +-- Private variables. +------------------------------------------------------------------------------------- + +-- Holds whether or not debugging is active. +local debugMode = false; + + +-- Holds the events the mod is interested in. +local listenEvents = {}; + +-- Holds data for each scroll area. +local scrollAreas = {}; + +-- Holds arrays of unmerged events, merged events to be displayed and the time since +-- the last merge for incoming and outgoing events. +local animationMergeData = { + ["Incoming"] = {["TimeSinceMerge"] = 0, UnmergedEvents={}, MergedEvents={}}, + ["Outgoing"] = {["TimeSinceMerge"] = 0, UnmergedEvents={}, MergedEvents={}}, +}; + +-- Holds whether or not a merge is still being processed. +local stillMerging = false; + +-- Temp arrays for repositioning animation display data to avoid overlaps. +local activeNonStickies = {}; +local activeStickies = {}; + +-- Create a new table recycler object that holds up to 50 table references +-- in primary cache. +local eventsRecycler = MikTRO:NewRecyclerObject(50); + + +------------------------------------------------------------------------------------- +-- Printing functions. +------------------------------------------------------------------------------------- + +-- ********************************************************************************** +-- Prints out the passed message to the default chat frame. +-- ********************************************************************************** +function MikSBT.Print(msg, r, g, b) + -- Add the message to the default chat frame. + DEFAULT_CHAT_FRAME:AddMessage("MSBT: " .. msg, r, g, b); +end + + +-- ********************************************************************************** +-- Prints out the passed message to the default chat frame. +-- ********************************************************************************** +function MikSBT.PrintDebug(msg, r, g, b) + -- Check if debugging is active. + if (debugMode) then + -- Add the message to the default chat frame. + DEFAULT_CHAT_FRAME:AddMessage(msg, r, g, b); + end +end + + +------------------------------------------------------------------------------------- +-- Core event handlers. +------------------------------------------------------------------------------------- + +-- ********************************************************************************** +-- Registers all of the core events the mod is interested in. +-- ********************************************************************************** +function MikSBT.RegisterEvents() + -- Register the events we are interested in receiving for shaman. + for k, v in listenEvents do + MSBTEventFrame:RegisterEvent(v); + end +end + + +-- ********************************************************************************** +-- Unregisters all of the events the mod registered for. +-- ********************************************************************************** +function MikSBT.UnregisterEvents() + for k, v in listenEvents do + MSBTEventFrame:UnregisterEvent(v); + end +end + + +-- ********************************************************************************** +-- Called when the mod is loaded. +-- ********************************************************************************** +function MikSBT.OnLoad() + -- Register for the ADDON_LOADED event. + MSBTEventFrame:RegisterEvent("ADDON_LOADED"); +end + +-- ********************************************************************************** +-- Called when the events we registered for occur. +-- ********************************************************************************** +function MikSBT.OnEvent() + -- When an addon is loaded. + if (event == "ADDON_LOADED") then + -- Make sure it's this 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. + MikSBT.RegisterEvents(); + + -- Initialize the mod. + MikSBT.Init(); + end + + end +end + + +-- ********************************************************************************** +-- Called when the core events frame is updated. +-- ********************************************************************************** +function MikSBT.OnUpdate() + + -- Loop through all of the merge data tables. + for _, mergeData in animationMergeData do + -- Add the elapsed time since the last merge. + mergeData.TimeSinceMerge = mergeData.TimeSinceMerge + arg1; + + -- Once enough time has passed and all previous merges are done. + if ((mergeData.TimeSinceMerge >= MERGE_DELAY_TIME) and not stillMerging) then + -- Set the still merging flag. + stillMerging = true; + + -- Merge like events. + local numEvents = table.getn(mergeData.UnmergedEvents); + MikSBT.MergeEvents(mergeData, numEvents); + + -- Add the merged animation events to the animation system. + for _, animationEvent in mergeData.MergedEvents do + MikSBT.AddAnimation(animationEvent); + end + + -- Clear the merged animation events array. + local numMergedEvents = table.getn(mergeData.MergedEvents); + for i = 1, numMergedEvents do + table.remove(mergeData.MergedEvents, 1); + end + + + -- Reset the last merged time. + mergeData.TimeSinceMerge = 0; + + -- Clear the still merging flag. + stillMerging = false; + end + end +end + + +-- ********************************************************************************** +-- Called when the mod's animation frames are updated. +-- ********************************************************************************** +function MikSBT.OnUpdateAnimationFrame(frame) + local scrollArea; + + -- Get the frame's name. + local frameName = frame:GetName(); + if (frameName == scrollAreas.Incoming.AssociatedFrame) then + scrollArea = scrollAreas.Incoming; + elseif (frameName == scrollAreas.Outgoing.AssociatedFrame) then + scrollArea = scrollAreas.Outgoing; + elseif (frameName == scrollAreas.Notification.AssociatedFrame) then + scrollArea = scrollAreas.Notification; + end + + -- Flag for whether or not all the animations are inactive. + local allInactive = true; + + -- Loop through all possible animation display objects for the scroll area. + for _, animDisplayInfo in scrollArea.AnimationDisplayArray do + -- Check if the animation is active. + if (animDisplayInfo.IsActive) then + -- Do the animation and clear the all inactive flag. + MikSBT.DoAnimation(animDisplayInfo, scrollArea); + allInactive = false; + end + end + + -- Check if none of the animations are active and the events frame is visible. If so, hide it so + -- the OnUpdate events stop firing. This is done to keep the number of OnUpdate events down to a minimum for + -- better performance. + if (allInactive and frame:IsVisible()) then + frame:Hide(); + end +end + + +-- ********************************************************************************** +-- Called when the mod is fully loaded (variables loaded). +-- ********************************************************************************** +function MikSBT.Init() + -- Register slash commands + SLASH_MSBT1 = MikSBT.COMMAND; + SlashCmdList["MSBT"] = function (params) + MikSBT.CommandHandler(params); + end + + -- Check if there are no saved variables. + if (not MikSBT_Save or not MikSBT_Save.Profiles) then + MikSBT_Save = {}; + + MikSBT_Save.UserDisabled = false; + MikSBT_Save.CurrentProfile = MikSBT.DEFAULT_PROFILE_NAME; + MikSBT_Save.Profiles = {}; + MikSBT_Save.Profiles[MikSBT_Save.CurrentProfile] = {}; + + -- Set all the options to their defaults. + MikSBT.ResetProfile(MikSBT_Save.CurrentProfile); + end + + -- Updates profiles created by older versions. + MikSBT.UpdateProfiles(); + + + -- Set the current profile. + MikSBT.CurrentProfile = MikSBT_Save.Profiles[MikSBT_Save.CurrentProfile]; + + -- Sets up all of the animation scroll areas. + MikSBT.SetupAnimationScrollAreas(); + + -- Reposition the animation frames to the stored offsets. + MikSBT.RepositionAnimationFrames(); + + -- Register the triggers with the combat event helper. + MikSBT.RegisterTriggers(); + + -- Disable or enable the mod depending on the saved setting. + MikSBT.SetOptionUserDisabled(MikSBT_Save.UserDisabled) +end + + +-- ********************************************************************************** +-- Sets up all of the animation scroll areas. +-- ********************************************************************************** +function MikSBT.SetupAnimationScrollAreas() + -- Setup a table for data for each scroll area. + scrollAreas.Incoming = {}; + scrollAreas.Outgoing = {}; + scrollAreas.Notification = {}; + + -- Setup the associated frames. + scrollAreas.Incoming.AssociatedFrame = "MSBTFrameIncoming"; + scrollAreas.Outgoing.AssociatedFrame = "MSBTFrameOutgoing"; + scrollAreas.Notification.AssociatedFrame = "MSBTFrameNotification"; + + -- Setup the display settings. + scrollAreas.Incoming.DisplaySettings = MikSBT.CurrentProfile.DisplaySettings.Incoming; + scrollAreas.Outgoing.DisplaySettings = MikSBT.CurrentProfile.DisplaySettings.Outgoing; + scrollAreas.Notification.DisplaySettings = MikSBT.CurrentProfile.DisplaySettings.Notification; + + + -- Loop through the scroll areas. + for _, scrollArea in scrollAreas do + -- Initialize the next available animation display object. + scrollArea.NextAnimationDisplay = 1; + + -- Initialize the next available sticky animation display object. + scrollArea.FirstSticky = 11; + scrollArea.NextSticky = scrollArea.FirstSticky; + + -- Create arrays for the animation display info. + scrollArea.AnimationDisplayArray = {}; + + -- Associate the appropriate font string object for each animation display object. + for x = 1, NUM_FONT_STRINGS do + scrollArea.AnimationDisplayArray[x] = {}; + scrollArea.AnimationDisplayArray[x].FontObject = getglobal(scrollArea.AssociatedFrame .. "Text" .. x); + scrollArea.AnimationDisplayArray[x].LastUpdated = 0; + end + end +end + + +-- ********************************************************************************** +-- Repositions the animation frames based on the stored offsets. +-- ********************************************************************************** +function MikSBT.RepositionAnimationFrames() + -- Loop through each scroll area and reposition its associated frame. + for _, scrollArea in scrollAreas do + getglobal(scrollArea.AssociatedFrame):SetPoint("BOTTOM", "UIParent", "CENTER", scrollArea.DisplaySettings.FrameOffsets.x, scrollArea.DisplaySettings.FrameOffsets.y); + end +end + + +-- ********************************************************************************** +-- Receive combat events from Mik's combat event helper. +-- ********************************************************************************** +function MikSBT.CombatEventsHandler(combatEvent) + -- Get a recycled table from the events recycler object. + local animationEvent = eventsRecycler:AcquireTable(); + + -- Initalize the event type string to the common prefix. + local eventTypeString = "MSBT_EVENTTYPE_"; + + -- Append the appropriate direction type to the event type string. + if (combatEvent.DirectionType == MikCEH.DIRECTIONTYPE_PLAYER_INCOMING) then + animationEvent.ScrollArea = scrollAreas.Incoming; + eventTypeString = eventTypeString .. "INCOMING_"; + elseif (combatEvent.DirectionType == MikCEH.DIRECTIONTYPE_PLAYER_OUTGOING) then + animationEvent.ScrollArea = scrollAreas.Outgoing; + eventTypeString = eventTypeString .. "OUTGOING_"; + elseif (combatEvent.DirectionType == MikCEH.DIRECTIONTYPE_PET_OUTGOING) then + animationEvent.ScrollArea = scrollAreas.Outgoing; + eventTypeString = eventTypeString .. "OUTGOING_PET_"; + end + + -- Check if it's a damage event. + if (combatEvent.EventType == MikCEH.EVENTTYPE_DAMAGE) then + -- Check if there is an associated spell/ability name. + if (combatEvent.EffectName ~= nil) then + eventTypeString = eventTypeString .. "SPELL_"; + end + + -- Append the appropriate action type to the event type string. + if (combatEvent.ActionType == MikCEH.ACTIONTYPE_HIT) then + if (combatEvent.HitType == MikCEH.HITTYPE_OVER_TIME) then + eventTypeString = eventTypeString .. "DOT"; + else + eventTypeString = eventTypeString .. "DAMAGE"; + end + elseif (combatEvent.ActionType == MikCEH.ACTIONTYPE_MISS) then + eventTypeString = eventTypeString .. "MISS"; + elseif (combatEvent.ActionType == MikCEH.ACTIONTYPE_DODGE) then + eventTypeString = eventTypeString .. "DODGE"; + elseif (combatEvent.ActionType == MikCEH.ACTIONTYPE_PARRY) then + eventTypeString = eventTypeString .. "PARRY"; + elseif (combatEvent.ActionType == MikCEH.ACTIONTYPE_BLOCK) then + eventTypeString = eventTypeString .. "BLOCK"; + elseif (combatEvent.ActionType == MikCEH.ACTIONTYPE_RESIST) then + eventTypeString = eventTypeString .. "RESIST"; + elseif (combatEvent.ActionType == MikCEH.ACTIONTYPE_ABSORB) then + eventTypeString = eventTypeString .. "ABSORB"; + elseif (combatEvent.ActionType == MikCEH.ACTIONTYPE_IMMUNE) then + eventTypeString = eventTypeString .. "IMMUNE"; + elseif (combatEvent.ActionType == MikCEH.ACTIONTYPE_EVADE) then + eventTypeString = eventTypeString .. "EVADE"; + elseif (combatEvent.ActionType == MikCEH.ACTIONTYPE_REFLECT) then + eventTypeString = eventTypeString .. "REFLECT"; + elseif (combatEvent.ActionType == MikCEH.ACTIONTYPE_DROWNING) then + eventTypeString = eventTypeString .. "ENVIRONMENTAL" + combatEvent.EffectName = MikSBT.MSG_ENVIRONMENTAL_DROWNING; + elseif (combatEvent.ActionType == MikCEH.ACTIONTYPE_FALLING) then + eventTypeString = eventTypeString .. "ENVIRONMENTAL" + combatEvent.EffectName = MikSBT.MSG_ENVIRONMENTAL_FALLING; + elseif (combatEvent.ActionType == MikCEH.ACTIONTYPE_FATIGUE) then + eventTypeString = eventTypeString .. "ENVIRONMENTAL" + combatEvent.EffectName = MikSBT.MSG_ENVIRONMENTAL_FATIGUE; + elseif (combatEvent.ActionType == MikCEH.ACTIONTYPE_FIRE) then + eventTypeString = eventTypeString .. "ENVIRONMENTAL" + combatEvent.EffectName = MikSBT.MSG_ENVIRONMENTAL_FIRE; + elseif (combatEvent.ActionType == MikCEH.ACTIONTYPE_LAVA) then + eventTypeString = eventTypeString .. "ENVIRONMENTAL" + combatEvent.EffectName = MikSBT.MSG_ENVIRONMENTAL_LAVA; + elseif (combatEvent.ActionType == MikCEH.ACTIONTYPE_SLIME) then + eventTypeString = eventTypeString .. "ENVIRONMENTAL" + combatEvent.EffectName = MikSBT.MSG_ENVIRONMENTAL_SLIME; + end + + -- Heal event. + elseif (combatEvent.EventType == MikCEH.EVENTTYPE_HEAL) then + if (combatEvent.HealType == MikCEH.HEALTYPE_NORMAL or combatEvent.HealType == MikCEH.HEALTYPE_CRIT) then + eventTypeString = eventTypeString .. "HEAL"; + elseif (combatEvent.HealType == MikCEH.HEALTYPE_OVER_TIME) then + eventTypeString = eventTypeString .. "HOT"; + end + + + -- Notification event. + elseif (combatEvent.EventType == MikCEH.EVENTTYPE_NOTIFICATION) then + animationEvent.ScrollArea = scrollAreas.Notification; + eventTypeString = eventTypeString .. "NOTIFICATION_"; + + -- Append the appropriate notification type to the event type string. + if (combatEvent.NotificationType == MikCEH.NOTIFICATIONTYPE_DEBUFF) then + eventTypeString = eventTypeString .. "DEBUFF"; + elseif (combatEvent.NotificationType == MikCEH.NOTIFICATIONTYPE_BUFF) then + eventTypeString = eventTypeString .. "BUFF"; + elseif (combatEvent.NotificationType == MikCEH.NOTIFICATIONTYPE_ITEM_BUFF) then + eventTypeString = eventTypeString .. "ITEM_BUFF"; + elseif (combatEvent.NotificationType == MikCEH.NOTIFICATIONTYPE_BUFF_FADE) then + eventTypeString = eventTypeString .. "BUFF_FADE"; + elseif (combatEvent.NotificationType == MikCEH.NOTIFICATIONTYPE_COMBAT_ENTER) then + eventTypeString = eventTypeString .. "COMBAT_ENTER"; + elseif (combatEvent.NotificationType == MikCEH.NOTIFICATIONTYPE_COMBAT_LEAVE) then + eventTypeString = eventTypeString .. "COMBAT_LEAVE"; + elseif (combatEvent.NotificationType == MikCEH.NOTIFICATIONTYPE_POWER_GAIN) then + eventTypeString = eventTypeString .. "POWER_GAIN"; + elseif (combatEvent.NotificationType == MikCEH.NOTIFICATIONTYPE_POWER_LOSS) then + eventTypeString = eventTypeString .. "POWER_LOSS"; + elseif (combatEvent.NotificationType == MikCEH.NOTIFICATIONTYPE_CP_GAIN) then + -- Check if we are at max combo points. + if (combatEvent.Amount == MAX_COMBO_POINTS) then + eventTypeString = eventTypeString .. "CP_FULL"; + else + eventTypeString = eventTypeString .. "CP_GAIN"; + end + elseif (combatEvent.NotificationType == MikCEH.NOTIFICATIONTYPE_HONOR_GAIN) then + eventTypeString = eventTypeString .. "HONOR_GAIN"; + elseif (combatEvent.NotificationType == MikCEH.NOTIFICATIONTYPE_REP_GAIN) then + eventTypeString = eventTypeString .. "REP_GAIN"; + elseif (combatEvent.NotificationType == MikCEH.NOTIFICATIONTYPE_REP_LOSS) then + eventTypeString = eventTypeString .. "REP_LOSS"; + elseif (combatEvent.NotificationType == MikCEH.NOTIFICATIONTYPE_SKILL_GAIN) then + eventTypeString = eventTypeString .. "SKILL_GAIN"; + elseif (combatEvent.NotificationType == MikCEH.NOTIFICATIONTYPE_EXPERIENCE_GAIN) then + eventTypeString = eventTypeString .. "EXPERIENCE_GAIN"; + elseif (combatEvent.NotificationType == MikCEH.NOTIFICATIONTYPE_PC_KILLING_BLOW) then + eventTypeString = eventTypeString .. "PC_KILLING_BLOW"; + elseif (combatEvent.NotificationType == MikCEH.NOTIFICATIONTYPE_NPC_KILLING_BLOW) then + eventTypeString = eventTypeString .. "NPC_KILLING_BLOW"; + elseif (combatEvent.NotificationType ~= nil) then + eventTypeString = eventTypeString .. combatEvent.NotificationType; + end + end + + -- Check if the event is a crit and set the crit field appropriately + if (combatEvent.HitType == MikCEH.HITTYPE_CRIT or combatEvent.HealType == MikCEH.HEALTYPE_CRIT) then + animationEvent.IsCrit = true; + end + + -- Copy the amount, effect name, and player/enemy name from the passed combat event data. + animationEvent.Amount = combatEvent.Amount; + animationEvent.EffectName = combatEvent.EffectName; + animationEvent.Name = combatEvent.Name; + + -- Check if there is a damage type and get the appropriate string. + if (combatEvent.DamageType ~= nil) then + animationEvent.DamageType = MikCEH.GetDamageTypeString(combatEvent.DamageType); + end + + -- If there are partial action types set the partial effect text appropriately. + if (combatEvent.PartialActionType == MikCEH.PARTIALACTIONTYPE_ABSORB) then + if (ABSORB_TRAILER) then + animationEvent.PartialEffectText = string.gsub(ABSORB_TRAILER, "%%d", combatEvent.PartialAmount); + end + elseif (combatEvent.PartialActionType == MikCEH.PARTIALACTIONTYPE_BLOCK) then + if (BLOCK_TRAILER) then + animationEvent.PartialEffectText = string.gsub(BLOCK_TRAILER, "%%d", combatEvent.PartialAmount); + end + elseif (combatEvent.PartialActionType == MikCEH.PARTIALACTIONTYPE_RESIST) then + if (RESIST_TRAILER) then + animationEvent.PartialEffectText = string.gsub(RESIST_TRAILER, "%%d", combatEvent.PartialAmount); + end + elseif (combatEvent.PartialActionType == MikCEH.PARTIALACTIONTYPE_VULNERABLE) then + if (MikSBT.MSG_VULERNABLE_TRAILER) then + animationEvent.PartialEffectText = string.gsub(MikSBT.MSG_VULERNABLE_TRAILER, "%%d", combatEvent.PartialAmount); + end + elseif (combatEvent.PartialActionType == MikCEH.PARTIALACTIONTYPE_CRUSHING) then + if (CRUSHING_TRAILER) then + animationEvent.PartialEffectText = CRUSHING_TRAILER; + end + elseif (combatEvent.PartialActionType == MikCEH.PARTIALACTIONTYPE_GLANCING) then + if (GLANCING_TRAILER) then + animationEvent.PartialEffectText = GLANCING_TRAILER; + end + elseif (combatEvent.PartialActionType == MikCEH.PARTIALACTIONTYPE_OVERHEAL) then + animationEvent.OverhealAmount = combatEvent.PartialAmount; + end + + + + -- Check if there is profile data for the event type. + if (MikSBT.CurrentProfile.EventSettings[eventTypeString]) then + -- Set the event type, the settings for it, its unformatted text and dispatch it to the animation system. + animationEvent.EventType = eventTypeString; + animationEvent.EventSettings = MikSBT.CurrentProfile.EventSettings[animationEvent.EventType]; + animationEvent.UnformattedText = animationEvent.EventSettings.Message; + + -- Dispatch the event to the animation system. + MikSBT.DispatchAnimationEvent(animationEvent); + else + -- Print an error message and reclaim the animation event table to the table recycler. + MikSBT.Print("No profile data found for " .. eventTypeString, 1, 0, 0) + eventsRecycler:ReclaimTable(animationEvent); + end +end + + + +-- ********************************************************************************** +-- Receive trigger events from Mik's trigger helper. +-- ********************************************************************************** +function MikSBT.TriggerHandler(triggerEvent) + -- Get a recycled table from the events recycler object. + local animationEvent = eventsRecycler:AcquireTable(); + + -- Check if there is profile data for the trigger. + if (MikSBT.CurrentProfile.Triggers[triggerEvent.TriggerKey].EventSettings) then + -- Set the scroll area, event settings, and output text. + animationEvent.ScrollArea = scrollAreas.Notification; + animationEvent.EventSettings = MikSBT.CurrentProfile.Triggers[triggerEvent.TriggerKey].EventSettings; + MikSBT.FormatTriggerText(animationEvent, triggerEvent); + + -- Dispatch the event to the animation system. + MikSBT.DispatchAnimationEvent(animationEvent); + else + -- Print an error message and reclaim the animation event table to the table recycler. + MikSBT.Print("No profile data found for trigger key " .. triggerEvent.TriggerKey, 1, 0, 0); + eventsRecycler:ReclaimTable(animationEvent); + end +end + + +------------------------------------------------------------------------------------- +-- Utility functions. +------------------------------------------------------------------------------------- + +-- ********************************************************************************** +-- This function copies a table. +-- ********************************************************************************** +function MikSBT.CopyTable(srcTable) + -- Create a new table. + local newTable = {}; + + -- Loop through all of the entires in the table. + for key, value in srcTable do + -- Check if it's a nested table. + if (type(value) == "table") then + -- Recursively call the function to copy the nested table. + value = MikSBT.CopyTable(value); + end + + -- Make a copy of the value into the new table. + newTable[key] = value; + end + + -- Return the new table. + return newTable; +end + + +-- ********************************************************************************** +-- Merges like animation events. +-- ********************************************************************************** +function MikSBT.MergeEvents(mergeData, numEvents) + -- Hold whether or not the event was merged. + local eventMerged = false; + + -- Don't attempt to merge any more events than were available when the function was called since + -- more events may get added while the merge is taking place. + for x = 1, numEvents do + + -- Loop through all of the events in the merged events array. + for _, animationEvent in mergeData.MergedEvents do + -- Check if the event types match and the effect names are the same. + if ((mergeData.UnmergedEvents[x].EventType == animationEvent.EventType) and + (mergeData.UnmergedEvents[x].EffectName == animationEvent.EffectName)) then + + -- Check if there is no effect name + if (mergeData.UnmergedEvents[x].EffectName == nil) then + -- Check if the affected unit name is the same. + if ((mergeData.UnmergedEvents[x].Name == animationEvent.Name) and mergeData.UnmergedEvents[x].Name ~= nil) then + -- Do Merge. + eventMerged = true; + end -- Same name. + + -- There is an effect name. + else + -- Check if there is a name and replace it with the multiple targets string. + if (animationEvent.Name ~= nil) then + animationEvent.Name = MikSBT.MSG_MULTIPLE_TARGETS; + end + + -- Do Merge. + eventMerged = true; + end -- Effect name? + end -- Event types match and effect names the same. + + + -- Check if the event should be merged. + if (eventMerged) then + -- Set the event merged flag for the event being merged. + mergeData.UnmergedEvents[x].EventMerged = true; + + -- If the events have an amount then total them. + if (animationEvent.Amount ~= nil and mergeData.UnmergedEvents[x].Amount ~= nil) then + animationEvent.Amount = animationEvent.Amount + mergeData.UnmergedEvents[x].Amount; + end + + -- Check if there is an overheal amount and total it. + if (mergeData.UnmergedEvents[x].OverhealAmount ~= nil) then + animationEvent.OverhealAmount = (animationEvent.OverhealAmount or 0) + mergeData.UnmergedEvents[x].OverhealAmount; + end + + -- Clear any partial effect text. + animationEvent.PartialEffectText = nil; + + + -- Increment the number of merged events. + animationEvent.NumMerged = animationEvent.NumMerged + 1; + + -- Check if the event being merged is a crit and increment the number of crits. + if (mergeData.UnmergedEvents[x].IsCrit) then + animationEvent.NumCrits = animationEvent.NumCrits + 1; + end + + -- Make sure the merged event is not flagged as a crit. + animationEvent.IsCrit = false; + end -- Do Merge. + end -- Loop through all merged events. + + + -- If the event wasn't merged add it to the end of the merged events array. + if (not eventMerged) then + local animationEvent = mergeData.UnmergedEvents[x]; + animationEvent.NumMerged = 0; + + -- Check if the event is a crit and set the number of crits appropriately. + if (animationEvent.IsCrit) then + animationEvent.NumCrits = 1; + else + animationEvent.NumCrits = 0; + end + + -- Add the animation event to the end of the merged events array. + table.insert(mergeData.MergedEvents, animationEvent); + end + + -- Reset the event merged flag. + eventMerged = false; + end + + + -- Loop through each event in the merged events array. + for _, animationEvent in mergeData.MergedEvents do + -- Check if there were any events merged. + if (animationEvent.NumMerged > 0) then + -- Create trailer text with the number of merged events. + local trailerText = " [" .. animationEvent.NumMerged + 1 .. " " .. MikSBT.MSG_HITS; + + -- Check if there were any crits merged. + if (animationEvent.NumCrits > 1) then + trailerText = trailerText .. ", " .. animationEvent.NumCrits .. " " .. MikSBT.MSG_CRITS; + elseif (animationEvent.NumCrits == 1) then + trailerText = trailerText .. ", " .. animationEvent.NumCrits .. " " .. MikSBT.MSG_CRIT; + end + + -- Close the merge string. + trailerText = trailerText .. "]"; + + -- Set the animation event's merge trailer text field. + animationEvent.MergeTrailerText = trailerText; + end + end + + + -- Remove the processed animation events from unmerged events queue. + for x = 1, numEvents do + -- Check if the event was merged into a different animation event. + if (mergeData.UnmergedEvents[1].EventMerged) then + -- Reclaim the animation event table to the events recycler. + eventsRecycler:ReclaimTable(mergeData.UnmergedEvents[1]); + end + + -- Remove the event from the unmerged events array. + table.remove(mergeData.UnmergedEvents, 1); + end +end + + +-- ********************************************************************************** +-- This function gets the appropriate font size for an event. +-- ********************************************************************************** +function MikSBT.GetFontSize(scrollArea, eventSettings, isCrit) + -- Holds the font sizes for the event level. + local eventFontSizeNormal = 0; + local eventFontSizeCrit = 0; + + -- Check if there are event settings. + if (eventSettings ~= nil) then + -- Get the font sizes for the event type. + eventFontSizeNormal = eventSettings.FontSettings.Normal.FontSize; + + -- Check if there are crit font settings for the event. + if (eventSettings.FontSettings.Crit ~= nil) then + eventFontSizeCrit = eventSettings.FontSettings.Crit.FontSize; + end + end + + -- Get the font sizes for the scroll area and master. + local scrollAreaFontSizeNormal = scrollArea.DisplaySettings.FontSettings.Normal.FontSize; + local scrollAreaFontSizeCrit = scrollArea.DisplaySettings.FontSettings.Crit.FontSize; + local masterFontSizeNormal = MikSBT.CurrentProfile.MasterFontSettings.Normal.FontSize; + local masterFontSizeCrit = MikSBT.CurrentProfile.MasterFontSettings.Crit.FontSize; + + + -- Get the normal font size for the event. + local fontSize = eventFontSizeNormal; + + -- Check if the font size is inherited from the scroll area font size. + if (fontSize == 0) then + fontSize = scrollAreaFontSizeNormal; + end + + -- Check if the font size for the scroll area is inherited from the master font size. + if (fontSize == 0) then + fontSize = masterFontSizeNormal; + end + + + -- Check if the event is a crit. + if (isCrit) then + -- Get the crit font size for the event. + fontSize = eventFontSizeCrit; + + -- Check if the font size is inherited from the scroll area font size. + if (fontSize == 0) then + fontSize = scrollAreaFontSizeCrit; + end + + -- Check if the font size for the scroll area is inherited from the master font size. + if (fontSize == 0) then + fontSize = masterFontSizeCrit; + end + end + + -- Return the font size. + return fontSize; +end + + +-- ********************************************************************************** +-- This function gets the appropriate font path for an event. +-- ********************************************************************************** +function MikSBT.GetFontPath(scrollArea, eventSettings, isCrit) + -- Holds the font indices for the event level. + local eventFontIndexNormal = 0; + local eventFontIndexCrit = 0; + + -- Check if there are event settings. + if (eventSettings ~= nil) then + -- Get the font indices for the event type. + eventFontIndexNormal = eventSettings.FontSettings.Normal.FontIndex; + + -- Check if there are crit font settings for the event. + if (eventSettings.FontSettings.Crit ~= nil) then + eventFontIndexCrit = eventSettings.FontSettings.Crit.FontIndex; + end + end + + -- Get the font indices for the scroll area and master. + local scrollAreaFontIndexNormal = scrollArea.DisplaySettings.FontSettings.Normal.FontIndex; + local scrollAreaFontIndexCrit = scrollArea.DisplaySettings.FontSettings.Crit.FontIndex; + local masterFontIndexNormal = MikSBT.CurrentProfile.MasterFontSettings.Normal.FontIndex; + local masterFontIndexCrit = MikSBT.CurrentProfile.MasterFontSettings.Crit.FontIndex; + + + -- Get the normal font index for the event. + local fontIndex = eventFontIndexNormal; + + -- Check if the font index is inherited from the scroll area font index. + if (fontIndex == 0) then + fontIndex = scrollAreaFontIndexNormal; + end + + -- Check if the font index for the scroll area is inherited from the master font index. + if (fontIndex == 0) then + fontIndex = masterFontIndexNormal; + end + + + -- Check if the event is a crit. + if (isCrit) then + -- Get the crit font index for the event. + fontIndex = eventFontIndexCrit; + + -- Check if the font index is inherited from the scroll area font index. + if (fontIndex == 0) then + fontIndex = scrollAreaFontIndexCrit; + end + + -- Check if the font index for the scroll area is inherited from the master font index. + if (fontIndex == 0) then + fontIndex = masterFontIndexCrit; + end + end + + -- Check if the font index is invalid and set it to the default if it is. + if (MikSBT.AVAILABLE_FONTS[fontIndex] == nil) then + fontIndex = 1; + end + + -- Return the font path. + return MikSBT.AVAILABLE_FONTS[fontIndex].Path; +end + + +-- ********************************************************************************** +-- This function gets the appropriate font outline style for an event. +-- ********************************************************************************** +function MikSBT.GetFontOutline(scrollArea, eventSettings, isCrit) + -- Holds the outline indices for the event level. + local eventOutlineIndexNormal = 0; + local eventOutlineIndexCrit = 0; + + -- Check if there are event settings. + if (eventSettings ~= nil) then + -- Get the outline indices for the event type. + eventOutlineIndexNormal = eventSettings.FontSettings.Normal.OutlineIndex; + + -- Check if there are crit font settings for the event. + if (eventSettings.FontSettings.Crit ~= nil) then + eventOutlineIndexCrit = eventSettings.FontSettings.Crit.OutlineIndex; + end + end + + -- Get the outline indices for the scroll area and master. + local scrollAreaOutlineIndexNormal = scrollArea.DisplaySettings.FontSettings.Normal.OutlineIndex; + local scrollAreaOutlineIndexCrit = scrollArea.DisplaySettings.FontSettings.Crit.OutlineIndex; + local masterOutlineIndexNormal = MikSBT.CurrentProfile.MasterFontSettings.Normal.OutlineIndex; + local masterOutlineIndexCrit = MikSBT.CurrentProfile.MasterFontSettings.Crit.OutlineIndex; + + + -- Get the normal outline index for the event. + local outlineIndex = eventOutlineIndexNormal; + + -- Check if the outline index is inherited from the scroll area outline index. + if (outlineIndex == 0) then + outlineIndex = scrollAreaOutlineIndexNormal; + end + + -- Check if the outline index for the scroll area is inherited from the master outline index. + if (outlineIndex == 0) then + outlineIndex = masterOutlineIndexNormal; + end + + + -- Check if the event is a crit. + if (isCrit) then + -- Get the crit outline index for the event. + outlineIndex = eventOutlineIndexCrit; + + -- Check if the outline index is inherited from the scroll area outline index. + if (outlineIndex == 0) then + outlineIndex = scrollAreaOutlineIndexCrit; + end + + -- Check if the outline index for the scroll area is inherited from the master outline index. + if (outlineIndex == 0) then + outlineIndex = masterOutlineIndexCrit; + end + end + + + -- Return the outline style. + return MikSBT.AVAILABLE_OUTLINES[outlineIndex].Style; +end + + +-- ********************************************************************************** +-- This function substitutes the codes in the unformatted text of the passed +-- animation event with the values in its fields. +-- ********************************************************************************** +function MikSBT.FormatEventText(animationEvent) + local outputString = animationEvent.UnformattedText; + + -- Check if there is no unformatted text and bail. + if (outputString == nil) then + return; + end + + -- Substitute amount. + if (animationEvent.Amount ~= nil) then + -- Check if there is overheal info + if (animationEvent.OverhealAmount ~= nil and MikSBT.CurrentProfile.ShowOverheals) then + local overhealTrailer = string.gsub(MikSBT.MSG_OVERHEAL_TRAILER, "%%d", animationEvent.OverhealAmount); + outputString = string.gsub(outputString, "%%a", (animationEvent.Amount - animationEvent.OverhealAmount) .. overhealTrailer); + else + outputString = string.gsub(outputString, "%%a", animationEvent.Amount); + end + end + + -- Substitute enemy/player names. + if (animationEvent.Name ~= nil) then + outputString = string.gsub(outputString, "%%n", animationEvent.Name); + end + + -- Substitute effect names. + if (animationEvent.EffectName ~= nil) then + outputString = string.gsub(outputString, "%%s", animationEvent.EffectName); + end + + -- Substitute damage types. + if (animationEvent.DamageType ~= nil) then + outputString = string.gsub(outputString, "%%t", animationEvent.DamageType); + end + + -- Check if there is partial effect text and the show partial effects flag is on and append it. + if (animationEvent.PartialEffectText ~= nil and MikSBT.CurrentProfile.ShowPartialEffects) then + outputString = outputString .. animationEvent.PartialEffectText; + end + + + -- Check if there is merge trailer text and append it. + if (animationEvent.MergeTrailerText ~= nil) then + outputString = outputString .. animationEvent.MergeTrailerText; + end + + -- Set the event's output text. + animationEvent.Text = outputString; +end + + +-- ********************************************************************************** +-- This function returns the output message for the passed trigger event with all +-- %1-9 codes substituted with captured data. +-- ********************************************************************************** +function MikSBT.FormatTriggerText(animationEvent, triggerEvent) + local outputString = animationEvent.EventSettings.Message; + + -- Check if there is no text and bail. + if (outputString == nil) then + return; + end + + -- Loop through all of the captures in the trigger event. + for i = 1, triggerEvent.NumCaptures do + outputString = string.gsub(outputString , "%%" .. i, triggerEvent["CapturedData" .. i]); + end + + -- Set the event's output text. + animationEvent.Text = outputString; +end + + +-- ********************************************************************************** +-- Registers the triggers in the current profile with combat event lib. +-- ********************************************************************************** +function MikSBT.RegisterTriggers() + -- Unregister all of the triggers from the combat event helper. + MikCEH.UnregisterAllTriggers(); + + -- Loop through all of the triggers in the current profile. + for triggerKey, triggerData in MikSBT.CurrentProfile.Triggers do + -- Make sure the trigger is being shown and register it with the combat event helper. + if (triggerData.EventSettings.Show) then + MikCEH.RegisterTrigger(triggerKey, triggerData.TriggerSettings); + end + end +end + + +------------------------------------------------------------------------------------- +-- Profile functions. +------------------------------------------------------------------------------------- + +-- ********************************************************************************** +-- Updates profiles created with older versions. +-- ********************************************************************************** +function MikSBT.UpdateProfiles() + -- Loop through all the profiles. + for _, profile in MikSBT_Save.Profiles do + -- Check if the profile was created prior to version 2.0. + if (profile.CreationVersion < 2.0) then + -- Update the profile's structure. + profile.ShowOverheals = MikSBT.DEFAULT_CONFIG.ShowOverheals; + profile.ShowGameDamage = MikSBT.DEFAULT_CONFIG.ShowGameDamage; + profile.UseStickyCrits = MikSBT.DEFAULT_CONFIG.UseStickyCrits; + + profile.EventSettings["MSBT_EVENTTYPE_INCOMING_SPELL_DOT"] = MikSBT.CopyTable(MikSBT.DEFAULT_CONFIG.EventSettings["MSBT_EVENTTYPE_INCOMING_SPELL_DOT"]); + profile.EventSettings["MSBT_EVENTTYPE_INCOMING_HOT"] = MikSBT.CopyTable(MikSBT.DEFAULT_CONFIG.EventSettings["MSBT_EVENTTYPE_INCOMING_HOT"]); + profile.EventSettings["MSBT_EVENTTYPE_OUTGOING_SPELL_DOT"] = MikSBT.CopyTable(MikSBT.DEFAULT_CONFIG.EventSettings["MSBT_EVENTTYPE_OUTGOING_SPELL_DOT"]); + profile.EventSettings["MSBT_EVENTTYPE_OUTGOING_HOT"] = MikSBT.CopyTable(MikSBT.DEFAULT_CONFIG.EventSettings["MSBT_EVENTTYPE_OUTGOING_HOT"]); + + -- Update the creation version to the current version. + profile.CreationVersion = 2.0; + end + + + -- Check if the profile was created prior to version 2.1. + if (profile.CreationVersion < 2.1) then + -- Update the profile's structure. + + -- Loop through all of the event settings. + for eventTypeName, eventType in profile.EventSettings do + -- Check for the event types that can't be crits and remove the crit settings table. + if (string.find(eventTypeName, "MISS") or string.find(eventTypeName, "DODGE") or string.find(eventTypeName, "PARRY") or + string.find(eventTypeName, "BLOCK") or string.find(eventTypeName, "ABSORB") or string.find(eventTypeName, "IMMUNE") or + string.find(eventTypeName, "DOT") or string.find(eventTypeName, "RESIST") or string.find(eventTypeName, "HOT") or + string.find(eventTypeName, "ENVIRONMENTAL") or string.find(eventTypeName, "EVADE") or string.find(eventTypeName, "NOTIFICATION")) then + + -- Remove the crit settings table. + eventType.FontSettings.Crit = nil; + end + + -- Check if the event type is a notification and add the IsSticky flag. + if (string.find(eventTypeName, "NOTIFICATION")) then + eventType.IsSticky = MikSBT.DEFAULT_CONFIG.EventSettings[eventTypeName].IsSticky; + end + + -- Add event settings for experience gains. + profile.EventSettings["MSBT_EVENTTYPE_NOTIFICATION_EXPERIENCE_GAIN"] = MikSBT.CopyTable(MikSBT.DEFAULT_CONFIG.EventSettings["MSBT_EVENTTYPE_NOTIFICATION_EXPERIENCE_GAIN"]); + end + + -- Update the creation version to the current version. + profile.CreationVersion = 2.1; + end + + + -- Check if the profile was created prior to version 3.0. + if (profile.CreationVersion < 3.0) then + -- Remove the low health, low mana, and execute notification event settings since they are now triggers. + profile.EventSettings["MSBT_EVENTTYPE_NOTIFICATION_LOW_HEALTH"] = nil; + profile.EventSettings["MSBT_EVENTTYPE_NOTIFICATION_LOW_MANA"] = nil; + profile.EventSettings["MSBT_EVENTTYPE_NOTIFICATION_EXECUTE"] = nil; + + -- Remove the low health and low mana warning percentage info since they are now triggers. + profile.WarningPercentageHealth = nil; + profile.WarningPercentageMana = nil; + + + -- Update the profile's structure with triggers. + profile.Triggers = MikSBT.CopyTable(MikSBT.DEFAULT_CONFIG.Triggers); + + -- Add event settings for killing blows. + profile.EventSettings["MSBT_EVENTTYPE_NOTIFICATION_PC_KILLING_BLOW"] = MikSBT.CopyTable(MikSBT.DEFAULT_CONFIG.EventSettings["MSBT_EVENTTYPE_NOTIFICATION_PC_KILLING_BLOW"]); + profile.EventSettings["MSBT_EVENTTYPE_NOTIFICATION_NPC_KILLING_BLOW"] = MikSBT.CopyTable(MikSBT.DEFAULT_CONFIG.EventSettings["MSBT_EVENTTYPE_NOTIFICATION_NPC_KILLING_BLOW"]); + + -- Update the profile's structure with suppresions. + profile.Suppressions = MikSBT.CopyTable(MikSBT.DEFAULT_CONFIG.Suppressions); + + -- Update the creation version to the current version. + profile.CreationVersion = 3.0; + end + + end +end + + +-- ********************************************************************************** +-- Returns whether or not the passed profile exists. +-- ********************************************************************************** +function MikSBT.ProfileExists(profileName) + local profileFound = false; + + -- Loop through all of the profiles looking for the passed one. + for pName in MikSBT_Save.Profiles do + if (pName == profileName) then + profileFound = true; + end + end + + -- Return whether or not the profile exists. + return profileFound; +end + + +-- ********************************************************************************** +-- Resets the passed profile to its defaults. +-- ********************************************************************************** +function MikSBT.ResetProfile(profileName, showOutput) + -- Get whether or not the profile exists. + local profileExists = MikSBT.ProfileExists(profileName); + + -- Check if the profile exists. + if (profileExists) then + -- Reset the profile. + MikSBT_Save.Profiles[profileName] = MikSBT.CopyTable(MikSBT.DEFAULT_CONFIG); + + -- Check if it's the current profile being reset. + if (profileName == MikSBT_Save.CurrentProfile) then + -- Reset the current profile pointer. + MikSBT.CurrentProfile = MikSBT_Save.Profiles[MikSBT_Save.CurrentProfile]; + + -- Reassociate the display settings if the scroll areas have been setup. + if (scrollAreas.Incoming ~= nil) then + -- Setup the display settings. + scrollAreas.Incoming.DisplaySettings = MikSBT.CurrentProfile.DisplaySettings.Incoming; + scrollAreas.Outgoing.DisplaySettings = MikSBT.CurrentProfile.DisplaySettings.Outgoing; + scrollAreas.Notification.DisplaySettings = MikSBT.CurrentProfile.DisplaySettings.Notification; + end + + -- Reposition the animation frames. + MikSBT.RepositionAnimationFrames(); + + -- Register the triggers with the combat event helper. + MikSBT.RegisterTriggers(); + end + + -- Check if the output text is to be shown. + if (showOutput) then + -- Print the profile reset string. + MikSBT.Print(profileName .. " " .. MikSBT.MSG_PROFILE_RESET, 0, 1, 0); + end + end +end + + +-- ********************************************************************************** +-- Selects the passed profile. +-- ********************************************************************************** +function MikSBT.SelectProfile(profileName) + -- Get whether or not the profile exists. + local profileExists = MikSBT.ProfileExists(profileName); + + -- Check if the profile exists. + if (profileExists) then + -- Set the current profile name to the one being selected. + MikSBT_Save.CurrentProfile = profileName; + + -- Reset the current profile pointer. + MikSBT.CurrentProfile = MikSBT_Save.Profiles[MikSBT_Save.CurrentProfile]; + + -- Reassociate the display settings if the scroll areas have been setup. + if (scrollAreas.Incoming ~= nil) then + -- Setup the display settings. + scrollAreas.Incoming.DisplaySettings = MikSBT.CurrentProfile.DisplaySettings.Incoming; + scrollAreas.Outgoing.DisplaySettings = MikSBT.CurrentProfile.DisplaySettings.Outgoing; + scrollAreas.Notification.DisplaySettings = MikSBT.CurrentProfile.DisplaySettings.Notification; + end + + -- Reposition the animation frames. + MikSBT.RepositionAnimationFrames(); + + -- Register the triggers with the combat event helper. + MikSBT.RegisterTriggers(); + end +end + + +-- ********************************************************************************** +-- Creates a profile for the passed name. +-- ********************************************************************************** +function MikSBT.CreateProfile(profileName) + -- Get whether or not the profile exists. + local profileExists = MikSBT.ProfileExists(profileName); + + -- Make sure a profile name was passed and it doesn't already exist. + if (not profileExists and profileName ~= nil and profileName ~= "") then + -- Create an array for the profile. + MikSBT_Save.Profiles[profileName] = {}; + + -- Reset the profile. + MikSBT.ResetProfile(profileName); + end +end + + +-- ********************************************************************************** +-- Deletes the passed profile. +-- ********************************************************************************** +function MikSBT.DeleteProfile(profileName) + -- Check if the passed profile is the default one. + if (profileName == MikSBT.DEFAULT_PROFILE_NAME) then + return; + end + + -- Get whether or not the profile exists. + local profileExists = MikSBT.ProfileExists(profileName); + + -- Check if the profile exists. + if (profileExists) then + -- Check if the profile being deleted is the current one. + if (profileName == MikSBT_Save.CurrentProfile) then + -- Select the default profile. + MikSBT.SelectProfile(MikSBT.DEFAULT_PROFILE_NAME); + end + + -- Delete the profile. + MikSBT_Save.Profiles[profileName] = nil; + end +end + + +------------------------------------------------------------------------------------- +-- Option functions. +------------------------------------------------------------------------------------- + +-- ********************************************************************************** +-- Set the user disabled option +-- ********************************************************************************** +function MikSBT.SetOptionUserDisabled(isDisabled) + MikSBT_Save.UserDisabled = isDisabled; + + -- Check if the mod is being set to disabled. + if (isDisabled) then + -- Unregister all events. + MikSBT.UnregisterEvents(); + MikCEH.UnregisterEvents(); + + -- Turn on the game's display of outgoing damage. + SetCVar("CombatDamage", 1); + + -- Turn on Blizzard's default combat text. + if (SHOW_COMBAT_TEXT ~= nil) then + SHOW_COMBAT_TEXT = 1; + end + else + -- Reregister events. + MikSBT.RegisterEvents(); + MikCEH.RegisterEvents(); + + -- Turn the game damage display on or off depending on the user setting. + MikSBT.SetOptionShowGameDamage(MikSBT.CurrentProfile.ShowGameDamage); + + -- Turn off Blizzard's default combat text. + if (SHOW_COMBAT_TEXT ~= nil) then + SHOW_COMBAT_TEXT = 0; + end + + -- Make sure that periodic spell effects are reported. + SetCVar("CombatLogPeriodicSpells", 1); + end +end + + +-- ********************************************************************************** +-- Set the game damage disabled option +-- ********************************************************************************** +function MikSBT.SetOptionShowGameDamage(showDamage) + MikSBT.CurrentProfile.ShowGameDamage = showDamage; + + -- Check if the game damage is being set to on. + if (showDamage) then + -- Turn on the game damage display. + SetCVar("CombatDamage", 1); + else + -- Turn off the game damage display. + SetCVar("CombatDamage", 0); + end +end + + +-- ********************************************************************************** +-- This function takes a string version of a variable path +-- and returns its value from the current profile. +-- ********************************************************************************** +function MikSBT.GetOptionFromVarPath(varPath) + -- Set the current table to the current profile. + local currentTable = MikSBT.CurrentProfile; + + -- Index into each sub table until we reach the actual variable wanted. + for varName in string.gfind(varPath, "[%w_]+") do + if (type(currentTable[varName]) == "table") then + currentTable = currentTable[varName]; + else + return currentTable[varName]; + end + end + + return nil; +end + + +-- ********************************************************************************** +-- This function takes a string version of a variable path +-- and sets its value in the current profile to the passed value. +-- ********************************************************************************** +function MikSBT.SetOptionFromVarPath(varPath, newValue) + -- Sets the current table to the current profile. + local currentTable = MikSBT.CurrentProfile; + + -- Index into each sub table until we reach the actual variable wanted and set it + -- to the passed value. + for varName in string.gfind(varPath, "[%w_]+") do + if (type(currentTable[varName]) == "table") then + currentTable = currentTable[varName] + else + currentTable[varName] = newValue; + end + end +end + + +------------------------------------------------------------------------------------- +-- Animation functions. +------------------------------------------------------------------------------------- + +-- ********************************************************************************** +-- Adds the passed animation event to the animation system for the appropriate scroll +-- area. +-- +-- animationEvent Possible Fields: +-- ScrollArea - The scroll area to use for the event. +-- EventType - The event type. +-- EventSettings - The event settings for the event. +-- IsCrit - Whether or not the event is a crit. +-- UnformattedText - The unformatted text to display. +-- Amount - The amount of the attack, heal, gain, loss, etc. +-- EffectName - The name of the spell, ability, buff, debuff, power type, etc. +-- Name - The name of the enemy/player. +-- DamageType - The type of damage. +-- PartialEffectText - Partial effect text to be appended. (partial resists, absorbs, blocks) +-- OverhealAmount - The amount overhealed. +-- Text - The formatted text to display. +-- ********************************************************************************** +function MikSBT.DispatchAnimationEvent(animationEvent) + -- Check if the event is to be shown. + if (animationEvent.EventSettings.Show and animationEvent.ScrollArea.DisplaySettings.Show) then + + -- If it's an incoming or outgoing event add it to the associated scroll area's events array + -- for potential merging. + if (animationEvent.ScrollArea == scrollAreas.Incoming) then + table.insert(animationMergeData.Incoming.UnmergedEvents, animationEvent); + elseif (animationEvent.ScrollArea == scrollAreas.Outgoing) then + table.insert(animationMergeData.Outgoing.UnmergedEvents, animationEvent); + + -- Add the event the animation system. + else + MikSBT.AddAnimation(animationEvent); + end + end +end + + +-- ********************************************************************************** +-- Add the event to the appropriate scroll area's animation display array. +-- ********************************************************************************** +function MikSBT.AddAnimation(animationEvent) + -- Format the animation event's output text. + MikSBT.FormatEventText(animationEvent); + + -- Loop through all of the suppression entries and look for a match. + for _, suppressionSettings in MikSBT.CurrentProfile.Suppressions do + -- Check if the suppression's search pattern is a match. + if (suppressionSettings.Enabled and string.find(animationEvent.Text, suppressionSettings.SearchPattern)) then + -- Reclaim the animation event table to the events recycler and leave the function. + eventsRecycler:ReclaimTable(animationEvent); + return; + end + end + + + -- Check if the animation event is to be displayed sticky style. + if (animationEvent.EventSettings ~= nil and animationEvent.EventSettings.IsSticky) then + animationEvent.IsSticky = true; + end + + + -- Get the next available animation display info object for the scroll area. + local animDisplayInfo = MikSBT.GetNextAnimationDisplayInfo(animationEvent); + + -- Get the scroll function to use. + animDisplayInfo.ScrollFunction = MikSBT.GetScrollFunction(animationEvent); + + -- Get the starting X and Y positions. + animDisplayInfo.PositionX, animDisplayInfo.PositionY = MikSBT.GetAnimationStartingPosition(animationEvent) + + + -- Check if the animation event has event settings associated with it. + if (animationEvent.EventSettings ~= nil) then + -- Get the font size for the event. + animDisplayInfo.FontSize = MikSBT.GetFontSize(animationEvent.ScrollArea, animationEvent.EventSettings, animationEvent.IsCrit); + + -- Get the font path for the event. + animDisplayInfo.FontPath = MikSBT.GetFontPath(animationEvent.ScrollArea, animationEvent.EventSettings, animationEvent.IsCrit); + + -- Get the font outline style for the event. + animDisplayInfo.FontOutline = MikSBT.GetFontOutline(animationEvent.ScrollArea, animationEvent.EventSettings, animationEvent.IsCrit); + + -- Set the r, g, and b color for the animation display object. + animDisplayInfo.ColorR = animationEvent.EventSettings.FontSettings.Color.r; + animDisplayInfo.ColorG = animationEvent.EventSettings.FontSettings.Color.g; + animDisplayInfo.ColorB = animationEvent.EventSettings.FontSettings.Color.b; + + -- No event type associated with the event so get the display info from the animation event itself. + else + -- Get the font size for the event. + animDisplayInfo.FontSize = animationEvent.FontSize; + + -- Get the font path for the event. + animDisplayInfo.FontPath = animationEvent.FontPath; + + -- Get the font outline style for the event. + animDisplayInfo.FontOutline = animationEvent.FontOutline; + + -- Set the r, g, and b color for the animation display object. + animDisplayInfo.ColorR = animationEvent.ColorR; + animDisplayInfo.ColorG = animationEvent.ColorG; + animDisplayInfo.ColorB = animationEvent.ColorB; + end + + + -- Set the animation display alpha, anchor point, crit flag, and sticky flag. + animDisplayInfo.Alpha = 0; + animDisplayInfo.AnchorPoint = MikSBT.AVAILABLE_TEXT_ALIGNS[animationEvent.ScrollArea.DisplaySettings.FontSettings.TextAlignIndex].AnchorPoint; + animDisplayInfo.IsCrit = animationEvent.IsCrit; + animDisplayInfo.IsSticky = animationEvent.IsSticky; + + -- Set the font object properties. + animDisplayInfo.FontObject:ClearAllPoints(); + animDisplayInfo.FontObject:SetFont(animDisplayInfo.FontPath, animDisplayInfo.FontSize, animDisplayInfo.FontOutline); + animDisplayInfo.FontObject:SetTextColor(animDisplayInfo.ColorR, animDisplayInfo.ColorG, animDisplayInfo.ColorB); + animDisplayInfo.FontObject:SetText(animationEvent.Text); + animDisplayInfo.FontObject:SetAlpha(animDisplayInfo.Alpha); + animDisplayInfo.FontObject:SetPoint(animDisplayInfo.AnchorPoint, animDisplayInfo.PositionX, animDisplayInfo.PositionY); + + + -- Set the last update to the current time. + animDisplayInfo.LastUpdated = GetTime(); + + -- Set the active flag. + animDisplayInfo.IsActive = true; + + + -- Check if the scroll area's display frame is not visible and make it visible so the OnUpdate events start firing. + -- This is done to keep the number of OnUpdate events down to a minimum for better performance. + if (not getglobal(animationEvent.ScrollArea.AssociatedFrame):IsVisible()) then + getglobal(animationEvent.ScrollArea.AssociatedFrame):Show(); + end + + -- Check if it's a sticky or a crit and sticky crits are enabled. + if (animDisplayInfo.IsSticky or (animDisplayInfo.IsCrit and MikSBT.CurrentProfile.UseStickyCrits)) then + -- Make sure the stickies don't overlap. + MikSBT.RepositionStickyAnimDisplayInfo(animationEvent.ScrollArea); + else + -- Make sure there are no overlaps in the scrolling text. + MikSBT.RepositionAnimDisplayInfo(animationEvent.ScrollArea); + end + + -- Reclaim the animation event table to the events recycler. + eventsRecycler:ReclaimTable(animationEvent); +end + + +-- ********************************************************************************** +-- This function gets the next animation display info object for the correct +-- scroll area. +-- ********************************************************************************** +function MikSBT.GetNextAnimationDisplayInfo(animationEvent) + -- Holds the next animation display info object. + local animDisplayInfo; + + -- Check if it's a sticky or it's a crit and sticky crits are enabled. + if (animationEvent.IsSticky or (animationEvent.IsCrit and MikSBT.CurrentProfile.UseStickyCrits)) then + -- Get the next available animation display object for stickies. + -- This is done so that stickies use the last set of font strings to avoid normal hits + -- overlapping them. + animDisplayInfo = animationEvent.ScrollArea.AnimationDisplayArray[animationEvent.ScrollArea.NextSticky]; + + -- Increment to the next sticky animation display object. + animationEvent.ScrollArea.NextSticky = animationEvent.ScrollArea.NextSticky + 1; + + -- Loop back around to the first sticky animation display object. + if (animationEvent.ScrollArea.NextSticky > NUM_FONT_STRINGS) then + animationEvent.ScrollArea.NextSticky = animationEvent.ScrollArea.FirstSticky; + end + + -- Not a sticky. + else + -- Get the next available animation display object. + animDisplayInfo = animationEvent.ScrollArea.AnimationDisplayArray[animationEvent.ScrollArea.NextAnimationDisplay]; + + -- Increment to the next animation display object. + animationEvent.ScrollArea.NextAnimationDisplay = animationEvent.ScrollArea.NextAnimationDisplay + 1; + + -- Loop back around to the first animation display object. + if (animationEvent.ScrollArea.NextAnimationDisplay > (animationEvent.ScrollArea.FirstSticky - 1)) then + animationEvent.ScrollArea.NextAnimationDisplay = 1; + end + end + + -- Return the animation display info object. + return animDisplayInfo; +end + + +-- ********************************************************************************** +-- This function gets the scroll function to use for the event. +-- ********************************************************************************** +function MikSBT.GetScrollFunction(animationEvent) + -- Straight animation style. + if (animationEvent.ScrollArea.DisplaySettings.AnimationStyle == ANIMATION_STYLE_STRAIGHT) then + -- Text is scrolling down. + if (animationEvent.ScrollArea.DisplaySettings.ScrollDirection == SCROLL_DIRECTION_DOWN) then + -- Return the appropriate animation function. + return MikSBT.ScrollStraightDown; + -- Text is scrolling up. + else + -- Return the appropriate animation function. + return MikSBT.ScrollStraightUp; + end + + -- Left parabola animation style. + elseif (animationEvent.ScrollArea.DisplaySettings.AnimationStyle == ANIMATION_STYLE_LEFT_PARABOLA) then + -- Text is scrolling down. + if (animationEvent.ScrollArea.DisplaySettings.ScrollDirection == SCROLL_DIRECTION_DOWN) then + -- Return the appropriate animation function. + return MikSBT.ScrollLeftParabolaDown; + -- Text is scrolling up. + else + -- Return the appropriate animation function. + return MikSBT.ScrollLeftParabolaUp; + end + + -- Right parabola animation style. + elseif (animationEvent.ScrollArea.DisplaySettings.AnimationStyle == ANIMATION_STYLE_RIGHT_PARABOLA) then + -- Text is scrolling down. + if (animationEvent.ScrollArea.DisplaySettings.ScrollDirection == SCROLL_DIRECTION_DOWN) then + -- Return the appropriate animation function. + return MikSBT.ScrollRightParabolaDown; + -- Text is scrolling up. + else + -- Return the appropriate animation function. + return MikSBT.ScrollRightParabolaUp; + end + + end + + -- Default to the straight up animation style although the function should never get + -- to this point. + return MikSBT.ScrollStraightUp; +end + + +-- ********************************************************************************** +-- This function gets the starting animation x and and y position. +-- ********************************************************************************** +function MikSBT.GetAnimationStartingPosition(animationEvent) + -- Holds where to start the animation at. + local startPositionX, startPositionY; + + -- Check which animation style is selected for the scroll area. + if (animationEvent.ScrollArea.DisplaySettings.AnimationStyle == ANIMATION_STYLE_STRAIGHT or + animationEvent.ScrollArea.DisplaySettings.AnimationStyle == ANIMATION_STYLE_LEFT_PARABOLA or + animationEvent.ScrollArea.DisplaySettings.AnimationStyle == ANIMATION_STYLE_RIGHT_PARABOLA) then + + -- Check if the text is scrolling down. + if (animationEvent.ScrollArea.DisplaySettings.ScrollDirection == SCROLL_DIRECTION_DOWN) then + -- Set the starting X and Y positions. + startPositionX = 0; + startPositionY = animationEvent.ScrollArea.DisplaySettings.ScrollHeight; + -- Text is scrolling up. + else + -- Set the starting X and Y positions. + startPositionX = 0; + startPositionY = 0; + end + + -- Check if it's a sticky or a crit and sticky crits are enabled. + if (animationEvent.IsSticky or (animationEvent.IsCrit and MikSBT.CurrentProfile.UseStickyCrits)) then + -- Set the sticky to the center. + startPositionY = ceil(animationEvent.ScrollArea.DisplaySettings.ScrollHeight / 2); + end + end + + -- Return the x and y starting positions. + return startPositionX, startPositionY; +end + + +-- ********************************************************************************** +-- This function makes sure there is no overlapping text. +-- ********************************************************************************** +function MikSBT.RepositionAnimDisplayInfo(scrollArea) + -- Construct a table with the non sticky animation display info in the same order the events were added. + for x = scrollArea.NextAnimationDisplay, scrollArea.FirstSticky-1 do + local animDisplayInfo = scrollArea.AnimationDisplayArray[x]; + if (animDisplayInfo.IsActive) then + table.insert(activeNonStickies, animDisplayInfo); + end + end + + for x = 1, scrollArea.NextAnimationDisplay-1 do + local animDisplayInfo = scrollArea.AnimationDisplayArray[x]; + if (animDisplayInfo.IsActive) then + table.insert(activeNonStickies, animDisplayInfo); + end + end + + -- Get the number of active non sticky data objects. + local numNonStickies = table.getn(activeNonStickies); + + -- Animation style straight, left parabola, or right parabola. + if (scrollArea.DisplaySettings.AnimationStyle == ANIMATION_STYLE_STRAIGHT or + scrollArea.DisplaySettings.AnimationStyle == ANIMATION_STYLE_LEFT_PARABOLA or + scrollArea.DisplaySettings.AnimationStyle == ANIMATION_STYLE_RIGHT_PARABOLA) then + + -- Scrolling down. + if (scrollArea.DisplaySettings.ScrollDirection == SCROLL_DIRECTION_DOWN) then + + -- Check if there is more than 1 active non sticky animation. + if (numNonStickies > 1) then + -- Loop backwards through the active non sticky animation display objects and move the ones that are colliding. + for x = numNonStickies, 2, -1 do + local bottomPointCurrent = activeNonStickies[x].PositionY; + local topPointNext = activeNonStickies[x-1].PositionY + activeNonStickies[x-1].FontSize + MIN_VERTICAL_SPACING; + if (topPointNext > bottomPointCurrent) then + activeNonStickies[x-1].PositionY = bottomPointCurrent - activeNonStickies[x-1].FontSize - MIN_VERTICAL_SPACING; + end + end + end + + -- Scrolling up. + else + + -- Check if there is more than 1 active non sticky animation. + if (numNonStickies > 1) then + -- Loop backwards through the active non sticky animation display objects and move the ones that are colliding. + for x = numNonStickies, 2, -1 do + local topPointCurrent = activeNonStickies[x].PositionY + activeNonStickies[x].FontSize + MIN_VERTICAL_SPACING; + local bottomPointNext = activeNonStickies[x-1].PositionY; + if (bottomPointNext < topPointCurrent) then + activeNonStickies[x-1].PositionY = topPointCurrent; + end + end + end + + end -- Scrolling Direction + end -- Animation Style + + -- Clear the temp non stickies table. + for x = 1, numNonStickies do + table.remove(activeNonStickies, 1); + end +end + + +-- ********************************************************************************** +-- This function makes sure stickies don't overlap. +-- ********************************************************************************** +function MikSBT.RepositionStickyAnimDisplayInfo(scrollArea) + -- Construct a table with the sticky animation display info in the same order the events were added. + for x = scrollArea.NextSticky, NUM_FONT_STRINGS do + local animDisplayInfo = scrollArea.AnimationDisplayArray[x]; + if (animDisplayInfo.IsActive) then + table.insert(activeStickies, animDisplayInfo); + end + end + + for x = scrollArea.FirstSticky, scrollArea.NextSticky-1 do + local animDisplayInfo = scrollArea.AnimationDisplayArray[x]; + if (animDisplayInfo.IsActive) then + table.insert(activeStickies, animDisplayInfo); + end + end + + -- Get the number of active stickies. + local numStickies = table.getn(activeStickies); + + + -- Animation style straight, left parabola, or right parabola. + if (scrollArea.DisplaySettings.AnimationStyle == ANIMATION_STYLE_STRAIGHT or + scrollArea.DisplaySettings.AnimationStyle == ANIMATION_STYLE_LEFT_PARABOLA or + scrollArea.DisplaySettings.AnimationStyle == ANIMATION_STYLE_RIGHT_PARABOLA) then + + -- Scrolling down. + if (scrollArea.DisplaySettings.ScrollDirection == SCROLL_DIRECTION_DOWN) then + + -- Check if there is more than 1 active sticky animation. + if (numStickies > 1) then + -- Get the middle active sticky. + local middleSticky = floor((numStickies + 1) / 2); + + -- Set the middle sticky to the center of the scroll area. + activeStickies[middleSticky].PositionY = scrollArea.DisplaySettings.ScrollHeight / 2; + + -- Loop backwards from the middle sticky. + for x = middleSticky - 1, 1, -1 do + activeStickies[x].PositionY = activeStickies[x+1].PositionY - activeStickies[x].FontSize - MIN_VERTICAL_SPACING; + end + + -- Loop forwards from the middle sticky. + for x = middleSticky + 1, numStickies do + activeStickies[x].PositionY = activeStickies[x-1].PositionY + activeStickies[x-1].FontSize + MIN_VERTICAL_SPACING; + end + end + + -- Scrolling up. + else + + -- Check if there is more than 1 active sticky animation. + if (numStickies > 1) then + -- Get the middle active sticky. + local middleSticky = ceil((numStickies + 1) / 2); + + -- Set the middle sticky to the center of the scroll area. + activeStickies[middleSticky].PositionY = scrollArea.DisplaySettings.ScrollHeight / 2; + + -- Loop backwards from the middle sticky. + for x = middleSticky - 1, 1, -1 do + activeStickies[x].PositionY = activeStickies[x+1].PositionY + activeStickies[x+1].FontSize + MIN_VERTICAL_SPACING; + end + + -- Loop forwards from the middle sticky. + for x = middleSticky + 1, numStickies do + activeStickies[x].PositionY = activeStickies[x-1].PositionY - activeStickies[x].FontSize - MIN_VERTICAL_SPACING; + end + end + + end -- Scrolling Direction + end -- Animation Style + + -- Clear the temp stickies table. + for x = 1, numStickies do + table.remove(activeStickies, 1); + end +end + + +-- ********************************************************************************** +-- Animates the passed animation display data. +-- ********************************************************************************** +function MikSBT.DoAnimation(animDisplayInfo, scrollArea) + + -- Get the current and elapsed times since the last update. + local currentTime = GetTime(); + local elapsedTime = currentTime - animDisplayInfo.LastUpdated; + + -- Check if it's a sticky or a crit and sticky crits are enabled. + if (animDisplayInfo.IsSticky or (animDisplayInfo.IsCrit and MikSBT.CurrentProfile.UseStickyCrits)) then + -- Move the sticky in case it was repositioned. + animDisplayInfo.FontObject:SetPoint(animDisplayInfo.AnchorPoint, animDisplayInfo.PositionX, animDisplayInfo.PositionY); + + if (elapsedTime <= STICKY_FADE_IN_TIME) then + local textDelta = animDisplayInfo.FontSize * (1 - (elapsedTime / STICKY_FADE_IN_TIME)); + animDisplayInfo.FontObject:SetTextHeight(animDisplayInfo.FontSize + textDelta); + animDisplayInfo.FontObject:SetAlpha(1); + return; + elseif (elapsedTime <= (STICKY_DISPLAY_TIME + STICKY_FADE_IN_TIME)) then + animDisplayInfo.FontObject:SetTextHeight(animDisplayInfo.FontSize); + return; + elseif (elapsedTime <= (STICKY_DISPLAY_TIME + STICKY_FADE_IN_TIME + STICKY_FADE_OUT_TIME)) then + local alpha = 1 - ((elapsedTime - STICKY_DISPLAY_TIME - STICKY_FADE_IN_TIME) / STICKY_FADE_OUT_TIME); + animDisplayInfo.FontObject:SetAlpha(alpha); + return; + end + + -- Deactivate the animation. + animDisplayInfo.FontObject:SetAlpha(0); + animDisplayInfo.IsActive = false; + + return; + end + + + -- Check if it's time to update. + if (elapsedTime > ANIMATION_SPEED) then + -- Scroll the text and set its alpha appropriately. + local animationComplete = animDisplayInfo.ScrollFunction(animDisplayInfo, scrollArea); + + + -- Check if the animation is complete. + if (animationComplete) then + -- Set the font object's alpha. + animDisplayInfo.FontObject:SetAlpha(0); + + -- Deactive the animation. + animDisplayInfo.IsActive = false; + else + -- Move the font object and set its alpha. + animDisplayInfo.FontObject:SetPoint(animDisplayInfo.AnchorPoint, animDisplayInfo.PositionX, animDisplayInfo.PositionY); + animDisplayInfo.FontObject:SetAlpha(animDisplayInfo.Alpha); + end + + -- Set the last update to the current time. + animDisplayInfo.LastUpdated = currentTime; + end -- Time for update. +end + + +-- ********************************************************************************** +-- Moves the passed animation display info upward and fades the alpha correctly. +-- Returns true when the animation is complete. +-- ********************************************************************************** +function MikSBT.ScrollUp(animDisplayInfo, scrollArea) + -- Calculate the animation midpoint. + local animationMidPoint = scrollArea.DisplaySettings.ScrollHeight / 2; + + -- Increment the Y position by the step. + animDisplayInfo.PositionY = animDisplayInfo.PositionY + MikSBT.CurrentProfile.AnimationStep; + + -- Start fading out the text on the upper half. + if (animDisplayInfo.PositionY >= animationMidPoint) then + animDisplayInfo.Alpha = 1 - ((animDisplayInfo.PositionY - animationMidPoint) / animationMidPoint); + else + animDisplayInfo.Alpha = 1; + end + + -- Check if the animation is complete. + if (animDisplayInfo.PositionY >= scrollArea.DisplaySettings.ScrollHeight) then + -- Return true to indicated the animation is complete. + return true; + end + + -- Return false to indicate the animation is NOT complete. + return false; +end + + +-- ********************************************************************************** +-- Moves the passed animation display info downward and fades the alpha correctly. +-- Returns true when the animation is complete. +-- ********************************************************************************** +function MikSBT.ScrollDown(animDisplayInfo, scrollArea) + -- Calculate the animation midpoint. + local animationMidPoint = scrollArea.DisplaySettings.ScrollHeight / 2; + + -- Decrement the Y position by the step. + animDisplayInfo.PositionY = animDisplayInfo.PositionY - MikSBT.CurrentProfile.AnimationStep; + + -- Start fading out the text on the bottom half. + if (animDisplayInfo.PositionY < animationMidPoint) then + animDisplayInfo.Alpha = 1 - ((animationMidPoint - animDisplayInfo.PositionY) / animationMidPoint); + else + animDisplayInfo.Alpha = 1; + end + + -- Check if the animation is complete. + if (animDisplayInfo.PositionY <= 0) then + -- Return true to indicated the animation is complete. + return true; + end + + -- Return false to indicate the animation is NOT complete. + return false; +end + + +-- ********************************************************************************** +-- Moves the passed animation display info straight up. Returns true when the +-- animation is complete. +-- ********************************************************************************** +function MikSBT.ScrollStraightUp(animDisplayInfo, scrollArea) + -- Returns the result of the scroll up function. + return MikSBT.ScrollUp(animDisplayInfo, scrollArea); +end + + +-- ********************************************************************************** +-- Moves the passed animation display info straight down. Returns true when the +-- animation is complete. +-- ********************************************************************************** +function MikSBT.ScrollStraightDown(animDisplayInfo, scrollArea) + -- Returns the result of the scroll down function. + return MikSBT.ScrollDown(animDisplayInfo, scrollArea); +end + + +-- ********************************************************************************** +-- Moves the passed animation display info in a left parabolic shape going upwards. +-- Returns true when the animation is complete. +-- ********************************************************************************** +function MikSBT.ScrollLeftParabolaUp(animDisplayInfo, scrollArea) + -- Scroll the animation display info straight up and set the alpha correctly. + local animationComplete = MikSBT.ScrollUp(animDisplayInfo, scrollArea); + + -- Calculate the animation midpoint. + local animationMidPoint = scrollArea.DisplaySettings.ScrollHeight / 2; + + -- Calculate the new x position based on equation of a parabola. + -- Equation of a parabola at vertex 0,0: x = y^2 / 4a + local parabolaMaxX = ceil((animationMidPoint * animationMidPoint) / (4 * animationMidPoint)); + local parabolaY = animDisplayInfo.PositionY - animationMidPoint; + local newX = parabolaMaxX - ceil((parabolaY * parabolaY) / (4 * animationMidPoint)); + + -- Set the new x position. + animDisplayInfo.PositionX = newX * -1; + + -- Return whether or not the animation is complete. + return animationComplete; +end + + +-- ********************************************************************************** +-- Moves the passed animation display info in a left parabolic shape going downwards. +-- Returns true when the animation is complete. +-- ********************************************************************************** +function MikSBT.ScrollLeftParabolaDown(animDisplayInfo, scrollArea) + -- Scroll the animation display info straight up and set the alpha correctly. + local animationComplete = MikSBT.ScrollDown(animDisplayInfo, scrollArea); + + -- Calculate the animation midpoint. + local animationMidPoint = scrollArea.DisplaySettings.ScrollHeight / 2; + + -- Calculate the new x position based on equation of a parabola. + -- Equation of a parabola at vertex 0,0: x = y^2 / 4a + local parabolaMaxX = ceil((animationMidPoint * animationMidPoint) / (4 * animationMidPoint)); + local parabolaY = animDisplayInfo.PositionY - animationMidPoint; + local newX = parabolaMaxX - ceil((parabolaY * parabolaY) / (4 * animationMidPoint)); + + -- Set the new x position. + animDisplayInfo.PositionX = newX * -1; + + -- Return whether or not the animation is complete. + return animationComplete; +end + + +-- ********************************************************************************** +-- Moves the passed animation display info in a right parabolic shape going upwards. +-- Returns true when the animation is complete. +-- ********************************************************************************** +function MikSBT.ScrollRightParabolaUp(animDisplayInfo, scrollArea) + -- Scroll the animation display info straight up and set the alpha correctly. + local animationComplete = MikSBT.ScrollUp(animDisplayInfo, scrollArea); + + -- Calculate the animation midpoint. + local animationMidPoint = scrollArea.DisplaySettings.ScrollHeight / 2; + + -- Calculate the new x position based on equation of a parabola. + -- Equation of a parabola at vertex 0,0: x = y^2 / 4a + local parabolaMaxX = ceil((animationMidPoint * animationMidPoint) / (4 * animationMidPoint)); + local parabolaY = animDisplayInfo.PositionY - animationMidPoint; + local newX = parabolaMaxX - ceil((parabolaY * parabolaY) / (4 * animationMidPoint)); + + -- Set the new x position. + animDisplayInfo.PositionX = newX; + + -- Return whether or not the animation is complete. + return animationComplete; +end + + +-- ********************************************************************************** +-- Moves the passed animation display info in a right parabolic shape going downwards. +-- Returns true when the animation is complete. +-- ********************************************************************************** +function MikSBT.ScrollRightParabolaDown(animDisplayInfo, scrollArea) + -- Scroll the animation display info straight up and set the alpha correctly. + local animationComplete = MikSBT.ScrollDown(animDisplayInfo, scrollArea); + + -- Calculate the animation midpoint. + local animationMidPoint = scrollArea.DisplaySettings.ScrollHeight / 2; + + -- Calculate the new x position based on equation of a parabola. + -- Equation of a parabola at vertex 0,0: x = y^2 / 4a + local parabolaMaxX = ceil((animationMidPoint * animationMidPoint) / (4 * animationMidPoint)); + local parabolaY = animDisplayInfo.PositionY - animationMidPoint; + local newX = parabolaMaxX - ceil((parabolaY * parabolaY) / (4 * animationMidPoint)); + + -- Set the new x position. + animDisplayInfo.PositionX = newX; + + -- Return whether or not the animation is complete. + return animationComplete; +end + + +------------------------------------------------------------------------------------- +-- Command handler functions. +------------------------------------------------------------------------------------- + +-- ********************************************************************************** +-- Returns the current and remaining parameters from the passed string. +-- ********************************************************************************** +function MikSBT.GetNextParameter(paramString) + local remainingParams; + local currentParam = paramString; + + -- Look for a space. + local idx = string.find(paramString, " "); + + if (idx) then + -- Get the current and remaing parameters. + currentParam = string.sub(paramString, 1, idx-1); + remainingParams = string.sub(paramString, idx+1); + end + + -- Return the current parameter and the remaining ones. + return currentParam, remainingParams; +end + + +-- ********************************************************************************** +-- Called to handle commands. +-- ********************************************************************************** +function MikSBT.CommandHandler(params) + -- Get the parameter. + local currentParam; + local remainingParams; + currentParam, remainingParams = MikSBT.GetNextParameter(params); + + -- Flag for whether or not to show usage info. + local showUsage = true; + + -- Make sure there is a current parameter and lower case it. + if (currentParam) then + currentParam = string.lower(currentParam); + end + + -- Look for the recognized parameters. + if (currentParam == "") then + -- Check if the load on demand options are not loaded. + if (not IsAddOnLoaded(MikSBT.MOD_NAME .. "Options")) then + -- Load the on demand options. + UIParentLoadAddOn(MikSBT.MOD_NAME .. "Options"); + end + + -- Make sure the on demand options actually loaded. + if (IsAddOnLoaded(MikSBT.MOD_NAME .. "Options")) then + -- Make sure the scroll area mover control frame is not shown. + if (not MSBTScrollAreaMoverControlFrame:IsShown()) then + -- Show the options interface. + MSBTFrameOptions:Show(); + end + end + + -- Don't show the usage info. + showUsage = false; + + elseif (currentParam == MikSBT.COMMAND_RESET) then + -- Reset the current profile. + MikSBT.ResetProfile(MikSBT_Save.CurrentProfile, true); + + -- Don't show the usage info. + showUsage = false; + + elseif (currentParam == MikSBT.COMMAND_DISABLE) then + -- Set the user disabled option. + MikSBT.SetOptionUserDisabled(true); + + -- Output an informative message. + MikSBT.Print(MikSBT.MSG_DISABLE, 1,1,1); + + -- Don't show the usage info. + showUsage = false; + + elseif (currentParam == MikSBT.COMMAND_ENABLE) then + -- Unset the user disabled option. + MikSBT.SetOptionUserDisabled(false); + + -- Output an informative message. + MikSBT.Print(MikSBT.MSG_ENABLE, 1,1,1); + + -- Don't show the usage info. + showUsage = false; + + elseif (currentParam == MikSBT.COMMAND_SHOWVER) then + -- Output the current version number. + MikSBT.Print(MikSBT.VERSION_STRING, 1,1,1); + + -- Don't show the usage info. + showUsage = false; + + elseif (currentParam == MikSBT.COMMAND_STATS) then + -- Print out stats about the event recycler. + eventsRecycler:PrintStats(); + + -- Don't show the usage info. + showUsage = false; + + elseif (currentParam == MikSBT.COMMAND_SEARCH) then + -- Check if there is any filter text + if (remainingParams and remainingParams ~= "") then + -- Turn on event searching mode. + MikCEH.EnableEventSearching(remainingParams); + MikSBT.Print(MikSBT.MSG_SEARCH_ENABLE .. remainingParams, 1, 1, 1); + else + -- Turn off event searching mode. + MikCEH.DisableEventSearching(); + MikSBT.Print(MikSBT.MSG_SEARCH_DISABLE, 1, 1, 1); + end + + -- Don't show the usage info. + showUsage = false; + + elseif (currentParam == MikSBT.COMMAND_DEBUG) then + -- Toggle the debug mode option. + debugMode = not debugMode; + + -- Check if debug mode was enabled or disabled and output the appropriate message. + if (debugMode) then + MikSBT.Print(MikSBT.MSG_DEBUG_ENABLE, 1,1,1); + else + MikSBT.Print(MikSBT.MSG_DEBUG_DISABLE, 1,1,1); + end + + -- Don't show the usage info. + showUsage = false; + + end + + -- Check if the usage information should be shown. + if (showUsage) then + MikSBT.PrintUsage(); + end +end + + +-- ********************************************************************************** +-- Prints out the usage information. +-- ********************************************************************************** +function MikSBT.PrintUsage() + -- Loop through all of the entries in the command usage list. + for _, msg in MikSBT.COMMAND_USAGE do + MikSBT.Print(msg, 1, 1, 1); + end +end + + + +------------------------------------------------------------------------------------- +-- Public Access functions. +------------------------------------------------------------------------------------- + +-- ********************************************************************************** +-- Displays the passed message in the passed scroll area with the passed parameters. +-- This function is for easy displaying of messages from external sources. +-- ********************************************************************************** +function MikSBT.DisplayMessage(message, displayType, isSticky, colorR, colorG, colorB, fontSize, fontIndex, outlineIndex) + -- Check if no message was passed and do nothing. + if (message == nil) then + return; + end + + -- Check if the passed display type is invalid.. + if (displayType ~= MikSBT.DISPLAYTYPE_INCOMING and displayType ~= MikSBT.DISPLAYTYPE_OUTGOING and + displayType ~= MikSBT.DISPLAYTYPE_NOTIFICATION) then + + -- Set the display type to the default. + displayType = MikSBT.DISPLAYTYPE_NOTIFICATION; + end + + -- Get the correct scroll area for the event. + local scrollArea; + if (displayType == MikSBT.DISPLAYTYPE_INCOMING) then + scrollArea = scrollAreas.Incoming; + elseif (displayType == MikSBT.DISPLAYTYPE_OUTGOING) then + scrollArea = scrollAreas.Outgoing; + elseif (displayType == MikSBT.DISPLAYTYPE_NOTIFICATION) then + scrollArea = scrollAreas.Notification; + end + + -- Check if the scroll area is hiding events. + if (not scrollArea.DisplaySettings.Show) then + return; + end + + -- Check if the red color value is invalid. + if (colorR == nil or colorR < 0 or colorR > 255) then + -- Set the red color value to the default. + colorR = 255; + end + + -- Check if the green color value is invalid. + if (colorG == nil or colorG < 0 or colorG > 255) then + -- Set the green color value to the default. + colorG = 255; + end + + -- Check if the blue color value is invalid. + if (colorB == nil or colorB < 0 or colorB > 255) then + -- Set the blue color value to the default. + colorB = 255; + end + + -- Check if the font size is invalid. + if (fontSize == nil or fontSize < 12 or fontSize > 32) then + fontSize = MikSBT.GetFontSize(scrollArea, nil, false); + end + + local fontPath; + -- Check if the font index in invalid. + if (fontIndex == nil or MikSBT.AVAILABLE_FONTS[fontIndex] == nil) then + fontPath = MikSBT.GetFontPath(scrollArea, nil, false); + -- Font index is valid. + else + fontPath = MikSBT.AVAILABLE_FONTS[fontIndex].Path; + end + + local fontOutline; + -- Check if the outline index in invalid. + if (outlineIndex == nil or MikSBT.AVAILABLE_OUTLINES[outlineIndex] == nil) then + fontOutline = MikSBT.GetFontOutline(scrollArea, nil, false); + else + fontOutline = MikSBT.AVAILABLE_OUTLINES[outlineIndex].Style; + end + + + -- Get a recycled table from the events recycler object. + local animationEvent = eventsRecycler:AcquireTable(); + + -- Populate the animation event data. + animationEvent.ScrollArea = scrollArea; + animationEvent.IsCrit = false; + animationEvent.IsSticky = isSticky; + animationEvent.Text = message; + animationEvent.FontSize = fontSize; + animationEvent.FontPath = fontPath; + animationEvent.FontOutline = fontOutline; + animationEvent.ColorR = colorR; + animationEvent.ColorG = colorG; + animationEvent.ColorB = colorB; + + + -- Add the event to the animation system. + MikSBT.AddAnimation(animationEvent); +end \ No newline at end of file diff --git a/MikScrollingBattleText/MikScrollingBattleText.toc b/MikScrollingBattleText/MikScrollingBattleText.toc new file mode 100644 index 0000000..878bc23 --- /dev/null +++ b/MikScrollingBattleText/MikScrollingBattleText.toc @@ -0,0 +1,11 @@ +## Interface: 11200 +## Version: 3.01 +## Title: Mik's Scrolling Battle Text +## Notes: Scrolls battle information around the character model. +## SavedVariables: MikSBT_Save +localization.lua +MikTableRecyclerObject.lua +MikCombatEventHelper.lua +MikScrollingBattleText.lua +MikCombatEventHelper.xml +MikScrollingBattleText.xml \ No newline at end of file diff --git a/MikScrollingBattleText/MikScrollingBattleText.xml b/MikScrollingBattleText/MikScrollingBattleText.xml new file mode 100644 index 0000000..c6b75ac --- /dev/null +++ b/MikScrollingBattleText/MikScrollingBattleText.xml @@ -0,0 +1,346 @@ + + + + + + MikSBT.OnEvent(); + MikSBT.OnLoad(); + MikSBT.OnUpdate(); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MikSBT.OnUpdateAnimationFrame(this); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MikSBT.OnUpdateAnimationFrame(this); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MikSBT.OnUpdateAnimationFrame(this); + + + \ No newline at end of file diff --git a/MikScrollingBattleText/MikTableRecyclerObject.lua b/MikScrollingBattleText/MikTableRecyclerObject.lua new file mode 100644 index 0000000..9c35d6b --- /dev/null +++ b/MikScrollingBattleText/MikTableRecyclerObject.lua @@ -0,0 +1,173 @@ +------------------------------------------------------------------------------------- +-- Title: Mik's Table Recyler Object +-- Author: Mik +-- Credits: +-- Thanks to tekkub, the author of compostLib. I adapted much of his code for +-- this object. +------------------------------------------------------------------------------------- + +-- Create "namespace." +MikTRO = {}; + +-- Set the __index property to the recycler object namespace so +-- when a new recycler object sets it metatable to the namespace +-- the recycler object inherits the functions in the namespace. +MikTRO.__index = MikTRO; + + +-- ********************************************************************************** +-- Creates a recycler object. +-- ********************************************************************************** +function MikTRO:NewRecyclerObject(maxEntries) + -- Create a table to use. + recyclerObject = {}; + + -- Create a table to hold the cache entries and set its max permanent size. + recyclerObject.PrimaryCache = {}; + recyclerObject.MaxEntries = maxEntries; + + -- Create some variables to hold stats. + recyclerObject.NumNew = 0; + recyclerObject.NumRecycled = 0; + recyclerObject.NumErased = 0; + recyclerObject.NumReclaimed = 0; + recyclerObject.AmountMemFreed = 0; + + + -- Create a table to hold overflow entries. If more tables are reclaimed + -- than the size of the max primary cache can hold, they will be reclaimed + -- into the overflow cache which is a weak table. This allows for spikes + -- in cache usage to still be optimized while not preventing garbage + -- collection on the extra data once there are no other references to them. + recyclerObject.OverflowCache = {}; + setmetatable(recyclerObject.OverflowCache, {__mode = "v"}); + + + -- Set the meta table for the cache object to the table recycler + -- obect's namespace so the cache object inherits the functions of + -- table recycler object. + setmetatable(recyclerObject, self); + + -- Return the recycler object. + return recyclerObject; +end + + + +-- ********************************************************************************** +-- Removes a table from the cache and returns it. If there are no tables available +-- in the cache a new one is returned. +-- ********************************************************************************** +function MikTRO:AcquireTable() + -- Check if there are any tables available in the primary cache and if so + -- return one. + if (table.getn(self.PrimaryCache) > 0) then + -- Increment the number of recycled tables. + self.NumRecycled = self.NumRecycled + 1; + + return table.remove(self.PrimaryCache); + + -- Check if there are any tables available in the overflow cache and if so + -- return one. + elseif self:TablesInOverflow() then + -- Increment the number of recycled tables. + self.NumRecycled = self.NumRecycled + 1; + + -- Loop through the tables in the overflow and return one. + for i in pairs(self.OverflowCache) do + return table.remove(self.OverflowCache, i); + end + + -- No tables available so return a new one. + else + -- Increment the number of new tables created. + self.NumNew = self.NumNew + 1; + return {}; + end +end + + +-- ********************************************************************************** +-- Reclaims a table into the cache. +-- ********************************************************************************** +function MikTRO:ReclaimTable(t) + -- Check if the passed value isn't valid. + if (type(t) ~= "table") then + return; + end + + -- Erase the passed table. + self:EraseTable(t); + + -- Check if the primary cache is already full. + if (table.getn(self.PrimaryCache) >= self.MaxEntries) then + -- Insert the table into the overflow cache. + table.insert(self.OverflowCache, t); + else + -- Insert the table into the primary cache. + table.insert(self.PrimaryCache, t); + end + + -- Increment the number of reclaimed tables. + self.NumReclaimed = self.NumReclaimed + 1; +end + + +-- ********************************************************************************** +-- Erases the passed table. Subtables are NOT erased. +-- ********************************************************************************** +function MikTRO:EraseTable(t) + -- Check if the passed value isn't valid. + if (type(t) ~= "table") then + return; + end + + -- Get the amount of memory used before the clear. + local currentMem = gcinfo(); + + -- 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); + + -- Increment the amount of memory freed. + self.AmountMemFreed = self.AmountMemFreed + math.abs(gcinfo() - currentMem); + + -- Incremnt the number of tables erased. + self.NumErased = self.NumErased + 1; +end + + +-- ********************************************************************************** +-- Prints stats. +-- ********************************************************************************** +function MikTRO:PrintStats() + local overflowSize = 0; + for i in pairs(self.OverflowCache) do + overflowSize = overflowSize + 1; + end + + DEFAULT_CHAT_FRAME:AddMessage(string.format( + "|cff00ff00New Tables: %d|r |cffffff00Recycled Tables: %d|r |cff00ffffCached Tables: %d|r |cffff0000Overflow Tables: %d|r |cff888888Erased Tables: %d|r |cffff00ffMemory Saved: %d KiB|r |cffff0088Tables Lost to GC: %d", + self.NumNew, + self.NumRecycled, + table.getn(self.PrimaryCache), + overflowSize, + self.NumErased, + self.AmountMemFreed + ((32/1024) * self.NumRecycled), + self.NumReclaimed - self.NumRecycled - table.getn(self.PrimaryCache))); +end + + +-- ********************************************************************************** +-- Checks if there are any tables in the overflow cache. +-- ********************************************************************************** +function MikTRO:TablesInOverflow() + -- Loop through all items in the overflow cache. + for i in pairs(self.OverflowCache) do + return true; + end +end \ No newline at end of file diff --git a/MikScrollingBattleText/localization.lua b/MikScrollingBattleText/localization.lua new file mode 100644 index 0000000..f3f5b70 --- /dev/null +++ b/MikScrollingBattleText/localization.lua @@ -0,0 +1,1030 @@ +------------------------------------------------------------------------------------- +-- Title: Mik's Scrolling Battle Text +-- Author: Mik +------------------------------------------------------------------------------------- + +-- Create "namespace." +MikSBT = {}; + +------------------------------------------------------------------------------- +-- Mod Constants +------------------------------------------------------------------------------- + +MikSBT.MOD_NAME = "MikScrollingBattleText" +MikSBT.VERSION_NUMBER = 3.01; +MikSBT.VERSION_STRING = "v3.01"; +MikSBT.WINDOW_TITLE = "Mik's Scrolling Battle Text " .. MikSBT.VERSION_STRING; + +MikSBT.COMMAND = "/msbt"; + + +------------------------------------------------------------------------------- +-- English (Default) +------------------------------------------------------------------------------- + +------------------------------ +-- Commands +------------------------------ +MikSBT.COMMAND_RESET = "reset"; +MikSBT.COMMAND_DISABLE = "disable"; +MikSBT.COMMAND_ENABLE = "enable"; +MikSBT.COMMAND_DISPLAY = "display"; +MikSBT.COMMAND_SHOWVER = "version"; +MikSBT.COMMAND_STATS = "stats"; +MikSBT.COMMAND_SEARCH = "search"; +MikSBT.COMMAND_DEBUG = "debug"; +MikSBT.COMMAND_HELP = "help"; + +MikSBT.COMMAND_USAGE = { + "Usage: " .. MikSBT.COMMAND .. " [params]", + " Commands:", + " " .. MikSBT.COMMAND_RESET .. " - Reset the current profile to the default settings.", + " " .. MikSBT.COMMAND_DISABLE .. " - Disables the mod.", + " " .. MikSBT.COMMAND_ENABLE .. " - Enables the mod.", + " " .. MikSBT.COMMAND_SHOWVER .. " - Shows the current version.", + " " .. MikSBT.COMMAND_STATS .. " - Reports stats about table recycling.", + " " .. MikSBT.COMMAND_SEARCH .. " filter - Sets a filter for searching event types.", + " " .. MikSBT.COMMAND_DEBUG .. " - Toggles debug mode.", + " " .. MikSBT.COMMAND_HELP .. " - Show the command usage.", +}; + + +------------------------------ +-- Output messages +------------------------------ + +MikSBT.MSG_DEBUG_ENABLE = "Debug mode has been enabled."; +MikSBT.MSG_DEBUG_DISABLE = "Debug mode has been disabled."; +MikSBT.MSG_SEARCH_ENABLE = "Event search mode has been enabled. Searching for: "; +MikSBT.MSG_SEARCH_DISABLE = "Event search mode has been disabled."; +MikSBT.MSG_DISABLE = "The mod is now disabled."; +MikSBT.MSG_ENABLE = "The mod is now enabled."; +MikSBT.MSG_HITS = "Hits"; +MikSBT.MSG_CRIT = "Crit"; +MikSBT.MSG_CRITS = "Crits"; +MikSBT.MSG_MULTIPLE_TARGETS = "Multiple"; +MikSBT.MSG_VULERNABLE_TRAILER = " (%d vulnerability)"; +MikSBT.MSG_OVERHEAL_TRAILER = " <%d>"; +MikSBT.MSG_PROFILE_RESET = "Profile Reset"; +MikSBT.MSG_ENVIRONMENTAL_DROWNING = "Drowning"; +MikSBT.MSG_ENVIRONMENTAL_FALLING = "Falling"; +MikSBT.MSG_ENVIRONMENTAL_FATIGUE = "Fatigue"; +MikSBT.MSG_ENVIRONMENTAL_FIRE = "Fire"; +MikSBT.MSG_ENVIRONMENTAL_LAVA = "Lava"; +MikSBT.MSG_ENVIRONMENTAL_SLIME = "Slime"; + + + +------------------------------ +-- Font info +------------------------------ + +-- Holds the available fonts. +MikSBT.AVAILABLE_FONTS = { + [1] = {Name="Adventure", Path="Interface\\Addons\\MikScrollingBattleText\\Fonts\\adventure.ttf"}, + [2] = {Name="Backsplatter", Path="Interface\\Addons\\MikScrollingBattleText\\Fonts\\backsplatter.ttf"}, + [3] = {Name="Budhand", Path="Interface\\Addons\\MikScrollingBattleText\\Fonts\\budhand.ttf"}, + [4] = {Name="Comic", Path="Interface\\Addons\\MikScrollingBattleText\\Fonts\\comic.ttf"}, + [5] = {Name="Creeper", Path="Interface\\Addons\\MikScrollingBattleText\\Fonts\\creeper.ttf"}, + [6] = {Name="Friz", Path="Fonts\\FRIZQT__.TTF"}, + [7] = {Name="Porky", Path="Interface\\Addons\\MikScrollingBattleText\\Fonts\\porky.ttf"}, + [8] = {Name="Signature", Path="Interface\\Addons\\MikScrollingBattleText\\Fonts\\signature.ttf"}, +}; + +-- Holds the available font outlines. +MikSBT.AVAILABLE_OUTLINES = { + [1] = {Name="None", Style=""}, + [2] = {Name="Thin", Style="OUTLINE"}, + [3] = {Name="Thick", Style="THICKOUTLINE"}, +}; + +-- Holds the available text aligns. +MikSBT.AVAILABLE_TEXT_ALIGNS = { + [1] = {Name="Left", AnchorPoint="BOTTOMLEFT"}, + [2] = {Name="Center", AnchorPoint="BOTTOM"}, + [3] = {Name="Right", AnchorPoint="BOTTOMRIGHT"}, +}; + + +------------------------------ +-- Animation info +------------------------------ + +MikSBT.AVAILABLE_SCROLL_DIRECTIONS = { + [1] = {Name="Up"}, + [2] = {Name="Down"}, +} + +-- Holds the available animation styles. +MikSBT.AVAILABLE_ANIMATION_STYLES = { + [1] = {Name="Straight", AllowedScrollDirections={1,2}}, + [2] = {Name="Left Parabola", AllowedScrollDirections={1,2}}, + [3] = {Name="Right Parabola", AllowedScrollDirections={1,2}}, +}; + + +------------------------------ +-- Trigger info +------------------------------ + +-- Holds the available trigger types. +MikSBT.AVAILABLE_TRIGGER_TYPES = { + [1] = {Name="Self Health"}, + [2] = {Name="Self Mana"}, + [3] = {Name="Pet Health"}, + [4] = {Name="Enemy Target Health"}, + [5] = {Name="Friendly Target Health"}, + [6] = {Name="Search Pattern"}, +}; + + +------------------------------ +-- Defaults +------------------------------ +MikSBT.DEFAULT_PROFILE_NAME = "Default"; + +-- %a = amount of the attack, heal, gain, loss, etc. +-- %n = name of enemy/player +-- %s = name of the spell, ability, buff, debuff, power type, etc. +-- %t = damage type +MikSBT.DEFAULT_CONFIG = { + CreationVersion = MikSBT.VERSION_NUMBER, + ShowPartialEffects = true, + ShowOverheals = true, + ShowGameDamage = false, + UseStickyCrits = true, + AnimationStep = 2, + MasterFontSettings = { + Normal = {FontIndex=1, OutlineIndex=3, FontSize=18}, + Crit = {FontIndex=1, OutlineIndex=3, FontSize=26}, + }, + DisplaySettings = { + Incoming = { + Show = true, + FrameOffsets = {x=-60, y=-160}, + AnimationStyle = 2, + ScrollDirection = 2, + ScrollHeight = 260, + FontSettings = { + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + Crit = {FontIndex=0, OutlineIndex=0, FontSize=0}, + TextAlignIndex = 3, + }, + }, + Outgoing = { + Show = true, + FrameOffsets = {x=60, y=-160}, + AnimationStyle = 3, + ScrollDirection = 2, + ScrollHeight = 260, + FontSettings = { + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + Crit = {FontIndex=0, OutlineIndex=0, FontSize=0}, + TextAlignIndex = 1, + }, + }, + Notification = { + Show = true, + FrameOffsets = {x=0, y=100}, + AnimationStyle = 1, + ScrollDirection = 1, + ScrollHeight = 150, + FontSettings = { + Normal = {FontIndex=0, OutlineIndex=0, FontSize = 0}, + Crit = {FontIndex=0, OutlineIndex=0, FontSize = 0}, + TextAlignIndex = 2, + }, + }, + }, + EventSettings = { + MSBT_EVENTTYPE_INCOMING_DAMAGE = { + Show = true, + Message = "(%n) -%a", + FontSettings = { + Color = {r=1, g=0, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + Crit = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_INCOMING_MISS = { + Show = true, + Message = "Miss!", + FontSettings = { + Color = {r=0, g=0, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_INCOMING_DODGE = { + Show = true, + Message = "Dodge!", + FontSettings = { + Color = {r=0, g=0, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_INCOMING_PARRY = { + Show = true, + Message = "Parry!", + FontSettings = { + Color = {r=0, g=0, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_INCOMING_BLOCK = { + Show = true, + Message = "Block!", + FontSettings = { + Color = {r=0, g=0, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_INCOMING_ABSORB = { + Show = true, + Message = "Absorb!", + FontSettings = { + Color = {r=1, g=1, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_INCOMING_IMMUNE = { + Show = true, + Message = "Immune!", + FontSettings = { + Color = {r=1, g=1, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_INCOMING_SPELL_DAMAGE = { + Show = true, + Message = "(%s) -%a", + FontSettings = { + Color = {r=0.502, g=0, b=0.502}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + Crit = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_INCOMING_SPELL_DOT = { + Show = true, + Message = "(%s) -%a", + FontSettings = { + Color = {r=0.502, g=0, b=0.502}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_INCOMING_SPELL_MISS = { + Show = true, + Message = "(%s) Miss!", + FontSettings = { + Color = {r=0, g=0, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_INCOMING_SPELL_DODGE = { + Show = true, + Message = "(%s) Dodge!", + FontSettings = { + Color = {r=0, g=0, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_INCOMING_SPELL_PARRY = { + Show = true, + Message = "(%s) Parry!", + FontSettings = { + Color = {r=0, g=0, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_INCOMING_SPELL_BLOCK = { + Show = true, + Message = "(%s) Block!", + FontSettings = { + Color = {r=0, g=0, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_INCOMING_SPELL_RESIST = { + Show = true, + Message = "(%s) Resist!", + FontSettings = { + Color = {r=0.502, g=0, b=0.502}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_INCOMING_SPELL_ABSORB = { + Show = true, + Message = "(%s) Absorb!", + FontSettings = { + Color = {r=1, g=1, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_INCOMING_SPELL_IMMUNE = { + Show = true, + Message = "(%s) Immune!", + FontSettings = { + Color = {r=1, g=1, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_INCOMING_SPELL_REFLECT = { + Show = true, + Message = "(%s) Reflect!", + FontSettings = { + Color = {r=0.502, g=0, b=0.502}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + Crit = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_INCOMING_HEAL = { + Show = true, + Message = "(%s - %n) +%a", + FontSettings = { + Color = {r=0, g=1, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + Crit = {FontIndex=0, OutlineIndex=0, FontSize=0}, + } + }, + MSBT_EVENTTYPE_INCOMING_HOT = { + Show = true, + Message = "(%s - %n) +%a", + FontSettings = { + Color = {r=0, g=1, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + } + }, + MSBT_EVENTTYPE_INCOMING_ENVIRONMENTAL = { + Show = true, + Message = "-%a %s", + FontSettings = { + Color = {r=1, g=0, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + + + MSBT_EVENTTYPE_OUTGOING_DAMAGE = { + Show = true, + Message = "%a", + FontSettings = { + Color = {r=1, g=1, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + Crit = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_MISS = { + Show = true, + Message = "Miss!", + FontSettings = { + Color = {r=1, g=1, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_DODGE = { + Show = true, + Message = "Dodge!", + FontSettings = { + Color = {r=1, g=1, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_PARRY = { + Show = true, + Message = "Parry!", + FontSettings = { + Color = {r=1, g=1, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_BLOCK = { + Show = true, + Message = "Block!", + FontSettings = { + Color = {r=1, g=1, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_ABSORB = { + Show = true, + Message = "Absorb!", + FontSettings = { + Color = {r=1, g=1, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_IMMUNE = { + Show = true, + Message = "Immune!", + FontSettings = { + Color = {r=1, g=1, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_EVADE = { + Show = true, + Message = "Evade!", + FontSettings = { + Color = {r=1, g=0.502, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=22}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_SPELL_DAMAGE = { + Show = true, + Message = "%a (%s)", + FontSettings = { + Color = {r=1, g=1, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + Crit = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_SPELL_DOT = { + Show = true, + Message = "%a (%s)", + FontSettings = { + Color = {r=1, g=1, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_SPELL_MISS = { + Show = true, + Message = "Miss! (%s)", + FontSettings = { + Color = {r=1, g=1, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_SPELL_DODGE = { + Show = true, + Message = "Dodge! (%s)", + FontSettings = { + Color = {r=1, g=1, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_SPELL_PARRY = { + Show = true, + Message = "Parry! (%s)", + FontSettings = { + Color = {r=1, g=1, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_SPELL_BLOCK = { + Show = true, + Message = "Block! (%s)", + FontSettings = { + Color = {r=1, g=1, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_SPELL_RESIST = { + Show = true, + Message = "Resist! (%s)", + FontSettings = { + Color = {r=0.502, g=0.502, b=0.698}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_SPELL_ABSORB = { + Show = true, + Message = "Absorb! (%s)", + FontSettings = { + Color = {r=1, g=1, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_SPELL_IMMUNE = { + Show = true, + Message = "Immune! (%s)", + FontSettings = { + Color = {r=1, g=1, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_SPELL_REFLECT = { + Show = true, + Message = "Reflect! (%s)", + FontSettings = { + Color = {r=1, g=1, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + Crit = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_SPELL_EVADE = { + Show = true, + Message = "Evade! (%s)", + FontSettings = { + Color = {r=1, g=0.502, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=22}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_HEAL = { + Show = true, + Message = "+%a (%s - %n)", + FontSettings = { + Color = {r=0, g=1, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + Crit = {FontIndex=0, OutlineIndex=0, FontSize=22}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_HOT = { + Show = true, + Message = "+%a (%s - %n)", + FontSettings = { + Color = {r=0, g=1, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + + + MSBT_EVENTTYPE_OUTGOING_PET_DAMAGE = { + Show = true, + Message = "Pet %a", + FontSettings = { + Color = {r=1, g=0.502, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + Crit = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + + }, + MSBT_EVENTTYPE_OUTGOING_PET_MISS = { + Show = true, + Message = "Pet Miss!", + FontSettings = { + Color = {r=1, g=0.502, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_PET_DODGE = { + Show = true, + Message = "Pet Dodge!", + FontSettings = { + Color = {r=1, g=0.502, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_PET_PARRY = { + Show = true, + Message = "Pet Parry!", + FontSettings = { + Color = {r=1, g=0.502, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_PET_BLOCK = { + Show = true, + Message = "Pet Block!", + FontSettings = { + Color = {r=1, g=0.502, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_PET_ABSORB = { + Show = true, + Message = "Pet Absorb!", + FontSettings = { + Color = {r=0.502, g=0.502, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_PET_IMMUNE = { + Show = true, + Message = "Pet Immune!", + FontSettings = { + Color = {r=0.502, g=0.502, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_PET_EVADE = { + Show = true, + Message = "Pet Evade!", + FontSettings = { + Color = {r=1, g=0.502, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_PET_SPELL_DAMAGE = { + Show = true, + Message = "Pet %a (%s)", + FontSettings = { + Color = {r=0.33, g=0.33, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + Crit = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_PET_SPELL_MISS = { + Show = true, + Message = "Pet Miss! (%s)", + FontSettings = { + Color = {r=0.33, g=0.33, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_PET_SPELL_DODGE = { + Show = true, + Message = "Pet Dodge! (%s)", + FontSettings = { + Color = {r=0.33, g=0.33, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_PET_SPELL_PARRY = { + Show = true, + Message = "Pet Parry! (%s)", + FontSettings = { + Color = {r=0.33, g=0.33, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_PET_SPELL_BLOCK = { + Show = true, + Message = "Pet Block! (%s)", + FontSettings = { + Color = {r=0.33, g=0.33, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_PET_SPELL_RESIST = { + Show = true, + Message = "Pet Resist! (%s)", + FontSettings = { + Color = {r=0.502, g=0.502, b=0.698}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_PET_SPELL_ABSORB = { + Show = true, + Message = "Pet Absorb! (%s)", + FontSettings = { + Color = {r=0.502, g=0.502, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_PET_SPELL_IMMUNE = { + Show = true, + Message = "Pet Immune! (%s)", + FontSettings = { + Color = {r=0.502, g=0.502, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_OUTGOING_PET_SPELL_EVADE = { + Show = true, + Message = "Pet Evade! (%s)", + FontSettings = { + Color = {r=1, g=0.502, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=22}, + }, + }, + + + + MSBT_EVENTTYPE_NOTIFICATION_DEBUFF = { + Show = true, + Message = "[%s]", + IsSticky = false, + FontSettings = { + Color = {r=0, g=0.502, b=0.502}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_NOTIFICATION_BUFF = { + Show = true, + Message = "[%s]", + IsSticky = false, + FontSettings = { + Color = {r=0.698, g=0.698, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_NOTIFICATION_ITEM_BUFF = { + Show = true, + Message = "[%s]", + IsSticky = false, + FontSettings = { + Color = {r=0.698, g=0.698, b=0.698}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_NOTIFICATION_BUFF_FADE = { + Show = true, + Message = "-[%s]", + IsSticky = false, + FontSettings = { + Color = {r=0.698, g=0.698, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_NOTIFICATION_COMBAT_ENTER = { + Show = true, + Message = "+Combat", + IsSticky = false, + FontSettings = { + Color = {r=1, g=1, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_NOTIFICATION_COMBAT_LEAVE = { + Show = true, + Message = "-Combat", + IsSticky = false, + FontSettings = { + Color = {r=1, g=1, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_NOTIFICATION_POWER_GAIN = { + Show = true, + Message = "+%a %s", + IsSticky = false, + FontSettings = { + Color = {r=1, g=1, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_NOTIFICATION_POWER_LOSS = { + Show = true, + Message = "-%a %s", + IsSticky = false, + FontSettings = { + Color = {r=1, g=1, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_NOTIFICATION_CP_GAIN = { + Show = true, + Message = "%a CP", + IsSticky = false, + FontSettings = { + Color = {r=1, g=0.502, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_NOTIFICATION_CP_FULL = { + Show = true, + Message = "%a CP Finish It!", + IsSticky = false, + FontSettings = { + Color = {r=1, g=0.502, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_NOTIFICATION_HONOR_GAIN = { + Show = true, + Message = "+%a Honor", + IsSticky = false, + FontSettings = { + Color = {r=0.502, g=0.502, b=0.698}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_NOTIFICATION_REP_GAIN = { + Show = true, + Message = "+%a Reputation (%s)", + IsSticky = false, + FontSettings = { + Color = {r=0.502, g=0.502, b=0.698}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_NOTIFICATION_REP_LOSS = { + Show = true, + Message = "-%a Reputation (%s)", + IsSticky = false, + FontSettings = { + Color = {r=0.502, g=0.502, b=0.698}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_NOTIFICATION_SKILL_GAIN = { + Show = true, + Message = "%s: %a", + IsSticky = false, + FontSettings = { + Color = {r=0.333, g=0.333, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=0}, + }, + }, + MSBT_EVENTTYPE_NOTIFICATION_EXPERIENCE_GAIN = { + Show = true, + Message = "%a XP", + IsSticky = true, + FontSettings = { + Color = {r=0.756, g=0.270, b=0.823}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=26}, + }, + }, + MSBT_EVENTTYPE_NOTIFICATION_PC_KILLING_BLOW = { + Show = true, + Message = "Killing Blow! (%s)", + IsSticky = true, + FontSettings = { + Color = {r=0.333, g=0.333, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=20}, + }, + }, + MSBT_EVENTTYPE_NOTIFICATION_NPC_KILLING_BLOW = { + Show = false, + Message = "Killing Blow! (%s)", + IsSticky = true, + FontSettings = { + Color = {r=0.333, g=0.333, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=20}, + }, + }, + }, + + Triggers = { + MSBT_TRIGGER_LOW_HEALTH = { + EventSettings = { + Show = true, + Message = "Low Health! (%1)", + IsSticky = false, + FontSettings = { + Color = {r=1, g=0.502, b=0.502}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=26}, + }, + }, + TriggerSettings = { + TriggerType = 1, + Threshold = 40, + }, + }, + MSBT_TRIGGER_LOW_MANA = { + EventSettings = { + Show = true, + Message = "Low Mana! (%1)", + IsSticky = false, + FontSettings = { + Color = {r=0.502, g=0.502, b=1}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=26}, + }, + }, + TriggerSettings = { + Classes = {DRUID=true,HUNTER=true,MAGE=true,PALADIN=true,PRIEST=true,SHAMAN=true,WARLOCK=true}, + TriggerType = 2, + Threshold = 35, + }, + }, + MSBT_TRIGGER_LOW_PET_HEALTH = { + EventSettings = { + Show = true, + Message = "Low Pet Health! (%1)", + IsSticky = false, + FontSettings = { + Color = {r=1, g=0.502, b=0.502}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=26}, + }, + }, + TriggerSettings = { + Classes = {HUNTER=true,WARLOCK=true}, + TriggerType = 3, + Threshold = 40, + }, + }, + MSBT_TRIGGER_EXECUTE = { + EventSettings = { + Show = true, + Message = "Execute!", + IsSticky = true, + FontSettings = { + Color = {r=1, g=1, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=26}, + }, + }, + TriggerSettings = { + Classes = {PALADIN=true,WARRIOR=true}, + TriggerType = 4, + Threshold = 20, + }, + }, + MSBT_TRIGGER_COUNTER_ATTACK = { + EventSettings = { + Show = true, + Message = "Counterattack!", + IsSticky = true, + FontSettings = { + Color = {r=1, g=1, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=26}, + }, + }, + TriggerSettings = { + Classes = {HUNTER=true}, + TriggerType = 6, + TriggerEvents = {"CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES", "CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES", "CHAT_MSG_COMBAT_PARTY_MISSES", + "CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE", "CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE", "CHAT_MSG_SPELL_PARTY_DAMAGE"}, + SearchPatterns = {"VSPARRYOTHERSELF", "SPELLPARRIEDOTHERSELF"}, + }, + }, + MSBT_TRIGGER_MONGOOSE_BITE = { + EventSettings = { + Show = true, + Message = "Mongoose Bite!", + IsSticky = true, + FontSettings = { + Color = {r=1, g=1, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=26}, + }, + }, + TriggerSettings = { + Classes = {HUNTER=true}, + TriggerType = 6, + TriggerEvents = {"CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES", "CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES", "CHAT_MSG_COMBAT_PARTY_MISSES", + "CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE", "CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE", "CHAT_MSG_SPELL_PARTY_DAMAGE"}, + SearchPatterns = {"VSDODGEOTHERSELF", "SPELLDODGEDOTHERSELF"}, + }, + }, + MSBT_TRIGGER_CLEARCAST = { + EventSettings = { + Show = true, + Message = "Clearcast!", + IsSticky = true, + FontSettings = { + Color = {r=1, g=1, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=26}, + }, + }, + TriggerSettings = { + Classes = {MAGE=true,SHAMAN=true}, + TriggerType = 6, + TriggerEvents = {"CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS"}, + SearchPatterns = {"You gain Clearcast"}, + }, + }, + MSBT_TRIGGER_RIPOSTE = { + EventSettings = { + Show = true, + Message = "Riposte!", + IsSticky = true, + FontSettings = { + Color = {r=1, g=1, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=26}, + }, + }, + TriggerSettings = { + Classes = {ROGUE=true}, + TriggerType = 6, + TriggerEvents = {"CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES", "CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES", "CHAT_MSG_COMBAT_PARTY_MISSES", + "CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE", "CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE", "CHAT_MSG_SPELL_PARTY_DAMAGE"}, + SearchPatterns = {"VSPARRYOTHERSELF", "SPELLPARRIEDOTHERSELF"}, + }, + }, + MSBT_TRIGGER_WINDFURY = { + EventSettings = { + Show = true, + Message = "Windfury!", + IsSticky = true, + FontSettings = { + Color = {r=1, g=1, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=26}, + }, + }, + TriggerSettings = { + TriggerType = 6, + TriggerEvents = {"CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS"}, + SearchPatterns = {"You gain %d extra attacks through Windfury"}, + }, + }, + MSBT_TRIGGER_NIGHTFALL = { + EventSettings = { + Show = true, + Message = "Nightfall!", + IsSticky = true, + FontSettings = { + Color = {r=0.709, g=0, b=0.709}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=26}, + }, + }, + TriggerSettings = { + Classes = {WARLOCK=true}, + TriggerType = 6, + TriggerEvents = {"CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS"}, + SearchPatterns = {"You gain Shadow Trance"}, + }, + }, + MSBT_TRIGGER_OVERPOWER = { + EventSettings = { + Show = true, + Message = "Overpower!", + IsSticky = true, + FontSettings = { + Color = {r=1, g=1, b=0}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=26}, + }, + }, + TriggerSettings = { + Classes = {WARRIOR=true}, + TriggerType = 6, + TriggerEvents = {"CHAT_MSG_COMBAT_SELF_MISSES", "CHAT_MSG_SPELL_SELF_DAMAGE"}, + SearchPatterns = {"VSDODGESELFOTHER", "SPELLDODGEDSELFOTHER"}, + }, + }, + }, + + Suppressions = { + MSBT_SUPPRESSION_WISDOM_MANA_GAINS = { + Enabled = true, + SearchPattern = "+[35][039] " .. MANA, + }, + }, +}; diff --git a/MikScrollingBattleText/readme.html b/MikScrollingBattleText/readme.html new file mode 100644 index 0000000..e06fa0e --- /dev/null +++ b/MikScrollingBattleText/readme.html @@ -0,0 +1,808 @@ + + + Mik's Scrolling Battle Text Readme + + + +
Mik's Scrolling Battle Text Readme
+
+ Version: 3.01
+ Author: Mik

+ Credits: +
    +
  • Thanks to grayhoof, the author of Scrolling Combat Text, for the original mod which inspired this mod.
  • +
  • Thanks to kergoth and Wobin for their suggestions on optimizations via reduced GC churn and namespacing tips.
  • +
  • Thanks to tekkub for compostLib which I borrowed some of the table recycling code from.
  • +
+
+ +
+
+ +
Table of Contents:
+ + + +
+ Return to TOC

+
+ Unzip the contents into the AddOns directory of your WoW game directory.

+ This is typically C:\Program Files\World of Warcraft\Interface\AddOns.

+ If your are upgrading the mod from a previous version, make sure to delete the old version prior to installing + the new version. +
+ + +
+ Return to TOC

+
+ This mod makes it easier to see combat information by scrolling it on the screen in 3 configurable scrolling areas. + There is a scroll area for incoming heals/damage, one for outgoing heals/damage, and a third for notifications. + Each scroll area is completely customizable.

+ + Features: +
    +
  • Scroll incoming damage/heals, outgoing damage/heals, and notifications in separate configurable scroll areas on the playing field.
  • +
  • Customize the position, animation style, show state, font style, font size, and font outline for each of the scroll areas.
  • +
  • Customize each individual event's color, font style, font size, font outline, output message, and show state.
  • +
  • Set "Master Font" settings that will be inherited by all of the scroll areas and the events in them unless they are overriden at the scroll area or event level.
  • +
  • Merge AoE data into one event with cumulative damage/healing done with number of normal and crits specified.
  • +
  • Show overhealing amounts against yourself or party/raid members.
  • +
  • Add triggers that will allow you to show notifications based on various health and mana thresholds, or custom search patterns. Triggers are also set to only fire for specific classes.
  • +
  • Suppress particular messages you do not want to see such as mana gains from Blessing/Judgement of Wisdom.
  • +
  • Load on demand options.
  • +
+ +
+ Supported Events: +
    +
  • Incoming:
  • +
      +
    • Melee Damage
    • +
    • Melee Misses, Dodges, Parries, Blocks, Absorbs, and Immunes
    • +
    • Ability/Spell Damage
    • +
    • Ability/Spell Damage Over Time (DoTs)
    • +
    • Ability/Spell Misses, Dodges, Parries, Blocks, Absorbs, Immunes, and Reflects
    • +
    • Spell Resists
    • +
    • Heals
    • +
    • Heals Over Time (HoTs)
    • +
    • Environmental Damage
    • +
    +
    +
  • Outgoing:
  • +
      +
    • Melee Damage
    • +
    • Melee Misses, Dodges, Parries, Blocks, Absorbs, and Evades
    • +
    • Ability/Spell Damage
    • +
    • Ability/Spell Damage Over Time (DoTs)
    • +
    • Ability/Spell Misses, Dodges, Parries, Blocks, Absorbs, Immunes, Reflects, and Evades
    • +
    • Spell Resists
    • +
    • Heals
    • +
    • Heals Over Time (HoTs)
    • +
    • Pet Melee Damage
    • +
    • Pet Melee Misses, Dodges, Parries, Blocks, Absorbs, Immunes, and Evades
    • +
    • Pet Ability/Spell Damage
    • +
    • Pet Ability/Spell Misses, Dodges, Parries, and Blocks, Absorbs, Immunes, Reflects, and Evades
    • +
    • Pet Spell Resists
    • +
    + +
    +
  • Notification:
  • +
      +
    • Debuffs
    • +
    • Buffs
    • +
    • Item Buffs
    • +
    • Buff Fades
    • +
    • Enter/Leave Combat
    • +
    • Power Gains and Losses
    • +
    • Combo Point Gains
    • +
    • Combo Points Full
    • +
    • Honor Gains
    • +
    • Reputation Gains and Losses
    • +
    • Skill Gains
    • +
    • Experience Gains
    • +
    • Killing Blows (Player and NPC)
    • +
    + +
    +
  • Default Triggers:
  • +
      +
    • Low Health
    • +
    • Low Mana
    • +
    • Low Pet Health
    • +
    • Execute
    • +
    • Counter Attack
    • +
    • Mongoose Bite +
    • Clearcast
    • +
    • Riposte
    • +
    • Windfury
    • +
    • Nightfall
    • +
    • Overpower
    • +
    + +
    +
  • Default Suppressions:
  • +
      +
    • Blessing/Judgement of Wisdom (+30 Mana, +33 Mana, +59 Mana)
    • +
    +
+
+ + +
+ Return to TOC

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
/msbtShows the options interface.
/msbt resetResets the current profile to the default settings.
/msbt disableDisables the mod.
/msbt enableEnables the mod.
/msbt versionShows the current version.
/msbt statsReports stats about table recycling.
/msbt search patternSets a pattern for searching event types.
/msbt debugToggles debug mode.
/msbt helpShows the command usage.
+
+ + +
+ Return to TOC

+
+ The trigger system allows you to specify notifications based on events that are not already covered by + MSBT's native events. The trigger system has been optimized so that having extra triggers which are + not enabled or which do not apply to the class you are currently playing add no overhead. +

+ + Due to this optimization, a lot of triggers that people will want (Windfury, Nightfall, Mongoose Bite, etc) + are probably already there by default, and will not waste resources for those which don't apply to your + class or are not enabled. +

+ + The following is a description of the fields unique to the Trigger Settings interface (see the Frequently Asked + Questions section for a tutorial on how to create a new trigger): +

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Output Message + This is the message that will be displayed when the trigger fires. If you are using a Search Pattern + with captures you can enter %1 through %9 to use the data that was captured. Also, for trigger types + with thresholds, the amount of health or mana will be in %1. +
Applicable Trigger Classes: + These are the classes that you want the trigger to apply to. NOTE: THIS IS YOUR CLASS NOT THE TARGET CLASS. + You may look at the Execute trigger for an example. Since Warrior and Paladin are selected, the trigger + will only apply when you are playing on a warrior or paladin. +
Trigger Type: + This is the type of trigger. +
    +
  • Self Health - This will trigger when your health falls below the selected threshold.
  • +
  • Self Mana - This will trigger when your mana falls below the selected threshold.
  • +
  • Pet Health - This will trigger when your pet's health falls below the selected threshold.
  • +
  • Enemy Target Health - This will trigger when your target is an enemy and their health falls below the selected threshold.
  • +
  • Friendly Target Health - This will trigger when your target is friendly and their health falls below the selected threshold.
  • +
  • Search Pattern - This will trigger when the search pattern you enter is found.
  • +
Threshold: + This slider will only be present if the selected trigger type is one of the types that support it. + It specifies the threshold percentage that must be crossed for the trigger to fire. +
Trigger Event Types: + This list will only be present if the selected trigger type is Search Pattern.

+ + This exists solely for optimization and is probably the most difficult field to enter. While not having this + field would make the trigger system easier to use, it would also make it extremely inefficient since searching + through an array of triggers which don't apply every time ANY event happens wastes precious resources. In order + to find the appropriate event types to use, type /msbt search pattern, where the word pattern is a lua search string. + Only combat messages that match the search string will display their associated event type. Once you are done you + can type /msbt search to toggle event searching mode back off. +
Search Pattern 1 & 2: + These fields will only be present if the selected trigger type is Search Pattern.

+ + These fields can either contain a global string from globalstrings.lua (if you happen to know which one you want) or a + lua formatted search string. The mod also supports data captured from the pattern. The output message specified for + the trigger can use the captured data by putting %1 - %9 where the number is the position of the captured data. +
+
+ + + +
+ Return to TOC

+
+ The suppression system allows you to suppress specific text that MSBT is displaying to the screen via lua search patterns. +

+ + The text next to enable checkbox is the search pattern that will be checked for matches against the output text. If a match is made, + the output text will be suppressed.
+ See the Frequently Asked Questions section for a tutorial on how to create a + new suppression. +

+ + Here is the official lua reference for patterns: +
+ Character Class: +

+ + A character class is used to represent a set of characters. The following combinations are allowed in describing a character class: +
    +
  • x: (where x is not one of the magic characters ^$()%.[]*+-?) represents the character x itself.
  • +
  • .: (a dot) represents all characters.
  • +
  • %a: represents all letters.
  • +
  • %c: represents all control characters.
  • +
  • %d: represents all digits.
  • +
  • %l: represents all lowercase letters.
  • +
  • %p: represents all punctuation characters.
  • +
  • %s: represents all space characters.
  • +
  • %u: represents all uppercase letters.
  • +
  • %w: represents all alphanumeric characters.
  • +
  • %x: represents all hexadecimal digits.
  • +
  • %z: represents the character with representation 0.
  • +
  • + %x: (where x is any non-alphanumeric character) represents the character x. This is the standard way to escape the magic characters. Any punctuation character (even the non magic) + can be preceded by a '%' when used to represent itself in a pattern. +
  • +
  • + [set]: represents the class which is the union of all characters in set. A range of characters may be specified by separating the end characters of the range with a '-'. All classes + %x described above may also be used as components in set. All other characters in set represent themselves. For example, [%w_] (or [_%w]) represents all alphanumeric characters plus + the underscore, [0-7] represents the octal digits, and [0-7%l%-] represents the octal digits plus the lowercase letters plus the '-' character. +

    + The interaction between ranges and classes is not defined. Therefore, patterns like [%a-z] or [a-%%] have no meaning. +
  • +
    +
  • [^set]: represents the complement of set, where set is interpreted as above.
  • +
+ For all classes represented by single letters (%a, %c, etc.), the corresponding uppercase letter represents the complement of the class. For instance, %S represents all non-space characters. +

+ The definitions of letter, space, and other character groups depend on the current locale. In particular, the class [a-z] may not be equivalent to %l. +

+ + Pattern Item: +

+ + A pattern item may be: +
    +
  • a single character class, which matches any single character in the class;
  • +
  • a single character class followed by '*', which matches 0 or more repetitions of characters in the class. These repetition items will always match the longest possible sequence;
  • +
  • a single character class followed by '+', which matches 1 or more repetitions of characters in the class. These repetition items will always match the longest possible sequence;
  • +
  • a single character class followed by '-', which also matches 0 or more repetitions of characters in the class. Unlike '*', these repetition items will always match the shortest possible sequence;
  • +
  • a single character class followed by '?', which matches 0 or 1 occurrence of a character in the class;
  • +
  • %n, for n between 1 and 9; such item matches a substring equal to the n-th captured string (see below);
  • +
  • + %bxy, where x and y are two distinct characters; such item matches strings that start with x, end with y, and where the x and y are balanced. This means that, if one reads the string from left to right, + counting +1 for an x and -1 for a y, the ending y is the first y where the count reaches 0. For instance, the item %b() matches expressions with balanced parentheses. +
  • +
+ + Pattern: +

+ A pattern is a sequence of pattern items. A '^' at the beginning of a pattern anchors the match at the beginning of the subject string. A '$' at the end of a pattern anchors the match at the end of the subject string. + At other positions, '^' and '$' have no special meaning and represent themselves. +

+ + Captures: +

+ A pattern may contain sub-patterns enclosed in parentheses; they describe captures. When a match succeeds, the substrings of the subject string that match captures are stored (captured) for future use. Captures are numbered + according to their left parentheses. For instance, in the pattern "(a*(.)%w(%s*))", the part of the string matching "a*(.)%w(%s*)" is stored as the first capture (and therefore has number 1); the character matching "." is + captured with number 2, and the part matching "%s*" has number 3. +

+ + As a special case, the empty capture () captures the current string position (a number). For instance, if we apply the pattern "()aa()" on the string "flaaap", there will be two captures: 3 and 5. +

+ A pattern cannot contain embedded zeros. Use %z instead. +
+
+ + + +
+ Return to TOC

+
+
MikSBT.DisplayMessage(message [, displayType, isSticky, colorR, colorG, colorB, fontSize, fontIndex, outlineIndex])
+

+
Parameters
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
message (Required)The string to display.
displayType (Optional) + Specifies the scroll area in which to display the message. This may be one of the following values:

+ + MikSBT.DISPLAYTYPE_INCOMING
+ MikSBT.DISPLAYTYPE_OUTGOING
+ MikSBT.DISPLAYTYPE_NOTIFICATION

+ + If the parameter is omitted or invalid a default of MikSBT.DISPLAYTYPE_NOTIFICATION will be used. +
isSticky (Optional) + Specifies whether or not the message should be displayed sticky style. This must be either true or false.

+ If the parameter is omitted a default of false will be used. +
colorR (Optional) + The red component of the color to display the message with. Value range is 0-255.

+ If the parameter is omitted a default of 255 will be used. +
colorG (Optional) + The green component of the color to display the message with. Value range is 0-255.

+ If the parameter is omitted a default of 255 will be used. +
colorB (Optional) + The blue component of the color to display the message with. Value range is 0-255.

+ If the parameter is omitted a default of 255 will be used. +
fontSize (Optional) + The font size to use. Value range is 12-32.

+ If this value is omitted or an invalid value is passed the settings for the scroll area will be used. +
fontIndex (Optional) + The index of the font to use. The valid indices can be seen by looking at the MikSBT.AVAILABLE_FONTS + table in the localization.lua file.

+ If the parameter is omitted or an invalid index is passed the font index for the scroll area will be used. +
outlineIndex (Optional) + The index of the outline to use. The valid indices can be seen by looking at the MikSBT.AVAILABLE_OUTLINES table in the localization.lua file.

+ If the parameter is omitted or an invalid index is passed the outline index for the scroll area will be used. +
+
+ +
Return Values
+
None.
+ +
Examples
+
+
+
+ -- Displays "Test Message" in the notification scroll area in white.
+ MikSBT.DisplayMessage("Test Message");
+ 
+ -- Displays "Another Message" in the incoming scroll area in white as a sticky.
+ MikSBT.DisplayMessage("Another Message", MikSBT.DISPLAYTYPE_INCOMING, true);
+
+ -- Displays "Uber Damage!" in the outgoing scroll area in blue.
+ MikSBT.DisplayMessage("Uber Damage!", MikSBT.DISPLAYTYPE_OUTGOING, false, 0, 0, 255);
+
+ -- Displays "Enemy begins to flee in fear" in the notification scroll area in green with the scroll area's
+ -- font size, the font set to index 2 and the outline set to index 1.
+ MikSBT.DisplayMessage("Enemy begins to flee in fear", nil, false, 0, 255, 0, nil, 2, 1);
+    
+
+
+ + + +
+ Return to TOC

+
+
    +
  1. + I don't like any of the fonts supplied with MSBT. How do I use my own fonts? +

    + + WARNING: ALL FONT MODIFICATION WILL REQUIRE THAT YOU COMPLETELY QUIT THE GAME AND RESTART IT. + RELOADING THE CONSOLE ALONE WILL NOT WORK. +

    + + NOTE: Keep in mind that if you use your own font files that you need to make sure the font + supports the characters that will be displayed. For example the typical way to display buff + gains is [BuffName]. If the font you use does not have a character glyph for the [ or ] + characters you will likely see a big ugly block instead of the intended characters. This is + especially important with non-English clients since a lot of characters aren't supported by + English fonts. +

    + + There are two ways to use custom fonts: +
      +
    • + The first, and easiest, method is to simply replace one of the font files in the + MikScrollingBattleText\Fonts directory with the truetype font (.ttf) that you want. The drawback + to this approach is that the mod's option screen will still reference the font with the old font's name. +

      + + For example, if you had a truetype font file "MyUberFont.ttf" you wanted to use. Rename MyUberFont.ttf to Adventure.ttf + and replace the Adventure.ttf font file in the MikScrollingBattleText\Fonts directory. In the MSBT options interface + it would still be called "Adventure," but it would actually be using the new font. +
    • +

      +
    • + The second method is to open the file localization.lua in the MikScrollingBattleText directory and find the + MikSBT.AVAILABLE_FONTS entry. You can add your font with the appropriate name and path. If you don't know + anything about programming, I wouldn't suggest trying this method. Another thing to keep in mind with this + approach is that due to the way WoW loads its data, I would suggest you put in new fonts you want to add in + the same place as the current fonts for the mod (MikScrollingBattleText\Fonts) to avoid problems with + loading. +
    • +
    +
  2. +

    + +
  3. + How do I create a new trigger? +

    + + Let's go through creating a trigger for a warrior's overpower ability which already exists, but will be used for illustrative purposes. +

    + + A warrior's overpower ability becomes available once the enemy they are fighting dodges. So, the first that needs to be done is to + ascertain the appropriate event types. +
    + Since we want the trigger to fire when the enemy dodges we need to take a look at what the combat log says when an enemy dodges. The combat + log message says "You attack. Mob dodges." To find out what event type this is you can type /msbt search dodge. What this will do is make + it so that every time an entry is added to the combat log with the word dodge in it, you will get a message + with the event type in your normal chat frame. In this case you would probably see something like: +

    + MSBT: CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES - Mob attacks. You dodge.
    + MSBT: CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES - Player attacks. You dodge.
    + MSBT: CHAT_MSG_COMBAT_SELF_MISSES - You attack. Mob dodges. <--- Aha, there is one.
    + MSBT: CHAT_MSG_SPELL_SELF_DAMAGE - Your hamstring is dodged by Mob. <--- There is another one.
    +

    + So the correct event types to choose are CHAT_MSG_COMBAT_SELF_MISSES and CHAT_MSG_SPELL_SELF_DAMAGE. Type /msbt search + to turn the event searching mode back off. +


    + Now that we know the correct event types we can create the trigger. Here are the steps to do so: +

    +
      +
    1. Since a new trigger is being created, click the Add Trigger button. A new trigger will appear in the list of triggers.
    2. +

      +
    3. Click the output message for the new trigger and enter Overpower!.
    4. +

      +
    5. Click the Trigger Settings button.
    6. +

      +
    7. + Uncheck "All" classes, and check Warrior for the class the trigger will apply to. It is better to select the + specific classes the trigger applies to instead of selecting all classes since by specifying classes, the mod + can completely ignore the trigger and save resources for the classes to which it does not apply.
    8. +
    9. Select Search Pattern for the Trigger Type.
    10. +

      +
    11. Choose the correct event types we ascertained above. CHAT_MSG_COMBAT_SELF_MISSES and CHAT_MSG_SPELL_SELF_DAMAGE.
    12. +

      +
    13. + Last, since there are two different combat log messages, you'll need to enter two different search patterns. In the + search pattern 1 field, enter "You attack. .+ dodges" to cover the first message and in the search pattern 2 field, + enter "Your .+ is dodged by .+". Both of those are entered without the quotes. There are other variations of the + search patterns that could be used, but these would work fine. +

      + NOTE: The trigger that is already setup uses the global strings VSDODGESELFOTHER and SPELLDODGEDSELFOTHER. Messages + that go to the combat log have an associated global string that is defined in globalstrings.lua by blizzard and can + be used. Global strings are really only useful in this sense if you are looking for a general event like dodges, + parries, misses, etc. Looking specifically for something like a buff name, for example, wouldn't have an available + global string and you'd need to enter a lua search pattern as demonstrated. +
    14. +

      +
    15. Click the Save Trigger button.
    16. +
    + +

    + The trigger is now set to fire any time a mob or player dodges one of your attacks (only if you are a warrior). +

    + The color, font settings, and sticky state for the trigger can be set like any other event. + +
  4. +

    + +
  5. + Some of the default triggers are not working for me while others are. What's up with that? +

    + Most likely, you are using a non-English client. Some of the search patterns for the triggers + use Blizzard's global strings which are translated by Blizzard and hence will work on your client + by default. Some other triggers have an English search pattern for when to fire the trigger. Simply + edit the trigger settings for the trigger that is not working and change the search pattern to an + appropriate one for your language. +
  6. +

    + +
  7. + How do I create a new suppression? +

    + As an example, let's create a suppression for warrior stance switching. +

    + Unless you have changed the output message format for buff gains and fades, the warrior stance switch + messages should be: +

    + [Battle Stance]
    + -[Battle Stance]
    + [Defensive Stance]
    + -[Defensive Stance]
    + [Bersker Stance]
    + -[Bersker Stance]
    +
    + What we want to do is create a search pattern that will match those output messages. +

    + Here is a search pattern that will match all of them: +

    + %[.+ Stance%] +

    + Now that we have a search pattern that will match all of the stance switching messages, we can + do the following to add the suppression: +

    +
      +
    1. Go to the Suppressions tab.
    2. +
    3. Click the Add New Suppression button.
    4. +
    5. Click the label where it says "New Suppression: Click here to edit."
    6. +
    7. Enter the seach pattern from above.
    8. +
    +
    + All of the warrior stance switch messages should now be suppressed. +
  8. +
+
+ + +
+ Return to TOC

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
3.01 +
    +
  • Fixed the bug where you could only add one suppression and adding a new one was overwriting it.
  • +
+
3.0 +
    +
  • Implemented a low overhead trigger system. See documentation above.
  • +
  • Implemented a suppression system that allows you to suppress particular messages you don't want to see.
  • +
  • + Made significant changes to the scroll area settings interface. The new interface shows all three + scroll areas at the same time. Each scroll area is now titled with its coordinates and there are + editboxes to enter specific coordinates in addition to being able to drag the scroll areas around. +
  • +
  • + Changed the core animation routines to use function pointers in order to eliminate the need for a + ton of conditional testing. Previously, every time the animation routine was called (typically + 60-70 times per second for every scrolling item), the animation style and scroll direction were + checked to calculate how to move the text. Now those items are only checked during the initial + animation object setup phase. This should help performance on slower PCs. +
  • +
  • Added the command "/msbt search pattern" to enable an event searching mode which helps identify event types used in the trigger system.
  • +
  • + Moved the Low Health, Low Mana, and Execute events into the trigger system. Due to this change + the Low Mana and Execute triggers will no longer waste resources checking on classes that don't + use mana or have an execute ability. Also moving them into the trigger system made the thresholds + at which to show the Low Health, and Low Mana warnings selectable. +
  • +
  • Made a few minor code performance tweaks to the animation setup "pipeline."
  • +
  • Added Killing Blow notification events for both players and NPCs.
  • +
  • Added crushing and glancing hit partial effects.
  • +
  • The font settings frame can now be moved.
  • +
  • Fixed a bug where messages added via the MikSBT.DisplayMessage function were being shown even if the scroll area was set to not show messages.
  • +
+
2.11 +
    +
  • Disabled Blizzard's new floating text in Patch 1.12 when MSBT is enabled.
  • +
  • Updated for Patch 1.12.
  • +
+
2.1 +
    +
  • Reduced memory usage a little by removing the underlying tables used to store crit information for events that can never be crits. (Down to around 477KB)
  • +
  • To go along with the above change, the font settings interface for events was reworked so that you can no longer set crit information for events that don't support them.
  • +
  • Added a title at the top of the font settings frame to help distinguish what is being modified.
  • +
  • Added an Experience Gains notification event.
  • +
  • Added the capability for notifications to be displayed "sticky" style.
  • +
  • Fixed the bug induced by patch 1.11 where reputation gains and losses weren't being displayed.
  • +
+
2.0 +
    +
  • + MAJOR optimization code rewrite: +
      +
    • Made options load on demand to significantly reduce memory usage and start up time.
    • +
    • + Implemented a table recycling system to reuse tables created during combat instead + of creating new ones and allowing them to be garbage collected. The net effect is that a + ton of garbage collection churn has been eliminated. Thanks go to kergoth and Wobin for + tips on how to achieve this. +
    • +
    • The combat event parser has been changed to reuse one single table for storing the results of the parsed data.
    • +
    • Streamlined the combat event to screen animation "pipeline."
    • +
    • Namespaced all code to reduce global namespace pollution.
    • +
    • + Load up KB Usage in v1.03 was approximately 1050 KB. This has been reduced to around + 488 KB. In addition, due to the table recycling system, memory usage during operation is + much more consistent instead of continuously increasing until the next garbage collection + cycle. +
    • +
    +
  • +
    +
  • + Added a function to allow messages to be easily displayed through MSBT from external sources.
    + This function is MikSBT.DisplayMessage and is detailed above. +
  • +
  • Added the command "/msbt stats" to report statistics about the table recycling system.
  • +
  • Changed the functionality of AoE merges so that the name reported is "Multiple" instead of the last affected unit.
  • +
  • Added the option to disable "game damage" instead of just always doing it.
  • +
  • Added the option to disable "sticky crits."
  • +
  • Added Execute/Hammer of Wrath notification event.
  • +
  • Separated Heals over time (HoTs) and Damage over time (DoTs) into their own events.
  • +
  • Added the option to display overhealing.v +
  • Fixed a bug where crits were not being recognized in non-English clients.
  • +
+
1.03 +
    +
  • Fixed a bug where options set with a checkbox were not being properly saved on logout.
  • +
+
1.02 +
    +
  • Fixed a bug where the global string parser wasn't appropriately accounting for the argument order of non-English clients.
  • +
+
1.01 +
    +
  • Updated for Patch 1.11.
  • +
+
1.0 +
    +
  • Initial version.
  • +
+
+
+ + \ No newline at end of file diff --git a/MikScrollingBattleTextOptions/MSBTOptions.lua b/MikScrollingBattleTextOptions/MSBTOptions.lua new file mode 100644 index 0000000..16322af --- /dev/null +++ b/MikScrollingBattleTextOptions/MSBTOptions.lua @@ -0,0 +1,3561 @@ +------------------------------------------------------------------------------------- +-- Title: Mik's Scrolling Battle Text Options +-- Author: Mik +------------------------------------------------------------------------------------- + +------------------------------------------------------------------------------------- +-- Local Constants. +------------------------------------------------------------------------------------- + +-- The name of the options frame. +local OPTIONS_FRAME_NAME = "MSBTFrameOptions"; + +-- The name of the font settings frame. +local FONT_SETTINGS_FRAME_NAME = "MSBTFontSettingsFrame"; + +-- The name of the scroll area frames. +local SCROLL_AREA_MOVER_FRAME_NAME = "MSBTScrollAreaMoverFrame"; +local SCROLL_AREA_MOVER_CONTROL_FRAME_NAME = "MSBTScrollAreaMoverControlFrame"; +local SCROLL_AREA_MOVER_INCOMING_FRAME_NAME = "MSBTScrollAreaMoverIncomingFrame"; +local SCROLL_AREA_MOVER_OUTGOING_FRAME_NAME = "MSBTScrollAreaMoverOutgoingFrame"; +local SCROLL_AREA_MOVER_NOTIFICATION_FRAME_NAME = "MSBTScrollAreaMoverNotificationFrame"; + +-- The name of the trigger configuration frame. +local TRIGGER_CONFIGURATION_FRAME_NAME = "MSBTTriggerConfigFrame"; + + +-- The min and max font sizes allowed. +local MIN_FONT_SIZE = 12; +local MAX_FONT_SIZE = 32; + +-- The min and max animation steps. +local MIN_ANIMATION_STEP = 1; +local MAX_ANIMATION_STEP = 5; + +-- The min and max scroll heights. +local MIN_SCROLL_HEIGHT = 100; +local MAX_SCROLL_HEIGHT = 300; + +-- The size of an event settings line and number of event items per page. +local EVENT_ITEM_HEIGHT = 25; +local EVENT_ITEMS_PER_PAGE = 10; + +-- The size of a trigger settings line and number of trigger items per page. +local TRIGGER_ITEM_HEIGHT = 25; +local TRIGGER_ITEMS_PER_PAGE = 11; + +-- The size of a trigger event line and the number of trigger event items per page. +local TRIGGER_EVENT_ITEM_HEIGHT = 25; +local TRIGGER_EVENT_ITEMS_PER_PAGE = 4; + +-- The size of a suppressions settings line and number of suppression items per page. +local SUPPRESSION_ITEM_HEIGHT = 25; +local SUPPRESSION_ITEMS_PER_PAGE = 11; + +-- Tab indices. +local TAB_INDEX_GENERAL = 1; +local TAB_INDEX_INCOMING = 2; +local TAB_INDEX_OUTGOING = 3; +local TAB_INDEX_NOTIFICATION = 4; +local TAB_INDEX_TRIGGERS = 5; +local TAB_INDEX_SUPPRESSIONS = 6; + + +------------------------------------------------------------------------------------- +-- Local variables. +------------------------------------------------------------------------------------- + +-- Holds available font and outline selections. +local availableFontsInherit; +local availableOutlinesInherit; + +-- Holds a table of available trigger events. +local availableTriggerEvents = {}; + + +------------------------------------------------------------------------------------- +-- Core event handlers. +------------------------------------------------------------------------------------- + +-- ********************************************************************************** +-- Called when the options frame is loaded. +-- ********************************************************************************** +function MikSBTOpt.OnLoad() + -- Register for the ADDON_LOADED event. + this:RegisterEvent("ADDON_LOADED"); +end + + +-- ********************************************************************************** +-- Called when the events we registered for occur. +-- ********************************************************************************** +function MikSBTOpt.OnEvent() + -- When an addon is loaded. + if (event == "ADDON_LOADED") then + -- Make sure it's this addon. + if (arg1 == string.gsub(MikSBT.MOD_NAME .. "Options", "%s", "")) then + + -- Don't get notification for other addons being loaded. + this:UnregisterEvent("ADDON_LOADED"); + + -- Initialize the options. + MikSBTOpt.Init(); + end + end +end + + +-- ********************************************************************************** +-- Called when the mod is fully loaded (variables loaded). +-- ********************************************************************************** +function MikSBTOpt.Init() + -- Set the options window title. + getglobal(OPTIONS_FRAME_NAME .. "TitleText"):SetText(MikSBT.WINDOW_TITLE); + + -- Set the normal and crit size font preview text. + getglobal(FONT_SETTINGS_FRAME_NAME .. "NormalPreviewText"):SetText(MikSBTOpt.MSG_NORMAL_PREVIEW_TEXT); + getglobal(FONT_SETTINGS_FRAME_NAME .. "CritPreviewText"):SetText(MikSBTOpt.MSG_CRIT_PREVIEW_TEXT); + + -- Set the trigger classes text + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "TriggerClassesText"):SetText(MikSBTOpt.MSG_TRIGGER_APPLICABLE_CLASSES_LABEL); + + + -- Initialize the dropdowns. + MikSBTOpt.InitDropdowns(); + + -- Initialize the checkboxes. + MikSBTOpt.InitCheckboxes(); + + -- Initialize the sliders. + MikSBTOpt.InitSliders(); + + -- Initialize the buttons. + MikSBTOpt.InitButtons(); + + -- Initialize the editboxes. + MikSBTOpt.InitEditboxes(); + + -- Initialize the events. + MikSBTOpt.InitEvents(); + + + + + + -- Populate the tabs and select the first one. + MikSBTOpt.PopulateTabs(); + MikSBTOpt.TabOnClick(1); + + + + -- Change the state of the profile buttons correctly, and set the current profile label. + MikSBTOpt.EnableDisableProfileButtons(); + getglobal(OPTIONS_FRAME_NAME .. "Tab1FrameCurrentProfileLabel"):SetText(MikSBTOpt.MSG_CURRENT_PROFILE_TEXT .. ": " .. MikSBT_Save.CurrentProfile); + + + -- Setup the available trigger events. + MikSBTOpt.SetupAvailableTriggerEvents(); + + -- Populate the options for the current profile. + MikSBTOpt.PopulateProfileOptions(); + + -- Insert the frame name into the UISpecialFrames array so it closes when the escape key is pressed. + table.insert(UISpecialFrames, OPTIONS_FRAME_NAME); +end + + +-- ********************************************************************************** +-- Called when the options frame is shown. +-- ********************************************************************************** +function MikSBTOpt.OnShow() + -- Holds whether or not to play a sound. + local doPlaySound = true; + + -- Get the scroll area mover control frame and make sure it exists. + local frame = getglobal(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME); + -- Check if the scroll area mover frame is shown. + if (frame and frame:IsShown()) then + -- Don't play a sound. + doPlaySound = false; + end + + -- Check if a sound should be played. + if (doPlaySound) then + -- Play the opening sound + PlaySound("igCharacterInfoOpen"); + end +end + + +-- ********************************************************************************** +-- Called when the options frame is hidden. +-- ********************************************************************************** +function MikSBTOpt.OnHide() + -- Holds whether or not to play a sound. + local doPlaySound = true; + + -- Get the scroll area mover control frame and make sure it exists. + local frame = getglobal(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME); + -- Check if the scroll area mover frame is shown. + if (frame and frame:IsShown()) then + -- Don't play a sound. + doPlaySound = false; + end + + -- Check if a sound should be played. + if (doPlaySound) then + -- Play the closing sound + PlaySound("igCharacterInfoClose"); + end + + -- Hide the font settings frame when the main frame is closed. + getglobal(FONT_SETTINGS_FRAME_NAME):Hide(); + + -- Hide the trigger config frame when the main frame is closed. + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME):Hide(); +end + + +-- ********************************************************************************** +-- Called when one of the scroll areas is scrolled. +-- ********************************************************************************** +function MikSBTOpt.OnVerticalScroll() + -- Uncomment once populate functions exist. + -- Check if it's the incoming event settings scroll frame. + if (this:GetName() == OPTIONS_FRAME_NAME .. "Tab2FrameEventsScrollFrame") then + FauxScrollFrame_OnVerticalScroll(EVENT_ITEM_HEIGHT, MikSBTOpt.PopulateIncomingEventSettings); + + -- Outgoing event settings scroll frame. + elseif (this:GetName() == OPTIONS_FRAME_NAME .. "Tab3FrameEventsScrollFrame") then + FauxScrollFrame_OnVerticalScroll(EVENT_ITEM_HEIGHT, MikSBTOpt.PopulateOutgoingEventSettings); + + -- Notification event settings scroll frame. + elseif (this:GetName() == OPTIONS_FRAME_NAME .. "Tab4FrameEventsScrollFrame") then + FauxScrollFrame_OnVerticalScroll(EVENT_ITEM_HEIGHT, MikSBTOpt.PopulateNotificationEventSettings); + + elseif (this:GetName() == OPTIONS_FRAME_NAME .. "Tab5FrameTriggersScrollFrame") then + FauxScrollFrame_OnVerticalScroll(TRIGGER_ITEM_HEIGHT, MikSBTOpt.PopulateTriggerEventSettings); + + elseif (this:GetName() == OPTIONS_FRAME_NAME .. "Tab6FrameSuppressionsScrollFrame") then + FauxScrollFrame_OnVerticalScroll(SUPPRESSION_ITEM_HEIGHT, MikSBTOpt.PopulateSuppressionSettings); + + elseif (this:GetName() == TRIGGER_CONFIGURATION_FRAME_NAME .. "EventsScrollFrame") then + FauxScrollFrame_OnVerticalScroll(TRIGGER_EVENT_ITEM_HEIGHT, MikSBTOpt.PopulateAvailableTriggerEvents); + + end +end + + + +------------------------------------------------------------------------------------- +-- Tab functions. +------------------------------------------------------------------------------------- + +-- ********************************************************************************** +-- Populates the tabs. +-- ********************************************************************************** +function MikSBTOpt.PopulateTabs() + -- Set the number of tabs for the options frame. + PanelTemplates_SetNumTabs(getglobal(OPTIONS_FRAME_NAME), table.getn(MikSBTOpt.TABS)); + + -- Loop through all of the tabs. + for tabNumber, tabData in MikSBTOpt.TABS do + -- Get the associated tab frame. + local tabFrame = getglobal(OPTIONS_FRAME_NAME .. "Tab" .. tabNumber); + if (tabFrame) then + -- Set the tooltip for the tab. + tabFrame.tooltipText = tabData.Tooltip; + + -- Set the text for the tab and resize it. + tabFrame:SetText(tabData.Label); + PanelTemplates_TabResize(1, tabFrame); + end + end +end + + +-- ********************************************************************************** +-- Called when a tab is clicked. +-- ********************************************************************************** +function MikSBTOpt.TabOnClick(tab) + -- Get the clicked tab + if (not tab) then + tab = this:GetID(); + end + + -- Set the selected tab + PanelTemplates_SetTab(getglobal(OPTIONS_FRAME_NAME), tab); + + -- Hide all of the tab frames. + for tabNumber, tabData in MikSBTOpt.TABS do + local associatedTabFrame = getglobal(OPTIONS_FRAME_NAME .. "Tab" .. tabNumber .. "Frame"); + if (associatedTabFrame) then + associatedTabFrame:Hide(); + end + end + + -- Show the associated frame for the selected tab. + local associatedTabFrame = getglobal(OPTIONS_FRAME_NAME .. "Tab" .. tab .. "Frame"); + if (associatedTabFrame) then + associatedTabFrame:Show(); + end + + -- Hide the font settings frame. + getglobal(FONT_SETTINGS_FRAME_NAME):Hide(); + + -- Hide the trigger config frame. + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME):Hide(); +end + + + +------------------------------------------------------------------------------------- +-- Dropdown functions. +------------------------------------------------------------------------------------- + +-- ********************************************************************************** +-- Initializes all the dropdowns. +-- ********************************************************************************** +function MikSBTOpt.InitDropdowns() + -- Setup the available fonts with the inherit option. + availableFontsInherit = MikSBT.CopyTable(MikSBT.AVAILABLE_FONTS); + table.insert(availableFontsInherit, 1, {Name=MikSBTOpt.MSG_INHERIT_TEXT}); + for key, data in availableFontsInherit do + data.Value = key - 1; + end + + -- Setup the available font outlines with the inherit option. + availableOutlinesInherit = MikSBT.CopyTable(MikSBT.AVAILABLE_OUTLINES); + table.insert(availableOutlinesInherit, 1, {Name=MikSBTOpt.MSG_INHERIT_TEXT}); + for key, data in availableOutlinesInherit do + data.Value = key - 1; + end + + -- Setup the available profiles. + local availableProfiles = {}; + for profileName, _ in MikSBT_Save.Profiles do + availableProfiles[profileName] = {Name=profileName}; + end + + -- Setup the available scroll areas. + local availableScrollAreas = {}; + availableScrollAreas["Incoming"] = {Name=MikSBTOpt.TABS[TAB_INDEX_INCOMING].Label}; + availableScrollAreas["Outgoing"] = {Name=MikSBTOpt.TABS[TAB_INDEX_OUTGOING].Label}; + availableScrollAreas["Notification"] = {Name=MikSBTOpt.TABS[TAB_INDEX_NOTIFICATION].Label}; + + + + -- Initialize the profile dropdown. + local key = "Tab1FrameProfileDropdown"; + MikSBTOpt.SetupDropdown(OPTIONS_FRAME_NAME .. key, MikSBTOpt.DROPDOWNS[key].Label, MikSBTOpt.DROPDOWNS[key].Tooltip, MikSBTOpt.ProfileDropdownOnClick, availableProfiles, nil); + MikSBTOpt.PopulateDropdown(OPTIONS_FRAME_NAME .. key, MikSBT_Save.CurrentProfile); + + + -- Initialize the scroll area dropdown. + key = "ScrollAreaDropdown"; + MikSBTOpt.SetupDropdown(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. key, MikSBTOpt.DROPDOWNS[key].Label, MikSBTOpt.DROPDOWNS[key].Tooltip, MikSBTOpt.ScrollAreaDropdownOnClick, availableScrollAreas, nil); + + -- Initialize the text align dropdown. + key = "TextAlignDropdown"; + MikSBTOpt.SetupDropdown(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. key, MikSBTOpt.DROPDOWNS[key].Label, MikSBTOpt.DROPDOWNS[key].Tooltip, MikSBTOpt.DropdownOnClick, MikSBT.AVAILABLE_TEXT_ALIGNS, nil); + + -- Initialize the animation styles dropdown. + key = "AnimationStyleDropdown"; + MikSBTOpt.SetupDropdown(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. key, MikSBTOpt.DROPDOWNS[key].Label, MikSBTOpt.DROPDOWNS[key].Tooltip, MikSBTOpt.DropdownOnClick, MikSBT.AVAILABLE_ANIMATION_STYLES, nil); + + -- Initialize the scroll direction dropdown. + key = "ScrollDirectionDropdown"; + MikSBTOpt.SetupDropdown(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. key, MikSBTOpt.DROPDOWNS[key].Label, MikSBTOpt.DROPDOWNS[key].Tooltip, MikSBTOpt.DropdownOnClick, MikSBT.AVAILABLE_SCROLL_DIRECTIONS, nil); + + -- Initialize the trigger types dropdown. + key = "TriggerTypeDropdown"; + MikSBTOpt.SetupDropdown(TRIGGER_CONFIGURATION_FRAME_NAME .. key, MikSBTOpt.DROPDOWNS[key].Label, MikSBTOpt.DROPDOWNS[key].Tooltip, MikSBTOpt.TriggerTypeDropdownOnClick, MikSBT.AVAILABLE_TRIGGER_TYPES, nil); + UIDropDownMenu_SetWidth(150, getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. key)); +end + + +-- ********************************************************************************** +-- Sets up a dropdown with the passed information. +-- ********************************************************************************** +function MikSBTOpt.SetupDropdown(frameName, label, tooltip, clickFunc, options, varPath) + local associatedFrame = getglobal(frameName); + + -- Make sure the associated frame exists. + if (associatedFrame) then + associatedFrame.tooltipText = tooltip; + associatedFrame.clickFunction = clickFunc; + associatedFrame.menuOptions = options; + associatedFrame.associatedVarPath = varPath; + + -- Set the label for the dropdown. + getglobal(frameName .. "Label"):SetText(label); + + -- Initialize the dropdown. + UIDropDownMenu_Initialize(associatedFrame, MikSBTOpt.DropdownInit); + end +end + + +-- ********************************************************************************** +-- Sets the dropdown's selected value for the passed frame name. If a value is passed +-- it is used, otherwise the function will attempt to get the value from the +-- associatedVarPath field of the dropdown frame. +-- ********************************************************************************** +function MikSBTOpt.PopulateDropdown(frameName, selectValue) + local associatedFrame = getglobal(frameName); + + -- Make sure the associated frame exists. + if (associatedFrame) then + local tempValue = selectValue; + + -- Check if no selected value was passed. + if (tempValue == nil) then + -- Check if there is an associated variable path for the dropdown. + if (associatedFrame.associatedVarPath) then + -- Get the selected value from the current profile. + tempValue = MikSBT.GetOptionFromVarPath(associatedFrame.associatedVarPath); + end + end + + -- Make sure there is a value to be selected. + if (tempValue ~= nil) then + -- Set the default selected value. + UIDropDownMenu_SetSelectedValue(associatedFrame, tempValue); + + -- Set the text for the default selected value. + for key, optionData in associatedFrame.menuOptions do + -- If there is no value for the option data, use the key as the value. + local optionValue = optionData.Value; + if (optionValue == nil) then + optionValue = key; + end + local selectedValue = associatedFrame.selectedValue; + + if (optionValue == selectedValue) then + UIDropDownMenu_SetText(optionData.Name, associatedFrame); + end + end + end + end +end + + +-- ********************************************************************************** +-- Called when a drop down menu is initialized (shown). +-- ********************************************************************************** +function MikSBTOpt.DropdownInit() + local info = {}; + + -- Check if the dropdown frame is the options frame and exit. + local dropdownFrame = this; + if (dropdownFrame:GetName() == OPTIONS_FRAME_NAME) then + return; + end + + -- Check if dropdownFrame is a button and not the actual dropdown itself. + if (not dropdownFrame.menuOptions) then + dropdownFrame = this:GetParent(); + end + + -- Make sure there is dropdown data. + if (dropdownFrame.menuOptions) then + -- Loop through all of the options for dropdown. + for key, optionData in dropdownFrame.menuOptions do + + -- If the option data has a value use it otherwise use the key as the value. + local tempValue = optionData.Value; + if (tempValue == nil) then + tempValue = key; + end + + -- Add the option to the dropdown list. + info = {}; + info.text = optionData.Name; + info.value = tempValue; + info.func = dropdownFrame.clickFunction; + info.arg1 = dropdownFrame:GetName(); + UIDropDownMenu_AddButton(info); + end + end +end + + +-- ********************************************************************************** +-- Called when one of the dropdown menu options is clicked. +-- ********************************************************************************** +function MikSBTOpt.DropdownOnClick(frameName) + -- Set the selected dropdown option to the appropriate value. + UIDropDownMenu_SetSelectedValue(getglobal(frameName), this.value); + + -- Get the associated variable path. + local associatedVarPath = getglobal(frameName).associatedVarPath; + + -- Make sure there is a variable path. + if (associatedVarPath) then + -- Update current profile data. + MikSBT.SetOptionFromVarPath(associatedVarPath, this.value); + end +end + + +-- ********************************************************************************** +-- Called when one of the dropdown menu options on the font settings frame is clicked. +-- ********************************************************************************** +function MikSBTOpt.FontSettingsDropdownOnClick(frameName) + -- Call the normal dropdown OnClick handler. + MikSBTOpt.DropdownOnClick(frameName); + + -- Update the font previews. + MikSBTOpt.UpdateFontPreviews(); +end + + +-- ********************************************************************************** +-- Called when one of the profile dropdown menu options is clicked. +-- ********************************************************************************** +function MikSBTOpt.ProfileDropdownOnClick(frameName) + -- Call the normal dropdown OnClick handler. + MikSBTOpt.DropdownOnClick(frameName); + + -- Enable and disable the load and delete profile buttons. + MikSBTOpt.EnableDisableProfileButtons(); +end + + +-- ********************************************************************************** +-- Called when one of the scroll area dropdown menu options is clicked. +-- ********************************************************************************** +function MikSBTOpt.ScrollAreaDropdownOnClick(frameName) + -- Save the settings in the controls to the control frame's current settings. + MikSBTOpt.SaveScrollAreaControlsToCurrentSettings(); + + -- Call the normal dropdown OnClick handler. + MikSBTOpt.DropdownOnClick(frameName); + + -- Get the selected scroll area. + scrollArea = UIDropDownMenu_GetSelectedValue(getglobal(frameName)); + if (scrollArea ~= nil) then + -- Populate the controls for the scroll area. + MikSBTOpt.PopulateScrollAreaControls(scrollArea); + end +end + +-- ********************************************************************************** +-- Called when the trigger type dropdown menu is clicked. +-- ********************************************************************************** +function MikSBTOpt.TriggerTypeDropdownOnClick(frameName) + -- Set the selected dropdown option to the appropriate value. + UIDropDownMenu_SetSelectedValue(getglobal(frameName), this.value); + + -- Setup the trigger controls appropriately depending on the trigger type. + MikSBTOpt.SetupVariableTriggerControls(getglobal(frameName):GetParent().TriggerKey, this.value == MikCEH.TRIGGERTYPE_SEARCH_PATTERN); +end + + +-- ********************************************************************************** +-- This function refreshes the options for the profiles dropdown. +-- ********************************************************************************** +function MikSBTOpt.RefreshProfilesDropdown() + -- Setup the available profiles. + local availableProfiles = {}; + for profileName, _ in MikSBT_Save.Profiles do + availableProfiles[profileName] = {Name=profileName}; + end + + -- Reset the available options for the profiles dropdown. + getglobal(OPTIONS_FRAME_NAME .. "Tab1FrameProfileDropdown").menuOptions = availableProfiles; +end + + + +------------------------------------------------------------------------------------- +-- Checkbox functions. +------------------------------------------------------------------------------------- + +-- ********************************************************************************** +-- Initializes all the checkboxes. +-- ********************************************************************************** +function MikSBTOpt.InitCheckboxes() + -- Initialize the Disable MSBT checkbox. + local key = "Tab1FrameDisableCheckbox"; + MikSBTOpt.SetupCheckbox(OPTIONS_FRAME_NAME .. key, MikSBTOpt.CHECKBOXES[key].Label, MikSBTOpt.CHECKBOXES[key].Tooltip, nil); + MikSBTOpt.PopulateCheckbox(OPTIONS_FRAME_NAME .. key, MikSBT_Save.UserDisabled); + + -- Initialize the Show Partial Effects checkbox. + key = "Tab1FrameShowPartialEffectsCheckbox"; + MikSBTOpt.SetupCheckbox(OPTIONS_FRAME_NAME .. key, MikSBTOpt.CHECKBOXES[key].Label, MikSBTOpt.CHECKBOXES[key].Tooltip, "ShowPartialEffects"); + + -- Initialize the Use Sticky Crits checkbox. + key = "Tab1FrameUseStickyCritsCheckbox"; + MikSBTOpt.SetupCheckbox(OPTIONS_FRAME_NAME .. key, MikSBTOpt.CHECKBOXES[key].Label, MikSBTOpt.CHECKBOXES[key].Tooltip, "UseStickyCrits"); + + -- Initialize the Show Overheals checkbox. + key = "Tab1FrameShowOverhealsCheckbox"; + MikSBTOpt.SetupCheckbox(OPTIONS_FRAME_NAME .. key, MikSBTOpt.CHECKBOXES[key].Label, MikSBTOpt.CHECKBOXES[key].Tooltip, "ShowOverheals"); + + -- Initialize the Show Game Damage checkbox. + key = "Tab1FrameShowGameDamageCheckbox"; + MikSBTOpt.SetupCheckbox(OPTIONS_FRAME_NAME .. key, MikSBTOpt.CHECKBOXES[key].Label, MikSBTOpt.CHECKBOXES[key].Tooltip, "ShowGameDamage"); + + + -- Initialize the show scroll area events checkboxes. + key = "Tab2FrameShowEventsCheckbox"; MikSBTOpt.SetupCheckbox(OPTIONS_FRAME_NAME .. key, MikSBTOpt.CHECKBOXES[key].Label, MikSBTOpt.CHECKBOXES[key].Tooltip, "DisplaySettings.Incoming.Show"); + key = "Tab3FrameShowEventsCheckbox"; MikSBTOpt.SetupCheckbox(OPTIONS_FRAME_NAME .. key, MikSBTOpt.CHECKBOXES[key].Label, MikSBTOpt.CHECKBOXES[key].Tooltip, "DisplaySettings.Outgoing.Show"); + key = "Tab4FrameShowEventsCheckbox"; MikSBTOpt.SetupCheckbox(OPTIONS_FRAME_NAME .. key, MikSBTOpt.CHECKBOXES[key].Label, MikSBTOpt.CHECKBOXES[key].Tooltip, "DisplaySettings.Notification.Show"); + + + -- Initialize the trigger config class checkboxes. + MikSBTOpt.SetupCheckbox(TRIGGER_CONFIGURATION_FRAME_NAME .. "AllClassesCheckbox", ALL, nil, nil); + MikSBTOpt.SetupCheckbox(TRIGGER_CONFIGURATION_FRAME_NAME .. "DruidCheckbox", MikSBTOpt.MSG_CLASS_NAME_DRUID, nil, nil); + MikSBTOpt.SetupCheckbox(TRIGGER_CONFIGURATION_FRAME_NAME .. "HunterCheckbox", MikSBTOpt.MSG_CLASS_NAME_HUNTER, nil, nil); + MikSBTOpt.SetupCheckbox(TRIGGER_CONFIGURATION_FRAME_NAME .. "MageCheckbox", MikSBTOpt.MSG_CLASS_NAME_MAGE, nil, nil); + MikSBTOpt.SetupCheckbox(TRIGGER_CONFIGURATION_FRAME_NAME .. "PaladinCheckbox", MikSBTOpt.MSG_CLASS_NAME_PALADIN, nil, nil); + MikSBTOpt.SetupCheckbox(TRIGGER_CONFIGURATION_FRAME_NAME .. "PriestCheckbox", MikSBTOpt.MSG_CLASS_NAME_PRIEST, nil, nil); + MikSBTOpt.SetupCheckbox(TRIGGER_CONFIGURATION_FRAME_NAME .. "RogueCheckbox", MikSBTOpt.MSG_CLASS_NAME_ROGUE, nil, nil); + MikSBTOpt.SetupCheckbox(TRIGGER_CONFIGURATION_FRAME_NAME .. "ShamanCheckbox", MikSBTOpt.MSG_CLASS_NAME_SHAMAN, nil, nil); + MikSBTOpt.SetupCheckbox(TRIGGER_CONFIGURATION_FRAME_NAME .. "WarlockCheckbox", MikSBTOpt.MSG_CLASS_NAME_WARLOCK, nil, nil); + MikSBTOpt.SetupCheckbox(TRIGGER_CONFIGURATION_FRAME_NAME .. "WarriorCheckbox", MikSBTOpt.MSG_CLASS_NAME_WARRIOR, nil, nil); + +end + + +-- ********************************************************************************** +-- Sets up a checkbox with the passed information. +-- ********************************************************************************** +function MikSBTOpt.SetupCheckbox(frameName, label, tooltip, varPath) + local associatedFrame = getglobal(frameName); + + -- Make sure the associated frame exists. + if (associatedFrame) then + associatedFrame.associatedVarPath = varPath; + associatedFrame.tooltipText = tooltip; + + -- Set the text for the checkbox. + if (label) then + getglobal(frameName .. "Text"):SetText(label); + end + end +end + + +-- ********************************************************************************** +-- Sets the checkbox's checked state for the passed frame name. If a value is passed +-- it is used, otherwise the function will attempt to get the value from the +-- associatedVarPath field of the checkbox frame. +-- ********************************************************************************** +function MikSBTOpt.PopulateCheckbox(frameName, isChecked) + local associatedFrame = getglobal(frameName); + + -- Make sure the associated frame exists. + if (associatedFrame) then + local tempValue = isChecked; + + -- Check if no value was passed. + if (tempValue == nil) then + -- Check if there is an associated variable path for the checkbox. + if (associatedFrame.associatedVarPath) then + -- Get the selected value from the current profile. + tempValue = MikSBT.GetOptionFromVarPath(associatedFrame.associatedVarPath); + end + end + + -- Make sure there is a value to set. + if (tempValue ~= nil) then + -- Set the checkbox checked state appropriately. + if (tempValue == true) then + associatedFrame:SetChecked(1); + else + associatedFrame:SetChecked(0); + end + end + end +end + + +-- ********************************************************************************** +-- Called when a checkbox is clicked. +-- ********************************************************************************** +function MikSBTOpt.CheckboxOnClick() + -- Disable MSBT checkbox. + if (this:GetName() == OPTIONS_FRAME_NAME .. "Tab1FrameDisableCheckbox") then + -- Check if the checkbox is checked. + if (this:GetChecked() == 1) then + MikSBT.SetOptionUserDisabled(true); + else + MikSBT.SetOptionUserDisabled(false); + end + + -- Return from the function. + return; + + -- Show Game Damage checkbox. + elseif (this:GetName() == OPTIONS_FRAME_NAME .. "Tab1FrameShowGameDamageCheckbox") then + -- Check if the checkbox is checked. + if (this:GetChecked() == 1) then + MikSBT.SetOptionShowGameDamage(true); + else + MikSBT.SetOptionShowGameDamage(false); + end + + -- Return from the function. + return; + + -- Inherit font size, or inherit critical font size checkbox. + elseif (this:GetName() == FONT_SETTINGS_FRAME_NAME .. "InheritFontSizeCheckbox" or + this:GetName() == FONT_SETTINGS_FRAME_NAME .. "InheritFontSizeCritCheckbox") then + + -- Call the font settings checkbox OnClick handler. + MikSBTOpt.FontSettingsCheckboxOnClick(); + + -- Return from the function. + return; + + -- Trigger frame all classes checkbox. + elseif (this:GetName() == TRIGGER_CONFIGURATION_FRAME_NAME .. "AllClassesCheckbox") then + -- Hide or show the individual class checkboxes depending on the state of the all classes + -- checkbox. + if (this:GetChecked() == 1) then + MikSBTOpt.HideTriggerClassCheckboxes(); + else + MikSBTOpt.ShowTriggerClassCheckboxes(); + end + + --Trigger frame trigger event checkbox. + elseif (string.find(this:GetName(), TRIGGER_CONFIGURATION_FRAME_NAME .. "TriggerEvent")) then + -- Make sure there is an associated trigger event. + if (this.TriggerEvent) then + local triggerFrame = getglobal(TRIGGER_CONFIGURATION_FRAME_NAME); + if (this:GetChecked()) then + triggerFrame.SelectedTriggerEvents[this.TriggerEvent] = true; + else + triggerFrame.SelectedTriggerEvents[this.TriggerEvent] = nil; + end + end + + end + + -- Check if there is an associated variable path and set it to the correct value. + if (this.associatedVarPath) then + if (this:GetChecked() == 1) then + -- Set the associated variable in the current profile to the inherited value. + MikSBT.SetOptionFromVarPath(this.associatedVarPath, true); + else + -- Set the associated variable in the current profile to the inherited value. + MikSBT.SetOptionFromVarPath(this.associatedVarPath, false); + end + end +end + + +-- ********************************************************************************** +-- Called when an enable trigger checkbox is clicked. +-- ********************************************************************************** +function MikSBTOpt.EnableTriggerCheckboxOnClick() + -- Check if there is an associated variable path and set it to the correct value. + if (this.associatedVarPath) then + if (this:GetChecked() == 1) then + -- Set the associated variable in the current profile to the inherited value. + MikSBT.SetOptionFromVarPath(this.associatedVarPath, true); + else + -- Set the associated variable in the current profile to the inherited value. + MikSBT.SetOptionFromVarPath(this.associatedVarPath, false); + end + end + + -- Reregister all of the triggers. + MikSBT.RegisterTriggers(); +end + + +-- ********************************************************************************** +-- Called when a checkbox in the font settings area is clicked. +-- ********************************************************************************** +function MikSBTOpt.FontSettingsCheckboxOnClick() + local associatedSlider; + local inheritedValue; + local sliderKey; + + -- Check if it's the inherit font size checkbox. + if (this:GetName() == FONT_SETTINGS_FRAME_NAME .. "InheritFontSizeCheckbox") then + sliderKey = "FontSizeSlider"; + associatedSlider = getglobal(FONT_SETTINGS_FRAME_NAME .. sliderKey); + inheritedValue = this:GetParent().InheritedFontSize; + elseif (this:GetName() == FONT_SETTINGS_FRAME_NAME .. "InheritFontSizeCritCheckbox") then + sliderKey = "FontSizeCritSlider"; + associatedSlider = getglobal(FONT_SETTINGS_FRAME_NAME .. sliderKey); + inheritedValue = this:GetParent().InheritedFontSizeCrit; + end + + -- Make sure there is an associated variable path. + if (this.associatedVarPath) then + if (this:GetChecked() == 1) then + -- Set the associated variable in the current profile to inherit. + MikSBT.SetOptionFromVarPath(this.associatedVarPath, 0); + + -- Hide the associated slider. + associatedSlider:Hide(); + else + -- Set the associated variable in the current profile to the inherited value. + MikSBT.SetOptionFromVarPath(this.associatedVarPath, inheritedValue); + + -- Show the associated slider. + associatedSlider:Show(); + + -- Populate the slider. + MikSBTOpt.PopulateSlider(FONT_SETTINGS_FRAME_NAME .. sliderKey); + end + end + + -- Update the font previews. + MikSBTOpt.UpdateFontPreviews(); +end + + +------------------------------------------------------------------------------------- +-- Slider functions. +------------------------------------------------------------------------------------- + +-- ********************************************************************************** +-- Initializes all the sliders. +-- ********************************************************************************** +function MikSBTOpt.InitSliders() + -- Initialize the Animation Step slider. + local key = "Tab1FrameAnimationStepSlider"; + MikSBTOpt.SetupSlider(OPTIONS_FRAME_NAME .. key, MikSBTOpt.SLIDERS[key].Label, MikSBTOpt.SLIDERS[key].Tooltip, MIN_ANIMATION_STEP, MAX_ANIMATION_STEP, 1, "AnimationStep"); + + -- Initialize the scroll height slider. + key = "ScrollHeightSlider"; + MikSBTOpt.SetupSlider(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. key, MikSBTOpt.SLIDERS[key].Label, MikSBTOpt.SLIDERS[key].Tooltip, MIN_SCROLL_HEIGHT, MAX_SCROLL_HEIGHT, 2, nil); + + key = "ThresholdSlider"; + MikSBTOpt.SetupSlider(TRIGGER_CONFIGURATION_FRAME_NAME .. key, MikSBTOpt.SLIDERS[key].Label, MikSBTOpt.SLIDERS[key].Tooltip, 1, 100, 1, nil); +end + + +-- ********************************************************************************** +-- Sets up a slider with the passed data. +-- ********************************************************************************** +function MikSBTOpt.SetupSlider(frameName, label, tooltip, minValue, maxValue, step, varPath) + local associatedSliderFrame = getglobal(frameName); + + -- Make sure the associated frame exists. + if (associatedSliderFrame) then + associatedSliderFrame.savedLabel = label; + associatedSliderFrame.tooltipText = tooltip; + associatedSliderFrame.associatedVarPath = varPath; + + -- Set the text for the slider. + getglobal(frameName .. "Text"):SetText(label); + + -- Set the min/max values for the slider. + associatedSliderFrame:SetMinMaxValues(minValue, maxValue); + associatedSliderFrame:SetValueStep(step); + end +end + + +-- ********************************************************************************** +-- Sets the slider's value for the passed frame name. If a value is passed +-- it is used, otherwise the function will attempt to get the value from the +-- associatedVarPath field of the slider frame. +-- ********************************************************************************** +function MikSBTOpt.PopulateSlider(frameName, sliderValue) + local associatedSliderFrame = getglobal(frameName); + + -- Make sure the associated frame exists. + if (associatedSliderFrame) then + local tempValue = sliderValue; + + -- Check if no value was passed. + if (tempValue == nil) then + -- Check if there is an associated variable path for the slider. + if (associatedSliderFrame.associatedVarPath) then + -- Get the selected value from the current profile. + tempValue = MikSBT.GetOptionFromVarPath(associatedSliderFrame.associatedVarPath); + end + end + + -- Make sure there is a value to set. + if (tempValue ~= nil) then + -- Set the slider's value to the appropriate value. + associatedSliderFrame:SetValue(tempValue); + + -- Update the label to reflect the new value. + getglobal(frameName .. "Text"):SetText(associatedSliderFrame.savedLabel .. ": " .. associatedSliderFrame:GetValue()); + end + end +end + + +-- ********************************************************************************** +-- Called when a slider values changes. +-- ********************************************************************************** +function MikSBTOpt.SliderOnValueChanged() + -- Update the label to reflect the new value. + getglobal(this:GetName() .. "Text"):SetText(this.savedLabel .. ": " .. this:GetValue()); + + -- Check if the slider has an associated variable path. + if (this.associatedVarPath) then + -- Update current profile data. + MikSBT.SetOptionFromVarPath(this.associatedVarPath, this:GetValue()); + end +end + + +-- ********************************************************************************** +-- Called when a font settings slider values changes. +-- ********************************************************************************** +function MikSBTOpt.FontSettingsSliderOnValueChanged() + -- Call the normal slider OnValueChanged handler. + MikSBTOpt.SliderOnValueChanged(); + + -- Update the font previews. + MikSBTOpt.UpdateFontPreviews(); +end + + +-- ********************************************************************************** +-- Called when the scroll area mover control slider value changes. +-- ********************************************************************************** +function MikSBTOpt.ScrollAreaMoverControlSliderOnValueChanged() + -- Call the normal slider OnValueChanged handler. + MikSBTOpt.SliderOnValueChanged(); + + -- Get the currently selected scroll area and the scroll area mover control frame. + local scrollArea = UIDropDownMenu_GetSelectedValue(getglobal(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. "ScrollAreaDropdown")); + local controlFrame = getglobal(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME); + + -- Save the scroll height for the selected scroll area. + controlFrame.MSBTCurrentSettings[scrollArea .. "ScrollHeight"] = this:GetValue(); + + -- Reposition the scroll area mover frames. + MikSBTOpt.RepositionScrollAreaMoverFrames(); +end + + +------------------------------------------------------------------------------------- +-- Button Functions. +------------------------------------------------------------------------------------- + +-- ********************************************************************************** +-- Initializes all the buttons. +-- ********************************************************************************** +function MikSBTOpt.InitButtons() + -- Initialize the edit font settings buttons for master, incoming, outgoing, and notification. + local key = "Tab1FrameEditFontSettingsButton"; MikSBTOpt.SetupButton(OPTIONS_FRAME_NAME .. key, MikSBTOpt.BUTTONS[key].Label, MikSBTOpt.BUTTONS[key].Tooltip); + key = "Tab2FrameEditFontSettingsButton"; MikSBTOpt.SetupButton(OPTIONS_FRAME_NAME .. key, MikSBTOpt.BUTTONS[key].Label, MikSBTOpt.BUTTONS[key].Tooltip); + key = "Tab3FrameEditFontSettingsButton"; MikSBTOpt.SetupButton(OPTIONS_FRAME_NAME .. key, MikSBTOpt.BUTTONS[key].Label, MikSBTOpt.BUTTONS[key].Tooltip); + key = "Tab4FrameEditFontSettingsButton"; MikSBTOpt.SetupButton(OPTIONS_FRAME_NAME .. key, MikSBTOpt.BUTTONS[key].Label, MikSBTOpt.BUTTONS[key].Tooltip); + + + -- Initialize the profile manipulation buttons. + key = "Tab1FrameLoadProfileButton"; MikSBTOpt.SetupButton(OPTIONS_FRAME_NAME .. key, MikSBTOpt.BUTTONS[key].Label, MikSBTOpt.BUTTONS[key].Tooltip); + key = "Tab1FrameDeleteProfileButton"; MikSBTOpt.SetupButton(OPTIONS_FRAME_NAME .. key, MikSBTOpt.BUTTONS[key].Label, MikSBTOpt.BUTTONS[key].Tooltip); + key = "Tab1FrameResetProfileButton"; MikSBTOpt.SetupButton(OPTIONS_FRAME_NAME .. key, MikSBTOpt.BUTTONS[key].Label, MikSBTOpt.BUTTONS[key].Tooltip); + key = "Tab1FrameCreateProfileButton"; MikSBTOpt.SetupButton(OPTIONS_FRAME_NAME .. key, MikSBTOpt.BUTTONS[key].Label, MikSBTOpt.BUTTONS[key].Tooltip); + + + -- Initialize the configure scroll area buttons for incoming, outgoing, and notification. + key = "Tab2FrameConfigureScrollAreaButton"; + local commonLabel = MikSBTOpt.BUTTONS[key].Label; + local commonTooltip = MikSBTOpt.BUTTONS[key].Tooltip; + MikSBTOpt.SetupButton(OPTIONS_FRAME_NAME .. key, commonLabel, commonTooltip); + key = "Tab3FrameConfigureScrollAreaButton"; MikSBTOpt.SetupButton(OPTIONS_FRAME_NAME .. key, commonLabel, commonTooltip); + key = "Tab4FrameConfigureScrollAreaButton"; MikSBTOpt.SetupButton(OPTIONS_FRAME_NAME .. key, commonLabel, commonTooltip); + + + -- Initialize the scroll area mover buttons. + key = "PreviewButton"; MikSBTOpt.SetupButton(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. key, MikSBTOpt.BUTTONS[key].Label, MikSBTOpt.BUTTONS[key].Tooltip); + key = "SaveButton"; MikSBTOpt.SetupButton(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. key, MikSBTOpt.BUTTONS[key].Label, MikSBTOpt.BUTTONS[key].Tooltip); + key = "CancelButton"; MikSBTOpt.SetupButton(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. key, MikSBTOpt.BUTTONS[key].Label, MikSBTOpt.BUTTONS[key].Tooltip); + + -- Initialize the add trigger button. + key = "Tab5FrameAddTriggerButton"; MikSBTOpt.SetupButton(OPTIONS_FRAME_NAME .. key, MikSBTOpt.BUTTONS[key].Label, MikSBTOpt.BUTTONS[key].Tooltip); + + -- Initialize the save and cancel trigger buttons. + key = "SaveTriggerButton"; MikSBTOpt.SetupButton(TRIGGER_CONFIGURATION_FRAME_NAME .. key, MikSBTOpt.BUTTONS[key].Label, MikSBTOpt.BUTTONS[key].Tooltip); + key = "CancelTriggerButton"; MikSBTOpt.SetupButton(TRIGGER_CONFIGURATION_FRAME_NAME .. key, MikSBTOpt.BUTTONS[key].Label, MikSBTOpt.BUTTONS[key].Tooltip); + + -- Initialize the add suppression button. + key = "Tab6FrameAddSuppressionButton"; MikSBTOpt.SetupButton(OPTIONS_FRAME_NAME .. key, MikSBTOpt.BUTTONS[key].Label, MikSBTOpt.BUTTONS[key].Tooltip); +end + + +-- ********************************************************************************** +-- Sets up a button with the passed data. +-- ********************************************************************************** +function MikSBTOpt.SetupButton(frameName, label, tooltip) + local associatedFrame = getglobal(frameName); + + -- Make sure the associated frame exists. + if (associatedFrame) then + associatedFrame.tooltipText = tooltip; + + -- Set the text for the button. + associatedFrame:SetText(label); + associatedFrame:SetWidth(associatedFrame:GetTextWidth() + 40); + end +end + + +-- ********************************************************************************** +-- Called when a button is clicked. +-- ********************************************************************************** +function MikSBTOpt.ButtonOnClick() + -- Edit master font settings button. + if (this:GetName() == OPTIONS_FRAME_NAME .. "Tab1FrameEditFontSettingsButton") then + local fontSettingsFrame = getglobal(FONT_SETTINGS_FRAME_NAME); + fontSettingsFrame:SetPoint("TOPLEFT", this, "BOTTOMLEFT"); + fontSettingsFrame:Raise(); + getglobal(FONT_SETTINGS_FRAME_NAME .. "Title"):SetText(MikSBTOpt.FONT_SETTINGS_TOOLTIPS["Master"].FontSettingsTitle); + MikSBTOpt.ShowMasterFontSettings(); + + -- Edit incoming font settings button. + elseif (this:GetName() == OPTIONS_FRAME_NAME .. "Tab2FrameEditFontSettingsButton") then + -- Hide the event message editbox if it's shown. + MikSBTOpt.HideMessageEditbox(OPTIONS_FRAME_NAME .. "Tab2FrameMessageEditbox"); + + -- Get the font settings frame, anchor it to the buton pushed, raise it, and change the title. + local fontSettingsFrame = getglobal(FONT_SETTINGS_FRAME_NAME); + fontSettingsFrame:SetPoint("TOPLEFT", this, "BOTTOMLEFT"); + fontSettingsFrame:Raise(); + getglobal(FONT_SETTINGS_FRAME_NAME .. "Title"):SetText(MikSBTOpt.TABS[TAB_INDEX_INCOMING].Label); + MikSBTOpt.ShowScrollAreaFontSettings("Incoming"); + + + -- Edit outgoing font settings button. + elseif (this:GetName() == OPTIONS_FRAME_NAME .. "Tab3FrameEditFontSettingsButton") then + -- Hide the event message editbox if it's shown. + MikSBTOpt.HideMessageEditbox(OPTIONS_FRAME_NAME .. "Tab3FrameMessageEditbox"); + + -- Get the font settings frame, anchor it to the buton pushed, raise it, and change the title. + local fontSettingsFrame = getglobal(FONT_SETTINGS_FRAME_NAME); + fontSettingsFrame:SetPoint("TOPLEFT", this, "BOTTOMLEFT"); + fontSettingsFrame:Raise(); + getglobal(FONT_SETTINGS_FRAME_NAME .. "Title"):SetText(MikSBTOpt.TABS[TAB_INDEX_OUTGOING].Label); + MikSBTOpt.ShowScrollAreaFontSettings("Outgoing"); + + + -- Edit notification font settings button. + elseif (this:GetName() == OPTIONS_FRAME_NAME .. "Tab4FrameEditFontSettingsButton") then + -- Hide the event message editbox if it's shown. + MikSBTOpt.HideMessageEditbox(OPTIONS_FRAME_NAME .. "Tab4FrameMessageEditbox"); + + -- Get the font settings frame, anchor it to the buton pushed, raise it, and change the title. + local fontSettingsFrame = getglobal(FONT_SETTINGS_FRAME_NAME); + fontSettingsFrame:SetPoint("TOPLEFT", this, "BOTTOMLEFT"); + fontSettingsFrame:Raise(); + getglobal(FONT_SETTINGS_FRAME_NAME .. "Title"):SetText(MikSBTOpt.TABS[TAB_INDEX_NOTIFICATION].Label); + MikSBTOpt.ShowScrollAreaFontSettings("Notification"); + + + -- Load profile button. + elseif (this:GetName() == OPTIONS_FRAME_NAME .. "Tab1FrameLoadProfileButton") then + -- Select the appropriate profile and update the current profile label. + MikSBT.SelectProfile(UIDropDownMenu_GetSelectedValue(getglobal(OPTIONS_FRAME_NAME .. "Tab1FrameProfileDropdown"))); + getglobal(OPTIONS_FRAME_NAME .. "Tab1FrameCurrentProfileLabel"):SetText(MikSBTOpt.MSG_CURRENT_PROFILE_TEXT .. ": " .. MikSBT_Save.CurrentProfile); + + -- Enable and disable the load and delete profile buttons. + MikSBTOpt.EnableDisableProfileButtons(); + + -- Repopulate the options. + MikSBTOpt.PopulateProfileOptions(); + + + -- Delete profile button. + elseif (this:GetName() == OPTIONS_FRAME_NAME .. "Tab1FrameDeleteProfileButton") then + local profileName = UIDropDownMenu_GetSelectedValue(getglobal(OPTIONS_FRAME_NAME .. "Tab1FrameProfileDropdown")); + MikSBT.DeleteProfile(profileName); + + -- Refresh the available profiles for the dropdown. + MikSBTOpt.RefreshProfilesDropdown(); + + -- Select the current profile in the dropdown and update the current profile label. + MikSBTOpt.PopulateDropdown(OPTIONS_FRAME_NAME .. "Tab1FrameProfileDropdown", MikSBT_Save.CurrentProfile); + getglobal(OPTIONS_FRAME_NAME .. "Tab1FrameCurrentProfileLabel"):SetText(MikSBTOpt.MSG_CURRENT_PROFILE_TEXT .. ": " .. MikSBT_Save.CurrentProfile); + + -- Enable and disable the load and delete profile buttons. + MikSBTOpt.EnableDisableProfileButtons(); + + -- Repopulate the options. + MikSBTOpt.PopulateProfileOptions(); + + -- Reset profile button. + elseif (this:GetName() == OPTIONS_FRAME_NAME .. "Tab1FrameResetProfileButton") then + local profileName = UIDropDownMenu_GetSelectedValue(getglobal(OPTIONS_FRAME_NAME .. "Tab1FrameProfileDropdown")); + MikSBT.ResetProfile(profileName, true); + + -- Repopulate the options. + MikSBTOpt.PopulateProfileOptions(); + + + -- Create profile button. + elseif (this:GetName() == OPTIONS_FRAME_NAME .. "Tab1FrameCreateProfileButton") then + local profileNameEditbox = getglobal(OPTIONS_FRAME_NAME .. "Tab1FrameNewProfileNameEditbox"); + local profileName = profileNameEditbox:GetText(); + + -- Clear the text in the profile name editbox. + profileNameEditbox:SetText(""); + + -- Make sure there is a profile name. + if (profileName ~= "") then + MikSBT.CreateProfile(profileName); + + -- Refresh the available profiles for the dropdown. + MikSBTOpt.RefreshProfilesDropdown(); + + -- Enable and disable the load and delete profile buttons. + MikSBTOpt.EnableDisableProfileButtons(); + + -- Hide the font settings frame when profile options are populated. + getglobal(FONT_SETTINGS_FRAME_NAME):Hide(); + + -- Hide the trigger frame when profile options are populated. + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME):Hide(); + end + + + -- Configure incoming scroll area button. + elseif (this:GetName() == OPTIONS_FRAME_NAME .. "Tab2FrameConfigureScrollAreaButton") then + -- Setup and show the scroll area mover frames. + MikSBTOpt.ShowScrollAreaMoverFrames("Incoming"); + + + -- Configure outgoing scroll area button. + elseif (this:GetName() == OPTIONS_FRAME_NAME .. "Tab3FrameConfigureScrollAreaButton") then + -- Setup and show the scroll area mover frames. + MikSBTOpt.ShowScrollAreaMoverFrames("Outgoing"); + + + -- Configure notification scroll area button. + elseif (this:GetName() == OPTIONS_FRAME_NAME .. "Tab4FrameConfigureScrollAreaButton") then + -- Setup and show the scroll area mover frames. + MikSBTOpt.ShowScrollAreaMoverFrames("Notification"); + + + -- Scroll area mover preview button. + elseif (this:GetName() == SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. "PreviewButton") then + -- Preview a test message in the new position. + MikSBTOpt.ScrollAreaMoverPreviewOnClick(); + + + -- Scroll area mover save button. + elseif (this:GetName() == SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. "SaveButton") then + -- Save the new position for the scroll area. + MikSBTOpt.ScrollAreaMoverSaveOnClick(); + + + -- Scroll area mover cancel button. + elseif (this:GetName() == SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. "CancelButton") then + -- Cancel the scroll area movement. + MikSBTOpt.ScrollAreaMoverCancelOnClick(); + + + -- Incoming event font settings button. + elseif (this:GetParent().EventArea == "Incoming") then + -- Hide the event message editbox if it's shown. + MikSBTOpt.HideMessageEditbox(OPTIONS_FRAME_NAME .. "Tab2FrameMessageEditbox"); + + local fontSettingsFrame = getglobal(FONT_SETTINGS_FRAME_NAME); + fontSettingsFrame:SetPoint("TOPLEFT", this, "BOTTOMLEFT"); + fontSettingsFrame:Raise(); + + -- Make sure the event type is set for the button. + if (this:GetParent().EventType ~= nil) then + getglobal(FONT_SETTINGS_FRAME_NAME .. "Title"):SetText(this:GetParent().FontFrameTitle); + MikSBTOpt.ShowEventFontSettings("Incoming", this:GetParent().EventType); + end + + + -- Outgoing event font settings button. + elseif (this:GetParent().EventArea == "Outgoing") then + -- Hide the event message editbox if it's shown. + MikSBTOpt.HideMessageEditbox(OPTIONS_FRAME_NAME .. "Tab3FrameMessageEditbox"); + + local fontSettingsFrame = getglobal(FONT_SETTINGS_FRAME_NAME); + fontSettingsFrame:SetPoint("TOPLEFT", this, "BOTTOMLEFT"); + fontSettingsFrame:Raise(); + + -- Make sure the event type is set for the button. + if (this:GetParent().EventType ~= nil) then + getglobal(FONT_SETTINGS_FRAME_NAME .. "Title"):SetText(this:GetParent().FontFrameTitle); + MikSBTOpt.ShowEventFontSettings("Outgoing", this:GetParent().EventType); + end + + + -- Notification event font settings button. + elseif (this:GetParent().EventArea == "Notification") then + -- Hide the event message editbox if it's shown. + MikSBTOpt.HideMessageEditbox(OPTIONS_FRAME_NAME .. "Tab4FrameMessageEditbox"); + + local fontSettingsFrame = getglobal(FONT_SETTINGS_FRAME_NAME); + fontSettingsFrame:SetPoint("TOPLEFT", this, "BOTTOMLEFT"); + fontSettingsFrame:Raise(); + + -- Make sure the event type is set for the button. + if (this:GetParent().EventType ~= nil) then + getglobal(FONT_SETTINGS_FRAME_NAME .. "Title"):SetText(this:GetParent().FontFrameTitle); + MikSBTOpt.ShowEventFontSettings("Notification", this:GetParent().EventType); + end + + + -- Add trigger button. + elseif (this:GetName() == OPTIONS_FRAME_NAME .. "Tab5FrameAddTriggerButton") then + -- Hide the trigger configuration frame. + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME):Hide(); + + -- Add a new trigger. + MikSBTOpt.AddNewTrigger(); + + + -- Trigger event font settings button. + elseif (this:GetParent().EventArea == "Trigger" and string.find(this:GetName(), "EditFontSettingsButton")) then + -- Hide the trigger event message editbox if it's shown. + MikSBTOpt.HideMessageEditbox(OPTIONS_FRAME_NAME .. "Tab5FrameMessageEditbox"); + + local fontSettingsFrame = getglobal(FONT_SETTINGS_FRAME_NAME); + fontSettingsFrame:SetPoint("TOPLEFT", this, "BOTTOMLEFT"); + fontSettingsFrame:Raise(); + + -- Make sure the trigger key is set for the button. + if (this:GetParent().TriggerKey ~= nil) then + getglobal(FONT_SETTINGS_FRAME_NAME .. "Title"):SetText(this:GetParent().FontFrameTitle); + MikSBTOpt.ShowTriggerFontSettings(this:GetParent().TriggerKey); + end + + + -- Trigger edit config button. + elseif (this:GetParent().EventArea == "Trigger" and string.find(this:GetName(), "EditTriggerSettingsButton")) then + -- Hide the trigger event message editbox if it's shown. + MikSBTOpt.HideMessageEditbox(OPTIONS_FRAME_NAME .. "Tab5FrameMessageEditbox"); + + local triggerConfigFrame = getglobal(TRIGGER_CONFIGURATION_FRAME_NAME); + triggerConfigFrame:SetPoint("TOPLEFT", this, "BOTTOMLEFT"); + triggerConfigFrame:Raise(); + + -- Make sure the trigger key is set for the button. + if (this:GetParent().TriggerKey ~= nil) then + MikSBTOpt.ShowTriggerConfig(this:GetParent().TriggerKey); + end + + + -- Delete trigger button. + elseif (string.find(this:GetName(), "DeleteTriggerButton")) then + -- Hide the trigger event message editbox if it's shown. + MikSBTOpt.HideMessageEditbox(OPTIONS_FRAME_NAME .. "Tab5FrameMessageEditbox"); + + -- Hide the trigger configuration frame. + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME):Hide(); + + -- Make sure the trigger key is set for the button. + if (this:GetParent().TriggerKey ~= nil) then + MikSBTOpt.DeleteTrigger(this:GetParent().TriggerKey); + end + + + -- Save trigger config button. + elseif (this:GetName() == TRIGGER_CONFIGURATION_FRAME_NAME .. "SaveTriggerButton") then + -- Save the trigger config and hide the frame. + MikSBTOpt.SaveTriggerConfig(); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME):Hide(); + + -- Cancel trigger config button. + elseif (this:GetName() == TRIGGER_CONFIGURATION_FRAME_NAME .. "CancelTriggerButton") then + -- Hide the frame. + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME):Hide(); + + + -- Add suppression button. + elseif (this:GetName() == OPTIONS_FRAME_NAME .. "Tab6FrameAddSuppressionButton") then + -- Add a new suppression. + MikSBTOpt.AddNewSuppression(); + + -- Delete suppression button. + elseif (string.find(this:GetName(), "DeleteSuppressionButton")) then + -- Hide the suppression event message editbox if it's shown. + MikSBTOpt.HideMessageEditbox(OPTIONS_FRAME_NAME .. "Tab6FrameMessageEditbox"); + + -- Make sure the suppression key is set for the button. + local suppressionKey = this:GetParent().SuppressionKey; + if (suppressionKey ~= nil) then + -- Remove the suppression. + MikSBT.CurrentProfile.Suppressions[suppressionKey] = nil; + + -- Repopulate the suppression settings. + MikSBTOpt.PopulateSuppressionSettings(); + end + + end +end + + + + +-- ********************************************************************************** +-- This function will enable and disable the load and delete profile +-- buttons according to which profile is selected. +-- ********************************************************************************** +function MikSBTOpt.EnableDisableProfileButtons() + local profileDropdown = getglobal(OPTIONS_FRAME_NAME .. "Tab1FrameProfileDropdown"); + local deleteProfileButton = getglobal(OPTIONS_FRAME_NAME .. "Tab1FrameDeleteProfileButton"); + local loadProfileButton = getglobal(OPTIONS_FRAME_NAME .. "Tab1FrameLoadProfileButton"); + + -- Enable the profile button manipulation buttons. + deleteProfileButton:Enable(); + loadProfileButton:Enable(); + + -- Check if the default profile is selected and disable the delete profile button. + if (UIDropDownMenu_GetSelectedValue(profileDropdown) == MikSBT.DEFAULT_PROFILE_NAME) then + deleteProfileButton:Disable(); + end + + -- Check if it's the currently loaded profile and disable the load button. + if (UIDropDownMenu_GetSelectedValue(profileDropdown) == MikSBT_Save.CurrentProfile) then + loadProfileButton:Disable(); + end +end + + +------------------------------------------------------------------------------------- +-- Editbox Functions. +------------------------------------------------------------------------------------- + +-- ********************************************************************************** +-- Initializes all the editboxes. +-- ********************************************************************************** +function MikSBTOpt.InitEditboxes() + -- Setup the new profile name editbox. + local key = "Tab1FrameNewProfileNameEditbox"; + MikSBTOpt.SetupEditbox(OPTIONS_FRAME_NAME .. key, MikSBTOpt.EDITBOXES[key].Label, MikSBTOpt.EDITBOXES[key].Tooltip, nil); + + -- Setup the scroll area X and Y offset editboxes. + key = "XOffsetEditbox"; MikSBTOpt.SetupEditbox(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. key, MikSBTOpt.EDITBOXES[key].Label, MikSBTOpt.EDITBOXES[key].Tooltip, nil); + key = "YOffsetEditbox"; MikSBTOpt.SetupEditbox(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. key, MikSBTOpt.EDITBOXES[key].Label, MikSBTOpt.EDITBOXES[key].Tooltip, nil); + + key = "SearchPattern1Editbox"; MikSBTOpt.SetupEditbox(TRIGGER_CONFIGURATION_FRAME_NAME .. key, MikSBTOpt.EDITBOXES[key].Label, MikSBTOpt.EDITBOXES[key].Tooltip, nil); + key = "SearchPattern2Editbox"; MikSBTOpt.SetupEditbox(TRIGGER_CONFIGURATION_FRAME_NAME .. key, MikSBTOpt.EDITBOXES[key].Label, MikSBTOpt.EDITBOXES[key].Tooltip, nil); +end + + +-- ********************************************************************************** +-- Sets up an editbox with the passed data. +-- ********************************************************************************** +function MikSBTOpt.SetupEditbox(frameName, label, tooltip, varPath) + local associatedFrame = getglobal(frameName); + + -- Make sure the associated frame exists. + if (associatedFrame) then + associatedFrame.tooltipText = tooltip; + associatedFrame.associatedVarPath = varPath; + + -- Set the label for the editbox. + getglobal(frameName .. "Label"):SetText(label); + end +end + + +-- ********************************************************************************** +-- Sets the editbox's text for the passed frame name. If a value is passed +-- it is used, otherwise the function will attempt to get the value from the +-- associatedVarPath field of the editbox frame. +-- ********************************************************************************** +function MikSBTOpt.PopulateEditbox(frameName, editboxValue) + local associatedFrame = getglobal(frameName); + + -- Make sure the associated frame exists. + if (associatedFrame) then + local tempValue = editboxValue; + + -- Check if no value was passed. + if (tempValue == nil) then + -- Check if there is an associated variable path for the editbox. + if (associatedFrame.associatedVarPath) then + tempValue = MikSBT.GetOptionFromVarPath(associatedFrame.associatedVarPath); + end + end + + -- Make sure there is a value to set. + if (tempValue) then + -- Set the value. + associatedFrame:SetText(tempValue); + end + end +end + + +-- ********************************************************************************** +-- Called when the text changes in an edit box. +-- ********************************************************************************** +function MikSBTOpt.EditboxOnTextChanged() + -- New Profile Name. + if (this:GetName() == OPTIONS_FRAME_NAME .. "Tab1FrameNewProfileNameEditbox") then + local createProfileButton = getglobal(OPTIONS_FRAME_NAME .. "Tab1FrameCreateProfileButton"); + + -- Enable the create profile button. + createProfileButton:Enable(); + + -- Check if there is no text and disable the create profile button. + if (this:GetText() == "") then + createProfileButton:Disable(); + -- Check if the profile already exists. + elseif (MikSBT.ProfileExists(this:GetText())) then + createProfileButton:Disable(); + end + + + -- Scroll Area X Offset. + elseif (this:GetName() == SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. "XOffsetEditbox") then + -- Get the number in the x offset editbox and make sure it's valid. + local xOffset = tonumber(this:GetText()); + if (xOffset ~= nil) then + MikSBTOpt.SaveScrollAreaControlsToCurrentSettings(); + MikSBTOpt.RepositionScrollAreaMoverFrames(); + end + + + -- Scroll Area Y Offset. + elseif (this:GetName() == SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. "YOffsetEditbox") then + -- Get the number in the y offset editbox and make sure it's valid. + local yOffset = tonumber(this:GetText()); + if (yOffset ~= nil) then + MikSBTOpt.SaveScrollAreaControlsToCurrentSettings(); + MikSBTOpt.RepositionScrollAreaMoverFrames(); + end + + + else + -- Check if there is an associated variable path and set it to the correct value. + if (this.associatedVarPath) then + -- Set the associated variable in the current profile to the value. + MikSBT.SetOptionFromVarPath(this.associatedVarPath, this:GetText()); + end + end +end + + + + + +------------------------------------------------------------------------------------- +-- Color swatch functions. +------------------------------------------------------------------------------------- + +-- ********************************************************************************** +-- Sets up a color swatch with the passed data. +-- ********************************************************************************** +function MikSBTOpt.SetupColorSwatch(frameName, tooltip, varPath) + local associatedFrame = getglobal(frameName); + + -- Make sure the associated frame exists. + if (associatedFrame) then + associatedFrame.tooltipText = tooltip; + associatedFrame.associatedVarPath = varPath; + end +end + + +-- ********************************************************************************** +-- Sets the color swatch's color for the passed frame name. If color values are +-- passed they are used, otherwise the function will attempt to get the values from +-- the associatedVarPath field of the color swatch frame. +-- ********************************************************************************** +function MikSBTOpt.PopulateColorSwatch(frameName, colorR, colorG, colorB) + local associatedFrame = getglobal(frameName); + + -- Make sure the associated frame exists. + if (associatedFrame) then + local tempR = colorR; + local tempG = colorG; + local tempB = colorB; + + -- Check if no r value was passed. + if (tempR == nil) then + -- Check if there is an associated variable path for the color swatch. + if (associatedFrame.associatedVarPath) then + tempR = MikSBT.GetOptionFromVarPath(associatedFrame.associatedVarPath .. ".r"); + end + end + + -- Check if no g value was passed. + if (tempG == nil) then + -- Check if there is an associated variable path for the color swatch. + if (associatedFrame.associatedVarPath) then + tempG = MikSBT.GetOptionFromVarPath(associatedFrame.associatedVarPath .. ".g"); + end + end + + -- Check if no b value was passed. + if (tempB == nil) then + -- Check if there is an associated variable path for the color swatch. + if (associatedFrame.associatedVarPath) then + tempB = MikSBT.GetOptionFromVarPath(associatedFrame.associatedVarPath .. ".b"); + end + end + + -- Make sure there are values to set. + if (tempR ~= nil and tempG ~= nil and tempB ~= nil) then + -- Set the values. + local objColorSwatchTexture = getglobal(associatedFrame:GetName() .. "NormalTexture"); + objColorSwatchTexture:SetVertexColor(tempR, tempG, tempB); + end + end +end + + +-- ********************************************************************************** +-- Called when on of the color swatches for an event is clicked. +-- ********************************************************************************** +function MikSBTOpt.ColorSwatchOnClick() + -- Check if the color swatch has an associated variable path. + if (this.associatedVarPath) then + -- Hide the event message editbox if it's shown. + MikSBTOpt.HideMessageEditbox(this:GetParent():GetParent():GetName().. "MessageEditbox"); + + -- Get the r, g, and b values from the associated variable path and show the color picker. + this.r = MikSBT.GetOptionFromVarPath(this.associatedVarPath .. ".r"); + this.g = MikSBT.GetOptionFromVarPath(this.associatedVarPath .. ".g"); + this.b = MikSBT.GetOptionFromVarPath(this.associatedVarPath .. ".b"); + this.swatchFunc = MikSBTOpt.ColorSwatchSetColor; + this.cancelFunc = MikSBTOpt.ColorSwatchCancel; + ColorPickerFrame.associatedVarPath = this.associatedVarPath; + ColorPickerFrame.associatedColorSwatch = this; + UIDropDownMenuButton_OpenColorPicker(this); + end +end + + +-- ********************************************************************************** +-- Caled when a color is selected for an event in the color picker dialog. +-- ********************************************************************************** +function MikSBTOpt.ColorSwatchSetColor() + -- Get the red, green, and blue color values. + local r, g, b = ColorPickerFrame:GetColorRGB(); + + -- Make sure there is an associated color swatch. + if (ColorPickerFrame.associatedColorSwatch) then + -- Get the associated color swatch texture and make sure it's valid. + local objColorSwatchTexture = getglobal(ColorPickerFrame.associatedColorSwatch:GetName() .. "NormalTexture"); + if (objColorSwatchTexture) then + -- Set the associated + objColorSwatchTexture:SetVertexColor(r, g, b); + end + end + + + -- Check if the color swatch has an associated variable path. + if (ColorPickerFrame.associatedVarPath) then + -- Update current profile data. + MikSBT.SetOptionFromVarPath(ColorPickerFrame.associatedVarPath .. ".r", r); + MikSBT.SetOptionFromVarPath(ColorPickerFrame.associatedVarPath .. ".g", g); + MikSBT.SetOptionFromVarPath(ColorPickerFrame.associatedVarPath .. ".b", b); + end +end + + +-- ********************************************************************************** +-- Called when the color picker dialog is canceled. +-- ********************************************************************************** +function MikSBTOpt.ColorSwatchCancel(previousValues) + -- Make sure there is an associated color swatch. + if (ColorPickerFrame.associatedColorSwatch) then + -- Get the associated color swatch texture and make sure it's valid. + local objColorSwatchTexture = getglobal(ColorPickerFrame.associatedColorSwatch:GetName() .. "NormalTexture"); + if (objColorSwatchTexture) then + -- Set the associated + objColorSwatchTexture:SetVertexColor(previousValues.r, previousValues.g, previousValues.b); + end + end + + -- Check if the color swatch has an associated variable path. + if (ColorPickerFrame.associatedVarPath) then + -- Update current profile data. + MikSBT.SetOptionFromVarPath(ColorPickerFrame.associatedVarPath .. ".r", previousValues.r); + MikSBT.SetOptionFromVarPath(ColorPickerFrame.associatedVarPath .. ".g", previousValues.g); + MikSBT.SetOptionFromVarPath(ColorPickerFrame.associatedVarPath .. ".b", previousValues.b); + end +end + + + +------------------------------------------------------------------------------------- +-- Event settings functions. +------------------------------------------------------------------------------------- + +-- ********************************************************************************** +-- Initializes all the events. +-- ********************************************************************************** +function MikSBTOpt.InitEvents() + local index; + local evtData; + + evtData = MikSBTOpt.INCOMING_EVENTS; + index = 1; evtData[index].EventType = "MSBT_EVENTTYPE_INCOMING_DAMAGE"; + index = 2; evtData[index].EventType = "MSBT_EVENTTYPE_INCOMING_MISS"; + index = 3; evtData[index].EventType = "MSBT_EVENTTYPE_INCOMING_DODGE"; + index = 4; evtData[index].EventType = "MSBT_EVENTTYPE_INCOMING_PARRY"; + index = 5; evtData[index].EventType = "MSBT_EVENTTYPE_INCOMING_BLOCK"; + index = 6; evtData[index].EventType = "MSBT_EVENTTYPE_INCOMING_ABSORB"; + index = 7; evtData[index].EventType = "MSBT_EVENTTYPE_INCOMING_IMMUNE"; + index = 8; evtData[index].EventType = "MSBT_EVENTTYPE_INCOMING_SPELL_DAMAGE"; + index = 9; evtData[index].EventType = "MSBT_EVENTTYPE_INCOMING_SPELL_DOT"; + index = 10; evtData[index].EventType = "MSBT_EVENTTYPE_INCOMING_SPELL_MISS"; + index = 11; evtData[index].EventType = "MSBT_EVENTTYPE_INCOMING_SPELL_DODGE"; + index = 12; evtData[index].EventType = "MSBT_EVENTTYPE_INCOMING_SPELL_PARRY"; + index = 13; evtData[index].EventType = "MSBT_EVENTTYPE_INCOMING_SPELL_BLOCK"; + index = 14; evtData[index].EventType = "MSBT_EVENTTYPE_INCOMING_SPELL_RESIST"; + index = 15; evtData[index].EventType = "MSBT_EVENTTYPE_INCOMING_SPELL_ABSORB"; + index = 16; evtData[index].EventType = "MSBT_EVENTTYPE_INCOMING_SPELL_IMMUNE"; + index = 17; evtData[index].EventType = "MSBT_EVENTTYPE_INCOMING_SPELL_REFLECT"; + index = 18; evtData[index].EventType = "MSBT_EVENTTYPE_INCOMING_HEAL"; + index = 19; evtData[index].EventType = "MSBT_EVENTTYPE_INCOMING_HOT"; + index = 20; evtData[index].EventType = "MSBT_EVENTTYPE_INCOMING_ENVIRONMENTAL"; + + + evtData = MikSBTOpt.OUTGOING_EVENTS; + index = 1; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_DAMAGE"; + index = 2; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_MISS"; + index = 3; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_DODGE"; + index = 4; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_PARRY"; + index = 5; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_BLOCK"; + index = 6; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_ABSORB"; + index = 7; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_IMMUNE"; + index = 8; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_EVADE"; + index = 9; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_SPELL_DAMAGE"; + index = 10; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_SPELL_DOT"; + index = 11; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_SPELL_MISS"; + index = 12; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_SPELL_DODGE"; + index = 13; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_SPELL_PARRY"; + index = 14; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_SPELL_BLOCK"; + index = 15; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_SPELL_RESIST"; + index = 16; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_SPELL_ABSORB"; + index = 17; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_SPELL_IMMUNE"; + index = 18; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_SPELL_REFLECT"; + index = 19; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_SPELL_EVADE"; + index = 20; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_HEAL"; + index = 21; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_HOT"; + index = 22; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_PET_DAMAGE"; + index = 23; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_PET_MISS"; + index = 24; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_PET_DODGE"; + index = 25; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_PET_PARRY"; + index = 26; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_PET_BLOCK"; + index = 27; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_PET_ABSORB"; + index = 28; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_PET_IMMUNE"; + index = 29; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_PET_EVADE"; + index = 30; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_PET_SPELL_DAMAGE"; + index = 31; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_PET_SPELL_MISS"; + index = 32; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_PET_SPELL_DODGE"; + index = 33; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_PET_SPELL_PARRY"; + index = 34; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_PET_SPELL_BLOCK"; + index = 35; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_PET_SPELL_RESIST"; + index = 36; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_PET_SPELL_ABSORB"; + index = 37; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_PET_SPELL_IMMUNE"; + index = 38; evtData[index].EventType = "MSBT_EVENTTYPE_OUTGOING_PET_SPELL_EVADE"; + + + evtData = MikSBTOpt.NOTIFICATION_EVENTS; + index = 1; evtData[index].EventType = "MSBT_EVENTTYPE_NOTIFICATION_DEBUFF"; + index = 2; evtData[index].EventType = "MSBT_EVENTTYPE_NOTIFICATION_BUFF"; + index = 3; evtData[index].EventType = "MSBT_EVENTTYPE_NOTIFICATION_ITEM_BUFF"; + index = 4; evtData[index].EventType = "MSBT_EVENTTYPE_NOTIFICATION_BUFF_FADE"; + index = 5; evtData[index].EventType = "MSBT_EVENTTYPE_NOTIFICATION_COMBAT_ENTER"; + index = 6; evtData[index].EventType = "MSBT_EVENTTYPE_NOTIFICATION_COMBAT_LEAVE"; + index = 7; evtData[index].EventType = "MSBT_EVENTTYPE_NOTIFICATION_POWER_GAIN"; + index = 8; evtData[index].EventType = "MSBT_EVENTTYPE_NOTIFICATION_POWER_LOSS"; + index = 9; evtData[index].EventType = "MSBT_EVENTTYPE_NOTIFICATION_CP_GAIN"; + index = 10; evtData[index].EventType = "MSBT_EVENTTYPE_NOTIFICATION_CP_FULL"; + index = 11; evtData[index].EventType = "MSBT_EVENTTYPE_NOTIFICATION_HONOR_GAIN"; + index = 12; evtData[index].EventType = "MSBT_EVENTTYPE_NOTIFICATION_REP_GAIN"; + index = 13; evtData[index].EventType = "MSBT_EVENTTYPE_NOTIFICATION_REP_LOSS"; + index = 14; evtData[index].EventType = "MSBT_EVENTTYPE_NOTIFICATION_SKILL_GAIN"; + index = 15; evtData[index].EventType = "MSBT_EVENTTYPE_NOTIFICATION_EXPERIENCE_GAIN"; + index = 16; evtData[index].EventType = "MSBT_EVENTTYPE_NOTIFICATION_PC_KILLING_BLOW"; + index = 17; evtData[index].EventType = "MSBT_EVENTTYPE_NOTIFICATION_NPC_KILLING_BLOW"; +end + + +-- ********************************************************************************** +-- This function populates the incoming event settings. +-- ********************************************************************************** +function MikSBTOpt.PopulateIncomingEventSettings() + -- Hide the event message editbox if it's shown. + MikSBTOpt.HideMessageEditbox(OPTIONS_FRAME_NAME .. "Tab2FrameMessageEditbox"); + + -- Get the total number of events. + totalItems = table.getn(MikSBTOpt.INCOMING_EVENTS); + + -- Get the incoming event settings scroll frame and its offset. + local objFrame = getglobal(OPTIONS_FRAME_NAME .. "Tab2FrameEventsScrollFrame"); + FauxScrollFrame_Update(objFrame, totalItems, EVENT_ITEMS_PER_PAGE, EVENT_ITEM_HEIGHT); + local skipCount = FauxScrollFrame_GetOffset(objFrame); + + local objEventSettings = nil; + -- Loop through all of the visible items. + for i = 1, EVENT_ITEMS_PER_PAGE do + objEventSettings = getglobal(OPTIONS_FRAME_NAME .. "Tab2FrameEvent" .. i); + + -- Make sure the event settings object exists. + if (objEventSettings) then + -- Check if there is not event settings data for the event settings slot. + if (i > totalItems) then + -- Hide the event settings. + objEventSettings:Hide(); + + -- There is data for the event settings slot. + else + -- Get the data for the event. + local evtData = MikSBTOpt.INCOMING_EVENTS[i+skipCount]; + + -- Make sure there is an associated event type and set it. + if (evtData.EventType ~= nil) then + objEventSettings.EventType = evtData.EventType; + end + + -- Set the font frame title to the checkbox's label and the event area. + objEventSettings.FontFrameTitle = evtData.Label; + objEventSettings.EventArea = "Incoming"; + + + -- Setup the color swatch and populate it. + MikSBTOpt.SetupColorSwatch(objEventSettings:GetName() .. "ColorSwatch", MikSBTOpt.MSG_EVENT_COLOR_SWATCH_TOOLTIP, "EventSettings." .. objEventSettings.EventType .. ".FontSettings.Color"); + MikSBTOpt.PopulateColorSwatch(objEventSettings:GetName() .. "ColorSwatch"); + + -- Setup and populate the event settings show checkbox. + MikSBTOpt.SetupCheckbox(objEventSettings:GetName() .. "ShowEventCheckbox", evtData.Label, evtData.Tooltips.ShowCheckbox, "EventSettings." .. objEventSettings.EventType .. ".Show"); + MikSBTOpt.PopulateCheckbox(objEventSettings:GetName() .. "ShowEventCheckbox"); + + + -- Set the message label to the appropriate text and the editbox's tooltip. + local objMessageLabel = getglobal(objEventSettings:GetName() .. "MessageLabel"); + if (objMessageLabel) then + -- Set the tooltip for the label. + objMessageLabel:GetParent().tooltipText = MikSBTOpt.MSG_EVENT_MESSAGE_LABEL_TOOLTIP; + if (objEventSettings.EventType ~= nil) then + objMessageLabel:SetText(MikSBT.GetOptionFromVarPath("EventSettings." .. objEventSettings.EventType .. ".Message")); + end + end + objEventSettings.EditboxTooltip = evtData.Tooltips.Editbox; + + -- Hide the sticky event checkbox. + getglobal(objEventSettings:GetName() .. "StickyEventCheckbox"):Hide(); + + + -- Setup the edit font settings button for the event. + MikSBTOpt.SetupButton(objEventSettings:GetName() .. "EditFontSettingsButton", MikSBTOpt.MSG_EVENT_EDIT_FONT_SETTINGS_BUTTON_LABEL, MikSBTOpt.MSG_EVENT_EDIT_FONT_SETTINGS_BUTTON_TOOLTIP); + + -- Show the event settings. + objEventSettings:Show(); + end + end + end + +end + + +-- ********************************************************************************** +-- This function populates the outgoing event settings. +-- ********************************************************************************** +function MikSBTOpt.PopulateOutgoingEventSettings() + -- Hide the event message editbox if it's shown. + MikSBTOpt.HideMessageEditbox(OPTIONS_FRAME_NAME .. "Tab3FrameMessageEditbox"); + + -- Get the total number of events. + totalItems = table.getn(MikSBTOpt.OUTGOING_EVENTS); + + -- Get the outgoing event settings scroll frame and its offset. + local objFrame = getglobal(OPTIONS_FRAME_NAME .. "Tab3FrameEventsScrollFrame"); + FauxScrollFrame_Update(objFrame, totalItems, EVENT_ITEMS_PER_PAGE, EVENT_ITEM_HEIGHT); + local skipCount = FauxScrollFrame_GetOffset(objFrame); + + local objEventSettings = nil; + -- Loop through all of the visible items. + for i = 1, EVENT_ITEMS_PER_PAGE do + objEventSettings = getglobal(OPTIONS_FRAME_NAME .. "Tab3FrameEvent" .. i); + + -- Make sure the event settings object exists. + if (objEventSettings) then + -- Check if there is not event settings data for the event settings slot. + if (i > totalItems) then + -- Hide the event settings. + objEventSettings:Hide(); + + -- There is data for the event settings slot. + else + -- Get the data for the event. + local evtData = MikSBTOpt.OUTGOING_EVENTS[i+skipCount]; + + -- Make sure there is an associated event type and set it. + if (evtData.EventType ~= nil) then + objEventSettings.EventType = evtData.EventType; + end + + -- Set the font frame title to the checkbox's label and the event area. + objEventSettings.FontFrameTitle = evtData.Label; + objEventSettings.EventArea = "Outgoing"; + + + -- Setup the color swatch and populate it. + MikSBTOpt.SetupColorSwatch(objEventSettings:GetName() .. "ColorSwatch", MikSBTOpt.MSG_EVENT_COLOR_SWATCH_TOOLTIP, "EventSettings." .. objEventSettings.EventType .. ".FontSettings.Color"); + MikSBTOpt.PopulateColorSwatch(objEventSettings:GetName() .. "ColorSwatch"); + + -- Setup and populate the event settings show checkbox. + MikSBTOpt.SetupCheckbox(objEventSettings:GetName() .. "ShowEventCheckbox", evtData.Label, evtData.Tooltips.ShowCheckbox, "EventSettings." .. objEventSettings.EventType .. ".Show"); + MikSBTOpt.PopulateCheckbox(objEventSettings:GetName() .. "ShowEventCheckbox"); + + + -- Set the message label to the appropriate text and the editbox's tooltip. + local objMessageLabel = getglobal(objEventSettings:GetName() .. "MessageLabel"); + if (objMessageLabel) then + -- Set the tooltip for the label. + objMessageLabel:GetParent().tooltipText = MikSBTOpt.MSG_EVENT_MESSAGE_LABEL_TOOLTIP; + if (objEventSettings.EventType ~= nil) then + objMessageLabel:SetText(MikSBT.GetOptionFromVarPath("EventSettings." .. objEventSettings.EventType .. ".Message")); + end + end + objEventSettings.EditboxTooltip = evtData.Tooltips.Editbox; + + -- Hide the sticky event checkbox. + getglobal(objEventSettings:GetName() .. "StickyEventCheckbox"):Hide(); + + + -- Setup the edit font settings button for the event. + MikSBTOpt.SetupButton(objEventSettings:GetName() .. "EditFontSettingsButton", MikSBTOpt.MSG_EVENT_EDIT_FONT_SETTINGS_BUTTON_LABEL, MikSBTOpt.MSG_EVENT_EDIT_FONT_SETTINGS_BUTTON_TOOLTIP); + + -- Show the event settings. + objEventSettings:Show(); + end + end + end + +end + + +-- ********************************************************************************** +-- This function populates the notification event settings. +-- ********************************************************************************** +function MikSBTOpt.PopulateNotificationEventSettings() + -- Hide the event message editbox if it's shown. + MikSBTOpt.HideMessageEditbox(OPTIONS_FRAME_NAME .. "Tab4FrameMessageEditbox"); + + -- Get the total number of events. + totalItems = table.getn(MikSBTOpt.NOTIFICATION_EVENTS); + + -- Get the notification event settings scroll frame and its offset. + local objFrame = getglobal(OPTIONS_FRAME_NAME .. "Tab4FrameEventsScrollFrame"); + FauxScrollFrame_Update(objFrame, totalItems, EVENT_ITEMS_PER_PAGE, EVENT_ITEM_HEIGHT); + local skipCount = FauxScrollFrame_GetOffset(objFrame); + + local objEventSettings = nil; + -- Loop through all of the visible items. + for i = 1, EVENT_ITEMS_PER_PAGE do + objEventSettings = getglobal(OPTIONS_FRAME_NAME .. "Tab4FrameEvent" .. i); + + -- Make sure the event settings object exists. + if (objEventSettings) then + -- Check if there is not event settings data for the event settings slot. + if (i > totalItems) then + -- Hide the event settings. + objEventSettings:Hide(); + + -- There is data for the event settings slot. + else + -- Get the data for the event. + local evtData = MikSBTOpt.NOTIFICATION_EVENTS[i+skipCount]; + + -- Make sure there is an associated event type and set it. + if (evtData.EventType ~= nil) then + objEventSettings.EventType = evtData.EventType; + end + + -- Set the font frame title to the checkbox's label and the event area. + objEventSettings.FontFrameTitle = evtData.Label; + objEventSettings.EventArea = "Outgoing"; + + + -- Setup the color swatch and populate it. + MikSBTOpt.SetupColorSwatch(objEventSettings:GetName() .. "ColorSwatch", MikSBTOpt.MSG_EVENT_COLOR_SWATCH_TOOLTIP, "EventSettings." .. objEventSettings.EventType .. ".FontSettings.Color"); + MikSBTOpt.PopulateColorSwatch(objEventSettings:GetName() .. "ColorSwatch"); + + -- Setup and populate the event settings show checkbox. + MikSBTOpt.SetupCheckbox(objEventSettings:GetName() .. "ShowEventCheckbox", evtData.Label, evtData.Tooltips.ShowCheckbox, "EventSettings." .. objEventSettings.EventType .. ".Show"); + MikSBTOpt.PopulateCheckbox(objEventSettings:GetName() .. "ShowEventCheckbox"); + + + -- Set the message label to the appropriate text and the editbox's tooltip. + local objMessageLabel = getglobal(objEventSettings:GetName() .. "MessageLabel"); + if (objMessageLabel) then + -- Set the tooltip for the label. + objMessageLabel:GetParent().tooltipText = MikSBTOpt.MSG_EVENT_MESSAGE_LABEL_TOOLTIP; + if (objEventSettings.EventType ~= nil) then + objMessageLabel:SetText(MikSBT.GetOptionFromVarPath("EventSettings." .. objEventSettings.EventType .. ".Message")); + end + end + objEventSettings.EditboxTooltip = evtData.Tooltips.Editbox; + + -- Setup the sticky checkbox for the event settings and populate it. + MikSBTOpt.SetupCheckbox(objEventSettings:GetName() .. "StickyEventCheckbox", nil, MikSBTOpt.MSG_EVENT_STICKY_CHECKBOX_TOOLTIP, "EventSettings." .. objEventSettings.EventType .. ".IsSticky"); + MikSBTOpt.PopulateCheckbox(objEventSettings:GetName() .. "StickyEventCheckbox"); + getglobal(objEventSettings:GetName() .. "StickyEventCheckbox"):Show(); + + + + -- Setup the edit font settings button for the event. + MikSBTOpt.SetupButton(objEventSettings:GetName() .. "EditFontSettingsButton", MikSBTOpt.MSG_EVENT_EDIT_FONT_SETTINGS_BUTTON_LABEL, MikSBTOpt.MSG_EVENT_EDIT_FONT_SETTINGS_BUTTON_TOOLTIP); + + -- Show the event settings. + objEventSettings:Show(); + end + end + end + +end + + +-- ********************************************************************************** +-- This function populates the trigger event settings. +-- ********************************************************************************** +function MikSBTOpt.PopulateTriggerEventSettings() + -- Hide the trigger event message editbox if it's shown. + MikSBTOpt.HideMessageEditbox(OPTIONS_FRAME_NAME .. "Tab5FrameMessageEditbox"); + + -- Get the total number of events. + totalItems = MikSBTOpt.CountTriggers(); + + -- Get the trigger settings scroll frame and its offset. + local objFrame = getglobal(OPTIONS_FRAME_NAME .. "Tab5FrameTriggersScrollFrame"); + FauxScrollFrame_Update(objFrame, totalItems, TRIGGER_ITEMS_PER_PAGE, TRIGGER_ITEM_HEIGHT); + local skipCount = FauxScrollFrame_GetOffset(objFrame); + + local objTriggerEventSettings = nil; + -- Loop through all of the visible items. + for i = 1, TRIGGER_ITEMS_PER_PAGE do + objTriggerEventSettings = getglobal(OPTIONS_FRAME_NAME .. "Tab5FrameTrigger" .. i); + + -- Make sure the trigger settings object exists. + if (objTriggerEventSettings) then + -- Check if there is not trigger settings data for the trigger settings slot. + if (i > totalItems) then + -- Hide the trigger settings. + objTriggerEventSettings:Hide(); + + -- There is data for the trigger settings slot. + else + -- Get the data for the trigger. + local triggerKey, triggerSettings = MikSBTOpt.GetTriggerSettings(i+skipCount); + + -- Set the trigger key, font frame title to the checkbox's label and the event area. + objTriggerEventSettings.TriggerKey = triggerKey; + objTriggerEventSettings.FontFrameTitle = triggerSettings.EventSettings.Message; + objTriggerEventSettings.EventArea = "Trigger"; + + + -- Setup the color swatch and populate it. + MikSBTOpt.SetupColorSwatch(objTriggerEventSettings:GetName() .. "ColorSwatch", MikSBTOpt.MSG_EVENT_COLOR_SWATCH_TOOLTIP, "Triggers." .. triggerKey .. ".EventSettings.FontSettings.Color"); + MikSBTOpt.PopulateColorSwatch(objTriggerEventSettings:GetName() .. "ColorSwatch"); + + + -- Setup and populate the trigger event settings enable checkbox. + MikSBTOpt.SetupCheckbox(objTriggerEventSettings:GetName() .. "EnableTriggerCheckbox", nil, MikSBTOpt.MSG_TRIGGER_ENABLE_TOOLTIP, "Triggers." .. triggerKey .. ".EventSettings.Show"); + MikSBTOpt.PopulateCheckbox(objTriggerEventSettings:GetName() .. "EnableTriggerCheckbox"); + + + -- Set the message label to the appropriate text and the editbox's tooltip. + local objMessageLabel = getglobal(objTriggerEventSettings:GetName() .. "MessageLabel"); + if (objMessageLabel) then + -- Set the tooltip for the label. + objMessageLabel:GetParent().tooltipText = MikSBTOpt.MSG_TRIGGER_MESSAGE_LABEL_TOOLTIP; + objMessageLabel:SetText(triggerSettings.EventSettings.Message); + end + objTriggerEventSettings.EditboxTooltip = MikSBTOpt.MSG_TRIGGER_MESSAGE_EDITBOX_TOOLTIP; + + + -- Setup the sticky checkbox for the trigger event settings and populate it. + MikSBTOpt.SetupCheckbox(objTriggerEventSettings:GetName() .. "StickyEventCheckbox", nil, MikSBTOpt.MSG_TRIGGER_STICKY_CHECKBOX_TOOLTIP, "Triggers." .. triggerKey .. ".EventSettings.IsSticky"); + MikSBTOpt.PopulateCheckbox(objTriggerEventSettings:GetName() .. "StickyEventCheckbox"); + + -- Setup the edit font settings button for the event. + MikSBTOpt.SetupButton(objTriggerEventSettings:GetName() .. "EditFontSettingsButton", MikSBTOpt.MSG_TRIGGER_EDIT_FONT_SETTINGS_BUTTON_LABEL, MikSBTOpt.MSG_TRIGGER_EDIT_FONT_SETTINGS_BUTTON_TOOLTIP); + + -- Setup the edit trigger settings button for the event. + MikSBTOpt.SetupButton(objTriggerEventSettings:GetName() .. "EditTriggerSettingsButton", MikSBTOpt.MSG_TRIGGER_EDIT_TRIGGER_SETTINGS_BUTTON_LABEL, MikSBTOpt.MSG_TRIGGER_EDIT_TRIGGER_SETTINGS_BUTTON_TOOLTIP); + + -- Setup the delete trigger button for the event. + MikSBTOpt.SetupButton(objTriggerEventSettings:GetName() .. "DeleteTriggerButton", "X", MikSBTOpt.MSG_TRIGGER_DELETE_TRIGGER_BUTTON_TOOLTIP); + + -- Show the trigger settings. + objTriggerEventSettings:Show(); + end + end + end + +end + + +-- ********************************************************************************** +-- This function populates the suppression settings. +-- ********************************************************************************** +function MikSBTOpt.PopulateSuppressionSettings() + -- Hide the suppression editbox if it's shown. + MikSBTOpt.HideMessageEditbox(OPTIONS_FRAME_NAME .. "Tab6FrameMessageEditbox"); + + -- Get the total number of suppressions. + totalItems = MikSBTOpt.CountSuppressions(); + + -- Get the trigger settings scroll frame and its offset. + local objFrame = getglobal(OPTIONS_FRAME_NAME .. "Tab6FrameSuppressionsScrollFrame"); + FauxScrollFrame_Update(objFrame, totalItems, SUPPRESSION_ITEMS_PER_PAGE, SUPPRESSION_ITEM_HEIGHT); + local skipCount = FauxScrollFrame_GetOffset(objFrame); + + -- Loop through all of the visible items. + for i = 1, SUPPRESSION_ITEMS_PER_PAGE do + objSuppressionItemSettings = getglobal(OPTIONS_FRAME_NAME .. "Tab6FrameSuppression" .. i); + + -- Make sure the suppression settings object exists. + if (objSuppressionItemSettings) then + -- Check if there is not suppression settings data for the suppression settings slot. + if (i > totalItems) then + -- Hide the suppression settings. + objSuppressionItemSettings:Hide(); + + -- There is data for the suppression settings slot. + else + local suppressionKey, suppressionSettings = MikSBTOpt.GetSuppressionSettings(i+skipCount); + + -- Set the suppression key. + objSuppressionItemSettings.SuppressionKey = suppressionKey; + + -- Setup and populate the enable suppression checkbox. + MikSBTOpt.SetupCheckbox(objSuppressionItemSettings:GetName() .. "EnableSuppressionCheckbox", nil, MikSBTOpt.MSG_SUPPRESSION_ENABLE_TOOLTIP, "Suppressions." .. suppressionKey .. ".Enabled"); + MikSBTOpt.PopulateCheckbox(objSuppressionItemSettings:GetName() .. "EnableSuppressionCheckbox"); + + + -- Set the message label to the appropriate text and the editbox's tooltip. + local objMessageLabel = getglobal(objSuppressionItemSettings:GetName() .. "MessageLabel"); + if (objMessageLabel) then + -- Set the tooltip for the label. + objMessageLabel:GetParent().tooltipText = MikSBTOpt.MSG_SUPPRESSION_MESSAGE_LABEL_TOOLTIP; + objMessageLabel:SetText(suppressionSettings.SearchPattern); + end + objSuppressionItemSettings.EditboxTooltip = MikSBTOpt.MSG_SUPPRESSION_MESSAGE_EDITBOX_TOOLTIP; + + + -- Setup the delete suppression button for the item. + MikSBTOpt.SetupButton(objSuppressionItemSettings:GetName() .. "DeleteSuppressionButton", "X", MikSBTOpt.MSG_SUPPRESSION_DELETE_SUPPRESSION_BUTTON_TOOLTIP); + + -- Show the suppression settings. + objSuppressionItemSettings:Show(); + end + end + end +end + + +-- ********************************************************************************** +-- Returns the number of triggers defined. +-- ********************************************************************************** +function MikSBTOpt.CountTriggers() + -- Declare a variable to count the number of triggers. + local numTriggers = 0; + + -- Loop through all of the trigger entries. + for _, triggerSettings in MikSBT.CurrentProfile.Triggers do + numTriggers = numTriggers + 1; + end + + -- Return the number of triggers. + return numTriggers; +end + + +-- ********************************************************************************** +-- Returns the number of suppressions defined. +-- ********************************************************************************** +function MikSBTOpt.CountSuppressions() + -- Declare a variable to count the number of suppressions. + local numSuppressions = 0; + + -- Loop through all of the suppression entries. + for _, suppressionSettings in MikSBT.CurrentProfile.Suppressions do + numSuppressions = numSuppressions + 1; + end + + -- Return the number of suppressions. + return numSuppressions; +end + + + +-- ********************************************************************************** +-- Returns the trigger settings for the passed trigger number. +-- ********************************************************************************** +function MikSBTOpt.GetTriggerSettings(triggerNumber) + -- Declare a variable to count hold the number of the current trigger. + local curTrigger = 0; + + -- Loop through all of the trigger entries. + for triggerKey, triggerSettings in MikSBT.CurrentProfile.Triggers do + curTrigger = curTrigger + 1; + + -- Check if this is the requested trigger. + if (curTrigger == triggerNumber) then + return triggerKey, triggerSettings; + end + end + + return nil; +end + + +-- ********************************************************************************** +-- Returns the suppression settings for the passed suppression number. +-- ********************************************************************************** +function MikSBTOpt.GetSuppressionSettings(suppressionNumber) + -- Declare a variable to count hold the number of the current suppression. + local curSuppression = 0; + + -- Loop through all of the suppression entries. + for suppressionKey, suppressionSettings in MikSBT.CurrentProfile.Suppressions do + curSuppression = curSuppression + 1; + + -- Check if this is the requested suppression. + if (curSuppression == suppressionNumber) then + return suppressionKey, suppressionSettings; + end + end + + return nil; +end + + +-- ********************************************************************************** +-- Called when one of the event message labels is clicked. +-- ********************************************************************************** +function MikSBTOpt.EventMessageLabelOnClick() + -- Get the event settings frame. + local objEventSettings = this:GetParent(); + + -- Make sure the event type is set for the label and there is an event data index. + if (objEventSettings.EventType ~= nil) then + -- Get the clicked label and hide it. + local labelFrameName = this:GetName() .. "Label"; + local objLabel = getglobal(labelFrameName); + objLabel:Hide(); + + -- Get the message editbox for the scroll area. + local editboxFrameName = objEventSettings:GetParent():GetName() .. "MessageEditbox"; + local objEditbox = getglobal(editboxFrameName); + + -- Hide the editbox to make sure everything is updated correctly. + objEditbox:Hide(); + + -- Show the editbox where the clicked label is, set the clicked label frame name for the editbox, and + -- set the previous text to the label's text. + objEditbox:Show(); + objEditbox:ClearAllPoints(); + objEditbox:SetPoint("TOPLEFT", this, "TOPLEFT"); + objEditbox.ClickedLabelFrameName = labelFrameName; + objEditbox.PreviousText = objLabel:GetText(); + + + -- Setup the event setting editbox and populate it. + MikSBTOpt.SetupEditbox(editboxFrameName, nil, MikSBTOpt.MSG_EVENT_MESSAGE_EDITBOX_TOOLTIP_PREFIX .. objEventSettings.EditboxTooltip, "EventSettings." .. objEventSettings.EventType .. ".Message"); + MikSBTOpt.PopulateEditbox(editboxFrameName); + + -- Set the focus to the editbox. + objEditbox:SetFocus(); + end +end + + +-- ********************************************************************************** +-- Called when one of the trigger message labels is clicked. +-- ********************************************************************************** +function MikSBTOpt.TriggerMessageLabelOnClick() + -- Get the trigger event settings frame. + local objTriggerEventSettings = this:GetParent(); + + -- Make sure the trigger key is set for the label. + if (objTriggerEventSettings.TriggerKey ~= nil) then + -- Get the clicked label and hide it. + local labelFrameName = this:GetName() .. "Label"; + local objLabel = getglobal(labelFrameName); + objLabel:Hide(); + + -- Get the message editbox. + local editboxFrameName = objTriggerEventSettings:GetParent():GetName() .. "MessageEditbox"; + local objEditbox = getglobal(editboxFrameName); + + -- Hide the editbox to make sure everything is updated correctly. + objEditbox:Hide(); + + -- Show the editbox where the clicked label is, set the clicked label frame name for the editbox, and + -- set the previous text to the label's text. + objEditbox:Show(); + objEditbox:ClearAllPoints(); + objEditbox:SetPoint("TOPLEFT", this, "TOPLEFT"); + objEditbox.ClickedLabelFrameName = labelFrameName; + objEditbox.PreviousText = objLabel:GetText(); + + + -- Setup the event setting editbox and populate it. + MikSBTOpt.SetupEditbox(editboxFrameName, nil, objTriggerEventSettings.EditboxTooltip, "Triggers." .. objTriggerEventSettings.TriggerKey .. ".EventSettings.Message"); + MikSBTOpt.PopulateEditbox(editboxFrameName); + + -- Set the focus to the editbox. + objEditbox:SetFocus(); + end +end + + +-- ********************************************************************************** +-- Called when one of the suppression message labels is clicked. +-- ********************************************************************************** +function MikSBTOpt.SuppressionMessageLabelOnClick() + -- Get the suppression settings frame. + local objSuppressionSettings = this:GetParent(); + + -- Make sure the suppression key is set for the label. + if (objSuppressionSettings.SuppressionKey ~= nil) then + -- Get the clicked label and hide it. + local labelFrameName = this:GetName() .. "Label"; + local objLabel = getglobal(labelFrameName); + objLabel:Hide(); + + -- Get the message editbox. + local editboxFrameName = objSuppressionSettings:GetParent():GetName() .. "MessageEditbox"; + local objEditbox = getglobal(editboxFrameName); + + -- Hide the editbox to make sure everything is updated correctly. + objEditbox:Hide(); + + -- Show the editbox where the clicked label is, set the clicked label frame name for the editbox, and + -- set the previous text to the label's text. + objEditbox:Show(); + objEditbox:ClearAllPoints(); + objEditbox:SetPoint("TOPLEFT", this, "TOPLEFT"); + objEditbox.ClickedLabelFrameName = labelFrameName; + objEditbox.PreviousText = objLabel:GetText(); + + + -- Setup the event setting editbox and populate it. + MikSBTOpt.SetupEditbox(editboxFrameName, nil, objSuppressionSettings.EditboxTooltip, "Suppressions." .. objSuppressionSettings.SuppressionKey .. ".SearchPattern"); + MikSBTOpt.PopulateEditbox(editboxFrameName); + + -- Set the focus to the editbox. + objEditbox:SetFocus(); + end +end + + +-- ********************************************************************************** +-- Hides the message editbox. +-- ********************************************************************************** +function MikSBTOpt.HideMessageEditbox(editboxFrameName) + -- Check if the event message editbox is shown and hide it. + local objEditbox = getglobal(editboxFrameName); + if (objEditbox and objEditbox:IsVisible()) then + objEditbox:Hide(); + end +end + + + +------------------------------------------------------------------------------------- +-- Font settings functions. +------------------------------------------------------------------------------------- + +-- ********************************************************************************** +-- Show master font settings. +-- ********************************************************************************** +function MikSBTOpt.ShowMasterFontSettings() + -- Show the crit font settings controls. + MikSBTOpt.ShowCritFontControls(); + + + -- Setup the normal font dropdown. + local key = "FontDropdown"; + MikSBTOpt.SetupDropdown(FONT_SETTINGS_FRAME_NAME .. key, MikSBTOpt.DROPDOWNS[key].Label, MikSBTOpt.FONT_SETTINGS_TOOLTIPS["Master"].Font, MikSBTOpt.FontSettingsDropdownOnClick, MikSBT.AVAILABLE_FONTS, "MasterFontSettings.Normal.FontIndex"); + MikSBTOpt.PopulateDropdown(FONT_SETTINGS_FRAME_NAME .. key); + + -- Setup the normal font outline dropdown. + key = "FontOutlineDropdown"; + MikSBTOpt.SetupDropdown(FONT_SETTINGS_FRAME_NAME .. key, MikSBTOpt.DROPDOWNS[key].Label, MikSBTOpt.FONT_SETTINGS_TOOLTIPS["Master"].Outline, MikSBTOpt.FontSettingsDropdownOnClick, MikSBT.AVAILABLE_OUTLINES, "MasterFontSettings.Normal.OutlineIndex"); + MikSBTOpt.PopulateDropdown(FONT_SETTINGS_FRAME_NAME .. key); + + -- Setup the crit font dropdown. + key = "FontCritDropdown"; + MikSBTOpt.SetupDropdown(FONT_SETTINGS_FRAME_NAME .. key, MikSBTOpt.DROPDOWNS[key].Label, MikSBTOpt.FONT_SETTINGS_TOOLTIPS["Master"].FontCrit, MikSBTOpt.FontSettingsDropdownOnClick, MikSBT.AVAILABLE_FONTS, "MasterFontSettings.Crit.FontIndex"); + MikSBTOpt.PopulateDropdown(FONT_SETTINGS_FRAME_NAME .. key); + + -- Setup the crit font outline dropdown. + key = "FontOutlineCritDropdown"; + MikSBTOpt.SetupDropdown(FONT_SETTINGS_FRAME_NAME .. key, MikSBTOpt.DROPDOWNS[key].Label, MikSBTOpt.FONT_SETTINGS_TOOLTIPS["Master"].OutlineCrit, MikSBTOpt.FontSettingsDropdownOnClick, MikSBT.AVAILABLE_OUTLINES, "MasterFontSettings.Crit.OutlineIndex"); + MikSBTOpt.PopulateDropdown(FONT_SETTINGS_FRAME_NAME .. key); + + + -- Setup the normal font size slider. + key = "FontSizeSlider"; + MikSBTOpt.SetupSlider(FONT_SETTINGS_FRAME_NAME .. key, MikSBTOpt.SLIDERS[key].Label, MikSBTOpt.FONT_SETTINGS_TOOLTIPS["Master"].FontSize, MIN_FONT_SIZE, MAX_FONT_SIZE, 2, "MasterFontSettings.Normal.FontSize"); + MikSBTOpt.PopulateSlider(FONT_SETTINGS_FRAME_NAME .. key); + + -- Setup the crit font size slider. + key = "FontSizeCritSlider"; + MikSBTOpt.SetupSlider(FONT_SETTINGS_FRAME_NAME .. key, MikSBTOpt.SLIDERS[key].Label, MikSBTOpt.FONT_SETTINGS_TOOLTIPS["Master"].FontSizeCrit, MIN_FONT_SIZE, MAX_FONT_SIZE, 2, "MasterFontSettings.Crit.FontSize"); + MikSBTOpt.PopulateSlider(FONT_SETTINGS_FRAME_NAME .. key); + + + -- Hide the inherit font size and crit font size checkboxes. + getglobal(FONT_SETTINGS_FRAME_NAME .. "InheritFontSizeCheckbox"):Hide(); + getglobal(FONT_SETTINGS_FRAME_NAME .. "InheritFontSizeCritCheckbox"):Hide(); + + -- Show the font size and crit size sliders. + getglobal(FONT_SETTINGS_FRAME_NAME .. "FontSizeSlider"):Show(); + getglobal(FONT_SETTINGS_FRAME_NAME .. "FontSizeCritSlider"):Show(); + + + -- Show the font settings frame. + getglobal(FONT_SETTINGS_FRAME_NAME):Show(); + + -- Update the font previews. + MikSBTOpt.UpdateFontPreviews(); +end + + +-- ********************************************************************************** +-- Show scroll area font settings . +-- ********************************************************************************** +function MikSBTOpt.ShowScrollAreaFontSettings(scrollArea) + -- Get the font settings frame. + local fontSettingsFrame = getglobal(FONT_SETTINGS_FRAME_NAME); + + -- Get the inherited font settings. + fontSettingsFrame.InheritedFontIndex = MikSBT.GetOptionFromVarPath("MasterFontSettings.Normal.FontIndex"); + fontSettingsFrame.InheritedOutlineIndex = MikSBT.GetOptionFromVarPath("MasterFontSettings.Normal.OutlineIndex"); + fontSettingsFrame.InheritedFontSize = MikSBT.GetOptionFromVarPath("MasterFontSettings.Normal.FontSize"); + fontSettingsFrame.InheritedFontCritIndex = MikSBT.GetOptionFromVarPath("MasterFontSettings.Crit.FontIndex"); + fontSettingsFrame.InheritedOutlineCritIndex = MikSBT.GetOptionFromVarPath("MasterFontSettings.Crit.OutlineIndex"); + fontSettingsFrame.InheritedFontSizeCrit = MikSBT.GetOptionFromVarPath("MasterFontSettings.Crit.FontSize"); + + + -- Show the crit font settings controls. + MikSBTOpt.ShowCritFontControls(); + + + -- Setup the normal font dropdown. + local key = "FontDropdown"; + MikSBTOpt.SetupDropdown(FONT_SETTINGS_FRAME_NAME .. key, MikSBTOpt.DROPDOWNS[key].Label, MikSBTOpt.FONT_SETTINGS_TOOLTIPS["ScrollArea"].Font, MikSBTOpt.FontSettingsDropdownOnClick, availableFontsInherit, "DisplaySettings." .. scrollArea .. ".FontSettings.Normal.FontIndex"); + MikSBTOpt.PopulateDropdown(FONT_SETTINGS_FRAME_NAME .. key); + + -- Setup the normal font outline dropdown. + key = "FontOutlineDropdown"; + MikSBTOpt.SetupDropdown(FONT_SETTINGS_FRAME_NAME .. key, MikSBTOpt.DROPDOWNS[key].Label, MikSBTOpt.FONT_SETTINGS_TOOLTIPS["ScrollArea"].Outline, MikSBTOpt.FontSettingsDropdownOnClick, availableOutlinesInherit, "DisplaySettings." .. scrollArea .. ".FontSettings.Normal.OutlineIndex"); + MikSBTOpt.PopulateDropdown(FONT_SETTINGS_FRAME_NAME .. key); + + -- Setup the crit font dropdown. + key = "FontCritDropdown"; + MikSBTOpt.SetupDropdown(FONT_SETTINGS_FRAME_NAME .. key, MikSBTOpt.DROPDOWNS[key].Label, MikSBTOpt.FONT_SETTINGS_TOOLTIPS["ScrollArea"].FontCrit, MikSBTOpt.FontSettingsDropdownOnClick, availableFontsInherit, "DisplaySettings." .. scrollArea .. ".FontSettings.Crit.FontIndex"); + MikSBTOpt.PopulateDropdown(FONT_SETTINGS_FRAME_NAME .. key); + + -- Setup the crit font outline dropdown. + key = "FontOutlineCritDropdown"; + MikSBTOpt.SetupDropdown(FONT_SETTINGS_FRAME_NAME .. key, MikSBTOpt.DROPDOWNS[key].Label, MikSBTOpt.FONT_SETTINGS_TOOLTIPS["ScrollArea"].OutlineCrit, MikSBTOpt.FontSettingsDropdownOnClick, availableOutlinesInherit, "DisplaySettings." .. scrollArea .. ".FontSettings.Crit.OutlineIndex"); + MikSBTOpt.PopulateDropdown(FONT_SETTINGS_FRAME_NAME .. key); + + + + -- Show the inherit font size and crit font size checkboxes. + getglobal(FONT_SETTINGS_FRAME_NAME .. "InheritFontSizeCheckbox"):Show(); + getglobal(FONT_SETTINGS_FRAME_NAME .. "InheritFontSizeCritCheckbox"):Show(); + + + -- Setup the inherit normal font size checkbox. + key = "InheritFontSizeCheckbox"; + MikSBTOpt.SetupCheckbox(FONT_SETTINGS_FRAME_NAME .. key, MikSBTOpt.CHECKBOXES[key].Label, MikSBTOpt.FONT_SETTINGS_TOOLTIPS["ScrollArea"].InheritFontSize, "DisplaySettings." .. scrollArea .. ".FontSettings.Normal.FontSize"); + + -- Setup the inherit crit font size checkbox. + key = "InheritFontSizeCritCheckbox"; + MikSBTOpt.SetupCheckbox(FONT_SETTINGS_FRAME_NAME .. key, MikSBTOpt.CHECKBOXES[key].Label, MikSBTOpt.FONT_SETTINGS_TOOLTIPS["ScrollArea"].InheritFontSizeCrit, "DisplaySettings." .. scrollArea .. ".FontSettings.Crit.FontSize"); + + + -- Setup the normal font size slider. + key = "FontSizeSlider"; + MikSBTOpt.SetupSlider(FONT_SETTINGS_FRAME_NAME .. key, MikSBTOpt.SLIDERS[key].Label, MikSBTOpt.FONT_SETTINGS_TOOLTIPS["ScrollArea"].FontSize, MIN_FONT_SIZE, MAX_FONT_SIZE, 2, "DisplaySettings." .. scrollArea .. ".FontSettings.Normal.FontSize"); + + -- Setup the crit font size slider. + key = "FontSizeCritSlider"; + MikSBTOpt.SetupSlider(FONT_SETTINGS_FRAME_NAME .. key, MikSBTOpt.SLIDERS[key].Label, MikSBTOpt.FONT_SETTINGS_TOOLTIPS["ScrollArea"].FontSizeCrit, MIN_FONT_SIZE, MAX_FONT_SIZE, 2, "DisplaySettings." .. scrollArea .. ".FontSettings.Crit.FontSize"); + + + -- Check if the normal font size is inherited. + if (MikSBT.GetOptionFromVarPath("DisplaySettings." .. scrollArea .. ".FontSettings.Normal.FontSize") == 0) then + -- Check the inherited checkbox and hide the slider. + getglobal(FONT_SETTINGS_FRAME_NAME .. "InheritFontSizeCheckbox"):SetChecked(true); + getglobal(FONT_SETTINGS_FRAME_NAME .. "FontSizeSlider"):Hide(); + else + -- Uncheck the inherited checkbox and setup the slider. + getglobal(FONT_SETTINGS_FRAME_NAME .. "InheritFontSizeCheckbox"):SetChecked(false); + getglobal(FONT_SETTINGS_FRAME_NAME .. "FontSizeSlider"):Show(); + + -- Populate the normal font size slider. + MikSBTOpt.PopulateSlider(FONT_SETTINGS_FRAME_NAME .. "FontSizeSlider"); + end + + + -- Check if the critical font size is inherited. + if (MikSBT.GetOptionFromVarPath("DisplaySettings." .. scrollArea .. ".FontSettings.Crit.FontSize") == 0) then + -- Check the inherited checkbox and hide the slider. + getglobal(FONT_SETTINGS_FRAME_NAME .. "InheritFontSizeCritCheckbox"):SetChecked(true); + getglobal(FONT_SETTINGS_FRAME_NAME .. "FontSizeCritSlider"):Hide(); + else + -- Uncheck the inherited checkbox and setup the slider. + getglobal(FONT_SETTINGS_FRAME_NAME .. "InheritFontSizeCritCheckbox"):SetChecked(false); + getglobal(FONT_SETTINGS_FRAME_NAME .. "FontSizeCritSlider"):Show(); + + -- Populate the crit font size slider. + MikSBTOpt.PopulateSlider(FONT_SETTINGS_FRAME_NAME .. "FontSizeCritSlider"); + end + + + -- Show the font settings frame. + fontSettingsFrame:Show(); + + -- Update the font previews. + MikSBTOpt.UpdateFontPreviews(); +end + + +-- ********************************************************************************** +-- Show event font settings. +-- ********************************************************************************** +function MikSBTOpt.ShowEventFontSettings(scrollArea, eventType) + -- Get the inherited font index. + local inheritedFontIndex = MikSBT.GetOptionFromVarPath("DisplaySettings." .. scrollArea .. ".FontSettings.Normal.FontIndex"); + if (inheritedFontIndex == 0) then + inheritedFontIndex = MikSBT.GetOptionFromVarPath("MasterFontSettings.Normal.FontIndex"); + end + + -- Get the inherited outline index. + local inheritedOutlineIndex = MikSBT.GetOptionFromVarPath("DisplaySettings." .. scrollArea .. ".FontSettings.Normal.OutlineIndex"); + if (inheritedOutlineIndex == 0) then + inheritedOutlineIndex = MikSBT.GetOptionFromVarPath("MasterFontSettings.Normal.OutlineIndex"); + end + + -- Get the inherited font size. + local inheritedFontSize = MikSBT.GetOptionFromVarPath("DisplaySettings." .. scrollArea .. ".FontSettings.Normal.FontSize"); + if (inheritedFontSize == 0) then + -- Get the font size from the scroll area and check if it's inherited from the master font size. + inheritedFontSize = MikSBT.GetOptionFromVarPath("MasterFontSettings.Normal.FontSize"); + end + + + + -- Get the inherited crit font index. + local inheritedFontCritIndex = MikSBT.GetOptionFromVarPath("DisplaySettings." .. scrollArea .. ".FontSettings.Crit.FontIndex"); + if (inheritedFontCritIndex == 0) then + inheritedFontCritIndex = MikSBT.GetOptionFromVarPath("MasterFontSettings.Crit.FontIndex"); + end + + -- Get the inherited crit outline index. + local inheritedOutlineCritIndex = MikSBT.GetOptionFromVarPath("DisplaySettings." .. scrollArea .. ".FontSettings.Crit.OutlineIndex"); + if (inheritedOutlineCritIndex == 0) then + inheritedOutlineCritIndex = MikSBT.GetOptionFromVarPath("MasterFontSettings.Crit.OutlineIndex"); + end + + -- Get the inherited crit font size. + local inheritedFontSizeCrit = MikSBT.GetOptionFromVarPath("DisplaySettings." .. scrollArea .. ".FontSettings.Crit.FontSize"); + if (inheritedFontSizeCrit == 0) then + -- Get the font size from the scroll area and check if it's inherited from the master font size. + inheritedFontSizeCrit = MikSBT.GetOptionFromVarPath("MasterFontSettings.Crit.FontSize"); + end + + + -- Get the font settings frame. + local fontSettingsFrame = getglobal(FONT_SETTINGS_FRAME_NAME); + + + -- Set the inherited settings to the frame. + fontSettingsFrame.InheritedFontIndex = inheritedFontIndex; + fontSettingsFrame.InheritedOutlineIndex = inheritedOutlineIndex; + fontSettingsFrame.InheritedFontSize = inheritedFontSize; + fontSettingsFrame.InheritedFontCritIndex = inheritedFontCritIndex; + fontSettingsFrame.InheritedOutlineCritIndex = inheritedOutlineCritIndex; + fontSettingsFrame.InheritedFontSizeCrit = inheritedFontSizeCrit; + + + -- Setup the normal font dropdown. + local key = "FontDropdown"; + MikSBTOpt.SetupDropdown(FONT_SETTINGS_FRAME_NAME .. key, MikSBTOpt.DROPDOWNS[key].Label, MikSBTOpt.FONT_SETTINGS_TOOLTIPS["Event"].Font, MikSBTOpt.FontSettingsDropdownOnClick, availableFontsInherit, "EventSettings." .. eventType .. ".FontSettings.Normal.FontIndex"); + MikSBTOpt.PopulateDropdown(FONT_SETTINGS_FRAME_NAME .. key); + + -- Setup the normal font outline dropdown. + key = "FontOutlineDropdown"; + MikSBTOpt.SetupDropdown(FONT_SETTINGS_FRAME_NAME .. key, MikSBTOpt.DROPDOWNS[key].Label, MikSBTOpt.FONT_SETTINGS_TOOLTIPS["Event"].Outline, MikSBTOpt.FontSettingsDropdownOnClick, availableOutlinesInherit, "EventSettings." .. eventType .. ".FontSettings.Normal.OutlineIndex"); + MikSBTOpt.PopulateDropdown(FONT_SETTINGS_FRAME_NAME .. key); + + + -- Show the inherit normal font size checkbox. + getglobal(FONT_SETTINGS_FRAME_NAME .. "InheritFontSizeCheckbox"):Show(); + + + -- Setup the inherit normal font size checkbox. + key = "InheritFontSizeCheckbox"; + MikSBTOpt.SetupCheckbox(FONT_SETTINGS_FRAME_NAME .. key, MikSBTOpt.CHECKBOXES[key].Label, MikSBTOpt.FONT_SETTINGS_TOOLTIPS["Event"].InheritFontSize, "EventSettings." .. eventType .. ".FontSettings.Normal.FontSize"); + + -- Setup the normal font size slider. + key = "FontSizeSlider"; + MikSBTOpt.SetupSlider(FONT_SETTINGS_FRAME_NAME .. key, MikSBTOpt.SLIDERS[key].Label, MikSBTOpt.FONT_SETTINGS_TOOLTIPS["Event"].FontSize, MIN_FONT_SIZE, MAX_FONT_SIZE, 2, "EventSettings." .. eventType .. ".FontSettings.Normal.FontSize"); + + + -- Check if the normal font size is inherited. + if (MikSBT.GetOptionFromVarPath("EventSettings." .. eventType .. ".FontSettings.Normal.FontSize") == 0) then + -- Check the inherited checkbox and hide the slider. + getglobal(FONT_SETTINGS_FRAME_NAME .. "InheritFontSizeCheckbox"):SetChecked(true); + getglobal(FONT_SETTINGS_FRAME_NAME .. "FontSizeSlider"):Hide(); + else + -- Uncheck the inherited checkbox and setup the slider. + getglobal(FONT_SETTINGS_FRAME_NAME .. "InheritFontSizeCheckbox"):SetChecked(false); + getglobal(FONT_SETTINGS_FRAME_NAME .. "FontSizeSlider"):Show(); + + -- Populate the normal font size slider. + MikSBTOpt.PopulateSlider(FONT_SETTINGS_FRAME_NAME .. "FontSizeSlider"); + end + + + + -- Check if the event type supports crits. + if (MikSBT.CurrentProfile.EventSettings[eventType].FontSettings.Crit ~= nil) then + -- Show the crit font settings controls. + MikSBTOpt.ShowCritFontControls(); + + -- Setup the crit font dropdown. + key = "FontCritDropdown"; + MikSBTOpt.SetupDropdown(FONT_SETTINGS_FRAME_NAME .. key, MikSBTOpt.DROPDOWNS[key].Label, MikSBTOpt.FONT_SETTINGS_TOOLTIPS["Event"].FontCrit, MikSBTOpt.FontSettingsDropdownOnClick, availableFontsInherit, "EventSettings." .. eventType .. ".FontSettings.Crit.FontIndex"); + MikSBTOpt.PopulateDropdown(FONT_SETTINGS_FRAME_NAME .. key); + + -- Setup the crit font outline dropdown. + key = "FontOutlineCritDropdown"; + MikSBTOpt.SetupDropdown(FONT_SETTINGS_FRAME_NAME .. key, MikSBTOpt.DROPDOWNS[key].Label, MikSBTOpt.FONT_SETTINGS_TOOLTIPS["Event"].OutlineCrit, MikSBTOpt.FontSettingsDropdownOnClick, availableOutlinesInherit, "EventSettings." .. eventType .. ".FontSettings.Crit.OutlineIndex"); + MikSBTOpt.PopulateDropdown(FONT_SETTINGS_FRAME_NAME .. key); + + + -- Show the inherit crit font size checkbox. + getglobal(FONT_SETTINGS_FRAME_NAME .. "InheritFontSizeCritCheckbox"):Show(); + + + -- Setup the inherit crit font size checkbox. + key = "InheritFontSizeCritCheckbox"; + MikSBTOpt.SetupCheckbox(FONT_SETTINGS_FRAME_NAME .. key, MikSBTOpt.CHECKBOXES[key].Label, MikSBTOpt.FONT_SETTINGS_TOOLTIPS["Event"].InheritFontSizeCrit, "EventSettings." .. eventType .. ".FontSettings.Crit.FontSize"); + + -- Setup the crit font size slider. + key = "FontSizeCritSlider"; + MikSBTOpt.SetupSlider(FONT_SETTINGS_FRAME_NAME .. key, MikSBTOpt.SLIDERS[key].Label, MikSBTOpt.FONT_SETTINGS_TOOLTIPS["Event"].FontSizeCrit, MIN_FONT_SIZE, MAX_FONT_SIZE, 2, "EventSettings." .. eventType .. ".FontSettings.Crit.FontSize"); + + -- Check if the critical font size is inherited. + if (MikSBT.GetOptionFromVarPath("EventSettings." .. eventType .. ".FontSettings.Crit.FontSize") == 0) then + -- Check the inherited checkbox and hide the slider. + getglobal(FONT_SETTINGS_FRAME_NAME .. "InheritFontSizeCritCheckbox"):SetChecked(true); + getglobal(FONT_SETTINGS_FRAME_NAME .. "FontSizeCritSlider"):Hide(); + else + -- Uncheck the inherited checkbox and setup the slider. + getglobal(FONT_SETTINGS_FRAME_NAME .. "InheritFontSizeCritCheckbox"):SetChecked(false); + getglobal(FONT_SETTINGS_FRAME_NAME .. "FontSizeCritSlider"):Show(); + + -- Populate the crit font size slider. + MikSBTOpt.PopulateSlider(FONT_SETTINGS_FRAME_NAME .. "FontSizeCritSlider"); + end + + -- The event type does not support crits. + else + -- Hide the crit font settings controls. + MikSBTOpt.HideCritFontControls(); + end + + + -- Show the font settings frame. + fontSettingsFrame:Show(); + + -- Update the font previews. + MikSBTOpt.UpdateFontPreviews(); +end + + +-- ********************************************************************************** +-- Show trigger font settings. +-- ********************************************************************************** +function MikSBTOpt.ShowTriggerFontSettings(triggerKey) + -- Get the inherited font index. + local inheritedFontIndex = MikSBT.GetOptionFromVarPath("DisplaySettings.Notification.FontSettings.Normal.FontIndex"); + if (inheritedFontIndex == 0) then + inheritedFontIndex = MikSBT.GetOptionFromVarPath("MasterFontSettings.Normal.FontIndex"); + end + + -- Get the inherited outline index. + local inheritedOutlineIndex = MikSBT.GetOptionFromVarPath("DisplaySettings.Notification.FontSettings.Normal.OutlineIndex"); + if (inheritedOutlineIndex == 0) then + inheritedOutlineIndex = MikSBT.GetOptionFromVarPath("MasterFontSettings.Normal.OutlineIndex"); + end + + -- Get the inherited font size. + local inheritedFontSize = MikSBT.GetOptionFromVarPath("DisplaySettings.Notification.FontSettings.Normal.FontSize"); + if (inheritedFontSize == 0) then + -- Get the font size from the scroll area and check if it's inherited from the master font size. + inheritedFontSize = MikSBT.GetOptionFromVarPath("MasterFontSettings.Normal.FontSize"); + end + + + -- Get the font settings frame. + local fontSettingsFrame = getglobal(FONT_SETTINGS_FRAME_NAME); + + + -- Set the inherited settings to the frame. + fontSettingsFrame.InheritedFontIndex = inheritedFontIndex; + fontSettingsFrame.InheritedOutlineIndex = inheritedOutlineIndex; + fontSettingsFrame.InheritedFontSize = inheritedFontSize; + + + -- Setup the normal font dropdown. + local key = "FontDropdown"; + MikSBTOpt.SetupDropdown(FONT_SETTINGS_FRAME_NAME .. key, MikSBTOpt.DROPDOWNS[key].Label, MikSBTOpt.FONT_SETTINGS_TOOLTIPS["Trigger"].Font, MikSBTOpt.FontSettingsDropdownOnClick, availableFontsInherit, "Triggers." .. triggerKey .. ".EventSettings.FontSettings.Normal.FontIndex"); + MikSBTOpt.PopulateDropdown(FONT_SETTINGS_FRAME_NAME .. key); + + -- Setup the normal font outline dropdown. + key = "FontOutlineDropdown"; + MikSBTOpt.SetupDropdown(FONT_SETTINGS_FRAME_NAME .. key, MikSBTOpt.DROPDOWNS[key].Label, MikSBTOpt.FONT_SETTINGS_TOOLTIPS["Trigger"].Outline, MikSBTOpt.FontSettingsDropdownOnClick, availableOutlinesInherit, "Triggers." .. triggerKey .. ".EventSettings.FontSettings.Normal.OutlineIndex"); + MikSBTOpt.PopulateDropdown(FONT_SETTINGS_FRAME_NAME .. key); + + + -- Show the inherit normal font size checkbox. + getglobal(FONT_SETTINGS_FRAME_NAME .. "InheritFontSizeCheckbox"):Show(); + + + -- Setup the inherit normal font size checkbox. + key = "InheritFontSizeCheckbox"; + MikSBTOpt.SetupCheckbox(FONT_SETTINGS_FRAME_NAME .. key, MikSBTOpt.CHECKBOXES[key].Label, MikSBTOpt.FONT_SETTINGS_TOOLTIPS["Trigger"].InheritFontSize, "Triggers." .. triggerKey .. ".EventSettings.FontSettings.Normal.FontSize"); + + -- Setup the normal font size slider. + key = "FontSizeSlider"; + MikSBTOpt.SetupSlider(FONT_SETTINGS_FRAME_NAME .. key, MikSBTOpt.SLIDERS[key].Label, MikSBTOpt.FONT_SETTINGS_TOOLTIPS["Trigger"].FontSize, MIN_FONT_SIZE, MAX_FONT_SIZE, 2, "Triggers." .. triggerKey .. ".EventSettings.FontSettings.Normal.FontSize"); + + + -- Check if the normal font size is inherited. + if (MikSBT.GetOptionFromVarPath("Triggers." .. triggerKey .. ".EventSettings.FontSettings.Normal.FontSize") == 0) then + -- Check the inherited checkbox and hide the slider. + getglobal(FONT_SETTINGS_FRAME_NAME .. "InheritFontSizeCheckbox"):SetChecked(true); + getglobal(FONT_SETTINGS_FRAME_NAME .. "FontSizeSlider"):Hide(); + else + -- Uncheck the inherited checkbox and setup the slider. + getglobal(FONT_SETTINGS_FRAME_NAME .. "InheritFontSizeCheckbox"):SetChecked(false); + getglobal(FONT_SETTINGS_FRAME_NAME .. "FontSizeSlider"):Show(); + + -- Populate the normal font size slider. + MikSBTOpt.PopulateSlider(FONT_SETTINGS_FRAME_NAME .. "FontSizeSlider"); + end + + + -- Hide the crit font settings controls. + MikSBTOpt.HideCritFontControls(); + + + -- Show the font settings frame. + fontSettingsFrame:Show(); + + -- Update the font previews. + MikSBTOpt.UpdateFontPreviews(); +end + + +-- ********************************************************************************** +-- Updates the font previews with values selected. +-- ********************************************************************************** +function MikSBTOpt.UpdateFontPreviews() + -- Get the font settings frame. + local fontSettingsFrame = getglobal(FONT_SETTINGS_FRAME_NAME); + + -- Get the selected normal font index. + local fontIndex = UIDropDownMenu_GetSelectedValue(getglobal(FONT_SETTINGS_FRAME_NAME .. "FontDropdown")); + if (fontIndex == 0) then + fontIndex = fontSettingsFrame.InheritedFontIndex; + end + + -- Get the selected normal outline index. + local outlineIndex = UIDropDownMenu_GetSelectedValue(getglobal(FONT_SETTINGS_FRAME_NAME .. "FontOutlineDropdown")); + if (outlineIndex == 0) then + outlineIndex = fontSettingsFrame.InheritedOutlineIndex; + end + + -- Check if the normal font size slider is shown. + local slider = getglobal(FONT_SETTINGS_FRAME_NAME .. "FontSizeSlider"); + local fontSize; + if (slider:IsShown()) then + -- Get the selected font size. + fontSize = slider:GetValue(); + else + -- Get the inherited font size. + fontSize = fontSettingsFrame.InheritedFontSize; + end + + + -- Make sure the normal font index is valid. + if (fontIndex ~= nil) then + local previewText = getglobal(FONT_SETTINGS_FRAME_NAME .. "NormalPreviewText"); + previewText:SetFont(MikSBT.AVAILABLE_FONTS[fontIndex].Path, fontSize, MikSBT.AVAILABLE_OUTLINES[outlineIndex].Style); + end + + + + -- Check if crits are to be shown. + if (getglobal(FONT_SETTINGS_FRAME_NAME .. "CritPreview"):IsShown()) then + -- Get the selected crit font index. + local fontCritIndex = UIDropDownMenu_GetSelectedValue(getglobal(FONT_SETTINGS_FRAME_NAME .. "FontCritDropdown")); + if (fontCritIndex == 0) then + fontCritIndex = fontSettingsFrame.InheritedFontCritIndex; + end + + + -- Get the selected crit outline index. + local outlineCritIndex = UIDropDownMenu_GetSelectedValue(getglobal(FONT_SETTINGS_FRAME_NAME .. "FontOutlineCritDropdown")); + if (outlineCritIndex == 0) then + outlineCritIndex = fontSettingsFrame.InheritedOutlineCritIndex; + end + + + -- Check if the crit font size slider is shown. + local slider = getglobal(FONT_SETTINGS_FRAME_NAME .. "FontSizeCritSlider"); + local fontSizeCrit; + if (slider:IsShown()) then + -- Get the selected crit font size. + fontSizeCrit = slider:GetValue(); + else + -- Get the inherited crit font size. + fontSizeCrit = fontSettingsFrame.InheritedFontSizeCrit; + end + + -- Make sure the crit font index is valid. + if (fontCritIndex ~= nil) then + local previewText = getglobal(FONT_SETTINGS_FRAME_NAME .. "CritPreviewText"); + previewText:SetFont(MikSBT.AVAILABLE_FONTS[fontCritIndex].Path, fontSizeCrit, MikSBT.AVAILABLE_OUTLINES[outlineCritIndex].Style); + end + end +end + + +-- ********************************************************************************** +-- Shows the crit font settings controls. +-- ********************************************************************************** +function MikSBTOpt.ShowCritFontControls() + -- Show all of the crit font settings controls. + getglobal(FONT_SETTINGS_FRAME_NAME .. "FontCritDropdown"):Show(); + getglobal(FONT_SETTINGS_FRAME_NAME .. "FontOutlineCritDropdown"):Show(); + getglobal(FONT_SETTINGS_FRAME_NAME .. "InheritFontSizeCritCheckbox"):Show(); + getglobal(FONT_SETTINGS_FRAME_NAME .. "FontSizeCritSlider"):Show(); + getglobal(FONT_SETTINGS_FRAME_NAME .. "CritPreview"):Show(); + + -- Move the normal font controls back to the left side. + getglobal(FONT_SETTINGS_FRAME_NAME .. "FontDropdown"):SetPoint("TOPLEFT", FONT_SETTINGS_FRAME_NAME, "TOPLEFT", 0, -60); +end + + +-- ********************************************************************************** +-- Hides the crit font settings controls. +-- ********************************************************************************** +function MikSBTOpt.HideCritFontControls() + -- Hide all of the crit font settings controls. + getglobal(FONT_SETTINGS_FRAME_NAME .. "FontCritDropdown"):Hide(); + getglobal(FONT_SETTINGS_FRAME_NAME .. "FontOutlineCritDropdown"):Hide(); + getglobal(FONT_SETTINGS_FRAME_NAME .. "InheritFontSizeCritCheckbox"):Hide(); + getglobal(FONT_SETTINGS_FRAME_NAME .. "FontSizeCritSlider"):Hide(); + getglobal(FONT_SETTINGS_FRAME_NAME .. "CritPreview"):Hide(); + + -- Center the normal font controls. + getglobal(FONT_SETTINGS_FRAME_NAME .. "FontDropdown"):SetPoint("TOPLEFT", FONT_SETTINGS_FRAME_NAME, "TOPLEFT", 85, -60); +end + + + +------------------------------------------------------------------------------------- +-- Scroll area mover functions. +------------------------------------------------------------------------------------- + +-- ********************************************************************************** +-- Setup and show the scroll area mover controls. +-- ********************************************************************************** +function MikSBTOpt.ShowScrollAreaMoverFrames(scrollArea) + local controlFrame = getglobal(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME); + + -- Check if the original settings settings table hasn't been created yet and create it if not. + if (not controlFrame.MSBTOriginalSettings) then controlFrame.MSBTOriginalSettings = {}; end + + + -- Save the original incoming scroll area settings into the control frame. + controlFrame.MSBTOriginalSettings.IncomingAnimationStyle = MikSBT.GetOptionFromVarPath("DisplaySettings.Incoming.AnimationStyle"); + controlFrame.MSBTOriginalSettings.IncomingScrollDirection = MikSBT.GetOptionFromVarPath("DisplaySettings.Incoming.ScrollDirection"); + controlFrame.MSBTOriginalSettings.IncomingTextAlignIndex = MikSBT.GetOptionFromVarPath("DisplaySettings.Incoming.FontSettings.TextAlignIndex"); + controlFrame.MSBTOriginalSettings.IncomingScrollHeight = MikSBT.GetOptionFromVarPath("DisplaySettings.Incoming.ScrollHeight"); + controlFrame.MSBTOriginalSettings.IncomingXOffset = MikSBT.GetOptionFromVarPath("DisplaySettings.Incoming.FrameOffsets.x"); + controlFrame.MSBTOriginalSettings.IncomingYOffset = MikSBT.GetOptionFromVarPath("DisplaySettings.Incoming.FrameOffsets.y"); + + -- Save the original outgoing scroll area settings into the control frame. + controlFrame.MSBTOriginalSettings.OutgoingAnimationStyle = MikSBT.GetOptionFromVarPath("DisplaySettings.Outgoing.AnimationStyle"); + controlFrame.MSBTOriginalSettings.OutgoingScrollDirection = MikSBT.GetOptionFromVarPath("DisplaySettings.Outgoing.ScrollDirection"); + controlFrame.MSBTOriginalSettings.OutgoingTextAlignIndex = MikSBT.GetOptionFromVarPath("DisplaySettings.Outgoing.FontSettings.TextAlignIndex"); + controlFrame.MSBTOriginalSettings.OutgoingScrollHeight = MikSBT.GetOptionFromVarPath("DisplaySettings.Outgoing.ScrollHeight"); + controlFrame.MSBTOriginalSettings.OutgoingXOffset = MikSBT.GetOptionFromVarPath("DisplaySettings.Outgoing.FrameOffsets.x"); + controlFrame.MSBTOriginalSettings.OutgoingYOffset = MikSBT.GetOptionFromVarPath("DisplaySettings.Outgoing.FrameOffsets.y"); + + -- Save the original notification scroll area settings into the control frame. + controlFrame.MSBTOriginalSettings.NotificationAnimationStyle = MikSBT.GetOptionFromVarPath("DisplaySettings.Notification.AnimationStyle"); + controlFrame.MSBTOriginalSettings.NotificationScrollDirection = MikSBT.GetOptionFromVarPath("DisplaySettings.Notification.ScrollDirection"); + controlFrame.MSBTOriginalSettings.NotificationTextAlignIndex = MikSBT.GetOptionFromVarPath("DisplaySettings.Notification.FontSettings.TextAlignIndex"); + controlFrame.MSBTOriginalSettings.NotificationScrollHeight = MikSBT.GetOptionFromVarPath("DisplaySettings.Notification.ScrollHeight"); + controlFrame.MSBTOriginalSettings.NotificationXOffset = MikSBT.GetOptionFromVarPath("DisplaySettings.Notification.FrameOffsets.x"); + controlFrame.MSBTOriginalSettings.NotificationYOffset = MikSBT.GetOptionFromVarPath("DisplaySettings.Notification.FrameOffsets.y"); + + + -- Set the starting current settings. + controlFrame.MSBTCurrentSettings = MikSBT.CopyTable(controlFrame.MSBTOriginalSettings); + + + -- Select the starting scroll area based on the passed scroll area. + MikSBTOpt.PopulateDropdown(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. "ScrollAreaDropdown", scrollArea); + MikSBTOpt.PopulateScrollAreaControls(scrollArea); + + + -- Get the scroll area mover frames for each scroll area. + local incomingFrame = getglobal(SCROLL_AREA_MOVER_INCOMING_FRAME_NAME); + local outgoingFrame = getglobal(SCROLL_AREA_MOVER_OUTGOING_FRAME_NAME); + local notificationFrame = getglobal(SCROLL_AREA_MOVER_NOTIFICATION_FRAME_NAME); + + + -- Set the tooltip for the scroll area mover frames. + incomingFrame.tooltipText = MikSBTOpt.FRAMES[SCROLL_AREA_MOVER_INCOMING_FRAME_NAME].Tooltip; + outgoingFrame.tooltipText = MikSBTOpt.FRAMES[SCROLL_AREA_MOVER_OUTGOING_FRAME_NAME].Tooltip; + notificationFrame.tooltipText = MikSBTOpt.FRAMES[SCROLL_AREA_MOVER_NOTIFICATION_FRAME_NAME].Tooltip; + + -- Reposition the scroll area mover frames. + MikSBTOpt.RepositionScrollAreaMoverFrames(); + + -- Populates the scroll area mover coordinates. + MikSBTOpt.PopulateScrollAreaMoverCoordinates() + + -- Show the scroll area mover frames. + controlFrame:Show(); + incomingFrame:Show(); + outgoingFrame:Show(); + notificationFrame:Show(); + + -- Hide the options frame. + getglobal(OPTIONS_FRAME_NAME):Hide(); +end + + +-- ********************************************************************************** +-- Closes the scroll area mover controls and opens the options screen back up. +-- ********************************************************************************** +function MikSBTOpt.HideScrollAreaMoverFrames() + -- Show the options frame. + getglobal(OPTIONS_FRAME_NAME):Show(); + + -- Hide the scroll area mover frames. + getglobal(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME):Hide(); + getglobal(SCROLL_AREA_MOVER_INCOMING_FRAME_NAME):Hide(); + getglobal(SCROLL_AREA_MOVER_OUTGOING_FRAME_NAME):Hide(); + getglobal(SCROLL_AREA_MOVER_NOTIFICATION_FRAME_NAME):Hide(); +end + + +-- ********************************************************************************** +-- Repositions all of the scroll area mover frames with the values in the current +-- settings of the control frame. +-- ********************************************************************************** +function MikSBTOpt.RepositionScrollAreaMoverFrames() + -- Get the scroll area mover control frame and all of the scroll area mover frames. + local controlFrame = getglobal(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME); + local incomingFrame = getglobal(SCROLL_AREA_MOVER_INCOMING_FRAME_NAME); + local outgoingFrame = getglobal(SCROLL_AREA_MOVER_OUTGOING_FRAME_NAME); + local notificationFrame = getglobal(SCROLL_AREA_MOVER_NOTIFICATION_FRAME_NAME); + + -- Reposition the incoming scroll area frame. + incomingFrame:SetHeight(controlFrame.MSBTCurrentSettings.IncomingScrollHeight); + incomingFrame:ClearAllPoints(); + incomingFrame:SetPoint("BOTTOM", UIParent, "CENTER", controlFrame.MSBTCurrentSettings.IncomingXOffset, controlFrame.MSBTCurrentSettings.IncomingYOffset); + + -- Reposition the outgoing scroll area frame. + outgoingFrame:SetHeight(controlFrame.MSBTCurrentSettings.OutgoingScrollHeight); + outgoingFrame:ClearAllPoints(); + outgoingFrame:SetPoint("BOTTOM", UIParent, "CENTER", controlFrame.MSBTCurrentSettings.OutgoingXOffset, controlFrame.MSBTCurrentSettings.OutgoingYOffset); + + -- Reposition the notification scroll area frame. + notificationFrame:SetHeight(controlFrame.MSBTCurrentSettings.NotificationScrollHeight); + notificationFrame:ClearAllPoints(); + notificationFrame:SetPoint("BOTTOM", UIParent, "CENTER", controlFrame.MSBTCurrentSettings.NotificationXOffset, controlFrame.MSBTCurrentSettings.NotificationYOffset); + + -- Populate the scroll area mover coordinates. + MikSBTOpt.PopulateScrollAreaMoverCoordinates(); +end + + +-- ********************************************************************************** +-- Colorizes the scroll area mover frames. +-- ********************************************************************************** +function MikSBTOpt.ColorizeScrollAreaMoverFrames(scrollArea) + -- Get the scroll area mover frames for each scroll area. + local incomingFrame = getglobal(SCROLL_AREA_MOVER_INCOMING_FRAME_NAME); + local outgoingFrame = getglobal(SCROLL_AREA_MOVER_OUTGOING_FRAME_NAME); + local notificationFrame = getglobal(SCROLL_AREA_MOVER_NOTIFICATION_FRAME_NAME); + + -- Set the colors appropriately. + if (scrollArea == "Incoming") then + incomingFrame:SetBackdropColor(0.5, 0.05, 0.05, 1.0); + outgoingFrame:SetBackdropColor(0.8, 0.8, 0.8, 1.0); + notificationFrame:SetBackdropColor(0.8, 0.8, 0.8, 1.0); + elseif (scrollArea == "Outgoing") then + incomingFrame:SetBackdropColor(0.8, 0.8, 0.8, 1.0); + outgoingFrame:SetBackdropColor(0.5, 0.05, 0.05, 1.0); + notificationFrame:SetBackdropColor(0.8, 0.8, 0.8, 1.0); + elseif (scrollArea == "Notification") then + incomingFrame:SetBackdropColor(0.8, 0.8, 0.8, 1.0); + outgoingFrame:SetBackdropColor(0.8, 0.8, 0.8, 1.0); + notificationFrame:SetBackdropColor(0.5, 0.05, 0.05, 1.0); + end +end + + +-- ********************************************************************************** +-- Populates the controls for the selected scroll area. +-- ********************************************************************************** +function MikSBTOpt.PopulateScrollAreaControls(scrollArea) + local controlFrame = getglobal(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME); + MikSBTOpt.PopulateDropdown(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. "AnimationStyleDropdown", controlFrame.MSBTCurrentSettings[scrollArea .. "AnimationStyle"]); + MikSBTOpt.PopulateDropdown(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. "ScrollDirectionDropdown", controlFrame.MSBTCurrentSettings[scrollArea .. "ScrollDirection"]); + MikSBTOpt.PopulateDropdown(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. "TextAlignDropdown", controlFrame.MSBTCurrentSettings[scrollArea .. "TextAlignIndex"]); + MikSBTOpt.PopulateSlider(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. "ScrollHeightSlider", controlFrame.MSBTCurrentSettings[scrollArea .. "ScrollHeight"]); + MikSBTOpt.PopulateEditbox(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. "XOffsetEditbox", controlFrame.MSBTCurrentSettings[scrollArea .. "XOffset"]); + MikSBTOpt.PopulateEditbox(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. "YOffsetEditbox", controlFrame.MSBTCurrentSettings[scrollArea .. "YOffset"]); + + -- Colorize the selected scroll area mover frame. + MikSBTOpt.ColorizeScrollAreaMoverFrames(scrollArea) +end + + +-- ********************************************************************************** +-- Populates the scroll area mover labels with the scroll area's coordinates. +-- ********************************************************************************** +function MikSBTOpt.PopulateScrollAreaMoverCoordinates() + -- Get the scroll area mover control frame. + local controlFrame = getglobal(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME); + + -- Populate the labels. + getglobal(SCROLL_AREA_MOVER_INCOMING_FRAME_NAME .. "Title"):SetText(MikSBTOpt.TABS[TAB_INDEX_INCOMING].Label .. " (" .. controlFrame.MSBTCurrentSettings.IncomingXOffset .. ", " .. controlFrame.MSBTCurrentSettings.IncomingYOffset .. ")"); + getglobal(SCROLL_AREA_MOVER_OUTGOING_FRAME_NAME .. "Title"):SetText(MikSBTOpt.TABS[TAB_INDEX_OUTGOING].Label .. " (" .. controlFrame.MSBTCurrentSettings.OutgoingXOffset .. ", " .. controlFrame.MSBTCurrentSettings.OutgoingYOffset .. ")"); + getglobal(SCROLL_AREA_MOVER_NOTIFICATION_FRAME_NAME .. "Title"):SetText(MikSBTOpt.TABS[TAB_INDEX_NOTIFICATION].Label .. " (" .. controlFrame.MSBTCurrentSettings.NotificationXOffset .. ", " .. controlFrame.MSBTCurrentSettings.NotificationYOffset .. ")"); + + -- Populate the x and y offset editboxes. + local scrollArea = UIDropDownMenu_GetSelectedValue(getglobal(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. "ScrollAreaDropdown")); + MikSBTOpt.PopulateEditbox(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. "XOffsetEditbox", controlFrame.MSBTCurrentSettings[scrollArea .. "XOffset"]); + MikSBTOpt.PopulateEditbox(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. "YOffsetEditbox", controlFrame.MSBTCurrentSettings[scrollArea .. "YOffset"]); +end + + +-- ********************************************************************************** +-- Save the coordinates of the scroll area mover to the control frame's current +-- settings. +-- ********************************************************************************** +function MikSBTOpt.SaveScrollAreaMoverCoordinates(frameName) + local controlFrame = getglobal(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME); + + -- Get the UIParent center x and y coords. + local uiParentX, uiParentY = UIParent:GetCenter(); + local xOffset = math.floor(this:GetCenter() - uiParentX); + local yOffset = math.ceil(this:GetBottom() - uiParentY); + + -- Save the coordinates for the correct scroll area. + if (frameName == SCROLL_AREA_MOVER_INCOMING_FRAME_NAME) then + controlFrame.MSBTCurrentSettings.IncomingXOffset = xOffset; + controlFrame.MSBTCurrentSettings.IncomingYOffset = yOffset; + elseif (frameName == SCROLL_AREA_MOVER_OUTGOING_FRAME_NAME) then + controlFrame.MSBTCurrentSettings.OutgoingXOffset = xOffset; + controlFrame.MSBTCurrentSettings.OutgoingYOffset = yOffset; + elseif (frameName == SCROLL_AREA_MOVER_NOTIFICATION_FRAME_NAME) then + controlFrame.MSBTCurrentSettings.NotificationXOffset = xOffset; + controlFrame.MSBTCurrentSettings.NotificationYOffset = yOffset; + end + + -- Populate the scroll area mover coordinates. + MikSBTOpt.PopulateScrollAreaMoverCoordinates(); +end + + +-- ********************************************************************************** +-- Save the values selected in the scroll area mover controls to the current settings +-- of the sroll area mover control frame. +-- ********************************************************************************** +function MikSBTOpt.SaveScrollAreaControlsToCurrentSettings() + -- Get the currently selected scroll area and the scroll area mover control frame. + local scrollArea = UIDropDownMenu_GetSelectedValue(getglobal(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. "ScrollAreaDropdown")); + local controlFrame = getglobal(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME); + + -- Set the control frame's current settings to the values in the controls. + controlFrame.MSBTCurrentSettings[scrollArea .. "AnimationStyle"] = UIDropDownMenu_GetSelectedValue(getglobal(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. "AnimationStyleDropdown")); + controlFrame.MSBTCurrentSettings[scrollArea .. "ScrollDirection"] = UIDropDownMenu_GetSelectedValue(getglobal(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. "ScrollDirectionDropdown")); + controlFrame.MSBTCurrentSettings[scrollArea .. "TextAlignIndex"] = UIDropDownMenu_GetSelectedValue(getglobal(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. "TextAlignDropdown")); + controlFrame.MSBTCurrentSettings[scrollArea .. "ScrollHeight"] = getglobal(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. "ScrollHeightSlider"):GetValue(); + + -- Get the x offset from the x offset editbox and make sure it's a number. + local xOffset = tonumber(getglobal(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. "XOffsetEditbox"):GetText()); + if (xOffset ~= nil) then + controlFrame.MSBTCurrentSettings[scrollArea .. "XOffset"] = xOffset; + end + + -- Get the y offset from the y offset editbox and make sure it's a number. + local yOffset = tonumber(getglobal(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME .. "YOffsetEditbox"):GetText()); + if (yOffset ~= nil) then + controlFrame.MSBTCurrentSettings[scrollArea .. "YOffset"] = yOffset; + end +end + + +-- ********************************************************************************** +-- Save the settings of the scroll area mover control to the profile for the +-- passed settings type. +-- ********************************************************************************** +function MikSBTOpt.SaveScrollAreaSettings(settingsType) + -- Save the settings in the controls to the control frame's current settings. + MikSBTOpt.SaveScrollAreaControlsToCurrentSettings(); + + -- Get the scroll area mover control frame. + local controlFrame = getglobal(SCROLL_AREA_MOVER_CONTROL_FRAME_NAME); + + -- Save the incoming scroll area settings into the profile. + MikSBT.SetOptionFromVarPath("DisplaySettings.Incoming.AnimationStyle", controlFrame[settingsType].IncomingAnimationStyle); + MikSBT.SetOptionFromVarPath("DisplaySettings.Incoming.ScrollDirection", controlFrame[settingsType].IncomingScrollDirection); + MikSBT.SetOptionFromVarPath("DisplaySettings.Incoming.FontSettings.TextAlignIndex", controlFrame[settingsType].IncomingTextAlignIndex); + MikSBT.SetOptionFromVarPath("DisplaySettings.Incoming.ScrollHeight", controlFrame[settingsType].IncomingScrollHeight); + MikSBT.SetOptionFromVarPath("DisplaySettings.Incoming.FrameOffsets.x", controlFrame[settingsType].IncomingXOffset); + MikSBT.SetOptionFromVarPath("DisplaySettings.Incoming.FrameOffsets.y", controlFrame[settingsType].IncomingYOffset); + + -- Save the outgoing scroll area settings into the profile. + MikSBT.SetOptionFromVarPath("DisplaySettings.Outgoing.AnimationStyle", controlFrame[settingsType].OutgoingAnimationStyle); + MikSBT.SetOptionFromVarPath("DisplaySettings.Outgoing.ScrollDirection", controlFrame[settingsType].OutgoingScrollDirection); + MikSBT.SetOptionFromVarPath("DisplaySettings.Outgoing.FontSettings.TextAlignIndex", controlFrame[settingsType].OutgoingTextAlignIndex); + MikSBT.SetOptionFromVarPath("DisplaySettings.Outgoing.ScrollHeight", controlFrame[settingsType].OutgoingScrollHeight); + MikSBT.SetOptionFromVarPath("DisplaySettings.Outgoing.FrameOffsets.x", controlFrame[settingsType].OutgoingXOffset); + MikSBT.SetOptionFromVarPath("DisplaySettings.Outgoing.FrameOffsets.y", controlFrame[settingsType].OutgoingYOffset); + + -- Save the notification scroll area settings into the profile. + MikSBT.SetOptionFromVarPath("DisplaySettings.Notification.AnimationStyle", controlFrame[settingsType].NotificationAnimationStyle); + MikSBT.SetOptionFromVarPath("DisplaySettings.Notification.ScrollDirection", controlFrame[settingsType].NotificationScrollDirection); + MikSBT.SetOptionFromVarPath("DisplaySettings.Notification.FontSettings.TextAlignIndex", controlFrame[settingsType].NotificationTextAlignIndex); + MikSBT.SetOptionFromVarPath("DisplaySettings.Notification.ScrollHeight", controlFrame[settingsType].NotificationScrollHeight); + MikSBT.SetOptionFromVarPath("DisplaySettings.Notification.FrameOffsets.x", controlFrame[settingsType].NotificationXOffset); + MikSBT.SetOptionFromVarPath("DisplaySettings.Notification.FrameOffsets.y", controlFrame[settingsType].NotificationYOffset); + + + -- Reposition the animation frames. + MikSBT.RepositionAnimationFrames(); +end + + +-- ********************************************************************************** +-- Previews a test message in the new scroll area position. +-- ********************************************************************************** +function MikSBTOpt.ScrollAreaMoverPreviewOnClick() + -- Save the current settings for all the scroll areas. + MikSBTOpt.SaveScrollAreaSettings("MSBTCurrentSettings"); + + -- Display the preview messages. + MikSBT.DisplayMessage(MikSBTOpt.MSG_SCROLL_AREA_PREVIEW_TEXT, MikSBT.DISPLAYTYPE_INCOMING, false, 255, 0, 0); + MikSBT.DisplayMessage(MikSBTOpt.MSG_SCROLL_AREA_PREVIEW_TEXT, MikSBT.DISPLAYTYPE_NOTIFICATION, false); + MikSBT.DisplayMessage(MikSBTOpt.MSG_SCROLL_AREA_PREVIEW_TEXT, MikSBT.DISPLAYTYPE_OUTGOING, false, 0, 0, 255); +end + + +-- ********************************************************************************** +-- Called the save button on the scroll area mover is clicked. +-- ********************************************************************************** +function MikSBTOpt.ScrollAreaMoverSaveOnClick() + -- Save the current settings for all the scroll areas. + MikSBTOpt.SaveScrollAreaSettings("MSBTCurrentSettings"); + + -- Show the options frame and hide the scroll area mover frames. + MikSBTOpt.HideScrollAreaMoverFrames(); +end + + +-- ********************************************************************************** +-- Cancels the changes made to the scroll area mover. +-- ********************************************************************************** +function MikSBTOpt.ScrollAreaMoverCancelOnClick() + -- Save the original settings for all the scroll areas. + MikSBTOpt.SaveScrollAreaSettings("MSBTOriginalSettings"); + + -- Show the options frame and hide the scroll area mover frames. + MikSBTOpt.HideScrollAreaMoverFrames(); +end + + + +------------------------------------------------------------------------------------- +-- Trigger functions. +------------------------------------------------------------------------------------- + +-- ********************************************************************************** +-- Sets up the available trigger events. +-- ********************************************************************************** +function MikSBTOpt.SetupAvailableTriggerEvents() + table.insert(availableTriggerEvents, "CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS"); + table.insert(availableTriggerEvents, "CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS"); + table.insert(availableTriggerEvents, "CHAT_MSG_COMBAT_PARTY_HITS"); + table.insert(availableTriggerEvents, "CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES"); + table.insert(availableTriggerEvents, "CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES"); + table.insert(availableTriggerEvents, "CHAT_MSG_COMBAT_PARTY_MISSES"); + table.insert(availableTriggerEvents, "CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE"); + table.insert(availableTriggerEvents, "CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE"); + table.insert(availableTriggerEvents, "CHAT_MSG_SPELL_PARTY_DAMAGE"); + table.insert(availableTriggerEvents, "CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS"); + table.insert(availableTriggerEvents, "CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF"); + table.insert(availableTriggerEvents, "CHAT_MSG_SPELL_CREATURE_VS_SELF_BUFF"); + table.insert(availableTriggerEvents, "CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE"); + table.insert(availableTriggerEvents, "CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS"); + table.insert(availableTriggerEvents, "CHAT_MSG_COMBAT_SELF_HITS"); + table.insert(availableTriggerEvents, "CHAT_MSG_COMBAT_SELF_MISSES"); + table.insert(availableTriggerEvents, "CHAT_MSG_SPELL_SELF_DAMAGE"); + table.insert(availableTriggerEvents, "CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF"); + table.insert(availableTriggerEvents, "CHAT_MSG_SPELL_SELF_BUFF"); + table.insert(availableTriggerEvents, "CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS"); + table.insert(availableTriggerEvents, "CHAT_MSG_SPELL_PERIODIC_PARTY_BUFFS"); + table.insert(availableTriggerEvents, "CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE"); + table.insert(availableTriggerEvents, "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE"); + table.insert(availableTriggerEvents, "CHAT_MSG_COMBAT_PET_HITS"); + table.insert(availableTriggerEvents, "CHAT_MSG_COMBAT_PET_MISSES"); + table.insert(availableTriggerEvents, "CHAT_MSG_SPELL_PET_DAMAGE"); + table.insert(availableTriggerEvents, "CHAT_MSG_SPELL_ITEM_ENCHANTMENTS"); + table.insert(availableTriggerEvents, "CHAT_MSG_SPELL_AURA_GONE_SELF"); + table.insert(availableTriggerEvents, "CHAT_MSG_COMBAT_HONOR_GAIN"); + table.insert(availableTriggerEvents, "CHAT_MSG_COMBAT_FACTION_CHANGE"); + table.insert(availableTriggerEvents, "CHAT_MSG_SKILL"); + table.insert(availableTriggerEvents, "CHAT_MSG_COMBAT_XP_GAIN"); + table.insert(availableTriggerEvents, "CHAT_MSG_COMBAT_HOSTILE_DEATH"); +end + + +-- ********************************************************************************** +-- Adds a new trigger. +-- ********************************************************************************** +function MikSBTOpt.AddNewTrigger() + -- Hold the next available custom trigger number. + local nextTriggerNum = 0; + local slotFound = false; + + -- Loop until an available slot is found. + while (true) do + -- Increment to the next trigger number. + nextTriggerNum = nextTriggerNum + 1; + + if (not MikSBT.CurrentProfile.Triggers["MSBT_TRIGGER_CUSTOM" .. nextTriggerNum]) then + break; + end + end + + -- Create the new default trigger. + MikSBT.CurrentProfile.Triggers["MSBT_TRIGGER_CUSTOM" .. nextTriggerNum] = { + EventSettings = { + Show = true, + Message = MikSBTOpt.MSG_TRIGGER_NEW_TRIGGER_DEFAULT_MESSAGE, + IsSticky = false, + FontSettings = { + Color = {r=1, g=0.502, b=0.502}, + Normal = {FontIndex=0, OutlineIndex=0, FontSize=26}, + }, + }, + TriggerSettings = { + TriggerType = 1, + Threshold = 40, + }, + } + + -- Reregister the trigger with the event helper. + MikSBT.RegisterTriggers(); + + -- Repopulate the trigger event settings so the new trigger shows up. + MikSBTOpt.PopulateTriggerEventSettings(); +end + +-- ********************************************************************************** +-- Deletes the passed trigger. +-- ********************************************************************************** +function MikSBTOpt.DeleteTrigger(triggerKey) + -- Remove the trigger. + MikSBT.CurrentProfile.Triggers[triggerKey] = nil; + + -- Reregister the trigger with the event helper. + MikSBT.RegisterTriggers(); + + -- Repopulate the trigger event settings. + MikSBTOpt.PopulateTriggerEventSettings(); +end + + +-- ********************************************************************************** +-- Shows the trigger settings for the passed trigger key. +-- ********************************************************************************** +function MikSBTOpt.ShowTriggerConfig(triggerKey) + -- Get the trigger configuration frame. + local triggerFrame = getglobal(TRIGGER_CONFIGURATION_FRAME_NAME); + + -- Set the trigger key for the config frame. + triggerFrame.TriggerKey = triggerKey; + + -- Get the trigger data for the passed trigger and make sure it exists. + local triggerData = MikSBT.CurrentProfile.Triggers[triggerKey]; + if (triggerData) then + -- Set the title to the output message. + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "Title"):SetText(triggerData.EventSettings.Message); + + -- Check if all classes are selected. + if (not triggerData.TriggerSettings.Classes) then + -- Check the all classes checkbox and hide the individual class checkboxes. + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "AllClassesCheckbox"):SetChecked(1); + MikSBTOpt.HideTriggerClassCheckboxes(); + else + -- Uncheck the all classes checkbox and show the individual class checkboxes. + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "AllClassesCheckbox"):SetChecked(0); + MikSBTOpt.ShowTriggerClassCheckboxes(); + + -- Set the correct individual class checkbox settings. + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "DruidCheckbox"):SetChecked(triggerData.TriggerSettings.Classes.DRUID); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "HunterCheckbox"):SetChecked(triggerData.TriggerSettings.Classes.HUNTER); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "MageCheckbox"):SetChecked(triggerData.TriggerSettings.Classes.MAGE); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "PaladinCheckbox"):SetChecked(triggerData.TriggerSettings.Classes.PALADIN); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "PriestCheckbox"):SetChecked(triggerData.TriggerSettings.Classes.PRIEST); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "RogueCheckbox"):SetChecked(triggerData.TriggerSettings.Classes.ROGUE); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "ShamanCheckbox"):SetChecked(triggerData.TriggerSettings.Classes.SHAMAN); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "WarlockCheckbox"):SetChecked(triggerData.TriggerSettings.Classes.WARLOCK); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "WarriorCheckbox"):SetChecked(triggerData.TriggerSettings.Classes.WARRIOR); + end + + -- Populate the trigger type. + MikSBTOpt.PopulateDropdown(TRIGGER_CONFIGURATION_FRAME_NAME .. "TriggerTypeDropdown", triggerData.TriggerSettings.TriggerType); + + -- Setup the trigger controls appropriately depending on the trigger type. + MikSBTOpt.SetupVariableTriggerControls(triggerKey, triggerData.TriggerSettings.TriggerType == MikCEH.TRIGGERTYPE_SEARCH_PATTERN); + + -- Show the trigger settings. + triggerFrame:Show(); + end +end + + +-- ********************************************************************************** +-- Show or hides the search pattern controls on the trigger config frame. +-- ********************************************************************************** +function MikSBTOpt.SetupVariableTriggerControls(triggerKey, showSearch) + -- Get the trigger configuration frame. + local triggerFrame = getglobal(TRIGGER_CONFIGURATION_FRAME_NAME); + + -- Get the trigger data for the passed trigger and make sure it exists. + local triggerData = MikSBT.CurrentProfile.Triggers[triggerKey]; + if (triggerData) then + + -- Check if the search pattern controls should be shown. + if (showSearch) then + -- Resize the trigger frame. + triggerFrame:SetHeight(420); + + -- Hide the threshold slider. + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "ThresholdSlider"):Hide(); + + -- TODO: Show the search pattern controls. + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "EventsScrollFrame"):Show(); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "TriggerEvent1Checkbox"):Show(); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "TriggerEvent2Checkbox"):Show(); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "TriggerEvent3Checkbox"):Show(); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "TriggerEvent4Checkbox"):Show(); + + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "SearchPattern1Editbox"):Show(); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "SearchPattern2Editbox"):Show(); + + -- Clear the selected trigger events. + if (not triggerFrame.SelectedTriggerEvents) then + triggerFrame.SelectedTriggerEvents = {}; + else + MikCEH.EraseTable(triggerFrame.SelectedTriggerEvents); + end + + -- Loop through all of the trigger events for the trigger. + for _, triggerEvent in triggerData.TriggerSettings.TriggerEvents do + triggerFrame.SelectedTriggerEvents[triggerEvent] = true; + end + + -- Populate the appropriate trigger events. + MikSBTOpt.PopulateAvailableTriggerEvents(); + + + -- Holds the search patterns. + local searchPattern1 = ""; + local searchPattern2 = ""; + + -- Check if there are search patterns defined. + if (triggerData.TriggerSettings.SearchPatterns) then + searchPattern1 = triggerData.TriggerSettings.SearchPatterns[1] or ""; + searchPattern2 = triggerData.TriggerSettings.SearchPatterns[2] or ""; + end + + -- Populate the search pattern settings. + MikSBTOpt.PopulateEditbox(TRIGGER_CONFIGURATION_FRAME_NAME .. "SearchPattern1Editbox", searchPattern1); + MikSBTOpt.PopulateEditbox(TRIGGER_CONFIGURATION_FRAME_NAME .. "SearchPattern2Editbox", searchPattern2); + + else + -- Resize the trigger frame. + triggerFrame:SetHeight(270); + + -- Show the threshold slider. + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "ThresholdSlider"):Show(); + + -- Hide the search pattern controls. + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "EventsScrollFrame"):Hide(); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "TriggerEvent1Checkbox"):Hide(); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "TriggerEvent2Checkbox"):Hide(); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "TriggerEvent3Checkbox"):Hide(); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "TriggerEvent4Checkbox"):Hide(); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "SearchPattern1Editbox"):Hide(); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "SearchPattern2Editbox"):Hide(); + + -- Populate the threshold slider. + MikSBTOpt.PopulateSlider(TRIGGER_CONFIGURATION_FRAME_NAME .. "ThresholdSlider", triggerData.TriggerSettings.Threshold or 1); + end + end +end + + +-- ********************************************************************************** +-- Hides the individual class checkboxes on the trigger config frame. +-- ********************************************************************************** +function MikSBTOpt.HideTriggerClassCheckboxes() + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "DruidCheckbox"):Hide(); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "HunterCheckbox"):Hide(); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "MageCheckbox"):Hide(); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "PaladinCheckbox"):Hide(); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "PriestCheckbox"):Hide(); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "RogueCheckbox"):Hide(); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "ShamanCheckbox"):Hide(); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "WarlockCheckbox"):Hide(); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "WarriorCheckbox"):Hide(); +end + + +-- ********************************************************************************** +-- Shows the individual class checkboxes on the trigger config frame. +-- ********************************************************************************** +function MikSBTOpt.ShowTriggerClassCheckboxes() + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "DruidCheckbox"):Show(); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "HunterCheckbox"):Show(); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "MageCheckbox"):Show(); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "PaladinCheckbox"):Show(); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "PriestCheckbox"):Show(); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "RogueCheckbox"):Show(); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "ShamanCheckbox"):Show(); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "WarlockCheckbox"):Show(); + getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "WarriorCheckbox"):Show(); +end + + +-- ********************************************************************************** +-- Saves the settings in the trigger config frame to the appropriate trigger. +-- ********************************************************************************** +function MikSBTOpt.SaveTriggerConfig() + -- Get the trigger configuration frame. + local triggerFrame = getglobal(TRIGGER_CONFIGURATION_FRAME_NAME); + + -- Get the trigger data for the trigger that is being saved and make sure it exists. + local triggerData = MikSBT.CurrentProfile.Triggers[triggerFrame.TriggerKey]; + if (triggerData) then + -- Check if the all classes checkbox is checked. + if (getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "AllClassesCheckbox"):GetChecked()) then + -- Clear the selected classes table for the trigger to indicate all classes. + triggerData.TriggerSettings.Classes = nil; + + -- The all classes checkbox is not checked. + else + -- Create a table to hold the selected classes. + local selectedClasses = {}; + + -- Set the class in the selected classes array if it's checked. + if (getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "DruidCheckbox"):GetChecked()) then selectedClasses.DRUID = true; end + if (getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "HunterCheckbox"):GetChecked()) then selectedClasses.HUNTER = true; end + if (getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "MageCheckbox"):GetChecked()) then selectedClasses.MAGE = true; end + if (getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "PaladinCheckbox"):GetChecked()) then selectedClasses.PALADIN = true; end + if (getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "PriestCheckbox"):GetChecked()) then selectedClasses.PRIEST = true; end + if (getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "RogueCheckbox"):GetChecked()) then selectedClasses.ROGUE = true; end + if (getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "ShamanCheckbox"):GetChecked()) then selectedClasses.SHAMAN = true; end + if (getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "WarlockCheckbox"):GetChecked()) then selectedClasses.WARLOCK = true; end + if (getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "WarriorCheckbox"):GetChecked()) then selectedClasses.WARRIOR = true; end + + -- Save the selected classes for the trigger. + triggerData.TriggerSettings.Classes = selectedClasses; + end + + -- Save the trigger type. + triggerData.TriggerSettings.TriggerType = UIDropDownMenu_GetSelectedValue(getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "TriggerTypeDropdown")); + + + -- Check if the trigger type is search pattern. + if (triggerData.TriggerSettings.TriggerType == MikCEH.TRIGGERTYPE_SEARCH_PATTERN) then + -- Clear the threshold field. + triggerData.TriggerSettings.Threshold = nil; + + local trigEvents = {}; + for triggerEvent in triggerFrame.SelectedTriggerEvents do + table.insert(trigEvents, triggerEvent); + end + + -- Save the selected trigger events. + triggerData.TriggerSettings.TriggerEvents = trigEvents; + + -- Create a table to hold the search patterns. + local searchPatterns = {}; + + -- Get the first search pattern, check if it is set to anything, and add it to the search patterns table. + local searchPattern = getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "SearchPattern1Editbox"):GetText(); + if (searchPattern ~= "") then + table.insert(searchPatterns, searchPattern); + end + + -- Get the second search pattern, check if it is set to anything, and add it to the search patterns table. + searchPattern = getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "SearchPattern2Editbox"):GetText(); + if (searchPattern ~= "") then + table.insert(searchPatterns, searchPattern); + end + + -- Save the search patterns for the trigger. + triggerData.TriggerSettings.SearchPatterns = searchPatterns; + + -- Trigger type is a threshold. + else + -- Clear the search pattern fields. + triggerData.TriggerSettings.TriggerEvents = nil; + triggerData.TriggerSettings.SearchPatterns = nil; + + -- Save the threshold. + triggerData.TriggerSettings.Threshold = getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "ThresholdSlider"):GetValue(); + end + + -- Reregister all of the triggers. + MikSBT.RegisterTriggers(); + end +end + + + +-- ********************************************************************************** +-- Populates the available trigger events scroll frame. +-- ********************************************************************************** +function MikSBTOpt.PopulateAvailableTriggerEvents() + local triggerFrame = getglobal(TRIGGER_CONFIGURATION_FRAME_NAME); + + -- Get the total number of available trigger events. + local totalItems = table.getn(availableTriggerEvents); + + -- Get the trigger settings scroll frame and its offset. + local objFrame = getglobal(TRIGGER_CONFIGURATION_FRAME_NAME .. "EventsScrollFrame"); + FauxScrollFrame_Update(objFrame, totalItems, TRIGGER_EVENT_ITEMS_PER_PAGE, TRIGGER_EVENT_ITEM_HEIGHT); + local skipCount = FauxScrollFrame_GetOffset(objFrame); + + -- Loop through all of the visible items. + for i = 1, TRIGGER_EVENT_ITEMS_PER_PAGE do + local checkboxName = TRIGGER_CONFIGURATION_FRAME_NAME .. "TriggerEvent" .. i .. "Checkbox"; + local objCheckbox = getglobal(checkboxName); + local triggerEvent = availableTriggerEvents[i+skipCount]; + + -- Set the checkbox's name to the trigger event. + MikSBTOpt.SetupCheckbox(checkboxName, triggerEvent, nil, nil); + if (objCheckbox) then objCheckbox.TriggerEvent = triggerEvent; end + + -- If the selected trigger events table exists get the appropriate value from it. + if (triggerFrame.SelectedTriggerEvents) then + MikSBTOpt.PopulateCheckbox(checkboxName, triggerFrame.SelectedTriggerEvents[triggerEvent] ~= nil); + -- Selected trigger events table doesn't exist so just uncheck the checkbox. + else + MikSBTOpt.PopulateCheckbox(checkboxName, false); + end + end +end + + +------------------------------------------------------------------------------------- +-- Suppression functions. +------------------------------------------------------------------------------------- + +-- ********************************************************************************** +-- Adds a new suppression. +-- ********************************************************************************** +function MikSBTOpt.AddNewSuppression() + -- Hold the next available custom suppression number. + local nextSuppressionNum = 0; + local slotFound = false; + + -- Loop until an available slot is found. + while (true) do + -- Increment to the next suppression number. + nextSuppressionNum = nextSuppressionNum + 1; + + if (not MikSBT.CurrentProfile.Suppressions["MSBT_SUPPRESSION_CUSTOM" .. nextSuppressionNum]) then + break; + end + end + + -- Create the new default trigger. + MikSBT.CurrentProfile.Suppressions["MSBT_SUPPRESSION_CUSTOM" .. nextSuppressionNum] = { + Enabled = true, + SearchPattern = MikSBTOpt.MSG_SUPPRESSION_NEW_SUPPRESSION_DEFAULT_MESSAGE, + }; + + -- Repopulate the suppression settings so the new suppression shows up. + MikSBTOpt.PopulateSuppressionSettings(); +end + +------------------------------------------------------------------------------------- +-- Populate profile functions. +------------------------------------------------------------------------------------- + +-- ********************************************************************************** +-- Populates the options from the currently selected profile. +-- ********************************************************************************** +function MikSBTOpt.PopulateProfileOptions() + -- Hide the font settings frame when profile options are populated. + getglobal(FONT_SETTINGS_FRAME_NAME):Hide(); + + + -- Populate the Animation Step slider value. + MikSBTOpt.PopulateSlider(OPTIONS_FRAME_NAME .. "Tab1FrameAnimationStepSlider"); + + -- Populate the Show Partial Events checkbox. + MikSBTOpt.PopulateCheckbox(OPTIONS_FRAME_NAME .. "Tab1FrameShowPartialEffectsCheckbox"); + + -- Populate the Use Sticky Crits checkbox. + MikSBTOpt.PopulateCheckbox(OPTIONS_FRAME_NAME .. "Tab1FrameUseStickyCritsCheckbox"); + + -- Populate the Show Overheals checkbox. + MikSBTOpt.PopulateCheckbox(OPTIONS_FRAME_NAME .. "Tab1FrameShowOverhealsCheckbox"); + + -- Populate the Show Game Damage checkbox and update it appropriately. + MikSBTOpt.PopulateCheckbox(OPTIONS_FRAME_NAME .. "Tab1FrameShowGameDamageCheckbox"); + MikSBT.SetOptionShowGameDamage(MikSBT.CurrentProfile.ShowGameDamage); + + + -- Populate the scroll area show events checkboxes to the values in the profile. + MikSBTOpt.PopulateCheckbox(OPTIONS_FRAME_NAME .. "Tab2FrameShowEventsCheckbox"); + MikSBTOpt.PopulateCheckbox(OPTIONS_FRAME_NAME .. "Tab3FrameShowEventsCheckbox"); + MikSBTOpt.PopulateCheckbox(OPTIONS_FRAME_NAME .. "Tab4FrameShowEventsCheckbox"); + + + -- Populate the incoming, outgoing, and notification event settings. + MikSBTOpt.PopulateIncomingEventSettings(); + MikSBTOpt.PopulateOutgoingEventSettings(); + MikSBTOpt.PopulateNotificationEventSettings(); + + + -- Populate the trigger settings. + MikSBTOpt.PopulateTriggerEventSettings(); + + -- Populate the suppression settings. + MikSBTOpt.PopulateSuppressionSettings(); +end \ No newline at end of file diff --git a/MikScrollingBattleTextOptions/MSBTOptions.xml b/MikScrollingBattleTextOptions/MSBTOptions.xml new file mode 100644 index 0000000..3f46616 --- /dev/null +++ b/MikScrollingBattleTextOptions/MSBTOptions.xml @@ -0,0 +1,2645 @@ + + + + + + + + + + + + + + + + + + + + + + + + if (this.tooltipText ~= nil) then + GameTooltip:SetOwner(this, "ANCHOR_RIGHT"); + GameTooltip:SetText(this.tooltipText, nil, nil, nil, nil, 1); + end + + GameTooltip:Hide(); + + + + + + + + + + + if (this:GetChecked()) then + PlaySound("igMainMenuOptionCheckBoxOff"); + else + PlaySound("igMainMenuOptionCheckBoxOn"); + end + + -- Call the font settings checkbox OnClick handler. + MikSBTOpt.CheckboxOnClick(); + + + + + + + + + MikSBTOpt.SliderOnValueChanged(); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + if (this.tooltipText ~= nil) then + GameTooltip:SetOwner(this, "ANCHOR_RIGHT"); + GameTooltip:SetText(this.tooltipText, nil, nil, nil, nil, 1); + end + + GameTooltip:Hide(); + MikSBTOpt.EditboxOnTextChanged(); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + if (this:GetChecked()) then + PlaySound("igMainMenuOptionCheckBoxOff"); + else + PlaySound("igMainMenuOptionCheckBoxOn"); + end + + -- Call the trigger settings checkbox OnClick handler. + MikSBTOpt.EnableTriggerCheckboxOnClick(); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + local scrollbar = getglobal(this:GetName().."ScrollBar"); + scrollbar:SetMinMaxValues(0, 1); + scrollbar:SetValue(1); + + MikSBTOpt.OnVerticalScroll(); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + local scrollbar = getglobal(this:GetName().."ScrollBar"); + scrollbar:SetMinMaxValues(0, 1); + scrollbar:SetValue(1); + + MikSBTOpt.OnVerticalScroll(); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + local scrollbar = getglobal(this:GetName().."ScrollBar"); + scrollbar:SetMinMaxValues(0, 1); + scrollbar:SetValue(1); + + MikSBTOpt.OnVerticalScroll(); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + if (this.tooltipText ~= nil) then + GameTooltip:SetOwner(this, "ANCHOR_RIGHT"); + GameTooltip:SetText(this.tooltipText, nil, nil, nil, nil, 1); + end + + GameTooltip:Hide(); + + -- Start moving the frame if the left mouse button is pressed. + if (arg1 == "LeftButton") then + this:StartMoving(); + end + + + -- Stop moving the frame. + this:StopMovingOrSizing(); + + -- Save the scroll area's coordinates to the control frame. + MikSBTOpt.SaveScrollAreaMoverCoordinates(this:GetName()); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MikSBTOpt.FontSettingsSliderOnValueChanged(); + + + + + + + + + + + + + + MikSBTOpt.FontSettingsSliderOnValueChanged(); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + this:SetBackdropColor(0.05, 0.05, 0.05, 1.0); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MikSBTOpt.ScrollAreaMoverControlSliderOnValueChanged(); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + this:SetBackdropColor(0.05, 0.05, 0.05, 1.0); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + local scrollbar = getglobal(this:GetName().."ScrollBar"); + scrollbar:SetMinMaxValues(0, 1); + scrollbar:SetValue(1); + + MikSBTOpt.OnVerticalScroll(); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + this:SetBackdropColor(0.05, 0.05, 0.05, 1.0); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- Start moving the parent frame if the left mouse button is pressed. + if (arg1 == "LeftButton") then + this:GetParent():StartMoving(); + end + + + -- Stop moving the parent frame. + this:GetParent():StopMovingOrSizing(); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MikSBTOpt.OnEvent(); + MikSBTOpt.OnLoad(); + MikSBTOpt.OnHide(); + MikSBTOpt.OnShow(); + + + + \ No newline at end of file diff --git a/MikScrollingBattleTextOptions/MikScrollingBattleTextOptions.toc b/MikScrollingBattleTextOptions/MikScrollingBattleTextOptions.toc new file mode 100644 index 0000000..6621658 --- /dev/null +++ b/MikScrollingBattleTextOptions/MikScrollingBattleTextOptions.toc @@ -0,0 +1,9 @@ +## Interface: 11200 +## Version: 3.0 +## Title: Mik's Scrolling Battle Text Options +## Notes: Load on demand options for Mik's Scrolling Battle Text +## Dependencies: MikScrollingBattleText +## LoadOnDemand: 1 +localization_options.lua +MSBTOptions.lua +MSBTOptions.xml \ No newline at end of file diff --git a/MikScrollingBattleTextOptions/localization_options.lua b/MikScrollingBattleTextOptions/localization_options.lua new file mode 100644 index 0000000..a3f4a29 --- /dev/null +++ b/MikScrollingBattleTextOptions/localization_options.lua @@ -0,0 +1,259 @@ +------------------------------------------------------------------------------------- +-- Title: Mik's Scrolling Battle Text Options +-- Author: Mik +------------------------------------------------------------------------------------- + +-- Create Options "namespace." +MikSBTOpt = {}; + + +------------------------------ +-- Interface messages +------------------------------ + +MikSBTOpt.MSG_INHERIT_TEXT = "Inherit"; +MikSBTOpt.MSG_NORMAL_PREVIEW_TEXT = "Normal"; +MikSBTOpt.MSG_CRIT_PREVIEW_TEXT = "Crit"; +MikSBTOpt.MSG_CURRENT_PROFILE_TEXT = "Current Profile"; +MikSBTOpt.MSG_SCROLL_AREA_PREVIEW_TEXT = "Preview Message"; + + +MikSBTOpt.MSG_EVENT_MESSAGE_LABEL_TOOLTIP = "Click here to edit what output message will be displayed when the event occurs.\n\nAny event codes will be substituted with actual data." +MikSBTOpt.MSG_EVENT_MESSAGE_EDITBOX_TOOLTIP_PREFIX = "Available Event Codes:\n\n"; +MikSBTOpt.MSG_EVENT_COLOR_SWATCH_TOOLTIP = "Allows you to pick the display color for the event."; +MikSBTOpt.MSG_EVENT_EDIT_FONT_SETTINGS_BUTTON_LABEL = "Edit Fonts"; +MikSBTOpt.MSG_EVENT_EDIT_FONT_SETTINGS_BUTTON_TOOLTIP = "Edits the event's font settings. These settings are inherited from the scroll area if they are set to inherit."; +MikSBTOpt.MSG_EVENT_STICKY_CHECKBOX_TOOLTIP = "Sets whether or not to display this event using the sticky style."; +MikSBTOpt.MSG_EVENT_EDIT_TRIGGER_BUTTON_LABEL = "Edit Trigger"; +MikSBTOpt.MSG_EVENT_EDIT_TRIGGER_BUTTON_TOOLTIP = "Edits the event's trigger settings."; +MikSBTOpt.MSG_EVENT_SOUND_BUTTON_TOOLTIP = "Allows you to pick a sound to play when the event occurs."; +MikSBTOpt.MSG_TRIGGER_ENABLE_TOOLTIP = "Sets whether or not the trigger is enabled." +MikSBTOpt.MSG_TRIGGER_MESSAGE_LABEL_TOOLTIP = "Click here to edit what output message will be displayed when the trigger occurs." +MikSBTOpt.MSG_TRIGGER_MESSAGE_EDITBOX_TOOLTIP = "Enter the output message to be displayed with the trigger occurs."; +MikSBTOpt.MSG_TRIGGER_STICKY_CHECKBOX_TOOLTIP = "Sets whether or not to display this trigger using the sticky style."; +MikSBTOpt.MSG_TRIGGER_EDIT_FONT_SETTINGS_BUTTON_LABEL = "Edit Fonts"; +MikSBTOpt.MSG_TRIGGER_EDIT_FONT_SETTINGS_BUTTON_TOOLTIP = "Edits the trigger's font settings. These settings are inherited from the notification scroll area if they are set to inherit."; +MikSBTOpt.MSG_TRIGGER_EDIT_TRIGGER_SETTINGS_BUTTON_LABEL = "Edit Trigger"; +MikSBTOpt.MSG_TRIGGER_EDIT_TRIGGER_SETTINGS_BUTTON_TOOLTIP = "Edits the trigger's settings."; +MikSBTOpt.MSG_TRIGGER_DELETE_TRIGGER_BUTTON_TOOLTIP = "Deletes the trigger."; +MikSBTOpt.MSG_TRIGGER_APPLICABLE_CLASSES_LABEL = "Applicable Trigger Classes:"; +MikSBTOpt.MSG_TRIGGER_NEW_TRIGGER_DEFAULT_MESSAGE = "New Trigger: Click here to edit."; +MikSBTOpt.MSG_SUPPRESSION_ENABLE_TOOLTIP = "Sets whether or not the suppression is enabled."; +MikSBTOpt.MSG_SUPPRESSION_DELETE_SUPPRESSION_BUTTON_TOOLTIP = "Deletes the suppression."; +MikSBTOpt.MSG_SUPPRESSION_MESSAGE_LABEL_TOOLTIP = "Click here to edit the search pattern to suppress." +MikSBTOpt.MSG_SUPPRESSION_MESSAGE_EDITBOX_TOOLTIP = "Enter the search pattern to be suppressed."; +MikSBTOpt.MSG_SUPPRESSION_NEW_SUPPRESSION_DEFAULT_MESSAGE = "New Suppression: Click here to edit."; + +-- Class Names. +MikSBTOpt.MSG_CLASS_NAME_DRUID = "Druid"; +MikSBTOpt.MSG_CLASS_NAME_HUNTER = "Hunter"; +MikSBTOpt.MSG_CLASS_NAME_MAGE = "Mage"; +MikSBTOpt.MSG_CLASS_NAME_PALADIN = "Paladin"; +MikSBTOpt.MSG_CLASS_NAME_PRIEST = "Priest"; +MikSBTOpt.MSG_CLASS_NAME_ROGUE = "Rogue"; +MikSBTOpt.MSG_CLASS_NAME_SHAMAN = "Shaman"; +MikSBTOpt.MSG_CLASS_NAME_WARLOCK = "Warlock"; +MikSBTOpt.MSG_CLASS_NAME_WARRIOR = "Warrior"; + + +------------------------------ +-- Interface objects info +------------------------------ + +MikSBTOpt.TABS = { + [1] = { Label="General", Tooltip="Display general options."}, + [2] = { Label="Incoming", Tooltip="Display options for the incoming scroll area."}, + [3] = { Label="Outgoing", Tooltip="Display options for the outgoing scroll area."}, + [4] = { Label="Notification", Tooltip="Display options for the notification scroll area."}, + [5] = { Label="Triggers", Tooltip="Display options for the trigger system."}, + [6] = { Label="Suppressions", Tooltip="Display options for the suppression system."}, +}; + +MikSBTOpt.DROPDOWNS = { + ["Tab1FrameProfileDropdown"] = { Label="Profile", Tooltip="Selects the current profile."}, + ["ScrollAreaDropdown"] = { Label="Scroll Area", Tooltip="Selects the scroll area to configure."}, + ["TextAlignDropdown"] = { Label="Text Align", Tooltip="The alignment of the text for the scroll area."}, + ["AnimationStyleDropdown"] = { Label="Animation Style", Tooltip="The animation style for the scroll area."}, + ["ScrollDirectionDropdown"] = { Label="Scroll Direction", Tooltip="The scroll direction for the scroll area."}, + ["FontDropdown"] = { Label="Normal Font"}, + ["FontOutlineDropdown"] = { Label="Normal Font Outline"}, + ["FontCritDropdown"] = { Label="Crit Font"}, + ["FontOutlineCritDropdown"] = { Label="Crit Font Outline"}, + ["TriggerTypeDropdown"] = { Label="Trigger Type", Tooltip="Select the type of trigger."}, +}; + +MikSBTOpt.CHECKBOXES = { + ["Tab1FrameDisableCheckbox"] = { Label="Disable Mik's Scrolling Battle Text", Tooltip="Sets whether or not MSBT is disabled."}, + ["Tab1FrameShowPartialEffectsCheckbox"] = { Label="Show Partial Effects", Tooltip="Sets whether or not to show partial resists, absorbs, blocks, etc."}, + ["Tab1FrameUseStickyCritsCheckbox"] = { Label="Display Crits Sticky", Tooltip="Sets whether or not to display crits using the sticky style."}, + ["Tab1FrameShowOverhealsCheckbox"] = { Label="Show Overheals", Tooltip="Sets whether or not to display overhealing information."}, + ["Tab1FrameShowGameDamageCheckbox"] = { Label="Show Game Damage", Tooltip="Sets whether or not to display the game's damage above the enemy's heads."}, + ["Tab2FrameShowEventsCheckbox"] = { Label="Enable Incoming Events", Tooltip="Sets whether or not to enable incoming events."}, + ["Tab3FrameShowEventsCheckbox"] = { Label="Enable Outgoing Events", Tooltip="Sets whether or not to enable outgoing events."}, + ["Tab4FrameShowEventsCheckbox"] = { Label="Enable Notification Events", Tooltip="Sets whether or not to enable notification events."}, + ["InheritFontSizeCheckbox"] = { Label="Inherit Font Size"}, + ["InheritFontSizeCritCheckbox"] = { Label="Inherit Crit Font Size"}, +}; + +MikSBTOpt.SLIDERS = { + ["Tab1FrameAnimationStepSlider"] = { Label="Animation Speed", Tooltip="Sets the speed of the animation."}, + ["ScrollHeightSlider"] = { Label="Scroll Height", Tooltip="The height of the scroll area."}, + ["FontSizeSlider"] = { Label="Font Size"}, + ["FontSizeCritSlider"] = { Label="Font Crit Size"}, + ["ThresholdSlider"] = { Label="Threshold Percentage", Tooltip="Sets the threshold percentage which must be passed for the trigger to fire."}, +}; + +MikSBTOpt.BUTTONS = { + ["Tab1FrameEditFontSettingsButton"] = { Label="Edit Master Font Settings", Tooltip="Edits the master font settings. These settings will be inherited by each scroll area and the events therein unless they are overridden."}, + ["Tab2FrameEditFontSettingsButton"] = { Label="Edit Scroll Area Fonts", Tooltip="Edits the incoming scroll area font settings. These settings will be inherited by each event in the incoming scroll area unless they are overridden."}, + ["Tab3FrameEditFontSettingsButton"] = { Label="Edit Scroll Area Fonts", Tooltip="Edits the outgoing scroll area font settings. These settings will be inherited by each event in the outgoing scroll area unless they are overridden."}, + ["Tab4FrameEditFontSettingsButton"] = { Label="Edit Scroll Area Fonts", Tooltip="Edits the notification scroll area font settings. These settings will be inherited by each event in the notification scroll area unless they are overridden."}, + ["Tab1FrameLoadProfileButton"] = { Label="Load Profile", Tooltip="Loads the selected profile."}, + ["Tab1FrameDeleteProfileButton"] = { Label="Delete Profile", Tooltip="Deletes the selected profile."}, + ["Tab1FrameResetProfileButton"] = { Label="Reset Profile", Tooltip="Resets the selected profile to the default settings."}, + ["Tab1FrameCreateProfileButton"] = { Label="Create Profile", Tooltip="Creates a new profile with the default settings."}, + ["Tab2FrameConfigureScrollAreaButton"] = { Label="Configure Scroll Area", Tooltip="Allows you to configure the animation style, scroll direction, text align, scroll height, and location of the scroll areas."}, + ["PreviewButton"] = { Label="Preview", Tooltip="Previews a test message in all the scrolling areas."}, + ["SaveButton"] = { Label="Save Settings", Tooltip="Saves the new settings for the scroll areas."}, + ["CancelButton"] = { Label="Cancel", Tooltip="Cancels the changes."}, + ["Tab5FrameAddTriggerButton"] = { Label="Add New Trigger", Tooltip="Adds a new trigger that can be configured."}, + ["SaveTriggerButton"] = { Label="Save Settings", Tooltip="Saves the settings for the trigger."}, + ["CancelTriggerButton"] = { Label="Cancel", Tooltip="Cancels the changes."}, + ["Tab6FrameAddSuppressionButton"] = { Label="Add New Suppression", Tooltip="Adds a new suppression."}, +}; + +MikSBTOpt.EDITBOXES = { + ["Tab1FrameNewProfileNameEditbox"] = { Label="New Profile Name", Tooltip="Allows you to enter the name of a new profile."}, + ["XOffsetEditbox"] = { Label="X Offset", Tooltip="Allows you to enter the X offset of the selected scroll frame."}, + ["YOffsetEditbox"] = { Label="Y Offset", Tooltip="Allows you to enter the Y offset of the selected scroll frame."}, + ["SearchPattern1Editbox"] = { Label="Search Pattern 1", Tooltip="Allows you to enter a search pattern that will cause the trigger to fire."}, + ["SearchPattern2Editbox"] = { Label="Search Pattern 2", Tooltip="Allows you to enter a search pattern that will cause the trigger to fire."}, +}; + +MikSBTOpt.FRAMES = { + ["MSBTScrollAreaMoverIncomingFrame"] = { Tooltip="Indicates the anchor column for the incoming scroll area. Drag this frame to the location you want or use the control frame x and y offset edit boxes."}, + ["MSBTScrollAreaMoverOutgoingFrame"] = { Tooltip="Indicates the anchor column for the outgoing scroll area. Drag this frame to the location you want or use the control frame x and y offset edit boxes."}, + ["MSBTScrollAreaMoverNotificationFrame"] = { Tooltip="Indicates the anchor column for the notification scroll area. Drag this frame to the location you want or use the control frame x and y offset edit boxes."}, +} + +MikSBTOpt.FONT_SETTINGS_TOOLTIPS = { + ["Master"] = { + FontSettingsTitle="Master", + Font="Set the master font for non-crits. This will be inherited by each scroll area and its events.", + FontCrit="Set the master font for crits. This will be inherited by each scroll area and its events.", + Outline="Set the master font outline for non-crits. This will be inherited by each scroll area and its events.", + OutlineCrit="Set the master font outline for crits. This will be inherited by each scroll area and its events.", + FontSize="Set the master font size for non-crits. This will be inherited by each scroll area and its events.", + FontSizeCrit="Set the master font size for crits. This will be inherited by each scroll area and its events.", + }, + ["ScrollArea"] = { + Font="Set the scroll area font for non-crits. This will be inherited by each event in the scroll area.", + FontCrit="Set the scroll area font for crits. This will be inherited by each event in the scroll area.", + Outline="Set the scroll area font outline for non-crits. This will be inherited by each event in the scroll area.", + OutlineCrit="Set the scroll area font outline for crits. This will be inherited by each event in the scroll area.", + InheritFontSize="Set whether or not to inherit the font size for non-crits from the master font settings.", + InheritFontSizeCrit="Set whether or not to inherit the font size for crits from the master font settings.", + FontSize="Set the scroll area font size for non-crits. This will be inherited by each event in the scroll area.", + FontSizeCrit="Set the scroll area font size for crits. This will be inherited by each event in the scroll area.", + }, + ["Event"] = { + Font="Set the event font for non-crits.", + FontCrit="Set the event font for crits.", + Outline="Set the event font outline for non-crits.", + OutlineCrit="Set the event font outline for crits.", + InheritFontSize="Set whether or not to inherit the font size for non-crits from the scroll area font settings.", + InheritFontSizeCrit="Set whether or not to inherit the font size for crits from the scroll area font settings.", + FontSize="Set the event font size for non-crits.", + FontSizeCrit="Set the event font size for crits.", + }, + ["Trigger"] = { + Font="Set the triger font.", + Outline="Set the trigger font outline.", + InheritFontSize="Set whether or not to inherit the font size from the notification scroll area font settings.", + FontSize="Set the trigger font size.", + } +} + +MikSBTOpt.INCOMING_EVENTS = { + [1] = { Label="Melee Damage", Tooltips={ShowCheckbox="Sets whether or not to show incoming melee damage.", Editbox="%a - Amount of damage taken.\n%n - Name of the attacker."}}, + [2] = { Label="Melee Misses", Tooltips={ShowCheckbox="Sets whether or not to show incoming melee misses.", Editbox="%n - Name of the attacker."}}, + [3] = { Label="Melee Dodges", Tooltips={ShowCheckbox="Sets whether or not to show incoming melee dodges.", Editbox="%n - Name of the attacker."}}, + [4] = { Label="Melee Parries", Tooltips={ShowCheckbox="Sets whether or not to show incoming melee parries.", Editbox="%n - Name of the attacker."}}, + [5] = { Label="Melee Blocks", Tooltips={ShowCheckbox="Sets whether or not to show incoming melee blocks.", Editbox="%n - Name of the attacker."}}, + [6] = { Label="Melee Absorbs", Tooltips={ShowCheckbox="Sets whether or not to show absorbed incoming melee damage.", Editbox="%n - Name of the attacker."}}, + [7] = { Label="Melee Immunes", Tooltips={ShowCheckbox="Sets whether or not to show incoming melee damage you are immune to.", Editbox="%n - Name of the attacker."}}, + [8] = { Label="Ability/Spell Damage", Tooltips={ShowCheckbox="Sets whether or not to show incoming spell and ability damage.", Editbox="%a - Amount of damage taken.\n%n - Name of the attacker.\n%s - Name of the spell or ability.\n%t - Type of damage taken."}}, + [9] = { Label="Ability/Spell DoTs", Tooltips={ShowCheckbox="Sets whether or not to show incoming spell and ability damage over time.", Editbox="%a - Amount of damage taken.\n%n - Name of the attacker.\n%s - Name of the spell or ability.\n%t - Type of damage taken."}}, + [10] = { Label="Ability Misses", Tooltips={ShowCheckbox="Sets whether or not to show incoming ability misses.", Editbox="%n - Name of the attacker.\n%s - Name of the ability."}}, + [11] = { Label="Ability Dodges", Tooltips={ShowCheckbox="Sets whether or not to show incoming ability dodges.", Editbox="%n - Name of the attacker.\n%s - Name of the ability."}}, + [12] = { Label="Ability Parries", Tooltips={ShowCheckbox="Sets whether or not to show incoming ability parries.", Editbox="%n - Name of the attacker.\n%s - Name of the ability."}}, + [13] = { Label="Ability Blocks", Tooltips={ShowCheckbox="Sets whether or not to show incoming ability blocks.", Editbox="%n - Name of the attacker.\n%s - Name of the ability."}}, + [14] = { Label="Spell Resists", Tooltips={ShowCheckbox="Sets whether or not to show incoming spell resists.", Editbox="%n - Name of the attacker.\n%s - Name of the spell."}}, + [15] = { Label="Ability/Spell Absorbs", Tooltips={ShowCheckbox="Sets whether or not to show absorbed damage from incoming spells and abilities.", Editbox="%n - Name of the attacker.\n%s - Name of the spell or ability."}}, + [16] = { Label="Ability/Spell Immunes", Tooltips={ShowCheckbox="Sets whether or not to show incoming spell and ability damage you are immune to.", Editbox="%n - Name of the attacker.\n%s - Name of the spell or ability."}}, + [17] = { Label="Ability/Spell Reflects", Tooltips={ShowCheckbox="Sets whether or not to show incoming spell and ability damage you reflected.", Editbox="%n - Name of the attacker.\n%s - Name of the spell or ability."}}, + [18] = { Label="Heals", Tooltips={ShowCheckbox="Sets whether or not to show incoming heals.", Editbox="%a - Amount of healing taken.\n%n - Name of the healer.\n%s - Name of the spell."}}, + [19] = { Label="Heals Over Time", Tooltips={ShowCheckbox="Sets whether or not to show incoming heals over time.", Editbox="%a - Amount of healing taken.\n%n - Name of the healer.\n%s - Name of the spell."}}, + [20] = { Label="Environmental Damage", Tooltips={ShowCheckbox="Sets whether or not to show environmental (falling, drowning, lava, etc...) damage.", Editbox="%a - Amount of damage taken.\n%s - Name of the source of the damage (falling, drowning, lava, etc...)"}}, +}; + +MikSBTOpt.OUTGOING_EVENTS = { + [1] = { Label="Melee Damage", Tooltips={ShowCheckbox="Sets whether or not to show outgoing melee damage.", Editbox="%a - Amount of damage done.\n%n - Name of the attacked unit."}}, + [2] = { Label="Melee Misses", Tooltips={ShowCheckbox="Sets whether or not to show outgoing melee misses.", Editbox="%n - Name of the attacked unit."}}, + [3] = { Label="Melee Dodges", Tooltips={ShowCheckbox="Sets whether or not to show outgoing melee dodges.", Editbox="%n - Name of the attacked unit."}}, + [4] = { Label="Melee Parries", Tooltips={ShowCheckbox="Sets whether or not to show outgoing melee parries.", Editbox="%n - Name of the attacked unit."}}, + [5] = { Label="Melee Blocks", Tooltips={ShowCheckbox="Sets whether or not to show outgoing melee blocks.", Editbox="%n - Name of the attacked unit."}}, + [6] = { Label="Melee Absorbs", Tooltips={ShowCheckbox="Sets whether or not to show absorbed outgoing melee damage.", Editbox="%n - Name of the attacked unit."}}, + [7] = { Label="Melee Immunes", Tooltips={ShowCheckbox="Sets whether or not to show outgoing melee damage the enemy is immune to.", Editbox="%n - Name of the attacked unit."}}, + [8] = { Label="Melee Evades", Tooltips={ShowCheckbox="Sets whether or not to show outgoing melee evades.", Editbox="%n - Name of the attacked unit."}}, + [9] = { Label="Ability/Spell Damage", Tooltips={ShowCheckbox="Sets whether or not to show outgoing spell and ability damage.", Editbox="%a - Amount of damage done.\n%n - Name of the attacked unit.\n%s - Name of the spell or ability.\n%t - Type of damage done."}}, + [10] = { Label="Ability/Spell DoTs", Tooltips={ShowCheckbox="Sets whether or not to show outgoing spell and ability damage over time.", Editbox="%a - Amount of damage done.\n%n - Name of the attacked unit.\n%s - Name of the spell or ability.\n%t - Type of damage done."}}, + [11] = { Label="Ability Misses", Tooltips={ShowCheckbox="Sets whether or not to show outgoing ability misses.", Editbox="%n - Name of the attacked unit.\n%s - Name of the ability."}}, + [12] = { Label="Ability Dodges", Tooltips={ShowCheckbox="Sets whether or not to show outgoing ability dodges.", Editbox="%n - Name of the attacked unit.\n%s - Name of the ability."}}, + [13] = { Label="Ability Parries", Tooltips={ShowCheckbox="Sets whether or not to show outgoing ability parries.", Editbox="%n - Name of the attacked unit.\n%s - Name of the ability."}}, + [14] = { Label="Ability Blocks", Tooltips={ShowCheckbox="Sets whether or not to show outgoing ability blocks.", Editbox="%n - Name of the attacked unit.\n%s - Name of the ability."}}, + [15] = { Label="Spell Resists", Tooltips={ShowCheckbox="Sets whether or not to show outgoing spell resists.", Editbox="%n - Name of the attacked unit.\n%s - Name of the spell."}}, + [16] = { Label="Ability/Spell Absorbs", Tooltips={ShowCheckbox="Sets whether or not to show absorbed damage from outgoing spells and abilities.", Editbox="%n - Name of the attacked unit.\n%s - Name of the spell or ability."}}, + [17] = { Label="Ability/Spell Immunes", Tooltips={ShowCheckbox="Sets whether or not to show outgoing spell and ability damage the enemy is immune to.", Editbox="%n - Name of the attacked unit.\n%s - Name of the spell or ability."}}, + [18] = { Label="Ability/Spell Reflects", Tooltips={ShowCheckbox="Sets whether or not to show outgoing spell and ability damage reflected back to you.", Editbox="%n - Name of the attacked unit.\n%s - Name of the spell or ability."}}, + [19] = { Label="Ability/Spell Evades", Tooltips={ShowCheckbox="Sets whether or not to show outgoing spell and ability evades.", Editbox="%n - Name of the attacked unit.\n%s - Name of the spell or ability."}}, + [20] = { Label="Heals", Tooltips={ShowCheckbox="Sets whether or not to show outgoing heals.", Editbox="%a - Amount of healing done.\n%n - Name of the healed unit.\n%s - Name of the spell."}}, + [21] = { Label="Heals Over Time", Tooltips={ShowCheckbox="Sets whether or not to show outgoing heals over time.", Editbox="%a - Amount of healing done.\n%n - Name of the healed unit.\n%s - Name of the spell."}}, + [22] = { Label="Pet Melee Damage", Tooltips={ShowCheckbox="Sets whether or not to show your pet's outgoing melee damage.", Editbox="%a - Amount of damage done.\n%n - Name of the attacked unit."}}, + [23] = { Label="Pet Melee Misses", Tooltips={ShowCheckbox="Sets whether or not to show your pet's outgoing melee misses.", Editbox="%n - Name of the attacked unit."}}, + [24] = { Label="Pet Melee Dodges", Tooltips={ShowCheckbox="Sets whether or not to show your pet's outgoing melee dodges.", Editbox="%n - Name of the attacked unit."}}, + [25] = { Label="Pet Melee Parries", Tooltips={ShowCheckbox="Sets whether or not to show your pet's outgoing melee parries.", Editbox="%n - Name of the attacked unit."}}, + [26] = { Label="Pet Melee Blocks", Tooltips={ShowCheckbox="Sets whether or not to show your pet's outgoing melee blocks.", Editbox="%n - Name of the attacked unit."}}, + [27] = { Label="Pet Melee Absorbs", Tooltips={ShowCheckbox="Sets whether or not to show your pet's absorbed outgoing melee damage.", Editbox="%n - Name of the attacked unit."}}, + [28] = { Label="Pet Melee Immunes", Tooltips={ShowCheckbox="Sets whether or not to show your pet's outgoing melee damage the enemy is immune to.", Editbox="%n - Name of the attacked unit."}}, + [29] = { Label="Pet Melee Evades", Tooltips={ShowCheckbox="Sets whether or not to show your pet's outgoing melee evades.", Editbox="%n - Name of the attacked unit."}}, + [30] = { Label="Pet Ability/Spell Damage", Tooltips={ShowCheckbox="Sets whether or not to show your pet's outgoing spell and ability damage.", Editbox="%a - Amount of damage done.\n%n - Name of the attacked unit.\n%s - Name of the spell or ability.\n%t - Type of damage done."}}, + [31] = { Label="Pet Ability Misses", Tooltips={ShowCheckbox="Sets whether or not to show your pet's outgoing ability misses.", Editbox="%n - Name of the attacked unit.\n%s - Name of the ability."}}, + [32] = { Label="Pet Ability Dodges", Tooltips={ShowCheckbox="Sets whether or not to show your pet's outgoing ability dodges.", Editbox="%n - Name of the attacked unit.\n%s - Name of the ability."}}, + [33] = { Label="Pet Ability Parries", Tooltips={ShowCheckbox="Sets whether or not to show your pet's outgoing ability parries.", Editbox="%n - Name of the attacked unit.\n%s - Name of the ability."}}, + [34] = { Label="Pet Ability Blocks", Tooltips={ShowCheckbox="Sets whether or not to show your pet's outgoing ability blocks.", Editbox="%n - Name of the attacked unit.\n%s - Name of the ability."}}, + [35] = { Label="Pet Spell Resists", Tooltips={ShowCheckbox="Sets whether or not to show your pet's outgoing spell resists.", Editbox="%n - Name of the attacked unit.\n%s - Name of the spell."}}, + [36] = { Label="Pet Ability/Spell Absorbs", Tooltips={ShowCheckbox="Sets whether or not to show your pet's absorbed damage from outgoing spells and abilities.", Editbox="%n - Name of the attacked unit.\n%s - Name of the spell or ability."}}, + [37] = { Label="Pet Ability/Spell Immunes", Tooltips={ShowCheckbox="Sets whether or not to show your pet's outgoing spell and ability damage the enemy is immune to.", Editbox="%n - Name of the attacked unit.\n%s - Name of the spell or ability."}}, + [38] = { Label="Pet Ability/Spell Evades", Tooltips={ShowCheckbox="Sets whether or not to show your pet's outgoing spell and ability evades.", Editbox="%n - Name of the attacked unit.\n%s - Name of the spell or ability."}}, +}; + +MikSBTOpt.NOTIFICATION_EVENTS = { + [1] = { Label="Debuffs", Tooltips={ShowCheckbox="Sets whether or not to show debuffs you are afflicted by.", Editbox="%s - Name of the debuff."}}, + [2] = { Label="Buffs", Tooltips={ShowCheckbox="Sets whether or not to show buffs you receive.", Editbox="%s - Name of the buff."}}, + [3] = { Label="Item Buffs", Tooltips={ShowCheckbox="Sets whether or not to show buffs your items receive.", Editbox="%s - Name of the item buff."}}, + [4] = { Label="Buff Fades", Tooltips={ShowCheckbox="Sets whether or not to show buffs and debuffs that have faded from you.", Editbox="%s - Name of the buff/debuff."}}, + [5] = { Label="Enter Combat", Tooltips={ShowCheckbox="Sets whether or not to show when you have entered combat.", Editbox="None."}}, + [6] = { Label="Leave Combat", Tooltips={ShowCheckbox="Sets whether or not to show when you have left combat.", Editbox="None."}}, + [7] = { Label="Power Gains", Tooltips={ShowCheckbox="Sets whether or not to show when you gain extra mana, rage, or energy.", Editbox="%a - Amount of energy gained.\n%s - Type of power gained (energy, rage, mana)."}}, + [8] = { Label="Power Losses", Tooltips={ShowCheckbox="Sets whether or not to show when you lose mana, rage, or energy from drains.", Editbox="%a - Amount of energy lost.\n%s - Type of power lost (energy, rage, mana)."}}, + [9] = { Label="Combo Point Gains", Tooltips={ShowCheckbox="Sets whether or not to show when you gain combo points.", Editbox="%a - Amount of combo points you have."}}, + [10] = { Label="Combo Points Full", Tooltips={ShowCheckbox="Sets whether or not to show when you attain full combo points.", Editbox="%a - Amount of combo points you have."}}, + [11] = { Label="Honor Gains", Tooltips={ShowCheckbox="Sets whether or not to show when you gain honor.", Editbox="%a - Amount of honor you gained."}}, + [12] = { Label="Reputation Gains", Tooltips={ShowCheckbox="Sets whether or not to show when you gain reputation.", Editbox="%a - Amount of reputation you gained.\n%s - Name of the faction."}}, + [13] = { Label="Reputation Losses", Tooltips={ShowCheckbox="Sets whether or not to show when you lose reputation.", Editbox="%a - Amount of reputation you lost.\n%s - Name of the faction."}}, + [14] = { Label="Skill Gains", Tooltips={ShowCheckbox="Sets whether or not to show when you gain skill points.", Editbox="%a - Amount of points you have in the skill.\n%s - Name of the skill."}}, + [15] = { Label="Experience Gains", Tooltips={ShowCheckbox="Sets whether or not to show when you gain experience points.", Editbox="%a - Amount of experience you gained."}}, + [16] = { Label="Player Killing Blows", Tooltips={ShowCheckbox="Sets whether or not to show when you get a killing blow against a hostile player.", Editbox="%s - Name of the unit killed."}}, + [17] = { Label="NPC Killing Blows", Tooltips={ShowCheckbox="Sets whether or not to show when you get a killing blow against an NPC.", Editbox="%s - Name of the unit killed."}}, +}; \ No newline at end of file