WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   AddOn Search/Requests (https://www.wowinterface.com/forums/forumdisplay.php?f=6)
-   -   Request for fixing an addon (setbackdrop changes) (https://www.wowinterface.com/forums/showthread.php?t=58297)

madar2252 10-16-20 05:26 AM

Request for fixing an addon (setbackdrop changes)
 
Hi, so there is an abandoned project "Simpletankframes" which only put up a tankframe to the screen. I found a few similar addons, but all of them are abandoned. I am wondering if there are any good soul who could fix this for a virtual beer.

The error is about the setbackdrop function, which changed with 9.0, in the frames.lua.

Thanks if anyone can a have a look on it.

Code:

local addon = CreateFrame("Frame")
_G.SimpleTankFrames = addon

local initialized = nil
local pName = UnitName("player")
local db = nil
local allFrames = {}
local L = LibStub("AceLocale-3.0"):GetLocale("SimpleTankFrames")

local backdrop = {bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", tile = true, tileSize = 16}

local function initCommon(frame)
        frame:SetBackdrop(backdrop)
        frame:SetBackdropColor(0, 0, 0, .5)
        frame:SetWidth(120)
        frame:SetHeight(22)

        local bar = CreateFrame("StatusBar", nil, frame)
        bar:SetPoint("TOPLEFT", 4, -3)
        bar:SetPoint("BOTTOMRIGHT", -4, 3)
        bar:SetStatusBarTexture(db.bar)
        frame.hp = bar

        local tx = bar:CreateTexture(nil, "BORDER")
        tx:SetTexture(db.bar)
        tx:SetVertexColor(.5, .5, .5, .5)
        tx:SetAllPoints(bar)
        frame.bg = tx

        if db.showHp then
                local value = bar:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
                value:SetJustifyH("RIGHT")
                value:SetPoint("TOPRIGHT", -2, -1)
                value:SetPoint("BOTTOMRIGHT", -2, 1)
                frame.value = value
        end

        local icon = bar:CreateTexture(nil, "OVERLAY")
        icon:SetTexture("Interface\\TargetingFrame\\UI-RaidTargetingIcons")
        icon:SetWidth(14)
        icon:SetPoint("TOPLEFT", 2, -1)
        icon:SetPoint("BOTTOMLEFT", 2, 1)
        frame.icon = icon

        local name = bar:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
        name:SetPoint("TOPLEFT", icon, "TOPRIGHT", 2, -1)
        frame.name = name
end

local function icon(self, unit)
        local unit = unit or self.unit
        if not unit then return end
        local index = GetRaidTargetIndex(unit)
        if index then
                SetRaidTargetIconTexture(self.icon, index)
                self.icon:Show()
        else
                self.icon:Hide()
        end
end

local colors = { disconnected = {.6, .6, .6}, class = {}, reaction = {} }
for class, color in next, RAID_CLASS_COLORS do colors.class[class] = {color.r, color.g, color.b} end
for class, color in next, FACTION_BAR_COLORS do colors.reaction[class] = {color.r, color.g, color.b} end
local function hp(self, unit)
        if self.unit ~= unit then return end
        local min, max = UnitHealth(unit), UnitHealthMax(unit)
        self.hp:SetMinMaxValues(0, max)
        local t = nil
        if not UnitIsConnected(unit) then
                self.hp:SetValue(max)
                self.hp:SetAlpha(0.5)
                if self.value then self.value:SetText() end
                t = colors.disconnected
        else
                self.hp:SetAlpha(1)
                self.hp:SetValue(min)
                if self.value then
                        local percent = max == 0 and 0 or math.floor(min / max * 100 + 0.5)
                        self.value:SetFormattedText("%d%%", percent)
                end
                if UnitIsPlayer(unit) then
                        t = colors.class[(select(2, UnitClass(unit)))]
                elseif UnitReaction(unit, "player") then
                        t = colors.reaction[UnitReaction(unit, "player")]
                end
        end
        if not t then return end
        self.hp:SetStatusBarColor(unpack(t))
end

local function name(self, unit)
        if self.unit ~= unit then return end
        local n = UnitName(unit)
        self.name:SetText(#n > 12 and n:sub(1, 12) or n)
end

local function fullUpdate(self)
        local unit = self.unit
        if not UnitExists(unit) then return end
        hp(self, unit)
        name(self, unit)
        icon(self, unit)
end

local eventFuncs = {
        PLAYER_ENTERING_WORLD = fullUpdate,
        UNIT_NAME_UPDATE = name,
        UNIT_MAXHEALTH = hp,
        UNIT_HEALTH = hp,
        RAID_TARGET_UPDATE = icon,
}
local function onEvent(self, event, unit) if eventFuncs[event] then eventFuncs[event](self, unit, event) end end

local function attributeChanged(self, name, value)
        if name ~= "unit" or not value then return end
        if self.unit and self.unit == value then return end

        if db.target then
                local target = SecureButton_GetModifiedUnit(self.target, self.target)
                self.target.unit = target
                fullUpdate(self.target)
        end

        if db.tot then
                local tot = SecureButton_GetModifiedUnit(self.tot, self.tot)
                self.tot.unit = tot
                fullUpdate(self.tot)
        end

        self.unit = SecureButton_GetModifiedUnit(self, self)
        fullUpdate(self)
end

local function onUpdate(self, elapsed)
        if not self.unit then return end
        self.timer = self.timer + elapsed
        if self.timer >= 0.3 then -- Health updates only happen every 0.3sec I think
                fullUpdate(self)
                self.timer = 0
        end
end

local function initializer(self, frame, ...)
        local tank = _G[frame]
        local target = tank:GetChildren()
        local tot = target:GetChildren()

        initCommon(tank)

        tank:RegisterEvent("UNIT_MAXHEALTH")
        tank:RegisterEvent("UNIT_HEALTH")
        tank:RegisterEvent("RAID_TARGET_UPDATE")
        tank:SetScript("OnEvent", onEvent)
        tank:SetScript("OnAttributeChanged", attributeChanged)

        allFrames[#allFrames + 1] = tank

        if db.target then
                RegisterUnitWatch(target)
                tank.target = target
                initCommon(target)
                target.timer = 0
                target:SetScript("OnUpdate", onUpdate)
                allFrames[#allFrames + 1] = target
        end

        if db.target and db.tot then
                RegisterUnitWatch(tot)
                tank.tot = tot
                initCommon(tot)
                tot.timer = 0
                tot:SetScript("OnUpdate", onUpdate)
                allFrames[#allFrames + 1] = tot
        end
end

local init = [[
        local header = self:GetParent()
        header:CallMethod("initializer", self:GetName())

        local clique = self:GetParent():GetFrameRef("clickcast_header")
        if clique then
                clique:SetAttribute("clickcast_button", self)
                clique:RunAttribute("clickcast_register")
        end
]]

local mover = nil
local header = nil

local function createFrames()
        mover = CreateFrame("Frame", "SimpleTankFrameMover", UIParent, "SecureFrameTemplate")
        mover:SetFrameStrata("LOW")
        mover:SetWidth(150)
        mover:SetHeight(13)
        mover:SetScale(db.scale)
        mover:SetAlpha(db.alpha)
        if not db.lock then
                mover:EnableMouse(true)
                mover:SetMovable(true)
                mover:RegisterForDrag("LeftButton")
                mover:SetScript("OnDragStart", function(self)
                        self:SetFrameStrata("DIALOG")
                        self:StartMoving()
                end)
                mover:SetScript("OnDragStop", function(self)
                        self:SetFrameStrata("LOW")
                        self:StopMovingOrSizing()
                        local s = self:GetEffectiveScale()
                        db.x = self:GetLeft() * s
                        db.y = self:GetTop() * s
                end)
                local text = mover:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
                text:SetText(L["Tanks"])
                text:SetAllPoints(mover)
        end
        if db.x and db.y then
                local s = mover:GetEffectiveScale()
                mover:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", db.x / s, db.y / s)
        else
                mover:SetPoint("CENTER")
        end
        mover:Hide()

        header = CreateFrame("Frame", "SimpleTankFrames", mover, "SecureRaidGroupHeaderTemplate")
        header:SetAttribute("template", "SimpleTankTemplate,STI_ClickCastUnitTemplate")
        SecureHandler_OnLoad(header)
        if ClickCastHeader then
                header:SetFrameRef("clickcast_header", ClickCastHeader)
        end
        if db.growup then
                header:SetPoint("BOTTOM", mover, "TOP")
                header:SetAttribute("point", "TOP")
                header:SetAttribute("yOffset", -1)
        else
                header:SetPoint("TOP", mover, "BOTTOM")
                header:SetAttribute("point", "BOTTOM")
                header:SetAttribute("yOffset", 1)
        end
        header:SetAttribute("sortDir", "DESC")
        header:SetAttribute("sortMethod", "NAMELIST")
        header:SetAttribute("initial-unitWatch", true)
        header:SetAttribute("nameList", "")
        header.initializer = initializer
        header:SetAttribute("initialConfigFunction", init)
        header:Show()
end

local function updateTargetHighlight()
        for i, frame in next, allFrames do
                if frame.unit and UnitIsUnit(frame.unit, "target") then
                        frame:SetBackdropColor(1, .84, 0, 1)
                else
                        frame:SetBackdropColor(0, 0, 0, .5)
                end
        end
end

local function reallyUpdateTanks(tanks)
        if db.highlight then
                local playerIsTank = nil
                for i, tank in next, tanks do
                        if tank == pName then
                                playerIsTank = true
                                break
                        end
                end
                if playerIsTank then
                        addon:UnregisterEvent("UNIT_TARGET")
                        addon:SetScript("OnUpdate", updateTargetHighlight)
                else
                        addon:RegisterEvent("UNIT_TARGET")
                        addon:SetScript("OnUpdate", nil)
                end
        end
        header:SetAttribute("nameList", table.concat(tanks, ","))
end

local updateTanksOnRegenEnabled = nil
local function updateTanksCallback(_, tanks)
        if InCombatLockdown() then
                updateTanksOnRegenEnabled = true
        else
                reallyUpdateTanks(tanks)
        end
end

addon:SetScript("OnEvent", function(self, event, addonName)
        if event == "UNIT_TARGET" then
                if not initialized then return end
                updateTargetHighlight()
        elseif event == "GROUP_ROSTER_UPDATE" or event == "PLAYER_REGEN_ENABLED" then
                if InCombatLockdown() then return end
                if not initialized then
                        createFrames()
                        oRA3.RegisterCallback(self, "OnTanksUpdated", updateTanksCallback)
                        updateTanksCallback(nil, oRA3:GetSortedTanks())
                        initialized = true
                end
                if mover:IsShown() and not UnitInRaid("player") then
                        mover:Hide()
                elseif not mover:IsShown() and UnitInRaid("player") then
                        mover:Show()
                end
                if updateTanksOnRegenEnabled then
                        updateTanksOnRegenEnabled = nil
                        reallyUpdateTanks(oRA3:GetSortedTanks())
                end
        elseif event == "VARIABLES_LOADED" then
                STFDB = STFDB or {}
                db = STFDB
                addon.db = db
                for k, v in pairs({
                        lock = nil,
                        showHp = true,
                        bar = "Interface\\AddOns\\SimpleTankFrames\\statusbar",
                        scale = 1,
                        highlight = true,
                        tot = nil,
                        alpha = 1,
                        target = true,
                        growup = nil,
                }) do
                        if type(db[k]) == "nil" then
                                db[k] = v
                        end
                end

                if not InCombatLockdown() then
                        createFrames()
                        oRA3.RegisterCallback(self, "OnTanksUpdated", updateTanksCallback)
                        -- In case we're in combat at VAR_LOADED we don't run reallyUpdateTanks
                        updateTanksCallback(nil, oRA3:GetSortedTanks())
                        initialized = true
                end
        end
end)

addon:RegisterEvent("VARIABLES_LOADED")
addon:RegisterEvent("GROUP_ROSTER_UPDATE")
addon:RegisterEvent("PLAYER_REGEN_ENABLED")


DahkCeles 10-16-20 06:19 PM

I would try inserting the following at line 12:


Lua Code:
  1. local function initCommon(frame) -- old line 11
  2.     if (BackdropTemplateMixin) then
  3.         Mixin(frame, BackdropTemplateMixin)
  4.     end
  5.     frame:SetBackdrop(backdrop) -- old line 12

After quickly scanning the code, my assumption is that every frame with a backdrop has this initCommon function called once only before any backdrop functions are used.

madar2252 10-17-20 02:08 AM

Thank you DahkCeles, it seems to work.
I've little knowledge about lua, and I've tried to insert Mixin code, but above the line 11, and just got Mixin lua error.

cheers!



All times are GMT -6. The time now is 07:58 PM.

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