WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (https://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   Alright guys I need your help on this one. (https://www.wowinterface.com/forums/showthread.php?t=59417)

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)


Tim 12-22-22 10:53 AM

Take a look at zork's old project "RingThing"
https://www.wowinterface.com/downloa...heRingMod.html

watchout 12-31-22 05:34 AM

Fascinating title ;)

You can also take a look at my HUD here https://github.com/watchout-mods/Elementary

Particularily at the inline libraries ArcBar and LibRotate.


All times are GMT -6. The time now is 04:51 PM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI