Nenue@40
|
1 local _, db = ...
|
Nenue@4
|
2 local wipe, tinsert, sort = table.wipe, tinsert, table.sort
|
Nenue@2
|
3 local pairs, ipairs = pairs, ipairs
|
Nenue@4
|
4 local floor, mod, time = floor, mod, time
|
Nenue@32
|
5 local max, min = math.max, math.min
|
Nenue@2
|
6 local GetTime = GetTime
|
Nenue@3
|
7 local GI_currentTime = time()
|
Nenue@32
|
8 local print = DEVIAN_WORKSPACE and function(...) print('ClassPlan', ...) end or nop
|
Nenue@3
|
9
|
Nenue@32
|
10 local CP_REPLACE_LANDINGPAGE = true
|
Nenue@32
|
11 local CP_HEADER_SIZE = 24
|
Nenue@40
|
12 db.ClassPlanDefaultType = {
|
Nenue@40
|
13
|
Nenue@40
|
14 backgroundColor = {0, 0, 0, 0.5},
|
Nenue@40
|
15 textColor = {1,1,1,1}
|
Nenue@40
|
16 }
|
Nenue@40
|
17 db.ClassPlanTypes = setmetatable({}, {__index = db.ClassPlanDefaultType})
|
Nenue@40
|
18 db.ClassPlanTypes.inProgress = {
|
Nenue@40
|
19 backgroundColor = {0, 0, 0, 0.5},
|
Nenue@40
|
20 textColor = {1,1,1}
|
Nenue@40
|
21 }
|
Nenue@40
|
22 db.ClassPlanTypes.shipmentsReady = {
|
Nenue@40
|
23 backgroundColor = {1, 1, 0, 0.25 },
|
Nenue@40
|
24 textColor = {1, 1, 0}
|
Nenue@40
|
25 }
|
Nenue@40
|
26 db.ClassPlanTypes.complete = {
|
Nenue@40
|
27 backgroundColor = {0, 1, 0, 0.25 },
|
Nenue@40
|
28 textColor = {0, 1, 0}
|
Nenue@2
|
29 }
|
Nenue@2
|
30
|
Nenue@4
|
31 local GetTimeLeftString = function(timeLeft)
|
Nenue@4
|
32 local days = floor(timeLeft/(24*3600))
|
Nenue@4
|
33 local hours = floor(mod(timeLeft, (24*3600)) / 3600)
|
Nenue@4
|
34 local minutes = floor(mod(timeLeft, 3600) / 60)
|
Nenue@4
|
35 local seconds = mod(timeLeft, 60)
|
Nenue@4
|
36 if days >= 1 then
|
Nenue@6
|
37 return (days .. 'd' .. ' ') .. ((hours > 0) and (hours .. 'h') or '')
|
Nenue@95
|
38 elseif timeLeft < 60 then
|
Nenue@95
|
39 return (seconds .. ' sec')
|
Nenue@4
|
40 else
|
Nenue@6
|
41 return ((hours > 0) and (hours .. 'h') or '') .. ((minutes > 0) and (' ' ..minutes .. ' min') or '')
|
Nenue@4
|
42 end
|
Nenue@4
|
43 end
|
Nenue@3
|
44
|
Nenue@32
|
45 ClassOrderPlanCore = {
|
Nenue@32
|
46 events = {},
|
Nenue@32
|
47 freeBlocks = {},
|
Nenue@35
|
48 characterButtons = {},
|
Nenue@32
|
49 blocks = {},
|
Nenue@32
|
50 sortedItems = {},
|
Nenue@32
|
51 timers = {},
|
Nenue@32
|
52 shipments = {},
|
Nenue@32
|
53 playerFirst = false,
|
Nenue@32
|
54 prototypes = {},
|
Nenue@40
|
55 Queued = {},
|
Nenue@40
|
56 Timers = {},
|
Nenue@40
|
57 ReportChunks = {},
|
Nenue@32
|
58 }
|
Nenue@40
|
59 ClassPlanHandlerBase = {
|
Nenue@32
|
60 numBlocks = 0,
|
Nenue@32
|
61 isStale = true,
|
Nenue@35
|
62 maxItems = 10
|
Nenue@32
|
63 }
|
Nenue@40
|
64 ClassPlanEntryBase = {}
|
Nenue@1
|
65
|
Nenue@32
|
66 local ClassPlan = ClassOrderPlanCore
|
Nenue@40
|
67 local Embed = function(object, ...)
|
Nenue@40
|
68 for i = 1, select('#', ...) do
|
Nenue@40
|
69 local src = select(i, ...)
|
Nenue@40
|
70 for k,v in pairs(src) do
|
Nenue@40
|
71 if not object[k] then
|
Nenue@40
|
72 object[k] = v
|
Nenue@40
|
73 end
|
Nenue@40
|
74 end
|
Nenue@40
|
75 end
|
Nenue@40
|
76 return object
|
Nenue@40
|
77 end
|
Nenue@5
|
78
|
Nenue@32
|
79 function ClassPlan:OnLoad ()
|
Nenue@3
|
80 self:RegisterEvent('PLAYER_LOGIN')
|
Nenue@3
|
81 self:RegisterEvent('ADDON_LOADED')
|
Nenue@3
|
82 self:RegisterEvent('PLAYER_REGEN_ENABLED')
|
Nenue@5
|
83 self:RegisterEvent('PLAYER_REGEN_DISABLED')
|
Nenue@40
|
84 self:RegisterEvent('GARRISON_SHOW_LANDING_PAGE')
|
Nenue@32
|
85 self:RegisterForDrag('LeftButton')
|
Nenue@95
|
86 self:EnableMouse(true)
|
Nenue@32
|
87 self:SetMovable(true)
|
Nenue@32
|
88 self:SetToplevel(true)
|
Nenue@32
|
89
|
Nenue@32
|
90 SLASH_CLASSPLAN1 = "/classplan"
|
Nenue@32
|
91 SLASH_CLASSPLAN2 = "/cp"
|
Nenue@32
|
92 SlashCmdList.CLASSPLAN = function(args)
|
Nenue@32
|
93 self:Toggle()
|
Nenue@32
|
94 end
|
Nenue@32
|
95
|
Nenue@40
|
96 local originalScript = GarrisonLandingPageMinimapButton:GetScript('OnClick')
|
Nenue@40
|
97 GarrisonLandingPageMinimapButton:SetScript("OnClick", function(minimap, button)
|
Nenue@40
|
98 if button == 'LeftButton' and (not IsShiftKeyDown()) then
|
Nenue@40
|
99 self:Toggle()
|
Nenue@40
|
100 else
|
Nenue@40
|
101 originalScript(minimap, button)
|
Nenue@40
|
102 end
|
Nenue@40
|
103 end)
|
Nenue@102
|
104 local OnStopped = function()
|
Nenue@102
|
105 print('Fade.OnStop()')
|
Nenue@102
|
106 self.isAnimating = nil
|
Nenue@102
|
107 self:SetShown(self.data.IsShown)
|
Nenue@102
|
108 end
|
Nenue@102
|
109
|
Nenue@102
|
110 self.FadeOut:SetScript('OnStop', OnStopped)
|
Nenue@40
|
111 self.FadeOut:SetScript('OnFinished', function()
|
Nenue@102
|
112 print('FadeOut.OnFinished()')
|
Nenue@40
|
113 self.isAnimating = nil
|
Nenue@102
|
114 self:SetShown(false)
|
Nenue@40
|
115 end)
|
Nenue@40
|
116 self.FadeIn:SetScript('OnPlay', function()
|
Nenue@102
|
117 print('FadeIn.OnPlay()')
|
Nenue@40
|
118 self.isAnimating = true
|
Nenue@102
|
119 self.data.IsShown = true
|
Nenue@40
|
120 end)
|
Nenue@102
|
121 self.FadeIn:SetScript('OnStop', OnStopped)
|
Nenue@40
|
122
|
Nenue@40
|
123 --hooksecurefunc(C_Garrison, 'RequestLandingPageShipmentInfo', function()
|
Nenue@40
|
124 -- WorldPlan:print("Requesting shipments data.")
|
Nenue@40
|
125 --end)
|
Nenue@40
|
126 C_Garrison.RequestLandingPageShipmentInfo();
|
Nenue@40
|
127 self.isStale = true
|
Nenue@95
|
128 UIPanelWindows[self:GetName()] = { area = "right", pushable = 3, whileDead = 1 };
|
Nenue@95
|
129 tinsert(UISpecialFrames, self:GetName())
|
Nenue@4
|
130 end
|
Nenue@19
|
131
|
Nenue@40
|
132
|
Nenue@32
|
133 function ClassPlan:GetCurrentProfile()
|
Nenue@32
|
134 WorldPlanData.OrderHall = WorldPlanData.OrderHall or {}
|
Nenue@32
|
135 local db = WorldPlanData.OrderHall
|
Nenue@32
|
136 self.data = db
|
Nenue@4
|
137
|
Nenue@32
|
138 local characters = db.characters or {}
|
Nenue@32
|
139 db.characters = characters
|
Nenue@4
|
140
|
Nenue@32
|
141 local name, realm = UnitName('player')
|
Nenue@32
|
142 realm = realm or GetRealmName()
|
Nenue@40
|
143
|
Nenue@32
|
144 local profileName = name .. '-' .. realm
|
Nenue@40
|
145 self.profile = characters[profileName] or {
|
Nenue@40
|
146 showItems = true
|
Nenue@40
|
147 }
|
Nenue@117
|
148 self.profileName = profileName
|
Nenue@32
|
149 self.characters = characters
|
Nenue@32
|
150 characters[profileName] = self.profile
|
Nenue@32
|
151
|
Nenue@32
|
152 local classColor = RAID_CLASS_COLORS[select(2, UnitClass('player'))]
|
Nenue@32
|
153 local className = UnitClass('player')
|
Nenue@32
|
154 print('|cFFFFFF00Loaded:|r', classColor.hex, className, profileName)
|
Nenue@32
|
155 self.profile.classColor = classColor
|
Nenue@32
|
156 self.profile.className = className
|
Nenue@35
|
157 self.profile.characterName = name
|
Nenue@35
|
158 self.profile.characterRealm = realm
|
Nenue@40
|
159 -- flip it on
|
Nenue@40
|
160 self.profile.showItems = true
|
Nenue@40
|
161
|
Nenue@40
|
162 self.HeaderInset:SetHeight(CP_HEADER_SIZE)
|
Nenue@40
|
163 self.ClassStripe:SetColorTexture(classColor.r, classColor.g, classColor.b, 1)
|
Nenue@40
|
164 self.ClassStripe:SetPoint('TOPLEFT', self.HeaderInset, 'BOTTOMLEFT')
|
Nenue@40
|
165
|
Nenue@95
|
166 self.maxItems = db.maxItems or self.maxItems
|
Nenue@95
|
167
|
Nenue@32
|
168 return self.profile
|
Nenue@3
|
169 end
|
Nenue@3
|
170
|
Nenue@40
|
171 function ClassPlan:AddHandler(frame)
|
Nenue@40
|
172 print('|cFF00FF00'..frame:GetName()..' loaded')
|
Nenue@40
|
173 for i, event in ipairs(frame.events) do
|
Nenue@32
|
174 print('|cFF00FF00 event', event)
|
Nenue@40
|
175 frame:RegisterEvent(event)
|
Nenue@1
|
176 end
|
Nenue@40
|
177 frame.sortedItems = {}
|
Nenue@40
|
178 for index, listKey in ipairs(frame.listKey) do
|
Nenue@117
|
179 self.profile[listKey] = self.profile[listKey] or {}
|
Nenue@40
|
180 frame.profile = self.profile
|
Nenue@40
|
181 frame.data = self.data
|
Nenue@40
|
182 local listTitle = frame.listTitle[index]
|
Nenue@40
|
183 setmetatable(self.profile[listKey], { __tostring = function() return listTitle end })
|
Nenue@40
|
184 frame.sortedItems[listKey] = {}
|
Nenue@95
|
185 frame.maxItems = self.maxItems
|
Nenue@32
|
186 end
|
Nenue@40
|
187 frame.owningFrame = self
|
Nenue@40
|
188 frame:SetList(1)
|
Nenue@3
|
189 end
|
Nenue@1
|
190
|
Nenue@32
|
191 function ClassPlan:OnEvent (event, arg)
|
Nenue@32
|
192 print(event, arg)
|
Nenue@5
|
193 if event == 'PLAYER_REGEN_DISABLED' then
|
Nenue@6
|
194 if self:IsVisible() then
|
Nenue@6
|
195 self.combatHide = true
|
Nenue@6
|
196 self:SetShown(false)
|
Nenue@6
|
197 end
|
Nenue@6
|
198
|
Nenue@5
|
199 elseif event == 'PLAYER_REGEN_ENABLED' then
|
Nenue@6
|
200 if self.combatHide == true then
|
Nenue@6
|
201 self.combatHide = nil
|
Nenue@6
|
202 self:SetShown(true)
|
Nenue@6
|
203 end
|
Nenue@32
|
204 elseif event == 'ADDON_LOADED' then
|
Nenue@32
|
205 if arg == 'Blizzard_GarrisonUI' then
|
Nenue@32
|
206 self:Reanchor()
|
Nenue@32
|
207 end
|
Nenue@3
|
208 elseif event == 'PLAYER_LOGIN' then
|
Nenue@3
|
209 if not self.initialized then
|
Nenue@4
|
210 self:Setup()
|
Nenue@1
|
211 end
|
Nenue@40
|
212 elseif event == 'GARRISON_SHOW_LANDING_PAGE' then
|
Nenue@40
|
213 self:RefreshData()
|
Nenue@2
|
214 end
|
Nenue@2
|
215 end
|
Nenue@2
|
216
|
Nenue@32
|
217 function ClassPlan:Setup()
|
Nenue@32
|
218 if IsLoggedIn() then
|
Nenue@32
|
219 print('|cFFFFFF00'..self:GetName()..':Setup()|r')
|
Nenue@32
|
220
|
Nenue@32
|
221 self:GetCurrentProfile()
|
Nenue@32
|
222 for _, handler in ipairs(self.Handlers) do
|
Nenue@40
|
223 self:AddHandler(handler)
|
Nenue@40
|
224 handler.initialized = true
|
Nenue@32
|
225 end
|
Nenue@32
|
226 self.initialized = true
|
Nenue@32
|
227 self:SetShown(self.data.IsShown)
|
Nenue@40
|
228
|
Nenue@41
|
229 GarrisonMinimap_HidePulse(GarrisonLandingPageMinimapButton, 1) -- buildings
|
Nenue@41
|
230 GarrisonMinimap_HidePulse(GarrisonLandingPageMinimapButton, 5) -- missions
|
Nenue@32
|
231 end
|
Nenue@3
|
232 end
|
Nenue@3
|
233
|
Nenue@4
|
234
|
Nenue@32
|
235 --- Update space
|
Nenue@4
|
236
|
Nenue@40
|
237 local max = math.max
|
Nenue@40
|
238 function ClassPlan:RefreshData()
|
Nenue@40
|
239 for index, handler in pairs(self.Handlers) do
|
Nenue@40
|
240 print(' |cFF00FF00'..handler:GetName()..' data update|r')
|
Nenue@40
|
241 handler:RefreshData()
|
Nenue@40
|
242 end
|
Nenue@40
|
243 self.requestingData = nil
|
Nenue@40
|
244 end
|
Nenue@35
|
245
|
Nenue@40
|
246 function ClassPlan:Update()
|
Nenue@40
|
247 print('|cFF00FFFF'..self:GetName()..'Refresh()|r')
|
Nenue@3
|
248
|
Nenue@40
|
249 self.currentHeight = 0
|
Nenue@40
|
250 for index, handler in ipairs(self.Handlers) do
|
Nenue@40
|
251 local itemsHeight = handler:UpdateItems()
|
Nenue@40
|
252 if itemsHeight then
|
Nenue@117
|
253
|
Nenue@40
|
254 self.currentHeight = max(itemsHeight, self.currentHeight)
|
Nenue@117
|
255 print('calc height', handler, self.currentHeight)
|
Nenue@40
|
256 end
|
Nenue@40
|
257 end
|
Nenue@23
|
258
|
Nenue@40
|
259 local index = 1
|
Nenue@40
|
260 for key, info in pairs(self.data.characters) do
|
Nenue@40
|
261 print('cbutton', key)
|
Nenue@40
|
262 if self.data[key] then
|
Nenue@40
|
263 print('|cFFFF4400remove legacy value', key)
|
Nenue@40
|
264 self.data[key] = nil
|
Nenue@23
|
265 end
|
Nenue@23
|
266
|
Nenue@35
|
267
|
Nenue@40
|
268 local button = self.characterButtons[index]
|
Nenue@40
|
269 if not button then
|
Nenue@40
|
270 button = CreateFrame('Button', nil, self, 'ClassOrderPlanCharacterButton')
|
Nenue@40
|
271 button:SetID(index)
|
Nenue@40
|
272 self.characterButtons[index] = button
|
Nenue@40
|
273
|
Nenue@40
|
274 if not self.lastButton then
|
Nenue@40
|
275 button:SetPoint('TOPLEFT', self.HeaderInset, 'TOPLEFT', 0, 0)
|
Nenue@40
|
276 else
|
Nenue@40
|
277 button:SetPoint('TOPLEFT', self.lastButton, 'TOPRIGHT', 2, 0)
|
Nenue@35
|
278 end
|
Nenue@40
|
279 self.lastButton = button
|
Nenue@40
|
280 end
|
Nenue@40
|
281 if not info.characterName then
|
Nenue@40
|
282 info.characterName, info.characterRealm = key:match("%(.+)%-(.+)^")
|
Nenue@35
|
283 end
|
Nenue@35
|
284
|
Nenue@40
|
285 print(info.characterName)
|
Nenue@35
|
286
|
Nenue@40
|
287 button:SetSize(CP_HEADER_SIZE, CP_HEADER_SIZE)
|
Nenue@40
|
288 button.profileKey = key
|
Nenue@40
|
289 button.className = info.className
|
Nenue@40
|
290 button.classColor = info.classColor
|
Nenue@40
|
291 button.characterName = info.characterName
|
Nenue@40
|
292 button.characterRealm = info.characterRealm
|
Nenue@40
|
293 button.showItems = info.showItems
|
Nenue@40
|
294 button.isMine = (info == self.profile)
|
Nenue@40
|
295 button:Update()
|
Nenue@40
|
296 button:Show()
|
Nenue@40
|
297 index = index + 1
|
Nenue@3
|
298 end
|
Nenue@3
|
299
|
Nenue@117
|
300 for i = index, #self.characterButtons do
|
Nenue@117
|
301 self.characterButtons[i]:Hide()
|
Nenue@117
|
302 end
|
Nenue@117
|
303
|
Nenue@117
|
304
|
Nenue@40
|
305 self.HeaderInset:SetHeight(CP_HEADER_SIZE)
|
Nenue@40
|
306 self.HeaderInset:ClearAllPoints()
|
Nenue@40
|
307 self.HeaderInset:SetPoint('TOPLEFT' ,self, 'TOPLEFT')
|
Nenue@40
|
308 self.HeaderInset:SetPoint('RIGHT' ,self, 'RIGHT')
|
Nenue@40
|
309 self.ClassStripe:ClearAllPoints()
|
Nenue@40
|
310 self.ClassStripe:SetPoint('TOPLEFT', self.HeaderInset, 'BOTTOMLEFT', 0, 0)
|
Nenue@40
|
311 self.ClassStripe:SetPoint('RIGHT')
|
Nenue@40
|
312 self:Reanchor()
|
Nenue@40
|
313 self.isStale = nil
|
Nenue@40
|
314 end
|
Nenue@40
|
315
|
Nenue@3
|
316
|
Nenue@32
|
317 function ClassPlan:Toggle()
|
Nenue@102
|
318 print('Toggle()', self:IsVisible(), self:IsShown())
|
Nenue@102
|
319 if self:IsVisible() then
|
Nenue@102
|
320 print('fade out')
|
Nenue@102
|
321 self.data.IsShown = false
|
Nenue@40
|
322 self.FadeOut:Play()
|
Nenue@3
|
323 else
|
Nenue@102
|
324 print('fade in')
|
Nenue@40
|
325 self.data.IsShown = true
|
Nenue@107
|
326 self:SetShown(true)
|
Nenue@40
|
327 self.FadeIn:Play()
|
Nenue@3
|
328 end
|
Nenue@3
|
329 end
|
Nenue@3
|
330
|
Nenue@40
|
331
|
Nenue@95
|
332 function ClassPlan:OnMouseDown(button)
|
Nenue@95
|
333 print(button)
|
Nenue@95
|
334 if button == 'RightButton' then
|
Nenue@95
|
335 self:Toggle()
|
Nenue@95
|
336 end
|
Nenue@95
|
337
|
Nenue@95
|
338 end
|
Nenue@95
|
339
|
Nenue@32
|
340 function ClassPlan:OnUpdate()
|
Nenue@40
|
341 if self.requestingData then
|
Nenue@40
|
342 self:RefreshData()
|
Nenue@40
|
343 elseif self.isStale then
|
Nenue@40
|
344 -- shouldn't happen, usually
|
Nenue@32
|
345 self:Update()
|
Nenue@18
|
346 end
|
Nenue@40
|
347 if #self.ReportChunks >= 1 then
|
Nenue@40
|
348 db.print(table.concat(self.ReportChunks, ', '))
|
Nenue@40
|
349 wipe(self.ReportChunks)
|
Nenue@40
|
350 end
|
Nenue@40
|
351
|
Nenue@3
|
352 end
|
Nenue@3
|
353
|
Nenue@32
|
354 function ClassPlan:OnShow()
|
Nenue@23
|
355 print('|cFF00FFFFShow()')
|
Nenue@40
|
356 self.isStale = true
|
Nenue@32
|
357 self:Reanchor()
|
Nenue@3
|
358 end
|
Nenue@3
|
359
|
Nenue@32
|
360 function ClassPlan:OnHide()
|
Nenue@32
|
361 print('|cFF00FFFFHide()')
|
Nenue@102
|
362 self.isAnimating = nil
|
Nenue@3
|
363 end
|
Nenue@3
|
364
|
Nenue@32
|
365 function ClassPlan:Reanchor()
|
Nenue@40
|
366 if not (self.data.positionX and self.data.positionY) then
|
Nenue@40
|
367 self.data.positionX = 0
|
Nenue@40
|
368 self.data.positionY = -148
|
Nenue@40
|
369 end
|
Nenue@32
|
370 self:ClearAllPoints()
|
Nenue@40
|
371 self:SetPoint('TOP', self.data.positionX, self.data.positionY)
|
Nenue@40
|
372 self.currentHeight = 0
|
Nenue@32
|
373 for index, frame in ipairs(self.Handlers) do
|
Nenue@32
|
374 frame:Reanchor()
|
Nenue@35
|
375 local ListTab = frame.ListTab
|
Nenue@35
|
376 if ListTab then
|
Nenue@35
|
377 ListTab:ClearAllPoints()
|
Nenue@40
|
378 ListTab:SetPoint('TOPLEFT', frame, 'TOPLEFT', 0, 0)
|
Nenue@40
|
379 ListTab:SetPoint('BOTTOMRIGHT', frame, 'TOPRIGHT', 0, -CP_HEADER_SIZE)
|
Nenue@35
|
380 ListTab.Label:SetText(frame.listTitle[frame.currentListIndex])
|
Nenue@35
|
381 ListTab:Show()
|
Nenue@117
|
382 print(ListTab:GetName(), ListTab:GetSize())
|
Nenue@35
|
383 end
|
Nenue@40
|
384 self.currentHeight = max(self.currentHeight, frame.currentHeight or 0)
|
Nenue@40
|
385 end
|
Nenue@40
|
386 self:SetHeight(self.currentHeight + self.HeaderInset:GetHeight() + self.ClassStripe:GetHeight())
|
Nenue@35
|
387
|
Nenue@2
|
388 end
|
Nenue@2
|
389
|
Nenue@32
|
390 function ClassPlan:OnDragStart()
|
Nenue@32
|
391 self:StartMoving()
|
Nenue@32
|
392 end
|
Nenue@32
|
393 function ClassPlan:OnDragStop()
|
Nenue@32
|
394 self:StopMovingOrSizing()
|
Nenue@32
|
395 local x,y = self:GetCenter()
|
Nenue@32
|
396 if x and y then
|
Nenue@32
|
397 x = (x - GetScreenWidth()/2)
|
Nenue@32
|
398 y = (y - GetScreenHeight()/2) * -1
|
Nenue@32
|
399 self.data.positionX, self.data.positionY = x,y
|
Nenue@32
|
400 print('saving positions:', x, y)
|
Nenue@32
|
401 end
|
Nenue@32
|
402 end
|
Nenue@32
|
403
|
Nenue@40
|
404 function ClassPlanHandlerBase:ScheduleUpdate(expires)
|
Nenue@40
|
405 -- value will occasionally lag so check here
|
Nenue@40
|
406 local duration = expires - time()
|
Nenue@40
|
407 self.Timers = self.Timers or {}
|
Nenue@40
|
408 if (duration > 0) and (not self.Timers[expires]) then
|
Nenue@40
|
409 print(' adding timer at', expires, 'c', duration)
|
Nenue@40
|
410 self.Timers[expires] = true
|
Nenue@40
|
411 C_Timer.After(duration, function()
|
Nenue@40
|
412 self.isStale = true
|
Nenue@40
|
413 self:UpdateItems()
|
Nenue@40
|
414 self.Timers[expires] = nil
|
Nenue@40
|
415 end)
|
Nenue@40
|
416 end
|
Nenue@40
|
417 end
|
Nenue@40
|
418
|
Nenue@40
|
419 function ClassPlanHandlerBase:SetList(index)
|
Nenue@40
|
420 local prevIndex = self.currentListIndex
|
Nenue@32
|
421 if not index then
|
Nenue@32
|
422 if self.currentListIndex == #self.listKey then
|
Nenue@32
|
423 index = 1
|
Nenue@32
|
424 else
|
Nenue@32
|
425 index = self.currentListIndex + 1
|
Nenue@32
|
426 end
|
Nenue@32
|
427 end
|
Nenue@32
|
428
|
Nenue@40
|
429 print('|cFF0088FF'..self:GetName()..'|r:SetList()', index, self.listKey[index])
|
Nenue@32
|
430 self.currentListIndex = index
|
Nenue@32
|
431 self.activeKey = self.listKey[index]
|
Nenue@32
|
432 self.activeTitle = self.listTitle[index]
|
Nenue@32
|
433
|
Nenue@40
|
434 self.ListTab.Label:SetText(self.listTitle[index])
|
Nenue@32
|
435 self.isStale = true
|
Nenue@40
|
436
|
Nenue@40
|
437 if self.OnSetList then
|
Nenue@40
|
438 self:OnSetList(self.currentListIndex, prevIndex)
|
Nenue@40
|
439 end
|
Nenue@32
|
440 end
|
Nenue@32
|
441
|
Nenue@95
|
442 function ClassPlanHandlerBase:OnLoad(...)
|
Nenue@95
|
443 print(self:GetName()..':OnLoad()', ...)
|
Nenue@95
|
444 self:EnableMouse(true)
|
Nenue@95
|
445 end
|
Nenue@95
|
446
|
Nenue@95
|
447 function ClassPlanHandlerBase:OnMouseDown(button, down)
|
Nenue@95
|
448 print(self:GetName().. ':OnMouseDown()', button)
|
Nenue@95
|
449 ClassOrderPlan:OnMouseDown(button)
|
Nenue@95
|
450 end
|
Nenue@95
|
451
|
Nenue@40
|
452 function ClassPlanHandlerBase:OnMouseWheel(delta)
|
Nenue@95
|
453 if IsControlKeyDown() then
|
Nenue@95
|
454 if delta > 0 then
|
Nenue@95
|
455 if self.maxItems < 30 then
|
Nenue@95
|
456 self.maxItems = self.maxItems + 1
|
Nenue@95
|
457 end
|
Nenue@95
|
458
|
Nenue@95
|
459 else
|
Nenue@95
|
460 if self.maxItems >= 2 then
|
Nenue@95
|
461 self.maxItems = self.maxItems - 1
|
Nenue@95
|
462 end
|
Nenue@95
|
463 end
|
Nenue@95
|
464 if WorldPlanData.OrderHall then
|
Nenue@95
|
465 WorldPlanData.OrderHall.maxItems = self.maxItems
|
Nenue@95
|
466 end
|
Nenue@95
|
467 else
|
Nenue@95
|
468 self.scrollOffset = (self.scrollOffset or 0) - ((delta > 0) and 1 or -1)
|
Nenue@95
|
469 end
|
Nenue@35
|
470 self:UpdateItems()
|
Nenue@35
|
471 end
|
Nenue@35
|
472
|
Nenue@40
|
473 function ClassPlanHandlerBase:RefreshData()
|
Nenue@40
|
474 print('|cFF0088FF'..self:GetName()..':RefreshData()')
|
Nenue@40
|
475 local activeKey = self.activeKey
|
Nenue@40
|
476 self.truncatedItems = 0
|
Nenue@40
|
477 self.currentTime = time()
|
Nenue@40
|
478 if self:GetParent().profile then
|
Nenue@40
|
479 self:GetPlayerData()
|
Nenue@40
|
480 end
|
Nenue@40
|
481 for _, listKey in ipairs(self.listKey) do
|
Nenue@40
|
482 local sortedItems = self.sortedItems[listKey]
|
Nenue@40
|
483 wipe(sortedItems)
|
Nenue@40
|
484 for key, profile in pairs(self.data.characters) do
|
Nenue@40
|
485 local isMine = (profile == self.profile)
|
Nenue@40
|
486 print(key, listKey, isMine, profile.showItems)
|
Nenue@40
|
487 local profileList = profile[listKey]
|
Nenue@40
|
488 if profileList and #profileList >= 1 then
|
Nenue@40
|
489 local classColor = profile.classColor or RAID_CLASS_COLORS['HUNTER']
|
Nenue@40
|
490 if profile.showItems then
|
Nenue@40
|
491 for index, data in ipairs(profileList) do
|
Nenue@40
|
492 data.classColor = classColor
|
Nenue@40
|
493 data.profileKey = key
|
Nenue@40
|
494 data.isMine = isMine
|
Nenue@40
|
495 if self.OnGetItem then
|
Nenue@40
|
496 self:OnGetItem(data)
|
Nenue@40
|
497 end
|
Nenue@40
|
498 tinsert(sortedItems, data)
|
Nenue@40
|
499 end
|
Nenue@40
|
500 else
|
Nenue@40
|
501 self.truncatedItems = self.truncatedItems + 1
|
Nenue@40
|
502 end
|
Nenue@40
|
503 end
|
Nenue@40
|
504 end
|
Nenue@40
|
505
|
Nenue@40
|
506 if self.SortHandler then
|
Nenue@40
|
507 sort(sortedItems, self.SortHandler)
|
Nenue@40
|
508 end
|
Nenue@40
|
509 end
|
Nenue@40
|
510
|
Nenue@40
|
511 for k,v in pairs(self.sortedItems) do
|
Nenue@40
|
512 print(' ', k)
|
Nenue@40
|
513 end
|
Nenue@40
|
514
|
Nenue@32
|
515 self.isStale = true
|
Nenue@32
|
516 end
|
Nenue@32
|
517
|
Nenue@40
|
518 function ClassPlanHandlerBase:OnEvent(event, id)
|
Nenue@40
|
519 if (event == 'GARRISON_MISSION_LIST_UPDATE') then
|
Nenue@40
|
520 if (id == LE_FOLLOWER_TYPE_GARRISON_7_0) then
|
Nenue@40
|
521 print('|cFF00FF88'..self:GetName()..':OnEvent()|r', event, id)
|
Nenue@40
|
522 self:RefreshData()
|
Nenue@40
|
523 end
|
Nenue@6
|
524 else
|
Nenue@40
|
525 print('|cFF00FF88'..self:GetName()..':OnEvent()|r', event, id)
|
Nenue@32
|
526 end
|
Nenue@32
|
527 end
|
Nenue@32
|
528
|
Nenue@40
|
529 function ClassPlanHandlerBase:OnUpdate()
|
Nenue@40
|
530 if self.isStale then
|
Nenue@40
|
531 print('|cFF00FF00'..self:GetName()..':OnUpdate()|r')
|
Nenue@40
|
532
|
Nenue@40
|
533 self:UpdateItems()
|
Nenue@40
|
534 end
|
Nenue@40
|
535 end
|
Nenue@32
|
536
|
Nenue@32
|
537 -- Stuff set on every list item
|
Nenue@40
|
538 function ClassPlanHandlerBase:SetOwnerData (self, data)
|
Nenue@32
|
539 local name, realm = string.match(data.profileKey, "(.+)%-(.+)")
|
Nenue@32
|
540 local ownerText = '|c'.. data.classColor.colorStr .. name .. '|r'
|
Nenue@32
|
541 self.Owner:SetText(ownerText)
|
Nenue@32
|
542 self.Name:SetText(self.name)
|
Nenue@32
|
543 self.Name:SetTextColor(data.classColor.r, data.classColor.g, data.classColor.b)
|
Nenue@32
|
544 end
|
Nenue@32
|
545
|
Nenue@117
|
546 function ClassPlanHandlerBase:Reanchor() end
|
Nenue@35
|
547
|
Nenue@40
|
548 function ClassPlanHandlerBase:UpdateItems()
|
Nenue@40
|
549 print('|cFF0088FF '..self:GetName()..':UpdateItems()|r', self.activeKey)
|
Nenue@35
|
550 self.MoreItemsUp:Hide()
|
Nenue@35
|
551 self.MoreItemsDown:Hide()
|
Nenue@40
|
552 local sortedItems = self.sortedItems[self.activeKey]
|
Nenue@35
|
553 local scrollOffset = self.scrollOffset or 0
|
Nenue@35
|
554 local numItems = #sortedItems
|
Nenue@35
|
555 if (not sortedItems[scrollOffset+1]) or (numItems <= self.maxItems) then
|
Nenue@35
|
556 scrollOffset = 0
|
Nenue@35
|
557 elseif (numItems > self.maxItems) and (scrollOffset > (numItems - self.maxItems)) then
|
Nenue@35
|
558 scrollOffset = (numItems - self.maxItems)
|
Nenue@35
|
559 end
|
Nenue@35
|
560
|
Nenue@117
|
561 if self.OnUpdateRequested then
|
Nenue@117
|
562 local overrideHeight = self:OnUpdateRequested()
|
Nenue@117
|
563 if overrideHeight then
|
Nenue@117
|
564 return overrideHeight
|
Nenue@117
|
565 end
|
Nenue@117
|
566
|
Nenue@117
|
567
|
Nenue@117
|
568 end
|
Nenue@117
|
569
|
Nenue@117
|
570
|
Nenue@40
|
571 self.ListTab.Count:SetText(numItems)
|
Nenue@32
|
572 self.blocks = self.blocks or {}
|
Nenue@32
|
573 local blocks = self.blocks
|
Nenue@32
|
574 local lastProfile
|
Nenue@40
|
575 local totalHeight = (self.ListTab:GetHeight() or 0)
|
Nenue@32
|
576 self.lastBlock = nil
|
Nenue@32
|
577 self.numActive = 0
|
Nenue@35
|
578 for i = 1, self.maxItems do
|
Nenue@35
|
579 local index = scrollOffset + i
|
Nenue@35
|
580 local data = sortedItems[index]
|
Nenue@35
|
581 if not data then
|
Nenue@40
|
582 print('|cFFFF4400end of data')
|
Nenue@35
|
583 break
|
Nenue@35
|
584 end
|
Nenue@35
|
585
|
Nenue@32
|
586 local block = blocks[i]
|
Nenue@32
|
587 if not block then
|
Nenue@40
|
588 block = CreateFrame('Button', self:GetName()..'ListItem'..i , self, self.templateName)
|
Nenue@32
|
589 block.listType = self.activeKey
|
Nenue@40
|
590
|
Nenue@40
|
591 block.doAnimation = true
|
Nenue@40
|
592
|
Nenue@32
|
593 block.handler = self
|
Nenue@32
|
594 self.numBlocks = self.numBlocks + 1
|
Nenue@32
|
595 blocks[i] = block
|
Nenue@32
|
596 end
|
Nenue@35
|
597 block:SetID(index)
|
Nenue@32
|
598 self.numActive = self.numActive + 1
|
Nenue@32
|
599
|
Nenue@32
|
600 if self.lastBlock then
|
Nenue@32
|
601 block:SetPoint('TOPLEFT', self.lastBlock, 'BOTTOMLEFT', 0, 0)
|
Nenue@40
|
602 --print('--', index, data.isComplete, data.missionEndTime, data.name)
|
Nenue@32
|
603 else
|
Nenue@40
|
604 block:SetPoint('TOPLEFT', self.ListTab, 'BOTTOMLEFT', 0, 0)
|
Nenue@40
|
605 --print('--top')
|
Nenue@32
|
606 end
|
Nenue@32
|
607 self.lastBlock = block
|
Nenue@32
|
608
|
Nenue@32
|
609 totalHeight = totalHeight + block:GetHeight()
|
Nenue@32
|
610 block.lastProfile = lastProfile
|
Nenue@32
|
611 -- blot out arbitrary flags
|
Nenue@32
|
612 block.offerEndTime = nil
|
Nenue@95
|
613 block.isComplete = data.isComplete
|
Nenue@32
|
614 block.missionEndTime = nil
|
Nenue@32
|
615 block.creationTime = nil
|
Nenue@32
|
616 block.duration = nil
|
Nenue@32
|
617 block.throttle = 5
|
Nenue@32
|
618
|
Nenue@32
|
619 for k,v in pairs(data) do
|
Nenue@32
|
620 if type(block[k]) ~= 'function' then
|
Nenue@32
|
621 block[k] = v
|
Nenue@32
|
622 end
|
Nenue@32
|
623 end
|
Nenue@32
|
624
|
Nenue@32
|
625 block:Update()
|
Nenue@32
|
626 self:SetOwnerData(block, data)
|
Nenue@32
|
627
|
Nenue@32
|
628 block:Show()
|
Nenue@32
|
629 lastProfile = data.profileKey
|
Nenue@6
|
630 end
|
Nenue@6
|
631
|
Nenue@35
|
632 if self.numActive < numItems then
|
Nenue@35
|
633 if scrollOffset < (numItems - self.maxItems) then
|
Nenue@35
|
634 self.MoreItemsDown:Show()
|
Nenue@35
|
635 end
|
Nenue@35
|
636 if scrollOffset > 0 then
|
Nenue@35
|
637 self.MoreItemsUp:Show()
|
Nenue@35
|
638 end
|
Nenue@35
|
639 end
|
Nenue@35
|
640
|
Nenue@35
|
641 for i = self.numActive + 1, self.numBlocks do
|
Nenue@32
|
642 if blocks[i] then
|
Nenue@32
|
643 blocks[i]:Hide()
|
Nenue@32
|
644 end
|
Nenue@32
|
645 end
|
Nenue@32
|
646
|
Nenue@40
|
647 self:Reanchor()
|
Nenue@40
|
648 if totalHeight ~= self.currentHeight then
|
Nenue@40
|
649 self.currentHeight = totalHeight
|
Nenue@40
|
650 self:SetHeight(self.currentHeight)
|
Nenue@40
|
651 self:GetParent():Reanchor()
|
Nenue@40
|
652 end
|
Nenue@40
|
653
|
Nenue@40
|
654
|
Nenue@35
|
655 self.scrollOffset = scrollOffset
|
Nenue@40
|
656 self.isStale = nil
|
Nenue@117
|
657
|
Nenue@117
|
658
|
Nenue@117
|
659 if self.OnItemsUpdated then
|
Nenue@117
|
660 return self:OnItemsUpdated()
|
Nenue@117
|
661 end
|
Nenue@117
|
662
|
Nenue@32
|
663 return totalHeight
|
Nenue@32
|
664 end
|
Nenue@32
|
665
|
Nenue@40
|
666 function ClassPlanEntryBase:OnAnimFinished()
|
Nenue@40
|
667 end
|
Nenue@40
|
668 function ClassPlanEntryBase:OnShow()
|
Nenue@32
|
669
|
Nenue@40
|
670 print('|cFF44FF00'..self:GetName()..':OnShow()')
|
Nenue@40
|
671 if self.doAnimation then
|
Nenue@40
|
672 self.doAnimation = nil
|
Nenue@40
|
673 if not ClassOrderPlan.isAnimating then
|
Nenue@40
|
674 self.NewBlockFade:Play()
|
Nenue@32
|
675 end
|
Nenue@32
|
676 end
|
Nenue@32
|
677 end
|
Nenue@35
|
678
|
Nenue@40
|
679 function ClassPlanEntryBase:SetTimeLeft(expires, duration)
|
Nenue@35
|
680 if not expires then
|
Nenue@35
|
681 return
|
Nenue@32
|
682 end
|
Nenue@32
|
683
|
Nenue@35
|
684 -- calculate here since time isn't available
|
Nenue@40
|
685 local timeLeft = expires - time()
|
Nenue@95
|
686 --print(self:GetName(), timeLeft)
|
Nenue@35
|
687 if timeLeft < 0 then
|
Nenue@35
|
688 -- handle being complete
|
Nenue@40
|
689 if self.shipmentsReady and (self.shipmentsReady < self.shipmentsTotal) then
|
Nenue@40
|
690 self.TimeLeft:SetText('Ready')
|
Nenue@40
|
691 else
|
Nenue@40
|
692 self.TimeLeft:SetText('Complete!')
|
Nenue@40
|
693 end
|
Nenue@35
|
694 else
|
Nenue@35
|
695 self.TimeLeft:SetText(GetTimeLeftString(timeLeft))
|
Nenue@95
|
696 if duration then
|
Nenue@95
|
697 local progress = (duration - timeLeft) / duration
|
Nenue@95
|
698 local r = ((progress >= .5) and (progress/2)) or 1
|
Nenue@95
|
699 local g = ((progress <= .5) and (progress*2)) or 1
|
Nenue@95
|
700 self.ProgressBG:Show()
|
Nenue@95
|
701 self.ProgressBar:Show()
|
Nenue@95
|
702 self.ProgressBG:SetColorTexture(r,g,0,0.25)
|
Nenue@95
|
703 self.ProgressBar:SetColorTexture(r,g,0,0.5)
|
Nenue@95
|
704 self.ProgressBar:SetWidth(self.ProgressBG:GetWidth() * progress)
|
Nenue@95
|
705 else
|
Nenue@32
|
706
|
Nenue@95
|
707 self.ProgressBG:Hide()
|
Nenue@95
|
708 self.ProgressBar:Hide()
|
Nenue@95
|
709 end
|
Nenue@35
|
710 end
|
Nenue@32
|
711 end
|
Nenue@32
|
712
|
Nenue@32
|
713
|
Nenue@40
|
714
|
Nenue@40
|
715 ClassPlanHeaderMixin = {}
|
Nenue@40
|
716 function ClassPlanHeaderMixin:OnLoad()
|
Nenue@40
|
717 self:EnableMouse((#self:GetParent().listKey > 1))
|
Nenue@40
|
718 self:RegisterForClicks('AnyUp')
|
Nenue@32
|
719 end
|
Nenue@40
|
720 function ClassPlanHeaderMixin:OnClick ()
|
Nenue@40
|
721 local frame = self:GetParent()
|
Nenue@40
|
722 frame:SetList()
|
Nenue@40
|
723 if frame.OnHeaderClick then
|
Nenue@117
|
724 frame:OnHeaderClick()
|
Nenue@32
|
725 end
|
Nenue@32
|
726 end
|
Nenue@32
|
727
|
Nenue@40
|
728 ClassPlanCharacterButtonMixin = {
|
Nenue@40
|
729 }
|
Nenue@40
|
730 function ClassPlanCharacterButtonMixin:Update ()
|
Nenue@40
|
731 --print(CLASS_ICON_TCOORDS[self.className:upper()])
|
Nenue@40
|
732 if self.className and CLASS_ICON_TCOORDS[self.className:upper()] then
|
Nenue@40
|
733 self.Icon:SetTexCoord(unpack(CLASS_ICON_TCOORDS[self.className:upper()]))
|
Nenue@32
|
734 end
|
Nenue@40
|
735 self.Icon:SetDesaturated((not self.showItems))
|
Nenue@40
|
736 self.SelectGlow:SetShown(self.isMine)
|
Nenue@32
|
737 end
|
Nenue@32
|
738
|
Nenue@117
|
739 function ClassPlanCharacterButtonMixin:OnLoad()
|
Nenue@117
|
740 self:RegisterForClicks('AnyDown')
|
Nenue@117
|
741 end
|
Nenue@117
|
742
|
Nenue@40
|
743 function ClassPlanCharacterButtonMixin:OnEnter()
|
Nenue@40
|
744 if not self.profileKey then
|
Nenue@18
|
745 return
|
Nenue@18
|
746 end
|
Nenue@2
|
747
|
Nenue@40
|
748 GameTooltip:SetOwner(self, 'ANCHOR_RIGHT')
|
Nenue@40
|
749 local info = ClassOrderPlan.data.characters[self.profileKey]
|
Nenue@117
|
750 GameTooltip:AddLine(self.characterName .. ' - ' .. self.characterRealm, self.classColor.r, self.classColor.g, self.classColor.b)
|
Nenue@40
|
751 local numItems = 0
|
Nenue@40
|
752 if info.missions then
|
Nenue@40
|
753 GameTooltip:AddLine(#info.missions .. ' mission'..((#info.missions == 1) and '' or 's')..' in progress')
|
Nenue@2
|
754 end
|
Nenue@40
|
755 if info.shipments then
|
Nenue@40
|
756 GameTooltip:AddLine(#info.shipments .. ' work order' .. ((#info.shipments == 1) and '' or 's'))
|
Nenue@40
|
757 end
|
Nenue@40
|
758 if info.available then
|
Nenue@40
|
759 GameTooltip:AddLine(#info.available .. ' mission'..((#info.available == 1) and '' or 's')..' available')
|
Nenue@40
|
760 end
|
Nenue@40
|
761 GameTooltip:Show()
|
Nenue@2
|
762 end
|
Nenue@2
|
763
|
Nenue@40
|
764 function ClassPlanCharacterButtonMixin:OnLeave()
|
Nenue@2
|
765 if GameTooltip:IsOwned(self) then
|
Nenue@2
|
766 GameTooltip:Hide()
|
Nenue@2
|
767 end
|
Nenue@2
|
768 end
|
Nenue@2
|
769
|
Nenue@40
|
770 function ClassPlanCharacterButtonMixin:OnClick(button, down)
|
Nenue@40
|
771 local clist = ClassOrderPlan.data.characters
|
Nenue@40
|
772
|
Nenue@3
|
773 if button == 'RightButton' then
|
Nenue@117
|
774
|
Nenue@117
|
775 if IsShiftKeyDown() then
|
Nenue@117
|
776 print('delete profile', self.profileKey)
|
Nenue@117
|
777 clist[self.profileKey] = nil
|
Nenue@117
|
778 else
|
Nenue@117
|
779
|
Nenue@117
|
780 for _, profile in pairs(clist) do
|
Nenue@117
|
781 profile.showItems = true
|
Nenue@117
|
782 end
|
Nenue@40
|
783 end
|
Nenue@117
|
784
|
Nenue@117
|
785
|
Nenue@117
|
786
|
Nenue@40
|
787 else
|
Nenue@40
|
788 if clist[self.profileKey].showItems then
|
Nenue@40
|
789 clist[self.profileKey].showItems = nil
|
Nenue@40
|
790 else
|
Nenue@40
|
791 clist[self.profileKey].showItems = true
|
Nenue@40
|
792 end
|
Nenue@3
|
793 end
|
Nenue@40
|
794 for i, handler in ipairs(ClassOrderPlan.Handlers) do
|
Nenue@40
|
795 handler.isStale = true
|
Nenue@40
|
796 end
|
Nenue@40
|
797
|
Nenue@117
|
798
|
Nenue@117
|
799
|
Nenue@40
|
800 ClassOrderPlan:RefreshData()
|
Nenue@40
|
801 ClassOrderPlan:Update()
|
Nenue@117
|
802 print('OnClick', self.profileKey)
|
Nenue@117
|
803 print( clist[self.profileKey] and clist[self.profileKey].showItems)
|
Nenue@32
|
804 end
|