annotate ClassPlan.lua @ 34:0100d923d8c3

WorldPlan: - Reward filter toggle changed to clear out other reward filters. The assumption being that one is most often looking only for that particular type of quest when they go to use it. - Fixed filter bar info falling out of sync after player-triggered world map updates. - Code stuff: -- Quest pin shown-state management makes better use of OnShow OnHide handlers, SetShown is toggled and it all goes from there -- WorldQuests module re-factored outside of the top level frame script. ClassPlan: - Available missions are now recorded; the mission list can be toggled between in-progress and available by clicking the heading.
author Nenue
date Wed, 02 Nov 2016 19:04:47 -0400
parents e8679ecb48d8
children 26dfa661daa7
rev   line source
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@32 4 local max, min = math.max, math.min
Nenue@2 5 local GetTime = GetTime
Nenue@3 6 local GI_currentTime = time()
Nenue@32 7 local print = DEVIAN_WORKSPACE and function(...) print('ClassPlan', ...) end or nop
Nenue@3 8
Nenue@32 9 local CG_GetBuildings = C_Garrison.GetBuildings
Nenue@32 10 local CG_GetFollowerShipments = C_Garrison.GetFollowerShipments
Nenue@32 11 local CG_GetLooseShipments = C_Garrison.GetLooseShipments
Nenue@32 12 local CG_GetTalentTrees = C_Garrison.GetTalentTrees
Nenue@32 13 local CG_GetCompleteTalent = C_Garrison.GetCompleteTalent
Nenue@32 14 local CG_GetLandingPageShipmentInfo = C_Garrison.GetLandingPageShipmentInfo
Nenue@32 15 local CG_GetLandingPageShipmentInfoByContainerID = C_Garrison.GetLandingPageShipmentInfoByContainerID
Nenue@32 16
Nenue@32 17 local CP_REPLACE_LANDINGPAGE = true
Nenue@32 18 local CP_HEADER_SIZE = 24
Nenue@32 19 local CP_BACKGROUND_COLOR = {
Nenue@32 20 inProgress = {0, 0, 0, 0.5},
Nenue@32 21 shipmentsReady = {0, 0, 0, 0.25},
Nenue@32 22 complete = {0.5, 0.5, 0.5, 0.5}
Nenue@2 23 }
Nenue@2 24
Nenue@4 25 local GetTimeLeftString = function(timeLeft)
Nenue@4 26 local days = floor(timeLeft/(24*3600))
Nenue@4 27 local hours = floor(mod(timeLeft, (24*3600)) / 3600)
Nenue@4 28 local minutes = floor(mod(timeLeft, 3600) / 60)
Nenue@4 29 local seconds = mod(timeLeft, 60)
Nenue@4 30 if days >= 1 then
Nenue@6 31 return (days .. 'd' .. ' ') .. ((hours > 0) and (hours .. 'h') or '')
Nenue@4 32 else
Nenue@6 33 return ((hours > 0) and (hours .. 'h') or '') .. ((minutes > 0) and (' ' ..minutes .. ' min') or '')
Nenue@4 34 end
Nenue@4 35 end
Nenue@3 36
Nenue@23 37
Nenue@32 38 ClassOrderPlanCore = {
Nenue@32 39 events = {},
Nenue@32 40 freeBlocks = {},
Nenue@32 41 blocks = {},
Nenue@32 42 sortedItems = {},
Nenue@32 43 timers = {},
Nenue@32 44 shipments = {},
Nenue@32 45 playerFirst = false,
Nenue@32 46 prototypes = {},
Nenue@32 47 Queued = {}
Nenue@32 48 }
Nenue@32 49 local MissionList = {
Nenue@32 50 templateName = 'ClassPlanMissionEntry',
Nenue@32 51 listKey = {'missions', 'available'},
Nenue@32 52 listTitle = {'In Progress', 'Available'},
Nenue@23 53
Nenue@32 54 point = 'TOPLEFT',
Nenue@32 55 relativePoint ='TOPLEFT',
Nenue@32 56 events = {
Nenue@32 57 'GARRISON_MISSION_LIST_UPDATE',
Nenue@32 58 'GARRISON_LANDINGPAGE_SHIPMENTS'},
Nenue@32 59 }
Nenue@32 60 local ShipmentList = {
Nenue@32 61 templateName = 'ClassPlanShipmentEntry',
Nenue@32 62 listKey = {'shipments'},
Nenue@32 63 listTitle = {'Work Orders'},
Nenue@32 64 events = {
Nenue@32 65 'GARRISON_MISSION_LIST_UPDATE',
Nenue@32 66 'GARRISON_LANDINGPAGE_SHIPMENTS',
Nenue@32 67 'GARRISON_TALENT_UPDATE',
Nenue@32 68 "GARRISON_TALENT_COMPLETE",
Nenue@32 69 "GARRISON_SHIPMENT_RECEIVED",
Nenue@32 70 'GARRISON_FOLLOWER_LIST_UPDATE',
Nenue@32 71 'GARRISON_SHOW_LANDING_PAGE'},
Nenue@32 72 }
Nenue@32 73 local SharedHandlers = {
Nenue@32 74 numBlocks = 0,
Nenue@32 75 isStale = true,
Nenue@32 76 }
Nenue@32 77 local SharedEntry = {}
Nenue@32 78 local ShipmentEntry = {}
Nenue@32 79 local MissionEntry = {}
Nenue@1 80
Nenue@32 81 local ClassPlan = ClassOrderPlanCore
Nenue@5 82
Nenue@32 83 function ClassPlan:OnLoad ()
Nenue@3 84 self:RegisterEvent('PLAYER_LOGIN')
Nenue@3 85 self:RegisterEvent('ADDON_LOADED')
Nenue@3 86 self:RegisterEvent('PLAYER_REGEN_ENABLED')
Nenue@5 87 self:RegisterEvent('PLAYER_REGEN_DISABLED')
Nenue@32 88 self:RegisterForDrag('LeftButton')
Nenue@32 89 self:SetMovable(true)
Nenue@32 90 self:SetToplevel(true)
Nenue@32 91
Nenue@32 92
Nenue@32 93 SLASH_CLASSPLAN1 = "/classplan"
Nenue@32 94 SLASH_CLASSPLAN2 = "/cp"
Nenue@32 95 SlashCmdList.CLASSPLAN = function(args)
Nenue@32 96 self:Toggle()
Nenue@32 97 end
Nenue@32 98
Nenue@4 99 end
Nenue@19 100
Nenue@32 101 function ClassPlan:GetCurrentProfile()
Nenue@32 102 WorldPlanData.OrderHall = WorldPlanData.OrderHall or {}
Nenue@32 103 local db = WorldPlanData.OrderHall
Nenue@32 104 self.data = db
Nenue@4 105
Nenue@32 106 local characters = db.characters or {}
Nenue@32 107 db.characters = characters
Nenue@4 108
Nenue@32 109 local name, realm = UnitName('player')
Nenue@32 110 realm = realm or GetRealmName()
Nenue@32 111 local profileName = name .. '-' .. realm
Nenue@4 112
Nenue@32 113 self.profile = characters[profileName] or {}
Nenue@32 114 self.characters = characters
Nenue@32 115 characters[profileName] = self.profile
Nenue@32 116
Nenue@32 117
Nenue@32 118 local classColor = RAID_CLASS_COLORS[select(2, UnitClass('player'))]
Nenue@32 119 local className = UnitClass('player')
Nenue@32 120
Nenue@32 121 print('|cFFFFFF00Loaded:|r', classColor.hex, className, profileName)
Nenue@32 122 self.Background:SetColorTexture(classColor.r, classColor.g, classColor.b, 0.5)
Nenue@32 123 self.profile.classColor = classColor
Nenue@32 124 self.profile.className = className
Nenue@32 125 return self.profile
Nenue@3 126 end
Nenue@3 127
Nenue@32 128 function ClassPlan:SetupHandler(handler)
Nenue@32 129 print('|cFF00FF00'..handler:GetName()..' loaded')
Nenue@32 130 for i, event in ipairs(handler.events) do
Nenue@32 131 print('|cFF00FF00 event', event)
Nenue@32 132 handler:RegisterEvent(event)
Nenue@1 133 end
Nenue@32 134 for index, listKey in ipairs(handler.listKey) do
Nenue@32 135 self.profile[listKey] = self.profile[listKey] or {}
Nenue@32 136 local listTitle = handler.listTitle[index]
Nenue@32 137 setmetatable(self.profile[listKey], { __tostring = listTitle })
Nenue@32 138 end
Nenue@32 139 handler:SetList(1)
Nenue@32 140 handler.sortedItems = {}
Nenue@3 141 end
Nenue@1 142
Nenue@32 143 function ClassPlan:OnEvent (event, arg)
Nenue@32 144 print(event, arg)
Nenue@5 145 if event == 'PLAYER_REGEN_DISABLED' then
Nenue@6 146 if self:IsVisible() then
Nenue@6 147 self.combatHide = true
Nenue@6 148 self:SetShown(false)
Nenue@6 149 end
Nenue@6 150
Nenue@5 151 elseif event == 'PLAYER_REGEN_ENABLED' then
Nenue@6 152 if self.combatHide == true then
Nenue@6 153 self.combatHide = nil
Nenue@6 154 self:SetShown(true)
Nenue@6 155 end
Nenue@32 156 elseif event == 'ADDON_LOADED' then
Nenue@32 157 if arg == 'Blizzard_GarrisonUI' then
Nenue@32 158 self:Reanchor()
Nenue@32 159 end
Nenue@3 160 elseif event == 'PLAYER_LOGIN' then
Nenue@3 161 if not self.initialized then
Nenue@4 162 self:Setup()
Nenue@1 163 end
Nenue@2 164 end
Nenue@2 165 end
Nenue@2 166
Nenue@32 167 function ClassPlan:Setup()
Nenue@32 168 if IsLoggedIn() then
Nenue@32 169 print('|cFFFFFF00'..self:GetName()..':Setup()|r')
Nenue@32 170
Nenue@32 171 self:GetCurrentProfile()
Nenue@32 172 for _, handler in ipairs(self.Handlers) do
Nenue@32 173 self:SetupHandler(handler)
Nenue@32 174 end
Nenue@32 175 self.initialized = true
Nenue@32 176 self:SetShown(self.data.IsShown)
Nenue@32 177 end
Nenue@3 178 end
Nenue@3 179
Nenue@4 180
Nenue@32 181 --- Update space
Nenue@4 182
Nenue@32 183 local max = math.max
Nenue@32 184 function ClassPlan:Update()
Nenue@32 185 print('|cFF00FFFFRefresh()|r')
Nenue@32 186 self.currentHeight = 0
Nenue@32 187 for index, handler in pairs(self.Handlers) do
Nenue@32 188 if handler.isStale then
Nenue@32 189 print(' |cFF00FF00'..index..' '..handler:GetName()..'|r')
Nenue@32 190 local sortedItems = handler.sortedItems
Nenue@32 191 local activeKey = handler.activeKey
Nenue@32 192 handler.profile = self.profile[handler.activeKey]
Nenue@3 193
Nenue@32 194 wipe(sortedItems)
Nenue@32 195 handler:GetPlayerData(self.profile)
Nenue@32 196 for key, profile in pairs(self.data.characters) do
Nenue@32 197 print('profile', key, activeKey)
Nenue@32 198 local profileList = profile[activeKey]
Nenue@32 199 if profileList and #profileList >= 1 then
Nenue@32 200 local classColor = profile.classColor or defaultClassColor
Nenue@32 201 local isMine = (profile == self.profile)
Nenue@32 202 for index, data in ipairs(profileList) do
Nenue@32 203 data.classColor = classColor
Nenue@32 204 data.profileKey = key
Nenue@32 205 data.isMine = isMine
Nenue@32 206 if handler.OnGetItem then
Nenue@32 207 handler.OnGetItem(data)
Nenue@32 208 end
Nenue@32 209 tinsert(sortedItems, data)
Nenue@32 210 end
Nenue@32 211 end
Nenue@32 212 end
Nenue@3 213
Nenue@32 214 if handler.SortHandler then
Nenue@32 215 sort(sortedItems, handler.SortHandler)
Nenue@23 216 end
Nenue@23 217
Nenue@23 218 end
Nenue@32 219 handler.isStale = nil
Nenue@32 220 local itemsHeight = handler:UpdateItems()
Nenue@32 221 self.currentHeight = max(itemsHeight, self.currentHeight)
Nenue@23 222
Nenue@23 223 end
Nenue@23 224
Nenue@32 225 self.isStale = nil
Nenue@32 226 self:Reanchor()
Nenue@32 227 self:SetHeight(self.currentHeight + CP_HEADER_SIZE)
Nenue@3 228 end
Nenue@3 229
Nenue@3 230
Nenue@32 231 function ClassPlan:Toggle()
Nenue@5 232 if self:IsShown() then
Nenue@3 233 self:Hide()
Nenue@3 234 else
Nenue@3 235 self:Show()
Nenue@3 236 end
Nenue@3 237
Nenue@3 238 if self.data then
Nenue@5 239 self.data.IsShown = self:IsShown()
Nenue@3 240 end
Nenue@3 241 end
Nenue@3 242
Nenue@32 243 function ClassPlan:OnUpdate()
Nenue@18 244 if self.isStale then
Nenue@32 245 print('|cFFFF4400An illusion! What are you hiding?|r')
Nenue@32 246 self:Update()
Nenue@18 247 end
Nenue@3 248 end
Nenue@3 249
Nenue@32 250 function ClassPlan:OnShow()
Nenue@23 251 print('|cFF00FFFFShow()')
Nenue@3 252 if self.isStale then
Nenue@32 253 self:Update()
Nenue@3 254 end
Nenue@32 255 self:Reanchor()
Nenue@3 256 end
Nenue@3 257
Nenue@32 258 function ClassPlan:OnHide()
Nenue@32 259 print('|cFF00FFFFHide()')
Nenue@3 260 end
Nenue@3 261
Nenue@32 262 function ClassPlan:Reanchor()
Nenue@32 263 self:ClearAllPoints()
Nenue@32 264 self:SetPoint('CENTER', self.data.positionX, self.data.positionY)
Nenue@32 265
Nenue@32 266 for index, frame in ipairs(self.Handlers) do
Nenue@32 267 frame:Reanchor()
Nenue@32 268 end
Nenue@2 269 end
Nenue@2 270
Nenue@32 271 function ClassPlan:OnDragStart()
Nenue@32 272 self:StartMoving()
Nenue@32 273 end
Nenue@32 274 function ClassPlan:OnDragStop()
Nenue@32 275
Nenue@32 276 self:StopMovingOrSizing()
Nenue@32 277 local x,y = self:GetCenter()
Nenue@32 278 if x and y then
Nenue@32 279 x = (x - GetScreenWidth()/2)
Nenue@32 280 y = (y - GetScreenHeight()/2) * -1
Nenue@32 281 self.data.positionX, self.data.positionY = x,y
Nenue@32 282 print('saving positions:', x, y)
Nenue@32 283 end
Nenue@32 284 end
Nenue@32 285
Nenue@32 286 function SharedHandlers:SetList(index)
Nenue@32 287 if not index then
Nenue@32 288 if self.currentListIndex == #self.listKey then
Nenue@32 289 index = 1
Nenue@32 290 else
Nenue@32 291 index = self.currentListIndex + 1
Nenue@32 292 end
Nenue@32 293 end
Nenue@32 294
Nenue@32 295 print('|cFF0088FF'..self:GetName()..'|r:SetList()', index)
Nenue@32 296 self.currentListIndex = index
Nenue@32 297 self.activeKey = self.listKey[index]
Nenue@32 298 self.activeTitle = self.listTitle[index]
Nenue@32 299
Nenue@32 300 self.isStale = true
Nenue@32 301 end
Nenue@32 302
Nenue@32 303 function SharedHandlers:RequestData()
Nenue@32 304 print('|cFF0088FF'..self:GetName()..':RequestData()')
Nenue@32 305 self.isStale = true
Nenue@32 306 end
Nenue@32 307
Nenue@32 308 function SharedHandlers:OnEvent(event, arg)
Nenue@32 309 if (event == 'GARRISON_MISSION_LIST_UPDATE') and (arg ~= LE_FOLLOWER_TYPE_GARRISON_7_0) then
Nenue@32 310 -- ignore non-OrderHall updates
Nenue@2 311 return
Nenue@2 312 end
Nenue@32 313 print('|cFF00FF88'..self:GetName()..':OnEvent()|r', event, arg)
Nenue@32 314 if self:IsVisible() then
Nenue@32 315 print('|cFF88FF00 frame visible; get busy')
Nenue@32 316 self:RequestData()
Nenue@6 317 else
Nenue@32 318 if not self.NextData then
Nenue@32 319 print('|cFF88FF00 setting timer')
Nenue@32 320 self.NextData = C_Timer.NewTimer(0.25, function()
Nenue@32 321 if self.initialized then
Nenue@32 322 self:RequestData()
Nenue@32 323 self.NextData:Cancel()
Nenue@32 324 self.NextData = nil
Nenue@32 325 print('|cFF88FF00'..self:GetName()..' clearing timer')
Nenue@32 326 end
Nenue@32 327
Nenue@32 328 end)
Nenue@32 329 end
Nenue@32 330 end
Nenue@32 331 end
Nenue@32 332 function SharedHandlers:OnUpdate()
Nenue@32 333 if self.isStale then
Nenue@32 334 self:GetParent():Update()
Nenue@32 335 end
Nenue@32 336 end
Nenue@32 337
Nenue@32 338
Nenue@32 339 -- Stuff set on every list item
Nenue@32 340 function SharedHandlers:SetOwnerData (self, data)
Nenue@32 341 local name, realm = string.match(data.profileKey, "(.+)%-(.+)")
Nenue@32 342 local ownerText = '|c'.. data.classColor.colorStr .. name .. '|r'
Nenue@32 343 self.Owner:SetText(ownerText)
Nenue@32 344 self.Name:SetText(self.name)
Nenue@32 345 self.Name:SetTextColor(data.classColor.r, data.classColor.g, data.classColor.b)
Nenue@32 346 end
Nenue@32 347
Nenue@32 348 function SharedHandlers:UpdateItems()
Nenue@32 349 local sortedItems = self.sortedItems
Nenue@32 350
Nenue@32 351 self.blocks = self.blocks or {}
Nenue@32 352 local blocks = self.blocks
Nenue@32 353
Nenue@32 354 local lastProfile
Nenue@32 355 local numItems = #sortedItems
Nenue@32 356 local totalHeight = 0
Nenue@32 357 self.lastBlock = nil
Nenue@32 358 self.numActive = 0
Nenue@32 359 for i, data in ipairs(sortedItems) do
Nenue@32 360 local block = blocks[i]
Nenue@32 361 if not block then
Nenue@32 362 block = CreateFrame('Button', nil, self, self.templateName)
Nenue@32 363 block:SetID(i)
Nenue@32 364 block.listType = self.activeKey
Nenue@32 365 block.handler = self
Nenue@32 366 self.numBlocks = self.numBlocks + 1
Nenue@32 367 blocks[i] = block
Nenue@32 368 end
Nenue@32 369
Nenue@32 370 print('RefreshItem', block)
Nenue@32 371 self.numActive = self.numActive + 1
Nenue@32 372
Nenue@32 373 if self.lastBlock then
Nenue@32 374 block:SetPoint('TOPLEFT', self.lastBlock, 'BOTTOMLEFT', 0, 0)
Nenue@32 375 print('--', i, data.isComplete, data.missionEndTime, data.name)
Nenue@32 376 else
Nenue@32 377 block:SetPoint('TOPLEFT', 0, 0)
Nenue@32 378 print('--top')
Nenue@32 379 end
Nenue@32 380 self.lastBlock = block
Nenue@32 381
Nenue@32 382 totalHeight = totalHeight + block:GetHeight()
Nenue@32 383 block.lastProfile = lastProfile
Nenue@32 384 -- blot out arbitrary flags
Nenue@32 385 block.offerEndTime = nil
Nenue@32 386 block.missionEndTime = nil
Nenue@32 387 block.creationTime = nil
Nenue@32 388 block.duration = nil
Nenue@32 389 block.throttle = 5
Nenue@32 390
Nenue@32 391 for k,v in pairs(data) do
Nenue@32 392 if type(block[k]) ~= 'function' then
Nenue@32 393 block[k] = v
Nenue@32 394 end
Nenue@32 395 end
Nenue@32 396
Nenue@32 397 block:Update()
Nenue@32 398 self:SetOwnerData(block, data)
Nenue@32 399
Nenue@32 400 block:Show()
Nenue@32 401 lastProfile = data.profileKey
Nenue@6 402 end
Nenue@6 403
Nenue@32 404 for i = numItems + 1, self.numBlocks do
Nenue@32 405 if blocks[i] then
Nenue@32 406 blocks[i]:Hide()
Nenue@32 407 end
Nenue@32 408 end
Nenue@32 409
Nenue@32 410 self:Reanchor()
Nenue@32 411
Nenue@32 412 return totalHeight
Nenue@32 413 end
Nenue@32 414
Nenue@32 415
Nenue@32 416 function ShipmentList:Reanchor()
Nenue@32 417 print('|cFF00FFFF'..self:GetName()..':Reanchor|r')
Nenue@32 418 self:SetPoint('TOPLEFT', 0, -24)
Nenue@32 419 self:SetPoint('BOTTOMRIGHT', -ClassOrderPlan:GetWidth()/2, 0)
Nenue@32 420 end
Nenue@32 421
Nenue@32 422 function MissionList:Reanchor()
Nenue@32 423 self:SetPoint('TOPRIGHT', 0, -24)
Nenue@32 424 self:SetPoint('BOTTOMLEFT', ClassOrderPlan:GetWidth()/2, 0)
Nenue@32 425
Nenue@32 426 self.ListTab:ClearAllPoints()
Nenue@32 427 self.ListTab:SetPoint('TOPLEFT', self, 'TOPLEFT', 0, CP_HEADER_SIZE)
Nenue@32 428 self.ListTab:SetPoint('BOTTOMRIGHT', self, 'TOPRIGHT', 0, 0)
Nenue@32 429 self.ListTab.Label:SetText(self.listTitle[self.currentListIndex])
Nenue@32 430 self.ListTab:Show()
Nenue@32 431 print(self.ListTab:GetSize())
Nenue@32 432 end
Nenue@32 433
Nenue@32 434 function MissionList:GetPlayerData (profile)
Nenue@32 435 wipe(profile.missions)
Nenue@32 436 wipe(profile.available)
Nenue@32 437
Nenue@32 438 local items = C_Garrison.GetAvailableMissions(GetPrimaryGarrisonFollowerType(LE_GARRISON_TYPE_7_0));
Nenue@32 439 for i = 1, #items do
Nenue@32 440 if (not items[i].isBuilding and items[i].isZoneSupport) then
Nenue@32 441 else
Nenue@32 442
Nenue@32 443 tinsert(profile.available, items[i])
Nenue@32 444 end
Nenue@32 445 end
Nenue@32 446
Nenue@32 447 local items = C_Garrison.GetLandingPageItems(LE_GARRISON_TYPE_7_0)
Nenue@32 448 for index, data in ipairs(items) do
Nenue@32 449 print(' -',data.name, '|cFF00FF00'.. data.timeLeft .. '|r', date("%A %I:%m %p", data.missionEndTime))
Nenue@32 450 tinsert(profile.missions, data)
Nenue@32 451 end
Nenue@32 452 return true
Nenue@32 453 end
Nenue@32 454
Nenue@32 455 do
Nenue@32 456 local ShipmentsInfo = {}
Nenue@32 457 local AddShipmentInfo = function(shipmentType, name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, itemName, itemIcon, itemQuality, itemID, followerID)
Nenue@32 458 -- early login queries may return empty tables, causing the sorter to compare nil
Nenue@32 459 if not creationTime then
Nenue@32 460 return
Nenue@32 461 end
Nenue@32 462 --print(shipmentType, name, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString)
Nenue@32 463 tinsert(ShipmentsInfo,
Nenue@32 464 {
Nenue@32 465 shipmentType = shipmentType,
Nenue@32 466 name = name,
Nenue@32 467 icon = texture,
Nenue@32 468 shipmentCapacity = shipmentCapacity,
Nenue@32 469 shipmentsReady = shipmentsReady,
Nenue@32 470 shipmentsTotal = shipmentsTotal,
Nenue@32 471 creationTime = creationTime,
Nenue@32 472 duration = duration,
Nenue@32 473 timeleftString = timeleftString,
Nenue@32 474 itemName = itemName,
Nenue@32 475 itemIcon = itemIcon,
Nenue@32 476 itemQuality = itemQuality,
Nenue@32 477 itemID = itemID,
Nenue@32 478 followerID = followerID,
Nenue@32 479 })
Nenue@32 480 end
Nenue@32 481 function ShipmentList:GetPlayerData (profile)
Nenue@32 482 if not profile then
Nenue@32 483 return false
Nenue@32 484 end
Nenue@32 485 local profileList = profile.shipments
Nenue@32 486 wipe(ShipmentsInfo)
Nenue@32 487
Nenue@32 488 local garrisonType = LE_GARRISON_TYPE_7_0
Nenue@32 489 local buildings = CG_GetBuildings(garrisonType);
Nenue@32 490 local shipmentIndex = 0
Nenue@32 491 --print('Buildings:')
Nenue@32 492 for i = 1, #buildings do
Nenue@32 493 local name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, itemName, itemIcon, itemQuality, itemID = CG_GetLandingPageShipmentInfo(buildingID);
Nenue@32 494 AddShipmentInfo('Building', name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, itemName, itemIcon, itemQuality, itemID)
Nenue@32 495 end
Nenue@32 496
Nenue@32 497 --print('Follower:')
Nenue@32 498 local followerShipments = CG_GetFollowerShipments(garrisonType);
Nenue@32 499 for i = 1, #followerShipments do
Nenue@32 500 local name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, _, _, _, _, followerID = CG_GetLandingPageShipmentInfoByContainerID(followerShipments[i]);
Nenue@32 501 AddShipmentInfo('Follower', name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString, nil, nil, nil, nil, followerID)
Nenue@32 502 end
Nenue@32 503
Nenue@32 504 --print('Loose:')
Nenue@32 505 local looseShipments = CG_GetLooseShipments(garrisonType)
Nenue@32 506 for i = 1, #looseShipments do
Nenue@32 507 local name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString = CG_GetLandingPageShipmentInfoByContainerID(looseShipments[i]);
Nenue@32 508 AddShipmentInfo('Misc', name, texture, shipmentCapacity, shipmentsReady, shipmentsTotal, creationTime, duration, timeleftString)
Nenue@32 509 end
Nenue@32 510
Nenue@32 511 local talentTrees = CG_GetTalentTrees(garrisonType, select(3, UnitClass("player")));
Nenue@32 512 -- this is a talent that has completed, but has not been seen in the talent UI yet.
Nenue@32 513 local completeTalentID = CG_GetCompleteTalent(garrisonType);
Nenue@32 514 --print('Talents:')
Nenue@32 515 if (talentTrees) then
Nenue@32 516 for treeIndex, tree in ipairs(talentTrees) do
Nenue@32 517 for talentIndex, talent in ipairs(tree) do
Nenue@32 518 local showTalent = false;
Nenue@32 519 if (talent.isBeingResearched) or (talent.id == completeTalentID) then
Nenue@32 520 AddShipmentInfo('Talent', talent.name, talent.icon, 1, (talent.isBeingResearched and 0 or 1), 1, talent.researchStartTime, talent.researchDuration, talent.timeleftString)
Nenue@32 521 end
Nenue@32 522 end
Nenue@32 523 end
Nenue@32 524 end
Nenue@32 525
Nenue@32 526 wipe(profileList)
Nenue@32 527 for index, data in ipairs(ShipmentsInfo) do
Nenue@32 528 --DEFAULT_CHAT_FRAME:AddMessage(data.shipmentType ..' '.. tostring(data.name) ..' '.. tostring(data.creationTime) ..' '.. tostring(data.duration))
Nenue@32 529 tinsert(profileList, data)
Nenue@32 530 end
Nenue@32 531 self.isStale = true
Nenue@32 532 return true
Nenue@32 533 end
Nenue@32 534 end
Nenue@32 535 MissionList.OnGetItem = function(data)
Nenue@32 536 if data.missionEndTime and (data.missionEndTime < GI_currentTime) then
Nenue@32 537 data.isComplete = true
Nenue@32 538 end
Nenue@32 539 end
Nenue@32 540
Nenue@32 541 MissionList.FreeBlock = function(self, block)
Nenue@32 542 end
Nenue@32 543
Nenue@32 544 MissionList.SortHandler = function (a,b)
Nenue@32 545 local result = false
Nenue@32 546 --if not a or not b then
Nenue@32 547 -- return true
Nenue@32 548 --else
Nenue@32 549 --if (a.isMine ~= b.isMine) then
Nenue@32 550 -- result = a.isMine
Nenue@32 551 --else
Nenue@32 552 --if (not b.missionEndTime) or (not a.missionEndTime) then
Nenue@32 553 -- print('missing article', b.missionEndTime, a.missionEndTime)
Nenue@32 554 --end
Nenue@32 555 if b.isComplete ~= a.isComplete then
Nenue@32 556 return a.isComplete
Nenue@32 557 elseif b.isMine ~= a.isMine then
Nenue@32 558 return a.isMine
Nenue@32 559 elseif b.missionEndTime then
Nenue@32 560 return ( b.missionEndTime > a.missionEndTime)
Nenue@32 561 else
Nenue@32 562 return ( b.offerEndTime > a.offerEndTime)
Nenue@32 563 end
Nenue@32 564
Nenue@32 565 --end
Nenue@32 566 --end
Nenue@32 567 end
Nenue@32 568
Nenue@32 569
Nenue@32 570 function MissionList:OnShow()
Nenue@32 571 print('|cFF00FF88'..self:GetName()..':OnShow()|r')
Nenue@32 572 end
Nenue@32 573
Nenue@32 574 function ShipmentList:OnLoad()
Nenue@32 575 C_Garrison.RequestLandingPageShipmentInfo();
Nenue@32 576 end
Nenue@32 577 function ShipmentList:OnShow()
Nenue@32 578 print('|cFF00FF88'..self:GetName()..':OnShow()|r')
Nenue@32 579 C_Garrison.RequestLandingPageShipmentInfo()
Nenue@32 580 end
Nenue@32 581
Nenue@32 582 -- Update shipment flags data
Nenue@32 583 local SetActualShipmentTime = function(self)
Nenue@32 584
Nenue@32 585 if self.isComplete then
Nenue@32 586 print('|cFF00FF88isComplete '..self.name..'|r')
Nenue@32 587 return true
Nenue@32 588 end
Nenue@32 589
Nenue@32 590 local timestamp = time()
Nenue@32 591 local timeLeft = self.creationTime + self.duration - timestamp
Nenue@32 592 local justFinished = false
Nenue@32 593 while (self.shipmentsReady < self.shipmentsTotal) and (timeLeft <= 0) do
Nenue@32 594 if not self.originalReady then
Nenue@32 595 self.originalReady = self.shipmentsReady
Nenue@32 596 self.originalCreationTime = self.creationTime
Nenue@32 597 end
Nenue@32 598
Nenue@32 599
Nenue@32 600 self.shipmentsReady = self.shipmentsReady + 1
Nenue@32 601 self.creationTime = self.creationTime + self.duration
Nenue@32 602 timeLeft = timeLeft + self.duration
Nenue@32 603 print('|cFF00FF88udpating '..self.name..'|r', 'timeLeft:', timeLeft, 'shipments:', self.shipmentsReady, self.shipmentsTotal)
Nenue@32 604 end
Nenue@32 605
Nenue@32 606 if (timeLeft <= 0) and (not self.isBeingResearched) then
Nenue@32 607 self.isComplete = true
Nenue@32 608 self.isStale = true
Nenue@32 609 end
Nenue@32 610
Nenue@32 611 return timeLeft
Nenue@32 612 end
Nenue@32 613
Nenue@32 614 ShipmentList.OnGetItem = function(data)
Nenue@32 615 print('OnGetItem()')
Nenue@32 616 if data.shipmentsTotal then
Nenue@32 617 SetActualShipmentTime(data)
Nenue@32 618 end
Nenue@32 619 end
Nenue@32 620
Nenue@32 621 ShipmentList.SortHandler = function(a, b)
Nenue@32 622 if b.isComplete ~= a.isComplete then
Nenue@32 623 return a.isComplete and true or false
Nenue@32 624 elseif a.shipmentsReady or b.shipmentsReady then
Nenue@32 625 return (a.shipmentsReady or 0) > (b.shipmentsReady or 0)
Nenue@32 626 else
Nenue@32 627 return (a.creationTime) < (b.creationTime)
Nenue@32 628 end
Nenue@32 629 end
Nenue@32 630
Nenue@32 631
Nenue@32 632 function MissionEntry:OnComplete()
Nenue@32 633 print('flagging complete', self.name)
Nenue@32 634 self:Update()
Nenue@32 635 end
Nenue@32 636
Nenue@32 637 function MissionEntry:OnUpdate(sinceLast)
Nenue@32 638 self.throttle = (self.throttle or .5) + sinceLast
Nenue@32 639 if self.throttle < .5 then
Nenue@32 640 return
Nenue@32 641 else
Nenue@32 642 self.throttle = self.throttle - .5
Nenue@32 643 end
Nenue@32 644 if self.offerEndTime then
Nenue@32 645 local timeLeft = self.offerEndTime
Nenue@32 646 self.TimeLeft:SetText(GetTimeLeftString(timeLeft))
Nenue@32 647 self.TimeLeft:SetTextColor(1,1,1)
Nenue@32 648 elseif self.missionEndTime then
Nenue@32 649
Nenue@32 650 if self.isComplete then
Nenue@32 651 return
Nenue@32 652 end
Nenue@1 653 local timeLeft = self.missionEndTime - time()
Nenue@1 654 if timeLeft < 0 then
Nenue@2 655 self:OnComplete()
Nenue@1 656 else
Nenue@2 657 self.TimeLeft:SetText(GetTimeLeftString(timeLeft))
Nenue@2 658 if timeLeft > 3600 then
Nenue@2 659 self.TimeLeft:SetTextColor(1,1,1)
Nenue@2 660 else
Nenue@2 661 self.TimeLeft:SetTextColor(1,1,0)
Nenue@2 662 end
Nenue@6 663 end
Nenue@2 664
Nenue@6 665 if not self.isComplete then
Nenue@18 666 local progress = (time() - (self.missionEndTime - self.durationSeconds)) / self.durationSeconds
Nenue@6 667 local w = self.ProgressBG:GetWidth()
Nenue@6 668 if progress >= 1 then
Nenue@6 669 self.ProgressBar:SetWidth(w)
Nenue@6 670 else
Nenue@18 671 self.ProgressBar:SetWidth(progress * w)
Nenue@18 672 local r, g = 1, 0
Nenue@18 673 if progress >= 0.5 then
Nenue@18 674 g = 1
Nenue@18 675 r = 1-((progress-0.5)*2)
Nenue@18 676 else
Nenue@18 677 g = min(progress * 2, 1)
Nenue@18 678 r = 1
Nenue@18 679 end
Nenue@32 680 self.ProgressBar:SetColorTexture(r,g,0,.4)
Nenue@18 681 self.ProgressBG:SetColorTexture(r,g,0,0.125)
Nenue@6 682 end
Nenue@6 683 self.ProgressBG:Show()
Nenue@6 684 self.ProgressBar:Show()
Nenue@6 685 else
Nenue@6 686 self.ProgressBG:Hide()
Nenue@6 687 self.ProgressBar:Hide()
Nenue@1 688 end
Nenue@1 689 else
Nenue@1 690 self.TimeLeft:SetText(self.missionEndTime)
Nenue@1 691 end
Nenue@2 692 end
Nenue@2 693
Nenue@32 694 function MissionEntry:OnLoad()
Nenue@32 695 print('|cFFFF4400',self:GetName() or tostring(self), 'onload')
Nenue@32 696 self.Count = self.Overlay.Count
Nenue@32 697 self.Name = self.Overlay.Name
Nenue@32 698 self.TimeLeft = self.Overlay.TimeLeft
Nenue@32 699 self.Owner = self.Overlay.Owner
Nenue@32 700
Nenue@32 701 self.Icon:SetDesaturated(false)
Nenue@32 702 self.Done:Hide()
Nenue@32 703 end
Nenue@32 704
Nenue@32 705 function MissionEntry:Update()
Nenue@2 706 local r,g,b = 1, 1, 1
Nenue@4 707 if self.isRare then
Nenue@2 708 r,g,b = 0.1, 0.4, 1
Nenue@5 709 self.IconBorder:SetVertexColor(r, g, b, 1)
Nenue@2 710 end
Nenue@2 711
Nenue@2 712 --self.missionData = data
Nenue@5 713 self.Name:SetText(self.name)
Nenue@4 714 if #self.rewards >= 1 then
Nenue@4 715 self.Icon:SetTexture(self.rewards[1].icon or GetItemIcon(self.rewards[1].itemID))
Nenue@4 716 self.rewardInfo = self.rewards[1]
Nenue@2 717 else
Nenue@4 718 self.Icon:SetAtlas(self.typeAtlas, false)
Nenue@2 719 end
Nenue@6 720
Nenue@32 721
Nenue@6 722
Nenue@18 723 if self.isComplete then
Nenue@18 724 self.TimeLeft:SetText('Complete!')
Nenue@18 725 self.Background:SetColorTexture(.25,.25,.25,1)
Nenue@18 726 else
Nenue@18 727 self.Background:SetColorTexture(0,0,0,0.5)
Nenue@18 728 end
Nenue@2 729 end
Nenue@2 730
Nenue@32 731 function MissionEntry:OnEnter()
Nenue@2 732 if self.rewardInfo and self.rewardInfo.itemID then
Nenue@2 733 GameTooltip:SetOwner(self, 'ANCHOR_LEFT')
Nenue@2 734 GameTooltip:SetItemByID(self.rewardInfo.itemID)
Nenue@2 735 GameTooltip:Show()
Nenue@2 736 end
Nenue@2 737 end
Nenue@19 738
Nenue@32 739 function MissionEntry:OnLeave()
Nenue@2 740 if GameTooltip:IsOwned(self) then
Nenue@2 741 GameTooltip:Hide()
Nenue@2 742 end
Nenue@2 743 end
Nenue@2 744
Nenue@32 745 function ShipmentEntry:OnLoad()
Nenue@32 746 MissionEntry.OnLoad(self)
Nenue@32 747 end
Nenue@3 748
Nenue@32 749
Nenue@32 750 function ShipmentEntry:Update()
Nenue@32 751 print('|cFF0088FF'.. self.name..'|r:Update()')
Nenue@4 752 self.Icon:SetTexture(self.icon)
Nenue@4 753 self.Count:SetText(self.shipmentsReady)
Nenue@4 754 self.Done:SetShown(self.shipmentsReady and (self.shipmentsReady >= 1))
Nenue@2 755
Nenue@3 756 -- flag as complete
Nenue@32 757
Nenue@32 758 local bgColor = CP_BACKGROUND_COLOR.inProgress
Nenue@6 759 if ( self.shipmentsReady >= self.shipmentsTotal ) and (not self.isBeingResearched) then
Nenue@2 760 self.Swipe:SetCooldownUNIX(0, 0);
Nenue@2 761 self.Done:Show();
Nenue@32 762 bgColor = CP_BACKGROUND_COLOR.complete
Nenue@2 763 else
Nenue@32 764 if (self.shipmentsReady >= 1) and (self.shipmentsReady < self.shipmentsTotal) then
Nenue@32 765 bgColor = CP_BACKGROUND_COLOR.shipmentsReady
Nenue@32 766 end
Nenue@4 767 self.Swipe:SetCooldownUNIX(self.creationTime or 0 , self.duration or 0);
Nenue@2 768 end
Nenue@32 769 self.Background:SetColorTexture(unpack(bgColor))
Nenue@2 770
Nenue@32 771 SetActualShipmentTime(self)
Nenue@32 772
Nenue@32 773 if self.originalReady then
Nenue@32 774 print('|cFF00FF88'..self.name..'|r', 'starting ready:', self.originalReady, 'starting time:', self.originalCreationTime)
Nenue@18 775 end
Nenue@19 776 end
Nenue@18 777
Nenue@32 778 function ShipmentEntry:OnUpdate(sinceLast)
Nenue@18 779 self.throttle = (self.throttle or 1) + sinceLast
Nenue@18 780 if self.throttle >= 1 then
Nenue@18 781 self.throttle = self.throttle - 1
Nenue@18 782 else
Nenue@18 783 return
Nenue@18 784 end
Nenue@2 785
Nenue@32 786
Nenue@6 787 if (self.shipmentsReady and self.shipmentsTotal) and (self.shipmentsReady < self.shipmentsTotal) then
Nenue@32 788 local timeLeft = SetActualShipmentTime(self)
Nenue@32 789
Nenue@32 790 if self.isComplete then
Nenue@32 791 self.TimeLeft:SetText('Complete!')
Nenue@32 792 self.TimeLeft:SetTextColor(0,0.5,1)
Nenue@32 793 elseif self.shipmentsReady >= 1 then
Nenue@6 794 self.TimeLeft:SetText(GetTimeLeftString(timeLeft))
Nenue@6 795 self.TimeLeft:SetTextColor(0,1,0)
Nenue@6 796 else
Nenue@6 797 self.TimeLeft:SetText(GetTimeLeftString(timeLeft))
Nenue@6 798 self.TimeLeft:SetTextColor(1,1,1)
Nenue@6 799 end
Nenue@32 800
Nenue@4 801 elseif self.isBeingResearched then
Nenue@4 802 self.TimeLeft:SetText(GetTimeLeftString(self.researchStartTime + self.researchDuration - time()))
Nenue@6 803 self.TimeLeft:SetTextColor(1,1,0)
Nenue@2 804 else
Nenue@2 805 self.TimeLeft:SetText('Complete!')
Nenue@6 806 self.TimeLeft:SetTextColor(0,1,0)
Nenue@2 807 end
Nenue@2 808
Nenue@18 809 if not self.isComplete then
Nenue@18 810 local progress = ((time() - self.creationTime) / self.duration)
Nenue@18 811 local w = self.ProgressBG:GetWidth()
Nenue@18 812 if progress >= 1 then
Nenue@18 813 self.ProgressBar:SetWidth(w)
Nenue@18 814 else
Nenue@18 815 self.ProgressBar:SetWidth(progress * w)
Nenue@18 816 end
Nenue@18 817
Nenue@18 818 local r, g = 1, 0
Nenue@18 819 if progress >= 0.5 then
Nenue@18 820 g = 1
Nenue@18 821 r = 1-((progress-0.5)*2)
Nenue@18 822 else
Nenue@18 823 g = min(progress * 2, 1)
Nenue@18 824 r = 1
Nenue@18 825 end
Nenue@32 826 self.ProgressBar:SetColorTexture(r, g, 0, .4)
Nenue@18 827 self.ProgressBG:SetColorTexture(r, g, 0, .125)
Nenue@18 828 self.ProgressBG:Show()
Nenue@18 829 self.ProgressBar:Show()
Nenue@18 830 else
Nenue@18 831 self.ProgressBG:Hide()
Nenue@18 832 self.ProgressBar:Hide()
Nenue@18 833 end
Nenue@2 834 end
Nenue@2 835
Nenue@32 836 function ShipmentEntry:OnEnter()
Nenue@4 837 if ( self.shipmentsReady and self.shipmentsTotal ) then
Nenue@2 838 GameTooltip:SetOwner(self, 'ANCHOR_LEFT')
Nenue@4 839 GameTooltip:AddLine(self.Owner:GetText(), self.Owner:GetTextColor())
Nenue@4 840 GameTooltip:AddLine(self.shipmentType)
Nenue@4 841 GameTooltip:AddLine(self.shipmentsReady .. ' of '.. self.shipmentsTotal)
Nenue@2 842 GameTooltip:Show()
Nenue@2 843 end
Nenue@2 844 end
Nenue@2 845
Nenue@32 846 function ShipmentEntry:OnLeave()
Nenue@2 847 if GameTooltip:IsOwned(self) then
Nenue@2 848 GameTooltip:Hide()
Nenue@2 849 end
Nenue@2 850 end
Nenue@2 851
Nenue@32 852 function ShipmentEntry:OnClick(button)
Nenue@3 853 if button == 'RightButton' then
Nenue@4 854 self.handler:FreeBlock(self)
Nenue@3 855 end
Nenue@32 856 end
Nenue@32 857
Nenue@32 858 ClassPlanMissionHandler = Mixin(MissionList, SharedHandlers)
Nenue@32 859 ClassPlanShipmentHandler = Mixin(ShipmentList, SharedHandlers)
Nenue@32 860 ClassPlanMissionEntryMixin = Mixin(MissionEntry, SharedEntry)
Nenue@32 861 ClassPlanShipmentEntryMixin = Mixin(ShipmentEntry,SharedEntry)
Nenue@32 862
Nenue@32 863 ClassPlanHeaderMixin = {
Nenue@32 864 OnClick = function(self)
Nenue@32 865 self:GetParent():SetList()
Nenue@32 866 self:GetParent().isStale = true
Nenue@32 867 ClassOrderPlan:Update()
Nenue@32 868 end
Nenue@32 869 }