Skip to content

Commit

Permalink
fix: macro not updating
Browse files Browse the repository at this point in the history
This fix changes the logic on how the macro is found and generated.
Previously, the code would try to find the macro based off a macro index
and try and do a string.find on RHT.b. Seeing RHT.b is a defunct part of
the macro, I changed this to use GetMacroIndexByName as the macro name
is always 'RHT'. This allows us to set the index in a much cleaner
fashion. Lastly, I removed the last line of SetRandomHearthToy that was
setting the RHT.b button which did not exist. This has been extensively
tested and the bug is now resolved
  • Loading branch information
lyledouglass committed Mar 17, 2024
1 parent a8b66c9 commit 9ff647c
Showing 1 changed file with 91 additions and 130 deletions.
221 changes: 91 additions & 130 deletions HearthstoneRandomizer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,54 +8,44 @@ local RHTInitialized = false

--Frame to catch events
local frame = CreateFrame("Frame")
-- Setting up an invisible button named RHTB. Toys can only be used through a button click, so we need one for the macro to click.
RHT.b = CreateFrame("Button","RHTB",nil,"SecureActionButtonTemplate")
RHT.b:RegisterForClicks("AnyUp","AnyDown")
RHT.b:SetAttribute("type","item")

-- Setting up a frame to wait and see if the toybox is loaded before getting stones on login.
local timeOut = 10 --Delay for checking stones.
RHT.to = CreateFrame("Frame","RHTO", UIParent)
RHT.to:SetScript("OnUpdate", function (self, elapse)
if timeOut > 0 then
timeOut = timeOut - elapse
else
if C_ToyBox.GetNumToys() > 0 then
GetLearnedStones()
if RHTInitialized then
SetRandomHearthToy()
print "HearthstoneRandomizer initialized"
RHT.to:SetScript("OnUpdate", nil)
else
timeOut = 1
end
else
timeOut = 1
end
end
if timeOut > 0 then
timeOut = timeOut - elapse
else
if C_ToyBox.GetNumToys() > 0 then
GetLearnedStones()
if RHTInitialized then
SetRandomHearthToy()
-- Debug output
-- print "HearthstoneRandomizer initialized"
RHT.to:SetScript("OnUpdate", nil)
else
timeOut = 1
end
else
timeOut = 1
end
end
end)

frame:RegisterEvent("PLAYER_ENTERING_WORLD")

-- Blizz broke deleting items from bags, leaving code incase I find a fix. Yeah. Right.
--frame:RegisterEvent("BAG_UPDATE")

-- Spellcast stopping is the check for if a hearthstone has been used.
frame:RegisterEvent("UNIT_SPELLCAST_STOP")

local function Event(self, event, arg1, arg2, arg3)
if event == "PLAYER_ENTERING_WORLD" then
GetMacroIndex()
frame:UnregisterEvent("PLAYER_ENTERING_WORLD")
end
-- When a spell cast stops and it's the player's spell, send the ID to check if it's a stone.
if event == "UNIT_SPELLCAST_STOP" and arg1 == "player" then
SpellcastUpdate(arg3)
end
-- Currently not used. Thx Blizz.
if event == "BAG_UPDATE" then
DeleteHearthstone()
end
if event == "PLAYER_ENTERING_WORLD" then
GetMacro()
frame:UnregisterEvent("PLAYER_ENTERING_WORLD")
end
-- When a spell cast stops and it's the player's spell, send the ID to check if it's a stone.
if event == "UNIT_SPELLCAST_STOP" and arg1 == "player" then
SpellcastUpdate(arg3)
end
end

frame:SetScript("OnEvent", Event)
Expand Down Expand Up @@ -93,121 +83,92 @@ AllHearthToyIndex[212337] = 431644 --Stone of the Hearth

-- This is the meat right here.
function SetRandomHearthToy()
-- Setting the new stone while in combat is bad.
--if not InCombatLockdown() then
-- Find the macro.
CheckMacroIndex()
-- Rebuild the stone list if it's empty.
if next(UsableHearthToyIndex) == nil then
GetLearnedStones()
end
local itemID, toyName = ''
-- Randomly pick one.
local k = RandomKey(UsableHearthToyIndex)
local itemID, toyName = C_ToyBox.GetToyInfo(k)
if toyName then
-- Remove it from the list so we don't pick it again.
RemoveStone(k)
-- Write the macro.
GenMacro(itemID, toyName)
-- Set button for first use
if not RHT.b:GetAttribute("item") then RHT.b:SetAttribute("item",toyName) end
end
--end
-- Find the macro.
GetMacro()
-- Rebuild the stone list if it's empty.
if next(UsableHearthToyIndex) == nil then
GetLearnedStones()
end
local itemID, toyName = ''
-- Randomly pick one.
local k = RandomKey(UsableHearthToyIndex)
local itemID, toyName = C_ToyBox.GetToyInfo(k)
if toyName then
-- Remove it from the list so we don't pick it again.
RemoveStone(k)
-- Write the macro.
GenMacro(itemID, toyName)
end
end

-- Get stones learned and usable by character
function GetLearnedStones()
-- Get the current setting for the toybox so we can set it back after we're done.
ToyCollSetting = C_ToyBox.GetCollectedShown()
ToyUnCollSetting = C_ToyBox.GetUncollectedShown()
ToyUsableSetting = C_ToyBox.GetUnusableShown()

