Trying To Use ActionButton_ShowOverlayGlow() But I get a ForceTaint_Strong error

I am aware that the ForceTaint_Strong error means that the function I am trying to call–ActionButton_ShowOverlayGlow(buttonForGlow )– is protected, but I am also of the impression there is a way around this using maybe hooksecurefunc… maybe some obscure Mixin function…

I have tried a bunch of things, and I am scratching my head now. I am also aware that WA can do this, but I don’t want to use it.

Oddly enough, even though I get said error, the glow still seems to happen in combat until I mouse over the frame.

local spellName = "Frenzied Regeneration"
local buttonForGlow

local function FindSpellByName()
	for i = 1, 12, 1 do
		local ButtonsOntoBar = _G["ActionButton" .. i]
		local actionSlotID = 96 + i -- Bear Form: slots 97 to 108
		if HasAction(actionSlotID) then
			local actionType, id, subType = GetActionInfo(actionSlotID)
			local actionName
			if actionType == "spell" then
				actionName = GetSpellInfo(id)
				if actionName == spellName then
					buttonForGlow = ButtonsOntoBar
				end
			end
		end
	end
end

I am sure the issue is partially the local variable being passed to ActionButton_ShowOverlayGlow(buttonForGlow)

What local variable? How are you using ActionButton_ShowOverlayGlow?

ActionButton_ShowOverlayGlow takes a single button as an argument.

hooksecurefunc("ActionButton_ShowOverlayGlow", function(button)
    -- button is the action button being told to show/animate its SpellActivationAlert region. I'm guessing this is where you want to:

    -- check for spell and do whatever?
end)

You shouldn’t really need to check 12 buttons but the code doesn’t indicate the actual button containing the spell needs to be the one activated and you’ve given no indication how FindSpellByName is being called or, what’s happening after it is finished.

Based on what’s there, once buttonForGlow contains a ButtonsOntoBar value, it will always contain a value each time FindSpellByName is run because it is not cleared (set to nil) before checking the buttons. Unless that happens before running the function?

So, at the end of my little function there, the “buttonForGlow” is assigned the final result (something like “ActionButton6”). atm I am just looking for 1 spell, Frenzied Regeneration, and the reason the code goes through all 12 buttons is because I want the glow to be assigned to the button with Frenzied Regen-- no matter where that button is located on the bar (maybe I decide to move it at some point).

With “buttonForGlow” being assigned a value, I feed it to this function here, in the SetScript later on:

local function glowHandler()
	local healthPercentage = UnitHealth("player") / UnitHealthMax("player") * 100
	if healthPercentage < 65 and GetShapeshiftForm() == 1 and UnitPower("player", Enum.PowerType.Rage) > 10 then
		ActionButton_ShowOverlayGlow(buttonForGlow)
	elseif healthPercentage > 70 or GetShapeshiftForm() ~= 1 or UnitPower("player", Enum.PowerType.Rage) < 10 then
		ActionButton_HideOverlayGlow(buttonForGlow)
	end
end

SetScript basically looks like the following (there are a few other events in there).

glowFrame:SetScript("OnEvent", function(self, event)
	if event == "PLAYER_ENTERING_WORLD" then
		FindSpellByName() -- function in my previous post
	elseif event == "UNIT_HEALTH" and buttonForGlow then
		glowHandler()
	end
end)

I want to eventually use my FindSpellByName() function to loop through more than one spell… But that will come later.

You probably want to use you own activation layer rather than relying on Blizz to setup and action a protected one. This is an example (mostly your code but I removed some bits that would need putting back. Sizing probably needs to be fixed also etc. etc.).

local spellName = "Frenzied Regeneration"
local buttonForGlow
local glowFrame = CreateFrame("Frame")

local function FindSpellByName()
    for i = 1, 12, 1 do
        local ButtonsOntoBar = _G["ActionButton" .. i]
        local actionSlotID = 0 + i -- Bear Form: slots 97 to 108
        if HasAction(actionSlotID) then
            local actionType, id, subType = GetActionInfo(actionSlotID)
            local actionName
            if actionType == "spell" then
                actionName = GetSpellInfo(id)
                if actionName == spellName then
                    buttonForGlow = ButtonsOntoBar
                    break -- we found it, no need to go on
                end
            end
        end
    end
end

local function glowHandler()
    local healthPercentage = UnitHealth("player") / UnitHealthMax("player") * 100
    if healthPercentage < 95 and not glowFrame.SpellActivationAlert.ProcStartAnim:IsPlaying() then
        glowFrame.SpellActivationAlert:Show()
        glowFrame.SpellActivationAlert.ProcStartAnim:Play()
        glowFrame.isRunning = true
    elseif healthPercentage > 95 and glowFrame.isRunning then
    	glowFrame.isRunning = nil
        glowFrame.SpellActivationAlert.ProcStartAnim:Stop()
        glowFrame.SpellActivationAlert:Hide()
    end
end

glowFrame:SetScript("OnEvent", function(self, event)
    if event == "PLAYER_ENTERING_WORLD" then
        FindSpellByName() -- function in my previous post
        if buttonForGlow then -- Just in case the spell isn't set, check each PEW
            self:UnregisterEvent("PLAYER_ENTERING_WORLD") -- and if so, unregister and setup glow
            glowFrame.SpellActivationAlert = CreateFrame("Frame", nil, button, "ActionBarButtonSpellActivationAlert");
            local frameWidth, frameHeight = buttonForGlow:GetSize();
            glowFrame.SpellActivationAlert:SetSize(frameWidth, frameHeight);
            glowFrame.SpellActivationAlert:SetPoint("CENTER", buttonForGlow, "CENTER", 0, 0);
            glowFrame.SpellActivationAlert:Hide();
        end
    elseif event == "UNIT_HEALTH" and buttonForGlow then
    	if not buttonForGlow then
    		return
    	end
        glowHandler()
    end
end)
glowFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
glowFrame:RegisterUnitEvent("UNIT_HEALTH", "player")
1 Like

Thank you for the help Fizzle. I have had a chance to test it, and your idea to create a new frame was simple and efficient.