Thread Tools Display Modes
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
10-16-20, 06:19 PM   #2
DahkCeles
A Cliff Giant
 
DahkCeles's Avatar
AddOn Author - Click to view addons
Join Date: Jun 2020
Posts: 73
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.
  Reply With Quote
10-17-20, 02:08 AM   #3
madar2252
A Defias Bandit
Join Date: Oct 2020
Posts: 2
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!

  Reply With Quote

WoWInterface » AddOns, Compilations, Macros » AddOn Search/Requests » Request for fixing an addon (setbackdrop changes)

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off