mirror of
https://github.com/Bluewhale1337/HealBotBlue.git
synced 2026-10-27 06:00:54 +00:00
+1
-1
@@ -1,6 +1,6 @@
|
||||
## Interface: 11200
|
||||
## Title: HealBotBlue
|
||||
## Version: 1.7.2
|
||||
## Version: 1.7.3
|
||||
## Author: Bluewhale
|
||||
## Notes: Raidframe replacement for healing, decursing, resource tracking and buffing with optional support for SuperWow, ClassicAPI, UnitXP_SP3 and Nampower.
|
||||
## SavedVariablesPerCharacter: HealBot_Config
|
||||
|
||||
+4
-2
@@ -136,9 +136,10 @@ end
|
||||
|
||||
-- HealBot_SplitString: Internal utility: HealBot_SplitString
|
||||
function HealBot_SplitString(str, delimiter)
|
||||
local result = {}
|
||||
local result = HealBot_GetTable()
|
||||
if not delimiter or delimiter == "" then
|
||||
return {str}
|
||||
table.insert(result, str)
|
||||
return result
|
||||
end
|
||||
local start_pos = 1
|
||||
while true do
|
||||
@@ -160,6 +161,7 @@ function HealBot_RunMacroText(body)
|
||||
ChatFrameEditBox:SetText(commands[i])
|
||||
ChatEdit_SendText(ChatFrameEditBox)
|
||||
end
|
||||
HealBot_ReleaseTable(commands)
|
||||
end
|
||||
|
||||
-- HealBot_RunMacro: Internal utility: HealBot_RunMacro
|
||||
|
||||
@@ -41,6 +41,7 @@ function HealBot_CheckShamanWeaponBuff(spellName)
|
||||
if not firstWord then return false end
|
||||
|
||||
HealBot_ScanTooltip:SetOwner(UIParent, "ANCHOR_NONE")
|
||||
if not HealBot_ScanTooltip_Lines then HealBot_ScanTooltip_Lines = {} end
|
||||
local slots = HealBot_GetTable()
|
||||
if hasMainHandEnchant then table.insert(slots, 16) end
|
||||
if hasOffHandEnchant then table.insert(slots, 17) end
|
||||
@@ -49,7 +50,11 @@ function HealBot_CheckShamanWeaponBuff(spellName)
|
||||
HealBot_ScanTooltip:ClearLines()
|
||||
HealBot_ScanTooltip:SetInventoryItem("player", slot)
|
||||
for i = 1, HealBot_ScanTooltip:NumLines() do
|
||||
local textObj = getglobal("HealBot_ScanTooltipTextLeft" .. i)
|
||||
local textObj = HealBot_ScanTooltip_Lines[i]
|
||||
if not textObj then
|
||||
textObj = getglobal("HealBot_ScanTooltipTextLeft" .. i)
|
||||
HealBot_ScanTooltip_Lines[i] = textObj
|
||||
end
|
||||
if textObj then
|
||||
local text = textObj:GetText()
|
||||
if text and string.find(text, firstWord) then
|
||||
@@ -184,7 +189,7 @@ function HealBot_OnEvent_UnitAura(this, unit)
|
||||
local iconCount = 0
|
||||
local i = 1;
|
||||
HealBot_UnitDebuff[unit] = nil;
|
||||
local trackedTextures = {}
|
||||
local trackedTextures = HealBot_GetTable()
|
||||
|
||||
while true do
|
||||
local debuff, tmp, debuff_type = UnitDebuff(unit, i, 1)
|
||||
@@ -301,5 +306,6 @@ function HealBot_OnEvent_UnitAura(this, unit)
|
||||
|
||||
-- Defer UI updates
|
||||
HealBot_View_DirtyUnits[unit] = true
|
||||
HealBot_ReleaseTable(trackedTextures)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -69,11 +69,11 @@ function HealBot_OnUpdate(this, arg1)
|
||||
local pending = HealBot_TargetRestorePending;
|
||||
HealBot_TargetRestorePending = nil;
|
||||
HealBot_TargetRestoreTimer = 0;
|
||||
if pending.type == "enemy" then
|
||||
if pending == "enemy" then
|
||||
TargetLastEnemy();
|
||||
elseif pending.type == "friend" then
|
||||
elseif pending == "friend" then
|
||||
TargetLastTarget();
|
||||
elseif pending.type == "clear" then
|
||||
elseif pending == "clear" then
|
||||
ClearTarget();
|
||||
end
|
||||
end
|
||||
@@ -112,11 +112,11 @@ function HealBot_OnUpdate(this, arg1)
|
||||
|
||||
-- Restore target logic
|
||||
if pendingCast.targetEnemy then
|
||||
HealBot_TargetRestorePending = { type = "enemy" }
|
||||
HealBot_TargetRestorePending = "enemy"
|
||||
elseif pendingCast.oldTarget and pendingCast.oldTarget ~= UnitName(pendingCast.target) then
|
||||
HealBot_TargetRestorePending = { type = "friend" }
|
||||
HealBot_TargetRestorePending = "friend"
|
||||
elseif not pendingCast.oldTarget then
|
||||
HealBot_TargetRestorePending = { type = "clear" }
|
||||
HealBot_TargetRestorePending = "clear"
|
||||
end
|
||||
HealBot_TargetRestoreTimer = 0
|
||||
end
|
||||
|
||||
+102
-24
@@ -3,6 +3,7 @@
|
||||
|
||||
HealBot_CastingSpell = nil;
|
||||
HealBot_CastingTarget = nil;
|
||||
HealBot_CastingGroupMembers = nil;
|
||||
HealBot_TargetRestorePending = nil;
|
||||
HealBot_TargetRestoreTimer = 0;
|
||||
|
||||
@@ -158,13 +159,52 @@ function HealBot_Process_HealValue(spell, target)
|
||||
end
|
||||
local uname = UnitName(target)
|
||||
if uname then
|
||||
HealBot_SendAddonMessage(HEALBOT_ADDON_ID, ">> " .. uname .. " <<=>> " .. HealBot_HealValue .. " << ");
|
||||
HealBot_SendAddonMessage("HealComm", "Heal/" .. uname .. "/" .. HealBot_HealValue .. "/1500/");
|
||||
if not HealBot_HealsIn[uname] then
|
||||
HealBot_HealsIn[uname] = 0;
|
||||
if not HealBot_CastingGroupMembers then HealBot_CastingGroupMembers = {} end
|
||||
for i=1, table.getn(HealBot_CastingGroupMembers) do HealBot_CastingGroupMembers[i] = nil end
|
||||
table.setn(HealBot_CastingGroupMembers, 0)
|
||||
if HEALBOT_PRAYER_OF_HEALING and string.find(spell, HEALBOT_PRAYER_OF_HEALING) then
|
||||
if GetNumRaidMembers() > 0 then
|
||||
local targetGroup = 0
|
||||
for i = 1, GetNumRaidMembers() do
|
||||
local name, _, subgroup = GetRaidRosterInfo(i)
|
||||
if name == uname then targetGroup = subgroup; break; end
|
||||
end
|
||||
if targetGroup > 0 then
|
||||
for i = 1, GetNumRaidMembers() do
|
||||
local name, _, subgroup = GetRaidRosterInfo(i)
|
||||
if subgroup == targetGroup and name then table.insert(HealBot_CastingGroupMembers, name); end
|
||||
end
|
||||
end
|
||||
else
|
||||
table.insert(HealBot_CastingGroupMembers, UnitName("player"))
|
||||
for i = 1, GetNumPartyMembers() do
|
||||
if UnitName("party"..i) then table.insert(HealBot_CastingGroupMembers, UnitName("party"..i)); end
|
||||
end
|
||||
end
|
||||
end
|
||||
if table.getn(HealBot_CastingGroupMembers) == 0 then
|
||||
table.insert(HealBot_CastingGroupMembers, uname)
|
||||
end
|
||||
|
||||
if table.getn(HealBot_CastingGroupMembers) > 1 then
|
||||
local commsStr = "GrpHeal/" .. HealBot_HealValue .. "/1500/"
|
||||
for _, memberName in ipairs(HealBot_CastingGroupMembers) do
|
||||
commsStr = commsStr .. memberName .. "/"
|
||||
end
|
||||
HealBot_SendAddonMessage("HealComm", commsStr)
|
||||
for _, memberName in ipairs(HealBot_CastingGroupMembers) do
|
||||
HealBot_SendAddonMessage(HEALBOT_ADDON_ID, ">> " .. memberName .. " <<=>> " .. HealBot_HealValue .. " << ")
|
||||
if not HealBot_HealsIn[memberName] then HealBot_HealsIn[memberName] = 0 end
|
||||
HealBot_HealsIn[memberName] = HealBot_HealsIn[memberName] + HealBot_HealValue
|
||||
HealBot_RecalcHeals(HealBot_FindUnitID(memberName))
|
||||
end
|
||||
else
|
||||
HealBot_SendAddonMessage("HealComm", "Heal/" .. uname .. "/" .. HealBot_HealValue .. "/1500/")
|
||||
HealBot_SendAddonMessage(HEALBOT_ADDON_ID, ">> " .. uname .. " <<=>> " .. HealBot_HealValue .. " << ")
|
||||
if not HealBot_HealsIn[uname] then HealBot_HealsIn[uname] = 0 end
|
||||
HealBot_HealsIn[uname] = HealBot_HealsIn[uname] + HealBot_HealValue
|
||||
HealBot_RecalcHeals(HealBot_FindUnitID(uname))
|
||||
end
|
||||
HealBot_HealsIn[uname] = HealBot_HealsIn[uname] + HealBot_HealValue;
|
||||
HealBot_RecalcHeals(HealBot_FindUnitID(uname));
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -217,14 +257,24 @@ function HealBot_StopCasting()
|
||||
if HealBot_HealValue > 0 then
|
||||
local uname = UnitName(HealBot_CastingTarget)
|
||||
if uname then
|
||||
HealBot_SendAddonMessage(HEALBOT_ADDON_ID, ">> " .. uname .. " <<=>> " .. 0 - HealBot_HealValue .. " << ");
|
||||
HealBot_SendAddonMessage("HealComm", "Healstop");
|
||||
if HealBot_HealsIn[uname] then
|
||||
HealBot_HealsIn[uname] = HealBot_HealsIn[uname] - HealBot_HealValue;
|
||||
if HealBot_HealsIn[uname] < 0 then
|
||||
HealBot_HealsIn[uname] = 0;
|
||||
end
|
||||
HealBot_RecalcHeals(HealBot_FindUnitID(uname));
|
||||
if HealBot_CastingGroupMembers and table.getn(HealBot_CastingGroupMembers) > 1 then
|
||||
HealBot_SendAddonMessage("HealComm", "GrpHealstop");
|
||||
for _, memberName in ipairs(HealBot_CastingGroupMembers) do
|
||||
HealBot_SendAddonMessage(HEALBOT_ADDON_ID, ">> " .. memberName .. " <<=>> " .. 0 - HealBot_HealValue .. " << ")
|
||||
if HealBot_HealsIn[memberName] then
|
||||
HealBot_HealsIn[memberName] = HealBot_HealsIn[memberName] - HealBot_HealValue;
|
||||
if HealBot_HealsIn[memberName] < 0 then HealBot_HealsIn[memberName] = 0; end
|
||||
HealBot_RecalcHeals(HealBot_FindUnitID(memberName));
|
||||
end
|
||||
end
|
||||
else
|
||||
HealBot_SendAddonMessage("HealComm", "Healstop");
|
||||
HealBot_SendAddonMessage(HEALBOT_ADDON_ID, ">> " .. uname .. " <<=>> " .. 0 - HealBot_HealValue .. " << ");
|
||||
if HealBot_HealsIn[uname] then
|
||||
HealBot_HealsIn[uname] = HealBot_HealsIn[uname] - HealBot_HealValue;
|
||||
if HealBot_HealsIn[uname] < 0 then HealBot_HealsIn[uname] = 0; end
|
||||
HealBot_RecalcHeals(HealBot_FindUnitID(uname));
|
||||
end
|
||||
end
|
||||
end
|
||||
HealBot_HealValue = 0;
|
||||
@@ -237,7 +287,7 @@ function HealBot_StopCasting()
|
||||
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
|
||||
bar:SetStatusBarColor(ar, ag, ab, 0);
|
||||
local sr = HealBot_Config.btextdisbledcolr[HealBot_Config.Current_Skin];
|
||||
local sg = HealBot_Config.btextdisbledcolg[HealBot_Config.Current_Skin];
|
||||
@@ -303,7 +353,7 @@ function HealBot_CheckCasting(unit)
|
||||
local sg = HealBot_Config.btextenabledcolg[HealBot_Config.Current_Skin];
|
||||
local sb = HealBot_Config.btextenabledcolb[HealBot_Config.Current_Skin];
|
||||
local sa = HealBot_Config.btextenabledcola[HealBot_Config.Current_Skin];
|
||||
bar.txt = getglobal(bar:GetName() .. "_text");
|
||||
if not bar.txt then bar.txt = getglobal(bar:GetName() .. "_text") end
|
||||
bar.txt:SetTextColor(sr, sg, sb, sa);
|
||||
end
|
||||
end
|
||||
@@ -328,7 +378,15 @@ function HealBot_CastSpellOnFriend(spell, target)
|
||||
if formCancelled then
|
||||
-- ALWAYS put the cast into the Pending queue so the OnUpdate loop can wait for the server
|
||||
-- to process the unshift before attempting the cast, otherwise we get "You are in shapeshift form".
|
||||
HealBot_PendingShapeshiftCast = { spell = spell, target = target, targetEnemy = targetEnemy, oldTarget = oldTarget, fireTime = GetTime() + 0.05, expires = GetTime() + 2.0 }
|
||||
if not HealBot_PendingShapeshiftCast then HealBot_PendingShapeshiftCast = {} end
|
||||
HealBot_PendingShapeshiftCast.spell = spell
|
||||
HealBot_PendingShapeshiftCast.target = target
|
||||
HealBot_PendingShapeshiftCast.targetEnemy = targetEnemy
|
||||
HealBot_PendingShapeshiftCast.oldTarget = oldTarget
|
||||
HealBot_PendingShapeshiftCast.fireTime = GetTime() + 0.05
|
||||
HealBot_PendingShapeshiftCast.expires = GetTime() + 2.0
|
||||
HealBot_PendingShapeshiftCast.started = nil
|
||||
HealBot_PendingShapeshiftCast.nextSpam = nil
|
||||
return;
|
||||
end
|
||||
|
||||
@@ -339,11 +397,11 @@ function HealBot_CastSpellOnFriend(spell, target)
|
||||
HealBot_StartCasting(spell, target, "direct");
|
||||
|
||||
if targetEnemy then
|
||||
HealBot_TargetRestorePending = { type = "enemy" };
|
||||
HealBot_TargetRestorePending = "enemy";
|
||||
elseif oldTarget and oldTarget ~= UnitName(target) then
|
||||
HealBot_TargetRestorePending = { type = "friend" };
|
||||
HealBot_TargetRestorePending = "friend";
|
||||
elseif not oldTarget then
|
||||
HealBot_TargetRestorePending = { type = "clear" };
|
||||
HealBot_TargetRestorePending = "clear";
|
||||
end
|
||||
HealBot_TargetRestoreTimer = 0;
|
||||
end
|
||||
@@ -472,7 +530,7 @@ function HealBot_FindHealSpells()
|
||||
end
|
||||
end);
|
||||
|
||||
local items = {};
|
||||
local items = HealBot_GetTable();
|
||||
for bag = 0, NUM_BAG_FRAMES do
|
||||
for slot = 1, GetContainerNumSlots(bag) do
|
||||
local item = HealBot_GetItemName(bag, slot);
|
||||
@@ -498,6 +556,7 @@ function HealBot_FindHealSpells()
|
||||
HealBot_Heals["raidpet" .. i] = HealBot_Heals.party;
|
||||
end
|
||||
|
||||
HealBot_ReleaseTable(items);
|
||||
if HealBot_CalcEquipBonus then
|
||||
HealBot_AddDebug("...Done Equip Bonus:" .. RealHealing);
|
||||
end
|
||||
@@ -568,7 +627,15 @@ end
|
||||
|
||||
-- HealBot_RecalcHeals: Flags unit for visual refresh.
|
||||
function HealBot_RecalcHeals(unit)
|
||||
HealBot_Action_Refresh(unit);
|
||||
if unit then
|
||||
HealBot_View_DirtyUnits[unit] = true;
|
||||
else
|
||||
if HealBot_Action_UnitButtons then
|
||||
for u, _ in pairs(HealBot_Action_UnitButtons) do
|
||||
HealBot_View_DirtyUnits[u] = true;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- HealBot_RecalcParty: Triggers group layout rebuild.
|
||||
@@ -673,8 +740,15 @@ function HealBot_InitGetSpellData(spell, id, class)
|
||||
_cast = 0;
|
||||
line = nil;
|
||||
|
||||
if not HealBot_ScanTooltip_Lines_Left then HealBot_ScanTooltip_Lines_Left = {} end
|
||||
if not HealBot_ScanTooltip_Lines_Right then HealBot_ScanTooltip_Lines_Right = {} end
|
||||
|
||||
for lineNum = 2, 6 do
|
||||
local lText = getglobal("HealBot_ScanTooltipTextLeft"..lineNum);
|
||||
local lText = HealBot_ScanTooltip_Lines_Left[lineNum];
|
||||
if not lText then
|
||||
lText = getglobal("HealBot_ScanTooltipTextLeft"..lineNum);
|
||||
HealBot_ScanTooltip_Lines_Left[lineNum] = lText;
|
||||
end
|
||||
if lText and lText:IsVisible() and lText:GetText() then
|
||||
local txt = lText:GetText();
|
||||
local t1, t2, match;
|
||||
@@ -698,7 +772,11 @@ function HealBot_InitGetSpellData(spell, id, class)
|
||||
end
|
||||
end
|
||||
|
||||
local rText = getglobal("HealBot_ScanTooltipTextRight"..lineNum);
|
||||
local rText = HealBot_ScanTooltip_Lines_Right[lineNum];
|
||||
if not rText then
|
||||
rText = getglobal("HealBot_ScanTooltipTextRight"..lineNum);
|
||||
HealBot_ScanTooltip_Lines_Right[lineNum] = rText;
|
||||
end
|
||||
if rText and rText:IsVisible() and rText:GetText() then
|
||||
local txt = rText:GetText();
|
||||
local t1, t2, match;
|
||||
|
||||
@@ -44,7 +44,7 @@ function HealBot_Integrations_Toggle()
|
||||
if not spellName then return end
|
||||
|
||||
if not HealBot_Nampower_Auras[target] then
|
||||
HealBot_Nampower_Auras[target] = {}
|
||||
HealBot_Nampower_Auras[target] = HealBot_GetTable()
|
||||
end
|
||||
|
||||
local expirationTime = GetTime() + (duration / 1000)
|
||||
@@ -61,7 +61,8 @@ function HealBot_Integrations_Toggle()
|
||||
HealBot_Integrations_Nampower_Active = false;
|
||||
HealBot_AddDebug("nampower Integration: DISABLED");
|
||||
if HealBot_Nampower_Auras then
|
||||
for k in pairs(HealBot_Nampower_Auras) do
|
||||
for k, v in pairs(HealBot_Nampower_Auras) do
|
||||
HealBot_ReleaseTable(v)
|
||||
HealBot_Nampower_Auras[k] = nil
|
||||
end
|
||||
end
|
||||
@@ -76,6 +77,7 @@ function HealBot_Integrations_PruneNampower()
|
||||
for targetName, auras in pairs(HealBot_Nampower_Auras) do
|
||||
-- Check if target is still in the raid/party
|
||||
if not HealBot_Model:GetUnitIDByName(targetName) then
|
||||
HealBot_ReleaseTable(auras)
|
||||
HealBot_Nampower_Auras[targetName] = nil
|
||||
else
|
||||
-- Prune expired auras
|
||||
@@ -88,6 +90,7 @@ function HealBot_Integrations_PruneNampower()
|
||||
end
|
||||
end
|
||||
if not hasAuras then
|
||||
HealBot_ReleaseTable(auras)
|
||||
HealBot_Nampower_Auras[targetName] = nil
|
||||
end
|
||||
end
|
||||
|
||||
+4
-3
@@ -245,11 +245,12 @@ function HealBot_Model:PreserveStateByGUID()
|
||||
for targetUnit, stateData in pairs(stateSwaps) do
|
||||
-- Deep copy to prevent memory aliasing
|
||||
if not self.units[targetUnit] then
|
||||
self.units[targetUnit] = { icons = {} }
|
||||
self.units[targetUnit] = HealBot_GetTable()
|
||||
self.units[targetUnit].icons = HealBot_GetTable()
|
||||
end
|
||||
|
||||
local targetIcons = self.units[targetUnit].icons
|
||||
if not targetIcons then targetIcons = {} end
|
||||
if not targetIcons then targetIcons = HealBot_GetTable() end
|
||||
for k in pairs(targetIcons) do targetIcons[k] = nil end
|
||||
|
||||
for k in pairs(self.units[targetUnit]) do self.units[targetUnit][k] = nil end
|
||||
@@ -262,7 +263,7 @@ function HealBot_Model:PreserveStateByGUID()
|
||||
self.units[targetUnit].icons = targetIcons
|
||||
|
||||
if HealBot_UnitIcons and iconSwaps[targetUnit] then
|
||||
if not HealBot_UnitIcons[targetUnit] then HealBot_UnitIcons[targetUnit] = {} end
|
||||
if not HealBot_UnitIcons[targetUnit] then HealBot_UnitIcons[targetUnit] = HealBot_GetTable() end
|
||||
for j=1, 10 do
|
||||
HealBot_UnitIcons[targetUnit][j] = iconSwaps[targetUnit][j]
|
||||
end
|
||||
|
||||
@@ -857,8 +857,10 @@ function HealBot_Action_PartyChanged()
|
||||
if i == last then break end
|
||||
end
|
||||
else
|
||||
local petUnits = { "pet", "partypet1", "partypet2", "partypet3", "partypet4" };
|
||||
for _, unit in ipairs(petUnits) do
|
||||
if not HealBot_PetUnits then
|
||||
HealBot_PetUnits = { "pet", "partypet1", "partypet2", "partypet3", "partypet4" };
|
||||
end
|
||||
for _, unit in ipairs(HealBot_PetUnits) do
|
||||
if not HealBot_Action_UnitButtons[unit] and HealBot_MayHeal(unit) then
|
||||
i = i + 1;
|
||||
HealBot_Action_SetHealButton(i, unit);
|
||||
@@ -1153,7 +1155,7 @@ end
|
||||
function HealBot_Action_AppendNewUnits()
|
||||
if not HealBot_Grid_LastI then return end
|
||||
|
||||
local unitsToCheck = {}
|
||||
local unitsToCheck = HealBot_GetTable()
|
||||
|
||||
-- Gather units based on config, similar to PartyChanged
|
||||
if HealBot_Config.GroupHeals == 1 then
|
||||
@@ -1220,4 +1222,5 @@ function HealBot_Action_AppendNewUnits()
|
||||
HealBot_Action_AppendUnit(unit)
|
||||
end
|
||||
end
|
||||
HealBot_ReleaseTable(unitsToCheck)
|
||||
end
|
||||
|
||||
@@ -49,6 +49,10 @@ Default installation path: `C:\Program Files\World of Warcraft\Interface\AddOns\
|
||||
|
||||
### Change Log
|
||||
|
||||
**v1.7.3**
|
||||
* **Performance Fix - Table Pooling Part 2** - Fixed remaining un-pooled table allocations in layout updates, macro parsing, nampower integration, and aura tracking by utilizing HealBot_GetTable().
|
||||
* **Performance Fix - HealComm Networking** - Fixed issue where incoming `HealComm` messages triggered synchronous UI redraws, causing massive lag in 40-man raids during combat. `HealBot_RecalcHeals` is now decoupled and deferred through the `HealBot_OnUpdate` dirty queue, allowing multiple network events to collapse into a single frame redraw.
|
||||
|
||||
**v1.7.2**
|
||||
* **Performance Fix - Table Pooling** - Fixed massive Vanilla Lua 5.0 garbage collection memory leaks caused by unbounded table allocations in high-frequency update loops (e.g., `OnUpdate` and `PreserveStateByGUID`). Moved tables to file-local scope and implemented inline clearing.
|
||||
* **Performance Fix - OOC Cleanup** - Added an out-of-combat garbage collection hook (`PLAYER_REGEN_ENABLED`) to purge disconnected senders from the `HealBot_IncomingHealers` global table, preventing memory bloat during prolonged play sessions.
|
||||
|
||||
Reference in New Issue
Block a user