Mercurial > wow > worldplan
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 |