Files
wow-weakauras/FreshShit/Absorbs/init.lua

210 lines
5.2 KiB
Lua

---@alias Color {r: number, g: number, b: number}
---@class Colorer
---@field colors table<number, Color>
---@field breakpoints table<number>
Colorer = {
--- Make sure colors and breakpoints always have the same number of entries! VERY IMPORTANT!
---@type table<number, Color>
colors = {
{ r = 0.62, g = 0.62, b = 0.62 }, -- Grey
-- { r = 1, g = 1, b = 1 }, -- White
{ r = 0.12, g = 1, b = 0 }, -- Green
{ r = 0, g = 0.44, b = 0.87 }, -- Blue
{ r = 0.64, g = 0.21, b = 0.93 }, -- Purple
{ r = 1, g = 0.5, b = 0 }, -- Orange
{ r = 0.9, g = 0.8, b = 0.5 }, -- Light Gold
{ r = 0, g = 0.8, b = 1.0 }, -- Blizzard Blue
},
breakpoints = { 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1000.0 },
---@param value number
---@return Color, nil|string
Interpolate = function(value)
local color = { r = 0, g = 0, b = 0 }
---@type table<number, table<number, number>>
local bracket = { { 0, 0 }, { 1, 1 } }
for i = 1, #Colorer.breakpoints do
if value < Colorer.breakpoints[i] then
bracket[2] = { i, Colorer.breakpoints[i] }
break
end
bracket[1] = { i, Colorer.breakpoints[i] }
end
---@type Color
local startColor = Colorer.colors[bracket[1][1]]
---@type Color
local endColor = Colorer.colors[bracket[2][1]]
local fraction = (value - bracket[1][2]) / (bracket[2][2] - bracket[1][2])
for k, v in pairs(startColor) do
color[k] = Colorer.lerp(v, endColor[k], fraction)
end
return color, nil
end,
---@param a number
---@param b number
---@param t number
---@return number
lerp = function(a, b, t)
return a * (1 - t) + b * t
end
}
setmetatable(Colorer, { __index = Colorer })
---@class ShieldBuffer
---@field records table<number, number>
---@field recordsToKeep number
---@field pointer number
ShieldBuffer = {
---@param recordsToKeep number
---@return ShieldBuffer
new = function(recordsToKeep)
local self = setmetatable({}, {
__index = ShieldBuffer
})
self.recordsToKeep = recordsToKeep
self.records = {}
self.pointer = 1
for i = 1, recordsToKeep do
self.records[i] = 0
end
return self
end,
---@param self ShieldBuffer
---@param shieldValue number
---@return nil
Append = function(self, shieldValue)
self.records[self.pointer] = shieldValue
self.pointer = (self.pointer % self.recordsToKeep) + 1
end,
---@param self ShieldBuffer
---@return number
GetMax = function(self)
local max = 0
for _, value in pairs(self.records) do
if value > max then
max = value
end
end
if max == nil then return 0 end
return max
end,
---@param self ShieldBuffer
---@return number
GetCurrent = function(self)
local val = self.records[(self.pointer + self.recordsToKeep - 2) % self.recordsToKeep + 1]
if val == nil then return 0 end
return val
end
}
---@class Shield
---@field name string
---@field value number
---@field buffer ShieldBuffer
Shield = {
---@param name string
---@return Shield
new = function(name)
local self = setmetatable({}, {
__index = Shield
})
self.name = name
self.value = 0
self.buffer = ShieldBuffer.new(30)
return self
end,
---@param self Shield
---@return nil, nil|string
Update = function(self)
local shieldValue = select(17, UnitAura("player", self.name))
if shieldValue then
self.value = shieldValue
else
self.value = 0
end
self.buffer:Append(self.value)
end
}
---@class ShieldManager
ShieldManager = {
---@return number
GetMax = function()
local value = 0
for _, shield in pairs(Shields) do
value = value + shield.buffer:GetMax()
end
return value
end,
---@return number
GetCurrent = function()
local value = 0
for _, shield in pairs(Shields) do
value = value + shield.buffer:GetCurrent()
end
return value
end,
---@return number current
---@return number max
GetStats = function()
local max = 0
local current = 0
for _, shield in pairs(Shields) do
max = max + shield.buffer:GetMax()
current = current + shield.buffer:GetCurrent()
end
return current, max
end,
---@return string current
---@return string max
---@return number current (raw)
---@return number max (raw)
GetStatsNice = function()
local current, max = ShieldManager.GetStats()
if max > 1e6 or current > 1e6 then
return string.format("%.1fM", current / 1e6), string.format("%.1fM", max / 1e6), current, max
end
return string.format("%.0fk", current / 1000), string.format("%.0fk", max / 1000), current, max
end
}
---@class Display
---@field current number
---@field max number
---@field currentRaw number
---@field maxRaw number
---@field ofHp string
---@field ofHpRaw number
---@field ofHpRawFraction number
---@field color Color
Display = {
Update = function()
local current, max, currentRaw, maxRaw = ShieldManager.GetStatsNice()
local hp = UnitHealthMax("player")
Display.current = current
Display.max = max
Display.currentRaw = currentRaw
Display.maxRaw = maxRaw
Display.ofHpRaw = currentRaw / hp * 100
Display.ofHpRawFraction = Display.ofHpRaw / 100
Display.ofHp = string.format("%.0f%%", Display.ofHpRaw)
Display.color = Colorer.Interpolate(Display.ofHpRawFraction)
return nil
end
}
---@type table<Shield>
Shields = {
[108366] = Shield.new("Soul Leech"),
[108416] = Shield.new("Dark Pact"),
[207472] = Shield.new("Xavaric's Magnum Opus"),
}