Nenue@13
|
1 local B = select(2,...).frame
|
Nenue@13
|
2 local mod = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame')
|
Nenue@13
|
3 local print = B.print('WidgetFactory')
|
Nenue@13
|
4 local UIParent = UIParent
|
Nenue@13
|
5 local GetQuestLogSpecialItemInfo, IsQuestLogSpecialItemInRange, GetQuestLogSpecialItemCooldown = GetQuestLogSpecialItemInfo, IsQuestLogSpecialItemInRange, GetQuestLogSpecialItemCooldown
|
Nenue@13
|
6 local CooldownFrame_SetTimer, SetItemButtonTextureVertexColor, CreateFrame, VeneerObjectiveScroll = CooldownFrame_SetTimer, SetItemButtonTextureVertexColor, CreateFrame, VeneerObjectiveScroll
|
Nenue@13
|
7 local tremove, tinsert, tContains, pairs, setmetatable = tremove, tinsert, tContains, pairs, setmetatable
|
Nenue@13
|
8 ----------------------------------------------------------------------------------------
|
Nenue@13
|
9 --- XML and script code lifted from "QuestKing 2" by Barjack,
|
Nenue@13
|
10 --- found at http://mods.curse.com/addons/wow/questking
|
Nenue@13
|
11 ----------------------------------------------------------------------------------------
|
Nenue@13
|
12 local usedButtons = mod.Quest.itemButtons
|
Nenue@13
|
13 local freeButtons = mod.Quest.freeButtons
|
Nenue@13
|
14 mod.SetItemButton = function(block, info)
|
Nenue@13
|
15 local itemInfo = info.specialItem
|
Nenue@13
|
16 if not itemInfo then
|
Nenue@13
|
17 return
|
Nenue@13
|
18 end
|
Nenue@13
|
19
|
Nenue@13
|
20 --- Quest.GetInfo().specialItem :: {link = link, charges = charges, icon = icon, start = start, duration = duration, enable = enable}
|
Nenue@13
|
21
|
Nenue@13
|
22
|
Nenue@13
|
23 local itemButton
|
Nenue@13
|
24 if not info.itemButton then
|
Nenue@13
|
25 if #freeButtons >= 1 then
|
Nenue@13
|
26 print(' |cFF00FFFFfound a free button')
|
Nenue@13
|
27 itemButton = freeButtons[#freeButtons]
|
Nenue@13
|
28 freeButtons[#freeButtons] = nil
|
Nenue@13
|
29 if itemButton.block then
|
Nenue@13
|
30 itemButton.block.itemButton = nil
|
Nenue@13
|
31 itemButton.block = nil
|
Nenue@13
|
32 end
|
Nenue@13
|
33 else
|
Nenue@13
|
34 local buttonIndex = mod.Quest.numButtons + #freeButtons + 1
|
Nenue@13
|
35 itemButton = CreateFrame('Button', 'VeneerQuestItemButton' .. buttonIndex, UIParent, 'VeneerItemButtonTemplate')
|
Nenue@13
|
36 itemButton.buttonIndex = buttonIndex
|
Nenue@13
|
37 itemButton:SetSize(36, 36)
|
Nenue@13
|
38 itemButton:GetNormalTexture():SetSize(36 * (5/3), 36 * (5/3))
|
Nenue@13
|
39 print(' |cFFFF4400starting new button', itemButton:GetName())
|
Nenue@13
|
40 end
|
Nenue@13
|
41 mod.Quest.numButtons = mod.Quest.numButtons + 1
|
Nenue@13
|
42 else
|
Nenue@13
|
43 itemButton = info.itemButton
|
Nenue@13
|
44 print(' |cFF00FF00found assigned button', itemButton:GetName())
|
Nenue@13
|
45
|
Nenue@13
|
46 end
|
Nenue@13
|
47 -- set values
|
Nenue@13
|
48
|
Nenue@13
|
49 info.itemButton = itemButton
|
Nenue@13
|
50 usedButtons[info.questID] = itemButton
|
Nenue@13
|
51 print(' |cFF8800FFassigning|r', itemButton:GetName(), 'to quest|cFF00FF00', info.questID, '|rat|cFFFFFF00', block:GetName(),'|r')
|
Nenue@13
|
52
|
Nenue@13
|
53 for k,v in pairs(usedButtons) do
|
Nenue@13
|
54 print('|cFFFF44DD'..k..'|r', v:GetName())
|
Nenue@13
|
55 end
|
Nenue@13
|
56
|
Nenue@13
|
57 itemButton:SetAttribute("type", "item")
|
Nenue@13
|
58 itemButton:SetAttribute("item", itemInfo.link)
|
Nenue@13
|
59
|
Nenue@13
|
60 itemButton.questID = info.questID
|
Nenue@13
|
61 itemButton.questLogIndex = info.questLogIndex
|
Nenue@13
|
62 itemButton.charges = itemInfo.charges
|
Nenue@13
|
63 itemButton.rangeTimer = -1
|
Nenue@13
|
64 itemButton.block = block
|
Nenue@13
|
65
|
Nenue@13
|
66 SetItemButtonTexture(itemButton, itemInfo.icon)
|
Nenue@13
|
67 SetItemButtonCount(itemButton, itemInfo.charges)
|
Nenue@13
|
68 Veneer_QuestObjectiveItem_UpdateCooldown(itemButton);
|
Nenue@13
|
69
|
Nenue@13
|
70 return itemButton
|
Nenue@13
|
71 end
|
Nenue@13
|
72 --- Clear an itemButton from the given block
|
Nenue@13
|
73 mod.FreeItemButtons = function(block)
|
Nenue@13
|
74
|
Nenue@13
|
75 if block.itemButton then
|
Nenue@13
|
76 local itemButton = block.itemButton
|
Nenue@13
|
77 if itemButton.questID ~= block.info.questID then
|
Nenue@13
|
78 block.itemButton = nil
|
Nenue@13
|
79 itemButton.block = mod.Quest.InfoBlock[itemButton.questID]
|
Nenue@13
|
80 else
|
Nenue@13
|
81 itemButton.block = nil
|
Nenue@13
|
82 itemButton:Hide()
|
Nenue@13
|
83
|
Nenue@13
|
84 usedButtons[itemButton.questID] = nil
|
Nenue@13
|
85 freeButtons[#freeButtons + 1] = itemButton
|
Nenue@13
|
86 mod.Quest.numButtons = mod.Quest.numButtons - 1
|
Nenue@13
|
87 print('|cFFFF0088released', itemButton:GetName(),'and', block:GetName())
|
Nenue@13
|
88 end
|
Nenue@13
|
89 end
|
Nenue@13
|
90 end
|
Nenue@13
|
91
|
Nenue@13
|
92 function Veneer_QuestObjectiveItem_OnUpdate (self, elapsed)
|
Nenue@13
|
93 -- Handle range indicator
|
Nenue@13
|
94 local rangeTimer = self.rangeTimer
|
Nenue@13
|
95 if (rangeTimer) then
|
Nenue@13
|
96 rangeTimer = rangeTimer - elapsed
|
Nenue@13
|
97 if (rangeTimer <= 0) then
|
Nenue@13
|
98 local link, item, charges, showItemWhenComplete = GetQuestLogSpecialItemInfo(self.questLogIndex)
|
Nenue@13
|
99 if ((not charges) or (charges ~= self.charges)) then
|
Nenue@13
|
100 mod.UpdateWrapper()
|
Nenue@13
|
101 return
|
Nenue@13
|
102 end
|
Nenue@13
|
103
|
Nenue@13
|
104 local count = self.HotKey
|
Nenue@13
|
105 local valid = IsQuestLogSpecialItemInRange(self.questLogIndex)
|
Nenue@13
|
106 if (valid == 0) then
|
Nenue@13
|
107 count:Show()
|
Nenue@13
|
108 count:SetVertexColor(1.0, 0.1, 0.1)
|
Nenue@13
|
109 elseif (valid == 1) then
|
Nenue@13
|
110 count:Show()
|
Nenue@13
|
111 count:SetVertexColor(0.6, 0.6, 0.6)
|
Nenue@13
|
112 else
|
Nenue@13
|
113 count:Hide()
|
Nenue@13
|
114 end
|
Nenue@13
|
115 rangeTimer = TOOLTIP_UPDATE_TIME
|
Nenue@13
|
116 end
|
Nenue@13
|
117
|
Nenue@13
|
118 self.rangeTimer = rangeTimer
|
Nenue@13
|
119 end
|
Nenue@13
|
120 end
|
Nenue@13
|
121
|
Nenue@13
|
122 function Veneer_QuestObjectiveItem_UpdateCooldown (itemButton)
|
Nenue@13
|
123 local start, duration, enable = GetQuestLogSpecialItemCooldown(itemButton.questLogIndex)
|
Nenue@13
|
124 if (start) then
|
Nenue@13
|
125 CooldownFrame_SetTimer(itemButton.Cooldown, start, duration, enable)
|
Nenue@13
|
126 if (duration > 0 and enable == 0) then
|
Nenue@13
|
127 SetItemButtonTextureVertexColor(itemButton, 0.4, 0.4, 0.4)
|
Nenue@13
|
128 else
|
Nenue@13
|
129 SetItemButtonTextureVertexColor(itemButton, 1, 1, 1)
|
Nenue@13
|
130 end
|
Nenue@13
|
131 end
|
Nenue@13
|
132 end
|
Nenue@13
|
133
|
Nenue@13
|
134 -----------------------------------------
|
Nenue@13
|
135 -- Criteria frames
|
Nenue@13
|
136
|
Nenue@13
|
137 --[[
|
Nenue@13
|
138 text = description,
|
Nenue@13
|
139 type = type,
|
Nenue@13
|
140 finished = completed,
|
Nenue@13
|
141 quantity = quantity,
|
Nenue@13
|
142 requiredQuantity = requiredQuantity,
|
Nenue@13
|
143 characterName = characterName,
|
Nenue@13
|
144 flags = flags,
|
Nenue@13
|
145 assetID = assetID,
|
Nenue@13
|
146 quantityString = quantityString,
|
Nenue@13
|
147 criteriaID = criteriaID,
|
Nenue@13
|
148 ]]
|
Nenue@13
|
149 local newWidgetID = 0
|
Nenue@13
|
150 mod.WidgetRegistry = {}
|
Nenue@13
|
151 local wr = mod.WidgetRegistry
|
Nenue@13
|
152
|
Nenue@13
|
153 --- Get a usable widget for the given achievement criteria set.
|
Nenue@13
|
154 -- Returns a frame object with dimensioning parameters needed to size the receiving tracker block
|
Nenue@13
|
155 mod.SetWidget = function(obj, info)
|
Nenue@13
|
156 local print = B.print('ObjectiveWidgets')
|
Nenue@13
|
157 local widgetType = obj.type
|
Nenue@13
|
158 local widget
|
Nenue@13
|
159 if wr[widgetType] and wr[widgetType].used[obj.criteriaID] then
|
Nenue@13
|
160 widget = wr[widgetType].used[obj.criteriaID]
|
Nenue@13
|
161 print('|cFF00FF00Updating ('..obj.criteriaID..')', widget)
|
Nenue@13
|
162 elseif not wr[widgetType] or #wr[widgetType].free == 0 then
|
Nenue@13
|
163 widget = CreateFrame('Frame', 'VeneerObjective' .. widgetType .. (wr[widgetType] and (wr[widgetType].lastn+1) or (1)), VeneerObjectiveScroll, 'VeneerObjectiveCriteria' .. widgetType)
|
Nenue@13
|
164
|
Nenue@13
|
165 print('|cFFFF0088Creating `'..widget:GetName()..'` id', wr[widgetType].lastn)
|
Nenue@13
|
166 else
|
Nenue@13
|
167 widget = tremove(wr[widgetType].free)
|
Nenue@13
|
168 print('|cFFFFFF00Acquiring released widget', widget:GetName())
|
Nenue@13
|
169 end
|
Nenue@13
|
170
|
Nenue@13
|
171 wr[widgetType].used[obj.criteriaID] = widget
|
Nenue@13
|
172 widget.info = obj
|
Nenue@13
|
173 widget.parentInfo = info
|
Nenue@13
|
174 mod.InitializeWidget(widget)
|
Nenue@13
|
175 return widget
|
Nenue@13
|
176 end
|
Nenue@13
|
177
|
Nenue@13
|
178 --- WidgetTemplate 'OnLoad'
|
Nenue@13
|
179 mod.RegisterWidget = function(frame)
|
Nenue@13
|
180 local print = B.print('ObjectiveWidgets')
|
Nenue@13
|
181 local widgetType = frame.widgetType
|
Nenue@13
|
182 if not wr[frame.widgetType] then
|
Nenue@13
|
183 print('|cFFFF4400[[WidgetTemplate]]|r', widgetType)
|
Nenue@13
|
184 wr[widgetType] = { lastn = 1, free = {}, used = {}, usedIndex = {}, freeIndex = {} }
|
Nenue@13
|
185 else
|
Nenue@13
|
186 print('|cFF0088FF+ [[WidgetTemplate]]r', widgetType, wr[widgetType].lastn)
|
Nenue@13
|
187 wr[widgetType].lastn = wr[widgetType].lastn + 1
|
Nenue@13
|
188 end
|
Nenue@13
|
189 end
|
Nenue@13
|
190
|
Nenue@13
|
191 --- WidgetTemplate 'OnShow'
|
Nenue@13
|
192 mod.InitializeWidget = setmetatable({}, {
|
Nenue@13
|
193 __call = function(t, frame)
|
Nenue@13
|
194 -- todo: config pull
|
Nenue@13
|
195 local maxWidth = 250
|
Nenue@13
|
196
|
Nenue@13
|
197 frame:SetWidth(maxWidth)
|
Nenue@13
|
198 mod.UpdateWidget[frame.widgetType](frame)
|
Nenue@13
|
199 frame:SetScript('OnEvent', mod.UpdateWidget[frame.widgetType])
|
Nenue@13
|
200 if frame.info.isCurrency then
|
Nenue@13
|
201 frame:RegisterEvent('CHAT_MSG_CURRENCY')
|
Nenue@13
|
202 frame:RegisterEvent('CURRENCY_LIST_UPDATE')
|
Nenue@13
|
203 end
|
Nenue@13
|
204 frame:RegisterEvent('TRACKED_ACHIEVEMENT_UPDATE')
|
Nenue@13
|
205 frame:RegisterEvent('TRACKED_ACHIEVEMENT_LIST_CHANGED')
|
Nenue@13
|
206 frame:RegisterEvent('CRITERIA_UPDATE')
|
Nenue@13
|
207 frame:RegisterEvent('CRITERIA_COMPLETE')
|
Nenue@13
|
208 frame:RegisterEvent('CRITERIA_EARNED')
|
Nenue@13
|
209
|
Nenue@13
|
210 return t[frame.widgetType](frame)
|
Nenue@13
|
211 end,
|
Nenue@13
|
212 })
|
Nenue@13
|
213
|
Nenue@13
|
214 --- WidgetTemplate 'OnEvent'
|
Nenue@13
|
215 mod.UpdateWidget = setmetatable({}, {
|
Nenue@13
|
216 __call = function(t, frame)
|
Nenue@13
|
217 if not frame.widgetType then
|
Nenue@13
|
218 error('Invalid widget template, needs .widgetType')
|
Nenue@13
|
219 return
|
Nenue@13
|
220 end
|
Nenue@13
|
221
|
Nenue@13
|
222 return t[frame.widgetType](frame)
|
Nenue@13
|
223 end
|
Nenue@13
|
224 })
|
Nenue@13
|
225
|
Nenue@13
|
226 --- WidgetTemplate 'OnHide'
|
Nenue@13
|
227 mod.ReleaseWidget = function(frame)
|
Nenue@13
|
228 local print = B.print('ObjectiveWidgets')
|
Nenue@13
|
229 local reg = wr[frame.widgetType]
|
Nenue@13
|
230 if reg and reg.used[frame.info.criteriaID] then
|
Nenue@13
|
231 reg.used[frame.info.criteriaID] = nil
|
Nenue@13
|
232 frame.info = nil
|
Nenue@13
|
233 frame.parentInfo = nil
|
Nenue@13
|
234 frame:UnregisterAllEvents()
|
Nenue@13
|
235 tinsert(reg.free, frame)
|
Nenue@13
|
236 print('|cFFBBBBBBreleased from service', frame:GetName())
|
Nenue@13
|
237 end
|
Nenue@13
|
238 end
|
Nenue@13
|
239
|
Nenue@13
|
240 --- RemoveTrackedAchievement post-hook
|
Nenue@13
|
241 mod.CleanWidgets = function()
|
Nenue@13
|
242 local print = B.print('ObjectiveWidgets')
|
Nenue@13
|
243 local tracked = {GetTrackedAchievements() }
|
Nenue@13
|
244 for type, reg in pairs(mod.WidgetRegistry) do
|
Nenue@13
|
245 print('collecting', type)
|
Nenue@13
|
246 for criteriaID, frame in pairs(reg.used) do
|
Nenue@13
|
247 local id = frame.info.cheevID
|
Nenue@13
|
248
|
Nenue@13
|
249 if id and not tContains(tracked, id) then
|
Nenue@13
|
250
|
Nenue@13
|
251 print(' untracked achievement', id, 'associated with', criteriaID, frame:GetName())
|
Nenue@13
|
252 frame:Hide()
|
Nenue@13
|
253 end
|
Nenue@13
|
254 end
|
Nenue@13
|
255 end
|
Nenue@13
|
256 end
|
Nenue@13
|
257
|
Nenue@13
|
258
|
Nenue@13
|
259 mod.defaults.WidgetVars = {
|
Nenue@13
|
260 ProgressBar = {
|
Nenue@13
|
261 bg = {
|
Nenue@13
|
262 Height = 20,
|
Nenue@13
|
263 },
|
Nenue@13
|
264 fg = {
|
Nenue@13
|
265 Height = 16,
|
Nenue@13
|
266 },
|
Nenue@13
|
267 status = {
|
Nenue@13
|
268 FontObject = _G.VeneerFontNormal
|
Nenue@13
|
269 }
|
Nenue@13
|
270 }
|
Nenue@13
|
271 }
|
Nenue@13
|
272 mod.InitializeWidget.ProgressBar = function(self)
|
Nenue@13
|
273 local c = mod.defaults.WidgetVars.ProgressBar
|
Nenue@13
|
274 local params = mod.WidgetParams[self.widgetType]
|
Nenue@13
|
275 self.height = params.height
|
Nenue@13
|
276 self:SetHeight(c.bg.Height)
|
Nenue@13
|
277 self.bg:SetHeight(c.bg.Height)
|
Nenue@13
|
278 self.fg:ClearAllPoints()
|
Nenue@13
|
279 self.fg:SetPoint('BOTTOMLEFT', self, 'BOTTOMLEFT', 2, 2)
|
Nenue@13
|
280 self.fg:SetHeight(c.fg.Height)
|
Nenue@13
|
281 self.status:SetFontObject(c.status.FontObject)
|
Nenue@13
|
282 self.status:SetText(self.info.quantityString)
|
Nenue@13
|
283 end
|
Nenue@13
|
284
|
Nenue@13
|
285 mod.UpdateWidget.ProgressBar = function (self)
|
Nenue@13
|
286 local quantity, requiredQuantity = self.info.quantity, self.info.requiredQuantity
|
Nenue@13
|
287
|
Nenue@13
|
288 if self.info.finished then
|
Nenue@13
|
289 self.fg:SetWidth(self.bg:GetWidth() - 4)
|
Nenue@13
|
290 elseif quantity == 0 then
|
Nenue@13
|
291 self.fg:Hide()
|
Nenue@13
|
292 else
|
Nenue@13
|
293 self.fg:Show()
|
Nenue@13
|
294 self.fg:SetWidth((self.bg:GetWidth()-4) * (quantity / requiredQuantity))
|
Nenue@13
|
295 end
|
Nenue@13
|
296 end
|
Nenue@13
|
297
|
Nenue@13
|
298
|
Nenue@13
|
299 mod.InitializeWidget.Hidden = function (self)
|
Nenue@13
|
300 self.height = 0
|
Nenue@13
|
301 end
|
Nenue@13
|
302 mod.UpdateWidget.Hidden = function (self)
|
Nenue@13
|
303 self.height= 0
|
Nenue@13
|
304 end |