C_ToyBox.SetCollectedShown(true) -- List collected toys
C_ToyBox.SetUncollectedShown(false) -- Don't list uncollected toys
C_ToyBox.SetUnusableShown(false) -- Don't list unusable toys in the the collection.

-- Go through all the toys to find the usable stons.
for i = 1, C_ToyBox.GetNumFilteredToys() do
-- Go through all the stone to see if this toy is a stone.
for k in pairs(AllHearthToyIndex) do
if k == C_ToyBox.GetToyFromIndex(i) then
UsableHearthToyIndex [k] = 1
end
end
end
-- Reset the toybox filter
C_ToyBox.SetCollectedShown(ToyCollSetting)
C_ToyBox.SetUncollectedShown(ToyUnCollSetting)
C_ToyBox.SetUnusableShown(ToyUsableSetting)
if next(UsableHearthToyIndex) then
RHTInitialized = true
end
end

-- We've removed the name from the macro, so now we need to find it so we know which one to edit.
function GetMacroIndex()
local numg, numc = GetNumMacros()
for i = 1, numg do
local macroCont = GetMacroBody(i)
-- Hopefully no other macro ever made has "RHT.b" in it...
if string.find(macroCont, "RHT.b") then
RHTIndex = i
end
end
-- Get the current setting for the toybox so we can set it back after we're done.
ToyCollSetting = C_ToyBox.GetCollectedShown()
ToyUnCollSetting = C_ToyBox.GetUncollectedShown()
ToyUsableSetting = C_ToyBox.GetUnusableShown()

C_ToyBox.SetCollectedShown(true) -- List collected toys
C_ToyBox.SetUncollectedShown(false) -- Don't list uncollected toys
C_ToyBox.SetUnusableShown(false) -- Don't list unusable toys in the the collection.

-- Go through all the toys to find the usable stons.
for i = 1, C_ToyBox.GetNumFilteredToys() do
-- Go through all the stone to see if this toy is a stone.
for k in pairs(AllHearthToyIndex) do
if k == C_ToyBox.GetToyFromIndex(i) then
UsableHearthToyIndex [k] = 1
end
end
end
-- Reset the toybox filter
C_ToyBox.SetCollectedShown(ToyCollSetting)
C_ToyBox.SetUncollectedShown(ToyUnCollSetting)
C_ToyBox.SetUnusableShown(ToyUsableSetting)
if next(UsableHearthToyIndex) then
RHTInitialized = true
end
end

-- Have we found the macro yet? Also, make sure the macro we're editing is the right one in case the user rearranged things or deleted it. If not, go find it.
function CheckMacroIndex()
local macroCont = GetMacroBody(RHTIndex)
if macroCont then
if string.find(macroCont, "RHT.b") then
return
end
end
GetMacroIndex()
-- We use RHT as the macro name, so we need to see if it exists. If it
-- does, we set the index. Else, it the nothing gets passed to GenMacro
-- and it creates a new one.
function GetMacro()
macroExists = GetMacroIndexByName("RHT")
if macroExists then
RHTIndex = macroExists
end
end

-- Macro writing time.
function GenMacro(itemID, toyName)
-- Did we find the index? If so, edit that. The macro changes the button to the next stone, but only if we aren't in combat; can't SetAttribute. It then casts the toyName
if RHTIndex then
EditMacro(RHTIndex, "RHT", "INV_MISC_QUESTIONMARK", "#showtooltip item:" .. itemID .. "\r/run if not InCombatLockdown() then RHT.b:SetAttribute(\"item\",\"" .. toyName .. "\") end\r/cast " .. toyName)
else
-- No macro found, make a new one, get it's ID
CreateMacro("RHT", "INV_MISC_QUESTIONMARK", "#showtooltip item:" .. itemID .. "\r/run if not InCombatLockdown() then RHT.b:SetAttribute(\"item\",\"" .. toyName .. "\") end\r/cast " .. toyName)
GetMacroIndex()
end
if RHTIndex then
EditMacro(RHTIndex, "RHT", "INV_MISC_QUESTIONMARK", "#showtooltip item:" .. itemID .. "\r/cast " .. toyName)
-- Debug output
-- print "Macro updated"
else
CreateMacro("RHT", "INV_MISC_QUESTIONMARK", "#showtooltip item:" .. itemID .. "\r/cast " .. toyName)
-- Debug output
-- print "Macro created"
GetMacro()
end
end

-- Remove stone from the list so we don't use it again. (Here for debugging)
function RemoveStone(k)
UsableHearthToyIndex[k] = nil
UsableHearthToyIndex[k] = nil
end

-- Did a stone get used?
function SpellcastUpdate(spellID)
if not InCombatLockdown() then
for k in pairs(AllHearthToyIndex) do
if spellID == AllHearthToyIndex[k] then
SetRandomHearthToy()
break
end
end
end
for k in pairs(AllHearthToyIndex) do
if spellID == AllHearthToyIndex[k] then
SetRandomHearthToy()
break
end
end
end

-- Old function to delete the base HS from bags. Leaving in case I can find a workaround from Blizz's change.
function DeleteHearthstone()
for bag = 0,4 do
for slot = 1, 32 do
local itemID = GetContainerItemID(bag,slot)
if itemID == 6948 then
PickupContainerItem(bag,slot)
DeleteCursorItem()
end
end
end
end

-- Code to randomly pick a key from a table.
Expand Down

0 comments on commit 9ff647c

Please sign in to comment.