comparison ClassPlan.lua @ 2:b8a19781f79b

shipment logging
author Nenue
date Thu, 13 Oct 2016 09:08:38 -0400
parents 232617b8bcd5
children c006ce87a147
comparison
equal deleted inserted replaced
1:232617b8bcd5 2:b8a19781f79b
1 local wipe = table.wipe
2 local pairs, ipairs = pairs, ipairs
3 local GetTime = GetTime
4 local blockTemplate = {
5 point = 'TOPLEFT',
6 relativePoint ='TOPLEFT',
7 }
8
1 SLASH_CLASSPLAN1 = "/classplan" 9 SLASH_CLASSPLAN1 = "/classplan"
2 SLASH_CLASSPLAN2 = "/cp" 10 SLASH_CLASSPLAN2 = "/cp"
3 SlashCmdList.CLASSPLAN = function(args) 11 SlashCmdList.CLASSPLAN = function(args)
4 if ClassOrderPlan:IsVisible() then 12 if ClassOrderPlan:IsVisible() then
5 ClassOrderPlan:Hide() 13 ClassOrderPlan:Hide()
8 DEFAULT_CHAT_FRAME:AddMessage('|cFF88FF00WorldPlan|r: Order Hall Panel') 16 DEFAULT_CHAT_FRAME:AddMessage('|cFF88FF00WorldPlan|r: Order Hall Panel')
9 end 17 end
10 end 18 end
11 19
12 ClassOrderPlanCore = { 20 ClassOrderPlanCore = {
21 freeBlocks = {},
13 blocks = {}, 22 blocks = {},
14 playerFirst = true, 23 shipmentBlocks = {},
15 timers = {} 24 freeShipmentBlocks = {},
25 sortedShipments = {},
26 sortedMissions = {},
27 timers = {},
28 shipments = {},
29 playerFirst = false,
30 templates = setmetatable({}, {
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 })
16 } 38 }
17 ClassPlanBlockMixin = { 39 ClassPlanBlockMixin = {}
18 followers = {}, 40 ClassPlanShipmentMixin = setmetatable({}, {__index = ClassPlanBlockMixin})
19 blocks = {}, 41 local core, block, shipment = ClassOrderPlanCore, ClassPlanBlockMixin, ClassPlanShipmentMixin
20 }
21 local core, block = ClassOrderPlanCore, ClassPlanBlockMixin
22 local print = DEVIAN_WORKSPACE and function(...) print('ClassPlan', ...) end or nop 42 local print = DEVIAN_WORKSPACE and function(...) print('ClassPlan', ...) end or nop
43
44
23 45
24 function core:OnLoad () 46 function core:OnLoad ()
25 self:RegisterUnitEvent('UNIT_PORTRAIT_UPDATE', 'player') 47 self:RegisterUnitEvent('UNIT_PORTRAIT_UPDATE', 'player')
26 self:RegisterEvent('GARRISON_MISSION_STARTED')
27 self:RegisterEvent('GARRISON_MISSION_FINISHED')
28 self:RegisterEvent('PLAYER_LOGIN') 48 self:RegisterEvent('PLAYER_LOGIN')
29 self:RegisterEvent('PLAYER_ENTERING_WORLD') 49 self:RegisterEvent('PLAYER_ENTERING_WORLD')
30 end 50 self:RegisterEvent('PLAYER_REGEN_ENABLED')
31 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,
70 point = 'TOPRIGHT',
71 relativePoint ='TOPRIGHT',
72 SetItemData = function(block, data)
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 }
32 97
33 function core:OnEvent (event, ...) 98 function core:OnEvent (event, ...)
99 print(event)
34 if event == 'UNIT_PORTRAIT_UPDATE' then 100 if event == 'UNIT_PORTRAIT_UPDATE' then
35 SetPortraitTexture(self.portrait, 'player') 101 SetPortraitTexture(self.portrait, 'player')
36 elseif event == 'PLAYER_LOGIN' then 102 elseif event == 'PLAYER_LOGIN' then
37 if not self.initialized then 103 if not self.initialized then
38 if IsLoggedIn() then 104 if IsLoggedIn() then
46 if not self.data[self.profileKey] then 112 if not self.data[self.profileKey] then
47 self.data[self.profileKey] = {} 113 self.data[self.profileKey] = {}
48 end 114 end
49 self.profile = self.data[self.profileKey] 115 self.profile = self.data[self.profileKey]
50 116
117 self.profile.shipments = self.profile.shipments or {}
118 self.profile.missions = self.profile.missions or {}
119 self.profile.classColor = RAID_CLASS_COLORS[select(2, UnitClass('player'))]
120
121 C_Garrison.RequestLandingPageShipmentInfo();
51 self.initialized = true 122 self.initialized = true
52 print('initialized')
53 end 123 end
54 end 124 end
55 else 125 elseif event == 'GARRISON_LANDINGPAGE_SHIPMENTS' or event == 'GARRISON_TALENT_UPDATE' then
56 self:Refresh () 126 self:UpdateShipments()
57 end 127 elseif event == 'PLAYER_REGEN_ENABLED' or event == 'GARRISON_MISSION_FINISHED' or event == 'GARRISON_TALENT_COMPLETE' or event == 'GARRISON_SHIPMENT_RECEIVED' then
58 end 128 self:UpdateNotifications()
59 129 else
60 function core:UpdateList() 130 self:UpdateItems ()
61 self.sortedMissions = self.sortedMissions or {} 131 end
62 table.wipe(self.sortedMissions) 132 end
63 133
134 function core:UpdateNotifications()
135 end
136
137 function core:RefreshItems(sortedItems, templateName)
138 self.blocks[templateName] = self.blocks[templateName] or {}
139 local blocks = self.blocks[templateName]
140 local template = self.templates[templateName] or {
141 parent = self.portrait,
142 point = 'TOPLEFT',
143 relativePoint ='TOPRIGHT',
144 }
145
146 local lastProfile
147 local numItems = #sortedItems
148 for i, data in ipairs(sortedItems) do
149 local block = blocks[i]
150
151 if not block then
152 block = CreateFrame('Frame', nil, self, templateName)
153 block:SetID(i)
154 template.numBlocks = (template.numBlocks or 0) + 1
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)
64 for name, profile in pairs(self.data) do 220 for name, profile in pairs(self.data) do
65 local isMine = (profile == self.profile) 221 local isMine = (profile == self.profile)
66 for index, data in pairs(profile.missions) do 222 for index, data in pairs(profile.missions) do
67 223
68 data.classColor = profile.classColor or {r = 0.7, g = 0.7, b =0.7} 224 data.classColor = profile.classColor or {r = 0.7, g = 0.7, b =0.7}
69
70 data.profileKey = name 225 data.profileKey = name
71 data.isMine = (profile == self.profile) 226 data.isMine = (profile == self.profile)
72 tinsert(self.sortedMissions, data) 227 tinsert(self.sortedMissions, data)
73 end 228 end
74 end 229
75 230 if not profile.shipments then
76 for i, v in ipairs(self.sortedMissions) do 231 profile.shipments = {}
77 print(i, v.missionEndTime, v.name) 232 profile.shipment = nil
78 end 233 end
79 234
80 235 for index, data in pairs(profile.shipments) do
81 table.sort(self.sortedMissions, function(a,b) 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)
82 local result = false 244 local result = false
83 if not a or not b then 245 if not a or not b then
84 result = true 246 result = true
85 else 247 else
86
87 if (a.isMine ~= b.isMine) and self.playerFirst then 248 if (a.isMine ~= b.isMine) and self.playerFirst then
88 result = a.isMine 249 result = a.isMine
89 else 250 else
90 if (not b.missionEndTime) or (not a.missionEndTime) then 251 if (not b.missionEndTime) or (not a.missionEndTime) then
91 print('missing article', b.missionEndTime, a.missionEndTime) 252 print('missing article', b.missionEndTime, a.missionEndTime)
92 end 253 end
93
94 result = ( b.missionEndTime > a.missionEndTime) 254 result = ( b.missionEndTime > a.missionEndTime)
95 end 255 end
96 end 256 end
97 257
98 print('cmp', (b and (b.missionEndTime .. ' ' .. tostring(b.isMine)) or '-'), '>', (a and (a.missionEndTime .. ' ' .. tostring(a.isMine)) or '-'), result, n) 258 --print('cmp', (b and (b.missionEndTime .. ' ' .. tostring(b.isMine)) or '-'), '>', (a and (a.missionEndTime .. ' ' .. tostring(a.isMine)) or '-'), result, n)
99 return result 259 return result
100 end) 260 end)
101 self.isStale = nil 261
102 262 end
103 local lastProfile 263
104 local numItems = #self.sortedMissions 264 function core:UpdateShipments()
105 for i, data in ipairs(self.sortedMissions) do 265 print('|cFF0088FFShipments|r:', self.profileKey)
106 local block = self.blocks[i]
107 if not block then
108 block = CreateFrame('Frame', nil, self, 'ClassPlanBlock')
109 block:SetID(i)
110 self.numBlocks = (self.numBlocks or 0) + 1
111
112 if self.lastBlock then
113 block:SetPoint('TOPLEFT', self.lastBlock, 'BOTTOMLEFT', 0, 0)
114 else
115 block:SetPoint('TOPLEFT', self.portrait, 'TOPRIGHT', 0, 0)
116 end
117 self.lastBlock = block
118 self.blocks[i] = block
119 end
120
121 local r,g,b = 1, 1, 1
122 if data.isRare then
123 r,g,b = 0.1, 0.4, 1
124 end
125 if data.isMine then
126 block.Icon:SetVertexColor(0,1,0,1)
127 else
128 block.Icon:SetVertexColor(1,1,1)
129 end
130
131
132 --block.missionData = data
133 block.missionID = data.missionID
134 block.missionEndTime = data.missionEndTime
135 block.Icon:SetAtlas(data.typeAtlas, false)
136 block.Label:SetText(data.name)
137 block.Label:SetTextColor(r, g, b)
138
139 if lastProfile ~= data.profileKey then
140 block.Owner:SetText(data.profileKey)
141 block.Owner:SetTextColor(data.classColor.r, data.classColor.g, data.classColor.b)
142 else
143 block.Owner:SetText(nil)
144 end
145 block.Background:SetColorTexture(data.classColor.r, data.classColor.g, data.classColor.b, 0.5)
146
147 block:Show()
148 lastProfile = data.profileKey
149 end
150 for i = numItems + 1, self.numBlocks do
151 if self.blocks[i] then
152 self.blocks[i]:Hide()
153 end
154 end
155 end
156
157 function core:OnShow()
158 if self.isStale then
159 print('updating items on show')
160 self:UpdateList()
161 end
162 end
163
164 function core:Refresh ()
165 if not self.profile then 266 if not self.profile then
166 return 267 return
167 end 268 end
168 269 wipe(self.shipments)
270
271
272 local garrisonType = LE_GARRISON_TYPE_7_0
273 local buildings = C_Garrison.GetBuildings(garrisonType);
274 local shipmentIndex = 0
275 print('Buildings:')
276 for i = 1, #buildings do
277 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,
280 {
281 shipmentType = 'Work Order',
282 name = name,
283 icon = texture,
284 shipmentCapacity = shipmentCapacity,
285 shipmentsReady = shipmentsReady,
286 shipmentsTotal = shipmentsTotal,
287 creationTime = creationTime,
288 duration = duration,
289 timeleftString = timeleftString,
290 itemName = itemName,
291 itemIcon = itemIcon,
292 itemQuality = itemQuality,
293 itemID = itemID
294 })
295 end
296
297 print('Follower:')
298 local followerShipments = C_Garrison.GetFollowerShipments(garrisonType);
299 for i = 1, #followerShipments do
300 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,
303 {
304 shipmentType = '',
305 name = name,
306 icon = texture,
307 shipmentCapacity = shipmentCapacity,
308 shipmentsReady = shipmentsReady,
309 shipmentsTotal = shipmentsTotal,
310 creationTime = creationTime,
311 duration = duration,
312 timeleftString = timeleftString,
313 followerID = followerID,
314 })
315 end
316
317 print('Loose:')
318 local looseShipments = C_Garrison.GetLooseShipments(garrisonType)
319 for i = 1, #looseShipments do
320 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,
323 {
324 shipmentType = '',
325 name = name,
326 icon = texture,
327 shipmentCapacity = shipmentCapacity,
328 shipmentsReady = shipmentsReady,
329 shipmentsTotal = shipmentsTotal,
330 creationTime = creationTime,
331 duration = duration,
332 timeleftString = timeleftString,
333 })
334 end
335
336 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.
338 local completeTalentID = C_Garrison.GetCompleteTalent(garrisonType);
339 print('Talents:')
340 if (talentTrees) then
341 for treeIndex, tree in ipairs(talentTrees) do
342 for talentIndex, talent in ipairs(tree) do
343 local showTalent = false;
344 if (talent.isBeingResearched) then
345 showTalent = true;
346 end
347 if (talent.id == completeTalentID) then
348 showTalent = true;
349 end
350 if (showTalent) then
351 print(talent.name)
352 talent.creationTime = talent.researchStartTime
353 talent.duration = talent.researchDuration
354 talent.shipmentType = 'Talent: '
355 tinsert(self.shipments, talent)
356 end
357 end
358 end
359 end
360
361 self.profile.shipments = self.profile.shipments or {}
362 if #self.shipments >= 1 then
363
364 wipe(self.profile.shipments)
365 for index, shipment in ipairs(self.shipments) do
366 tinsert(self.profile.shipments, shipment)
367 end
368 self.isStale = true
369 end
370
371 if self:IsVisible() then
372 self:Refresh()
373 end
374 end
375
376 function core:UpdateItems ()
377 if not self.profile then
378 return
379 end
169 self.items = C_Garrison.GetLandingPageItems(LE_GARRISON_TYPE_7_0) 380 self.items = C_Garrison.GetLandingPageItems(LE_GARRISON_TYPE_7_0)
170 381
171 self.profile.missions = self.profile.missions or {} 382
172 383
173 self.profile.classColor = RAID_CLASS_COLORS[select(2, UnitClass('player'))] 384
174 385 print('|cFF0088FFLandingPageItems|r:', self.profileKey)
175
176 print('|cFF0088FFLocal Scoop|r:', self.profileKey)
177 if #self.items >= 1 then 386 if #self.items >= 1 then
178 table.wipe(self.profile.missions) 387 wipe(self.profile.missions)
179 for index, data in ipairs(self.items) do 388 for index, data in ipairs(self.items) do
180 print('', data.name) 389 print('', data.name)
181 print(' |cFF00FF00', data.timeLeft .. '|r', date("%A %I:%m %p", data.missionEndTime)) 390 print(' |cFF00FF00', data.timeLeft .. '|r', date("%A %I:%m %p", data.missionEndTime))
182 tinsert(self.profile.missions, data) 391 tinsert(self.profile.missions, data)
183 end 392 end
184 end
185
186 if self:IsVisible() then
187 self:UpdateList()
188 else
189 print('items update pending') 393 print('items update pending')
190 self.isStale = true 394 self.isStale = true
191 end 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()
405 end
406
407 local GetTimeLeftString = function(timeLeft)
408
409 local days = floor(timeLeft/(24*3600))
410 local hours = floor(mod(timeLeft, (24*3600)) / 3600)
411 local minutes = floor(mod(timeLeft, 3600) / 60)
412 local seconds = mod(timeLeft, 60)
413 if days >= 1 then
414 return (days .. 'd' .. ' ') .. ((hours > 0) and (hours .. 'h ') or '')
415 else
416 return ((hours > 0) and (hours .. 'h ') or '') .. ((minutes > 0) and (minutes .. ' min') or '')
417 end
192 end 418 end
193 419
194 function block:OnUpdate() 420 function block:OnUpdate()
421 if self.isComplete then
422 return
423 end
424
195 if self.missionEndTime then 425 if self.missionEndTime then
196 local timeLeft = self.missionEndTime - time() 426 local timeLeft = self.missionEndTime - time()
197 if timeLeft < 0 then 427 if timeLeft < 0 then
198 self.TimeLeft:SetText('Complete!') 428 self:OnComplete()
199 else 429 else
200 local days = floor(timeLeft/(24*3600)) 430 self.TimeLeft:SetText(GetTimeLeftString(timeLeft))
201 local hours = floor(mod(timeLeft, (24*3600)) / 3600) 431
202 local minutes = floor(mod(timeLeft, 3600) / 60) 432 if timeLeft > 3600 then
203 local seconds = mod(timeLeft, 60) 433 self.TimeLeft:SetTextColor(1,1,1)
204 self.TimeLeft:SetText( 434 else
205 ((days > 0) and (days .. ' d') or '') .. 435 self.TimeLeft:SetTextColor(1,1,0)
206 ((hours > 0) and (' '.. hours .. ' hr') or '').. 436 end
207 ((minutes > 0) and (' ' .. minutes .. ' min' or '')) 437
208 , 1,1,1)
209 end 438 end
210 else 439 else
211 self.TimeLeft:SetText(self.missionEndTime) 440 self.TimeLeft:SetText(self.missionEndTime)
212 end 441 end
213 end 442 end
443
444 local SetClassColors = function(self, data)
445
446 if self.lastProfile ~= data.profileKey then
447 self.Owner:SetText(data.profileKey)
448 self.Owner:SetTextColor(data.classColor.r, data.classColor.g, data.classColor.b)
449 else
450 self.Owner:SetText(nil)
451 end
452 self.Background:SetColorTexture(data.classColor.r, data.classColor.g, data.classColor.b,
453 (data.isComplete and 0.5 or 0.1))
454 end
455
456 function block:Refresh(data)
457 data = data or self.data
458 self.data = data
459
460 local r,g,b = 1, 1, 1
461 if data.isRare then
462 r,g,b = 0.1, 0.4, 1
463 end
464
465
466 --self.missionData = data
467 self.Label:SetText(data.name)
468 self.Label:SetTextColor(r, g, b)
469
470 if #data.rewards >= 1 then
471 self.Icon:SetTexture(data.rewards[1].icon or GetItemIcon(data.rewards[1].itemID))
472 self.rewardInfo = data.rewards[1]
473 else
474 self.Icon:SetAtlas(data.typeAtlas, false)
475 end
476
477 SetClassColors(self, data)
478
479 if self.isComplete then
480 self.TimeLeft:SetText('Complete!')
481 end
482 end
483
484
485 function block:OnEnter()
486 if self.rewardInfo and self.rewardInfo.itemID then
487 GameTooltip:SetOwner(self, 'ANCHOR_LEFT')
488 GameTooltip:SetItemByID(self.rewardInfo.itemID)
489 GameTooltip:Show()
490 end
491 end
492 function block:OnLeave()
493 if GameTooltip:IsOwned(self) then
494 GameTooltip:Hide()
495 end
496 end
497
498
499
500 function shipment:Refresh(data)
501 data = data or self.data
502 self.Icon:SetTexture(data.icon)
503 self.data = data
504
505 self.Name:SetText(data.shipmentType .. data.name)
506 self.Count:SetText(data.shipmentsReady)
507
508 self.Done:SetShown(data.shipmentsReady and (data.shipmentsReady >= 1))
509
510 if ( data.shipmentsReady == data.shipmentsTotal ) then
511 self.Swipe:SetCooldownUNIX(0, 0);
512 self.Done:Show();
513 if not data.isBeingResearched then
514 data.isComplete = true
515 end
516 else
517 self.Swipe:SetCooldownUNIX(data.creationTime or 0 , data.duration or 0);
518 end
519
520
521
522 SetClassColors(self, data)
523 end
524 function shipment:UpdateShipment()
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
539 if (data.shipmentsReady and data.shipmentsTotal) and (data.shipmentsReady ~= data.shipmentsTotal) then
540 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')
547
548
549 elseif data.isBeingResearched then
550 self.TimeLeft:SetText(GetTimeLeftString(data.researchStartTime + data.researchDuration - time()))
551 else
552 self.TimeLeft:SetText('Complete!')
553 end
554
555 end
556
557 function shipment:OnEnter()
558 local data = self.data
559 if ( data.shipmentsReady and data.shipmentsTotal ) then
560 GameTooltip:SetOwner(self, 'ANCHOR_LEFT')
561 GameTooltip:AddLine(data.shipmentsReady .. ' of '.. data.shipmentsTotal)
562 GameTooltip:Show()
563 end
564 end
565
566 function shipment:OnLeave()
567 if GameTooltip:IsOwned(self) then
568 GameTooltip:Hide()
569 end
570 end
571
572 function shipment:OnClick(button)
573 --todo: trigger cleanup script for dead shipment data
574 end