| Nenue@6 | 1 --- ${PACKAGE_NAME} | 
| Nenue@6 | 2 -- @file-author@ | 
| Nenue@6 | 3 -- @project-revision@ @project-hash@ | 
| Nenue@6 | 4 -- @file-revision@ @file-hash@ | 
| Nenue@6 | 5 -- Created: 2/2/2016 12:09 AM | 
| Nenue@6 | 6 | 
| Nenue@6 | 7 local mod = Turok:NewModule("Toast", "AceTimer-3.0") | 
| Nenue@6 | 8 local _G = _G | 
| Nenue@6 | 9 local db | 
| Nenue@6 | 10 local T, tostring, type, max, tinsert, UIParent, loadstring = _G.Turok, tostring, type, max, table.insert, _G.UIParent, loadstring | 
| Nenue@6 | 11 --@debug@ | 
| Nenue@6 | 12 local DEBUG = true | 
| Nenue@6 | 13 --@end-debug@ | 
| Nenue@6 | 14 local cType, cText, cNum, cWord, cKey, cPink, cBool = cType, cText, cNum, cWord, cKey, cPink, cBool | 
| Nenue@6 | 15 local print = function(...) | 
| Nenue@6 | 16   if not DEBUG then return end | 
| Nenue@6 | 17   if _G.Devian and _G.DevianDB.workspace ~= 1 then | 
| Nenue@6 | 18     _G.print('Toast', ...) | 
| Nenue@6 | 19   end | 
| Nenue@6 | 20 end | 
| Nenue@6 | 21 | 
| Nenue@6 | 22 -- GLOBALS:BossBanner_OnEvent, BossBanner | 
| Nenue@6 | 23 -- kill off the default BossBanner | 
| Nenue@6 | 24 local old_bb = BossBanner_OnEvent | 
| Nenue@6 | 25 BossBanner_OnEvent = function(self, event, ...) | 
| Nenue@6 | 26   T:Print(event, ...) | 
| Nenue@6 | 27 end | 
| Nenue@6 | 28 | 
| Nenue@6 | 29 T.defaults.toast = { | 
| Nenue@6 | 30   alert_hold = 2, | 
| Nenue@6 | 31   alert_fade = 1, | 
| Nenue@6 | 32   alert_flash = .6, | 
| Nenue@6 | 33   anchor = 'TOP', | 
| Nenue@6 | 34   parent = 'UIParent', | 
| Nenue@6 | 35   anchorTo = 'TOP', | 
| Nenue@6 | 36   x = 0, y= -56, | 
| Nenue@6 | 37   loot = { | 
| Nenue@6 | 38     background_color = {}, | 
| Nenue@6 | 39   } | 
| Nenue@6 | 40 } | 
| Nenue@6 | 41 | 
| Nenue@6 | 42 mod.events = { | 
| Nenue@6 | 43   "ACHIEVEMENT_EARNED", | 
| Nenue@6 | 44   "CRITERIA_EARNED", | 
| Nenue@6 | 45   "LFG_COMPLETION_REWARD", | 
| Nenue@6 | 46   "GUILD_CHALLENGE_COMPLETED", | 
| Nenue@6 | 47   "CHALLENGE_MODE_COMPLETED", | 
| Nenue@6 | 48   "LOOT_ITEM_ROLL_WON", | 
| Nenue@6 | 49   "SHOW_LOOT_TOAST", | 
| Nenue@6 | 50   "SHOW_LOOT_TOAST_UPGRADE", | 
| Nenue@6 | 51   "SHOW_PVP_FACTION_LOOT_TOAST", | 
| Nenue@6 | 52   "PET_BATTLE_CLOSE", | 
| Nenue@6 | 53   "STORE_PRODUCT_DELIVERED", | 
| Nenue@6 | 54   "GARRISON_BUILDING_ACTIVATABLE", | 
| Nenue@6 | 55   "GARRISON_MISSION_FINISHED", | 
| Nenue@6 | 56   "GARRISON_FOLLOWER_ADDED", | 
| Nenue@6 | 57   "GARRISON_RANDOM_MISSION_ADDED", | 
| Nenue@6 | 58   "BOSS_KILL", | 
| Nenue@6 | 59   "ENCOUNTER_LOOT_RECEIVED", | 
| Nenue@6 | 60 } | 
| Nenue@6 | 61 | 
| Nenue@6 | 62 mod.events_args = { | 
| Nenue@6 | 63   ['ACHIEVEMENT_EARNED'] = {12, false}, | 
| Nenue@6 | 64   ['ACHIEVEMENT_EARNED'] = {12, true}, | 
| Nenue@6 | 65   ['LFG_COMPLETED_REWARD'] = {}, | 
| Nenue@6 | 66 } | 
| Nenue@6 | 67 local y_factor = -1 | 
| Nenue@6 | 68 local x_factor = 0 | 
| Nenue@6 | 69 local tkAlerts = TkAlertContainer | 
| Nenue@6 | 70 local AlertFrame_FixPosition = function(alertFrame) | 
| Nenue@6 | 71   print('   pos:', alertFrame.order, cKey(alertFrame.x), cWord(alertFrame.y)) | 
| Nenue@6 | 72   alertFrame:SetPoint('TOPLEFT', tkAlerts, 'TOPLEFT', alertFrame.x, alertFrame.y) | 
| Nenue@6 | 73 end | 
| Nenue@6 | 74 | 
| Nenue@6 | 75 --- Goes through the alert container index and fixes the frame positions | 
| Nenue@6 | 76 -- used before and after an alert frame changes visibility | 
| Nenue@6 | 77 local AlertContainer_Update = function(self) | 
| Nenue@6 | 78   local anum = 1 | 
| Nenue@6 | 79   local offset = 0 | 
| Nenue@6 | 80   for i, alert in ipairs(tkAlerts.alerts) do | 
| Nenue@6 | 81     if alert:IsShown() then | 
| Nenue@6 | 82       alert.x = offset * x_factor | 
| Nenue@6 | 83       alert.y = offset * y_factor | 
| Nenue@6 | 84       alert.drawHeight = alert.ename:GetStringHeight()+ alert.desc:GetStringHeight() | 
| Nenue@6 | 85       alert.order = anum | 
| Nenue@6 | 86       anum = anum + 1 | 
| Nenue@6 | 87       offset = offset + alert.drawHeight | 
| Nenue@6 | 88       print('   draw height:', i, cText(alert.drawHeight)) | 
| Nenue@6 | 89       print('      position:', i, cPink(offset)) | 
| Nenue@6 | 90       AlertFrame_FixPosition(alert) | 
| Nenue@6 | 91       print('index', i, 'shifted from position', cNum(alert.order), 'to', cNum(anum), ' at draw point', alert.y) | 
| Nenue@6 | 92       print('    draw distance update ', cNum(0), 'x', cNum(offset)) | 
| Nenue@6 | 93     else | 
| Nenue@6 | 94       print('index', i, 'is not visible') | 
| Nenue@6 | 95     end | 
| Nenue@6 | 96   end | 
| Nenue@6 | 97   self:SetHeight(offset) | 
| Nenue@6 | 98 end | 
| Nenue@6 | 99 | 
| Nenue@6 | 100 --- config mode blocking command | 
| Nenue@6 | 101 local AlertFrame_Block = function(alertFrame) | 
| Nenue@6 | 102   -- only do stuff when configMode is on | 
| Nenue@6 | 103   if not mod.configMode then | 
| Nenue@6 | 104     return | 
| Nenue@6 | 105   end | 
| Nenue@6 | 106 end | 
| Nenue@6 | 107 | 
| Nenue@6 | 108 --- if not config mode, then fire at the end of fadeIn animation to queue fadeOut | 
| Nenue@6 | 109 local AlertFrame_Pin = function(alertFrame) | 
| Nenue@6 | 110   if not mod.configMode then | 
| Nenue@6 | 111     alertFrame.fadeOut.a1:SetStartDelay(db.alert_hold) | 
| Nenue@6 | 112     alertFrame.fadeOut:Play() | 
| Nenue@6 | 113   end | 
| Nenue@6 | 114 end | 
| Nenue@6 | 115 | 
| Nenue@6 | 116 --- if not config mode, then fire at the end of fadeOut to remove the frame from view and trigger positions update | 
| Nenue@6 | 117 local AlertFrame_Remove = function(alertFrame) | 
| Nenue@6 | 118   mod.num_events = mod.num_events - 1 | 
| Nenue@6 | 119   alertFrame:Hide() | 
| Nenue@6 | 120   print(mod.num_events) | 
| Nenue@6 | 121   AlertContainer_Update(tkAlerts) | 
| Nenue@6 | 122 end | 
| Nenue@6 | 123 | 
| Nenue@6 | 124 --- orders all visible frames to fadeOut | 
| Nenue@6 | 125 -- @param stagger forces the spacing of startDelay times for each frame | 
| Nenue@6 | 126 local AlertContainer_Clear = function(self, stagger) | 
| Nenue@6 | 127   stagger = stagger or 0.1 | 
| Nenue@6 | 128   for i = #self.alerts, 1, -1 do | 
| Nenue@6 | 129     print('clear check', i) | 
| Nenue@6 | 130     local alert = self.alerts[i] | 
| Nenue@6 | 131     if alert:IsShown() and not alert.fadeOut:IsPlaying() then | 
| Nenue@6 | 132       alert.fadeOut.a1:SetStartDelay((#self.alerts-i)* stagger) | 
| Nenue@6 | 133       alert.fadeOut:Play() | 
| Nenue@6 | 134     end | 
| Nenue@6 | 135   end | 
| Nenue@6 | 136 end | 
| Nenue@6 | 137 local AlertContainer_Unlock = function() | 
| Nenue@6 | 138 end | 
| Nenue@6 | 139 | 
| Nenue@6 | 140 --- Displays a new alert | 
| Nenue@6 | 141 -- @param name text naming the class of event that occurred | 
| Nenue@6 | 142 -- @param text alert subtext describing basic info about the event | 
| Nenue@6 | 143 -- @order order (optional) sets display slot of the alert | 
| Nenue@6 | 144 local function AlertContainer_ShowAlert(self, name, text, order) | 
| Nenue@6 | 145   local db = TurokData.toast | 
| Nenue@6 | 146   mod.num_events = mod.num_events + 1 | 
| Nenue@6 | 147 | 
| Nenue@6 | 148   local alertFrame | 
| Nenue@6 | 149   if not order then | 
| Nenue@6 | 150   local i = 1 | 
| Nenue@6 | 151     while i <= #self.alerts and not alertFrame do | 
| Nenue@6 | 152       if not self.alerts[i]:IsShown() then | 
| Nenue@6 | 153         alertFrame = self.alerts[i] | 
| Nenue@6 | 154         print('re-using alert frame #', i) | 
| Nenue@6 | 155       end | 
| Nenue@6 | 156       i = i +1 | 
| Nenue@6 | 157     end | 
| Nenue@6 | 158   else | 
| Nenue@6 | 159     alertFrame = self.alerts[order] | 
| Nenue@6 | 160   end | 
| Nenue@6 | 161 | 
| Nenue@6 | 162   if not alertFrame then | 
| Nenue@6 | 163     alertFrame = CreateFrame('Frame', 'TkAlertPanel'..(order or #self.alerts+1), self, 'TkAlertFrame') | 
| Nenue@6 | 164     self.alerts[#self.alerts+1] = alertFrame | 
| Nenue@6 | 165     print('creating new alert frame', #self.alerts) | 
| Nenue@6 | 166 | 
| Nenue@6 | 167     alertFrame.Pin = AlertFrame_Pin | 
| Nenue@6 | 168     alertFrame.Remove = AlertFrame_Remove | 
| Nenue@6 | 169   end | 
| Nenue@6 | 170 | 
| Nenue@6 | 171   alertFrame.ename:SetText(name) | 
| Nenue@6 | 172   local height1 = alertFrame.ename:GetStringHeight() | 
| Nenue@6 | 173   alertFrame.desc:SetText(text) | 
| Nenue@6 | 174   local height2 = height1+ alertFrame.desc:GetStringHeight() | 
| Nenue@6 | 175   alertFrame.desc:SetPoint('TOPLEFT', alertFrame, 'TOPLEFT', 0, -height1) | 
| Nenue@6 | 176 | 
| Nenue@6 | 177   alertFrame.order = order or mod.num_events | 
| Nenue@6 | 178   alertFrame:SetSize(300, height2) | 
| Nenue@6 | 179   alertFrame:Show() | 
| Nenue@6 | 180   --alertFrame.flashIn.a1:SetDuration(db.alert_flash/2) | 
| Nenue@6 | 181   --alertFrame.flashIn.a2:SetDuration(db.alert_flash/2) | 
| Nenue@6 | 182   alertFrame.flashIn:Play() | 
| Nenue@6 | 183   if not mod.configMode then | 
| Nenue@6 | 184     AlertContainer_Update(tkAlerts) | 
| Nenue@6 | 185   end | 
| Nenue@6 | 186 end | 
| Nenue@6 | 187 | 
| Nenue@6 | 188 | 
| Nenue@6 | 189 --- updates the completed missions index and returns info on the mission ID if passed | 
| Nenue@6 | 190 local completedMissions | 
| Nenue@6 | 191 local Garrison_UpdateCompleteMissions = function(missionID) | 
| Nenue@6 | 192   completedMissions = C_Garrison.GetCompleteMissions() | 
| Nenue@6 | 193   --- slide entries around for reference | 
| Nenue@6 | 194   for i, set in ipairs(completedMissions) do | 
| Nenue@6 | 195     if i ~= set.missionID then | 
| Nenue@6 | 196       completedMissions[set.missionID] = set | 
| Nenue@6 | 197       completedMissions[i] = nil | 
| Nenue@6 | 198     end | 
| Nenue@6 | 199   end | 
| Nenue@6 | 200 | 
| Nenue@6 | 201   if missionID and completedMissions[missionID] then | 
| Nenue@6 | 202     local m = completedMissions[missionID] | 
| Nenue@6 | 203     return m.name, m.location, m.locPrefix, m.isRare, m.followers, m.rewards, m.state | 
| Nenue@6 | 204   else | 
| Nenue@6 | 205     return false | 
| Nenue@6 | 206   end | 
| Nenue@6 | 207 end | 
| Nenue@6 | 208 --- container events handler | 
| Nenue@6 | 209 local AlertContainer_OnEvent = function (self, event, ...) | 
| Nenue@6 | 210   print(event, ...) | 
| Nenue@6 | 211   tkAlerts:Show() | 
| Nenue@6 | 212   if event == 'SHOW_LOOT_TOAST' then | 
| Nenue@6 | 213     local typeIdentifier, itemLink, quantity, specID, sex, isPersonal, lootSource = ...; | 
| Nenue@6 | 214     if typeIdentifier == "currency" then | 
| Nenue@6 | 215       AlertContainer_ShowAlert(self, itemLink, 'x'..quantity) | 
| Nenue@6 | 216     elseif typeIdentifier == "item" then | 
| Nenue@6 | 217       local _, _, _, ilvl, _, _, _, _, equipSlot = GetItemInfo(itemLink) | 
| Nenue@6 | 218       AlertContainer_ShowAlert(self, itemLink, tostring(ilvl)..' '..tostring(_G[equipSlot])) | 
| Nenue@6 | 219     end | 
| Nenue@6 | 220   elseif event == 'GARRISON_MISSION_FINISHED' then | 
| Nenue@6 | 221     local missionID = ... | 
| Nenue@6 | 222     local name, location, locPrefix, isRare, followers, rewards = Garrison_UpdateCompleteMissions(missionID) | 
| Nenue@6 | 223     local mission_info = { | 
| Nenue@6 | 224       (isRare and ('|cFF44BBFF') or ('|cFFFFFF00')..name.. '|r'), | 
| Nenue@6 | 225     } | 
| Nenue@6 | 226 | 
| Nenue@6 | 227     if followers then | 
| Nenue@6 | 228       for i, guid in ipairs(followers) do | 
| Nenue@6 | 229         print(C_Garrison.GetFollowerInfo(guid)) | 
| Nenue@6 | 230       end | 
| Nenue@6 | 231     end | 
| Nenue@6 | 232 | 
| Nenue@6 | 233       --'|T:'..icon..':0 | 
| Nenue@6 | 234 | 
| Nenue@6 | 235 | 
| Nenue@6 | 236     AlertContainer_ShowAlert(self, 'Mission Complete') | 
| Nenue@6 | 237   elseif event == 'GARRISON_BUILDING_ACTIVATABLE' then | 
| Nenue@6 | 238     local missionID = ... | 
| Nenue@6 | 239   elseif event == 'ACHIEVEMENT_EARNED' then | 
| Nenue@6 | 240   elseif event == 'LFG_COMPLETION_REWARD' then | 
| Nenue@6 | 241     local name, typeID, subtypeID, textureFilename, moneyBase, moneyVar, experienceBase, experienceVar, numStrangers, numRewards = GetLFGCompletionReward() | 
| Nenue@6 | 242     local _, _, _, _, hasBonusStep, isBonusStepComplete = C_Scenario.GetInfo(); | 
| Nenue@6 | 243 | 
| Nenue@6 | 244   end | 
| Nenue@6 | 245 end | 
| Nenue@6 | 246 | 
| Nenue@6 | 247 local AlertContainer_Test = function() | 
| Nenue@6 | 248   if not mod.configMode then | 
| Nenue@6 | 249     print('starting test mode') | 
| Nenue@6 | 250     tkAlerts:Show() | 
| Nenue@6 | 251     mod.configMode = true | 
| Nenue@6 | 252 | 
| Nenue@6 | 253     tkAlerts.configBG:Show() | 
| Nenue@6 | 254     tkAlerts.configBG:SetTexture(0,0.5,0,0.5) | 
| Nenue@6 | 255     tkAlerts:RegisterForDrag('LeftButton') | 
| Nenue@6 | 256     tkAlerts:EnableMouse(true) | 
| Nenue@6 | 257 | 
| Nenue@6 | 258     for i, frame in ipairs(tkAlerts.tools) do | 
| Nenue@6 | 259       frame:Show() | 
| Nenue@6 | 260     end | 
| Nenue@6 | 261     -- test fillers | 
| Nenue@6 | 262     local _,_, offset, range = GetSpellTabInfo(2) | 
| Nenue@6 | 263     print(offset, range) | 
| Nenue@6 | 264 | 
| Nenue@6 | 265     for i, event in ipairs(mod.events) do | 
| Nenue@6 | 266       --print(i, event) | 
| Nenue@6 | 267       local _, id = GetSpellBookItemInfo(math.random(offset, offset+range), 'spell') | 
| Nenue@6 | 268       print(id) | 
| Nenue@6 | 269 | 
| Nenue@6 | 270       local name = GetSpellLink(id) | 
| Nenue@6 | 271       local text = GetSpellDescription(id) | 
| Nenue@6 | 272       if not tkAlerts.alerts[i] then | 
| Nenue@6 | 273         print('creating alert frame #', i) | 
| Nenue@6 | 274         AlertContainer_ShowAlert(tkAlerts, name, text, i) | 
| Nenue@6 | 275       else | 
| Nenue@6 | 276         print('updating alert frame #', i) | 
| Nenue@6 | 277         local alert = tkAlerts.alerts[i] | 
| Nenue@6 | 278         alert:Show() | 
| Nenue@6 | 279         alert.order = i | 
| Nenue@6 | 280         alert.ename:SetText(name) | 
| Nenue@6 | 281         alert.desc:SetText(text) | 
| Nenue@6 | 282         if alert.fadeOut:IsPlaying() then | 
| Nenue@6 | 283           alert.fadeOut:Stop() | 
| Nenue@6 | 284           alert.backdrop:SetAlpha(0.5) | 
| Nenue@6 | 285         end | 
| Nenue@6 | 286 | 
| Nenue@6 | 287         alert.flashIn:Play() | 
| Nenue@6 | 288       end | 
| Nenue@6 | 289     end | 
| Nenue@6 | 290     AlertContainer_Update(tkAlerts) | 
| Nenue@6 | 291   else | 
| Nenue@6 | 292     tkAlerts:EnableMouse(false) | 
| Nenue@6 | 293     tkAlerts.configBG:Hide() | 
| Nenue@6 | 294     mod.configMode = nil | 
| Nenue@6 | 295     for i, frame in ipairs(tkAlerts.tools) do | 
| Nenue@6 | 296       frame:Hide() | 
| Nenue@6 | 297     end | 
| Nenue@6 | 298     for i, alert in ipairs(tkAlerts.alerts) do | 
| Nenue@6 | 299       for j, frame in ipairs(alert.tools) do | 
| Nenue@6 | 300         frame:Hide() | 
| Nenue@6 | 301       end | 
| Nenue@6 | 302       alert.fadeOut.a1:SetStartDelay(i*0.2) | 
| Nenue@6 | 303       alert.fadeOut:Play() | 
| Nenue@6 | 304     end | 
| Nenue@6 | 305 | 
| Nenue@6 | 306   end | 
| Nenue@6 | 307 end | 
| Nenue@6 | 308 | 
| Nenue@6 | 309 mod.OnEnable = function() | 
| Nenue@6 | 310   db = TurokData.toast | 
| Nenue@6 | 311 | 
| Nenue@6 | 312   --- find the closest frame to the center bottom and anchor to that | 
| Nenue@6 | 313 | 
| Nenue@6 | 314   local cX, cY = (GetScreenWidth() / 2), (GetScreenHeight() / 2) | 
| Nenue@6 | 315   local min_skewness = cX | 
| Nenue@6 | 316   local max_centrality, center_frame | 
| Nenue@6 | 317   for n, f in ipairs({UIParent:GetChildren()}) do | 
| Nenue@6 | 318     if type(f) == 'table' and f.GetObjectType and f.GetName then | 
| Nenue@6 | 319       if f.IsForbidden and f:IsForbidden() then | 
| Nenue@6 | 320         print(n, 'is a forbidden object') | 
| Nenue@6 | 321       else | 
| Nenue@6 | 322         local name = f:GetName() | 
| Nenue@6 | 323 | 
| Nenue@6 | 324         if f:IsVisible() and f:IsMouseEnabled() then | 
| Nenue@6 | 325           print(name and name or tostring(f):sub(8), 'is a frame!') | 
| Nenue@6 | 326           local x = f:GetCenter() | 
| Nenue@6 | 327           local y = f:GetTop()    -- Y need center top position | 
| Nenue@6 | 328           if (x and y) and (y <= cY) then | 
| Nenue@6 | 329             x = math.abs(x - cX) -- X works in either direction | 
| Nenue@6 | 330 | 
| Nenue@6 | 331             -- distance of current - distant of record / max to get ratio of 1 where direct center results in 1 | 
| Nenue@6 | 332             local skewness_factor = (cX - x) / cX | 
| Nenue@6 | 333             local vertness_factor = y / cY | 
| Nenue@6 | 334             local centrality = skewness_factor * vertness_factor | 
| Nenue@6 | 335             print('result: (', floor(x), floor(y), ') = ', skewness_factor, 'skew,', vertness_factor, 'vertness.\nTotal score:', cNum(centrality)) | 
| Nenue@6 | 336             if (not max_centrality) or max_centrality < centrality then | 
| Nenue@6 | 337               center_frame = f | 
| Nenue@6 | 338               max_centrality = centrality | 
| Nenue@6 | 339               print(cWord(name and name or tostring(f):sub(8)),cPink(' is the new record!')) | 
| Nenue@6 | 340             end | 
| Nenue@6 | 341 | 
| Nenue@6 | 342           end | 
| Nenue@6 | 343         end | 
| Nenue@6 | 344       end | 
| Nenue@6 | 345     end | 
| Nenue@6 | 346   end | 
| Nenue@6 | 347 | 
| Nenue@6 | 348   mod.num_events = 0 | 
| Nenue@6 | 349   tkAlerts.alerts = {} | 
| Nenue@6 | 350   for i, event in ipairs(mod.events) do | 
| Nenue@6 | 351     tkAlerts:RegisterEvent(event) | 
| Nenue@6 | 352   end | 
| Nenue@6 | 353 | 
| Nenue@6 | 354   tkAlerts.Clear = AlertContainer_Clear | 
| Nenue@6 | 355   tkAlerts.Unlock = AlertContainer_Unlock | 
| Nenue@6 | 356   tkAlerts.Close = AlertContainer_Test | 
| Nenue@6 | 357 | 
| Nenue@6 | 358   tkAlerts:ClearAllPoints() | 
| Nenue@6 | 359   tkAlerts:SetPoint(db.anchor, db.parent, db.anchorTo, db.x, db.y) | 
| Nenue@6 | 360   tkAlerts.x = db.x | 
| Nenue@6 | 361   tkAlerts.y = db.y | 
| Nenue@6 | 362   tkAlerts.parent = db.parent | 
| Nenue@6 | 363   tkAlerts.anchor = db.anchor | 
| Nenue@6 | 364   tkAlerts.anchorTo = db.anchorTo | 
| Nenue@6 | 365   tkAlerts:EnableMouse(false) | 
| Nenue@6 | 366 | 
| Nenue@6 | 367   tkAlerts:SetScript('OnEvent', AlertContainer_OnEvent) | 
| Nenue@6 | 368   T:RegisterChatCommand("alert", AlertContainer_Test) | 
| Nenue@6 | 369   T:RegisterChatCommand("atest", function() | 
| Nenue@6 | 370     AlertContainer_OnEvent(tkAlerts, 'GARRISON_MISSION_FINISHED', 327) | 
| Nenue@6 | 371   end) | 
| Nenue@6 | 372 end |