annotate ClassPlan.lua @ 4:4c7e9efec4b5

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