From c8a5e4f0ebf926230929319c664a69f63357759b Mon Sep 17 00:00:00 2001 From: Bluewhale1337 <295648290+Bluewhale1337@users.noreply.github.com> Date: Sat, 18 Jul 2026 13:35:59 +0200 Subject: [PATCH 01/12] perf: eliminate string allocation GC spikes in healthbar refreshing and remove full UI rebuilds on target change --- HealBot_Controller_Events.lua | 5 ++++- HealBot_Controller_Spells.lua | 2 +- HealBot_View_Layout.lua | 17 +++++++++++------ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/HealBot_Controller_Events.lua b/HealBot_Controller_Events.lua index 122b32f..825d1ae 100644 --- a/HealBot_Controller_Events.lua +++ b/HealBot_Controller_Events.lua @@ -378,7 +378,10 @@ function HealBot_OnEvent_PlayerRegenEnabled(this) end function HealBot_OnEvent_PlayerTargetChanged(this) - HealBot_RecalcParty(); + if HealBot_Action_UnitButtons and HealBot_Action_UnitButtons["target"] then + HealBot_Action_RefreshButtons("target"); + HealBot_OnEvent_UnitAura(nil, "target"); + end end function HealBot_OnEvent_PartyMembersChanged(this) diff --git a/HealBot_Controller_Spells.lua b/HealBot_Controller_Spells.lua index 97f9dd9..2895dd3 100644 --- a/HealBot_Controller_Spells.lua +++ b/HealBot_Controller_Spells.lua @@ -246,7 +246,7 @@ function HealBot_CheckCasting(unit) local ag = HealBot_Config.babortcolg[HealBot_Config.Current_Skin] or 0.1; local ab = HealBot_Config.babortcolb[HealBot_Config.Current_Skin] or 0.5; local aa = HealBot_Config.babortcola[HealBot_Config.Current_Skin] or 1; - bar.txt = getglobal(bar:GetName() .. "_text"); + if not bar.txt then bar.txt = getglobal(bar:GetName() .. "_text") end if HealBot_IsCasting == false and HealBot_AbortButton == 0 then bar:SetStatusBarColor(ar, ag, ab, 0); diff --git a/HealBot_View_Layout.lua b/HealBot_View_Layout.lua index 40ef3c9..8756244 100644 --- a/HealBot_View_Layout.lua +++ b/HealBot_View_Layout.lua @@ -87,13 +87,17 @@ function HealBot_HealthColor(unit, hlth, maxhlth) end function HealBot_Action_HealthBar(button) - local name = button:GetName(); - return getglobal(name .. "Bar"); + if not button.bar then + button.bar = getglobal(button:GetName() .. "Bar") + end + return button.bar; end function HealBot_Action_HealthBar2(button) - local name = button:GetName(); - return getglobal(name .. "Bar2"); + if not button.bar2 then + button.bar2 = getglobal(button:GetName() .. "Bar2") + end + return button.bar2; end function HealBot_Action_EnableButton(button) @@ -108,7 +112,8 @@ function HealBot_Action_EnableButton(button) local bar = HealBot_Action_HealthBar(button); local bar2 = HealBot_Action_HealthBar2(button); - local bar3 = getglobal(button:GetName() .. "Bar3"); + if not button.bar3 then button.bar3 = getglobal(button:GetName() .. "Bar3") end + local bar3 = button.bar3; local btexture = HealBot_Config.btexture[HealBot_Config.Current_Skin]; local bheight = HealBot_Config.bheight[HealBot_Config.Current_Skin]; local sr = HealBot_Config.btextenabledcolr[HealBot_Config.Current_Skin]; @@ -175,7 +180,7 @@ function HealBot_Action_EnableButton(button) else bar2:SetValue(0); end - bar.txt = getglobal(bar:GetName() .. "_text"); + if not bar.txt then bar.txt = getglobal(bar:GetName() .. "_text") end if (not HealBot_IsCasting and (HealBot_CanHeal(unit) or HealBot_MissingBuffs[unit])) then button:Enable(); if HealBot_UnitDebuff[unit] then From 8854cd3caa5effa062390a0d97e10b3e1c253138 Mon Sep 17 00:00:00 2001 From: Bluewhale1337 <295648290+Bluewhale1337@users.noreply.github.com> Date: Sat, 18 Jul 2026 23:26:14 +0200 Subject: [PATCH 02/12] docs: add release notes for v1.4.2 to README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 0e8b1be..063f1fd 100644 --- a/README.md +++ b/README.md @@ -47,8 +47,10 @@ Default installation path: `C:\Program Files\World of Warcraft\Interface\AddOns\ * **Macro, Item, and Script Bindings:** Support for binding named macros, inventory items, and inline scripts (e.g. `/target`) directly to mouse clicks in the Spells tab. All of these now natively support implicit `@mouseover` targeting on the unit frame you click, without losing your current target. * **Modifier-Aware Tooltips & Resource Costs:** The tooltip dynamically updates to show exactly what action is bound when holding down Shift, Ctrl, or Alt over a frame. Spells also show their required mana cost, turning red if you do not have enough mana to cast them. * **Memory Recycling Pool:** Added a local table recycling pool in the data layer to greatly reduce Lua garbage collection (GC) spikes, improving overall client frame rates during intense combat. + **v1.4.2** * **Memory Optimization:** Fixed a significant memory leak where tracking tables were being repeatedly allocated every tick during aura scanning, and replaced `table.foreach` with pairs loops to avoid GC spikes during combat. + **v1.4.1** * **Talent-based Healing Calculations:** Implemented dynamic spell healing calculations for Druid, Priest, and Paladin classes based on talents. * **Modifier Key Polling:** Replaced MODIFIER_STATE_CHANGED event with polling in HealBot_OnUpdate to track modifier keys reliably. From 826bf64eda86cf83e27f68f3f0759d7ce70a2a5d Mon Sep 17 00:00:00 2001 From: Bluewhale1337 <295648290+Bluewhale1337@users.noreply.github.com> Date: Sat, 18 Jul 2026 23:34:20 +0200 Subject: [PATCH 03/12] fix: resolve Self Only buff tracking failing on raid frames by replacing direct unit string comparisons with UnitIsUnit --- HealBot_Controller_Aura.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/HealBot_Controller_Aura.lua b/HealBot_Controller_Aura.lua index 9ae5d5e..5ece90c 100644 --- a/HealBot_Controller_Aura.lua +++ b/HealBot_Controller_Aura.lua @@ -91,7 +91,7 @@ function HealBot_CheckBuffs(unit) local val = HealBot_Config.BuffDropDowns[myClass][j] if val and val > 0 then local isSelfOnly = (HealBot_Config.BuffWatchSelf and HealBot_Config.BuffWatchSelf[j] == 1) - if not (isSelfOnly and unit ~= "player") then + if not (isSelfOnly and not UnitIsUnit(unit, "player")) then local spellName = HealBot_Buff_Spells[myClass][val] local hasIt = hasBuff[spellName] @@ -100,7 +100,7 @@ function HealBot_CheckBuffs(unit) end if not hasIt then - if myClass == "SHAMAN" and unit == "player" and string.find(spellName, " Weapon") then + if myClass == "SHAMAN" and UnitIsUnit(unit, "player") and string.find(spellName, " Weapon") then hasIt = HealBot_CheckShamanWeaponBuff(spellName) end end From 3845ada15f5fc05342b70b83c9bc6fd5cfbbac1a Mon Sep 17 00:00:00 2001 From: Bluewhale1337 <295648290+Bluewhale1337@users.noreply.github.com> Date: Sat, 18 Jul 2026 23:37:51 +0200 Subject: [PATCH 04/12] fix: remove artificial mana check to allow 0-mana cost buffs and fix tooltips disappearing instead of turning red --- HealBot_Controller_Spells.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/HealBot_Controller_Spells.lua b/HealBot_Controller_Spells.lua index 2895dd3..38784c1 100644 --- a/HealBot_Controller_Spells.lua +++ b/HealBot_Controller_Spells.lua @@ -462,7 +462,8 @@ end function HealBot_CanCastSpell(spell, unit) local this = HealBot_Spells[spell]; - if this.Mana > UnitMana("player") then return false end; + -- Removed manual mana check so WoW can properly handle 0-cost buffs (Clearcasting/Inner Focus) + -- and so tooltips can render in red instead of disappearing. if this.BagSlot then local bag, slot = HealBot_UnpackBagSlot(this.BagSlot); local start, duration, enable = GetContainerItemCooldown(bag, slot); From 9f08b356e1cca7412a3867894a7b96e7641cf437 Mon Sep 17 00:00:00 2001 From: Bluewhale1337 <295648290+Bluewhale1337@users.noreply.github.com> Date: Sat, 18 Jul 2026 23:39:07 +0200 Subject: [PATCH 05/12] docs: append v1.5.1 changelog detailing memory, mana, and buff tracking fixes --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 063f1fd..7179741 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,11 @@ Default installation path: `C:\Program Files\World of Warcraft\Interface\AddOns\ ### Change Log +**v1.5.1** +* **Memory Optimization:** Fixed severe Lua garbage collection spikes during UI reloads by preventing full party layout rebuilds on `PLAYER_TARGET_CHANGED`, and cached dynamic string concatenations directly to unit frames to eliminate memory leakage on high frequency UI refreshes. +* **Mana Validation Fix:** Removed artificial spell mana gating, fixing an issue where low-mana spells disappeared from tooltips and couldn't be cast. WoW's native mana validation now correctly processes 0-cost buffs (e.g. Clearcasting, Inner Focus) while turning low-mana tooltip spells red. +* **Self-Buff Tracking:** Fixed a bug where "Self Only" buff tracking incorrectly excluded the player when represented by party or raid frames instead of the standard "player" unit ID. + **v1.5** * **Macro, Item, and Script Bindings:** Support for binding named macros, inventory items, and inline scripts (e.g. `/target`) directly to mouse clicks in the Spells tab. All of these now natively support implicit `@mouseover` targeting on the unit frame you click, without losing your current target. * **Modifier-Aware Tooltips & Resource Costs:** The tooltip dynamically updates to show exactly what action is bound when holding down Shift, Ctrl, or Alt over a frame. Spells also show their required mana cost, turning red if you do not have enough mana to cast them. From e6ad9e7506c1094af5eee26045189016634b0c1d Mon Sep 17 00:00:00 2001 From: Bluewhale1337 <295648290+Bluewhale1337@users.noreply.github.com> Date: Sat, 18 Jul 2026 23:43:35 +0200 Subject: [PATCH 06/12] perf: eliminate remaining GC spikes by preventing layout rebuilds on combat toggle and zeroing hot-loop table allocations --- HealBot_Controller_Aura.lua | 6 +++++- HealBot_Controller_Events.lua | 8 ++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/HealBot_Controller_Aura.lua b/HealBot_Controller_Aura.lua index 5ece90c..64eed93 100644 --- a/HealBot_Controller_Aura.lua +++ b/HealBot_Controller_Aura.lua @@ -2,6 +2,7 @@ -- Handles tracking buffs/debuffs (auras) on group/raid units HealBot_MissingBuffs = {} +local StaticHasBuff = {} function HealBot_UnitAffected(unit, effect) if not effect then return nil; end @@ -68,7 +69,10 @@ function HealBot_CheckBuffs(unit) } -- Gather buffs on unit - local hasBuff = {} + local hasBuff = StaticHasBuff + for k in pairs(hasBuff) do + hasBuff[k] = nil + end local i = 1 while true do local buffTexture = UnitBuff(unit, i) diff --git a/HealBot_Controller_Events.lua b/HealBot_Controller_Events.lua index 825d1ae..d7d4276 100644 --- a/HealBot_Controller_Events.lua +++ b/HealBot_Controller_Events.lua @@ -85,8 +85,8 @@ function HealBot_OnUpdate(this, arg1) if not HealBot_IsFighting then HealsIn_Timer = HealsIn_Timer + 1; if HealsIn_Timer >= 10 then - HealBot_HealsIn = {}; - HealBot_Healers = {}; + for k in pairs(HealBot_HealsIn) do HealBot_HealsIn[k] = nil end + for k in pairs(HealBot_Healers) do HealBot_Healers[k] = nil end HealsIn_Timer = 0; end @@ -338,7 +338,7 @@ function HealBot_OnEvent_ZoneChanged(this) end function HealBot_OnEvent_PlayerRegenDisabled(this) - HealBot_RecalcParty(); + -- Removed HealBot_RecalcParty(); if (UnitIsDeadOrGhost("player")) or (UnitOnTaxi("player")) then if HealBot_Config.AutoClose==1 and HealBot_Config.ActionVisible~=0 then HealBot_Action.ProgrammaticHide = true; @@ -374,7 +374,7 @@ end function HealBot_OnEvent_PlayerRegenEnabled(this) HealBot_IsFighting = false; - HealBot_Delay_RecalcParty = 1; + -- Removed HealBot_Delay_RecalcParty = 1; end function HealBot_OnEvent_PlayerTargetChanged(this) From 441a45150f6461d8fd7f33de9b731399e7a29f82 Mon Sep 17 00:00:00 2001 From: Bluewhale1337 <295648290+Bluewhale1337@users.noreply.github.com> Date: Mon, 20 Jul 2026 18:13:47 +0200 Subject: [PATCH 07/12] feat: add Spell_Holy_AshesToAshes icon and implement debuff tracking loop in UnitAura handler --- HealBot_Controller_Aura.lua | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/HealBot_Controller_Aura.lua b/HealBot_Controller_Aura.lua index 64eed93..95fc671 100644 --- a/HealBot_Controller_Aura.lua +++ b/HealBot_Controller_Aura.lua @@ -127,6 +127,7 @@ local HealBot_TrackedHoTs = { ["Interface\\Icons\\Spell_Holy_SealOfProtection"] = true, ["Interface\\Icons\\Spell_Holy_Excorcism"] = true, ["Interface\\Icons\\btnholyscriptures"] = true, + ["Interface\\Icons\\Spell_Holy_AshesToAshes"] = true, } function HealBot_OnEvent_UnitAura(this, unit) @@ -172,6 +173,17 @@ function HealBot_OnEvent_UnitAura(this, unit) end b = b + 1 end + + local d = 1 + while true do + local debuff = UnitDebuff(unit, d) + if not debuff then break end + if HealBot_TrackedHoTs[debuff] and iconCount < 5 then + iconCount = iconCount + 1 + HealBot_UnitIcons[unit][iconCount] = debuff + end + d = d + 1 + end if HealBot_UnitDebuff[unit] then if DebuffType and HealBot_Range_Check(unit, 27) == 1 then From 85ad55c1cb2fe889ad3bddbd7e87b67c0c69471c Mon Sep 17 00:00:00 2001 From: Bluewhale1337 <295648290+Bluewhale1337@users.noreply.github.com> Date: Mon, 20 Jul 2026 23:22:15 +0200 Subject: [PATCH 08/12] perf: optimize CPU and memory usage via boolean state tracking, event filtering, and per-character SavedVariables. --- HealBotBlue.toc | 2 +- HealBot_Controller_Aura.lua | 2 +- HealBot_Controller_Events.lua | 44 ++++++++++++----------------------- HealBot_Data.lua | 2 +- HealBot_Options_CDC.lua | 6 ++--- README.md | 4 ++++ 6 files changed, 25 insertions(+), 35 deletions(-) diff --git a/HealBotBlue.toc b/HealBotBlue.toc index 6309ac0..1713e79 100644 --- a/HealBotBlue.toc +++ b/HealBotBlue.toc @@ -3,7 +3,7 @@ ## Version: 1.5 ## Author: Bluewhale ## Notes: Adds panel with skinable bars for healing and decursive -## SavedVariables: HealBot_Config +## SavedVariablesPerCharacter: HealBot_Config ..\..\FrameXML\Fonts.xml ..\..\FrameXML\OptionsFrameTemplates.xml ..\..\FrameXML\UIPanelTemplates.xml diff --git a/HealBot_Controller_Aura.lua b/HealBot_Controller_Aura.lua index 95fc671..9dee3c1 100644 --- a/HealBot_Controller_Aura.lua +++ b/HealBot_Controller_Aura.lua @@ -149,7 +149,7 @@ function HealBot_OnEvent_UnitAura(this, unit) iconCount = iconCount + 1 HealBot_UnitIcons[unit][iconCount] = debuff end - if HealBot_CDCInc[UnitClass(unit)] == 1 and HealBot_DebuffWatch[debuff_type] == "YES" then + if HealBot_CDCInc[UnitClass(unit)] == 1 and HealBot_DebuffWatch[debuff_type] then HealBot_UnitDebuff[unit] = debuff_type DebuffType = debuff_type; if HealBot_DebuffPriority[debuff_type] then diff --git a/HealBot_Controller_Events.lua b/HealBot_Controller_Events.lua index d7d4276..228fb0e 100644 --- a/HealBot_Controller_Events.lua +++ b/HealBot_Controller_Events.lua @@ -43,17 +43,20 @@ end function HealBot_OnUpdate(this, arg1) if HealBot_Action_TooltipUnit and HealBot_Tooltip:IsVisible() then - local currentModState = "" - if IsShiftKeyDown() then currentModState = currentModState .. "S" end - if IsControlKeyDown() then currentModState = currentModState .. "C" end - if IsAltKeyDown() then currentModState = currentModState .. "A" end + local s = IsShiftKeyDown() and true or false + local c = IsControlKeyDown() and true or false + local a = IsAltKeyDown() and true or false - if HealBot_LastModState ~= currentModState then - HealBot_LastModState = currentModState + if HealBot_LastModS ~= s or HealBot_LastModC ~= c or HealBot_LastModA ~= a then + HealBot_LastModS = s + HealBot_LastModC = c + HealBot_LastModA = a HealBot_Action_RefreshTooltip(HealBot_Action_TooltipUnit) end else - HealBot_LastModState = "" + HealBot_LastModS = false + HealBot_LastModC = false + HealBot_LastModA = false end if HealBot_TargetRestorePending then @@ -131,6 +134,7 @@ local HealBot_EventHandlers = { HealBot_OnEvent_UnitHealth(this, arg1) end, ["UNIT_MANA"] = function(this, arg1) + if arg1 ~= "player" and HealBot_Config.ShowManaBars == 0 then return end if HealBot_Model:UpdateUnitPower(arg1) then HealBot_Model:NotifyObservers("UNIT_POWER_CHANGED", arg1) end @@ -138,6 +142,7 @@ local HealBot_EventHandlers = { HealBot_Action_RefreshButtons(arg1); end, ["UNIT_RAGE"] = function(this, arg1) + if arg1 ~= "player" and HealBot_Config.ShowManaBars == 0 then return end if HealBot_Model:UpdateUnitPower(arg1) then HealBot_Model:NotifyObservers("UNIT_POWER_CHANGED", arg1) end @@ -145,6 +150,7 @@ local HealBot_EventHandlers = { HealBot_Action_RefreshButtons(arg1); end, ["UNIT_ENERGY"] = function(this, arg1) + if arg1 ~= "player" and HealBot_Config.ShowManaBars == 0 then return end if HealBot_Model:UpdateUnitPower(arg1) then HealBot_Model:NotifyObservers("UNIT_POWER_CHANGED", arg1) end @@ -152,6 +158,7 @@ local HealBot_EventHandlers = { HealBot_Action_RefreshButtons(arg1); end, ["UNIT_DISPLAYPOWER"] = function(this, arg1) + if arg1 ~= "player" and HealBot_Config.ShowManaBars == 0 then return end if HealBot_Model:UpdateUnitPower(arg1) then HealBot_Model:NotifyObservers("UNIT_POWER_CHANGED", arg1) end @@ -201,8 +208,6 @@ local HealBot_EventHandlers = { ["SPELLCAST_FAILED"] = function(this) HealBot_OnEvent_SpellcastStop(this, "SPELLCAST_FAILED") end, ["PLAYER_REGEN_DISABLED"] = function(this) HealBot_OnEvent_PlayerRegenDisabled(this) end, ["PLAYER_REGEN_ENABLED"] = function(this) HealBot_OnEvent_PlayerRegenEnabled(this) end, - ["BAG_UPDATE_COOLDOWN"] = function(this, arg1) HealBot_OnEvent_BagUpdateCooldown(this, arg1) end, - ["BAG_UPDATE"] = function(this, arg1) HealBot_OnEvent_BagUpdate(this, arg1) end, ["PARTY_MEMBER_DISABLE"] = function(this, arg1) HealBot_OnEvent_PartyMemberDisable(this, arg1) end, ["PARTY_MEMBER_ENABLE"] = function(this, arg1) HealBot_OnEvent_PartyMemberEnable(this, arg1) end, ["CHAT_MSG_SYSTEM"] = function(this, arg1) HealBot_OnEvent_SystemMsg(this, arg1) end, @@ -212,11 +217,10 @@ local HealBot_EventHandlers = { HealBot_OnEvent_PlayerEquipmentChanged(this) end, ["UNIT_INVENTORY_CHANGED"] = function(this, arg1) + if arg1 ~= "player" then return end HealBot_Model:NotifyObservers("EQUIPMENT_CHANGED", arg1) HealBot_OnEvent_PlayerEquipmentChanged2(this, arg1) end, - ["PET_BAR_SHOWGRID"] = function(this) HealBot_OnEvent_PartyMembersChanged(this) end, - ["PET_BAR_HIDEGRID"] = function(this) HealBot_OnEvent_PartyMembersChanged(this) end, ["UNIT_PET"] = function(this, arg1) HealBot_OnEvent_PartyMembersChanged(this) end, ["SPELLS_CHANGED"] = function(this, arg1) HealBot_OnEvent_SpellsChanged(this, arg1) end, ["UPDATE_SHAPESHIFT_FORM"] = function(this) HealBot_UpdateShapeshiftForm() end, @@ -288,8 +292,6 @@ function HealBot_OnEvent_VariablesLoaded(this) this:RegisterEvent("PARTY_MEMBERS_CHANGED"); this:RegisterEvent("PARTY_MEMBER_DISABLE"); this:RegisterEvent("PARTY_MEMBER_ENABLE"); - this:RegisterEvent("PET_BAR_SHOWGRID"); - this:RegisterEvent("PET_BAR_HIDEGRID"); this:RegisterEvent("UNIT_PET"); this:RegisterEvent("UNIT_HEALTH"); this:RegisterEvent("UNIT_MANA"); @@ -301,8 +303,6 @@ function HealBot_OnEvent_VariablesLoaded(this) this:RegisterEvent("SPELLCAST_STOP"); this:RegisterEvent("SPELLCAST_INTERRUPTED"); this:RegisterEvent("SPELLCAST_FAILED"); - this:RegisterEvent("BAG_UPDATE"); - this:RegisterEvent("BAG_UPDATE_COOLDOWN"); this:RegisterEvent("UNIT_AURA"); this:RegisterEvent("UPDATE_INVENTORY_ALERTS"); this:RegisterEvent("UNIT_INVENTORY_CHANGED"); @@ -442,20 +442,6 @@ function HealBot_OnEvent_TalentsChanged(this, arg1) HealBot_AddDebug("HB: TalentsChanged"); end -function HealBot_OnEvent_BagUpdate(this, bag) - if HealBot_EquipChangeTimer == 0 then - HealBot_RecalcSpells(); - end -end - -function HealBot_OnEvent_BagUpdateCooldown(this, bag) - if not bag then - bag = "undef" - elseif HealBot_EquipChangeTimer == 0 then - HealBot_RecalcSpells(); - end -end - function HealBot_OnEvent_PlayerEnteringWorld(this) HealBot_IsFighting = false; -- Re-apply the refresh hook late in case another addon overrode it during load diff --git a/HealBot_Data.lua b/HealBot_Data.lua index 6915aa6..a6fe2bf 100644 --- a/HealBot_Data.lua +++ b/HealBot_Data.lua @@ -545,7 +545,7 @@ HealBot_Debuff_Types = { HealBot_IsFighting = false; HealBot_DebuffPriority = {"none"}; -HealBot_DebuffWatch = {[HEALBOT_DISEASE_en]="NO", [HEALBOT_MAGIC_en]="NO", [HEALBOT_POISON_en]="NO", [HEALBOT_CURSE_en]="NO"}; +HealBot_DebuffWatch = {[HEALBOT_DISEASE_en]=false, [HEALBOT_MAGIC_en]=false, [HEALBOT_POISON_en]=false, [HEALBOT_CURSE_en]=false}; HealBot_Heals = {}; diff --git a/HealBot_Options_CDC.lua b/HealBot_Options_CDC.lua index 14e81c4..c52de4b 100644 --- a/HealBot_Options_CDC.lua +++ b/HealBot_Options_CDC.lua @@ -247,16 +247,16 @@ function HealBot_Options_Debuff_Reset() local classEN=HealBot_UnitClass("player") if classEN=="PRIEST" or classEN=="DRUID" or classEN=="PALADIN" or classEN=="SHAMAN" then local spell = HealBot_Config.CDCLeftText[UnitClass("player")]; - HealBot_DebuffWatch = {[HEALBOT_DISEASE_en]="NO", [HEALBOT_MAGIC_en]="NO", [HEALBOT_POISON_en]="NO", [HEALBOT_CURSE_en]="NO" } + HealBot_DebuffWatch = {[HEALBOT_DISEASE_en]=false, [HEALBOT_MAGIC_en]=false, [HEALBOT_POISON_en]=false, [HEALBOT_CURSE_en]=false } if spell ~= "None" then table.foreach(HealBot_Debuff_Types[spell], function (index,debuff) - HealBot_DebuffWatch[debuff]="YES"; + HealBot_DebuffWatch[debuff]=true; end) end spell = HealBot_Config.CDCRightText[UnitClass("player")]; if spell ~= "None" then table.foreach(HealBot_Debuff_Types[spell], function (index,debuff) - HealBot_DebuffWatch[debuff]="YES"; + HealBot_DebuffWatch[debuff]=true; end) end end diff --git a/README.md b/README.md index 7179741..68f0212 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,10 @@ Default installation path: `C:\Program Files\World of Warcraft\Interface\AddOns\ * **Memory Optimization:** Fixed severe Lua garbage collection spikes during UI reloads by preventing full party layout rebuilds on `PLAYER_TARGET_CHANGED`, and cached dynamic string concatenations directly to unit frames to eliminate memory leakage on high frequency UI refreshes. * **Mana Validation Fix:** Removed artificial spell mana gating, fixing an issue where low-mana spells disappeared from tooltips and couldn't be cast. WoW's native mana validation now correctly processes 0-cost buffs (e.g. Clearcasting, Inner Focus) while turning low-mana tooltip spells red. * **Self-Buff Tracking:** Fixed a bug where "Self Only" buff tracking incorrectly excluded the player when represented by party or raid frames instead of the standard "player" unit ID. +* **Settings Persistence Fix:** Changed `SavedVariables` to `SavedVariablesPerCharacter` in TOC so configurations correctly load unique per character instead of account-wide. +* **CPU Optimization:** Added early exit logic to resource tracking events (Mana, Rage, Energy) to stop background polling on party/raid members when "Show Mana Bars" is toggled off. Also removed excessive triggers (`BAG_UPDATE`, `PET_BAR_SHOWGRID`) and filtered `UNIT_INVENTORY_CHANGED` to only process the player, eliminating massive CPU spikes and unnecessary UI layout rebuilds during looting, item cooldowns, or when other players change gear. +* **OnUpdate GC Spike Fix:** Rewrote the modifier polling logic inside `HealBot_OnUpdate` to use boolean state tracking instead of dynamic string concatenation, eliminating a major source of garbage collection bloat while hovering over unit frames. +* **Aura Scanning Optimization:** Refactored Debuff tracking (`HealBot_DebuffWatch`) to use native boolean values (`true`/`false`) instead of string comparisons (`"YES"`/`"NO"`). This improves performance inside the continuous aura scanning loops. **v1.5** * **Macro, Item, and Script Bindings:** Support for binding named macros, inventory items, and inline scripts (e.g. `/target`) directly to mouse clicks in the Spells tab. All of these now natively support implicit `@mouseover` targeting on the unit frame you click, without losing your current target. From dd9f9886b4f96c4f939767b0adb0da28c02cb8d6 Mon Sep 17 00:00:00 2001 From: Bluewhale1337 <295648290+Bluewhale1337@users.noreply.github.com> Date: Tue, 21 Jul 2026 09:02:33 +0200 Subject: [PATCH 09/12] feat: implement automatic skin swapping based on group size and add horizontal grid layout options --- HealBotBlue.toc | 1 + HealBot_Data.lua | 10 +++ HealBot_Options.lua | 2 + HealBot_Options.xml | 9 +++ HealBot_Options_Auto.lua | 79 ++++++++++++++++++++ HealBot_Options_Auto.xml | 152 ++++++++++++++++++++++++++++++++++++++ HealBot_Options_Skins.lua | 18 +++++ HealBot_Options_Skins.xml | 36 ++++++++- HealBot_View_Layout.lua | 93 +++++++++++++++++++---- 9 files changed, 385 insertions(+), 15 deletions(-) create mode 100644 HealBot_Options_Auto.lua create mode 100644 HealBot_Options_Auto.xml diff --git a/HealBotBlue.toc b/HealBotBlue.toc index 1713e79..cb73825 100644 --- a/HealBotBlue.toc +++ b/HealBotBlue.toc @@ -27,3 +27,4 @@ HealBot_Options_CDC.xml HealBot_Options_Skins.xml HealBot_Options_Buffs.xml HealBot_Options_Chat.xml +HealBot_Options_Auto.xml diff --git a/HealBot_Data.lua b/HealBot_Data.lua index a6fe2bf..e0a5377 100644 --- a/HealBot_Data.lua +++ b/HealBot_Data.lua @@ -181,7 +181,17 @@ HealBot_ConfigDefaults = { Current_Skin = "Modern Flat", Skin_ID = 1, Skins = {"Modern Flat", HEALBOT_SKINS_STD, "HealBot Party", "HealBot Raid", "Alteric Valley"}, + AutoSwap_Enabled = 0, + AutoSwap_Profiles = { + [1] = "Modern Flat", -- Solo + [2] = "HealBot Party", -- Party (2-5) + [3] = "HealBot Raid", -- Raid 15 (6-15) + [4] = "HealBot Raid", -- Raid 25 (16-25) + [5] = "HealBot Raid", -- Raid 40 (26-40) + }, numcols = {[HEALBOT_SKINS_STD] = 1, ["HealBot Party"] = 1, ["HealBot Raid"] = 4, ["Alteric Valley"] = 2, ["Modern Flat"] = 1}, + bmaxrows = {[HEALBOT_SKINS_STD] = 0, ["HealBot Party"] = 0, ["HealBot Raid"] = 0, ["Alteric Valley"] = 0, ["Modern Flat"] = 0}, + GridOrientation = {[HEALBOT_SKINS_STD] = 1, ["HealBot Party"] = 1, ["HealBot Raid"] = 1, ["Alteric Valley"] = 1, ["Modern Flat"] = 1}, btexture = {[HEALBOT_SKINS_STD] = 8,["HealBot Party"] = 6, ["HealBot Raid"] = 7, ["Alteric Valley"] = 9, ["Modern Flat"] = 10}, bcspace = {[HEALBOT_SKINS_STD] = 4, ["HealBot Party"] = 4, ["HealBot Raid"] = 2, ["Alteric Valley"] = 2, ["Modern Flat"] = 4}, brspace = {[HEALBOT_SKINS_STD] = 1, ["HealBot Party"] = 2, ["HealBot Raid"] = 2, ["Alteric Valley"] = 1, ["Modern Flat"] = 2}, diff --git a/HealBot_Options.lua b/HealBot_Options.lua index 0a30e9c..f3ebf3e 100644 --- a/HealBot_Options.lua +++ b/HealBot_Options.lua @@ -314,6 +314,8 @@ function HealBot_Options_SetSkins() HealBot_Options_BarHeightS:SetValue(HealBot_Config.bheight[HealBot_Config.Current_Skin]) HealBot_Options_BarWidthS:SetValue(HealBot_Config.bwidth[HealBot_Config.Current_Skin]) HealBot_Options_BarNumColsS:SetValue(HealBot_Config.numcols[HealBot_Config.Current_Skin]) + HealBot_Options_BarMaxRowsS:SetValue(HealBot_Config.bmaxrows[HealBot_Config.Current_Skin] or 0) + HealBot_Options_GridOrientation:SetChecked((HealBot_Config.GridOrientation[HealBot_Config.Current_Skin] == 2) and 1 or nil) HealBot_Options_BarBRSpaceS:SetValue(HealBot_Config.brspace[HealBot_Config.Current_Skin]) HealBot_Options_BarBCSpaceS:SetValue(HealBot_Config.bcspace[HealBot_Config.Current_Skin]) HealBot_Options_FramePaddingS:SetValue((HealBot_Config.bpadding and HealBot_Config.bpadding[HealBot_Config.Current_Skin]) or 10) diff --git a/HealBot_Options.xml b/HealBot_Options.xml index 31db38a..c2c12a2 100644 --- a/HealBot_Options.xml +++ b/HealBot_Options.xml @@ -206,6 +206,15 @@ +