annotate ClassPlan.lua @ 19:6016ec3c8adf v1.0-rc5

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