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@109
|
110
|
Nenue@109
|
111 local talentTrees = C_Garrison.GetTalentTreeIDsByClassID(garrisonType, select(3, UnitClass("player")));
|
Nenue@40
|
112 -- this is a talent that has completed, but has not been seen in the talent UI yet.
|
Nenue@40
|
113 local completeTalentID = CG_GetCompleteTalent(garrisonType);
|
Nenue@109
|
114 print('Talents:')
|
Nenue@40
|
115 if (talentTrees) then
|
Nenue@109
|
116 for treeIndex, treeID in ipairs(talentTrees) do
|
Nenue@111
|
117 local _, _, tree = C_Garrison.GetTalentTreeInfoForID(treeID);
|
Nenue@40
|
118 for talentIndex, talent in ipairs(tree) do
|
Nenue@40
|
119 local showTalent = false;
|
Nenue@40
|
120 if (talent.isBeingResearched) or (talent.id == completeTalentID) then
|
Nenue@40
|
121 AddShipmentInfo(OH_TALENT, talent.name, talent.icon, 1, (talent.isBeingResearched and 0 or 1), 1, talent.researchStartTime, talent.researchDuration, talent.timeleftString)
|
Nenue@40
|
122 end
|
Nenue@40
|
123 end
|
Nenue@40
|
124 end
|
Nenue@40
|
125 end
|
Nenue@40
|
126
|
Nenue@40
|
127 wipe(profileList)
|
Nenue@40
|
128 for index, data in ipairs(ShipmentsInfo) do
|
Nenue@40
|
129 --DEFAULT_CHAT_FRAME:AddMessage(data.shipmentType ..' '.. tostring(data.name) ..' '.. tostring(data.creationTime) ..' '.. tostring(data.duration))
|
Nenue@40
|
130 tinsert(profileList, data)
|
Nenue@40
|
131 end
|
Nenue@40
|
132 self.isStale = true
|
Nenue@40
|
133 return true
|
Nenue@40
|
134 end
|
Nenue@40
|
135 end
|
Nenue@40
|
136 -- Update shipment flags data
|
Nenue@40
|
137 local SetActualShipmentTime = function(self)
|
Nenue@40
|
138
|
Nenue@40
|
139 if self.isComplete then
|
Nenue@40
|
140 return nil, nil
|
Nenue@40
|
141 end
|
Nenue@40
|
142
|
Nenue@40
|
143 local timestamp = time()
|
Nenue@40
|
144 local timeLeft = self.creationTime + self.duration - timestamp
|
Nenue@40
|
145 local duration = self.duration * (self.fullDuration and (self.shipmentsTotal - self.shipmentsReady) or 1)
|
Nenue@40
|
146 local justFinished = false
|
Nenue@40
|
147 while (self.shipmentsReady < self.shipmentsTotal) and (timeLeft <= 0) do
|
Nenue@40
|
148 if not self.originalReady then
|
Nenue@40
|
149 self.originalReady = self.shipmentsReady
|
Nenue@40
|
150 self.originalCreationTime = self.creationTime
|
Nenue@40
|
151 end
|
Nenue@40
|
152
|
Nenue@40
|
153 self.shipmentsReady = self.shipmentsReady + 1
|
Nenue@40
|
154 self.creationTime = self.creationTime + self.duration
|
Nenue@40
|
155 timeLeft = timeLeft + self.duration
|
Nenue@40
|
156 print('|cFF00FF88 pre-parse "'..self.name..'"|r', 'timeLeft:', timeLeft, 'shipments:', self.shipmentsReady, self.shipmentsTotal)
|
Nenue@40
|
157 end
|
Nenue@40
|
158
|
Nenue@40
|
159 if (timeLeft <= 0) and (not self.isBeingResearched) then
|
Nenue@40
|
160 self.isComplete = true
|
Nenue@40
|
161 self.isStale = true
|
Nenue@40
|
162 end
|
Nenue@40
|
163
|
Nenue@40
|
164 local expires = (self.originalCreationTime or self.creationTime) + duration
|
Nenue@40
|
165 return expires, duration
|
Nenue@40
|
166 end
|
Nenue@40
|
167
|
Nenue@40
|
168 function ShipmentList:OnEvent(event, ...)
|
Nenue@40
|
169 if (event == 'SHIPMENT_CRAFTER_INFO' or event == 'ITEM_PUSH' or event == 'GARRISON_FOLLOWER_LIST_UPDATE') then
|
Nenue@40
|
170 C_Garrison.RequestLandingPageShipmentInfo()
|
Nenue@40
|
171 elseif event == 'SHIPMENT_UPDATE' then
|
Nenue@40
|
172 local shipmentStarted = ...
|
Nenue@40
|
173 if shipmentStarted then
|
Nenue@40
|
174 C_Garrison.RequestLandingPageShipmentInfo()
|
Nenue@40
|
175 end
|
Nenue@40
|
176 elseif event == 'GARRISON_LANDINGPAGE_SHIPMENTS' then
|
Nenue@40
|
177 --WorldPlan:print("New shipments data received.")
|
Nenue@40
|
178 self:RefreshData()
|
Nenue@40
|
179 else
|
Nenue@40
|
180 ClassPlanHandlerBase.OnEvent(self, event, ...)
|
Nenue@40
|
181 end
|
Nenue@40
|
182 end
|
Nenue@40
|
183
|
Nenue@40
|
184
|
Nenue@40
|
185 function ShipmentList:OnGetItem (data)
|
Nenue@40
|
186 if data.shipmentsTotal then
|
Nenue@40
|
187 local expires = SetActualShipmentTime(data)
|
Nenue@40
|
188 if expires and (expires > time()) then
|
Nenue@40
|
189 self:ScheduleUpdate(expires)
|
Nenue@40
|
190 end
|
Nenue@40
|
191 end
|
Nenue@40
|
192
|
Nenue@40
|
193 if data.shipmentType == 255 or type(data.shipmentType == 'string') then
|
Nenue@40
|
194 if data.name == 'Artifact Research Notes' then
|
Nenue@40
|
195 data.shipmentType = AK_NOTES
|
Nenue@40
|
196 elseif string.match(data.name, 'Recipes') then
|
Nenue@40
|
197 data.shipmentType = NOMI
|
Nenue@40
|
198 elseif FollowerTypes[data.name] then
|
Nenue@40
|
199 data.shipmentType = RECRUIT_MINOR
|
Nenue@40
|
200 else
|
Nenue@40
|
201 data.shipmentType = OH_TALENT
|
Nenue@40
|
202 end
|
Nenue@40
|
203 end
|
Nenue@40
|
204
|
Nenue@40
|
205
|
Nenue@40
|
206 end
|
Nenue@40
|
207
|
Nenue@40
|
208 function ShipmentList:OnHeaderClick()
|
Nenue@40
|
209 -- flip sort table and key, push a sort and refresh
|
Nenue@40
|
210 end
|
Nenue@40
|
211
|
Nenue@40
|
212
|
Nenue@40
|
213 ShipmentList.SortHandler = function(a, b)
|
Nenue@95
|
214 local status = false
|
Nenue@107
|
215 if b.isComplete ~= a.isComplete then
|
Nenue@107
|
216 if a.isComplete then
|
Nenue@107
|
217 status = true
|
Nenue@107
|
218 end
|
Nenue@107
|
219 else
|
Nenue@107
|
220 if a[SortKey] then
|
Nenue@107
|
221 if b[SortKey] then
|
Nenue@107
|
222 status = (SortTable[a[SortKey]] < SortTable[b[SortKey]])
|
Nenue@107
|
223 else
|
Nenue@95
|
224 status = true
|
Nenue@95
|
225 end
|
Nenue@40
|
226 else
|
Nenue@40
|
227 if a.profileKey ~= b.profileKey then
|
Nenue@95
|
228 status = (a.profileKey < b.profileKey)
|
Nenue@95
|
229
|
Nenue@40
|
230 else
|
Nenue@40
|
231 if a.shipmentsReady and b.shipmentsReady then
|
Nenue@95
|
232 status = (a.shipmentsReady) > (b.shipmentsReady)
|
Nenue@40
|
233 elseif a.shipmentsReady or b.shipmentsReady then
|
Nenue@95
|
234 status = (a.shipmentsReady) or true or false
|
Nenue@40
|
235 else
|
Nenue@40
|
236
|
Nenue@40
|
237 if (a.creationTime ~= b.creationTime) then
|
Nenue@95
|
238 status = (a.creationTime) < (b.creationTime)
|
Nenue@40
|
239 else
|
Nenue@95
|
240 status = (a.name) < (b.name)
|
Nenue@40
|
241 end
|
Nenue@40
|
242 end
|
Nenue@40
|
243
|
Nenue@40
|
244 end
|
Nenue@40
|
245 end
|
Nenue@40
|
246 end
|
Nenue@95
|
247 return status
|
Nenue@40
|
248 end
|
Nenue@40
|
249
|
Nenue@40
|
250 function ShipmentList:OnShow()
|
Nenue@40
|
251 print('|cFF00FF88'..self:GetName()..':OnShow()|r')
|
Nenue@40
|
252 end
|
Nenue@40
|
253
|
Nenue@40
|
254 function ShipmentEntry:OnLoad()
|
Nenue@40
|
255 ClassPlanMissionEntryMixin.OnLoad(self)
|
Nenue@40
|
256 end
|
Nenue@40
|
257
|
Nenue@40
|
258
|
Nenue@40
|
259 function ShipmentEntry:Update()
|
Nenue@40
|
260 --print(' |cFF00FF88"'.. self.name..'":Update()|r')
|
Nenue@40
|
261 self.Icon:SetTexture(self.icon)
|
Nenue@40
|
262 self.Count:SetText(self.shipmentsReady ..'/'.. self.shipmentsTotal)
|
Nenue@40
|
263
|
Nenue@40
|
264 -- flag as complete
|
Nenue@40
|
265 local itemType = db.ClassPlanTypes.inProgress
|
Nenue@40
|
266 if ( self.shipmentsReady >= self.shipmentsTotal ) and (not self.isBeingResearched) then
|
Nenue@40
|
267 self.Swipe:SetCooldownUNIX(0, 0);
|
Nenue@40
|
268 itemType = db.ClassPlanTypes.complete
|
Nenue@40
|
269 else
|
Nenue@40
|
270 if (self.shipmentsReady >= 1) and (self.shipmentsReady < self.shipmentsTotal) then
|
Nenue@40
|
271 itemType = db.ClassPlanTypes.shipmentsReady
|
Nenue@40
|
272 end
|
Nenue@40
|
273 self.Swipe:SetCooldownUNIX(self.creationTime or 0 , self.duration or 0);
|
Nenue@40
|
274 end
|
Nenue@40
|
275 self.Background:SetColorTexture(unpack(itemType.backgroundColor))
|
Nenue@40
|
276
|
Nenue@40
|
277 SetActualShipmentTime(self)
|
Nenue@40
|
278 self.throttle = 2
|
Nenue@40
|
279 end
|
Nenue@40
|
280
|
Nenue@40
|
281
|
Nenue@40
|
282
|
Nenue@40
|
283 function ShipmentEntry:OnUpdate(sinceLast)
|
Nenue@40
|
284 self.throttle = (self.throttle or 1) + sinceLast
|
Nenue@40
|
285 if self.throttle >= 1 then
|
Nenue@40
|
286 self.throttle = self.throttle - 1
|
Nenue@40
|
287 else
|
Nenue@40
|
288 return
|
Nenue@40
|
289 end
|
Nenue@40
|
290
|
Nenue@40
|
291 if (self.shipmentsReady and self.shipmentsTotal) and (self.shipmentsReady < self.shipmentsTotal) then
|
Nenue@40
|
292 local expires, duration = SetActualShipmentTime(self)
|
Nenue@40
|
293 if self.isComplete then
|
Nenue@40
|
294 self.TimeLeft:SetText('Complete!')
|
Nenue@40
|
295 self.TimeLeft:SetTextColor(0,1,1)
|
Nenue@40
|
296 elseif self.shipmentsReady >= 1 then
|
Nenue@40
|
297 self:SetTimeLeft(expires, duration)
|
Nenue@40
|
298 self.TimeLeft:SetTextColor(1,1,0)
|
Nenue@40
|
299 else
|
Nenue@40
|
300 self:SetTimeLeft(expires, duration)
|
Nenue@40
|
301 self.TimeLeft:SetTextColor(1,1,1)
|
Nenue@40
|
302 end
|
Nenue@40
|
303 elseif self.isBeingResearched then
|
Nenue@40
|
304 self:SetTimeLeft(self.researchStartTime + self.researchDuration - time(), self.researchDuration)
|
Nenue@40
|
305 self.TimeLeft:SetTextColor(1,1,1)
|
Nenue@40
|
306 else
|
Nenue@40
|
307 self.TimeLeft:SetText('Complete!')
|
Nenue@40
|
308 self.TimeLeft:SetTextColor(0,1,0)
|
Nenue@40
|
309 end
|
Nenue@40
|
310 end
|
Nenue@40
|
311
|
Nenue@40
|
312 function ShipmentEntry:OnEnter()
|
Nenue@40
|
313 if ( self.shipmentsReady and self.shipmentsTotal ) then
|
Nenue@40
|
314 GameTooltip:SetOwner(self, 'ANCHOR_LEFT')
|
Nenue@40
|
315 GameTooltip:AddLine(self.Owner:GetText(), self.Owner:GetTextColor())
|
Nenue@40
|
316 GameTooltip:AddLine(self.shipmentsReady .. ' of '.. self.shipmentsTotal)
|
Nenue@40
|
317 GameTooltip:Show()
|
Nenue@40
|
318 end
|
Nenue@40
|
319 end
|
Nenue@40
|
320
|
Nenue@40
|
321
|
Nenue@40
|
322 function ShipmentEntry:OnLeave()
|
Nenue@40
|
323 if GameTooltip:IsOwned(self) then
|
Nenue@40
|
324 GameTooltip:Hide()
|
Nenue@40
|
325 end
|
Nenue@40
|
326 end
|
Nenue@40
|
327
|
Nenue@40
|
328 function ShipmentEntry:OnClick(button)
|
Nenue@40
|
329 self.fullDuration = not self.fullDuration
|
Nenue@40
|
330 self:Update()
|
Nenue@40
|
331 end
|
Nenue@40
|
332
|
Nenue@40
|
333 ClassPlanShipmentHandler = CreateFromMixins(ClassPlanHandlerBase, ShipmentList)
|
Nenue@40
|
334 ClassPlanShipmentEntryMixin = CreateFromMixins(ClassPlanEntryBase, ShipmentEntry) |