annotate ClassPlan.lua @ 1:232617b8bcd5

New Order Hall mission tracker: - record active missions and shipments across characters
author Nenue
date Thu, 13 Oct 2016 05:32:43 -0400
parents
children b8a19781f79b
rev   line source
Nenue@1 1 SLASH_CLASSPLAN1 = "/classplan"
Nenue@1 2 SLASH_CLASSPLAN2 = "/cp"
Nenue@1 3 SlashCmdList.CLASSPLAN = function(args)
Nenue@1 4 if ClassOrderPlan:IsVisible() then
Nenue@1 5 ClassOrderPlan:Hide()
Nenue@1 6 else
Nenue@1 7 ClassOrderPlan:Show()
Nenue@1 8 DEFAULT_CHAT_FRAME:AddMessage('|cFF88FF00WorldPlan|r: Order Hall Panel')
Nenue@1 9 end
Nenue@1 10 end
Nenue@1 11
Nenue@1 12 ClassOrderPlanCore = {
Nenue@1 13 blocks = {},
Nenue@1 14 playerFirst = true,
Nenue@1 15 timers = {}
Nenue@1 16 }
Nenue@1 17 ClassPlanBlockMixin = {
Nenue@1 18 followers = {},
Nenue@1 19 blocks = {},
Nenue@1 20 }
Nenue@1 21 local core, block = ClassOrderPlanCore, ClassPlanBlockMixin
Nenue@1 22 local print = DEVIAN_WORKSPACE and function(...) print('ClassPlan', ...) end or nop
Nenue@1 23
Nenue@1 24 function core:OnLoad ()
Nenue@1 25 self:RegisterUnitEvent('UNIT_PORTRAIT_UPDATE', 'player')
Nenue@1 26 self:RegisterEvent('GARRISON_MISSION_STARTED')
Nenue@1 27 self:RegisterEvent('GARRISON_MISSION_FINISHED')
Nenue@1 28 self:RegisterEvent('PLAYER_LOGIN')
Nenue@1 29 self:RegisterEvent('PLAYER_ENTERING_WORLD')
Nenue@1 30 end
Nenue@1 31
Nenue@1 32
Nenue@1 33 function core:OnEvent (event, ...)
Nenue@1 34 if event == 'UNIT_PORTRAIT_UPDATE' then
Nenue@1 35 SetPortraitTexture(self.portrait, 'player')
Nenue@1 36 elseif event == 'PLAYER_LOGIN' then
Nenue@1 37 if not self.initialized then
Nenue@1 38 if IsLoggedIn() then
Nenue@1 39 WorldPlanData.OrderHall = WorldPlanData.OrderHall or {}
Nenue@1 40 self.data = WorldPlanData.OrderHall
Nenue@1 41
Nenue@1 42
Nenue@1 43 local name, realm = UnitName('player')
Nenue@1 44 realm = realm or GetRealmName()
Nenue@1 45 self.profileKey = name .. '-' .. realm
Nenue@1 46 if not self.data[self.profileKey] then
Nenue@1 47 self.data[self.profileKey] = {}
Nenue@1 48 end
Nenue@1 49 self.profile = self.data[self.profileKey]
Nenue@1 50
Nenue@1 51 self.initialized = true
Nenue@1 52 print('initialized')
Nenue@1 53 end
Nenue@1 54 end
Nenue@1 55 else
Nenue@1 56 self:Refresh ()
Nenue@1 57 end
Nenue@1 58 end
Nenue@1 59
Nenue@1 60 function core:UpdateList()
Nenue@1 61 self.sortedMissions = self.sortedMissions or {}
Nenue@1 62 table.wipe(self.sortedMissions)
Nenue@1 63
Nenue@1 64 for name, profile in pairs(self.data) do
Nenue@1 65 local isMine = (profile == self.profile)
Nenue@1 66 for index, data in pairs(profile.missions) do
Nenue@1 67
Nenue@1 68 data.classColor = profile.classColor or {r = 0.7, g = 0.7, b =0.7}
Nenue@1 69
Nenue@1 70 data.profileKey = name
Nenue@1 71 data.isMine = (profile == self.profile)
Nenue@1 72 tinsert(self.sortedMissions, data)
Nenue@1 73 end
Nenue@1 74 end
Nenue@1 75
Nenue@1 76 for i, v in ipairs(self.sortedMissions) do
Nenue@1 77 print(i, v.missionEndTime, v.name)
Nenue@1 78 end
Nenue@1 79
Nenue@1 80
Nenue@1 81 table.sort(self.sortedMissions, function(a,b)
Nenue@1 82 local result = false
Nenue@1 83 if not a or not b then
Nenue@1 84 result = true
Nenue@1 85 else
Nenue@1 86
Nenue@1 87 if (a.isMine ~= b.isMine) and self.playerFirst then
Nenue@1 88 result = a.isMine
Nenue@1 89 else
Nenue@1 90 if (not b.missionEndTime) or (not a.missionEndTime) then
Nenue@1 91 print('missing article', b.missionEndTime, a.missionEndTime)
Nenue@1 92 end
Nenue@1 93
Nenue@1 94 result = ( b.missionEndTime > a.missionEndTime)
Nenue@1 95 end
Nenue@1 96 end
Nenue@1 97
Nenue@1 98 print('cmp', (b and (b.missionEndTime .. ' ' .. tostring(b.isMine)) or '-'), '>', (a and (a.missionEndTime .. ' ' .. tostring(a.isMine)) or '-'), result, n)
Nenue@1 99 return result
Nenue@1 100 end)
Nenue@1 101 self.isStale = nil
Nenue@1 102
Nenue@1 103 local lastProfile
Nenue@1 104 local numItems = #self.sortedMissions
Nenue@1 105 for i, data in ipairs(self.sortedMissions) do
Nenue@1 106 local block = self.blocks[i]
Nenue@1 107 if not block then
Nenue@1 108 block = CreateFrame('Frame', nil, self, 'ClassPlanBlock')
Nenue@1 109 block:SetID(i)
Nenue@1 110 self.numBlocks = (self.numBlocks or 0) + 1
Nenue@1 111
Nenue@1 112 if self.lastBlock then
Nenue@1 113 block:SetPoint('TOPLEFT', self.lastBlock, 'BOTTOMLEFT', 0, 0)
Nenue@1 114 else
Nenue@1 115 block:SetPoint('TOPLEFT', self.portrait, 'TOPRIGHT', 0, 0)
Nenue@1 116 end
Nenue@1 117 self.lastBlock = block
Nenue@1 118 self.blocks[i] = block
Nenue@1 119 end
Nenue@1 120
Nenue@1 121 local r,g,b = 1, 1, 1
Nenue@1 122 if data.isRare then
Nenue@1 123 r,g,b = 0.1, 0.4, 1
Nenue@1 124 end
Nenue@1 125 if data.isMine then
Nenue@1 126 block.Icon:SetVertexColor(0,1,0,1)
Nenue@1 127 else
Nenue@1 128 block.Icon:SetVertexColor(1,1,1)
Nenue@1 129 end
Nenue@1 130
Nenue@1 131
Nenue@1 132 --block.missionData = data
Nenue@1 133 block.missionID = data.missionID
Nenue@1 134 block.missionEndTime = data.missionEndTime
Nenue@1 135 block.Icon:SetAtlas(data.typeAtlas, false)
Nenue@1 136 block.Label:SetText(data.name)
Nenue@1 137 block.Label:SetTextColor(r, g, b)
Nenue@1 138
Nenue@1 139 if lastProfile ~= data.profileKey then
Nenue@1 140 block.Owner:SetText(data.profileKey)
Nenue@1 141 block.Owner:SetTextColor(data.classColor.r, data.classColor.g, data.classColor.b)
Nenue@1 142 else
Nenue@1 143 block.Owner:SetText(nil)
Nenue@1 144 end
Nenue@1 145 block.Background:SetColorTexture(data.classColor.r, data.classColor.g, data.classColor.b, 0.5)
Nenue@1 146
Nenue@1 147 block:Show()
Nenue@1 148 lastProfile = data.profileKey
Nenue@1 149 end
Nenue@1 150 for i = numItems + 1, self.numBlocks do
Nenue@1 151 if self.blocks[i] then
Nenue@1 152 self.blocks[i]:Hide()
Nenue@1 153 end
Nenue@1 154 end
Nenue@1 155 end
Nenue@1 156
Nenue@1 157 function core:OnShow()
Nenue@1 158 if self.isStale then
Nenue@1 159 print('updating items on show')
Nenue@1 160 self:UpdateList()
Nenue@1 161 end
Nenue@1 162 end
Nenue@1 163
Nenue@1 164 function core:Refresh ()
Nenue@1 165 if not self.profile then
Nenue@1 166 return
Nenue@1 167 end
Nenue@1 168
Nenue@1 169 self.items = C_Garrison.GetLandingPageItems(LE_GARRISON_TYPE_7_0)
Nenue@1 170
Nenue@1 171 self.profile.missions = self.profile.missions or {}
Nenue@1 172
Nenue@1 173 self.profile.classColor = RAID_CLASS_COLORS[select(2, UnitClass('player'))]
Nenue@1 174
Nenue@1 175
Nenue@1 176 print('|cFF0088FFLocal Scoop|r:', self.profileKey)
Nenue@1 177 if #self.items >= 1 then
Nenue@1 178 table.wipe(self.profile.missions)
Nenue@1 179 for index, data in ipairs(self.items) do
Nenue@1 180 print('', data.name)
Nenue@1 181 print(' |cFF00FF00', data.timeLeft .. '|r', date("%A %I:%m %p", data.missionEndTime))
Nenue@1 182 tinsert(self.profile.missions, data)
Nenue@1 183 end
Nenue@1 184 end
Nenue@1 185
Nenue@1 186 if self:IsVisible() then
Nenue@1 187 self:UpdateList()
Nenue@1 188 else
Nenue@1 189 print('items update pending')
Nenue@1 190 self.isStale = true
Nenue@1 191 end
Nenue@1 192 end
Nenue@1 193
Nenue@1 194 function block:OnUpdate()
Nenue@1 195 if self.missionEndTime then
Nenue@1 196 local timeLeft = self.missionEndTime - time()
Nenue@1 197 if timeLeft < 0 then
Nenue@1 198 self.TimeLeft:SetText('Complete!')
Nenue@1 199 else
Nenue@1 200 local days = floor(timeLeft/(24*3600))
Nenue@1 201 local hours = floor(mod(timeLeft, (24*3600)) / 3600)
Nenue@1 202 local minutes = floor(mod(timeLeft, 3600) / 60)
Nenue@1 203 local seconds = mod(timeLeft, 60)
Nenue@1 204 self.TimeLeft:SetText(
Nenue@1 205 ((days > 0) and (days .. ' d') or '') ..
Nenue@1 206 ((hours > 0) and (' '.. hours .. ' hr') or '')..
Nenue@1 207 ((minutes > 0) and (' ' .. minutes .. ' min' or ''))
Nenue@1 208 , 1,1,1)
Nenue@1 209 end
Nenue@1 210 else
Nenue@1 211 self.TimeLeft:SetText(self.missionEndTime)
Nenue@1 212 end
Nenue@1 213 end