EvilMaddness |
12-22-22 08:20 AM |
Alright guys I need your help on this one.
It's been many years since I posted on here. But I'm back and need a lot of help with this code.
We all know WeakAuras has a ring feature for Unit Frames health, mana, power or anything you can think of for it but I'm trying to make a stand alone add-on just for the Unit Frames.
This code works but the animation doesn't run as smoothly as it does in WeakAuras or have key features like a option display in game so we can set the start and end angles where we need them to be, which color to pick, ect.
So I'm asking for anyone who would like to help build this code up more and get it to that level of greatness.
That's what it's all about. Someone here might be an expert on how to display options in game for this or someone else might know how to make the animation run smoother.
Your welcome to have a crack at it. Lots of credit goes to Fizzlemizz she helped me with most of the code while I would be in game putting it in place. Sorry I don't have the textures to share to see it in game but if you know anyway to add in a start and end angle option or make this run smoother with the animation please do! Thank you!!!
Code:
-- Usage:
-- spinner = CreateSpinner(parent)
-- spinner:SetTexture('texturePath')
-- spinner:SetBlendMode('blendMode')
-- spinner:SetVertexColor(r, g, b)
-- spinner:SetClockwise(boolean) -- true to fill clockwise, false to fill counterclockwise
-- spinner:SetReverse(boolean) -- true to empty the bar instead of filling it
-- spinner:SetValue(percent) -- value between 0 and 1 to fill the bar to
-- Some math stuff
local cos, sin, pi2, halfpi = math.cos, math.sin, math.rad(360), math.rad(90)
local function Transform(tx, x, y, angle, aspect) -- Translates texture to x, y and rotates about its center
local c, s = cos(angle), sin(angle)
local y, oy = y / aspect, 0.5 / aspect
local ULx, ULy = 0.5 + (x - 0.5) * c - (y - oy) * s, (oy + (y - oy) * c + (x - 0.5) * s) * aspect
local LLx, LLy = 0.5 + (x - 0.5) * c - (y + oy) * s, (oy + (y + oy) * c + (x - 0.5) * s) * aspect
local URx, URy = 0.5 + (x + 0.5) * c - (y - oy) * s, (oy + (y - oy) * c + (x + 0.5) * s) * aspect
local LRx, LRy = 0.5 + (x + 0.5) * c - (y + oy) * s, (oy + (y + oy) * c + (x + 0.5) * s) * aspect
tx:SetTexCoord(ULx, ULy, LLx, LLy, URx, URy, LRx, LRy)
end
-- Permanently pause our rotation animation after it starts playing
local function OnPlayUpdate(self)
self:SetScript('OnUpdate', nil)
self:Pause()
end
local function OnPlay(self)
self:SetScript('OnUpdate', OnPlayUpdate)
end
local function SetValue(self, value)
-- Correct invalid ranges, preferably just don't feed it invalid numbers
if value > 1 then value = 1
elseif value < 0 then value = 0 end
-- Reverse our normal behavior
if self._reverse then
value = 1 - value
end
-- Determine which quadrant we're in
local q, quadrant = self._clockwise and (1 - value) or value -- 4 - floor(value / 0.25)
if q >= 0.75 then
quadrant = 1
elseif q >= 0.5 then
quadrant = 2
elseif q >= 0.25 then
quadrant = 3
else
quadrant = 4
end
if self._quadrant ~= quadrant then
self._quadrant = quadrant
-- Show/hide necessary textures if we need to
if self._clockwise then
for i = 1, 4 do
self._textures[i]:SetShown(i < quadrant)
end
else
for i = 1, 4 do
self._textures[i]:SetShown(i > quadrant)
end
end
-- Move scrollframe/wedge to the proper quadrant
self._scrollframe:SetAllPoints(self._textures[quadrant])
end
-- Rotate the things
local rads = value * pi2
if not self._clockwise then rads = -rads + halfpi end
Transform(self._wedge, -0.5, -0.5, rads, self._aspect)
self._rotation:SetRadians(-rads)
end
local function SetClockwise(self, clockwise)
self._clockwise = clockwise
end
local function SetReverse(self, reverse)
self._reverse = reverse
end
local function OnSizeChanged(self, width, height)
self._wedge:SetSize(width, height) -- it's important to keep this texture sized correctly
self._aspect = width / height -- required to calculate the texture coordinates
end
-- Creates a function that calls a method on all textures at once
local function CreateTextureFunction(func, self, ...)
return function(self, ...)
for i = 1, 4 do
local tx = self._textures[i]
tx[func](tx, ...)
end
self._wedge[func](self._wedge, ...)
end
end
-- Pass calls to these functions on our frame to its textures
local TextureFunctions = {
SetTexture = CreateTextureFunction('SetTexture'),
SetBlendMode = CreateTextureFunction('SetBlendMode'),
SetVertexColor = CreateTextureFunction('SetVertexColor'),
}
local function CreateSpinner(parent)
local spinner = CreateFrame('Frame', nil, parent)
-- ScrollFrame clips the actively animating portion of the spinner
local scrollframe = CreateFrame('ScrollFrame', nil, spinner)
scrollframe:SetPoint('BOTTOMLEFT', spinner, 'CENTER')
scrollframe:SetPoint('TOPRIGHT')
spinner._scrollframe = scrollframe
local scrollchild = CreateFrame('frame', nil, scrollframe)
scrollframe:SetScrollChild(scrollchild)
scrollchild:SetAllPoints(scrollframe)
-- Wedge thing
local wedge = scrollchild:CreateTexture()
wedge:SetPoint('BOTTOMRIGHT', spinner, 'CENTER')
spinner._wedge = wedge
-- Top Right
local trTexture = spinner:CreateTexture()
trTexture:SetPoint('BOTTOMLEFT', spinner, 'CENTER')
trTexture:SetPoint('TOPRIGHT')
trTexture:SetTexCoord(0.5, 1, 0, 0.5)
-- Bottom Right
local brTexture = spinner:CreateTexture()
brTexture:SetPoint('TOPLEFT', spinner, 'CENTER')
brTexture:SetPoint('BOTTOMRIGHT')
brTexture:SetTexCoord(0.5, 1, 0.5, 1)
-- Bottom Left
local blTexture = spinner:CreateTexture()
blTexture:SetPoint('TOPRIGHT', spinner, 'CENTER')
blTexture:SetPoint('BOTTOMLEFT')
blTexture:SetTexCoord(0, 0.5, 0.5, 1)
-- Top Left
local tlTexture = spinner:CreateTexture()
tlTexture:SetPoint('BOTTOMRIGHT', spinner, 'CENTER')
tlTexture:SetPoint('TOPLEFT')
tlTexture:SetTexCoord(0, 0.5, 0, 0.5)
-- /4|1\ -- Clockwise texture arrangement
-- \3|2/ --
spinner._textures = {trTexture, brTexture, blTexture, tlTexture}
spinner._quadrant = nil -- Current active quadrant
spinner._clockwise = true -- fill clockwise
spinner._reverse = false -- Treat the provided value as its inverse, eg. 75% will display as 25%
spinner._aspect = 1 -- aspect ratio, width / height of spinner frame
spinner:HookScript('OnSizeChanged', OnSizeChanged)
for method, func in pairs(TextureFunctions) do
spinner[method] = func
end
spinner.SetClockwise = SetClockwise
spinner.SetReverse = SetReverse
spinner.SetValue = SetValue
local group = wedge:CreateAnimationGroup()
local rotation = group:CreateAnimation('Rotation')
spinner._rotation = rotation
rotation:SetSmoothing("IN_OUT")
rotation:SetDuration(0)
rotation:SetEndDelay(1)
rotation:SetOrigin('BOTTOMRIGHT', 0, 0)
group:SetScript('OnPlay', OnPlay)
group:Play()
return spinner
end
local spinner1 = CreateSpinner(UIParent)
spinner1:SetPoint('CENTER', TargetFrame.TargetFrameContainer.Portrait)
spinner1:SetSize(116, 108)
spinner1:SetTexture("Interface\\Addons\\Images\\Ring_20px")
spinner1:SetVertexColor(0, 1, 0)
spinner1:SetClockwise(false)
spinner1:SetReverse(false)
spinner1:Hide()
spinner1.Background = spinner1:CreateTexture()
spinner1.Background:SetDrawLayer("BACKGROUND", -1)
spinner1.Background:SetSize(155, 142)
spinner1.Background:SetPoint("CENTER", TargetFrame.TargetFrameContainer.Portrait)
spinner1.Background:SetTexture("Interface\\Addons\\Images\\FullCircleFrameTwo")
local CenterOverlay = CreateFrame("Frame", nil, spinner1)
CenterOverlay:SetFrameLevel(0)
CenterOverlay:SetSize(100, 100)
CenterOverlay:SetPoint("CENTER")
CenterOverlay.Texture = CenterOverlay:CreateTexture()
CenterOverlay.Texture:SetAllPoints()
CenterOverlay.Texture:SetTexture("Interface\\Masks\\CircleMaskScalable")
CenterOverlay.Texture:SetVertexColor(0, 0, 0)
local healthmax = 0
local health = 0
spinner1:RegisterUnitEvent("UNIT_HEALTH", target)
spinner1:RegisterEvent("PLAYER_TARGET_CHANGED")
spinner1:SetScript("OnEvent", function(self, event, ...)
if event == "PLAYER_TARGET_CHANGED" then
if not UnitExists("target") then
spinner1:Hide()
return
end
spinner1:Show()
end
healthmax = UnitHealthMax("target")
health = UnitHealth("target")
local h = health / healthmax
spinner1:SetValue(h)
end)
local spinner2 = CreateSpinner(UIParent)
spinner2:SetPoint('CENTER', TargetFrame.TargetFrameContainer.Portrait)
spinner2:SetSize(158, 148)
spinner2:SetTexture("Interface\\Addons\\Images\\DragonCircleBackgroundTwo")
spinner2:SetVertexColor(1, 1, 1)
spinner2:SetClockwise(true)
spinner2:SetReverse(false)
spinner2:Hide()
local powermax = 0
local power = 0
spinner2:RegisterUnitEvent("UNIT_POWER_FREQUENT", target)
spinner2:RegisterEvent("PLAYER_TARGET_CHANGED")
spinner2:SetScript("OnEvent", function(self, event, ...)
if event == "PLAYER_TARGET_CHANGED" then
if not UnitExists("target") then
spinner2:Hide()
return
end
spinner2:Show()
end
powermax = UnitPowerMax("target")
power = UnitPower("target")
local p = power / powermax
spinner2:SetValue(p)
end)
local spinner3 = CreateSpinner(UIParent)
spinner3:SetFrameLevel(1)
spinner3:SetSize(90, 90)
spinner3:SetPoint('CENTER', TargetFrame.TargetFrameContainer.Portrait)
spinner3:SetTexture("Interface\\Masks\\CircleMaskScalable")
spinner3:SetVertexColor(0.2, 0.2, 0.8)
spinner3:SetClockwise(true)
spinner3:SetReverse(false)
spinner3:Hide()
local manamax = 0
local mana = 0
spinner3:RegisterUnitEvent("UNIT_POWER_UPDATE", "target")
spinner3:RegisterEvent("PLAYER_TARGET_CHANGED")
spinner3:SetScript("OnEvent", function(self, event, ...)
if event == "PLAYER_TARGET_CHANGED" then
if not UnitExists("target") then
spinner3:Hide()
return
end
spinner3:Show()
end
local mana = UnitPower("target", Enum.PowerType.Mana)
if not mana or mana == 0 then
spinner3:SetValue(0)
return
end
local manaMax = UnitPowerMax("target", Enum.PowerType.Mana)
spinner3:SetValue(mana / manaMax)
end)
local spinner1 = CreateSpinner(UIParent)
spinner1:SetPoint('CENTER', TargetFrame.TargetFrameContainer.Portrait)
spinner1:SetSize(116, 108)
spinner1:SetTexture("Interface\\Addons\\Images\\Ring_20px")
spinner1:SetVertexColor(0, 1, 0)
spinner1:SetClockwise(false)
spinner1:SetReverse(false)
spinner1:Hide()
spinner1.Background = spinner1:CreateTexture()
spinner1.Background:SetDrawLayer("BACKGROUND", -1)
spinner1.Background:SetSize(155, 142)
spinner1.Background:SetPoint("CENTER", TargetFrame.TargetFrameContainer.Portrait)
spinner1.Background:SetTexture("Interface\\Addons\\Images\\FullCircleFrameTwo")
local CenterOverlay = CreateFrame("Frame", nil, spinner1)
CenterOverlay:SetFrameLevel(0)
CenterOverlay:SetSize(100, 100)
CenterOverlay:SetPoint("CENTER")
CenterOverlay.Texture = CenterOverlay:CreateTexture()
CenterOverlay.Texture:SetAllPoints()
CenterOverlay.Texture:SetTexture("Interface\\Masks\\CircleMaskScalable")
CenterOverlay.Texture:SetVertexColor(0, 0, 0)
local healthmax = 0
local health = 0
spinner1:RegisterUnitEvent("UNIT_HEALTH", target)
spinner1:RegisterEvent("PLAYER_TARGET_CHANGED")
spinner1:SetScript("OnEvent", function(self, event, ...)
if event == "PLAYER_TARGET_CHANGED" then
if not UnitExists("target") then
spinner1:Hide()
return
end
spinner1:Show()
end
healthmax = UnitHealthMax("target")
health = UnitHealth("target")
local h = health / healthmax
spinner1:SetValue(h)
end)
local spinner2 = CreateSpinner(UIParent)
spinner2:SetPoint('CENTER', TargetFrame.TargetFrameContainer.Portrait)
spinner2:SetSize(158, 148)
spinner2:SetTexture("Interface\\Addons\\Images\\DragonCircleBackgroundTwo")
spinner2:SetVertexColor(1, 1, 1)
spinner2:SetClockwise(true)
spinner2:SetReverse(false)
spinner2:Hide()
local powermax = 0
local power = 0
spinner2:RegisterUnitEvent("UNIT_POWER_FREQUENT", target)
spinner2:RegisterEvent("PLAYER_TARGET_CHANGED")
spinner2:SetScript("OnEvent", function(self, event, ...)
if event == "PLAYER_TARGET_CHANGED" then
if not UnitExists("target") then
spinner2:Hide()
return
end
spinner2:Show()
end
powermax = UnitPowerMax("target")
power = UnitPower("target")
local p = power / powermax
spinner2:SetValue(p)
end)
local spinner1 = CreateSpinner(UIParent)
spinner1:SetPoint('CENTER', TargetFrame.TargetFrameContainer.Portrait)
spinner1:SetSize(116, 108)
spinner1:SetTexture("Interface\\Addons\\Images\\Ring_20px")
spinner1:SetVertexColor(0, 1, 0)
spinner1:SetClockwise(false)
spinner1:SetReverse(false)
spinner1:Hide()
spinner1.Background = spinner1:CreateTexture()
spinner1.Background:SetDrawLayer("BACKGROUND", -1)
spinner1.Background:SetSize(155, 142)
spinner1.Background:SetPoint("CENTER", TargetFrame.TargetFrameContainer.Portrait)
spinner1.Background:SetTexture("Interface\\Addons\\Images\\FullCircleFrameTwo")
local CenterOverlay = CreateFrame("Frame", nil, spinner1)
CenterOverlay:SetFrameLevel(0)
CenterOverlay:SetSize(100, 100)
CenterOverlay:SetPoint("CENTER")
CenterOverlay.Texture = CenterOverlay:CreateTexture()
CenterOverlay.Texture:SetAllPoints()
CenterOverlay.Texture:SetTexture("Interface\\Masks\\CircleMaskScalable")
CenterOverlay.Texture:SetVertexColor(0, 0, 0)
local healthmax = 0
local health = 0
spinner1:RegisterUnitEvent("UNIT_HEALTH", target)
spinner1:RegisterEvent("PLAYER_TARGET_CHANGED")
spinner1:SetScript("OnEvent", function(self, event, ...)
if event == "PLAYER_TARGET_CHANGED" then
if not UnitExists("target") then
spinner1:Hide()
return
end
spinner1:Show()
end
healthmax = UnitHealthMax("target")
health = UnitHealth("target")
local h = health / healthmax
spinner1:SetValue(h)
end)
local spinner2 = CreateSpinner(UIParent)
spinner2:SetPoint('CENTER', TargetFrame.TargetFrameContainer.Portrait)
spinner2:SetSize(158, 148)
spinner2:SetTexture("Interface\\Addons\\Images\\DragonCircleBackgroundTwo")
spinner2:SetVertexColor(1, 1, 1)
spinner2:SetClockwise(true)
spinner2:SetReverse(false)
spinner2:Hide()
local powermax = 0
local power = 0
spinner2:RegisterUnitEvent("UNIT_POWER_FREQUENT", target)
spinner2:RegisterEvent("PLAYER_TARGET_CHANGED")
spinner2:SetScript("OnEvent", function(self, event, ...)
if event == "PLAYER_TARGET_CHANGED" then
if not UnitExists("target") then
spinner2:Hide()
return
end
spinner2:Show()
end
powermax = UnitPowerMax("target")
power = UnitPower("target")
local p = power / powermax
spinner2:SetValue(p)
end)
local spinner3 = CreateSpinner(UIParent)
spinner3:SetFrameLevel(1)
spinner3:SetSize(90, 90)
spinner3:SetPoint('CENTER', TargetFrame.TargetFrameContainer.Portrait)
spinner3:SetTexture("Interface\\Masks\\CircleMaskScalable")
spinner3:SetVertexColor(0.2, 0.2, 0.8)
spinner3:SetClockwise(true)
spinner3:SetReverse(false)
spinner3:Hide()
local manamax = 0
local mana = 0
spinner3:RegisterUnitEvent("UNIT_POWER_UPDATE", "target")
spinner3:RegisterEvent("PLAYER_TARGET_CHANGED")
spinner3:SetScript("OnEvent", function(self, event, ...)
if event == "PLAYER_TARGET_CHANGED" then
if not UnitExists("target") then
spinner3:Hide()
return
end
spinner3:Show()
end
local mana = UnitPower("target", Enum.PowerType.Mana)
if not mana or mana == 0 then
spinner3:SetValue(0)
return
end
local manaMax = UnitPowerMax("target", Enum.PowerType.Mana)
spinner3:SetValue(mana / manaMax)
end)
local spinner4 = CreateSpinner(UIParent)
spinner4:SetPoint('CENTER', PlayerFrame.PlayerFrameContainer.PlayerPortraitMask)
spinner4:SetSize(116, 108)
spinner4:SetTexture("Interface\\Addons\\Images\\Ring_20px")
spinner4:SetVertexColor(0, 1, 0)
spinner4:SetClockwise(true)
spinner4:SetReverse(false)
spinner4:Hide()
spinner4.Background = spinner1:CreateTexture()
spinner4.Background:SetDrawLayer("BACKGROUND", -1)
spinner4.Background:SetSize(155, 142)
spinner4.Background:SetPoint("CENTER", PlayerFrame.PlayerFrameContainer.PlayerPortraitMask)
spinner4.Background:SetTexture("Interface\\Addons\\Images\\FullCircleFrameTwo")
local CenterOverlay = CreateFrame("Frame", nil, spinner4)
CenterOverlay:SetFrameLevel(0)
CenterOverlay:SetSize(100, 100)
CenterOverlay:SetPoint("CENTER", PlayerFrame.PlayerFrameContainer.PlayerPortraitMask)
CenterOverlay.Texture = CenterOverlay:CreateTexture()
CenterOverlay.Texture:SetAllPoints()
CenterOverlay.Texture:SetTexture("Interface\\Masks\\CircleMaskScalable")
CenterOverlay.Texture:SetVertexColor(0, 0, 0)
local healthmax = 0
local health = 0
spinner4:RegisterUnitEvent("UNIT_HEALTH", player)
spinner4:RegisterEvent("PLAYER_ENTERING_WORLD")
spinner4:SetScript("OnEvent", function(self, event, ...)
if event == "PLAYER_ENTERING_WORLD" then
if not UnitExists("player") then
spinner6:Show()
return
end
spinner4:Show()
end
healthmax = UnitHealthMax("player")
health = UnitHealth("player")
local h = health / healthmax
spinner4:SetValue(h)
end)
local spinner5 = CreateSpinner(UIParent)
spinner5:SetPoint('CENTER', PlayerFrame.PlayerFrameContainer.PlayerPortraitMask)
spinner5:SetSize(158, 148)
spinner5:SetTexture("Interface\\Addons\\Images\\DragonCircleBackgroundPlayer")
spinner5:SetVertexColor(1, 1, 1)
spinner5:SetClockwise(true)
spinner5:SetReverse(false)
spinner5:Hide()
spinner5.Background = spinner1:CreateTexture()
spinner5.Background:SetDrawLayer("BACKGROUND", -1)
spinner5.Background:SetSize(155, 142)
spinner5.Background:SetPoint("CENTER", PlayerFrame.PlayerFrameContainer.PlayerPortraitMask)
spinner5.Background:SetTexture("Interface\\Addons\\Images\\DragonCircleBackgroundPlayer")
spinner5.Background:SetVertexColor(0, 0, 0)
local powermax = 0
local power = 0
spinner5:RegisterUnitEvent("UNIT_POWER_FREQUENT", player)
spinner5:RegisterEvent("PLAYER_ENTERING_WORLD")
spinner5:SetScript("OnEvent", function(self, event, ...)
if event == "PLAYER_ENTERING_WORLD" then
if not UnitExists("player") then
spinner5:Hide()
return
end
spinner5:Show()
end
powermax = UnitPowerMax("player")
power = UnitPower("player")
local p = power / powermax
spinner5:SetValue(p)
end)
local spinner6 = CreateSpinner(UIParent)
spinner6:SetFrameLevel(1)
spinner6:SetSize(90, 90)
spinner6:SetPoint('CENTER', PlayerFrame.PlayerFrameContainer.PlayerPortraitMask)
spinner6:SetTexture("Interface\\Masks\\CircleMaskScalable")
spinner6:SetVertexColor(0.2, 0.2, 0.8)
spinner6:SetClockwise(true)
spinner6:SetReverse(false)
spinner6:Hide()
local manamax = 0
local mana = 0
spinner6:RegisterUnitEvent("UNIT_POWER_UPDATE", "player")
spinner6:RegisterEvent("PLAYER_ENTERING_WORLD")
spinner6:SetScript("OnEvent", function(self, event, ...)
if event == "PLAYER_ENTERING_WORLD" then
if not UnitExists("player") then
spinner6:Hide()
return
end
spinner6:Show()
end
local mana = UnitPower("player", Enum.PowerType.Mana)
if not mana or mana == 0 then
spinner6:SetValue(0)
return
end
local manaMax = UnitPowerMax("player", Enum.PowerType.Mana)
spinner6:SetValue(mana / manaMax)
end)
|