View Single Post
10-16-20, 05:26 AM   #1
madar2252
A Defias Bandit
Join Date: Oct 2020
Posts: 2
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")
  Reply With Quote