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