Files
coa-weakauras/WeakAuras/BaseRegions/StopMotion.lua
T
2025-04-03 21:03:11 +02:00

357 lines
12 KiB
Lua

if not WeakAuras.IsLibsOK() then return end
local AddonName = ...
local Private = select(2, ...)
local L = WeakAuras.L
local texture_data = WeakAuras.StopMotion.texture_data
Private.StopMotionBase = {}
-- Helper method for Options
function Private.StopMotionBase.textureNameHasData(textureName)
if not textureName then
return false
end
local pattern = "%.x(%d+)y(%d+)f(%d+)%.[tb][gl][ap]$"
local pattern2 = "%.x(%d+)y(%d+)f(%d+)w(%d+)h(%d+)W(%d+)H(%d+)%.[tb][gl][ap]$"
local ok = textureName:lower():match(pattern)
if ok then return true end
local ok2 = textureName:match(pattern2)
if ok2 then
return true
else
return false
end
end
local function setTile(texture, frame, rows, columns, frameScaleW, frameScaleH)
frame = frame - 1
local row = floor(frame / columns)
local column = frame % columns
local deltaX = frameScaleW / columns
local deltaY = frameScaleH / rows
local left = deltaX * column
local right = left + deltaX
local top = deltaY * row
local bottom = top + deltaY
pcall(function() texture:SetTexCoord(left, right, top, bottom) end)
end
WeakAuras.setTile = setTile
-- Helper method for Options
function Private.StopMotionBase.setTextureFunc(textureWidget, texturePath, textureName)
local data = texture_data[texturePath]
if not(data) then
local pattern = "%.x(%d+)y(%d+)f(%d+)%.[tb][gl][ap]"
local pattern2 = "%.x(%d+)y(%d+)f(%d+)w(%d+)h(%d+)W(%d+)H(%d+)%.[tb][gl][ap]"
local rows, columns, frames = texturePath:lower():match(pattern)
if rows then
data = {
count = tonumber(frames),
rows = tonumber(rows),
columns = tonumber(columns)
}
else
local rows, columns, frames, frameWidth, frameHeight, fileWidth, fileHeight = texturePath:match(pattern2)
if rows then
rows, columns, frames, frameWidth, frameHeight, fileWidth, fileHeight
= tonumber(rows), tonumber(columns), tonumber(frames), tonumber(frameWidth), tonumber(frameHeight),
tonumber(fileWidth), tonumber(fileHeight)
local frameScaleW = 1
local frameScaleH = 1
if fileWidth > 0 and frameWidth > 0 then
frameScaleW = (frameWidth * columns) / fileWidth
end
if fileHeight > 0 and frameHeight > 0 then
frameScaleH = (frameHeight * rows) / fileHeight
end
data = {
count = frames,
rows = rows,
columns = columns,
frameScaleW = frameScaleW,
frameScaleH = frameScaleH
}
end
end
end
textureWidget.frameNr = 0
if (data) then
if (data.rows and data.columns) then
-- Texture Atlas
textureWidget:SetTexture(texturePath, textureName)
setTile(textureWidget, data.count, data.rows, data.columns, data.frameScaleW or 1, data.frameScaleH or 1)
textureWidget:SetOnUpdate(function(self, elapsed)
self.elapsed = (self.elapsed or 0) + elapsed
if(self.elapsed > 0.1) then
self.elapsed = self.elapsed - 0.1
textureWidget.frameNr = textureWidget.frameNr + 1
if (textureWidget.frameNr == data.count) then
textureWidget.frameNr = 1
end
setTile(textureWidget, textureWidget.frameNr, data.rows, data.columns, data.frameScaleW or 1, data.frameScaleH or 1)
end
end)
else
-- Numbered Textures
local texture = texturePath .. string.format("%03d", texture_data[texturePath].count)
textureWidget:SetTexture(texture, textureName)
textureWidget:SetTexCoord(0, 1, 0, 1)
textureWidget:SetOnUpdate(function(self, elapsed)
self.elapsed = (self.elapsed or 0) + elapsed
if(self.elapsed > 0.1) then
self.elapsed = self.elapsed - 0.1
textureWidget.frameNr = textureWidget.frameNr + 1
if (textureWidget.frameNr == data.count) then
textureWidget.frameNr = 1
end
local texture = texturePath .. string.format("%03d", textureWidget.frameNr)
textureWidget:SetTexture(texture, textureName)
end
end)
end
else
local texture = texturePath .. string.format("%03d", 1)
textureWidget:SetTexture(texture, textureName)
end
end
local function SetTextureViaAtlas(self, texture)
self.texture:SetTexture(texture)
end
local function SetFrameViaAtlas(self, texture, frame)
local frameScaleW = 1
local frameScaleH = 1
if self.fileWidth and self.frameWidth and self.fileWidth > 0 and self.frameWidth > 0 then
frameScaleW = (self.frameWidth * self.columns) / self.fileWidth
end
if self.fileHeight and self.frameHeight and self.fileHeight > 0 and self.frameHeight > 0 then
frameScaleH = (self.frameHeight * self.rows) / self.fileHeight
end
setTile(self.texture, frame, self.rows, self.columns, frameScaleW, frameScaleH)
end
local function SetTextureViaFrames(self, texture)
self.texture:SetTexture(texture .. string.format("%03d", 0))
self.texture:SetTexCoord(0, 1, 0, 1)
end
local function SetFrameViaFrames(self, texture, frame)
self.texture:SetTexture(texture .. string.format("%03d", frame))
end
local funcs = {
SetDesaturated = function(self, b)
self.texture:SetDesaturated(b)
end,
SetColor = function(self, r, g, b, a)
self.texture:SetVertexColor(r, g, b, a)
end,
GetColor = function(self)
return self.texture:GetVertexColor()
end,
SetStartTime = function(self, time)
self.startTime = time
end,
TimedUpdate = function(self)
local timeSinceStart = (GetTime() - self.startTime)
local newCurrentFrame = floor(timeSinceStart * (self.frameRate or 15))
if (newCurrentFrame == self.currentFrame) then
return
end
self.currentFrame = newCurrentFrame
local frames
local startFrame = self.startFrame
local endFrame = self.endFrame
local inverse = self.inverseDirection
if (endFrame >= startFrame) then
frames = endFrame - startFrame + 1
else
frames = startFrame - endFrame + 1
startFrame, endFrame = endFrame, startFrame
inverse = not inverse
end
local frame = 0
if (self.animationType == "loop") then
frame = (newCurrentFrame % frames) + startFrame
elseif (self.animationType == "bounce") then
local direction = floor(newCurrentFrame / frames) % 2
if (direction == 0) then
frame = (newCurrentFrame % frames) + startFrame
else
frame = endFrame - (newCurrentFrame % frames)
end
elseif (self.animationType == "once") then
frame = newCurrentFrame + startFrame
if (frame > endFrame) then
frame = endFrame
end
end
if (inverse) then
frame = endFrame - frame + startFrame
end
if (frame > endFrame) then
frame = endFrame
end
if (frame < startFrame) then
frame = startFrame
end
self:SetFrame(self.textureFile, frame)
end,
SetProgress = function(self, progress)
local frames
local startFrame = self.startFrame
local endFrame = self.endFrame
local inverse = self.inverseDirection
if (endFrame >= startFrame) then
frames = endFrame - startFrame + 1
else
frames = startFrame - endFrame + 1
startFrame, endFrame = endFrame, startFrame
inverse = not inverse
end
local frame = floor( (frames - 1) * progress) + startFrame
if (inverse) then
frame = endFrame - frame + startFrame
end
if (frame > endFrame) then
frame = endFrame
end
if (frame < startFrame) then
frame = startFrame
end
self:SetFrame(self.textureFile, frame)
end,
ClearAllPoints = function(self)
self.texture:ClearAllPoints()
end,
SetAllPoints = function(self, ...)
self.texture:SetAllPoints(...)
end,
SetPoint = function(self, ...)
self.texture:SetPoint(...)
end,
SetSize = function(self, w, h)
self.texture:SetSize(w, h)
end,
SetVisible = function(self, b)
if b then
self.texture:Show()
else
self.texture:Hide()
end
end
}
function Private.StopMotionBase.create(frame, drawLayer)
local stopMotion = {}
local texture = frame:CreateTexture(nil, "ARTWORK")
stopMotion.texture = texture
texture:SetAllPoints(frame)
for funcName, func in pairs(funcs) do
stopMotion[funcName] = func
end
return stopMotion
end
function Private.StopMotionBase.modify(stopMotion, options)
stopMotion.frameRate = options.frameRate
stopMotion.inverseDirection = options.inverseDirection
stopMotion.animationType = options.animationType
stopMotion.textureFile = options.texture
local pattern = "%.x(%d+)y(%d+)f(%d+)%.[tb][gl][ap]"
local pattern2 = "%.x(%d+)y(%d+)f(%d+)w(%d+)h(%d+)W(%d+)H(%d+)%.[tb][gl][ap]"
do -- setup texture
local tdata = texture_data[stopMotion.textureFile]
if (tdata) then
local lastFrame = tdata.count - 1
stopMotion.lastFrame = lastFrame
stopMotion.startFrame = floor( (options.startPercent or 0) * lastFrame) + 1
stopMotion.endFrame = floor( (options.endPercent or 1) * lastFrame) + 1
stopMotion.rows = tdata.rows
stopMotion.columns = tdata.columns
stopMotion.fileWidth = 0
stopMotion.fileHeight = 0
stopMotion.frameWidth = 0
stopMotion.frameHeight = 0
else
local rows, columns, frames = stopMotion.textureFile:lower():match(pattern)
if rows then
local lastFrame = tonumber(frames) - 1
stopMotion.lastFrame = lastFrame
stopMotion.startFrame = floor( (options.startPercent or 0) * lastFrame) + 1
stopMotion.endFrame = floor( (options.endPercent or 1) * lastFrame) + 1
stopMotion.rows = tonumber(rows)
stopMotion.columns = tonumber(columns)
stopMotion.fileWidth = 0
stopMotion.fileHeight = 0
stopMotion.frameWidth = 0
stopMotion.frameHeight = 0
else
local rows, columns, frames, frameWidth, frameHeight, fileWidth, fileHeight
= stopMotion.textureFile:match(pattern2)
if rows then
local lastFrame = tonumber(frames) - 1
stopMotion.lastFrame = lastFrame
stopMotion.startFrame = floor( (options.startPercent or 0) * lastFrame) + 1
stopMotion.endFrame = floor( (options.endPercent or 1) * lastFrame) + 1
stopMotion.rows = tonumber(rows)
stopMotion.columns = tonumber(columns)
stopMotion.fileWidth = tonumber(fileWidth)
stopMotion.fileHeight = tonumber(fileHeight)
stopMotion.frameWidth = tonumber(frameWidth)
stopMotion.frameHeight = tonumber(frameHeight)
else
local lastFrame = (options.customFrames or 256) - 1
stopMotion.lastFrame = lastFrame
stopMotion.startFrame = floor( (options.startPercent or 0) * lastFrame) + 1
stopMotion.endFrame = floor( (options.endPercent or 1) * lastFrame) + 1
stopMotion.rows = options.customRows
stopMotion.columns = options.customColumns
stopMotion.fileWidth = options.customFileWidth
stopMotion.fileHeight = options.customFileHeight
stopMotion.frameWidth = options.customFrameWidth
stopMotion.frameHeight = options.customFrameHeight
end
end
end
end
if (stopMotion.rows and stopMotion.columns) then
stopMotion.SetBaseTexture = SetTextureViaAtlas
stopMotion.SetFrame = SetFrameViaAtlas
else
stopMotion.SetBaseTexture = SetTextureViaFrames
stopMotion.SetFrame = SetFrameViaFrames
end
stopMotion:SetBaseTexture(options.texture)
if stopMotion.animationType == "background" then
stopMotion:SetFrame(options.texture, stopMotion.endFrame or 1)
else
stopMotion:SetFrame(options.texture, 1)
end
stopMotion.texture:SetBlendMode(options.blendMode)
end