Mercurial > wow > worldplan
comparison ClassPlan.lua @ 32:e8679ecb48d8
ClassPlan:
- Available missions are now recorded; the mission list can be toggled between in-progress and available by clicking the heading.
author | Nenue |
---|---|
date | Tue, 01 Nov 2016 10:48:50 -0400 |
parents | 4a7e89bffbcb |
children | 26dfa661daa7 |
comparison
equal
deleted
inserted
replaced
31:d0114b51cdea | 32:e8679ecb48d8 |
---|---|
1 local wipe, tinsert, sort = table.wipe, tinsert, table.sort | 1 local wipe, tinsert, sort = table.wipe, tinsert, table.sort |
2 local pairs, ipairs = pairs, ipairs | 2 local pairs, ipairs = pairs, ipairs |
3 local floor, mod, time = floor, mod, time | 3 local floor, mod, time = floor, mod, time |
4 local max, min = math.max, math.min | |
4 local GetTime = GetTime | 5 local GetTime = GetTime |
5 local GI_currentTime = time() | 6 local GI_currentTime = time() |
6 | 7 local print = DEVIAN_WORKSPACE and function(...) print('ClassPlan', ...) end or nop |
7 local BOUND_FRAMES = {} | 8 |
8 local blockTemplate = { | 9 local CG_GetBuildings = C_Garrison.GetBuildings |
9 point = 'TOPLEFT', | 10 local CG_GetFollowerShipments = C_Garrison.GetFollowerShipments |
10 relativePoint ='TOPLEFT', | 11 local CG_GetLooseShipments = C_Garrison.GetLooseShipments |
12 local CG_GetTalentTrees = C_Garrison.GetTalentTrees | |
13 local CG_GetCompleteTalent = C_Garrison.GetCompleteTalent | |
14 local CG_GetLandingPageShipmentInfo = C_Garrison.GetLandingPageShipmentInfo | |
15 local CG_GetLandingPageShipmentInfoByContainerID = C_Garrison.GetLandingPageShipmentInfoByContainerID | |
16 | |
17 local CP_REPLACE_LANDINGPAGE = true | |
18 local CP_HEADER_SIZE = 24 | |
19 local CP_BACKGROUND_COLOR = { | |
20 inProgress = {0, 0, 0, 0.5}, | |
21 shipmentsReady = {0, 0, 0, 0.25}, | |
22 complete = {0.5, 0.5, 0.5, 0.5} | |
11 } | 23 } |
12 | 24 |
13 SLASH_CLASSPLAN1 = "/classplan" | 25 local GetTimeLeftString = function(timeLeft) |
14 SLASH_CLASSPLAN2 = "/cp" | 26 local days = floor(timeLeft/(24*3600)) |
15 SlashCmdList.CLASSPLAN = function(args) | 27 local hours = floor(mod(timeLeft, (24*3600)) / 3600) |
16 ClassOrderPlan:Toggle() | 28 local minutes = floor(mod(timeLeft, 3600) / 60) |
17 end | 29 local seconds = mod(timeLeft, 60) |
30 if days >= 1 then | |
31 return (days .. 'd' .. ' ') .. ((hours > 0) and (hours .. 'h') or '') | |
32 else | |
33 return ((hours > 0) and (hours .. 'h') or '') .. ((minutes > 0) and (' ' ..minutes .. ' min') or '') | |
34 end | |
35 end | |
36 | |
18 | 37 |
19 ClassOrderPlanCore = { | 38 ClassOrderPlanCore = { |
20 events = {}, | 39 events = {}, |
21 freeBlocks = {}, | 40 freeBlocks = {}, |
22 blocks = {}, | 41 blocks = {}, |
25 shipments = {}, | 44 shipments = {}, |
26 playerFirst = false, | 45 playerFirst = false, |
27 prototypes = {}, | 46 prototypes = {}, |
28 Queued = {} | 47 Queued = {} |
29 } | 48 } |
30 | 49 local MissionList = { |
31 ClassPlanMissionMixin = { | |
32 templateName = 'ClassPlanMissionEntry', | 50 templateName = 'ClassPlanMissionEntry', |
51 listKey = {'missions', 'available'}, | |
52 listTitle = {'In Progress', 'Available'}, | |
53 | |
54 point = 'TOPLEFT', | |
55 relativePoint ='TOPLEFT', | |
33 events = { | 56 events = { |
34 'GARRISON_MISSION_LIST_UPDATE', | 57 'GARRISON_MISSION_LIST_UPDATE', |
35 'GARRISON_MISSION_STARTED', | 58 'GARRISON_LANDINGPAGE_SHIPMENTS'}, |
36 'GARRISON_MISSION_FINISHED', | 59 } |
37 'GARRISON_LANDINGPAGE_SHIPMENTS'},} | 60 local ShipmentList = { |
38 ClassPlanShipmentMixin = { | |
39 templateName = 'ClassPlanShipmentEntry', | 61 templateName = 'ClassPlanShipmentEntry', |
40 parent = false, | 62 listKey = {'shipments'}, |
41 point = 'TOPRIGHT', | 63 listTitle = {'Work Orders'}, |
42 relativePoint ='TOPRIGHT', | |
43 events = { | 64 events = { |
65 'GARRISON_MISSION_LIST_UPDATE', | |
44 'GARRISON_LANDINGPAGE_SHIPMENTS', | 66 'GARRISON_LANDINGPAGE_SHIPMENTS', |
45 'GARRISON_TALENT_UPDATE', | 67 'GARRISON_TALENT_UPDATE', |
46 "GARRISON_TALENT_COMPLETE", | 68 "GARRISON_TALENT_COMPLETE", |
47 "GARRISON_SHIPMENT_RECEIVED", | 69 "GARRISON_SHIPMENT_RECEIVED", |
48 'GARRISON_FOLLOWER_LIST_UPDATE', | 70 'GARRISON_FOLLOWER_LIST_UPDATE', |
49 'GARRISON_SHOW_LANDING_PAGE'}, | 71 'GARRISON_SHOW_LANDING_PAGE'}, |
50 } | 72 } |
51 setmetatable(ClassPlanShipmentMixin, {__index = ClassPlanMissionMixin}) | 73 local SharedHandlers = { |
52 local core, MissionsHandler, ShipmentsHandler = ClassOrderPlanCore, ClassPlanMissionMixin, ClassPlanShipmentMixin | 74 numBlocks = 0, |
53 local print = DEVIAN_WORKSPACE and function(...) print('ClassPlan', ...) end or nop | 75 isStale = true, |
54 | 76 } |
55 local GetTimeLeftString = function(timeLeft) | 77 local SharedEntry = {} |
56 local days = floor(timeLeft/(24*3600)) | 78 local ShipmentEntry = {} |
57 local hours = floor(mod(timeLeft, (24*3600)) / 3600) | 79 local MissionEntry = {} |
58 local minutes = floor(mod(timeLeft, 3600) / 60) | 80 |
59 local seconds = mod(timeLeft, 60) | 81 local ClassPlan = ClassOrderPlanCore |
60 if days >= 1 then | 82 |
61 return (days .. 'd' .. ' ') .. ((hours > 0) and (hours .. 'h') or '') | 83 function ClassPlan:OnLoad () |
62 else | 84 self:RegisterEvent('PLAYER_LOGIN') |
63 return ((hours > 0) and (hours .. 'h') or '') .. ((minutes > 0) and (' ' ..minutes .. ' min') or '') | 85 self:RegisterEvent('ADDON_LOADED') |
64 end | 86 self:RegisterEvent('PLAYER_REGEN_ENABLED') |
65 end | 87 self:RegisterEvent('PLAYER_REGEN_DISABLED') |
66 | 88 self:RegisterForDrag('LeftButton') |
67 | 89 self:SetMovable(true) |
68 | 90 self:SetToplevel(true) |
69 MissionsHandler.GetPlayerData = function(self) | 91 |
70 if not self.profile then | 92 |
93 SLASH_CLASSPLAN1 = "/classplan" | |
94 SLASH_CLASSPLAN2 = "/cp" | |
95 SlashCmdList.CLASSPLAN = function(args) | |
96 self:Toggle() | |
97 end | |
98 | |
99 end | |
100 | |
101 function ClassPlan:GetCurrentProfile() | |
102 WorldPlanData.OrderHall = WorldPlanData.OrderHall or {} | |
103 local db = WorldPlanData.OrderHall | |
104 self.data = db | |
105 | |
106 local characters = db.characters or {} | |
107 db.characters = characters | |
108 | |
109 local name, realm = UnitName('player') | |
110 realm = realm or GetRealmName() | |
111 local profileName = name .. '-' .. realm | |
112 | |
113 self.profile = characters[profileName] or {} | |
114 self.characters = characters | |
115 characters[profileName] = self.profile | |
116 | |
117 | |
118 local classColor = RAID_CLASS_COLORS[select(2, UnitClass('player'))] | |
119 local className = UnitClass('player') | |
120 | |
121 print('|cFFFFFF00Loaded:|r', classColor.hex, className, profileName) | |
122 self.Background:SetColorTexture(classColor.r, classColor.g, classColor.b, 0.5) | |
123 self.profile.classColor = classColor | |
124 self.profile.className = className | |
125 return self.profile | |
126 end | |
127 | |
128 function ClassPlan:SetupHandler(handler) | |
129 print('|cFF00FF00'..handler:GetName()..' loaded') | |
130 for i, event in ipairs(handler.events) do | |
131 print('|cFF00FF00 event', event) | |
132 handler:RegisterEvent(event) | |
133 end | |
134 for index, listKey in ipairs(handler.listKey) do | |
135 self.profile[listKey] = self.profile[listKey] or {} | |
136 local listTitle = handler.listTitle[index] | |
137 setmetatable(self.profile[listKey], { __tostring = listTitle }) | |
138 end | |
139 handler:SetList(1) | |
140 handler.sortedItems = {} | |
141 end | |
142 | |
143 function ClassPlan:OnEvent (event, arg) | |
144 print(event, arg) | |
145 if event == 'PLAYER_REGEN_DISABLED' then | |
146 if self:IsVisible() then | |
147 self.combatHide = true | |
148 self:SetShown(false) | |
149 end | |
150 | |
151 elseif event == 'PLAYER_REGEN_ENABLED' then | |
152 if self.combatHide == true then | |
153 self.combatHide = nil | |
154 self:SetShown(true) | |
155 end | |
156 elseif event == 'ADDON_LOADED' then | |
157 if arg == 'Blizzard_GarrisonUI' then | |
158 self:Reanchor() | |
159 end | |
160 elseif event == 'PLAYER_LOGIN' then | |
161 if not self.initialized then | |
162 self:Setup() | |
163 end | |
164 end | |
165 end | |
166 | |
167 function ClassPlan:Setup() | |
168 if IsLoggedIn() then | |
169 print('|cFFFFFF00'..self:GetName()..':Setup()|r') | |
170 | |
171 self:GetCurrentProfile() | |
172 for _, handler in ipairs(self.Handlers) do | |
173 self:SetupHandler(handler) | |
174 end | |
175 self.initialized = true | |
176 self:SetShown(self.data.IsShown) | |
177 end | |
178 end | |
179 | |
180 | |
181 --- Update space | |
182 | |
183 local max = math.max | |
184 function ClassPlan:Update() | |
185 print('|cFF00FFFFRefresh()|r') | |
186 self.currentHeight = 0 | |
187 for index, handler in pairs(self.Handlers) do | |
188 if handler.isStale then | |
189 print(' |cFF00FF00'..index..' '..handler:GetName()..'|r') | |
190 local sortedItems = handler.sortedItems | |
191 local activeKey = handler.activeKey | |
192 handler.profile = self.profile[handler.activeKey] | |
193 | |
194 wipe(sortedItems) | |
195 handler:GetPlayerData(self.profile) | |
196 for key, profile in pairs(self.data.characters) do | |
197 print('profile', key, activeKey) | |
198 local profileList = profile[activeKey] | |
199 if profileList and #profileList >= 1 then | |
200 local classColor = profile.classColor or defaultClassColor | |
201 local isMine = (profile == self.profile) | |
202 for index, data in ipairs(profileList) do | |
203 data.classColor = classColor | |
204 data.profileKey = key | |
205 data.isMine = isMine | |
206 if handler.OnGetItem then | |
207 handler.OnGetItem(data) | |
208 end | |
209 tinsert(sortedItems, data) | |
210 end | |
211 end | |
212 end | |
213 | |
214 if handler.SortHandler then | |
215 sort(sortedItems, handler.SortHandler) | |
216 end | |
217 | |
218 end | |
219 handler.isStale = nil | |
220 local itemsHeight = handler:UpdateItems() | |
221 self.currentHeight = max(itemsHeight, self.currentHeight) | |
222 | |
223 end | |
224 | |
225 self.isStale = nil | |
226 self:Reanchor() | |
227 self:SetHeight(self.currentHeight + CP_HEADER_SIZE) | |
228 end | |
229 | |
230 | |
231 function ClassPlan:Toggle() | |
232 if self:IsShown() then | |
233 self:Hide() | |
234 else | |
235 self:Show() | |
236 end | |
237 | |
238 if self.data then | |
239 self.data.IsShown = self:IsShown() | |
240 end | |
241 end | |
242 | |
243 function ClassPlan:OnUpdate() | |
244 if self.isStale then | |
245 print('|cFFFF4400An illusion! What are you hiding?|r') | |
246 self:Update() | |
247 end | |
248 end | |
249 | |
250 function ClassPlan:OnShow() | |
251 print('|cFF00FFFFShow()') | |
252 if self.isStale then | |
253 self:Update() | |
254 end | |
255 self:Reanchor() | |
256 end | |
257 | |
258 function ClassPlan:OnHide() | |
259 print('|cFF00FFFFHide()') | |
260 end | |
261 | |
262 function ClassPlan:Reanchor() | |
263 self:ClearAllPoints() | |
264 self:SetPoint('CENTER', self.data.positionX, self.data.positionY) | |
265 | |
266 for index, frame in ipairs(self.Handlers) do | |
267 frame:Reanchor() | |
268 end | |
269 end | |
270 | |
271 function ClassPlan:OnDragStart() | |
272 self:StartMoving() | |
273 end | |
274 function ClassPlan:OnDragStop() | |
275 | |
276 self:StopMovingOrSizing() | |
277 local x,y = self:GetCenter() | |
278 if x and y then | |
279 x = (x - GetScreenWidth()/2) | |
280 y = (y - GetScreenHeight()/2) * -1 | |
281 self.data.positionX, self.data.positionY = x,y | |
282 print('saving positions:', x, y) | |
283 end | |
284 end | |
285 | |
286 function SharedHandlers:SetList(index) | |
287 if not index then | |
288 if self.currentListIndex == #self.listKey then | |
289 index = 1 | |
290 else | |
291 index = self.currentListIndex + 1 | |
292 end | |
293 end | |
294 | |
295 print('|cFF0088FF'..self:GetName()..'|r:SetList()', index) | |
296 self.currentListIndex = index | |
297 self.activeKey = self.listKey[index] | |
298 self.activeTitle = self.listTitle[index] | |
299 | |
300 self.isStale = true | |
301 end | |
302 | |
303 function SharedHandlers:RequestData() | |
304 print('|cFF0088FF'..self:GetName()..':RequestData()') | |
305 self.isStale = true | |
306 end | |
307 | |
308 function SharedHandlers:OnEvent(event, arg) | |
309 if (event == 'GARRISON_MISSION_LIST_UPDATE') and (arg ~= LE_FOLLOWER_TYPE_GARRISON_7_0) then | |
310 -- ignore non-OrderHall updates | |
71 return | 311 return |
72 end | 312 end |
313 print('|cFF00FF88'..self:GetName()..':OnEvent()|r', event, arg) | |
314 if self:IsVisible() then | |
315 print('|cFF88FF00 frame visible; get busy') | |
316 self:RequestData() | |
317 else | |
318 if not self.NextData then | |
319 print('|cFF88FF00 setting timer') | |
320 self.NextData = C_Timer.NewTimer(0.25, function() | |
321 if self.initialized then | |
322 self:RequestData() | |
323 self.NextData:Cancel() | |
324 self.NextData = nil | |
325 print('|cFF88FF00'..self:GetName()..' clearing timer') | |
326 end | |
327 | |
328 end) | |
329 end | |
330 end | |
331 end | |
332 function SharedHandlers:OnUpdate() | |
333 if self.isStale then | |
334 self:GetParent():Update() | |
335 end | |
336 end | |
337 | |
338 | |
339 -- Stuff set on every list item | |
340 function SharedHandlers:SetOwnerData (self, data) | |
341 local name, realm = string.match(data.profileKey, "(.+)%-(.+)") | |
342 local ownerText = '|c'.. data.classColor.colorStr .. name .. '|r' | |
343 self.Owner:SetText(ownerText) | |
344 self.Name:SetText(self.name) | |
345 self.Name:SetTextColor(data.classColor.r, data.classColor.g, data.classColor.b) | |
346 end | |
347 | |
348 function SharedHandlers:UpdateItems() | |
349 local sortedItems = self.sortedItems | |
350 | |
351 self.blocks = self.blocks or {} | |
352 local blocks = self.blocks | |
353 | |
354 local lastProfile | |
355 local numItems = #sortedItems | |
356 local totalHeight = 0 | |
357 self.lastBlock = nil | |
358 self.numActive = 0 | |
359 for i, data in ipairs(sortedItems) do | |
360 local block = blocks[i] | |
361 if not block then | |
362 block = CreateFrame('Button', nil, self, self.templateName) | |
363 block:SetID(i) | |
364 block.listType = self.activeKey | |
365 block.handler = self | |
366 self.numBlocks = self.numBlocks + 1 | |
367 blocks[i] = block | |
368 end | |
369 | |
370 print('RefreshItem', block) | |
371 self.numActive = self.numActive + 1 | |
372 | |
373 if self.lastBlock then | |
374 block:SetPoint('TOPLEFT', self.lastBlock, 'BOTTOMLEFT', 0, 0) | |
375 print('--', i, data.isComplete, data.missionEndTime, data.name) | |
376 else | |
377 block:SetPoint('TOPLEFT', 0, 0) | |
378 print('--top') | |
379 end | |
380 self.lastBlock = block | |
381 | |
382 totalHeight = totalHeight + block:GetHeight() | |
383 block.lastProfile = lastProfile | |
384 -- blot out arbitrary flags | |
385 block.offerEndTime = nil | |
386 block.missionEndTime = nil | |
387 block.creationTime = nil | |
388 block.duration = nil | |
389 block.throttle = 5 | |
390 | |
391 for k,v in pairs(data) do | |
392 if type(block[k]) ~= 'function' then | |
393 block[k] = v | |
394 end | |
395 end | |
396 | |
397 block:Update() | |
398 self:SetOwnerData(block, data) | |
399 | |
400 block:Show() | |
401 lastProfile = data.profileKey | |
402 end | |
403 | |
404 for i = numItems + 1, self.numBlocks do | |
405 if blocks[i] then | |
406 blocks[i]:Hide() | |
407 end | |
408 end | |
409 | |
410 self:Reanchor() | |
411 | |
412 return totalHeight | |
413 end | |
414 | |
415 | |
416 function ShipmentList:Reanchor() | |
417 print('|cFF00FFFF'..self:GetName()..':Reanchor|r') | |
418 self:SetPoint('TOPLEFT', 0, -24) | |
419 self:SetPoint('BOTTOMRIGHT', -ClassOrderPlan:GetWidth()/2, 0) | |
420 end | |
421 | |
422 function MissionList:Reanchor() | |
423 self:SetPoint('TOPRIGHT', 0, -24) | |
424 self:SetPoint('BOTTOMLEFT', ClassOrderPlan:GetWidth()/2, 0) | |
425 | |
426 self.ListTab:ClearAllPoints() | |
427 self.ListTab:SetPoint('TOPLEFT', self, 'TOPLEFT', 0, CP_HEADER_SIZE) | |
428 self.ListTab:SetPoint('BOTTOMRIGHT', self, 'TOPRIGHT', 0, 0) | |
429 self.ListTab.Label:SetText(self.listTitle[self.currentListIndex]) | |
430 self.ListTab:Show() | |
431 print(self.ListTab:GetSize()) | |
432 end | |
433 | |
434 function MissionList:GetPlayerData (profile) | |
435 wipe(profile.missions) | |
436 wipe(profile.available) | |
437 | |
438 local items = C_Garrison.GetAvailableMissions(GetPrimaryGarrisonFollowerType(LE_GARRISON_TYPE_7_0)); | |
439 for i = 1, #items do | |
440 if (not items[i].isBuilding and items[i].isZoneSupport) then | |
441 else | |
442 | |
443 tinsert(profile.available, items[i]) | |
444 end | |
445 end | |
446 | |
73 local items = C_Garrison.GetLandingPageItems(LE_GARRISON_TYPE_7_0) | 447 local items = C_Garrison.GetLandingPageItems(LE_GARRISON_TYPE_7_0) |
74 wipe(self.profile.missions) | |
75 for index, data in ipairs(items) do | 448 for index, data in ipairs(items) do |
76 print(' -',data.name, '|cFF00FF00'.. data.timeLeft .. '|r', date("%A %I:%m %p", data.missionEndTime)) | 449 print(' -',data.name, '|cFF00FF00'.. data.timeLeft .. '|r', date("%A %I:%m %p", data.missionEndTime)) |
77 tinsert(self.profile.missions, data) | 450 tinsert(profile.missions, data) |
78 end | 451 end |
79 ClassOrderPlan.isStale = true | 452 return true |
80 end | 453 end |
81 | 454 |
82 MissionsHandler.OnGetItem = function(data) | 455 do |
83 if data.missionEndTime < GI_currentTime then | 456 local ShipmentsInfo = {} |
457 local AddShipmentInfo = function(shipmentType, name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, itemName, itemIcon, itemQuality, itemID, followerID) | |
458 -- early login queries may return empty tables, causing the sorter to compare nil | |
459 if not creationTime then | |
460 return | |
461 end | |
462 --print(shipmentType, name, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString) | |
463 tinsert(ShipmentsInfo, | |
464 { | |
465 shipmentType = shipmentType, | |
466 name = name, | |
467 icon = texture, | |
468 shipmentCapacity = shipmentCapacity, | |
469 shipmentsReady = shipmentsReady, | |
470 shipmentsTotal = shipmentsTotal, | |
471 creationTime = creationTime, | |
472 duration = duration, | |
473 timeleftString = timeleftString, | |
474 itemName = itemName, | |
475 itemIcon = itemIcon, | |
476 itemQuality = itemQuality, | |
477 itemID = itemID, | |
478 followerID = followerID, | |
479 }) | |
480 end | |
481 function ShipmentList:GetPlayerData (profile) | |
482 if not profile then | |
483 return false | |
484 end | |
485 local profileList = profile.shipments | |
486 wipe(ShipmentsInfo) | |
487 | |
488 local garrisonType = LE_GARRISON_TYPE_7_0 | |
489 local buildings = CG_GetBuildings(garrisonType); | |
490 local shipmentIndex = 0 | |
491 --print('Buildings:') | |
492 for i = 1, #buildings do | |
493 local name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, itemName, itemIcon, itemQuality, itemID = CG_GetLandingPageShipmentInfo(buildingID); | |
494 AddShipmentInfo('Building', name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, itemName, itemIcon, itemQuality, itemID) | |
495 end | |
496 | |
497 --print('Follower:') | |
498 local followerShipments = CG_GetFollowerShipments(garrisonType); | |
499 for i = 1, #followerShipments do | |
500 local name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, _, _, _, _, followerID = CG_GetLandingPageShipmentInfoByContainerID(followerShipments[i]); | |
501 AddShipmentInfo('Follower', name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, nil, nil, nil, nil, followerID) | |
502 end | |
503 | |
504 --print('Loose:') | |
505 local looseShipments = CG_GetLooseShipments(garrisonType) | |
506 for i = 1, #looseShipments do | |
507 local name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString = CG_GetLandingPageShipmentInfoByContainerID(looseShipments[i]); | |
508 AddShipmentInfo('Misc', name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString) | |
509 end | |
510 | |
511 local talentTrees = CG_GetTalentTrees(garrisonType, select(3, UnitClass("player"))); | |
512 -- this is a talent that has completed, but has not been seen in the talent UI yet. | |
513 local completeTalentID = CG_GetCompleteTalent(garrisonType); | |
514 --print('Talents:') | |
515 if (talentTrees) then | |
516 for treeIndex, tree in ipairs(talentTrees) do | |
517 for talentIndex, talent in ipairs(tree) do | |
518 local showTalent = false; | |
519 if (talent.isBeingResearched) or (talent.id == completeTalentID) then | |
520 AddShipmentInfo('Talent', talent.name, talent.icon, 1, (talent.isBeingResearched and 0 or 1), 1, talent.researchStartTime, talent.researchDuration, talent.timeleftString) | |
521 end | |
522 end | |
523 end | |
524 end | |
525 | |
526 wipe(profileList) | |
527 for index, data in ipairs(ShipmentsInfo) do | |
528 --DEFAULT_CHAT_FRAME:AddMessage(data.shipmentType ..' '.. tostring(data.name) ..' '.. tostring(data.creationTime) ..' '.. tostring(data.duration)) | |
529 tinsert(profileList, data) | |
530 end | |
531 self.isStale = true | |
532 return true | |
533 end | |
534 end | |
535 MissionList.OnGetItem = function(data) | |
536 if data.missionEndTime and (data.missionEndTime < GI_currentTime) then | |
84 data.isComplete = true | 537 data.isComplete = true |
85 end | 538 end |
86 end | 539 end |
87 | 540 |
88 MissionsHandler.FreeBlock = function(self, block) | 541 MissionList.FreeBlock = function(self, block) |
89 end | 542 end |
90 | 543 |
91 MissionsHandler.SortHandler = function (a,b) | 544 MissionList.SortHandler = function (a,b) |
92 local result = false | 545 local result = false |
93 --if not a or not b then | 546 --if not a or not b then |
94 -- return true | 547 -- return true |
95 --else | 548 --else |
96 --if (a.isMine ~= b.isMine) then | 549 --if (a.isMine ~= b.isMine) then |
97 -- result = a.isMine | 550 -- result = a.isMine |
98 --else | 551 --else |
99 --if (not b.missionEndTime) or (not a.missionEndTime) then | 552 --if (not b.missionEndTime) or (not a.missionEndTime) then |
100 -- print('missing article', b.missionEndTime, a.missionEndTime) | 553 -- print('missing article', b.missionEndTime, a.missionEndTime) |
101 --end | 554 --end |
102 return ( b.missionEndTime > a.missionEndTime) | 555 if b.isComplete ~= a.isComplete then |
556 return a.isComplete | |
557 elseif b.isMine ~= a.isMine then | |
558 return a.isMine | |
559 elseif b.missionEndTime then | |
560 return ( b.missionEndTime > a.missionEndTime) | |
561 else | |
562 return ( b.offerEndTime > a.offerEndTime) | |
563 end | |
564 | |
103 --end | 565 --end |
104 --end | 566 --end |
105 end | 567 end |
106 | 568 |
107 ShipmentsHandler.OnGetItem = function(data) | 569 |
570 function MissionList:OnShow() | |
571 print('|cFF00FF88'..self:GetName()..':OnShow()|r') | |
572 end | |
573 | |
574 function ShipmentList:OnLoad() | |
575 C_Garrison.RequestLandingPageShipmentInfo(); | |
576 end | |
577 function ShipmentList:OnShow() | |
578 print('|cFF00FF88'..self:GetName()..':OnShow()|r') | |
579 C_Garrison.RequestLandingPageShipmentInfo() | |
580 end | |
581 | |
582 -- Update shipment flags data | |
583 local SetActualShipmentTime = function(self) | |
584 | |
585 if self.isComplete then | |
586 print('|cFF00FF88isComplete '..self.name..'|r') | |
587 return true | |
588 end | |
589 | |
590 local timestamp = time() | |
591 local timeLeft = self.creationTime + self.duration - timestamp | |
592 local justFinished = false | |
593 while (self.shipmentsReady < self.shipmentsTotal) and (timeLeft <= 0) do | |
594 if not self.originalReady then | |
595 self.originalReady = self.shipmentsReady | |
596 self.originalCreationTime = self.creationTime | |
597 end | |
598 | |
599 | |
600 self.shipmentsReady = self.shipmentsReady + 1 | |
601 self.creationTime = self.creationTime + self.duration | |
602 timeLeft = timeLeft + self.duration | |
603 print('|cFF00FF88udpating '..self.name..'|r', 'timeLeft:', timeLeft, 'shipments:', self.shipmentsReady, self.shipmentsTotal) | |
604 end | |
605 | |
606 if (timeLeft <= 0) and (not self.isBeingResearched) then | |
607 self.isComplete = true | |
608 self.isStale = true | |
609 end | |
610 | |
611 return timeLeft | |
612 end | |
613 | |
614 ShipmentList.OnGetItem = function(data) | |
615 print('OnGetItem()') | |
108 if data.shipmentsTotal then | 616 if data.shipmentsTotal then |
109 local timeLeft = data.creationTime + data.duration - GI_currentTime | 617 SetActualShipmentTime(data) |
110 if (timeLeft <= 0) and (data.shipmentsReady < data.shipmentsTotal) then | 618 end |
111 local numOrders = min(-1*floor(timeLeft/data.duration), (data.shipmentsTotal - data.shipmentsReady)) | 619 end |
112 | 620 |
113 if not data.originalCreationTime then | 621 ShipmentList.SortHandler = function(a, b) |
114 data.originalCreationTime = data.creationTime | |
115 data.originalShipmentsReady = data.shipmentsReady | |
116 end | |
117 | |
118 data.creationTime = data.creationTime + numOrders*data.duration | |
119 data.shipmentsReady = data.shipmentsReady + numOrders | |
120 print(data.profileKey, 'shipment "'.. data.name..'" reconciling', numOrders, 'lapsed orders. -->', data.creationTime, data.shipmentsReady) | |
121 end | |
122 end | |
123 end | |
124 | |
125 ShipmentsHandler.SortHandler = function(a, b) | |
126 if b.isComplete ~= a.isComplete then | 622 if b.isComplete ~= a.isComplete then |
127 return a.isComplete and true or false | 623 return a.isComplete and true or false |
128 elseif a.shipmentsReady or b.shipmentsReady then | 624 elseif a.shipmentsReady or b.shipmentsReady then |
129 return (a.shipmentsReady or 0) > (b.shipmentsReady or 0) | 625 return (a.shipmentsReady or 0) > (b.shipmentsReady or 0) |
130 else | 626 else |
131 return (a.creationTime) < (b.creationTime) | 627 return (a.creationTime) < (b.creationTime) |
132 end | 628 end |
133 end | 629 end |
134 | 630 |
135 local ShipmentsInfo = {} | 631 |
136 local AddShipmentInfo = function(shipmentType, name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, itemName, itemIcon, itemQuality, itemID, followerID) | 632 function MissionEntry:OnComplete() |
137 -- early login queries may return empty tables, causing the sorter to compare nil | 633 print('flagging complete', self.name) |
138 if not creationTime then | 634 self:Update() |
635 end | |
636 | |
637 function MissionEntry:OnUpdate(sinceLast) | |
638 self.throttle = (self.throttle or .5) + sinceLast | |
639 if self.throttle < .5 then | |
139 return | 640 return |
140 end | 641 else |
141 --print(shipmentType, name, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString) | |
142 tinsert(ShipmentsInfo, | |
143 { | |
144 shipmentType = shipmentType, | |
145 name = name, | |
146 icon = texture, | |
147 shipmentCapacity = shipmentCapacity, | |
148 shipmentsReady = shipmentsReady, | |
149 shipmentsTotal = shipmentsTotal, | |
150 creationTime = creationTime, | |
151 duration = duration, | |
152 timeleftString = timeleftString, | |
153 itemName = itemName, | |
154 itemIcon = itemIcon, | |
155 itemQuality = itemQuality, | |
156 itemID = itemID, | |
157 followerID = followerID, | |
158 }) | |
159 end | |
160 ShipmentsHandler.GetPlayerData = function (self) | |
161 if not self.profile then | |
162 return | |
163 end | |
164 wipe(ShipmentsInfo) | |
165 | |
166 local garrisonType = LE_GARRISON_TYPE_7_0 | |
167 local buildings = C_Garrison.GetBuildings(garrisonType); | |
168 local shipmentIndex = 0 | |
169 --print('Buildings:') | |
170 for i = 1, #buildings do | |
171 local name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, itemName, itemIcon, itemQuality, itemID = C_Garrison.GetLandingPageShipmentInfo(buildingID); | |
172 AddShipmentInfo('Building', name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, itemName, itemIcon, itemQuality, itemID) | |
173 end | |
174 | |
175 --print('Follower:') | |
176 local followerShipments = C_Garrison.GetFollowerShipments(garrisonType); | |
177 for i = 1, #followerShipments do | |
178 local name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, _, _, _, _, followerID = C_Garrison.GetLandingPageShipmentInfoByContainerID(followerShipments[i]); | |
179 AddShipmentInfo('Follower', name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, nil, nil, nil, nil, followerID) | |
180 end | |
181 | |
182 --print('Loose:') | |
183 local looseShipments = C_Garrison.GetLooseShipments(garrisonType) | |
184 for i = 1, #looseShipments do | |
185 local name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString = C_Garrison.GetLandingPageShipmentInfoByContainerID(looseShipments[i]); | |
186 AddShipmentInfo('Misc', name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString) | |
187 end | |
188 | |
189 local talentTrees = C_Garrison.GetTalentTrees(garrisonType, select(3, UnitClass("player"))); | |
190 -- this is a talent that has completed, but has not been seen in the talent UI yet. | |
191 local completeTalentID = C_Garrison.GetCompleteTalent(garrisonType); | |
192 --print('Talents:') | |
193 if (talentTrees) then | |
194 for treeIndex, tree in ipairs(talentTrees) do | |
195 for talentIndex, talent in ipairs(tree) do | |
196 local showTalent = false; | |
197 if (talent.isBeingResearched) or (talent.id == completeTalentID) then | |
198 AddShipmentInfo('Talent', talent.name, talent.icon, 1, (talent.isBeingResearched and 0 or 1), 1, talent.researchStartTime, talent.researchDuration, talent.timeleftString) | |
199 end | |
200 end | |
201 end | |
202 end | |
203 | |
204 self.profile.shipments = self.profile.shipments or {} | |
205 wipe(self.profile.shipments) | |
206 for index, data in ipairs(ShipmentsInfo) do | |
207 --DEFAULT_CHAT_FRAME:AddMessage(data.shipmentType ..' '.. tostring(data.name) ..' '.. tostring(data.creationTime) ..' '.. tostring(data.duration)) | |
208 tinsert(self.profile.shipments, data) | |
209 end | |
210 ClassOrderPlan.isStale = true | |
211 end | |
212 | |
213 function core:OnLoad () | |
214 self:RegisterEvent('PLAYER_LOGIN') | |
215 self:RegisterEvent('ADDON_LOADED') | |
216 self:RegisterEvent('PLAYER_REGEN_ENABLED') | |
217 self:RegisterEvent('PLAYER_REGEN_DISABLED') | |
218 -- Blizzard_GarrisonUI already fires a shipment data request for GARRISON_SHIPMENT_RECEIVED; this is unlikely to | |
219 self:AddHandler('missions', MissionsHandler) | |
220 self:AddHandler('shipments', ShipmentsHandler) | |
221 self:Reanchor() | |
222 C_Garrison.RequestLandingPageShipmentInfo(); | |
223 end | |
224 | |
225 local parentFrames = {'VeneerWorldState', 'OrderHallCommandBar'} | |
226 function core:Reanchor() | |
227 self:ClearAllPoints() | |
228 self.anchorParent = UIParent | |
229 local anchorTo = 'TOP' | |
230 for i, name in ipairs(parentFrames) do | |
231 local frame = _G[name] | |
232 if frame then | |
233 if not BOUND_FRAMES[frame] then | |
234 BOUND_FRAMES[frame] = {visible = (frame:IsVisible() and frame:IsShown())} | |
235 hooksecurefunc(frame, 'Show', function() | |
236 BOUND_FRAMES[frame].visible = true | |
237 print(frame:GetName(), 'Show', 'reanchor trigger') | |
238 self:Reanchor() | |
239 end) | |
240 hooksecurefunc(frame, 'Hide', function() | |
241 BOUND_FRAMES[frame].visible = nil | |
242 print(frame:GetName(), 'Hide', 'reanchor trigger') | |
243 self:Reanchor() | |
244 end) | |
245 end | |
246 print('f:', frame:GetName(), BOUND_FRAMES[frame].visible) | |
247 if BOUND_FRAMES[frame].visible then | |
248 self.anchorParent = frame | |
249 anchorTo = 'BOTTOM' | |
250 break | |
251 end | |
252 end | |
253 end | |
254 print('|cFFFF8800Using ' .. tostring(self.anchorParent:GetName()) .. '-'..anchorTo..' as anchor point') | |
255 | |
256 if self:IsShown() then | |
257 ClassPlanButton.Background:Show() | |
258 ClassPlanButton:SetWidth(600) | |
259 else | |
260 ClassPlanButton.Background:Hide() | |
261 ClassPlanButton:SetWidth(200) | |
262 end | |
263 | |
264 self:SetPoint('TOP', ClassPlanButton, 'BOTTOM', 0, 0) | |
265 ClassPlanButton:ClearAllPoints() | |
266 ClassPlanButton:SetPoint('TOP', self.anchorParent, anchorTo, 0, 0) | |
267 | |
268 print(ClassPlanButton:GetPoint(1)) | |
269 end | |
270 | |
271 function core:AddHandler(name, prototype) | |
272 self.prototypes[name] = setmetatable(prototype, { | |
273 __index = blockTemplate, | |
274 __tostring = function() return name end | |
275 }) | |
276 | |
277 for i, event in ipairs(prototype.events) do | |
278 if not self.events[event] then | |
279 self:RegisterEvent(event) | |
280 self.events[event] = {} | |
281 print('|cFF00FF00registering', event) | |
282 end | |
283 | |
284 prototype.numBlocks = 0 | |
285 if not self.events[event][name] then | |
286 print('adding', name, 'to', event) | |
287 self.events[event][name] = prototype.GetPlayerData | |
288 end | |
289 end | |
290 self.sortedItems[name] = {} | |
291 end | |
292 | |
293 function core:Setup() | |
294 if IsLoggedIn() then | |
295 WorldPlanData.OrderHall = WorldPlanData.OrderHall or {} | |
296 self.data = WorldPlanData.OrderHall | |
297 self.data.characters = self.data.characters or {} | |
298 | |
299 local name, realm = UnitName('player') | |
300 realm = realm or GetRealmName() | |
301 self.profileKey = name .. '-' .. realm | |
302 if not self.data.characters[self.profileKey] then | |
303 self.data.characters[self.profileKey] = {} | |
304 end | |
305 self.profile = self.data.characters[self.profileKey] | |
306 | |
307 self.profile.shipments = self.profile.shipments or {} | |
308 self.profile.missions = self.profile.missions or {} | |
309 self.profile.classColor = RAID_CLASS_COLORS[select(2, UnitClass('player'))] | |
310 | |
311 if self.data.IsShown then | |
312 self:Show() | |
313 end | |
314 self.initialized = true | |
315 self.isStale = true | |
316 end | |
317 end | |
318 | |
319 local last_invoc = {} | |
320 function core:OnEvent (event, ...) | |
321 print(event) | |
322 if event == 'PLAYER_REGEN_DISABLED' then | |
323 if self:IsVisible() then | |
324 self.combatHide = true | |
325 self:SetShown(false) | |
326 end | |
327 | |
328 elseif event == 'PLAYER_REGEN_ENABLED' then | |
329 if self.combatHide == true then | |
330 self.combatHide = nil | |
331 self:SetShown(true) | |
332 end | |
333 elseif event == 'PLAYER_LOGIN' then | |
334 if not self.initialized then | |
335 self:Setup() | |
336 end | |
337 elseif self.initialized and self.events[event] then | |
338 self.isStale = true | |
339 if self:IsVisible() then | |
340 | |
341 else | |
342 for handler, func in pairs(self.events[event]) do | |
343 if not self.Queued[handler] then | |
344 print('scheduling update for handler', handler) | |
345 self.Queued[handler] = C_Timer.NewTimer(0.25, function() | |
346 func(handler) | |
347 self.Queued[handler] = nil | |
348 end) | |
349 end | |
350 end | |
351 end | |
352 end | |
353 end | |
354 | |
355 function core:UpdateNotifications() | |
356 end | |
357 | |
358 | |
359 local SetOwnerData = function(self, data) | |
360 local name, realm = string.match(data.profileKey, "(.+)%-(.+)") | |
361 local ownerText = '|c'.. data.classColor.colorStr .. name .. '|r' | |
362 --if realm ~= GI_currentRealm then | |
363 --ownerText = ownerText .. ' (' .. realm .. ')' | |
364 --end | |
365 self.Owner:SetText(ownerText) | |
366 self.Name:SetTextColor(data.classColor.r, data.classColor.g, data.classColor.b) | |
367 end | |
368 | |
369 function core:RefreshItems(configKey, prototype) | |
370 local sortedItems = self.sortedItems[configKey] | |
371 | |
372 self.blocks[configKey] = self.blocks[configKey] or {} | |
373 local blocks = self.blocks[configKey] | |
374 | |
375 local lastProfile | |
376 local numItems = #sortedItems | |
377 local totalHeight = 0 | |
378 for i, data in ipairs(sortedItems) do | |
379 local block = blocks[i] | |
380 | |
381 if not block then | |
382 block = CreateFrame('Button', nil, self, prototype.templateName) | |
383 block:SetID(i) | |
384 block.handler = prototype | |
385 prototype.numBlocks = prototype.numBlocks + 1 | |
386 | |
387 if prototype.lastBlock then | |
388 block:SetPoint('TOPLEFT', prototype.lastBlock, 'BOTTOMLEFT', 0, 0) | |
389 else | |
390 block:SetPoint(prototype.point, self[prototype.parent] or self, prototype.relativePoint, 0, 0) | |
391 end | |
392 prototype.lastBlock = block | |
393 blocks[i] = block | |
394 end | |
395 | |
396 totalHeight = totalHeight + block:GetHeight() | |
397 block.lastProfile = lastProfile | |
398 for k,v in pairs(data) do | |
399 if type(block[k]) ~= 'function' then | |
400 block[k] = v | |
401 end | |
402 end | |
403 block:Refresh(data) | |
404 print(block.isComplete, block.missionEndTime, block.name) | |
405 SetOwnerData(block, data) | |
406 | |
407 block:Show() | |
408 lastProfile = data.profileKey | |
409 end | |
410 | |
411 for i = numItems + 1, prototype.numBlocks do | |
412 if blocks[i] then | |
413 blocks[i]:Hide() | |
414 end | |
415 end | |
416 | |
417 return totalHeight | |
418 end | |
419 | |
420 | |
421 local GI_profileKey, GI_profile, GI_isMine | |
422 local defaultClassColor = {r = 0.7, g = 0.7, b =0.7, colorStr = "ffffffff"} | |
423 local DoItemList = function (source, dest, onGetItem) | |
424 local numItems = 0 | |
425 for index, data in ipairs(source) do | |
426 data.classColor = GI_profile.classColor or defaultClassColor | |
427 data.profileKey = GI_profileKey | |
428 data.isMine = GI_isMine | |
429 if onGetItem then | |
430 onGetItem(data) | |
431 end | |
432 numItems = numItems + 1 | |
433 tinsert(dest, data) | |
434 end | |
435 return numItems | |
436 end | |
437 | |
438 local max = math.max | |
439 function core:Refresh() | |
440 print('|cFF00FFFFRefresh()|r') | |
441 self.currentHeight = 0 | |
442 for name, ptype in pairs(self.prototypes) do | |
443 print(' |cFF00FF00'..name..'|r') | |
444 if self.isStale then | |
445 ptype.GetPlayerData(self) | |
446 self.sortedItems[name] = self.sortedItems[name] or {} | |
447 | |
448 wipe(self.sortedItems[name]) | |
449 --print( 'object:', ptype) | |
450 for key, profile in pairs(self.data.characters) do | |
451 if profile[name] and #profile[name] >= 1 then | |
452 print(' ', #profile[name], key) | |
453 GI_profileKey = key | |
454 GI_profile = profile | |
455 GI_isMine = (profile == self.profile) | |
456 local results = DoItemList(profile[name], self.sortedItems[name], ptype.OnGetItem) | |
457 end | |
458 | |
459 end | |
460 | |
461 if ptype.SortHandler then | |
462 sort(self.sortedItems[name], ptype.SortHandler) | |
463 end | |
464 end | |
465 | |
466 local itemsHeight = self:RefreshItems(name, ptype) | |
467 self.currentHeight = max(itemsHeight, self.currentHeight) | |
468 end | |
469 | |
470 self:Reanchor() | |
471 self:SetHeight(self.currentHeight) | |
472 self.isStale = nil | |
473 end | |
474 | |
475 function core:Toggle() | |
476 if self:IsShown() then | |
477 self:Hide() | |
478 else | |
479 self:Show() | |
480 end | |
481 | |
482 if self.data then | |
483 self.data.IsShown = self:IsShown() | |
484 end | |
485 end | |
486 | |
487 function core:OnUpdate() | |
488 if self.isStale then | |
489 print('update requested internally') | |
490 self:Refresh() | |
491 end | |
492 end | |
493 | |
494 function core:OnShow() | |
495 print('|cFF00FFFFShow()') | |
496 if self.isStale then | |
497 print('on-show update') | |
498 self:Refresh() | |
499 end | |
500 ClassPlanButton.Background:Show() | |
501 ClassPlanButton.Grip:SetShown(true) | |
502 end | |
503 function core:OnHide() | |
504 print('|cFF00FFFFHide()') | |
505 ClassPlanButton.Background:Hide() | |
506 ClassPlanButton.Grip:SetShown(false) | |
507 end | |
508 | |
509 | |
510 function core:SortItems(ptype) | |
511 print('|cFF0088FFSortItems('..tostring(ptype)..')|r') | |
512 GI_currentTime = time() | |
513 | |
514 end | |
515 | |
516 function MissionsHandler:OnComplete() | |
517 print('flagging complete', self.name) | |
518 self:Refresh() | |
519 end | |
520 | |
521 function MissionsHandler:OnUpdate(sinceLast) | |
522 if self.isComplete then | |
523 return | |
524 end | |
525 self.throttle = (self.throttle or .5) + sinceLast | |
526 if self.throttle >= .5 then | |
527 self.throttle = self.throttle - .5 | 642 self.throttle = self.throttle - .5 |
528 else | 643 end |
529 return | 644 if self.offerEndTime then |
530 end | 645 local timeLeft = self.offerEndTime |
531 | 646 self.TimeLeft:SetText(GetTimeLeftString(timeLeft)) |
532 if self.missionEndTime then | 647 self.TimeLeft:SetTextColor(1,1,1) |
648 elseif self.missionEndTime then | |
649 | |
650 if self.isComplete then | |
651 return | |
652 end | |
533 local timeLeft = self.missionEndTime - time() | 653 local timeLeft = self.missionEndTime - time() |
534 if timeLeft < 0 then | 654 if timeLeft < 0 then |
535 self:OnComplete() | 655 self:OnComplete() |
536 else | 656 else |
537 self.TimeLeft:SetText(GetTimeLeftString(timeLeft)) | 657 self.TimeLeft:SetText(GetTimeLeftString(timeLeft)) |
555 r = 1-((progress-0.5)*2) | 675 r = 1-((progress-0.5)*2) |
556 else | 676 else |
557 g = min(progress * 2, 1) | 677 g = min(progress * 2, 1) |
558 r = 1 | 678 r = 1 |
559 end | 679 end |
560 self.ProgressBar:SetColorTexture(r,g,0,1) | 680 self.ProgressBar:SetColorTexture(r,g,0,.4) |
561 self.ProgressBG:SetColorTexture(r,g,0,0.125) | 681 self.ProgressBG:SetColorTexture(r,g,0,0.125) |
562 end | 682 end |
563 self.ProgressBG:Show() | 683 self.ProgressBG:Show() |
564 self.ProgressBar:Show() | 684 self.ProgressBar:Show() |
565 else | 685 else |
569 else | 689 else |
570 self.TimeLeft:SetText(self.missionEndTime) | 690 self.TimeLeft:SetText(self.missionEndTime) |
571 end | 691 end |
572 end | 692 end |
573 | 693 |
574 function MissionsHandler:Refresh() | 694 function MissionEntry:OnLoad() |
695 print('|cFFFF4400',self:GetName() or tostring(self), 'onload') | |
696 self.Count = self.Overlay.Count | |
697 self.Name = self.Overlay.Name | |
698 self.TimeLeft = self.Overlay.TimeLeft | |
699 self.Owner = self.Overlay.Owner | |
700 | |
701 self.Icon:SetDesaturated(false) | |
702 self.Done:Hide() | |
703 end | |
704 | |
705 function MissionEntry:Update() | |
575 local r,g,b = 1, 1, 1 | 706 local r,g,b = 1, 1, 1 |
576 if self.isRare then | 707 if self.isRare then |
577 r,g,b = 0.1, 0.4, 1 | 708 r,g,b = 0.1, 0.4, 1 |
578 self.IconBorder:SetVertexColor(r, g, b, 1) | 709 self.IconBorder:SetVertexColor(r, g, b, 1) |
579 end | 710 end |
585 self.rewardInfo = self.rewards[1] | 716 self.rewardInfo = self.rewards[1] |
586 else | 717 else |
587 self.Icon:SetAtlas(self.typeAtlas, false) | 718 self.Icon:SetAtlas(self.typeAtlas, false) |
588 end | 719 end |
589 | 720 |
590 if self.isComplete then | 721 |
591 self.Done:Show() | |
592 else | |
593 self.Done:Hide() | |
594 end | |
595 | 722 |
596 if self.isComplete then | 723 if self.isComplete then |
597 self.TimeLeft:SetText('Complete!') | 724 self.TimeLeft:SetText('Complete!') |
598 self.Background:SetColorTexture(.25,.25,.25,1) | 725 self.Background:SetColorTexture(.25,.25,.25,1) |
599 else | 726 else |
600 self.Background:SetColorTexture(0,0,0,0.5) | 727 self.Background:SetColorTexture(0,0,0,0.5) |
601 end | 728 end |
602 end | 729 end |
603 | 730 |
604 function MissionsHandler:OnEnter() | 731 function MissionEntry:OnEnter() |
605 if self.rewardInfo and self.rewardInfo.itemID then | 732 if self.rewardInfo and self.rewardInfo.itemID then |
606 GameTooltip:SetOwner(self, 'ANCHOR_LEFT') | 733 GameTooltip:SetOwner(self, 'ANCHOR_LEFT') |
607 GameTooltip:SetItemByID(self.rewardInfo.itemID) | 734 GameTooltip:SetItemByID(self.rewardInfo.itemID) |
608 GameTooltip:Show() | 735 GameTooltip:Show() |
609 end | 736 end |
610 end | 737 end |
611 | 738 |
612 function MissionsHandler:OnLeave() | 739 function MissionEntry:OnLeave() |
613 if GameTooltip:IsOwned(self) then | 740 if GameTooltip:IsOwned(self) then |
614 GameTooltip:Hide() | 741 GameTooltip:Hide() |
615 end | 742 end |
616 end | 743 end |
617 | 744 |
618 function ShipmentsHandler:Refresh() | 745 function ShipmentEntry:OnLoad() |
619 --[[ | 746 MissionEntry.OnLoad(self) |
620 self.icon = data.icon | 747 end |
621 self.shipmentCapacity = data.shipmentCapacity | 748 |
622 self.shipmentsReady = data.shipmentsReady | 749 |
623 self.shipmentsTotal = data.shipmentsTotal | 750 function ShipmentEntry:Update() |
624 self.creationTime = data.creationTime | 751 print('|cFF0088FF'.. self.name..'|r:Update()') |
625 self.duration = data.duration | |
626 self.itemID = data.itemID | |
627 self.itemQuality = data.itemQuality | |
628 icon = texture, | |
629 shipmentCapacity = shipmentCapacity, | |
630 shipmentsReady = shipmentsReady, | |
631 shipmentsTotal = shipmentsTotal, | |
632 creationTime = creationTime, | |
633 duration = duration, | |
634 timeleftString = timeleftString, | |
635 itemName = itemName, | |
636 itemIcon = itemIcon, | |
637 itemQuality = itemQuality, | |
638 itemID = itemID | |
639 | |
640 --]] | |
641 self.Icon:SetTexture(self.icon) | 752 self.Icon:SetTexture(self.icon) |
642 self.Name:SetText(self.name) | |
643 self.Count:SetText(self.shipmentsReady) | 753 self.Count:SetText(self.shipmentsReady) |
644 self.Done:SetShown(self.shipmentsReady and (self.shipmentsReady >= 1)) | 754 self.Done:SetShown(self.shipmentsReady and (self.shipmentsReady >= 1)) |
645 | 755 |
646 -- flag as complete | 756 -- flag as complete |
757 | |
758 local bgColor = CP_BACKGROUND_COLOR.inProgress | |
647 if ( self.shipmentsReady >= self.shipmentsTotal ) and (not self.isBeingResearched) then | 759 if ( self.shipmentsReady >= self.shipmentsTotal ) and (not self.isBeingResearched) then |
648 self.Swipe:SetCooldownUNIX(0, 0); | 760 self.Swipe:SetCooldownUNIX(0, 0); |
649 self.Done:Show(); | 761 self.Done:Show(); |
650 self.isComplete = true | 762 bgColor = CP_BACKGROUND_COLOR.complete |
651 else | 763 else |
764 if (self.shipmentsReady >= 1) and (self.shipmentsReady < self.shipmentsTotal) then | |
765 bgColor = CP_BACKGROUND_COLOR.shipmentsReady | |
766 end | |
652 self.Swipe:SetCooldownUNIX(self.creationTime or 0 , self.duration or 0); | 767 self.Swipe:SetCooldownUNIX(self.creationTime or 0 , self.duration or 0); |
653 end | 768 end |
654 | 769 self.Background:SetColorTexture(unpack(bgColor)) |
655 if self.isComplete then | 770 |
656 self.TimeLeft:SetText('Complete!') | 771 SetActualShipmentTime(self) |
657 self.Background:SetColorTexture(0.5,0.5,0.5) | 772 |
658 elseif (self.shipmentsReady and (self.shipmentsReady > 0)) then | 773 if self.originalReady then |
659 self.Background:SetColorTexture(0.5,0.5,0.5,.5) | 774 print('|cFF00FF88'..self.name..'|r', 'starting ready:', self.originalReady, 'starting time:', self.originalCreationTime) |
660 else | 775 end |
661 self.Background:SetColorTexture(0,0,0,0.5) | 776 end |
662 end | 777 |
663 end | 778 function ShipmentEntry:OnUpdate(sinceLast) |
664 | |
665 local time = time | |
666 function ShipmentsHandler:OnUpdate(sinceLast) | |
667 self.throttle = (self.throttle or 1) + sinceLast | 779 self.throttle = (self.throttle or 1) + sinceLast |
668 if self.throttle >= 1 then | 780 if self.throttle >= 1 then |
669 self.throttle = self.throttle - 1 | 781 self.throttle = self.throttle - 1 |
670 else | 782 else |
671 return | 783 return |
672 end | 784 end |
673 | 785 |
786 | |
674 if (self.shipmentsReady and self.shipmentsTotal) and (self.shipmentsReady < self.shipmentsTotal) then | 787 if (self.shipmentsReady and self.shipmentsTotal) and (self.shipmentsReady < self.shipmentsTotal) then |
675 local timeLeft = self.creationTime + self.duration - time() | 788 local timeLeft = SetActualShipmentTime(self) |
676 if self.shipmentsReady >= 1 then | 789 |
790 if self.isComplete then | |
791 self.TimeLeft:SetText('Complete!') | |
792 self.TimeLeft:SetTextColor(0,0.5,1) | |
793 elseif self.shipmentsReady >= 1 then | |
677 self.TimeLeft:SetText(GetTimeLeftString(timeLeft)) | 794 self.TimeLeft:SetText(GetTimeLeftString(timeLeft)) |
678 self.TimeLeft:SetTextColor(0,1,0) | 795 self.TimeLeft:SetTextColor(0,1,0) |
679 else | 796 else |
680 self.TimeLeft:SetText(GetTimeLeftString(timeLeft)) | 797 self.TimeLeft:SetText(GetTimeLeftString(timeLeft)) |
681 self.TimeLeft:SetTextColor(1,1,1) | 798 self.TimeLeft:SetTextColor(1,1,1) |
682 end | 799 end |
683 if (timeLeft < 0) then | 800 |
684 if self.shipmentsReady < self.shipmentsTotal then | |
685 self.shipmentsReady = self.shipmentsReady + 1 | |
686 self.creationTime = self.creationTime + self.duration | |
687 -- text will be set on next update | |
688 end | |
689 end | |
690 elseif self.isBeingResearched then | 801 elseif self.isBeingResearched then |
691 self.TimeLeft:SetText(GetTimeLeftString(self.researchStartTime + self.researchDuration - time())) | 802 self.TimeLeft:SetText(GetTimeLeftString(self.researchStartTime + self.researchDuration - time())) |
692 self.TimeLeft:SetTextColor(1,1,0) | 803 self.TimeLeft:SetTextColor(1,1,0) |
693 else | 804 else |
694 self.TimeLeft:SetText('Complete!') | 805 self.TimeLeft:SetText('Complete!') |
710 r = 1-((progress-0.5)*2) | 821 r = 1-((progress-0.5)*2) |
711 else | 822 else |
712 g = min(progress * 2, 1) | 823 g = min(progress * 2, 1) |
713 r = 1 | 824 r = 1 |
714 end | 825 end |
715 self.ProgressBar:SetColorTexture(r, g, 0, 1) | 826 self.ProgressBar:SetColorTexture(r, g, 0, .4) |
716 self.ProgressBG:SetColorTexture(r, g, 0, .125) | 827 self.ProgressBG:SetColorTexture(r, g, 0, .125) |
717 self.ProgressBG:Show() | 828 self.ProgressBG:Show() |
718 self.ProgressBar:Show() | 829 self.ProgressBar:Show() |
719 else | 830 else |
720 self.ProgressBG:Hide() | 831 self.ProgressBG:Hide() |
721 self.ProgressBar:Hide() | 832 self.ProgressBar:Hide() |
722 end | 833 end |
723 end | 834 end |
724 | 835 |
725 function ShipmentsHandler:OnEnter() | 836 function ShipmentEntry:OnEnter() |
726 if ( self.shipmentsReady and self.shipmentsTotal ) then | 837 if ( self.shipmentsReady and self.shipmentsTotal ) then |
727 GameTooltip:SetOwner(self, 'ANCHOR_LEFT') | 838 GameTooltip:SetOwner(self, 'ANCHOR_LEFT') |
728 GameTooltip:AddLine(self.Owner:GetText(), self.Owner:GetTextColor()) | 839 GameTooltip:AddLine(self.Owner:GetText(), self.Owner:GetTextColor()) |
729 GameTooltip:AddLine(self.shipmentType) | 840 GameTooltip:AddLine(self.shipmentType) |
730 GameTooltip:AddLine(self.shipmentsReady .. ' of '.. self.shipmentsTotal) | 841 GameTooltip:AddLine(self.shipmentsReady .. ' of '.. self.shipmentsTotal) |
731 GameTooltip:Show() | 842 GameTooltip:Show() |
732 end | 843 end |
733 end | 844 end |
734 | 845 |
735 function ShipmentsHandler:OnLeave() | 846 function ShipmentEntry:OnLeave() |
736 if GameTooltip:IsOwned(self) then | 847 if GameTooltip:IsOwned(self) then |
737 GameTooltip:Hide() | 848 GameTooltip:Hide() |
738 end | 849 end |
739 end | 850 end |
740 | 851 |
741 function ShipmentsHandler:OnClick(button) | 852 function ShipmentEntry:OnClick(button) |
742 if button == 'RightButton' then | 853 if button == 'RightButton' then |
743 self.handler:FreeBlock(self) | 854 self.handler:FreeBlock(self) |
744 end | 855 end |
745 end | 856 end |
857 | |
858 ClassPlanMissionHandler = Mixin(MissionList, SharedHandlers) | |
859 ClassPlanShipmentHandler = Mixin(ShipmentList, SharedHandlers) | |
860 ClassPlanMissionEntryMixin = Mixin(MissionEntry, SharedEntry) | |
861 ClassPlanShipmentEntryMixin = Mixin(ShipmentEntry,SharedEntry) | |
862 | |
863 ClassPlanHeaderMixin = { | |
864 OnClick = function(self) | |
865 self:GetParent():SetList() | |
866 self:GetParent().isStale = true | |
867 ClassOrderPlan:Update() | |
868 end | |
869 } |