Nenue@40
|
1 local _, db = ...
|
Nenue@40
|
2
|
Nenue@40
|
3 local wipe, tinsert, ipairs, select = table.wipe, table.insert, ipairs, select
|
Nenue@40
|
4 local UnitClass = UnitClass
|
Nenue@40
|
5 local time, max, min = time, max, min
|
Nenue@40
|
6 local print = DEVIAN_WORKSPACE and function(...) print('ClassPlan', ...) end or nop
|
Nenue@40
|
7
|
Nenue@40
|
8
|
Nenue@40
|
9 local CG_GetBuildings = C_Garrison.GetBuildings
|
Nenue@40
|
10 local CG_GetFollowerShipments = C_Garrison.GetFollowerShipments
|
Nenue@40
|
11 local CG_GetLooseShipments = C_Garrison.GetLooseShipments
|
Nenue@40
|
12 local CG_GetTalentTrees = C_Garrison.GetTalentTrees
|
Nenue@40
|
13 local CG_GetCompleteTalent = C_Garrison.GetCompleteTalent
|
Nenue@40
|
14 local CG_GetLandingPageShipmentInfo = C_Garrison.GetLandingPageShipmentInfo
|
Nenue@40
|
15 local CG_GetLandingPageShipmentInfoByContainerID = C_Garrison.GetLandingPageShipmentInfoByContainerID
|
Nenue@40
|
16
|
Nenue@40
|
17 local AK_NOTES, RECRUIT_MAJOR, RECRUIT_MINOR, OH_TALENT, NOMI = 2, 4, 8, 16, 32
|
Nenue@40
|
18
|
Nenue@40
|
19 local FollowerTypes = {
|
Nenue@40
|
20 ['Pathfinders'] = true,
|
Nenue@40
|
21 ['Acolytes'] = true,
|
Nenue@40
|
22 }
|
Nenue@40
|
23 local ShipmentOrder = {
|
Nenue@40
|
24 [AK_NOTES] = 2,
|
Nenue@40
|
25 [RECRUIT_MAJOR] = 3,
|
Nenue@40
|
26 [RECRUIT_MINOR] = 4,
|
Nenue@40
|
27 [NOMI] = 5,
|
Nenue@40
|
28 [OH_TALENT] = 6,
|
Nenue@40
|
29 }
|
Nenue@40
|
30 local SortKey = 'shipmentType'
|
Nenue@40
|
31 local SortTable = ShipmentOrder
|
Nenue@40
|
32
|
Nenue@40
|
33 local ShipmentList = {
|
Nenue@40
|
34 templateName = 'ClassPlanShipmentEntry',
|
Nenue@40
|
35 listKey = {'shipments'},
|
Nenue@40
|
36 listTitle = {'Work Orders'},
|
Nenue@40
|
37 events = {
|
Nenue@40
|
38 'GARRISON_MISSION_LIST_UPDATE',
|
Nenue@40
|
39 'GARRISON_LANDINGPAGE_SHIPMENTS',
|
Nenue@40
|
40 'GARRISON_TALENT_UPDATE',
|
Nenue@40
|
41 "GARRISON_TALENT_COMPLETE",
|
Nenue@40
|
42 "GARRISON_SHIPMENT_RECEIVED",
|
Nenue@40
|
43 'GARRISON_FOLLOWER_LIST_UPDATE',
|
Nenue@40
|
44 'SHIPMENT_CRAFTER_INFO',
|
Nenue@40
|
45 'ITEM_PUSH'},
|
Nenue@40
|
46 }
|
Nenue@40
|
47
|
Nenue@40
|
48 local ShipmentEntry = {}
|
Nenue@40
|
49
|
Nenue@40
|
50 function ShipmentList:Reanchor()
|
Nenue@40
|
51 print('|cFF00FFFF'..self:GetName()..':Reanchor|r')
|
Nenue@40
|
52 self:SetPoint('TOPLEFT', ClassOrderPlan.BackgroundInset, 'TOPLEFT')
|
Nenue@40
|
53 self:SetPoint('BOTTOMRIGHT', -ClassOrderPlan.BackgroundInset:GetWidth()/2, 0)
|
Nenue@40
|
54 end
|
Nenue@40
|
55
|
Nenue@40
|
56 do
|
Nenue@40
|
57 local ShipmentsInfo = {}
|
Nenue@40
|
58 local AddShipmentInfo = function(shipmentType, name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, itemName, itemIcon, itemQuality, itemID, followerID)
|
Nenue@40
|
59 -- early login queries may return empty tables, causing the sorter to compare nil
|
Nenue@40
|
60 if not creationTime then
|
Nenue@40
|
61 return
|
Nenue@40
|
62 end
|
Nenue@40
|
63 --print(shipmentType, name, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString)
|
Nenue@40
|
64 tinsert(ShipmentsInfo,
|
Nenue@40
|
65 {
|
Nenue@40
|
66 shipmentType = shipmentType,
|
Nenue@40
|
67 name = name,
|
Nenue@40
|
68 icon = texture,
|
Nenue@40
|
69 shipmentCapacity = shipmentCapacity,
|
Nenue@40
|
70 shipmentsReady = shipmentsReady,
|
Nenue@40
|
71 shipmentsTotal = shipmentsTotal,
|
Nenue@40
|
72 creationTime = creationTime,
|
Nenue@40
|
73 duration = duration,
|
Nenue@40
|
74 timeleftString = timeleftString,
|
Nenue@40
|
75 itemName = itemName,
|
Nenue@40
|
76 itemIcon = itemIcon,
|
Nenue@40
|
77 itemQuality = itemQuality,
|
Nenue@40
|
78 itemID = itemID,
|
Nenue@40
|
79 followerID = followerID,
|
Nenue@40
|
80 })
|
Nenue@40
|
81 print(' ', name, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration)
|
Nenue@40
|
82 end
|
Nenue@40
|
83 function ShipmentList:GetPlayerData ()
|
Nenue@40
|
84 local profileList = self:GetParent().profile.shipments
|
Nenue@40
|
85 wipe(ShipmentsInfo)
|
Nenue@40
|
86
|
Nenue@40
|
87 local garrisonType = LE_GARRISON_TYPE_7_0
|
Nenue@40
|
88 local buildings = CG_GetBuildings(garrisonType);
|
Nenue@40
|
89 local shipmentIndex = 0
|
Nenue@40
|
90 --print('Buildings:')
|
Nenue@40
|
91 for i = 1, #buildings do
|
Nenue@40
|
92 local name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, itemName, itemIcon, itemQuality, itemID = CG_GetLandingPageShipmentInfo(i);
|
Nenue@40
|
93 AddShipmentInfo(RECRUIT_MAJOR, name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, itemName, itemIcon, itemQuality, itemID)
|
Nenue@40
|
94 end
|
Nenue@40
|
95
|
Nenue@40
|
96 --print('Follower:')
|
Nenue@40
|
97 local followerShipments = CG_GetFollowerShipments(garrisonType);
|
Nenue@40
|
98 for i = 1, #followerShipments do
|
Nenue@40
|
99 local name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, _, _, _, _, followerID = CG_GetLandingPageShipmentInfoByContainerID(followerShipments[i]);
|
Nenue@40
|
100 AddShipmentInfo(RECRUIT_MINOR, name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, nil, nil, nil, nil, followerID)
|
Nenue@40
|
101 end
|
Nenue@40
|
102
|
Nenue@40
|
103 --print('Loose:')
|
Nenue@40
|
104 local looseShipments = CG_GetLooseShipments(garrisonType)
|
Nenue@40
|
105 for i = 1, #looseShipments do
|
Nenue@40
|
106 local name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString = CG_GetLandingPageShipmentInfoByContainerID(looseShipments[i]);
|
Nenue@40
|
107 AddShipmentInfo(AK_NOTES, name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString)
|
Nenue@40
|
108 end
|
Nenue@40
|
109
|
Nenue@102
|
110 local talentTrees = C_Garrison.GetTalentTreeIDsByClassID(garrisonType, select(3, UnitClass("player")));
|
Nenue@40
|
111 -- this is a talent that has completed, but has not been seen in the talent UI yet.
|
Nenue@40
|
112 local completeTalentID = CG_GetCompleteTalent(garrisonType);
|
Nenue@102
|
113 print('Talents:')
|
Nenue@40
|
114 if (talentTrees) then
|
Nenue@102
|
115 for treeIndex, treeID in ipairs(talentTrees) do
|
Nenue@102
|
116 local _, _, tree = C_Garrison.GetTalentTreeInfoForID(garrisonType, treeID);
|
Nenue@40
|
117 for talentIndex, talent in ipairs(tree) do
|
Nenue@40
|
118 local showTalent = false;
|
Nenue@40
|
119 if (talent.isBeingResearched) or (talent.id == completeTalentID) then
|
Nenue@40
|
120 AddShipmentInfo(OH_TALENT, talent.name, talent.icon, 1, (talent.isBeingResearched and 0 or 1), 1, talent.researchStartTime, talent.researchDuration, talent.timeleftString)
|
Nenue@40
|
121 end
|
Nenue@40
|
122 end
|
Nenue@40
|
123 end
|
Nenue@40
|
124 end
|
Nenue@40
|
125
|
Nenue@40
|
126 wipe(profileList)
|
Nenue@40
|
127 for index, data in ipairs(ShipmentsInfo) do
|
Nenue@40
|
128 --DEFAULT_CHAT_FRAME:AddMessage(data.shipmentType ..' '.. tostring(data.name) ..' '.. tostring(data.creationTime) ..' '.. tostring(data.duration))
|
Nenue@40
|
129 tinsert(profileList, data)
|
Nenue@40
|
130 end
|
Nenue@40
|
131 self.isStale = true
|
Nenue@40
|
132 return true
|
Nenue@40
|
133 end
|
Nenue@40
|
134 end
|
Nenue@40
|
135 -- Update shipment flags data
|
Nenue@40
|
136 local SetActualShipmentTime = function(self)
|
Nenue@40
|
137
|
Nenue@40
|
138 if self.isComplete then
|
Nenue@40
|
139 return nil, nil
|
Nenue@40
|
140 end
|
Nenue@40
|
141
|
Nenue@40
|
142 local timestamp = time()
|
Nenue@40
|
143 local timeLeft = self.creationTime + self.duration - timestamp
|
Nenue@40
|
144 local duration = self.duration * (self.fullDuration and (self.shipmentsTotal - self.shipmentsReady) or 1)
|
Nenue@40
|
145 local justFinished = false
|
Nenue@40
|
146 while (self.shipmentsReady < self.shipmentsTotal) and (timeLeft <= 0) do
|
Nenue@40
|
147 if not self.originalReady then
|
Nenue@40
|
148 self.originalReady = self.shipmentsReady
|
Nenue@40
|
149 self.originalCreationTime = self.creationTime
|
Nenue@40
|
150 end
|
Nenue@40
|
151
|
Nenue@40
|
152 self.shipmentsReady = self.shipmentsReady + 1
|
Nenue@40
|
153 self.creationTime = self.creationTime + self.duration
|
Nenue@40
|
154 timeLeft = timeLeft + self.duration
|
Nenue@40
|
155 print('|cFF00FF88 pre-parse "'..self.name..'"|r', 'timeLeft:', timeLeft, 'shipments:', self.shipmentsReady, self.shipmentsTotal)
|
Nenue@40
|
156 end
|
Nenue@40
|
157
|
Nenue@40
|
158 if (timeLeft <= 0) and (not self.isBeingResearched) then
|
Nenue@40
|
159 self.isComplete = true
|
Nenue@40
|
160 self.isStale = true
|
Nenue@40
|
161 end
|
Nenue@40
|
162
|
Nenue@40
|
163 local expires = (self.originalCreationTime or self.creationTime) + duration
|
Nenue@40
|
164 return expires, duration
|
Nenue@40
|
165 end
|
Nenue@40
|
166
|
Nenue@40
|
167 function ShipmentList:OnEvent(event, ...)
|
Nenue@40
|
168 if (event == 'SHIPMENT_CRAFTER_INFO' or event == 'ITEM_PUSH' or event == 'GARRISON_FOLLOWER_LIST_UPDATE') then
|
Nenue@40
|
169 C_Garrison.RequestLandingPageShipmentInfo()
|
Nenue@40
|
170 elseif event == 'SHIPMENT_UPDATE' then
|
Nenue@40
|
171 local shipmentStarted = ...
|
Nenue@40
|
172 if shipmentStarted then
|
Nenue@40
|
173 C_Garrison.RequestLandingPageShipmentInfo()
|
Nenue@40
|
174 end
|
Nenue@40
|
175 elseif event == 'GARRISON_LANDINGPAGE_SHIPMENTS' then
|
Nenue@40
|
176 --WorldPlan:print("New shipments data received.")
|
Nenue@40
|
177 self:RefreshData()
|
Nenue@40
|
178 else
|
Nenue@40
|
179 ClassPlanHandlerBase.OnEvent(self, event, ...)
|
Nenue@40
|
180 end
|
Nenue@40
|
181 end
|
Nenue@40
|
182
|
Nenue@40
|
183
|
Nenue@40
|
184 function ShipmentList:OnGetItem (data)
|
Nenue@40
|
185 if data.shipmentsTotal then
|
Nenue@40
|
186 local expires = SetActualShipmentTime(data)
|
Nenue@40
|
187 if expires and (expires > time()) then
|
Nenue@40
|
188 self:ScheduleUpdate(expires)
|
Nenue@40
|
189 end
|
Nenue@40
|
190 end
|
Nenue@40
|
191
|
Nenue@40
|
192 if data.shipmentType == 255 or type(data.shipmentType == 'string') then
|
Nenue@40
|
193 if data.name == 'Artifact Research Notes' then
|
Nenue@40
|
194 data.shipmentType = AK_NOTES
|
Nenue@40
|
195 elseif string.match(data.name, 'Recipes') then
|
Nenue@40
|
196 data.shipmentType = NOMI
|
Nenue@40
|
197 elseif FollowerTypes[data.name] then
|
Nenue@40
|
198 data.shipmentType = RECRUIT_MINOR
|
Nenue@40
|
199 else
|
Nenue@40
|
200 data.shipmentType = OH_TALENT
|
Nenue@40
|
201 end
|
Nenue@40
|
202 end
|
Nenue@40
|
203
|
Nenue@40
|
204
|
Nenue@40
|
205 end
|
Nenue@40
|
206
|
Nenue@40
|
207 function ShipmentList:OnHeaderClick()
|
Nenue@40
|
208 -- flip sort table and key, push a sort and refresh
|
Nenue@40
|
209 end
|
Nenue@40
|
210
|
Nenue@40
|
211
|
Nenue@40
|
212 ShipmentList.SortHandler = function(a, b)
|
Nenue@95
|
213 local status = false
|
Nenue@95
|
214 if b.isComplete ~= a.isComplete then
|
Nenue@95
|
215 if a.isComplete then
|
Nenue@95
|
216 status = true
|
Nenue@40
|
217 end
|
Nenue@40
|
218 else
|
Nenue@95
|
219 if a[SortKey] then
|
Nenue@95
|
220 if b[SortKey] then
|
Nenue@95
|
221 status = (SortTable[a[SortKey]] < SortTable[b[SortKey]])
|
Nenue@95
|
222 else
|
Nenue@95
|
223 status = true
|
Nenue@95
|
224 end
|
Nenue@40
|
225 else
|
Nenue@40
|
226 if a.profileKey ~= b.profileKey then
|
Nenue@95
|
227 status = (a.profileKey < b.profileKey)
|
Nenue@95
|
228
|
Nenue@40
|
229 else
|
Nenue@40
|
230 if a.shipmentsReady and b.shipmentsReady then
|
Nenue@95
|
231 status = (a.shipmentsReady) > (b.shipmentsReady)
|
Nenue@40
|
232 elseif a.shipmentsReady or b.shipmentsReady then
|
Nenue@95
|
233 status = (a.shipmentsReady) or true or false
|
Nenue@40
|
234 else
|
Nenue@40
|
235
|
Nenue@40
|
236 if (a.creationTime ~= b.creationTime) then
|
Nenue@95
|
237 status = (a.creationTime) < (b.creationTime)
|
Nenue@40
|
238 else
|
Nenue@95
|
239 status = (a.name) < (b.name)
|
Nenue@40
|
240 end
|
Nenue@40
|
241 end
|
Nenue@40
|
242
|
Nenue@40
|
243 end
|
Nenue@40
|
244 end
|
Nenue@40
|
245 end
|
Nenue@95
|
246 return status
|
Nenue@40
|
247 end
|
Nenue@40
|
248
|
Nenue@40
|
249 function ShipmentList:OnShow()
|
Nenue@40
|
250 print('|cFF00FF88'..self:GetName()..':OnShow()|r')
|
Nenue@40
|
251 end
|
Nenue@40
|
252
|
Nenue@40
|
253 function ShipmentEntry:OnLoad()
|
Nenue@40
|
254 ClassPlanMissionEntryMixin.OnLoad(self)
|
Nenue@40
|
255 end
|
Nenue@40
|
256
|
Nenue@40
|
257
|
Nenue@40
|
258 function ShipmentEntry:Update()
|
Nenue@40
|
259 --print(' |cFF00FF88"'.. self.name..'":Update()|r')
|
Nenue@40
|
260 self.Icon:SetTexture(self.icon)
|
Nenue@40
|
261 self.Count:SetText(self.shipmentsReady ..'/'.. self.shipmentsTotal)
|
Nenue@40
|
262
|
Nenue@40
|
263 -- flag as complete
|
Nenue@40
|
264 local itemType = db.ClassPlanTypes.inProgress
|
Nenue@40
|
265 if ( self.shipmentsReady >= self.shipmentsTotal ) and (not self.isBeingResearched) then
|
Nenue@40
|
266 self.Swipe:SetCooldownUNIX(0, 0);
|
Nenue@40
|
267 itemType = db.ClassPlanTypes.complete
|
Nenue@40
|
268 else
|
Nenue@40
|
269 if (self.shipmentsReady >= 1) and (self.shipmentsReady < self.shipmentsTotal) then
|
Nenue@40
|
270 itemType = db.ClassPlanTypes.shipmentsReady
|
Nenue@40
|
271 end
|
Nenue@40
|
272 self.Swipe:SetCooldownUNIX(self.creationTime or 0 , self.duration or 0);
|
Nenue@40
|
273 end
|
Nenue@40
|
274 self.Background:SetColorTexture(unpack(itemType.backgroundColor))
|
Nenue@40
|
275
|
Nenue@40
|
276 SetActualShipmentTime(self)
|
Nenue@40
|
277 self.throttle = 2
|
Nenue@40
|
278 end
|
Nenue@40
|
279
|
Nenue@40
|
280
|
Nenue@40
|
281
|
Nenue@40
|
282 function ShipmentEntry:OnUpdate(sinceLast)
|
Nenue@40
|
283 self.throttle = (self.throttle or 1) + sinceLast
|
Nenue@40
|
284 if self.throttle >= 1 then
|
Nenue@40
|
285 self.throttle = self.throttle - 1
|
Nenue@40
|
286 else
|
Nenue@40
|
287 return
|
Nenue@40
|
288 end
|
Nenue@40
|
289
|
Nenue@40
|
290 if (self.shipmentsReady and self.shipmentsTotal) and (self.shipmentsReady < self.shipmentsTotal) then
|
Nenue@40
|
291 local expires, duration = SetActualShipmentTime(self)
|
Nenue@40
|
292 if self.isComplete then
|
Nenue@40
|
293 self.TimeLeft:SetText('Complete!')
|
Nenue@40
|
294 self.TimeLeft:SetTextColor(0,1,1)
|
Nenue@40
|
295 elseif self.shipmentsReady >= 1 then
|
Nenue@40
|
296 self:SetTimeLeft(expires, duration)
|
Nenue@40
|
297 self.TimeLeft:SetTextColor(1,1,0)
|
Nenue@40
|
298 else
|
Nenue@40
|
299 self:SetTimeLeft(expires, duration)
|
Nenue@40
|
300 self.TimeLeft:SetTextColor(1,1,1)
|
Nenue@40
|
301 end
|
Nenue@40
|
302 elseif self.isBeingResearched then
|
Nenue@40
|
303 self:SetTimeLeft(self.researchStartTime + self.researchDuration - time(), self.researchDuration)
|
Nenue@40
|
304 self.TimeLeft:SetTextColor(1,1,1)
|
Nenue@40
|
305 else
|
Nenue@40
|
306 self.TimeLeft:SetText('Complete!')
|
Nenue@40
|
307 self.TimeLeft:SetTextColor(0,1,0)
|
Nenue@40
|
308 end
|
Nenue@40
|
309 end
|
Nenue@40
|
310
|
Nenue@40
|
311 function ShipmentEntry:OnEnter()
|
Nenue@40
|
312 if ( self.shipmentsReady and self.shipmentsTotal ) then
|
Nenue@40
|
313 GameTooltip:SetOwner(self, 'ANCHOR_LEFT')
|
Nenue@40
|
314 GameTooltip:AddLine(self.Owner:GetText(), self.Owner:GetTextColor())
|
Nenue@40
|
315 GameTooltip:AddLine(self.shipmentsReady .. ' of '.. self.shipmentsTotal)
|
Nenue@40
|
316 GameTooltip:Show()
|
Nenue@40
|
317 end
|
Nenue@40
|
318 end
|
Nenue@40
|
319
|
Nenue@40
|
320
|
Nenue@40
|
321 function ShipmentEntry:OnLeave()
|
Nenue@40
|
322 if GameTooltip:IsOwned(self) then
|
Nenue@40
|
323 GameTooltip:Hide()
|
Nenue@40
|
324 end
|
Nenue@40
|
325 end
|
Nenue@40
|
326
|
Nenue@40
|
327 function ShipmentEntry:OnClick(button)
|
Nenue@40
|
328 self.fullDuration = not self.fullDuration
|
Nenue@40
|
329 self:Update()
|
Nenue@40
|
330 end
|
Nenue@40
|
331
|
Nenue@40
|
332 ClassPlanShipmentHandler = CreateFromMixins(ClassPlanHandlerBase, ShipmentList)
|
Nenue@40
|
333 ClassPlanShipmentEntryMixin = CreateFromMixins(ClassPlanEntryBase, ShipmentEntry) |