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