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@11
|
33 anchor = 'TOPLEFT',
|
Nenue@6
|
34 parent = 'UIParent',
|
Nenue@11
|
35 anchorTo = 'LEFT',
|
Nenue@11
|
36 x =200, y= 0,
|
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@11
|
309 mod.GetToastsAnchor = function(self)
|
Nenue@6
|
310
|
Nenue@6
|
311 local cX, cY = (GetScreenWidth() / 2), (GetScreenHeight() / 2)
|
Nenue@6
|
312 local min_skewness = cX
|
Nenue@6
|
313 local max_centrality, center_frame
|
Nenue@6
|
314 for n, f in ipairs({UIParent:GetChildren()}) do
|
Nenue@6
|
315 if type(f) == 'table' and f.GetObjectType and f.GetName then
|
Nenue@6
|
316 if f.IsForbidden and f:IsForbidden() then
|
Nenue@6
|
317 print(n, 'is a forbidden object')
|
Nenue@6
|
318 else
|
Nenue@6
|
319 local name = f:GetName()
|
Nenue@6
|
320
|
Nenue@6
|
321 if f:IsVisible() and f:IsMouseEnabled() then
|
Nenue@6
|
322 print(name and name or tostring(f):sub(8), 'is a frame!')
|
Nenue@6
|
323 local x = f:GetCenter()
|
Nenue@6
|
324 local y = f:GetTop() -- Y need center top position
|
Nenue@6
|
325 if (x and y) and (y <= cY) then
|
Nenue@6
|
326 x = math.abs(x - cX) -- X works in either direction
|
Nenue@6
|
327
|
Nenue@6
|
328 -- distance of current - distant of record / max to get ratio of 1 where direct center results in 1
|
Nenue@6
|
329 local skewness_factor = (cX - x) / cX
|
Nenue@6
|
330 local vertness_factor = y / cY
|
Nenue@6
|
331 local centrality = skewness_factor * vertness_factor
|
Nenue@6
|
332 print('result: (', floor(x), floor(y), ') = ', skewness_factor, 'skew,', vertness_factor, 'vertness.\nTotal score:', cNum(centrality))
|
Nenue@6
|
333 if (not max_centrality) or max_centrality < centrality then
|
Nenue@6
|
334 center_frame = f
|
Nenue@6
|
335 max_centrality = centrality
|
Nenue@6
|
336 print(cWord(name and name or tostring(f):sub(8)),cPink(' is the new record!'))
|
Nenue@6
|
337 end
|
Nenue@6
|
338
|
Nenue@6
|
339 end
|
Nenue@6
|
340 end
|
Nenue@6
|
341 end
|
Nenue@6
|
342 end
|
Nenue@6
|
343 end
|
Nenue@11
|
344 return center_frame
|
Nenue@11
|
345 end
|
Nenue@11
|
346
|
Nenue@11
|
347 mod.OnEnable = function()
|
Nenue@11
|
348 db = TurokData.toast
|
Nenue@11
|
349
|
Nenue@11
|
350 --- find the closest frame to the center bottom and anchor to that
|
Nenue@11
|
351
|
Nenue@6
|
352
|
Nenue@6
|
353 mod.num_events = 0
|
Nenue@6
|
354 tkAlerts.alerts = {}
|
Nenue@6
|
355 for i, event in ipairs(mod.events) do
|
Nenue@6
|
356 tkAlerts:RegisterEvent(event)
|
Nenue@6
|
357 end
|
Nenue@6
|
358
|
Nenue@6
|
359 tkAlerts.Clear = AlertContainer_Clear
|
Nenue@6
|
360 tkAlerts.Unlock = AlertContainer_Unlock
|
Nenue@6
|
361 tkAlerts.Close = AlertContainer_Test
|
Nenue@6
|
362
|
Nenue@6
|
363 tkAlerts:ClearAllPoints()
|
Nenue@6
|
364 tkAlerts:SetPoint(db.anchor, db.parent, db.anchorTo, db.x, db.y)
|
Nenue@6
|
365 tkAlerts.x = db.x
|
Nenue@6
|
366 tkAlerts.y = db.y
|
Nenue@6
|
367 tkAlerts.parent = db.parent
|
Nenue@6
|
368 tkAlerts.anchor = db.anchor
|
Nenue@6
|
369 tkAlerts.anchorTo = db.anchorTo
|
Nenue@6
|
370 tkAlerts:EnableMouse(false)
|
Nenue@6
|
371
|
Nenue@6
|
372 tkAlerts:SetScript('OnEvent', AlertContainer_OnEvent)
|
Nenue@6
|
373 T:RegisterChatCommand("alert", AlertContainer_Test)
|
Nenue@6
|
374 T:RegisterChatCommand("atest", function()
|
Nenue@6
|
375 AlertContainer_OnEvent(tkAlerts, 'GARRISON_MISSION_FINISHED', 327)
|
Nenue@6
|
376 end)
|
Nenue@6
|
377 end |