comparison Modules/ArtifactPower.lua @ 97:5476337198ec

- apply default anchors when docking modules - Arifact Power tracker: totals AP items in bags and bank, and forecasts progress on each weapon. Requires user to shift-click each weapon at least once to get initial XP data.
author Nenue
date Mon, 16 Jan 2017 20:24:12 -0500
parents
children dadddb8a551f
comparison
equal deleted inserted replaced
96:bb38bc0e787f 97:5476337198ec
1 -- Veneer
2 -- ArtifactPower.lua
3 -- Created: 1/15/2017 11:44 PM
4 -- %file-revision%
5 --
6
7 local print = DEVIAN_WORKSPACE and function(...) print('VnAP', ...) end or nop
8 VeneerArtifactPowerMixin = {
9
10 anchorPoint = 'TOP',
11 anchorFrom = 'TOP',
12 }
13 local ap = VeneerArtifactPowerMixin
14 local BAGS_TO_SCAN = {BACKPACK_CONTAINER }
15 local TOOLTIP_NAME = 'VeneerAPScanner'
16
17 function ap:OnLoad()
18 self:RegisterEvent('BAG_UPDATE') -- use to obtain bag IDs to scan
19 self:RegisterEvent('BAG_UPDATE_DELAYED') -- use to trigger actual scan activity
20 self:RegisterEvent('BANKFRAME_OPENED') -- determine when bank info is available
21 self:RegisterEvent('BANKFRAME_CLOSED') -- " " "
22 self:RegisterEvent('ARTIFACT_UPDATE') -- when artifact data has changed
23 self:RegisterEvent('ARTIFACT_UPDATE_XP') -- when artifact xp has changed (but not necessarily data)
24 self:RegisterEvent('MODIFIER_STATE_CHANGED')
25 self:RegisterEvent('PLAYER_REGEN_ENABLED')
26 self:RegisterEvent('PLAYER_REGEN_DISABLED')
27 Veneer:AddHandler(self, self.anchorPoint, true)
28 SLASH_VENEER_AP1 = "/vap"
29 SLASH_VENEER_AP2 = "/veneerap"
30 SlashCmdList.VENEER_AP = function()
31 self:Show()
32 end
33
34 self.tooltip = CreateFrame('GameTooltip', TOOLTIP_NAME, self, 'GameTooltipTemplate')
35
36 end
37
38 local defaultSettings = {
39 }
40
41 function ap:Setup()
42 print(self:GetName()..':Setup()')
43 local guid = UnitGUID('player')
44 VeneerData.ArtifactPower = VeneerData.ArtifactPower or defaultSettings
45 VeneerData.ArtifactPower[guid] = VeneerData.ArtifactPower[guid] or {}
46 self.profile = VeneerData.ArtifactPower[guid]
47 self.profile.bagslots = self.profile.bagslots or {}
48 self.profile.artifacts = self.profile.artifacts or {}
49 self:GetCurrentArtifact(true)
50 self.updateSummary = true
51
52 -- Bagnon compatibility
53 -- todo: ArkInventory, Elv, etc
54 if IsAddOnLoaded('Bagnon') then
55 local oToggleAllBags = ToggleAllBags
56 ToggleAllBags = function()
57 print('|cFFFF0088ToggleAllBags')
58 oToggleAllBags()
59 if BagnonFrameinventory:IsShown() then
60 self:Show()
61 else
62 self.enabled = nil
63 self:Hide()
64 end
65 end
66 else
67 hooksecurefunc("OpenBackpack", function()
68 self:Show()
69 end)
70 hooksecurefunc("CloseBackpack", function()
71 self.enabled = nil
72 self:Hide()
73 end)
74 end
75
76
77 end
78 local UNDERLIGHT_ANGLER_ID = 133755
79 function ap:GetCurrentArtifact(newItem)
80 if not self.profile then
81 return
82 end
83 local artifacts = self.profile.artifacts
84 local itemID, altItemID, name, texture, currentXP, pointsSpent, _, _, artifactAppearanceID, appearanceModID, itemAppearanceID, altItemAppearanceID, altOnTop = C_ArtifactUI:GetArtifactInfo()
85
86
87 if itemID then
88
89
90
91
92 print('updating', itemID, name, currentXP, pointsSpent, pointsAvailable, adjustedXP)
93 table.wipe(artifacts[itemID])
94 artifacts[itemID] = artifacts[itemID] or {}
95 artifacts[itemID].name = name
96 artifacts[itemID].texture = texture
97 artifacts[itemID].currentXP = currentXP
98 artifacts[itemID].level = pointsSpent
99 end
100
101
102 self:Update()
103 end
104 function ap:QueueBag(containerID)
105 containerID = tonumber(containerID)
106 if not containerID then
107 return
108 end
109
110 if not tContains(BAGS_TO_SCAN, containerID) then
111 print(' queueing', containerID, type(containerID), #BAGS_TO_SCAN , 'in line')
112 BAGS_TO_SCAN[#BAGS_TO_SCAN + 1] = containerID
113 end
114 end
115
116 function ap:OnShow()
117 self.enabled = true
118 self:Update()
119 Veneer:DynamicReanchor()
120 end
121 function ap:OnHide()
122 Veneer:DynamicReanchor()
123 end
124
125 function ap:OnEnter()
126
127 GameTooltip:SetOwner(self, 'ANCHOR_CURSOR')
128
129 GameTooltip:AddLine(self.bagAP)
130 GameTooltip:AddLine(self.bankAP)
131
132 end
133
134 function ap:OnEvent(event, ...)
135 print(self:GetName()..':OnEvent()', event, ...)
136 if event == 'BAG_UPDATE' then
137 local containerID = ...
138 self:QueueBag(containerID)
139 elseif event == 'PLAYER_BANKSLOTS_CHANGED' then
140 self:QueueBag(BANK_CONTAINER)
141 elseif event == 'BAG_UPDATE_DELAYED' then
142 self:ScanAllBags()
143 elseif event == 'BANKFRAME_OPENED' then
144 self.bankAccess = true
145 self:QueueBag(BANK_CONTAINER)
146 for i = 1, GetNumBankSlots() do
147 self:QueueBag(i+NUM_BAG_SLOTS)
148 end
149 self:ScanAllBags()
150 elseif event == 'BANKFRAME_CLOSED' then
151 self.bankAccess = false
152 self:Update()
153 elseif event == 'ARTIFACT_UPDATE' then
154 self:GetCurrentArtifact(...)
155 elseif event == 'ARTIFACT_UPDATE_XP' then
156 self:GetCurrentArtifact(...)
157 self:Update()
158 elseif event == 'MODIFIER_STATE_CHANGED' then
159 self:Update()
160 elseif event == 'PLAYER_REGEN_ENABLED' then
161 if self.enabled then
162 self:Show()
163 end
164
165 elseif event == 'PLAYER_REGEN_DISABLED' then
166 self:Hide()
167 end
168 end
169
170 function ap:OnMouseDown()
171 self.enabled = nil
172 self:Hide()
173 end
174
175 function ap:Update()
176 if not self:IsShown() then
177 return
178 end
179 print('|cFF00FFFFUpdate()|r')
180
181 local bankText, bagText
182 if not (self.bankAP and self.bagAP) then
183 bankText = '|cFFFF0000Open bank frame to count all AP|r '
184 else
185 bankText = '|cFFFFFFFFAP:|r' .. tostring(self.bagAP + self.bankAP) .. ' |cFFFFFF00('..tostring(self.bankAP)..' banked)|r'
186 end
187 self.SummaryHeader:SetText(bankText)
188
189 -- Artifact icons, in no particular order
190 local equippedID = C_ArtifactUI.GetEquippedArtifactInfo()
191 local numButtons = 0
192 local lastFrame
193 for itemID, artifact in pairs(self.profile.artifacts) do
194 print(artifact.name, artifact.texture, artifact.currentXP)
195 numButtons = numButtons + 1
196 local button = self.Artifact[numButtons]
197
198 button:SetID(itemID)
199 for k,v in pairs(artifact) do
200 --print('::',k,v)
201 button[k] = v
202 end
203
204
205 local pointsAvailable = button.level
206 local cost = C_ArtifactUI.GetCostForPointAtRank(pointsAvailable)
207 local adjustedXP = button.currentXP
208 if itemID ~= UNDERLIGHT_ANGLER_ID then
209 adjustedXP = adjustedXP + (self.bankAP or 0) + (self.bagAP or 0)
210 print('not UL angler', adjustedXP)
211 else
212 print('UL angler', adjustedXP)
213 end
214
215 while adjustedXP >= cost do
216 pointsAvailable = pointsAvailable + 1
217 adjustedXP = adjustedXP - cost
218 print(pointsAvailable, '-', cost, '=', adjustedXP)
219 cost = C_ArtifactUI.GetCostForPointAtRank(pointsAvailable)
220 end
221 button.adjustedXP = adjustedXP
222 button.actualLevel = pointsAvailable
223
224 button.isEquipped = (equippedID == itemID)
225 button.relativeFrame = lastFrame
226 button:Update()
227 lastFrame = button
228 button:Show()
229 end
230 for i = numButtons+1, #self.Artifact do
231 print('hide', i)
232 self.Artifact[i]:Hide()
233 end
234
235
236
237 self:SetWidth(64*3+ 16)
238 self:SetHeight(8 + self.SummaryHeader:GetHeight() + 64)
239 self:Reanchor()
240
241 end
242
243 function ap:ScanBag(id)
244 print('|cFF00FFFFScanBag()|r', id, IsBagOpen(id), GetContainerNumSlots(id))
245 local numSlots = GetContainerNumSlots(id)
246 local requiresUpdate
247 if numSlots == 0 then
248 return nil
249 end
250
251
252 self.profile.bagslots[id] = self.profile.bagslots[id] or {}
253 table.wipe(self.profile.bagslots[id])
254 local bagData = self.profile.bagslots[id]
255 bagData.totalAP = 0
256 for slotID = 1, numSlots do
257 local texture, count, locked, quality, readable, lootable, link = GetContainerItemInfo(id, slotID)
258 local itemID = GetContainerItemID(id, slotID)
259
260 if link then
261 self.tooltip:SetOwner(self, 'ANCHOR_NONE')
262 self.tooltip:SetHyperlink(link)
263 self.tooltip:Show()
264 local numLines = self.tooltip:NumLines()
265 if numLines >= 3 then
266 local subText = _G[TOOLTIP_NAME .. 'TextLeft2']:GetText()
267 if subText and subText:match(ARTIFACT_POWER) then
268 for i = 3, numLines do
269 local text = _G[TOOLTIP_NAME .. 'TextLeft'.. i]:GetText()
270 if text and text:match(ARTIFACT_POWER) then
271 text = text:gsub('[,%D]', '')
272 print(link, '-', tonumber(text))
273 local itemAP = tonumber(text)
274 if itemAP then
275 bagData.numItems = (bagData.numItems or 0) + 1
276 bagData.totalAP = (bagData.totalAP or 0) + itemAP
277 bagData.items = bagData.items or {}
278 if not bagData.items[itemID] then
279 requiresUpdate = true
280 bagData.numUnique = (bagData.numUnique or 0) + 1
281 end
282 bagData.items[itemID] = (bagData.items[itemAP] or 0) + 1
283 end
284 end
285 end
286 end
287 end
288 end
289
290 if self.profile.artifacts[itemID] then
291 print('artfiact weapon', itemID, link, id, slotID)
292 self.profile.artifacts[itemID].containerID = id
293 self.profile.artifacts[itemID].slotID = slotID
294 end
295
296 end
297
298 return requiresUpdate
299 end
300
301 function ap:ScanAllBags()
302 print('|cFFFF0088ScanAllBags()|r')
303
304 local bagID = tremove(BAGS_TO_SCAN, 1)
305 while bagID do
306 self.updateSummary = self:ScanBag(bagID) or self.updateSummary
307 bagID = tremove(BAGS_TO_SCAN, 1)
308 end
309
310 if self.updateSummary then
311 print('tripped updater')
312 self.bankAP = 0
313 self.bagAP = 0
314 for id, bagData in pairs(self.profile.bagslots) do
315 print(id, GetBagName(id), bagData.totalAP)
316 id = tonumber(id)
317 if bagData.totalAP then
318 if (id == BANK_CONTAINER) or (id >= 5) then
319 self.bankAP = self.bankAP + bagData.totalAP
320 else
321 self.bagAP = self.bagAP + bagData.totalAP
322 end
323 end
324
325 end
326 self.lastUpdate = GetTime()
327 self:Update()
328 end
329 self.updateSummary = nil
330 end
331
332 VeneerArtifactButtonMixin = {}
333 function VeneerArtifactButtonMixin:Update()
334
335 if self.actualLevel ~= self.level then
336 self.Level:SetText(self.actualLevel)
337 self.Level:SetTextColor(0,1,0)
338 self.CurrentXP:SetText(self.adjustedXP)
339 self.CurrentXP:SetTextColor(0,1,0)
340 else
341 self.Level:SetText(self.level, 1, 1, 1)
342 self.Level:SetTextColor(1,1,1)
343 self.CurrentXP:SetText(self.currentXP)
344 self.CurrentXP:SetTextColor(1,1,0)
345 end
346
347 if self.isEquipped then
348 self:SetNormalTexture([[Interface\Buttons\ButtonHilight-Square]])
349 self:GetNormalTexture():SetBlendMode('ADD')
350 self:GetNormalTexture():SetVertexColor(0,1,0)
351 else
352 self:SetNormalTexture(nil, 'ADD')
353 end
354
355 self:ClearAllPoints()
356 if self.relativeFrame then
357 self:SetPoint('BOTTOMLEFT', self.relativeFrame, 'BOTTOMRIGHT', 4, 0)
358 else
359 self:SetPoint('BOTTOMLEFT', 4, 4)
360 end
361
362
363
364 self.Icon:SetTexture(self.texture)
365 self.Name:SetText(self.name)
366 self:SetSize(64,64)
367 end
368
369 function VeneerArtifactButtonMixin:OnEnter()
370 GameTooltip:SetOwner(self, 'ANCHOR_CURSOR')
371 GameTooltip:SetText(self.name)
372 GameTooltip:AddLine(self.currentXP, 1, 1, 0)
373 if self.adjustedXP ~= self.currentXP then
374 GameTooltip:AddLine(self.adjustedXP, 0, 1, 1)
375 end
376
377
378 GameTooltip:Show()
379 end
380 function VeneerArtifactButtonMixin:OnLeave()
381 if GameTooltip:IsOwned(self) then
382 GameTooltip:Hide()
383 end
384 end
385
386 function VeneerArtifactButtonMixin:OnClick(button, down)
387 if self.isEquipped then
388 SocketInventoryItem(16)
389 else
390 SocketContainerItem(self.containerID, self.slotID)
391 end
392 end