comparison ClassPlan.lua @ 3:c006ce87a147

prototype structure
author Nenue
date Sat, 15 Oct 2016 09:54:56 -0400
parents b8a19781f79b
children 4c7e9efec4b5
comparison
equal deleted inserted replaced
2:b8a19781f79b 3:c006ce87a147
1 local wipe = table.wipe 1 local wipe = table.wipe
2 local pairs, ipairs = pairs, ipairs 2 local pairs, ipairs = pairs, ipairs
3 local GetTime = GetTime 3 local GetTime = GetTime
4 local GI_currentTime = time()
5
6
4 local blockTemplate = { 7 local blockTemplate = {
5 point = 'TOPLEFT', 8 point = 'TOPLEFT',
6 relativePoint ='TOPLEFT', 9 relativePoint ='TOPLEFT',
7 } 10 }
8 11
9 SLASH_CLASSPLAN1 = "/classplan" 12 SLASH_CLASSPLAN1 = "/classplan"
10 SLASH_CLASSPLAN2 = "/cp" 13 SLASH_CLASSPLAN2 = "/cp"
11 SlashCmdList.CLASSPLAN = function(args) 14 SlashCmdList.CLASSPLAN = function(args)
12 if ClassOrderPlan:IsVisible() then 15 ClassOrderPlan:Toggle()
13 ClassOrderPlan:Hide()
14 else
15 ClassOrderPlan:Show()
16 DEFAULT_CHAT_FRAME:AddMessage('|cFF88FF00WorldPlan|r: Order Hall Panel')
17 end
18 end 16 end
19 17
20 ClassOrderPlanCore = { 18 ClassOrderPlanCore = {
19 events = {},
21 freeBlocks = {}, 20 freeBlocks = {},
22 blocks = {}, 21 blocks = {},
23 shipmentBlocks = {}, 22 sortedItems = {},
24 freeShipmentBlocks = {},
25 sortedShipments = {},
26 sortedMissions = {},
27 timers = {}, 23 timers = {},
28 shipments = {}, 24 shipments = {},
29 playerFirst = false, 25 playerFirst = false,
30 templates = setmetatable({}, { 26 prototypes = {}
31 __newindex = function(t,k ,v)
32 if type(v) == 'table' then
33 setmetatable(v, {__index = blockTemplate})
34 rawset(t,k,v)
35 end
36 end
37 })
38 } 27 }
39 ClassPlanBlockMixin = {} 28 ClassPlanBlockMixin = {
40 ClassPlanShipmentMixin = setmetatable({}, {__index = ClassPlanBlockMixin}) 29 templateName = 'ClassPlanBlock',
41 local core, block, shipment = ClassOrderPlanCore, ClassPlanBlockMixin, ClassPlanShipmentMixin 30 events = {'GARRISON_MISSION_LIST_UPDATE', 'GARRISON_MISSION_FINISHED', 'GARRISON_MISSION_FINISHED'},}
42 local print = DEVIAN_WORKSPACE and function(...) print('ClassPlan', ...) end or nop 31 ClassPlanShipmentMixin = {
43 32 templateName = 'ClassPlanShipment',
44
45
46 function core:OnLoad ()
47 self:RegisterUnitEvent('UNIT_PORTRAIT_UPDATE', 'player')
48 self:RegisterEvent('PLAYER_LOGIN')
49 self:RegisterEvent('PLAYER_ENTERING_WORLD')
50 self:RegisterEvent('PLAYER_REGEN_ENABLED')
51
52 self:RegisterEvent('GARRISON_MISSION_LIST_UPDATE')
53 self:RegisterEvent('GARRISON_MISSION_FINISHED')
54 self:RegisterEvent("GARRISON_LANDINGPAGE_SHIPMENTS");
55 self:RegisterEvent("GARRISON_SHIPMENT_RECEIVED");
56 self:RegisterEvent("GARRISON_TALENT_UPDATE");
57 self:RegisterEvent("GARRISON_TALENT_COMPLETE");
58 end
59
60 core.templates.ClassPlanBlock = {
61 SetItemData = function(block, data)
62 block.isComplete = data.isComplete
63 block.missionEndTime = data.missionEndTime
64 end
65 }
66
67 core.templates.ClassPlanShipment = {
68
69 parent = false, 33 parent = false,
70 point = 'TOPRIGHT', 34 point = 'TOPRIGHT',
71 relativePoint ='TOPRIGHT', 35 relativePoint ='TOPRIGHT',
72 SetItemData = function(block, data) 36 events = {'GARRISON_LANDINGPAGE_SHIPMENTS', 'GARRISON_TALENT_UPDATE', "GARRISON_TALENT_COMPLETE", 'GARRISON_TALENT_COMPLETE', 'GARRISON_SHIPMENT_RECEIVED', "GARRISON_SHIPMENT_RECEIVED"},
73 block.icon = data.icon
74 block.shipmentCapacity = data.shipmentCapacity
75 block.shipmentsReady = data.shipmentsReady
76 block.shipmentsTotal = data.shipmentsTotal
77 block.creationTime = data.creationTime
78 block.duration = data.duration
79 block.itemID = data.itemID
80 block.itemQuality = data.itemQuality
81 --[[
82 icon = texture,
83 shipmentCapacity = shipmentCapacity,
84 shipmentsReady = shipmentsReady,
85 shipmentsTotal = shipmentsTotal,
86 creationTime = creationTime,
87 duration = duration,
88 timeleftString = timeleftString,
89 itemName = itemName,
90 itemIcon = itemIcon,
91 itemQuality = itemQuality,
92 itemID = itemID
93
94 --]]
95 end
96 } 37 }
97 38 setmetatable(ClassPlanShipmentMixin, {__index = ClassPlanBlockMixin})
98 function core:OnEvent (event, ...) 39 local core, MissionsHandler, ShipmentsHandler = ClassOrderPlanCore, ClassPlanBlockMixin, ClassPlanShipmentMixin
99 print(event) 40 local print = DEVIAN_WORKSPACE and function(...) print('ClassPlan', ...) end or nop
100 if event == 'UNIT_PORTRAIT_UPDATE' then 41
101 SetPortraitTexture(self.portrait, 'player') 42
102 elseif event == 'PLAYER_LOGIN' then 43
103 if not self.initialized then 44 MissionsHandler.GetPlayerData = function(self)
104 if IsLoggedIn() then 45 if not self.profile then
105 WorldPlanData.OrderHall = WorldPlanData.OrderHall or {} 46 return
106 self.data = WorldPlanData.OrderHall 47 end
107 48 self.items = C_Garrison.GetLandingPageItems(LE_GARRISON_TYPE_7_0)
108 49
109 local name, realm = UnitName('player') 50 if #self.items >= 1 then
110 realm = realm or GetRealmName() 51 wipe(self.profile.missions)
111 self.profileKey = name .. '-' .. realm 52 for index, data in ipairs(self.items) do
112 if not self.data[self.profileKey] then 53 print(' ',data.name, '|cFF00FF00'.. data.timeLeft .. '|r', date("%A %I:%m %p", data.missionEndTime))
113 self.data[self.profileKey] = {} 54 tinsert(self.profile.missions, data)
114 end 55 end
115 self.profile = self.data[self.profileKey] 56 print('items update pending')
116 57 self.isStale = true
117 self.profile.shipments = self.profile.shipments or {} 58 end
118 self.profile.missions = self.profile.missions or {} 59
119 self.profile.classColor = RAID_CLASS_COLORS[select(2, UnitClass('player'))] 60 if self:IsVisible() then
120 61 self:Refresh()
121 C_Garrison.RequestLandingPageShipmentInfo(); 62 end
122 self.initialized = true 63 end
64
65 MissionsHandler.SortHandler = function (a,b)
66 local result = false
67 if not a or not b then
68 result = true
69 else
70 if (a.isMine ~= b.isMine) then
71 result = a.isMine
72 else
73 if (not b.missionEndTime) or (not a.missionEndTime) then
74 print('missing article', b.missionEndTime, a.missionEndTime)
123 end 75 end
124 end 76 result = ( b.missionEndTime > a.missionEndTime)
125 elseif event == 'GARRISON_LANDINGPAGE_SHIPMENTS' or event == 'GARRISON_TALENT_UPDATE' then 77 end
126 self:UpdateShipments() 78 end
127 elseif event == 'PLAYER_REGEN_ENABLED' or event == 'GARRISON_MISSION_FINISHED' or event == 'GARRISON_TALENT_COMPLETE' or event == 'GARRISON_SHIPMENT_RECEIVED' then 79 return result
128 self:UpdateNotifications() 80 end
129 else 81
130 self:UpdateItems () 82
131 end 83 ShipmentsHandler.OnGetItem = function(data)
132 end 84 if data.shipmentsTotal then
133 85 local timeLeft = data.creationTime + data.duration - GI_currentTime
134 function core:UpdateNotifications() 86 if (timeLeft <= 0) and (data.shipmentsReady < data.shipmentsTotal) then
135 end 87 local numOrders = -1*floor(timeLeft/data.duration)
136 88
137 function core:RefreshItems(sortedItems, templateName) 89 data.originalCreationTime = data.creationTime
138 self.blocks[templateName] = self.blocks[templateName] or {} 90 data.originalShipmentsReady = data.shipmentsReady
139 local blocks = self.blocks[templateName] 91
140 local template = self.templates[templateName] or { 92 data.creationTime = data.creationTime + numOrders*data.duration
141 parent = self.portrait, 93 data.shipmentsReady = data.shipmentsReady + numOrders
142 point = 'TOPLEFT', 94 print(data.profileKey, 'shipment "'.. data.name..'" reconciling', numOrders, 'lapsed orders. -->', data.creationTime, data.shipmentsReady)
143 relativePoint ='TOPRIGHT', 95 end
144 } 96 end
145 97 end
146 local lastProfile 98
147 local numItems = #sortedItems 99 ShipmentsHandler.SortHandler = function(a, b)
148 for i, data in ipairs(sortedItems) do 100 if b.isComplete ~= a.isComplete then
149 local block = blocks[i] 101 return a.isComplete and true or false
150 102 end
151 if not block then 103 return (a.creationTime) < (b.creationTime)
152 block = CreateFrame('Frame', nil, self, templateName) 104 end
153 block:SetID(i) 105
154 template.numBlocks = (template.numBlocks or 0) + 1 106 ShipmentsHandler.GetPlayerData = function (self)
155
156 if template.lastBlock then
157 block:SetPoint('TOPLEFT', template.lastBlock, 'BOTTOMLEFT', 0, 0)
158 else
159 block:SetPoint(template.point, self[template.parent] or self, template.relativePoint, 0, 0)
160 end
161 template.lastBlock = block
162 blocks[i] = block
163 end
164
165 if template.SetItemData then
166 template.SetItemData(block, data)
167 end
168
169
170 block.lastProfile = lastProfile
171 block:Refresh(data)
172 block:Show()
173 lastProfile = data.profileKey
174 end
175
176 for i = numItems + 1, template.numBlocks do
177 if blocks[i] then
178 blocks[i]:Hide()
179 end
180 end
181 end
182
183 function core:Refresh()
184 if self.isStale then
185 self:SortLists()
186 end
187 self.isStale = nil
188
189 self:RefreshItems(self.sortedMissions, 'ClassPlanBlock')
190 self:RefreshItems(self.sortedShipments, 'ClassPlanShipment')
191
192
193 local posX = self.data.posX or 0
194 local posY = self.data.posY or -24
195 local point = self.point or 'TOP'
196 local relativePoint = self.point or 'TOP'
197 self:SetPoint(point, UIParent, relativePoint, posX, posY)
198
199
200 end
201
202 function core:OnUpdate()
203 if self.fadeTimer and self.fadeTimer < GetTime() then
204 self:Hide()
205 end
206 end
207
208 function core:OnShow()
209 if self.isStale then
210 print('updating items on show')
211 self:Refresh()
212 end
213
214 end
215
216 function core:SortLists()
217
218 wipe(self.sortedShipments)
219 wipe(self.sortedMissions)
220 for name, profile in pairs(self.data) do
221 local isMine = (profile == self.profile)
222 for index, data in pairs(profile.missions) do
223
224 data.classColor = profile.classColor or {r = 0.7, g = 0.7, b =0.7}
225 data.profileKey = name
226 data.isMine = (profile == self.profile)
227 tinsert(self.sortedMissions, data)
228 end
229
230 if not profile.shipments then
231 profile.shipments = {}
232 profile.shipment = nil
233 end
234
235 for index, data in pairs(profile.shipments) do
236 data.classColor = profile.classColor or {r = 0.7, g = 0.7, b =0.7}
237 data.profileKey = name
238 data.isMine = (profile == self.profile)
239 tinsert(self.sortedShipments, data)
240 end
241 end
242
243 table.sort(self.sortedMissions, function (a,b)
244 local result = false
245 if not a or not b then
246 result = true
247 else
248 if (a.isMine ~= b.isMine) and self.playerFirst then
249 result = a.isMine
250 else
251 if (not b.missionEndTime) or (not a.missionEndTime) then
252 print('missing article', b.missionEndTime, a.missionEndTime)
253 end
254 result = ( b.missionEndTime > a.missionEndTime)
255 end
256 end
257
258 --print('cmp', (b and (b.missionEndTime .. ' ' .. tostring(b.isMine)) or '-'), '>', (a and (a.missionEndTime .. ' ' .. tostring(a.isMine)) or '-'), result, n)
259 return result
260 end)
261
262 end
263
264 function core:UpdateShipments()
265 print('|cFF0088FFShipments|r:', self.profileKey)
266 if not self.profile then 107 if not self.profile then
267 return 108 return
268 end 109 end
269 wipe(self.shipments) 110 wipe(self.shipments)
270 111
271 112
272 local garrisonType = LE_GARRISON_TYPE_7_0 113 local garrisonType = LE_GARRISON_TYPE_7_0
273 local buildings = C_Garrison.GetBuildings(garrisonType); 114 local buildings = C_Garrison.GetBuildings(garrisonType);
274 local shipmentIndex = 0 115 local shipmentIndex = 0
275 print('Buildings:') 116 --print('Buildings:')
276 for i = 1, #buildings do 117 for i = 1, #buildings do
277 local name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, itemName, itemIcon, itemQuality, itemID = C_Garrison.GetLandingPageShipmentInfo(buildingID); 118 local name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, itemName, itemIcon, itemQuality, itemID = C_Garrison.GetLandingPageShipmentInfo(buildingID);
278 print(buildings[i], name, creationTime, duration)
279 tinsert(self.shipments, 119 tinsert(self.shipments,
280 { 120 {
281 shipmentType = 'Work Order', 121 shipmentType = 'Work Order',
282 name = name, 122 name = name,
283 icon = texture, 123 icon = texture,
292 itemQuality = itemQuality, 132 itemQuality = itemQuality,
293 itemID = itemID 133 itemID = itemID
294 }) 134 })
295 end 135 end
296 136
297 print('Follower:') 137 --print('Follower:')
298 local followerShipments = C_Garrison.GetFollowerShipments(garrisonType); 138 local followerShipments = C_Garrison.GetFollowerShipments(garrisonType);
299 for i = 1, #followerShipments do 139 for i = 1, #followerShipments do
300 local name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, _, _, _, _, followerID = C_Garrison.GetLandingPageShipmentInfoByContainerID(followerShipments[i]); 140 local name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, _, _, _, _, followerID = C_Garrison.GetLandingPageShipmentInfoByContainerID(followerShipments[i]);
301 print(followerShipments[i], name, creationTime, duration)
302 tinsert(self.shipments, 141 tinsert(self.shipments,
303 { 142 {
304 shipmentType = '', 143 shipmentType = '',
305 name = name, 144 name = name,
306 icon = texture, 145 icon = texture,
312 timeleftString = timeleftString, 151 timeleftString = timeleftString,
313 followerID = followerID, 152 followerID = followerID,
314 }) 153 })
315 end 154 end
316 155
317 print('Loose:') 156 --print('Loose:')
318 local looseShipments = C_Garrison.GetLooseShipments(garrisonType) 157 local looseShipments = C_Garrison.GetLooseShipments(garrisonType)
319 for i = 1, #looseShipments do 158 for i = 1, #looseShipments do
320 local name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString = C_Garrison.GetLandingPageShipmentInfoByContainerID(looseShipments[i]); 159 local name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString = C_Garrison.GetLandingPageShipmentInfoByContainerID(looseShipments[i]);
321 print(looseShipments[i], name, creationTime, duration)
322 tinsert(self.shipments, 160 tinsert(self.shipments,
323 { 161 {
324 shipmentType = '', 162 shipmentType = '',
325 name = name, 163 name = name,
326 icon = texture, 164 icon = texture,
334 end 172 end
335 173
336 local talentTrees = C_Garrison.GetTalentTrees(garrisonType, select(3, UnitClass("player"))); 174 local talentTrees = C_Garrison.GetTalentTrees(garrisonType, select(3, UnitClass("player")));
337 -- this is a talent that has completed, but has not been seen in the talent UI yet. 175 -- this is a talent that has completed, but has not been seen in the talent UI yet.
338 local completeTalentID = C_Garrison.GetCompleteTalent(garrisonType); 176 local completeTalentID = C_Garrison.GetCompleteTalent(garrisonType);
339 print('Talents:') 177 --print('Talents:')
340 if (talentTrees) then 178 if (talentTrees) then
341 for treeIndex, tree in ipairs(talentTrees) do 179 for treeIndex, tree in ipairs(talentTrees) do
342 for talentIndex, talent in ipairs(tree) do 180 for talentIndex, talent in ipairs(tree) do
343 local showTalent = false; 181 local showTalent = false;
344 if (talent.isBeingResearched) then 182 if (talent.isBeingResearched) then
359 end 197 end
360 198
361 self.profile.shipments = self.profile.shipments or {} 199 self.profile.shipments = self.profile.shipments or {}
362 if #self.shipments >= 1 then 200 if #self.shipments >= 1 then
363 201
202
364 wipe(self.profile.shipments) 203 wipe(self.profile.shipments)
365 for index, shipment in ipairs(self.shipments) do 204 for index, data in ipairs(self.shipments) do
366 tinsert(self.profile.shipments, shipment) 205 print(' ', data.shipmentType .. data.name, data.creationTime, data.duration)
206 tinsert(self.profile.shipments, data)
367 end 207 end
368 self.isStale = true 208 self.isStale = true
369 end 209 end
370 210
371 if self:IsVisible() then 211 if self:IsVisible() then
372 self:Refresh() 212 self:Refresh()
373 end 213 end
374 end 214 end
375 215
216 function core:OnLoad ()
217 self:RegisterUnitEvent('UNIT_PORTRAIT_UPDATE', 'player')
218 self:RegisterEvent('PLAYER_LOGIN')
219 self:RegisterEvent('PLAYER_ENTERING_WORLD')
220 self:RegisterEvent('ADDON_LOADED')
221 self:RegisterEvent('PLAYER_REGEN_ENABLED')
222
223 self:AddHandler('missions', MissionsHandler)
224 self:AddHandler('shipments', ShipmentsHandler)
225 end
226
227 function core:AddHandler(name, prototype)
228 self.prototypes[name] = setmetatable(prototype, {
229 __index = blockTemplate,
230 __tostring = function() return name end
231 })
232
233 for i, event in ipairs(prototype.events) do
234 if not self.events[event] then
235 self:RegisterEvent(event)
236 self.events[event] = {}
237 print('|cFF00FF00registering', event)
238 end
239
240 prototype.numBlocks = 0
241 if not self.events[event][name] then
242 print('adding', name, 'to', event)
243 self.events[event][name] = prototype.GetPlayerData
244 end
245 end
246 self.sortedItems[name] = {}
247 end
248
249 function core:OnEvent (event, ...)
250 print(event)
251 if event == 'UNIT_PORTRAIT_UPDATE' then
252 SetPortraitTexture(self.portrait, 'player')
253 elseif event == 'PLAYER_LOGIN' then
254 if not self.initialized then
255 if IsLoggedIn() then
256 WorldPlanData.OrderHall = WorldPlanData.OrderHall or {}
257 self.data = WorldPlanData.OrderHall
258
259
260 local name, realm = UnitName('player')
261 realm = realm or GetRealmName()
262 self.profileKey = name .. '-' .. realm
263 if not self.data[self.profileKey] then
264 self.data[self.profileKey] = {}
265 end
266 self.profile = self.data[self.profileKey]
267
268 self.profile.shipments = self.profile.shipments or {}
269 self.profile.missions = self.profile.missions or {}
270 self.profile.classColor = RAID_CLASS_COLORS[select(2, UnitClass('player'))]
271
272 C_Garrison.RequestLandingPageShipmentInfo();
273
274 if self.data.IsShown then
275 self:Show()
276 end
277 self.initialized = true
278 end
279 end
280 elseif self.events[event] then
281 for ptype, eventFunc in pairs(self.events[event]) do
282 print('|cFF88FF00' .. tostring(ptype) .. '|r:GetPlayerData()')
283 eventFunc(self, event)
284 end
285 end
286 end
287
288 function core:UpdateNotifications()
289 end
290
291 function core:RefreshItems(configKey, prototype)
292 local sortedItems = self.sortedItems[configKey]
293
294 self.blocks[configKey] = self.blocks[configKey] or {}
295 local blocks = self.blocks[configKey]
296
297 local lastProfile
298 local numItems = #sortedItems
299 local totalHeight = 0
300 for i, data in ipairs(sortedItems) do
301 local block = blocks[i]
302
303 if not block then
304 block = CreateFrame('Button', nil, self, prototype.templateName)
305 block:SetID(i)
306 prototype.numBlocks = prototype.numBlocks + 1
307
308 if prototype.lastBlock then
309 block:SetPoint('TOPLEFT', prototype.lastBlock, 'BOTTOMLEFT', 0, 0)
310 else
311 block:SetPoint(prototype.point, self[prototype.parent] or self, prototype.relativePoint, 0, 0)
312 end
313 prototype.lastBlock = block
314 blocks[i] = block
315 end
316
317 totalHeight = totalHeight + block:GetHeight()
318 block.lastProfile = lastProfile
319 block:Refresh(data)
320 block:Show()
321 lastProfile = data.profileKey
322 end
323
324 for i = numItems + 1, prototype.numBlocks do
325 if blocks[i] then
326 blocks[i]:Hide()
327 end
328 end
329
330 return totalHeight
331 end
332 local max = math.max
333 function core:Refresh()
334 if self.isStale then
335 self:SortItems()
336 end
337 self.isStale = nil
338
339 self.currentHeight = 0
340 for name, info in pairs(self.prototypes) do
341 local itemsHeight = self:RefreshItems(name, info)
342 self.currentHeight = max(itemsHeight, self.currentHeight)
343 end
344
345 if OrderHallCommandBar and OrderHallCommandBar:IsVisible() then
346 self:ClearAllPoints()
347 self:SetPoint('TOP', OrderHallCommandBar, 'BOTTOM')
348 else
349
350 local posX = self.data.posX or 0
351 local posY = self.data.posY or -24
352 local point = self.point or 'TOP'
353 local relativePoint = self.point or 'TOP'
354 self:SetPoint(point, UIParent, relativePoint, posX, posY)
355 end
356
357 self:SetHeight(self.currentHeight)
358 end
359
360 function core:Toggle()
361 if self:IsVisible() then
362 self:Hide()
363 else
364 self:Show()
365 end
366
367 if self.data then
368 self.data.IsShown = self:IsVisible()
369 end
370 end
371
372 function core:OnUpdate()
373 if self.fadeTimer and self.fadeTimer < GetTime() then
374 self:Hide()
375 end
376 end
377
378 function core:OnShow()
379 if self.isStale then
380 print('updating items on show')
381 self:Refresh()
382 end
383 ClassPlanButton:SetPoint('TOP', self, 'TOP', 0, 0)
384 end
385 function core:OnHide()
386 ClassPlanButton:SetPoint('TOP', UIParent, 'TOP', 0, 0)
387 end
388
389 local GI_profileKey, GI_profile, GI_isMine
390 local GetItemList = function (source, dest, onGetItem)
391 if not source then
392 return
393 end
394 local numItems = 0
395 for index, data in ipairs(source) do
396 data.classColor = GI_profile.classColor or {r = 0.7, g = 0.7, b =0.7}
397 data.profileKey = GI_profileKey
398 data.isMine = GI_isMine
399 if onGetItem then
400 onGetItem(data)
401 end
402 numItems = numItems + 1
403 tinsert(dest, data)
404 end
405 return numItems
406 end
407
408 function core:SortItems()
409 print('|cFF0088FFSortItems()|r')
410 GI_currentTime = time()
411
412 for key, sortedItems in pairs(self.sortedItems) do
413 wipe(sortedItems)
414 local ptype = self.prototypes[key]
415 print( 'object:', ptype)
416 for name, profile in pairs(self.data.characters) do
417 GI_profileKey = name
418 GI_profile = profile
419 GI_isMine = (profile == self.profile)
420
421 local results = GetItemList(profile[key], sortedItems, ptype.OnGetItem)
422 print(' - ', name, results, 'items')
423
424 end
425
426 if ptype.SortHandler then
427 print(' sorting', key, #sortedItems)
428 table.sort(sortedItems, ptype.SortHandler)
429 end
430 end
431 end
432
433
434
376 function core:UpdateItems () 435 function core:UpdateItems ()
377 if not self.profile then 436 end
378 return 437
379 end 438 function MissionsHandler:OnComplete()
380 self.items = C_Garrison.GetLandingPageItems(LE_GARRISON_TYPE_7_0) 439 self.data.isComplete = true
381
382
383
384
385 print('|cFF0088FFLandingPageItems|r:', self.profileKey)
386 if #self.items >= 1 then
387 wipe(self.profile.missions)
388 for index, data in ipairs(self.items) do
389 print('', data.name)
390 print(' |cFF00FF00', data.timeLeft .. '|r', date("%A %I:%m %p", data.missionEndTime))
391 tinsert(self.profile.missions, data)
392 end
393 print('items update pending')
394 self.isStale = true
395 end
396
397 if self:IsVisible() then
398 self:Refresh()
399 end
400 end
401
402 function block:OnComplete()
403 self.isComplete = true
404 self:Refresh() 440 self:Refresh()
405 end 441 end
406 442
407 local GetTimeLeftString = function(timeLeft) 443 local GetTimeLeftString = function(timeLeft)
408 444
415 else 451 else
416 return ((hours > 0) and (hours .. 'h ') or '') .. ((minutes > 0) and (minutes .. ' min') or '') 452 return ((hours > 0) and (hours .. 'h ') or '') .. ((minutes > 0) and (minutes .. ' min') or '')
417 end 453 end
418 end 454 end
419 455
420 function block:OnUpdate() 456 function MissionsHandler:OnUpdate()
421 if self.isComplete then 457 if self.data.isComplete then
422 return 458 return
423 end 459 end
424 460
425 if self.missionEndTime then 461 if self.missionEndTime then
426 local timeLeft = self.missionEndTime - time() 462 local timeLeft = self.missionEndTime - time()
451 end 487 end
452 self.Background:SetColorTexture(data.classColor.r, data.classColor.g, data.classColor.b, 488 self.Background:SetColorTexture(data.classColor.r, data.classColor.g, data.classColor.b,
453 (data.isComplete and 0.5 or 0.1)) 489 (data.isComplete and 0.5 or 0.1))
454 end 490 end
455 491
456 function block:Refresh(data) 492 function MissionsHandler:Refresh(data)
457 data = data or self.data 493 data = data or self.data
458 self.data = data 494 self.data = data
495
496 self.isComplete = data.isComplete
497 self.missionEndTime = data.missionEndTime
459 498
460 local r,g,b = 1, 1, 1 499 local r,g,b = 1, 1, 1
461 if data.isRare then 500 if data.isRare then
462 r,g,b = 0.1, 0.4, 1 501 r,g,b = 0.1, 0.4, 1
463 end 502 end
471 self.Icon:SetTexture(data.rewards[1].icon or GetItemIcon(data.rewards[1].itemID)) 510 self.Icon:SetTexture(data.rewards[1].icon or GetItemIcon(data.rewards[1].itemID))
472 self.rewardInfo = data.rewards[1] 511 self.rewardInfo = data.rewards[1]
473 else 512 else
474 self.Icon:SetAtlas(data.typeAtlas, false) 513 self.Icon:SetAtlas(data.typeAtlas, false)
475 end 514 end
476
477 SetClassColors(self, data)
478
479 if self.isComplete then 515 if self.isComplete then
480 self.TimeLeft:SetText('Complete!') 516 self.TimeLeft:SetText('Complete!')
481 end 517 end
482 end 518 SetClassColors(self, data)
483 519 end
484 520
485 function block:OnEnter() 521
522 function MissionsHandler:OnEnter()
486 if self.rewardInfo and self.rewardInfo.itemID then 523 if self.rewardInfo and self.rewardInfo.itemID then
487 GameTooltip:SetOwner(self, 'ANCHOR_LEFT') 524 GameTooltip:SetOwner(self, 'ANCHOR_LEFT')
488 GameTooltip:SetItemByID(self.rewardInfo.itemID) 525 GameTooltip:SetItemByID(self.rewardInfo.itemID)
489 GameTooltip:Show() 526 GameTooltip:Show()
490 end 527 end
491 end 528 end
492 function block:OnLeave() 529 function MissionsHandler:OnLeave()
493 if GameTooltip:IsOwned(self) then 530 if GameTooltip:IsOwned(self) then
494 GameTooltip:Hide() 531 GameTooltip:Hide()
495 end 532 end
496 end 533 end
497 534
498 535
499 536
500 function shipment:Refresh(data) 537 function ShipmentsHandler:Refresh(data)
501 data = data or self.data 538 data = data or self.data
539
540 --[[
541 self.icon = data.icon
542 self.shipmentCapacity = data.shipmentCapacity
543 self.shipmentsReady = data.shipmentsReady
544 self.shipmentsTotal = data.shipmentsTotal
545 self.creationTime = data.creationTime
546 self.duration = data.duration
547 self.itemID = data.itemID
548 self.itemQuality = data.itemQuality
549 icon = texture,
550 shipmentCapacity = shipmentCapacity,
551 shipmentsReady = shipmentsReady,
552 shipmentsTotal = shipmentsTotal,
553 creationTime = creationTime,
554 duration = duration,
555 timeleftString = timeleftString,
556 itemName = itemName,
557 itemIcon = itemIcon,
558 itemQuality = itemQuality,
559 itemID = itemID
560
561 --]]
562
502 self.Icon:SetTexture(data.icon) 563 self.Icon:SetTexture(data.icon)
503 self.data = data 564 self.data = data
504 565
566
567 local isComplete = data.isComplete
568
569
570
505 self.Name:SetText(data.shipmentType .. data.name) 571 self.Name:SetText(data.shipmentType .. data.name)
506 self.Count:SetText(data.shipmentsReady) 572 self.Count:SetText(data.shipmentsReady)
507
508 self.Done:SetShown(data.shipmentsReady and (data.shipmentsReady >= 1)) 573 self.Done:SetShown(data.shipmentsReady and (data.shipmentsReady >= 1))
509 574
510 if ( data.shipmentsReady == data.shipmentsTotal ) then 575
576 -- flag as complete
577 if ( data.shipmentsReady == data.shipmentsTotal ) and (not data.isBeingResearched) then
511 self.Swipe:SetCooldownUNIX(0, 0); 578 self.Swipe:SetCooldownUNIX(0, 0);
512 self.Done:Show(); 579 self.Done:Show();
513 if not data.isBeingResearched then 580 isComplete = true
514 data.isComplete = true
515 end
516 else 581 else
517 self.Swipe:SetCooldownUNIX(data.creationTime or 0 , data.duration or 0); 582 self.Swipe:SetCooldownUNIX(data.creationTime or 0 , data.duration or 0);
518 end 583 end
519 584
520 585 data.isComplete = isComplete
521 586
522 SetClassColors(self, data) 587 SetClassColors(self, data)
523 end 588 end
524 function shipment:UpdateShipment() 589 function ShipmentsHandler:OnUpdate()
525
526 local data = self.data
527 if data.shipmentsTotal then
528 local timeLeft = data.creationTime + data.duration - time()
529 if timeLeft < 0 then
530 local numReady = floor((1*timeLeft) / data.duration)
531 data.shipmentsReady = data.shipmentsReady + numReady
532 data.creationTime = data.creationTime + (numReady * data.duration)
533 self:Refresh()
534 end
535 end
536 end
537 function shipment:OnUpdate()
538 local data = self.data 590 local data = self.data
539 if (data.shipmentsReady and data.shipmentsTotal) and (data.shipmentsReady ~= data.shipmentsTotal) then 591 if (data.shipmentsReady and data.shipmentsTotal) and (data.shipmentsReady ~= data.shipmentsTotal) then
540 local timeLeft = data.creationTime + data.duration - time() 592 local timeLeft = data.creationTime + data.duration - time()
541 if timeLeft < 0 then
542 self:UpdateShipment()
543 return
544 end
545
546 self.TimeLeft:SetText('Next: '.. GetTimeLeftString(timeLeft) .. ' |cFFFFFF00'..data.shipmentsTotal..' orders|r') 593 self.TimeLeft:SetText('Next: '.. GetTimeLeftString(timeLeft) .. ' |cFFFFFF00'..data.shipmentsTotal..' orders|r')
547 594 elseif data.isStale then
548 595 self.TimeLeft:SetText('|cFFFF0000Needs refresh|r')
549 elseif data.isBeingResearched then 596 elseif data.isBeingResearched then
550 self.TimeLeft:SetText(GetTimeLeftString(data.researchStartTime + data.researchDuration - time())) 597 self.TimeLeft:SetText(GetTimeLeftString(data.researchStartTime + data.researchDuration - time()))
551 else 598 else
552 self.TimeLeft:SetText('Complete!') 599 self.TimeLeft:SetText('Complete!')
553 end 600 end
554 601
555 end 602 end
556 603
557 function shipment:OnEnter() 604 function ShipmentsHandler:OnEnter()
558 local data = self.data 605 local data = self.data
559 if ( data.shipmentsReady and data.shipmentsTotal ) then 606 if ( data.shipmentsReady and data.shipmentsTotal ) then
560 GameTooltip:SetOwner(self, 'ANCHOR_LEFT') 607 GameTooltip:SetOwner(self, 'ANCHOR_LEFT')
561 GameTooltip:AddLine(data.shipmentsReady .. ' of '.. data.shipmentsTotal) 608 GameTooltip:AddLine(data.shipmentsReady .. ' of '.. data.shipmentsTotal)
562 GameTooltip:Show() 609 GameTooltip:Show()
563 end 610 end
564 end 611 end
565 612
566 function shipment:OnLeave() 613 function ShipmentsHandler:OnLeave()
567 if GameTooltip:IsOwned(self) then 614 if GameTooltip:IsOwned(self) then
568 GameTooltip:Hide() 615 GameTooltip:Hide()
569 end 616 end
570 end 617 end
571 618
572 function shipment:OnClick(button) 619 function ShipmentsHandler:OnClick(button)
573 --todo: trigger cleanup script for dead shipment data 620 if button == 'RightButton' then
574 end 621 for name, profile in pairs(ClassOrderPlan.data) do
622 for index, shipment in pairs(profile.shipments) do
623 if shipment == self.data then
624 profile.shipments[index] = nil
625 ClassOrderPlan:Refresh()
626 end
627 end
628 end
629 end
630 end