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