36 Commits

Author SHA1 Message Date
Bluewhale1337 5340eb253a Merge pull request #9 from Bluewhale1337/dev
Merge pull request #8 from Bluewhale1337/main
2026-07-21 13:52:32 +02:00
Bluewhale1337 bbff4a461c Merge branch 'dev' of https://github.com/Bluewhale1337/HealBotBlue into dev 2026-07-21 13:51:55 +02:00
Bluewhale1337 40ad96ae07 bump version to 1.6.0 in HealBotBlue.toc 2026-07-21 13:51:51 +02:00
Bluewhale1337 611f584b8d docs: update version to v1.6 in changelog 2026-07-21 13:50:07 +02:00
Bluewhale1337 5f015c89e5 Merge branch 'main' of https://github.com/Bluewhale1337/HealBotBlue 2026-07-21 13:48:03 +02:00
Bluewhale1337 e20c5baf74 docs: remove redundant trailing space in README version history 2026-07-21 13:48:00 +02:00
Bluewhale1337 9fd6f47946 Merge pull request #8 from Bluewhale1337/main
Hotfix merge
2026-07-21 13:44:13 +02:00
Bluewhale1337 1f339a8da5 Merge branch 'dev' into main
Signed-off-by: Bluewhale1337 <295648290+Bluewhale1337@users.noreply.github.com>
2026-07-21 13:40:02 +02:00
Bluewhale1337 00f9c3d485 fix(ui): center text, fix menu overlap, relabel extra to raid (hotfix 1.5.1) 2026-07-21 13:28:55 +02:00
Bluewhale1337 41e4a15075 feat: read version dynamically from TOC file 2026-07-21 13:26:43 +02:00
Bluewhale1337 026d4093aa refactor: optimize event processing, move global UI buttons, and reorganize options layout 2026-07-21 11:21:35 +02:00
Bluewhale1337 db07c467a3 chore: dynamically fetch version from add-on metadata instead of hardcoding 2026-07-21 09:31:55 +02:00
Bluewhale1337 c47d17f790 feat: implement auto-swap profile system and add safety null checks for skin configuration data 2026-07-21 09:29:44 +02:00
Bluewhale1337 dd9f9886b4 feat: implement automatic skin swapping based on group size and add horizontal grid layout options 2026-07-21 09:02:33 +02:00
Bluewhale1337 85ad55c1cb perf: optimize CPU and memory usage via boolean state tracking, event filtering, and per-character SavedVariables. 2026-07-20 23:22:15 +02:00
Bluewhale1337 441a45150f feat: add Spell_Holy_AshesToAshes icon and implement debuff tracking loop in UnitAura handler 2026-07-20 18:13:47 +02:00
Bluewhale1337 0b610adaab Merge pull request #7 from Bluewhale1337/Bluewhale1337-patch-1
Update README.md
2026-07-20 08:12:21 +02:00
Bluewhale1337 609e2cc87b Update README.md
Fixed formatting

Signed-off-by: Bluewhale1337 <295648290+Bluewhale1337@users.noreply.github.com>
2026-07-20 08:12:07 +02:00
Bluewhale1337 12838ff250 Update HealBot_Localization.en.lua
in-game displayed version update
2026-07-19 22:43:28 +02:00
Bluewhale1337 e6ad9e7506 perf: eliminate remaining GC spikes by preventing layout rebuilds on combat toggle and zeroing hot-loop table allocations 2026-07-18 23:43:35 +02:00
Bluewhale1337 9f08b356e1 docs: append v1.5.1 changelog detailing memory, mana, and buff tracking fixes 2026-07-18 23:39:07 +02:00
Bluewhale1337 3845ada15f fix: remove artificial mana check to allow 0-mana cost buffs and fix tooltips disappearing instead of turning red 2026-07-18 23:37:51 +02:00
Bluewhale1337 826bf64eda fix: resolve Self Only buff tracking failing on raid frames by replacing direct unit string comparisons with UnitIsUnit 2026-07-18 23:34:20 +02:00
Bluewhale1337 8854cd3caa docs: add release notes for v1.4.2 to README.md 2026-07-18 23:26:14 +02:00
Bluewhale1337 c8a5e4f0eb perf: eliminate string allocation GC spikes in healthbar refreshing and remove full UI rebuilds on target change 2026-07-18 13:35:59 +02:00
Bluewhale1337 2d75406d88 Merge pull request #6 from Bluewhale1337/dev
Merge pull request #5 from Bluewhale1337/main
2026-07-18 12:40:48 +02:00
Bluewhale1337 2e35be6516 Merge pull request #5 from Bluewhale1337/main
Hotfix merge to dev
2026-07-18 12:40:18 +02:00
Bluewhale1337 07a9c3a93d Merge branch 'dev' into main
Signed-off-by: Bluewhale1337 <295648290+Bluewhale1337@users.noreply.github.com>
2026-07-18 12:40:04 +02:00
Bluewhale1337 c8e62fe80e docs: restore v1.4.2 changelog entry 2026-07-18 12:36:38 +02:00
Bluewhale1337 1334fc09bf perf: replace table.foreach with pairs loops to avoid GC spikes during combat 2026-07-18 12:27:51 +02:00
Bluewhale1337 ce594af5fa fix: memory leak in UnitAura and bump version to 1.4.2 2026-07-18 10:47:28 +02:00
Bluewhale1337 f1c5d6a8d1 Features: Expand action handling to support inline scripts, macros, and items while adding dynamic tooltip mana colorization and table memory management. 2026-07-15 14:56:03 +02:00
Bluewhale1337 0186fc1d93 Merge pull request #4 from Bluewhale1337/dev
Merging dev changes to main 1.4.1
2026-07-12 20:21:49 +02:00
Bluewhale1337 ff97414bb1 feat: implement robust spell failure detection, talent-based healing calculations, and improved incoming heal synchronization. 2026-07-12 19:44:50 +02:00
Bluewhale1337 d0d6a39fb9 feat: implement talent-based dynamic spell healing calculations for Druid, Priest, and Paladin classes 2026-07-12 15:44:44 +02:00
Bluewhale1337 66172cab45 refactor: replace MODIFIER_STATE_CHANGED event with polling in HealBot_OnUpdate to track modifier keys 2026-07-12 00:37:25 +02:00
23 changed files with 1002 additions and 236 deletions
+5 -1
View File
@@ -284,12 +284,16 @@ do
spellName = HealBot_ScanTooltipTextLeft1 and HealBot_ScanTooltipTextLeft1:GetText() spellName = HealBot_ScanTooltipTextLeft1 and HealBot_ScanTooltipTextLeft1:GetText()
end end
HealBot_CastFailed = false
orig(slot, checkCursor, onSelf) orig(slot, checkCursor, onSelf)
if autoSelfCast then if autoSelfCast then
SetCVar("autoSelfCast", autoSelfCast) SetCVar("autoSelfCast", autoSelfCast)
end end
if spellName and HealBot_AnnounceCast then if spellName and not HealBot_CastFailed then
HealBot_CastingSpell = spellName
HealBot_CastingTarget = mouseover
HealBot_Process_HealValue(spellName, mouseover)
HealBot_AnnounceCast(spellName, mouseover) HealBot_AnnounceCast(spellName, mouseover)
end end
end end
+1 -1
View File
@@ -18,7 +18,7 @@
<FontString name="$parent_text" inherits="GameFontNormalSmall"> <FontString name="$parent_text" inherits="GameFontNormalSmall">
<Anchors> <Anchors>
<Anchor point="CENTER"> <Anchor point="CENTER">
<Offset> <AbsDimension y="1"/> </Offset> <Offset> <AbsDimension y="0"/> </Offset>
</Anchor> </Anchor>
</Anchors> </Anchors>
</FontString> </FontString>
+3 -2
View File
@@ -1,9 +1,9 @@
## Interface: 11200 ## Interface: 11200
## Title: HealBotBlue ## Title: HealBotBlue
## Version: 1.4.0 ## Version: 1.6.0
## Author: Bluewhale ## Author: Bluewhale
## Notes: Adds panel with skinable bars for healing and decursive ## Notes: Adds panel with skinable bars for healing and decursive
## SavedVariables: HealBot_Config ## SavedVariablesPerCharacter: HealBot_Config
..\..\FrameXML\Fonts.xml ..\..\FrameXML\Fonts.xml
..\..\FrameXML\OptionsFrameTemplates.xml ..\..\FrameXML\OptionsFrameTemplates.xml
..\..\FrameXML\UIPanelTemplates.xml ..\..\FrameXML\UIPanelTemplates.xml
@@ -27,3 +27,4 @@ HealBot_Options_CDC.xml
HealBot_Options_Skins.xml HealBot_Options_Skins.xml
HealBot_Options_Buffs.xml HealBot_Options_Buffs.xml
HealBot_Options_Chat.xml HealBot_Options_Chat.xml
HealBot_Options_Auto.xml
+134 -21
View File
@@ -22,9 +22,9 @@ function HealBot_ShouldHeal(unit)
end end
function HealBot_Action_ShouldHealSome() function HealBot_Action_ShouldHealSome()
return table.foreach(HealBot_Action_HealButtons, function (index,button) for index, button in pairs(HealBot_Action_HealButtons) do
if (HealBot_ShouldHeal(button.unit)) then return button.unit; end if (HealBot_ShouldHeal(button.unit)) then return button.unit; end
end); end
end end
function HealBot_MustHeal(unit) function HealBot_MustHeal(unit)
@@ -32,9 +32,9 @@ function HealBot_MustHeal(unit)
end end
function HealBot_Action_MustHealSome() function HealBot_Action_MustHealSome()
return table.foreach(HealBot_Action_HealButtons, function (index,button) for index, button in pairs(HealBot_Action_HealButtons) do
if (HealBot_MustHeal(button.unit)) then return button.unit; end if (HealBot_MustHeal(button.unit)) then return button.unit; end
end); end
end end
function HealBot_GetRezSpellForClass() function HealBot_GetRezSpellForClass()
@@ -117,11 +117,107 @@ function HealBot_Action_HealUnit_OnLeave(this)
HealBot_Action_HideTooltip(this); HealBot_Action_HideTooltip(this);
end end
--------------------------------------------------------------------------------------------------
-- Puppeteer Utility Ports for Macro and Item Execution
--------------------------------------------------------------------------------------------------
function HealBot_SplitString(str, delimiter)
local result = {}
local start_pos = 1
while true do
local end_pos = string.find(str, delimiter, start_pos, true)
if not end_pos then
table.insert(result, string.sub(str, start_pos))
break
end
table.insert(result, string.sub(str, start_pos, end_pos - 1))
start_pos = end_pos + string.len(delimiter)
end
return result
end
function HealBot_RunMacroText(body)
local commands = HealBot_SplitString(body, "\n")
for i = 1, table.getn(commands) do
ChatFrameEditBox:SetText(commands[i])
ChatEdit_SendText(ChatFrameEditBox)
end
end
function HealBot_RunMacro(name)
if GetMacroIndexByName(name) == 0 then return end
local _, _, body = GetMacroInfo(GetMacroIndexByName(name))
HealBot_RunMacroText(body)
end
function HealBot_GetBagSlotInfo(bag, slot)
local link = GetContainerItemLink(bag, slot)
if not link then return end
local _, _, name = string.find(link, "%[(.*)%]")
local _, count = GetContainerItemInfo(bag, slot)
return name, count
end
function HealBot_FindBagSlot(itemName)
local bestBag, bestSlot, lowestStackSize
for bag = 0, NUM_BAG_FRAMES do
for slot = 1, GetContainerNumSlots(bag) do
local name, count = HealBot_GetBagSlotInfo(bag, slot)
if itemName == name then
if not lowestStackSize or lowestStackSize > count then
bestBag = bag
bestSlot = slot
lowestStackSize = count
end
end
end
end
return bestBag, bestSlot
end
function HealBot_UseItem(itemName)
local bag, slot = HealBot_FindBagSlot(itemName)
if not bag then return false end
UseContainerItem(bag, slot)
return true
end
function HealBot_Action_HealUnit_OnClick(this,button) function HealBot_Action_HealUnit_OnClick(this,button)
local decode_button = HealBot_Decode_Button(button); local decode_button = HealBot_Decode_Button(button);
local pattern = HealBot_Action_SpellPattern(decode_button); local pattern = HealBot_Action_SpellPattern(decode_button);
-- Resurrection override on dead target if not pattern then return end
-- Buff casting override (Spells only)
if HealBot_Config.BuffWatch == 1 then
local inCombat = UnitAffectingCombat("player")
if (not inCombat) or (HealBot_Config.BuffWatchInCombat == 1) then
if HealBot_MissingBuffs[this.unit] then
local missingBuff = HealBot_MissingBuffs[this.unit]
if decode_button == "Left" or decode_button == "Right" then
HealBot_CastSpellOnFriend(missingBuff, this.unit)
return
end
end
end
end
-- Priority 1: Inline Scripts (starts with /)
if string.sub(pattern, 1, 1) == "/" then
local oldTarget = nil
if UnitExists("target") then oldTarget = UnitName("target") end
TargetUnit(this.unit)
HealBot_RunMacroText(pattern)
if oldTarget then
TargetByName(oldTarget)
else
ClearTarget()
end
return
end
-- Priority 2: Spells
-- Resurrection override on dead target first
if UnitIsDeadOrGhost(this.unit) then if UnitIsDeadOrGhost(this.unit) then
local rezSpell = HealBot_GetRezSpellForClass(); local rezSpell = HealBot_GetRezSpellForClass();
if rezSpell then if rezSpell then
@@ -129,24 +225,41 @@ function HealBot_Action_HealUnit_OnClick(this,button)
return return
end end
end end
-- Buff casting override if HealBot_Spells[pattern] or HealBot_GetSpellId(pattern) then
if HealBot_Config.BuffWatch == 1 then HealBot_HealUnit(this.unit, pattern);
local inCombat = UnitAffectingCombat("player") return
if (not inCombat) or (HealBot_Config.BuffWatchInCombat == 1) then end
local myClass = UnitClass("player")
if HealBot_MissingBuffs[this.unit] then -- Priority 3: Named Macros
local missingBuff = HealBot_MissingBuffs[this.unit] if GetMacroIndexByName(pattern) ~= 0 then
if decode_button == "Left" or decode_button == "Right" then local oldTarget = nil
HealBot_CastSpellOnFriend(missingBuff, this.unit) if UnitExists("target") then oldTarget = UnitName("target") end
return TargetUnit(this.unit)
end HealBot_RunMacro(pattern)
end if oldTarget then
TargetByName(oldTarget)
else
ClearTarget()
end end
end return
end
-- Priority 4: Items
local bag, slot = HealBot_FindBagSlot(pattern)
if bag then
local oldTarget = nil
if UnitExists("target") then oldTarget = UnitName("target") end
TargetUnit(this.unit)
UseContainerItem(bag, slot)
if SpellIsTargeting() then SpellTargetUnit(this.unit) end
if oldTarget then TargetByName(oldTarget) else ClearTarget() end
return
end
HealBot_HealUnit(this.unit,pattern); -- Fallback attempt
end HealBot_HealUnit(this.unit, pattern);
end
function HealBot_Action_HealUnitCheck_OnClick(this) function HealBot_Action_HealUnitCheck_OnClick(this)
if not this.unit then return end if not this.unit then return end
+36 -16
View File
@@ -2,6 +2,7 @@
-- Handles tracking buffs/debuffs (auras) on group/raid units -- Handles tracking buffs/debuffs (auras) on group/raid units
HealBot_MissingBuffs = {} HealBot_MissingBuffs = {}
local StaticHasBuff = {}
function HealBot_UnitAffected(unit, effect) function HealBot_UnitAffected(unit, effect)
if not effect then return nil; end if not effect then return nil; end
@@ -68,7 +69,10 @@ function HealBot_CheckBuffs(unit)
} }
-- Gather buffs on unit -- Gather buffs on unit
local hasBuff = {} local hasBuff = StaticHasBuff
for k in pairs(hasBuff) do
hasBuff[k] = nil
end
local i = 1 local i = 1
while true do while true do
local buffTexture = UnitBuff(unit, i) local buffTexture = UnitBuff(unit, i)
@@ -91,7 +95,7 @@ function HealBot_CheckBuffs(unit)
local val = HealBot_Config.BuffDropDowns[myClass][j] local val = HealBot_Config.BuffDropDowns[myClass][j]
if val and val > 0 then if val and val > 0 then
local isSelfOnly = (HealBot_Config.BuffWatchSelf and HealBot_Config.BuffWatchSelf[j] == 1) 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 spellName = HealBot_Buff_Spells[myClass][val]
local hasIt = hasBuff[spellName] local hasIt = hasBuff[spellName]
@@ -100,7 +104,7 @@ function HealBot_CheckBuffs(unit)
end end
if not hasIt then 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) hasIt = HealBot_CheckShamanWeaponBuff(spellName)
end end
end end
@@ -115,23 +119,28 @@ function HealBot_CheckBuffs(unit)
end end
end end
local HealBot_TrackedHoTs = {
["Interface\\Icons\\Spell_Holy_Renew"] = true,
["Interface\\Icons\\Spell_Nature_Rejuvenation"] = true,
["Interface\\Icons\\Spell_Nature_ResistNature"] = true,
["Interface\\Icons\\Spell_Holy_PowerWordShield"] = true,
["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) function HealBot_OnEvent_UnitAura(this, unit)
local DebuffType; local DebuffType;
if HealBot_Heals[unit] and unit ~= "target" then if HealBot_Heals[unit] and unit ~= "target" then
HealBot_UnitIcons[unit] = {} if not HealBot_UnitIcons[unit] then
HealBot_UnitIcons[unit] = {}
end
for j = 1, 5 do
HealBot_UnitIcons[unit][j] = nil
end
local iconCount = 0 local iconCount = 0
local HealBot_TrackedHoTs = {
["Interface\\Icons\\Spell_Holy_Renew"] = true,
["Interface\\Icons\\Spell_Nature_Rejuvenation"] = true,
["Interface\\Icons\\Spell_Nature_ResistNature"] = true,
["Interface\\Icons\\Spell_Holy_PowerWordShield"] = true,
["Interface\\Icons\\Spell_Holy_SealOfProtection"] = true,
["Interface\\Icons\\Spell_Holy_Excorcism"] = true,
["Interface\\Icons\\btnholyscriptures"] = true,
}
local i = 1; local i = 1;
while true do while true do
local debuff, tmp, debuff_type = UnitDebuff(unit, i, 1) local debuff, tmp, debuff_type = UnitDebuff(unit, i, 1)
@@ -140,7 +149,7 @@ function HealBot_OnEvent_UnitAura(this, unit)
iconCount = iconCount + 1 iconCount = iconCount + 1
HealBot_UnitIcons[unit][iconCount] = debuff HealBot_UnitIcons[unit][iconCount] = debuff
end 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 HealBot_UnitDebuff[unit] = debuff_type
DebuffType = debuff_type; DebuffType = debuff_type;
if HealBot_DebuffPriority[debuff_type] then if HealBot_DebuffPriority[debuff_type] then
@@ -164,6 +173,17 @@ function HealBot_OnEvent_UnitAura(this, unit)
end end
b = b + 1 b = b + 1
end 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 HealBot_UnitDebuff[unit] then
if DebuffType and HealBot_Range_Check(unit, 27) == 1 then if DebuffType and HealBot_Range_Check(unit, 27) == 1 then
+1
View File
@@ -70,6 +70,7 @@ function HealBot_OnEvent_AddonMsg(this, addon_id, inc_msg, dist_target, sender_i
local tmpTest, unitname, heal_val local tmpTest, unitname, heal_val
tmpTest, tmpTest, unitname, heal_val = string.find(inc_msg, ">> (%a+) <<=>> (.%d+) <<" ); tmpTest, tmpTest, unitname, heal_val = string.find(inc_msg, ">> (%a+) <<=>> (.%d+) <<" );
if heal_val then if heal_val then
if sender_id == UnitName("player") then return end
if not HealBot_HealsIn[unitname] then if not HealBot_HealsIn[unitname] then
HealBot_HealsIn[unitname] = 0; HealBot_HealsIn[unitname] = 0;
end end
+54 -62
View File
@@ -3,10 +3,10 @@
HealBot_View_DirtyUnits = {} HealBot_View_DirtyUnits = {}
local HealBot_Timer1, HealsIn_Timer = 0, 0; local HealBot_Timer1, HealsIn_Timer = 0, 0;
HealBot_LastModState = ""
function HealBot_OnLoad(this) function HealBot_OnLoad(this)
this:RegisterEvent("VARIABLES_LOADED"); this:RegisterEvent("VARIABLES_LOADED");
this:RegisterEvent("MODIFIER_STATE_CHANGED");
SLASH_HEALBOT1 = "/healbot"; SLASH_HEALBOT1 = "/healbot";
SLASH_HEALBOT2 = "/hb"; SLASH_HEALBOT2 = "/hb";
@@ -30,9 +30,7 @@ function HealBot_OnLoad(this)
end) end)
HealBot_Model:RegisterObserver("EQUIPMENT_CHANGED", function(unitID) HealBot_Model:RegisterObserver("EQUIPMENT_CHANGED", function(unitID)
if unitID == "player" then if unitID == "player" then
HealBot_BonusScanner:ScanEquipment() HealBot_EquipChangeTimer = 1
HealBot_CalcEquipBonus = true;
HealBot_RecalcSpells();
end end
end) end)
end end
@@ -42,6 +40,23 @@ function HealBot_RegisterThis(this)
end end
function HealBot_OnUpdate(this, arg1) function HealBot_OnUpdate(this, arg1)
if HealBot_Action_TooltipUnit and HealBot_Tooltip:IsVisible() then
local s = IsShiftKeyDown() and true or false
local c = IsControlKeyDown() and true or false
local a = IsAltKeyDown() and true or false
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_LastModS = false
HealBot_LastModC = false
HealBot_LastModA = false
end
if HealBot_TargetRestorePending then if HealBot_TargetRestorePending then
HealBot_TargetRestoreTimer = HealBot_TargetRestoreTimer + arg1; HealBot_TargetRestoreTimer = HealBot_TargetRestoreTimer + arg1;
if HealBot_TargetRestoreTimer >= 0.1 then if HealBot_TargetRestoreTimer >= 0.1 then
@@ -59,10 +74,20 @@ function HealBot_OnUpdate(this, arg1)
end end
-- Process Dirty Queue for MVC View -- Process Dirty Queue for MVC View
if next(HealBot_View_DirtyUnits) ~= nil then local unitID, _ = next(HealBot_View_DirtyUnits)
for unitID in pairs(HealBot_View_DirtyUnits) do while unitID do
HealBot_Action_RefreshButtons(unitID) HealBot_Action_RefreshButtons(unitID)
HealBot_View_DirtyUnits[unitID] = nil HealBot_View_DirtyUnits[unitID] = nil
unitID, _ = next(HealBot_View_DirtyUnits)
end
if HealBot_EquipChangeTimer > 0 then
HealBot_EquipChangeTimer = HealBot_EquipChangeTimer - arg1
if HealBot_EquipChangeTimer <= 0 then
HealBot_EquipChangeTimer = 0
HealBot_BonusScanner:ScanEquipment()
HealBot_CalcEquipBonus = true;
HealBot_RecalcSpells();
end end
end end
@@ -71,20 +96,12 @@ function HealBot_OnUpdate(this, arg1)
if not HealBot_IsFighting then if not HealBot_IsFighting then
HealsIn_Timer = HealsIn_Timer + 1; HealsIn_Timer = HealsIn_Timer + 1;
if HealsIn_Timer >= 10 then if HealsIn_Timer >= 10 then
HealBot_HealsIn = {}; for k in pairs(HealBot_HealsIn) do HealBot_HealsIn[k] = nil end
HealBot_Healers = {}; for k in pairs(HealBot_Healers) do HealBot_Healers[k] = nil end
HealsIn_Timer = 0; HealsIn_Timer = 0;
end end
if HealBot_EquipChangeTimer > 0 then
HealBot_EquipChangeTimer = HealBot_EquipChangeTimer - arg1
if HealBot_EquipChangeTimer <= 0 then
HealBot_EquipChangeTimer = 0
HealBot_BonusScanner:ScanEquipment()
HealBot_CalcEquipBonus = true;
HealBot_RecalcSpells();
end
end
if HealBot_SpellsInitFlag > 1 then if HealBot_SpellsInitFlag > 1 then
HealBot_SpellsInitFlag = HealBot_SpellsInitFlag + 1; HealBot_SpellsInitFlag = HealBot_SpellsInitFlag + 1;
@@ -117,32 +134,28 @@ local HealBot_EventHandlers = {
HealBot_OnEvent_UnitHealth(this, arg1) HealBot_OnEvent_UnitHealth(this, arg1)
end, end,
["UNIT_MANA"] = function(this, arg1) ["UNIT_MANA"] = function(this, arg1)
if arg1 ~= "player" and HealBot_Config.ShowManaBars == 0 then return end
if HealBot_Model:UpdateUnitPower(arg1) then if HealBot_Model:UpdateUnitPower(arg1) then
HealBot_Model:NotifyObservers("UNIT_POWER_CHANGED", arg1) HealBot_Model:NotifyObservers("UNIT_POWER_CHANGED", arg1)
end end
if (arg1 == "player") then HealBot_RecalcHeals(); end
HealBot_Action_RefreshButtons(arg1);
end, end,
["UNIT_RAGE"] = function(this, arg1) ["UNIT_RAGE"] = function(this, arg1)
if arg1 ~= "player" and HealBot_Config.ShowManaBars == 0 then return end
if HealBot_Model:UpdateUnitPower(arg1) then if HealBot_Model:UpdateUnitPower(arg1) then
HealBot_Model:NotifyObservers("UNIT_POWER_CHANGED", arg1) HealBot_Model:NotifyObservers("UNIT_POWER_CHANGED", arg1)
end end
if (arg1 == "player") then HealBot_RecalcHeals(); end
HealBot_Action_RefreshButtons(arg1);
end, end,
["UNIT_ENERGY"] = function(this, arg1) ["UNIT_ENERGY"] = function(this, arg1)
if arg1 ~= "player" and HealBot_Config.ShowManaBars == 0 then return end
if HealBot_Model:UpdateUnitPower(arg1) then if HealBot_Model:UpdateUnitPower(arg1) then
HealBot_Model:NotifyObservers("UNIT_POWER_CHANGED", arg1) HealBot_Model:NotifyObservers("UNIT_POWER_CHANGED", arg1)
end end
if (arg1 == "player") then HealBot_RecalcHeals(); end
HealBot_Action_RefreshButtons(arg1);
end, end,
["UNIT_DISPLAYPOWER"] = function(this, arg1) ["UNIT_DISPLAYPOWER"] = function(this, arg1)
if arg1 ~= "player" and HealBot_Config.ShowManaBars == 0 then return end
if HealBot_Model:UpdateUnitPower(arg1) then if HealBot_Model:UpdateUnitPower(arg1) then
HealBot_Model:NotifyObservers("UNIT_POWER_CHANGED", arg1) HealBot_Model:NotifyObservers("UNIT_POWER_CHANGED", arg1)
end end
if (arg1 == "player") then HealBot_RecalcHeals(); end
HealBot_Action_RefreshButtons(arg1);
end, end,
["UNIT_AURA"] = function(this, arg1) ["UNIT_AURA"] = function(this, arg1)
HealBot_Model:MarkAuraChanged(arg1) HealBot_Model:MarkAuraChanged(arg1)
@@ -179,21 +192,14 @@ local HealBot_EventHandlers = {
["VARIABLES_LOADED"] = function(this) ["VARIABLES_LOADED"] = function(this)
HealBot_OnEvent_VariablesLoaded(this) HealBot_OnEvent_VariablesLoaded(this)
end, end,
["MODIFIER_STATE_CHANGED"] = function(this, arg1, arg2)
if HealBot_Action_TooltipUnit and HealBot_Tooltip:IsVisible() then
HealBot_Action_RefreshTooltip(HealBot_Action_TooltipUnit)
end
end,
-- Legacy pass-throughs -- Legacy pass-throughs
["CHAT_MSG_ADDON"] = function(this, arg1, arg2, arg3, arg4) HealBot_OnEvent_AddonMsg(this, arg1, arg2, arg3, arg4) end, ["CHAT_MSG_ADDON"] = function(this, arg1, arg2, arg3, arg4) HealBot_OnEvent_AddonMsg(this, arg1, arg2, arg3, arg4) end,
["SPELLCAST_START"] = function(this, arg1, arg2) HealBot_OnEvent_SpellcastStart(this, arg1, arg2) end, ["SPELLCAST_START"] = function(this, arg1, arg2) HealBot_OnEvent_SpellcastStart(this, arg1, arg2) end,
["SPELLCAST_STOP"] = function(this) HealBot_OnEvent_SpellcastStop(this) end, ["SPELLCAST_STOP"] = function(this) HealBot_OnEvent_SpellcastStop(this, "SPELLCAST_STOP") end,
["SPELLCAST_INTERRUPTED"] = function(this) HealBot_OnEvent_SpellcastStop(this) end, ["SPELLCAST_INTERRUPTED"] = function(this) HealBot_OnEvent_SpellcastStop(this, "SPELLCAST_INTERRUPTED") end,
["SPELLCAST_FAILED"] = function(this) HealBot_OnEvent_SpellcastStop(this) end, ["SPELLCAST_FAILED"] = function(this) HealBot_OnEvent_SpellcastStop(this, "SPELLCAST_FAILED") end,
["PLAYER_REGEN_DISABLED"] = function(this) HealBot_OnEvent_PlayerRegenDisabled(this) end, ["PLAYER_REGEN_DISABLED"] = function(this) HealBot_OnEvent_PlayerRegenDisabled(this) end,
["PLAYER_REGEN_ENABLED"] = function(this) HealBot_OnEvent_PlayerRegenEnabled(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_DISABLE"] = function(this, arg1) HealBot_OnEvent_PartyMemberDisable(this, arg1) end,
["PARTY_MEMBER_ENABLE"] = function(this, arg1) HealBot_OnEvent_PartyMemberEnable(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, ["CHAT_MSG_SYSTEM"] = function(this, arg1) HealBot_OnEvent_SystemMsg(this, arg1) end,
@@ -203,11 +209,10 @@ local HealBot_EventHandlers = {
HealBot_OnEvent_PlayerEquipmentChanged(this) HealBot_OnEvent_PlayerEquipmentChanged(this)
end, end,
["UNIT_INVENTORY_CHANGED"] = function(this, arg1) ["UNIT_INVENTORY_CHANGED"] = function(this, arg1)
if arg1 ~= "player" then return end
HealBot_Model:NotifyObservers("EQUIPMENT_CHANGED", arg1) HealBot_Model:NotifyObservers("EQUIPMENT_CHANGED", arg1)
HealBot_OnEvent_PlayerEquipmentChanged2(this, arg1) HealBot_OnEvent_PlayerEquipmentChanged2(this, arg1)
end, 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, ["UNIT_PET"] = function(this, arg1) HealBot_OnEvent_PartyMembersChanged(this) end,
["SPELLS_CHANGED"] = function(this, arg1) HealBot_OnEvent_SpellsChanged(this, arg1) end, ["SPELLS_CHANGED"] = function(this, arg1) HealBot_OnEvent_SpellsChanged(this, arg1) end,
["UPDATE_SHAPESHIFT_FORM"] = function(this) HealBot_UpdateShapeshiftForm() end, ["UPDATE_SHAPESHIFT_FORM"] = function(this) HealBot_UpdateShapeshiftForm() end,
@@ -279,8 +284,6 @@ function HealBot_OnEvent_VariablesLoaded(this)
this:RegisterEvent("PARTY_MEMBERS_CHANGED"); this:RegisterEvent("PARTY_MEMBERS_CHANGED");
this:RegisterEvent("PARTY_MEMBER_DISABLE"); this:RegisterEvent("PARTY_MEMBER_DISABLE");
this:RegisterEvent("PARTY_MEMBER_ENABLE"); this:RegisterEvent("PARTY_MEMBER_ENABLE");
this:RegisterEvent("PET_BAR_SHOWGRID");
this:RegisterEvent("PET_BAR_HIDEGRID");
this:RegisterEvent("UNIT_PET"); this:RegisterEvent("UNIT_PET");
this:RegisterEvent("UNIT_HEALTH"); this:RegisterEvent("UNIT_HEALTH");
this:RegisterEvent("UNIT_MANA"); this:RegisterEvent("UNIT_MANA");
@@ -292,8 +295,6 @@ function HealBot_OnEvent_VariablesLoaded(this)
this:RegisterEvent("SPELLCAST_STOP"); this:RegisterEvent("SPELLCAST_STOP");
this:RegisterEvent("SPELLCAST_INTERRUPTED"); this:RegisterEvent("SPELLCAST_INTERRUPTED");
this:RegisterEvent("SPELLCAST_FAILED"); this:RegisterEvent("SPELLCAST_FAILED");
this:RegisterEvent("BAG_UPDATE");
this:RegisterEvent("BAG_UPDATE_COOLDOWN");
this:RegisterEvent("UNIT_AURA"); this:RegisterEvent("UNIT_AURA");
this:RegisterEvent("UPDATE_INVENTORY_ALERTS"); this:RegisterEvent("UPDATE_INVENTORY_ALERTS");
this:RegisterEvent("UNIT_INVENTORY_CHANGED"); this:RegisterEvent("UNIT_INVENTORY_CHANGED");
@@ -312,7 +313,6 @@ end
function HealBot_OnEvent_UnitHealth(this, unit) function HealBot_OnEvent_UnitHealth(this, unit)
if (not HealBot_Heals[unit]) then return end if (not HealBot_Heals[unit]) then return end
HealBot_CheckCasting(unit); HealBot_CheckCasting(unit);
HealBot_RecalcHeals(unit);
if unit == HealBot_Action_TooltipUnit then if unit == HealBot_Action_TooltipUnit then
HealBot_Action_RefreshTooltip(HealBot_Action_TooltipUnit); HealBot_Action_RefreshTooltip(HealBot_Action_TooltipUnit);
end end
@@ -329,7 +329,7 @@ function HealBot_OnEvent_ZoneChanged(this)
end end
function HealBot_OnEvent_PlayerRegenDisabled(this) function HealBot_OnEvent_PlayerRegenDisabled(this)
HealBot_RecalcParty(); -- Removed HealBot_RecalcParty();
if (UnitIsDeadOrGhost("player")) or (UnitOnTaxi("player")) then if (UnitIsDeadOrGhost("player")) or (UnitOnTaxi("player")) then
if HealBot_Config.AutoClose==1 and HealBot_Config.ActionVisible~=0 then if HealBot_Config.AutoClose==1 and HealBot_Config.ActionVisible~=0 then
HealBot_Action.ProgrammaticHide = true; HealBot_Action.ProgrammaticHide = true;
@@ -365,11 +365,14 @@ end
function HealBot_OnEvent_PlayerRegenEnabled(this) function HealBot_OnEvent_PlayerRegenEnabled(this)
HealBot_IsFighting = false; HealBot_IsFighting = false;
HealBot_Delay_RecalcParty = 1; -- Removed HealBot_Delay_RecalcParty = 1;
end end
function HealBot_OnEvent_PlayerTargetChanged(this) function HealBot_OnEvent_PlayerTargetChanged(this)
HealBot_RecalcParty(); if HealBot_Action_UnitButtons and HealBot_Action_UnitButtons["target"] then
HealBot_View_DirtyUnits["target"] = true
HealBot_OnEvent_UnitAura(nil, "target");
end
end end
function HealBot_OnEvent_PartyMembersChanged(this) function HealBot_OnEvent_PartyMembersChanged(this)
@@ -430,20 +433,6 @@ function HealBot_OnEvent_TalentsChanged(this, arg1)
HealBot_AddDebug("HB: TalentsChanged"); HealBot_AddDebug("HB: TalentsChanged");
end 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) function HealBot_OnEvent_PlayerEnteringWorld(this)
HealBot_IsFighting = false; HealBot_IsFighting = false;
-- Re-apply the refresh hook late in case another addon overrode it during load -- Re-apply the refresh hook late in case another addon overrode it during load
@@ -464,8 +453,11 @@ function HealBot_OnEvent_SpellcastStart(this, spell, duration)
end end
end end
function HealBot_OnEvent_SpellcastStop(this) function HealBot_OnEvent_SpellcastStop(this, eventName)
HealBot_IsCasting = false; HealBot_IsCasting = false;
if eventName == "SPELLCAST_FAILED" then
HealBot_CastFailed = true;
end
HealBot_StopCasting(); HealBot_StopCasting();
HealBot_RecalcHeals(); HealBot_RecalcHeals();
if HealBot_IamRessing then if HealBot_IamRessing then
+156 -30
View File
@@ -127,10 +127,45 @@ function HealBot_AnnounceCast(spell, target)
end end
end end
function HealBot_Process_HealValue(spell, target)
if HealBot_Spells[spell] and HealBot_Spells[spell].CastTime > 1 then
HealBot_HealValue = HealBot_Spells[spell].HealsDur;
-- Apply dynamic Preservation bonus
if HEALBOT_REGROWTH and string.find(spell, HEALBOT_REGROWTH) then
local presRank = HealBot_GetTalentRank("Preservation")
if presRank > 0 then
local hasRejuv = false
for i=1,32 do
local buff = UnitBuff(target, i)
if not buff then break end
if string.find(buff, "Spell_Nature_Rejuvenation") then
hasRejuv = true
break
end
end
if hasRejuv then
local extHeal = HealBot_Spells[spell].HealsExt or 0
local bonus = extHeal * (presRank * 0.10)
HealBot_HealValue = HealBot_HealValue + math.floor(bonus)
end
end
end
local uname = UnitName(target)
if uname then
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
end
end
function HealBot_StartCasting(spell, target, ttype) function HealBot_StartCasting(spell, target, ttype)
HealBot_CastFailed = false;
HealBot_CastSpellByName(spell); HealBot_CastSpellByName(spell);
HealBot_CastingSpell = spell;
HealBot_CastingTarget = target;
if ( SpellCanTargetUnit(target) ) then if ( SpellCanTargetUnit(target) ) then
SpellTargetUnit(target); SpellTargetUnit(target);
ttype = "fired"; ttype = "fired";
@@ -138,28 +173,36 @@ function HealBot_StartCasting(spell, target, ttype)
SpellTargetUnit(target); SpellTargetUnit(target);
SpellStopTargeting() SpellStopTargeting()
elseif ttype == "direct" then elseif ttype == "direct" then
if ( CheckInteractDistance(target, 4) ) then if ( UnitIsUnit(target, "player") or CheckInteractDistance(target, 4) ) then
ttype = "fired"; ttype = "fired";
end end
end end
HealBot_AnnounceCast(spell, target)
if ttype == "fired" and HealBot_Spells[spell] then if ttype == "fired" and HealBot_Spells[spell] then
if HealBot_Spells[spell].CastTime > 1 then if not HealBot_CastFailed then
HealBot_HealValue = HealBot_Spells[spell].HealsDur; HealBot_CastingSpell = spell;
HealBot_SendAddonMessage(HEALBOT_ADDON_ID, ">> " .. UnitName(target) .. " <<=>> " .. HealBot_HealValue .. " << "); HealBot_CastingTarget = target;
HealBot_Process_HealValue(spell, target);
HealBot_AnnounceCast(spell, target);
end end
end end
end end
function HealBot_StopCasting() function HealBot_StopCasting()
if HealBot_CastingTarget then if HealBot_CastingTarget then
if HealBot_HealsIn[UnitName(HealBot_CastingTarget)] then if HealBot_HealValue > 0 then
if HealBot_HealValue > 0 then local uname = UnitName(HealBot_CastingTarget)
HealBot_SendAddonMessage(HEALBOT_ADDON_ID, ">> " .. UnitName(HealBot_CastingTarget) .. " <<=>> " .. 0 - HealBot_HealValue .. " << "); if uname then
HealBot_HealValue = 0; 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;
end end
end end
HealBot_CastingSpell = nil; HealBot_CastingSpell = nil;
@@ -203,7 +246,7 @@ function HealBot_CheckCasting(unit)
local ag = HealBot_Config.babortcolg[HealBot_Config.Current_Skin] or 0.1; 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 ab = HealBot_Config.babortcolb[HealBot_Config.Current_Skin] or 0.5;
local aa = HealBot_Config.babortcola[HealBot_Config.Current_Skin] or 1; 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 if HealBot_IsCasting == false and HealBot_AbortButton == 0 then
bar:SetStatusBarColor(ar, ag, ab, 0); bar:SetStatusBarColor(ar, ag, ab, 0);
@@ -298,7 +341,46 @@ function HealBot_SetItemDefaults(spell)
end end
function HealBot_SetSpellDefaults(spell) function HealBot_SetSpellDefaults(spell)
HealBot_Spells[spell].HealsDur = math.floor((HealBot_Spells[spell].HealsCast + HealBot_Spells[spell].HealsExt) + HealBot_Spells[spell].RealHealing); local baseHeal = HealBot_Spells[spell].HealsCast or 0
local extHeal = HealBot_Spells[spell].HealsExt or 0
local realHeal = HealBot_Spells[spell].RealHealing or 0
local _, class = UnitClass("player")
if class == "DRUID" then
local giftRank = HealBot_GetTalentRank("Gift of Nature")
local genRank = HealBot_GetTalentRank("Genesis")
local mult = 1 + (giftRank * 0.02)
baseHeal = baseHeal * mult
extHeal = extHeal * mult
realHeal = realHeal * mult
if genRank > 0 then
extHeal = extHeal * (1 + (genRank * 0.05))
end
elseif class == "PRIEST" then
local spiritRank = HealBot_GetTalentRank("Spiritual Healing")
local mult = 1 + (spiritRank * 0.06)
baseHeal = baseHeal * mult
extHeal = extHeal * mult
realHeal = realHeal * mult
if HEALBOT_RENEW and string.find(spell, HEALBOT_RENEW) then
local renewRank = HealBot_GetTalentRank("Improved Renew")
extHeal = extHeal * (1 + (renewRank * 0.05))
end
elseif class == "PALADIN" then
local hlRank = HealBot_GetTalentRank("Healing Light")
if (HEALBOT_HOLY_LIGHT and string.find(spell, HEALBOT_HOLY_LIGHT)) or
(HEALBOT_FLASH_OF_LIGHT and string.find(spell, HEALBOT_FLASH_OF_LIGHT)) or
(HEALBOT_HOLY_SHOCK and string.find(spell, HEALBOT_HOLY_SHOCK)) then
local mult = 1 + (hlRank * 0.04)
baseHeal = baseHeal * mult
realHeal = realHeal * mult
end
end
HealBot_Spells[spell].HealsDur = math.floor(baseHeal + extHeal + realHeal);
end end
function HealBot_AddHeal(spell) function HealBot_AddHeal(spell)
@@ -380,7 +462,8 @@ end
function HealBot_CanCastSpell(spell, unit) function HealBot_CanCastSpell(spell, unit)
local this = HealBot_Spells[spell]; 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 if this.BagSlot then
local bag, slot = HealBot_UnpackBagSlot(this.BagSlot); local bag, slot = HealBot_UnpackBagSlot(this.BagSlot);
local start, duration, enable = GetContainerItemCooldown(bag, slot); local start, duration, enable = GetContainerItemCooldown(bag, slot);
@@ -393,19 +476,43 @@ end
function HealBot_GetHealSpell(unit, pattern) function HealBot_GetHealSpell(unit, pattern)
if (not UnitName(unit)) then return nil end; if (not UnitName(unit)) then return nil end;
if not pattern then return nil end;
if UnitOnTaxi("player") then return nil end; if UnitOnTaxi("player") then return nil end;
if HealBot_Config.ProtectPvP == 1 and UnitIsPVP(unit) and not UnitIsPVP("player") then return nil end if HealBot_Config.ProtectPvP == 1 and UnitIsPVP(unit) and not UnitIsPVP("player") then return nil end
if HealBot_UnitClass("player") == "DRUID" then if HealBot_UnitClass("player") == "DRUID" then
if HealBot_ActiveShapeshiftStance and HealBot_Config.AutoUnshift ~= 1 then return nil end; if HealBot_ActiveShapeshiftStance and HealBot_Config.AutoUnshift ~= 1 then return nil end;
end
local spell = HealBot_GetSpellName(HealBot_GetSpellId(pattern))
local range = 40;
if HealBot_Spells[spell] then
if not HealBot_CanCastSpell(spell, unit) then return nil end;
range = HealBot_Spells[spell].range;
end end
if HealBot_Range_Check(unit, range) == 0 then return nil end;
return spell; -- Handle Inline Scripts
if string.sub(pattern, 1, 1) == "/" then
return pattern;
end
-- Handle Spells
if HealBot_Spells[pattern] or HealBot_GetSpellId(pattern) then
local spell = HealBot_GetSpellName(HealBot_GetSpellId(pattern)) or pattern
local range = 40;
if HealBot_Spells[spell] then
if not HealBot_CanCastSpell(spell, unit) then return nil end;
range = HealBot_Spells[spell].range or 40;
end
if HealBot_Range_Check(unit, range) == 0 then return nil end;
return spell;
end
-- Handle Named Macros
if GetMacroIndexByName(pattern) ~= 0 then
return pattern;
end
-- Handle Items
local bag, slot = HealBot_FindBagSlot(pattern)
if bag then
-- optionally check item range, but skipping for now as it's complex in vanilla
return pattern;
end
return nil;
end end
function HealBot_HealUnit(unit, pattern) function HealBot_HealUnit(unit, pattern)
@@ -433,17 +540,38 @@ function HealBot_RecalcSpells()
HealBot_RecalcParty(); HealBot_RecalcParty();
end end
function HealBot_GetTalentRank(talentName)
for t = 1, GetNumTalentTabs() do
for i = 1, GetNumTalents(t) do
local nameTalent, icon, tier, column, currRank, maxRank = GetTalentInfo(t, i);
if nameTalent == talentName then
return currRank;
end
end
end
return 0;
end
function HealBot_SpiBonus(spell) function HealBot_SpiBonus(spell)
local heals_modifer = 0; local heals_modifer = 0;
local base, stat, posBuff, negBuff = UnitStat("player", 5); local base, stat, posBuff, negBuff = UnitStat("player", 5);
nameTalent, icon, tier, column, currRank, maxRank = GetTalentInfo(2, 14); -- Spiritual guidance local currRank = HealBot_GetTalentRank("Spiritual Guidance")
spiGuideBonus = stat * 0.05; if currRank > 0 then
heals_modifer = heals_modifer + (currRank * spiGuideBonus); local spiGuideBonus = stat * 0.05;
heals_modifer = heals_modifer + (currRank * spiGuideBonus);
end
return heals_modifer; return heals_modifer;
end end
function HealBot_GetBonus() function HealBot_GetBonus()
local HealBonus = HealBot_BonusScanner:GetBonus(); local HealBonus = HealBot_BonusScanner:GetBonus() or 0;
if UnitClass("player") == "PALADIN" then
local ironRank = HealBot_GetTalentRank("Ironclad")
if ironRank > 0 then
local base, effectiveArmor = UnitArmor("player")
HealBonus = HealBonus + (effectiveArmor * (ironRank * 0.01))
end
end
return HealBonus; return HealBonus;
end end
@@ -465,9 +593,7 @@ function HealBot_InitSpells()
end end
id = id + 1; id = id + 1;
end end
if class == "PRIEST" or class == "DRUID" or class == "PALADIN" or class == "SHAMAN" then
HealBot_AddChat("Initiated HealBot_CurrentSpells with " .. cnt .. " Spells");
end
return cnt; return cnt;
end end
+45 -1
View File
@@ -2,6 +2,20 @@ HealBot_ConfigDefaults = {
ShowManaBars=0, ShowManaBars=0,
ManaBarsHealersOnly=0, ManaBarsHealersOnly=0,
Version = HEALBOT_VERSION, Version = HEALBOT_VERSION,
AutoSwap_Enabled = 0,
AutoSwap_Profiles = {
[1] = HEALBOT_SKINS_STD,
[2] = HEALBOT_SKINS_STD,
[3] = HEALBOT_SKINS_STD,
[4] = HEALBOT_SKINS_STD,
[5] = HEALBOT_SKINS_STD,
},
bmaxrows = {
[HEALBOT_SKINS_STD] = 0,
},
GridOrientation = {
[HEALBOT_SKINS_STD] = 1,
},
AlertLevel = 0.95, AlertLevel = 0.95,
AutoClose = 1, AutoClose = 1,
PanelSounds = 1, PanelSounds = 1,
@@ -181,7 +195,17 @@ HealBot_ConfigDefaults = {
Current_Skin = "Modern Flat", Current_Skin = "Modern Flat",
Skin_ID = 1, Skin_ID = 1,
Skins = {"Modern Flat", HEALBOT_SKINS_STD, "HealBot Party", "HealBot Raid", "Alteric Valley"}, 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}, 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}, 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}, 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}, brspace = {[HEALBOT_SKINS_STD] = 1, ["HealBot Party"] = 2, ["HealBot Raid"] = 2, ["Alteric Valley"] = 1, ["Modern Flat"] = 2},
@@ -545,7 +569,7 @@ HealBot_Debuff_Types = {
HealBot_IsFighting = false; HealBot_IsFighting = false;
HealBot_DebuffPriority = {"none"}; 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 = {}; HealBot_Heals = {};
@@ -559,3 +583,23 @@ HealBot_SpamCnt=0;
HealBot_Action_TooltipUnit=nil; HealBot_Action_TooltipUnit=nil;
HealBot_Ressing = {}; HealBot_Ressing = {};
HealBot_IamRessing = false; HealBot_IamRessing = false;
-- Table Recycling Pool (Puppeteer-inspired)
local tablePool = {}
function HealBot_GetTable()
local t = table.remove(tablePool)
if not t then
t = {}
end
return t
end
function HealBot_ReleaseTable(t)
if type(t) == "table" then
for k in pairs(t) do
t[k] = nil
end
table.insert(tablePool, t)
end
end
+3 -2
View File
@@ -1,4 +1,4 @@
HEALBOT_VERSION = "1.4"; HEALBOT_VERSION = GetAddOnMetadata("HealBotBlue", "Version");
------------- -------------
-- ENGLISH -- -- ENGLISH --
@@ -323,9 +323,10 @@ HEALBOT_OPTIONS_HEAL_BUTTONS = "Healing bars";
HEALBOT_OPTIONS_EMERGFILTER = "Show extra bars for"; HEALBOT_OPTIONS_EMERGFILTER = "Show extra bars for";
HEALBOT_OPTIONS_GROUPHEALS = "Group"; HEALBOT_OPTIONS_GROUPHEALS = "Group";
HEALBOT_OPTIONS_GROUPHEALS_LABEL = "Group Only";
HEALBOT_OPTIONS_TANKHEALS = "Main tanks"; HEALBOT_OPTIONS_TANKHEALS = "Main tanks";
HEALBOT_OPTIONS_TARGETHEALS = "Targets"; HEALBOT_OPTIONS_TARGETHEALS = "Targets";
HEALBOT_OPTIONS_EMERGENCYHEALS= "Extra"; HEALBOT_OPTIONS_EMERGENCYHEALS= "Raid / Extra";
HEALBOT_OPTIONS_HEALLEVEL = "Healing Level"; HEALBOT_OPTIONS_HEALLEVEL = "Healing Level";
HEALBOT_OPTIONS_ALERTLEVEL = "Alert Level"; HEALBOT_OPTIONS_ALERTLEVEL = "Alert Level";
HEALBOT_OPTIONS_OVERHEAL = "Show Abort button when overhealing" HEALBOT_OPTIONS_OVERHEAL = "Show Abort button when overhealing"
+3 -1
View File
@@ -234,7 +234,7 @@ function HealBot_Options_OnLoad(this)
table.insert(UISpecialFrames,this:GetName()); table.insert(UISpecialFrames,this:GetName());
-- Tabs -- Tabs
PanelTemplates_SetNumTabs(this,7); PanelTemplates_SetNumTabs(this,8);
this.selectedTab = 1; this.selectedTab = 1;
PanelTemplates_UpdateTabs(this); PanelTemplates_UpdateTabs(this);
HealBot_Options_ShowPanel(this.selectedTab); HealBot_Options_ShowPanel(this.selectedTab);
@@ -314,6 +314,8 @@ function HealBot_Options_SetSkins()
HealBot_Options_BarHeightS:SetValue(HealBot_Config.bheight[HealBot_Config.Current_Skin]) HealBot_Options_BarHeightS:SetValue(HealBot_Config.bheight[HealBot_Config.Current_Skin])
HealBot_Options_BarWidthS:SetValue(HealBot_Config.bwidth[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_BarNumColsS:SetValue(HealBot_Config.numcols[HealBot_Config.Current_Skin])
HealBot_Options_BarMaxRowsS:SetValue((HealBot_Config.bmaxrows and HealBot_Config.bmaxrows[HealBot_Config.Current_Skin]) or 0)
HealBot_Options_GridOrientation:SetChecked(((HealBot_Config.GridOrientation and 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_BarBRSpaceS:SetValue(HealBot_Config.brspace[HealBot_Config.Current_Skin])
HealBot_Options_BarBCSpaceS:SetValue(HealBot_Config.bcspace[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) HealBot_Options_FramePaddingS:SetValue((HealBot_Config.bpadding and HealBot_Config.bpadding[HealBot_Config.Current_Skin]) or 10)
+5 -27
View File
@@ -94,7 +94,7 @@
<Frame name="HealBot_Options" toplevel="true" frameStrata="DIALOG" <Frame name="HealBot_Options" toplevel="true" frameStrata="DIALOG"
movable="true" parent="UIParent" enableMouse="true" hidden="true"> movable="true" parent="UIParent" enableMouse="true" hidden="true">
<Size> <Size>
<AbsDimension x="420" y="455"/> <AbsDimension x="480" y="455"/>
</Size> </Size>
<Anchors> <Anchors>
<Anchor point="CENTER"> <Anchor point="CENTER">
@@ -206,38 +206,16 @@
</Anchor> </Anchor>
</Anchors> </Anchors>
</Button> </Button>
<Button name="HealBot_Options_Defaults" inherits="UIPanelButtonTemplate" text="HEALBOT_OPTIONS_DEFAULTS"> <Button name="HealBot_OptionsTab8" inherits="HealBot_Options_Tab" id="8" text="Auto">
<Size>
<AbsDimension x="80" y="22"/>
</Size>
<Anchors> <Anchors>
<Anchor point="BOTTOM" relativePoint="BOTTOM"> <Anchor point="LEFT" relativeTo="HealBot_OptionsTab7" relativePoint="RIGHT">
<Offset> <Offset>
<AbsDimension x="-50" y="15"/> <AbsDimension x="-14" y="0" />
</Offset> </Offset>
</Anchor> </Anchor>
</Anchors> </Anchors>
<Scripts>
<OnClick>HealBot_Options_Defaults_OnClick(this)</OnClick>
</Scripts>
</Button>
<Button name="HealBot_Options_CloseButton" inherits="UIPanelButtonTemplate" text="HEALBOT_OPTIONS_CLOSE">
<Size>
<AbsDimension x="80" y="22"/>
</Size>
<Anchors>
<Anchor point="BOTTOM" relativePoint="BOTTOM">
<Offset>
<AbsDimension x="50" y="15"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>
HideUIPanel(this:GetParent());
</OnClick>
</Scripts>
</Button> </Button>
</Frames> </Frames>
<Scripts> <Scripts>
<OnLoad>HealBot_Options_OnLoad(this);</OnLoad> <OnLoad>HealBot_Options_OnLoad(this);</OnLoad>
+82
View File
@@ -0,0 +1,82 @@
function HealBot_Options_AutoSwap_OnClick(this)
if this:GetChecked() then
HealBot_Config.AutoSwap_Enabled = 1
else
HealBot_Config.AutoSwap_Enabled = 0
end
HealBot_Action_PartyChanged()
end
function HealBot_Options_Auto_Initialize()
local dropdownName = UIDROPDOWNMENU_OPEN_MENU
if not dropdownName then return end
local dropdownFrame = getglobal(dropdownName)
if not dropdownFrame then return end
local id = dropdownFrame:GetID()
if not id then return end
for i=1, getn(HealBot_Config.Skins), 1 do
local info = {}
info.text = HealBot_Config.Skins[i]
info.func = HealBot_Options_Auto_OnSelect
info.value = id
if not HealBot_Config.AutoSwap_Profiles then HealBot_Config.AutoSwap_Profiles = {} end
if HealBot_Config.AutoSwap_Profiles[id] == HealBot_Config.Skins[i] then
info.checked = 1
else
info.checked = nil
end
UIDropDownMenu_AddButton(info)
end
end
function HealBot_Options_Auto_OnSelect()
local skin = this:GetText()
local id = this.value
if not id or not skin then return end
if not HealBot_Config.AutoSwap_Profiles then HealBot_Config.AutoSwap_Profiles = {} end
HealBot_Config.AutoSwap_Profiles[id] = skin
local dropdowns = {
"HealBot_Options_Auto_Solo",
"HealBot_Options_Auto_Party",
"HealBot_Options_Auto_Raid15",
"HealBot_Options_Auto_Raid25",
"HealBot_Options_Auto_Raid40"
}
local dropdownName = dropdowns[id]
local dropdownFrame = getglobal(dropdownName)
HealBot_UIDropDownMenu_SetSelectedValue(dropdownFrame, skin)
UIDropDownMenu_SetText(skin, dropdownFrame)
HealBot_Action_PartyChanged()
end
function HealBot_Options_Auto_OnShow(this)
if HealBot_Config.AutoSwap_Enabled == 1 then
HealBot_Options_AutoSwap:SetChecked(1)
else
HealBot_Options_AutoSwap:SetChecked(nil)
end
local dropdowns = {
"HealBot_Options_Auto_Solo",
"HealBot_Options_Auto_Party",
"HealBot_Options_Auto_Raid15",
"HealBot_Options_Auto_Raid25",
"HealBot_Options_Auto_Raid40"
}
for id, name in ipairs(dropdowns) do
local dropdownFrame = getglobal(name)
if dropdownFrame then
UIDropDownMenu_SetWidth(150, dropdownFrame)
if not HealBot_Config.AutoSwap_Profiles then HealBot_Config.AutoSwap_Profiles = {} end
local skin = HealBot_Config.AutoSwap_Profiles[id]
if skin then
HealBot_UIDropDownMenu_SetSelectedValue(dropdownFrame, skin)
UIDropDownMenu_SetText(skin, dropdownFrame)
end
end
end
end
+152
View File
@@ -0,0 +1,152 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\FrameXML\UI.xsd">
<Script file="HealBot_Options_Auto.lua" />
<Frame name="HealBot_Options_Panel8" parent="HealBot_Options" hidden="true" setAllPoints="true">
<Frames>
<CheckButton name="HealBot_Options_AutoSwap" inherits="OptionsCheckButtonTemplate">
<Anchors>
<Anchor point="TOPLEFT">
<Offset>
<AbsDimension x="25" y="-30" />
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>
getglobal(this:GetName().."Text"):SetText("Enable Auto-Swap");
</OnLoad>
<OnClick>
HealBot_Options_AutoSwap_OnClick(this);
</OnClick>
</Scripts>
</CheckButton>
<Frame name="HealBot_Options_Auto_Solo" inherits="UIDropDownMenuTemplate" id="1">
<Layers>
<Layer level="BACKGROUND">
<FontString name="$parentLabel" text="Solo Skin:" inherits="GameFontNormalSmall">
<Anchors>
<Anchor point="TOPLEFT">
<Offset><AbsDimension x="-10" y="15" /></Offset>
</Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<Anchors>
<Anchor point="TOPLEFT">
<Offset><AbsDimension x="30" y="-80" /></Offset>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>
UIDropDownMenu_Initialize(this, HealBot_Options_Auto_Initialize);
</OnLoad>
</Scripts>
</Frame>
<Frame name="HealBot_Options_Auto_Party" inherits="UIDropDownMenuTemplate" id="2">
<Layers>
<Layer level="BACKGROUND">
<FontString name="$parentLabel" text="Party Skin:" inherits="GameFontNormalSmall">
<Anchors>
<Anchor point="TOPLEFT">
<Offset><AbsDimension x="-10" y="15" /></Offset>
</Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<Anchors>
<Anchor point="TOPLEFT">
<Offset><AbsDimension x="30" y="-130" /></Offset>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>
UIDropDownMenu_Initialize(this, HealBot_Options_Auto_Initialize);
</OnLoad>
</Scripts>
</Frame>
<Frame name="HealBot_Options_Auto_Raid15" inherits="UIDropDownMenuTemplate" id="3">
<Layers>
<Layer level="BACKGROUND">
<FontString name="$parentLabel" text="Raid 15 Skin:" inherits="GameFontNormalSmall">
<Anchors>
<Anchor point="TOPLEFT">
<Offset><AbsDimension x="-10" y="15" /></Offset>
</Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<Anchors>
<Anchor point="TOPLEFT">
<Offset><AbsDimension x="30" y="-180" /></Offset>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>
UIDropDownMenu_Initialize(this, HealBot_Options_Auto_Initialize);
</OnLoad>
</Scripts>
</Frame>
<Frame name="HealBot_Options_Auto_Raid25" inherits="UIDropDownMenuTemplate" id="4">
<Layers>
<Layer level="BACKGROUND">
<FontString name="$parentLabel" text="Raid 25 Skin:" inherits="GameFontNormalSmall">
<Anchors>
<Anchor point="TOPLEFT">
<Offset><AbsDimension x="-10" y="15" /></Offset>
</Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<Anchors>
<Anchor point="TOPLEFT">
<Offset><AbsDimension x="30" y="-230" /></Offset>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>
UIDropDownMenu_Initialize(this, HealBot_Options_Auto_Initialize);
</OnLoad>
</Scripts>
</Frame>
<Frame name="HealBot_Options_Auto_Raid40" inherits="UIDropDownMenuTemplate" id="5">
<Layers>
<Layer level="BACKGROUND">
<FontString name="$parentLabel" text="Raid 40 Skin:" inherits="GameFontNormalSmall">
<Anchors>
<Anchor point="TOPLEFT">
<Offset><AbsDimension x="-10" y="15" /></Offset>
</Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<Anchors>
<Anchor point="TOPLEFT">
<Offset><AbsDimension x="30" y="-280" /></Offset>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>
UIDropDownMenu_Initialize(this, HealBot_Options_Auto_Initialize);
</OnLoad>
</Scripts>
</Frame>
</Frames>
<Scripts>
<OnShow>
HealBot_Options_Auto_OnShow(this);
</OnShow>
</Scripts>
</Frame>
</Ui>
+6 -6
View File
@@ -123,7 +123,7 @@
<Anchors> <Anchors>
<Anchor point="TOPLEFT" relativeTo="HealBot_Options_Buff1" relativePoint="BOTTOMLEFT"> <Anchor point="TOPLEFT" relativeTo="HealBot_Options_Buff1" relativePoint="BOTTOMLEFT">
<Offset> <Offset>
<AbsDimension x="0" y="-20" /> <AbsDimension x="0" y="-35" />
</Offset> </Offset>
</Anchor> </Anchor>
</Anchors> </Anchors>
@@ -160,7 +160,7 @@
<Anchors> <Anchors>
<Anchor point="TOPLEFT" relativeTo="HealBot_Options_Buff2" relativePoint="BOTTOMLEFT"> <Anchor point="TOPLEFT" relativeTo="HealBot_Options_Buff2" relativePoint="BOTTOMLEFT">
<Offset> <Offset>
<AbsDimension x="0" y="-20" /> <AbsDimension x="0" y="-35" />
</Offset> </Offset>
</Anchor> </Anchor>
</Anchors> </Anchors>
@@ -197,7 +197,7 @@
<Anchors> <Anchors>
<Anchor point="TOPLEFT" relativeTo="HealBot_Options_Buff3" relativePoint="BOTTOMLEFT"> <Anchor point="TOPLEFT" relativeTo="HealBot_Options_Buff3" relativePoint="BOTTOMLEFT">
<Offset> <Offset>
<AbsDimension x="0" y="-20" /> <AbsDimension x="0" y="-35" />
</Offset> </Offset>
</Anchor> </Anchor>
</Anchors> </Anchors>
@@ -271,7 +271,7 @@
<Anchors> <Anchors>
<Anchor point="TOPLEFT" relativeTo="HealBot_Options_Buff5" relativePoint="BOTTOMLEFT"> <Anchor point="TOPLEFT" relativeTo="HealBot_Options_Buff5" relativePoint="BOTTOMLEFT">
<Offset> <Offset>
<AbsDimension x="0" y="-20" /> <AbsDimension x="0" y="-35" />
</Offset> </Offset>
</Anchor> </Anchor>
</Anchors> </Anchors>
@@ -308,7 +308,7 @@
<Anchors> <Anchors>
<Anchor point="TOPLEFT" relativeTo="HealBot_Options_Buff6" relativePoint="BOTTOMLEFT"> <Anchor point="TOPLEFT" relativeTo="HealBot_Options_Buff6" relativePoint="BOTTOMLEFT">
<Offset> <Offset>
<AbsDimension x="0" y="-20" /> <AbsDimension x="0" y="-35" />
</Offset> </Offset>
</Anchor> </Anchor>
</Anchors> </Anchors>
@@ -345,7 +345,7 @@
<Anchors> <Anchors>
<Anchor point="TOPLEFT" relativeTo="HealBot_Options_Buff7" relativePoint="BOTTOMLEFT"> <Anchor point="TOPLEFT" relativeTo="HealBot_Options_Buff7" relativePoint="BOTTOMLEFT">
<Offset> <Offset>
<AbsDimension x="0" y="-20" /> <AbsDimension x="0" y="-35" />
</Offset> </Offset>
</Anchor> </Anchor>
</Anchors> </Anchors>
+3 -3
View File
@@ -247,16 +247,16 @@ function HealBot_Options_Debuff_Reset()
local classEN=HealBot_UnitClass("player") local classEN=HealBot_UnitClass("player")
if classEN=="PRIEST" or classEN=="DRUID" or classEN=="PALADIN" or classEN=="SHAMAN" then if classEN=="PRIEST" or classEN=="DRUID" or classEN=="PALADIN" or classEN=="SHAMAN" then
local spell = HealBot_Config.CDCLeftText[UnitClass("player")]; 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 if spell ~= "None" then
table.foreach(HealBot_Debuff_Types[spell], function (index,debuff) table.foreach(HealBot_Debuff_Types[spell], function (index,debuff)
HealBot_DebuffWatch[debuff]="YES"; HealBot_DebuffWatch[debuff]=true;
end) end)
end end
spell = HealBot_Config.CDCRightText[UnitClass("player")]; spell = HealBot_Config.CDCRightText[UnitClass("player")];
if spell ~= "None" then if spell ~= "None" then
table.foreach(HealBot_Debuff_Types[spell], function (index,debuff) table.foreach(HealBot_Debuff_Types[spell], function (index,debuff)
HealBot_DebuffWatch[debuff]="YES"; HealBot_DebuffWatch[debuff]=true;
end) end)
end end
end end
+32 -2
View File
@@ -265,8 +265,38 @@
</Scripts> </Scripts>
</CheckButton> </CheckButton>
<Button name="HealBot_Options_Defaults" inherits="UIPanelButtonTemplate" text="HEALBOT_OPTIONS_DEFAULTS">
<Size>
<AbsDimension x="80" y="22"/>
</Size>
<Anchors>
<Anchor point="BOTTOM" relativePoint="BOTTOM">
<Offset>
<AbsDimension x="-50" y="15"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>HealBot_Options_Defaults_OnClick(this)</OnClick>
</Scripts>
</Button>
<Button name="HealBot_Options_CloseButton" inherits="UIPanelButtonTemplate" text="HEALBOT_OPTIONS_CLOSE">
<Size>
<AbsDimension x="80" y="22"/>
</Size>
<Anchors>
<Anchor point="BOTTOM" relativePoint="BOTTOM">
<Offset>
<AbsDimension x="50" y="15"/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick>
HideUIPanel(this:GetParent():GetParent());
</OnClick>
</Scripts>
</Button>
</Frames> </Frames>
</Frame> </Frame>
+1 -1
View File
@@ -52,7 +52,7 @@
</Anchor> </Anchor>
</Anchors> </Anchors>
<Scripts> <Scripts>
<OnLoad>HealBot_Options_GroupHeals_OnLoad(this,HEALBOT_OPTIONS_GROUPHEALS)</OnLoad> <OnLoad>HealBot_Options_GroupHeals_OnLoad(this,HEALBOT_OPTIONS_GROUPHEALS_LABEL)</OnLoad>
<OnClick>HealBot_Options_GroupHeals_OnClick(this)</OnClick> <OnClick>HealBot_Options_GroupHeals_OnClick(this)</OnClick>
</Scripts> </Scripts>
</CheckButton> </CheckButton>
+22
View File
@@ -1,6 +1,22 @@
-- HealBot Options panel file: HealBot_Options_Skins.lua -- HealBot Options panel file: HealBot_Options_Skins.lua
-- Split from original HealBot_Options.lua -- Split from original HealBot_Options.lua
function HealBot_Options_BarMaxRowsS_OnValueChanged(this)
if not HealBot_Config.bmaxrows then HealBot_Config.bmaxrows = {} end
HealBot_Config.bmaxrows[HealBot_Config.Current_Skin] = this:GetValue()
HealBot_Action_PartyChanged()
end
function HealBot_Options_GridOrientation_OnClick(this)
if not HealBot_Config.GridOrientation then HealBot_Config.GridOrientation = {} end
if this:GetChecked() then
HealBot_Config.GridOrientation[HealBot_Config.Current_Skin] = 2 -- Horizontal
else
HealBot_Config.GridOrientation[HealBot_Config.Current_Skin] = 1 -- Vertical
end
HealBot_Action_PartyChanged()
end
function HealBot_Options_NewSkin_OnTextChanged(this) function HealBot_Options_NewSkin_OnTextChanged(this)
local text= this:GetText() local text= this:GetText()
if string.len(text)>0 then if string.len(text)>0 then
@@ -11,6 +27,10 @@ function HealBot_Options_NewSkin_OnTextChanged(this)
end end
function HealBot_Options_NewSkinb_OnClick(this) function HealBot_Options_NewSkinb_OnClick(this)
HealBot_Config.numcols[HealBot_Options_NewSkin:GetText()] = HealBot_Config.numcols[HealBot_Config.Current_Skin] HealBot_Config.numcols[HealBot_Options_NewSkin:GetText()] = HealBot_Config.numcols[HealBot_Config.Current_Skin]
if not HealBot_Config.bmaxrows then HealBot_Config.bmaxrows = {} end
if not HealBot_Config.GridOrientation then HealBot_Config.GridOrientation = {} end
HealBot_Config.bmaxrows[HealBot_Options_NewSkin:GetText()] = HealBot_Config.bmaxrows[HealBot_Config.Current_Skin] or 0
HealBot_Config.GridOrientation[HealBot_Options_NewSkin:GetText()] = HealBot_Config.GridOrientation[HealBot_Config.Current_Skin] or 1
HealBot_Config.btexture[HealBot_Options_NewSkin:GetText()] = HealBot_Config.btexture[HealBot_Config.Current_Skin] HealBot_Config.btexture[HealBot_Options_NewSkin:GetText()] = HealBot_Config.btexture[HealBot_Config.Current_Skin]
HealBot_Config.bcspace[HealBot_Options_NewSkin:GetText()] = HealBot_Config.bcspace[HealBot_Config.Current_Skin] HealBot_Config.bcspace[HealBot_Options_NewSkin:GetText()] = HealBot_Config.bcspace[HealBot_Config.Current_Skin]
HealBot_Config.brspace[HealBot_Options_NewSkin:GetText()] = HealBot_Config.brspace[HealBot_Config.Current_Skin] HealBot_Config.brspace[HealBot_Options_NewSkin:GetText()] = HealBot_Config.brspace[HealBot_Config.Current_Skin]
@@ -56,6 +76,8 @@ end
function HealBot_Options_DeleteSkin_OnClick(this) function HealBot_Options_DeleteSkin_OnClick(this)
if HealBot_Config.Current_Skin~=HEALBOT_SKINS_STD then if HealBot_Config.Current_Skin~=HEALBOT_SKINS_STD then
HealBot_Config.numcols[HealBot_Options_SkinsText:GetText()] = nil HealBot_Config.numcols[HealBot_Options_SkinsText:GetText()] = nil
if HealBot_Config.bmaxrows then HealBot_Config.bmaxrows[HealBot_Options_SkinsText:GetText()] = nil end
if HealBot_Config.GridOrientation then HealBot_Config.GridOrientation[HealBot_Options_SkinsText:GetText()] = nil end
HealBot_Config.btexture[HealBot_Options_SkinsText:GetText()] = nil HealBot_Config.btexture[HealBot_Options_SkinsText:GetText()] = nil
HealBot_Config.bcspace[HealBot_Options_SkinsText:GetText()] = nil HealBot_Config.bcspace[HealBot_Options_SkinsText:GetText()] = nil
HealBot_Config.brspace[HealBot_Options_SkinsText:GetText()] = nil HealBot_Config.brspace[HealBot_Options_SkinsText:GetText()] = nil
+55 -19
View File
@@ -266,9 +266,9 @@
<AbsDimension x="123" y="17" /> <AbsDimension x="123" y="17" />
</Size> </Size>
<Anchors> <Anchors>
<Anchor point="TOPLEFT" relativeTo="HealBot_Options_BarBRSpaceS" relativePoint="TOPLEFT"> <Anchor point="TOPLEFT" relativeTo="HealBot_Options_BarBCSpaceS" relativePoint="TOPRIGHT">
<Offset> <Offset>
<AbsDimension x="0" y="-35" /> <AbsDimension x="10" y="0" />
</Offset> </Offset>
</Anchor> </Anchor>
</Anchors> </Anchors>
@@ -277,28 +277,14 @@
<OnValueChanged>HealBot_Options_FramePaddingS_OnValueChanged(this)</OnValueChanged> <OnValueChanged>HealBot_Options_FramePaddingS_OnValueChanged(this)</OnValueChanged>
</Scripts> </Scripts>
</Slider> </Slider>
<Slider name="HealBot_Options_BorderThicknessS" inherits="HealBot_Options_SliderTemplate">
<Size>
<AbsDimension x="123" y="17" />
</Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HealBot_Options_FramePaddingS" relativePoint="TOPRIGHT">
<Offset>
<AbsDimension x="10" y="0" />
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>HealBot_Options_val_OnLoad(this,"Solid Border",1,10)</OnLoad>
<OnValueChanged>HealBot_Options_BorderThicknessS_OnValueChanged(this)</OnValueChanged>
</Scripts>
</Slider>
<Slider name="HealBot_Options_BarAlpha" inherits="HealBot_Options_SliderTemplate"> <Slider name="HealBot_Options_BarAlpha" inherits="HealBot_Options_SliderTemplate">
<Size> <Size>
<AbsDimension x="123" y="17" /> <AbsDimension x="123" y="17" />
</Size> </Size>
<Anchors> <Anchors>
<Anchor point="TOPLEFT" relativeTo="HealBot_Options_FramePaddingS" relativePoint="TOPLEFT"> <Anchor point="TOPLEFT" relativeTo="HealBot_Options_BarBRSpaceS" relativePoint="TOPLEFT">
<Offset> <Offset>
<AbsDimension x="0" y="-35" /> <AbsDimension x="0" y="-35" />
</Offset> </Offset>
@@ -375,6 +361,56 @@
</Scripts> </Scripts>
</Slider> </Slider>
<Slider name="HealBot_Options_BorderThicknessS" inherits="HealBot_Options_SliderTemplate">
<Size>
<AbsDimension x="123" y="17" />
</Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HealBot_Options_BarAlphaInHeal" relativePoint="TOPRIGHT">
<Offset>
<AbsDimension x="10" y="0" />
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>HealBot_Options_val_OnLoad(this,"Solid Border",1,10)</OnLoad>
<OnValueChanged>HealBot_Options_BorderThicknessS_OnValueChanged(this)</OnValueChanged>
</Scripts>
</Slider>
<Slider name="HealBot_Options_BarMaxRowsS" inherits="HealBot_Options_SliderTemplate">
<Size>
<AbsDimension x="123" y="17" />
</Size>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HealBot_Options_AbortBarSize" relativePoint="TOPRIGHT">
<Offset>
<AbsDimension x="10" y="0" />
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>HealBot_Options_val_OnLoad(this,"Max Rows",0,40)</OnLoad>
<OnValueChanged>HealBot_Options_BarMaxRowsS_OnValueChanged(this)</OnValueChanged>
</Scripts>
</Slider>
<CheckButton name="HealBot_Options_GridOrientation" inherits="OptionsCheckButtonTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HealBot_Options_BarMaxRowsS" relativePoint="BOTTOMLEFT">
<Offset>
<AbsDimension x="-5" y="-10" />
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnLoad>
getglobal(this:GetName().."Text"):SetText("Horizontal Grid");
</OnLoad>
<OnClick>
HealBot_Options_GridOrientation_OnClick(this);
</OnClick>
</Scripts>
</CheckButton>
<Button name="HealBot_EnTextColorpickb"> <Button name="HealBot_EnTextColorpickb">
<Size> <Size>
<AbsDimension x="87" y="20"/> <AbsDimension x="87" y="20"/>
+141 -31
View File
@@ -87,13 +87,17 @@ function HealBot_HealthColor(unit, hlth, maxhlth)
end end
function HealBot_Action_HealthBar(button) function HealBot_Action_HealthBar(button)
local name = button:GetName(); if not button.bar then
return getglobal(name .. "Bar"); button.bar = getglobal(button:GetName() .. "Bar")
end
return button.bar;
end end
function HealBot_Action_HealthBar2(button) function HealBot_Action_HealthBar2(button)
local name = button:GetName(); if not button.bar2 then
return getglobal(name .. "Bar2"); button.bar2 = getglobal(button:GetName() .. "Bar2")
end
return button.bar2;
end end
function HealBot_Action_EnableButton(button) function HealBot_Action_EnableButton(button)
@@ -108,7 +112,8 @@ function HealBot_Action_EnableButton(button)
local bar = HealBot_Action_HealthBar(button); local bar = HealBot_Action_HealthBar(button);
local bar2 = HealBot_Action_HealthBar2(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 btexture = HealBot_Config.btexture[HealBot_Config.Current_Skin];
local bheight = HealBot_Config.bheight[HealBot_Config.Current_Skin]; local bheight = HealBot_Config.bheight[HealBot_Config.Current_Skin];
local sr = HealBot_Config.btextenabledcolr[HealBot_Config.Current_Skin]; local sr = HealBot_Config.btextenabledcolr[HealBot_Config.Current_Skin];
@@ -175,7 +180,7 @@ function HealBot_Action_EnableButton(button)
else else
bar2:SetValue(0); bar2:SetValue(0);
end 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 if (not HealBot_IsCasting and (HealBot_CanHeal(unit) or HealBot_MissingBuffs[unit])) then
button:Enable(); button:Enable();
if HealBot_UnitDebuff[unit] then if HealBot_UnitDebuff[unit] then
@@ -255,9 +260,9 @@ function HealBot_Action_EnableButton(button)
end end
function HealBot_Action_EnableButtons() function HealBot_Action_EnableButtons()
table.foreach(HealBot_Action_HealButtons, function (index, button) for index, button in pairs(HealBot_Action_HealButtons) do
HealBot_Action_EnableButton(button); HealBot_Action_EnableButton(button)
end); end
end end
function HealBot_Action_RefreshButton(button) function HealBot_Action_RefreshButton(button)
@@ -285,13 +290,13 @@ end
function HealBot_Action_RefreshButtons(unit) function HealBot_Action_RefreshButtons(unit)
if unit and HealBot_Action_UnitButtons[unit] then if unit and HealBot_Action_UnitButtons[unit] then
table.foreach(HealBot_Action_UnitButtons[unit], function (index, button) for index, button in pairs(HealBot_Action_UnitButtons[unit]) do
HealBot_Action_RefreshButton(button); HealBot_Action_RefreshButton(button)
end); end
else else
table.foreach(HealBot_Action_HealButtons, function (index, button) for index, button in pairs(HealBot_Action_HealButtons) do
HealBot_Action_RefreshButton(button); HealBot_Action_RefreshButton(button)
end); end
end end
end end
@@ -330,6 +335,41 @@ function HealBot_Action_PositionButton(button, OsetX, OsetY, bwidth, bheight, ch
return OsetY; return OsetY;
end end
function HealBot_Action_PositionButtonHorizontal(button, OsetX, OsetY, bwidth, bheight, checked, header)
local bcspace = HealBot_Config.bcspace[HealBot_Config.Current_Skin] or 3;
if header then
headerno = headerno + 1;
local headerobj = getglobal("HealBot_Action_Header" .. headerno);
headerobj:SetText(header)
headerobj:Show();
headerobj:ClearAllPoints();
headerobj:SetHeight(bheight);
headerobj:SetWidth(bwidth);
headerobj:SetPoint("TOPLEFT", "HealBot_Action", "TOPLEFT", OsetX, -OsetY);
headerobj:Disable();
OsetX = OsetX + bwidth + bcspace;
else
local unit = button.unit;
button:SetText(" ");
if (HealBot_MayHeal(unit)) then
button:Show();
button:ClearAllPoints();
button:SetHeight(bheight);
if checked then
button:SetWidth(bwidth - 14);
button:SetPoint("TOPLEFT", "HealBot_Action", "TOPLEFT", OsetX + 14, -OsetY);
else
button:SetWidth(bwidth);
button:SetPoint("TOPLEFT", "HealBot_Action", "TOPLEFT", OsetX, -OsetY);
end
OsetX = OsetX + bwidth + bcspace;
else
button:Hide();
end
end
return OsetX;
end
function HealBot_Action_SetHeightWidth(width, height, bwidth) function HealBot_Action_SetHeightWidth(width, height, bwidth)
if HealBot_ActionHeight then if HealBot_ActionHeight then
HealBot_Action:SetHeight(HealBot_ActionHeight); HealBot_Action:SetHeight(HealBot_ActionHeight);
@@ -380,6 +420,31 @@ function HealBot_Action_PartyChanged()
local TempMaxH = 0; local TempMaxH = 0;
local HeaderPos = {}; local HeaderPos = {};
if HealBot_Config.AutoSwap_Enabled == 1 then
local totalMembers = GetNumRaidMembers()
if totalMembers == 0 then totalMembers = GetNumPartyMembers() end
local threshold = 1
if totalMembers == 0 then
threshold = 1 -- Solo
elseif totalMembers > 0 and totalMembers <= 5 then
threshold = 2 -- Party
elseif totalMembers > 5 and totalMembers <= 15 then
threshold = 3 -- Raid15
elseif totalMembers > 15 and totalMembers <= 25 then
threshold = 4 -- Raid25
else
threshold = 5 -- Raid40
end
if not HealBot_Config.AutoSwap_Profiles then HealBot_Config.AutoSwap_Profiles = {} end
local swapSkin = HealBot_Config.AutoSwap_Profiles[threshold]
if swapSkin and swapSkin ~= HealBot_Config.Current_Skin then
HealBot_Config.Current_Skin = swapSkin
HealBot_Options_SetSkins()
end
end
for j = 1, 15 do for j = 1, 15 do
local headerobj = getglobal("HealBot_Action_Header" .. j); local headerobj = getglobal("HealBot_Action_Header" .. j);
headerobj:SetText(" ") headerobj:SetText(" ")
@@ -738,8 +803,12 @@ function HealBot_Action_PartyChanged()
local OffsetY = bpadding; local OffsetY = bpadding;
local OffsetX = bpadding; local OffsetX = bpadding;
local MaxOffsetY = 0; local MaxOffsetY = 0;
local MaxOffsetX = 0;
if cols > (numBars - numHeaders) then local maxRows = (HealBot_Config.bmaxrows and HealBot_Config.bmaxrows[HealBot_Config.Current_Skin]) or 0
local orientation = (HealBot_Config.GridOrientation and HealBot_Config.GridOrientation[HealBot_Config.Current_Skin]) or 1
if cols > (numBars - numHeaders) and maxRows == 0 then
cols = numBars - numHeaders; cols = numBars - numHeaders;
end end
if cols <= 0 then cols = 1 end if cols <= 0 then cols = 1 end
@@ -747,33 +816,64 @@ function HealBot_Action_PartyChanged()
local h = 1; local h = 1;
local i = 0; local i = 0;
local z = 1; local z = 1;
local brspace = HealBot_Config.brspace[HealBot_Config.Current_Skin] or 3;
local bcspace = HealBot_Config.bcspace[HealBot_Config.Current_Skin] or 3;
table.foreach(HealBot_Action_HealButtons, function (index, button) local limit = math.ceil((numBars) / cols)
if orientation == 1 and maxRows > 0 then
limit = maxRows
elseif orientation == 2 then
limit = cols
end
for index, button in pairs(HealBot_Action_HealButtons) do
i = i + 1; i = i + 1;
local checked = false; local checked = false;
local header; local header;
if HeaderPos[i] then if HeaderPos[i] then
header = HeaderPos[i]; header = HeaderPos[i];
OffsetY = HealBot_Action_PositionButton(nil, OffsetX, OffsetY, bwidth, bheight, checked, header); if orientation == 1 then
if h == math.ceil((numBars) / cols) and z < numBars then OffsetY = HealBot_Action_PositionButton(nil, OffsetX, OffsetY, bwidth, bheight, checked, header);
h = 0; if h == limit and z < numBars then
if MaxOffsetY < OffsetY then MaxOffsetY = OffsetY; end h = 0;
OffsetY = bpadding; if MaxOffsetY < OffsetY then MaxOffsetY = OffsetY; end
OffsetX = OffsetX + bwidth + bcspace; OffsetY = bpadding;
OffsetX = OffsetX + bwidth + bcspace;
end
else
OffsetX = HealBot_Action_PositionButtonHorizontal(nil, OffsetX, OffsetY, bwidth, bheight, checked, header);
if h == limit and z < numBars then
h = 0;
if MaxOffsetX < OffsetX then MaxOffsetX = OffsetX; end
OffsetX = bpadding;
OffsetY = OffsetY + bheight + brspace;
end
end end
h = h + 1; h = h + 1;
z = z + 1; z = z + 1;
end end
if checked_start <= i and checked_end >= i then checked = true; end if checked_start <= i and checked_end >= i then checked = true; end
OffsetY = HealBot_Action_PositionButton(button, OffsetX, OffsetY, bwidth, bheight, checked, nil);
if h == math.ceil((numBars) / cols) and z < numBars then if orientation == 1 then
h = 0; OffsetY = HealBot_Action_PositionButton(button, OffsetX, OffsetY, bwidth, bheight, checked, nil);
if MaxOffsetY < OffsetY then MaxOffsetY = OffsetY; end if h == limit and z < numBars then
OffsetY = bpadding; h = 0;
OffsetX = OffsetX + bwidth + bcspace; if MaxOffsetY < OffsetY then MaxOffsetY = OffsetY; end
OffsetY = bpadding;
OffsetX = OffsetX + bwidth + bcspace;
end
else
OffsetX = HealBot_Action_PositionButtonHorizontal(button, OffsetX, OffsetY, bwidth, bheight, checked, nil);
if h == limit and z < numBars then
h = 0;
if MaxOffsetX < OffsetX then MaxOffsetX = OffsetX; end
OffsetX = bpadding;
OffsetY = OffsetY + bheight + brspace;
end
end end
z = z + 1; z = z + 1;
h = h + 1; h = h + 1;
local bar = HealBot_Action_HealthBar(button); local bar = HealBot_Action_HealthBar(button);
@@ -787,9 +887,19 @@ function HealBot_Action_PartyChanged()
bar:SetScale(barScale); bar:SetScale(barScale);
bar2:SetHeight(bheight); bar2:SetHeight(bheight);
HealBot_Action_SetTexture(bar2, btexture); HealBot_Action_SetTexture(bar2, btexture);
end); end
if MaxOffsetY < OffsetY then MaxOffsetY = OffsetY; end if orientation == 1 then
if MaxOffsetY < OffsetY then MaxOffsetY = OffsetY; end
else
if MaxOffsetX < OffsetX then MaxOffsetX = OffsetX; end
-- In horizontal mode, OffsetY represents the active row. We need to measure total height.
MaxOffsetY = OffsetY + bheight + brspace
OffsetX = MaxOffsetX
if numBars > 0 then
OffsetX = OffsetX - bwidth - bcspace
end
end
if HealBot_Config.HideOptions == 1 then if HealBot_Config.HideOptions == 1 then
HealBot_Action_OptionsButton:Hide(); HealBot_Action_OptionsButton:Hide();
+30 -10
View File
@@ -3,6 +3,16 @@
HealBot_Action_TooltipUnit = nil HealBot_Action_TooltipUnit = nil
function HealBot_Tooltip_GetSpellColor(spell)
local r, g, b = 1, 1, 0 -- default yellow
if spell and HealBot_Spells and HealBot_Spells[spell] and HealBot_Spells[spell].Mana then
if UnitMana("player") < HealBot_Spells[spell].Mana then
r, g, b = 1, 0, 0 -- red if not enough mana
end
end
return r, g, b
end
function HealBot_Action_RefreshTooltip(unit) function HealBot_Action_RefreshTooltip(unit)
if HealBot_Config.ShowTooltip==0 then return end if HealBot_Config.ShowTooltip==0 then return end
if not unit then unit = HealBot_Action_TooltipUnit end if not unit then unit = HealBot_Action_TooltipUnit end
@@ -33,53 +43,63 @@ function HealBot_Action_RefreshTooltip(unit)
if HealBot_Config.Tooltip_ShowSpellDetail==1 then if HealBot_Config.Tooltip_ShowSpellDetail==1 then
if spellLeft then if spellLeft then
linenum=linenum+2 linenum=linenum+2
HealBot_Action_Tooltip_SetLineLeft(HEALBOT_OPTIONS_BUTTONLEFT.." "..HEALBOT_OPTIONS_COMBOBUTTON..": "..spellLeft,1,1,0,linenum) local sr, sg, sb = HealBot_Tooltip_GetSpellColor(spellLeft)
HealBot_Action_Tooltip_SetLineLeft(HEALBOT_OPTIONS_BUTTONLEFT.." "..HEALBOT_OPTIONS_COMBOBUTTON..": "..spellLeft,sr,sg,sb,linenum)
linenum=HealBot_Action_Tooltip_SpellInfo(spellLeft,linenum); linenum=HealBot_Action_Tooltip_SpellInfo(spellLeft,linenum);
end end
if spellMiddle then if spellMiddle then
linenum=linenum+2 linenum=linenum+2
HealBot_Action_Tooltip_SetLineLeft(HEALBOT_OPTIONS_BUTTONMIDDLE.." "..HEALBOT_OPTIONS_COMBOBUTTON..": "..spellMiddle,1,1,0,linenum) local sr, sg, sb = HealBot_Tooltip_GetSpellColor(spellMiddle)
HealBot_Action_Tooltip_SetLineLeft(HEALBOT_OPTIONS_BUTTONMIDDLE.." "..HEALBOT_OPTIONS_COMBOBUTTON..": "..spellMiddle,sr,sg,sb,linenum)
linenum=HealBot_Action_Tooltip_SpellInfo(spellMiddle,linenum); linenum=HealBot_Action_Tooltip_SpellInfo(spellMiddle,linenum);
end end
if spellRight then if spellRight then
linenum=linenum+2 linenum=linenum+2
HealBot_Action_Tooltip_SetLineLeft(HEALBOT_OPTIONS_BUTTONRIGHT.." "..HEALBOT_OPTIONS_COMBOBUTTON..": "..spellRight,1,1,0,linenum) local sr, sg, sb = HealBot_Tooltip_GetSpellColor(spellRight)
HealBot_Action_Tooltip_SetLineLeft(HEALBOT_OPTIONS_BUTTONRIGHT.." "..HEALBOT_OPTIONS_COMBOBUTTON..": "..spellRight,sr,sg,sb,linenum)
linenum=HealBot_Action_Tooltip_SpellInfo(spellRight,linenum); linenum=HealBot_Action_Tooltip_SpellInfo(spellRight,linenum);
end end
if spellButton4 then if spellButton4 then
linenum=linenum+2 linenum=linenum+2
HealBot_Action_Tooltip_SetLineLeft(HEALBOT_OPTIONS_BUTTON4.." "..HEALBOT_OPTIONS_COMBOBUTTON..": "..spellButton4,1,1,0,linenum) local sr, sg, sb = HealBot_Tooltip_GetSpellColor(spellButton4)
HealBot_Action_Tooltip_SetLineLeft(HEALBOT_OPTIONS_BUTTON4.." "..HEALBOT_OPTIONS_COMBOBUTTON..": "..spellButton4,sr,sg,sb,linenum)
linenum=HealBot_Action_Tooltip_SpellInfo(spellButton4,linenum); linenum=HealBot_Action_Tooltip_SpellInfo(spellButton4,linenum);
end end
if spellButton5 then if spellButton5 then
linenum=linenum+2 linenum=linenum+2
HealBot_Action_Tooltip_SetLineLeft(HEALBOT_OPTIONS_BUTTON5.." "..HEALBOT_OPTIONS_COMBOBUTTON..": "..spellButton5,1,1,0,linenum) local sr, sg, sb = HealBot_Tooltip_GetSpellColor(spellButton5)
HealBot_Action_Tooltip_SetLineLeft(HEALBOT_OPTIONS_BUTTON5.." "..HEALBOT_OPTIONS_COMBOBUTTON..": "..spellButton5,sr,sg,sb,linenum)
linenum=HealBot_Action_Tooltip_SpellInfo(spellButton5,linenum); linenum=HealBot_Action_Tooltip_SpellInfo(spellButton5,linenum);
end end
else else
if spellLeft then if spellLeft then
linenum=linenum+1 linenum=linenum+1
HealBot_Action_Tooltip_SetLineLeft(HEALBOT_OPTIONS_BUTTONLEFT..":",1,1,0,linenum) local sr, sg, sb = HealBot_Tooltip_GetSpellColor(spellLeft)
HealBot_Action_Tooltip_SetLineLeft(HEALBOT_OPTIONS_BUTTONLEFT..":",sr,sg,sb,linenum)
HealBot_Action_Tooltip_SetLineRight(HealBot_Action_Tooltip_SpellSummary(spellLeft),1,1,1,linenum) HealBot_Action_Tooltip_SetLineRight(HealBot_Action_Tooltip_SpellSummary(spellLeft),1,1,1,linenum)
end end
if spellMiddle then if spellMiddle then
linenum=linenum+1 linenum=linenum+1
HealBot_Action_Tooltip_SetLineLeft(HEALBOT_OPTIONS_BUTTONMIDDLE..":",1,1,0,linenum) local sr, sg, sb = HealBot_Tooltip_GetSpellColor(spellMiddle)
HealBot_Action_Tooltip_SetLineLeft(HEALBOT_OPTIONS_BUTTONMIDDLE..":",sr,sg,sb,linenum)
HealBot_Action_Tooltip_SetLineRight(HealBot_Action_Tooltip_SpellSummary(spellMiddle),1,1,1,linenum) HealBot_Action_Tooltip_SetLineRight(HealBot_Action_Tooltip_SpellSummary(spellMiddle),1,1,1,linenum)
end end
if spellRight then if spellRight then
linenum=linenum+1 linenum=linenum+1
HealBot_Action_Tooltip_SetLineLeft(HEALBOT_OPTIONS_BUTTONRIGHT..":",1,1,0,linenum) local sr, sg, sb = HealBot_Tooltip_GetSpellColor(spellRight)
HealBot_Action_Tooltip_SetLineLeft(HEALBOT_OPTIONS_BUTTONRIGHT..":",sr,sg,sb,linenum)
HealBot_Action_Tooltip_SetLineRight(HealBot_Action_Tooltip_SpellSummary(spellRight),1,1,1,linenum) HealBot_Action_Tooltip_SetLineRight(HealBot_Action_Tooltip_SpellSummary(spellRight),1,1,1,linenum)
end end
if spellButton4 then if spellButton4 then
linenum=linenum+1 linenum=linenum+1
HealBot_Action_Tooltip_SetLineLeft(HEALBOT_OPTIONS_BUTTON4..":",1,1,0,linenum) local sr, sg, sb = HealBot_Tooltip_GetSpellColor(spellButton4)
HealBot_Action_Tooltip_SetLineLeft(HEALBOT_OPTIONS_BUTTON4..":",sr,sg,sb,linenum)
HealBot_Action_Tooltip_SetLineRight(HealBot_Action_Tooltip_SpellSummary(spellButton4),1,1,1,linenum) HealBot_Action_Tooltip_SetLineRight(HealBot_Action_Tooltip_SpellSummary(spellButton4),1,1,1,linenum)
end end
if spellButton5 then if spellButton5 then
linenum=linenum+1 linenum=linenum+1
HealBot_Action_Tooltip_SetLineLeft(HEALBOT_OPTIONS_BUTTON5..":",1,1,0,linenum) local sr, sg, sb = HealBot_Tooltip_GetSpellColor(spellButton5)
HealBot_Action_Tooltip_SetLineLeft(HEALBOT_OPTIONS_BUTTON5..":",sr,sg,sb,linenum)
HealBot_Action_Tooltip_SetLineRight(HealBot_Action_Tooltip_SpellSummary(spellButton5),1,1,1,linenum) HealBot_Action_Tooltip_SetLineRight(HealBot_Action_Tooltip_SpellSummary(spellButton5),1,1,1,linenum)
end end
end end
+32
View File
@@ -31,12 +31,44 @@ Default installation path: `C:\Program Files\World of Warcraft\Interface\AddOns\
* **Non-Mana Resource Tracking:** Track Rage, Energy, and Focus for non-mana classes. * **Non-Mana Resource Tracking:** Track Rage, Energy, and Focus for non-mana classes.
* **Highly Customizable Skins:** Fully configure dimensions (width, height), row spacing, column layouts, custom textures, opacity, class-colored frames, and outline of fonts. * **Highly Customizable Skins:** Fully configure dimensions (width, height), row spacing, column layouts, custom textures, opacity, class-colored frames, and outline of fonts.
### To be implemented
- **GUID-based frame mapping:** Migrate internal state to use lightweight GUID tracking to resolve bugs when targets switch or duplicate names appear (e.g., enemy mobs, warlock pets).
- **Mod Integration Optimization:** Add conditional SuperWoW/UnitXP SP3 integration to reduce GC spikes and improve frame rendering accuracy.
### Known issues ### Known issues
* **New spell rank bug** you may experience lua error spaming your chat frame after learning new healing spells. /reload will clear the issue. To be fixed next release * **New spell rank bug** you may experience lua error spaming your chat frame after learning new healing spells. /reload will clear the issue. To be fixed next release
### Change Log ### Change Log
**v1.6**
* **Event Loop Decoupling:** Ripped out redundant synchronous UI redraws that were bypassed by the new MVC architecture. High-frequency events (mana regen, health ticks) now fully rely on the `HealBot_OnUpdate` dirty queue, severely reducing CPU bottlenecks.
* **Combat UI Optimizations:** Removed unnecessary full spell recalculations when dropping combat, preventing client stutter after every mob kill.
* **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.
* **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.
* **Incoming Heals Fix:** Fixed a bug where incoming heals failed to broadcast or show on the UI due to synchronous GCD fails and `CheckInteractDistance` limitations in the 1.12 API.
* **Hovercast Incoming Heals:** Added full support for processing and displaying incoming heals when using action bar hovercasting.
* **Zero-latency Self-Heals:** Incoming heals for the local player now process instantly with zero latency and no network reliance, ensuring they function even when playing solo.
**v1.4** **v1.4**
* **Extra Frame support for pets and familiars added:** Togglable from healing tab - Extra frames option selected & pets selected from dropdown. * **Extra Frame support for pets and familiars added:** Togglable from healing tab - Extra frames option selected & pets selected from dropdown.
* **Customizable Health Text:** Added a new dropdown in the Healing Options tab that allows users to choose how health text is displayed on unit frames (`Name Only`, `Health Percentage`, `Real Health`, or `Health Deficit`). Includes a smart truncation algorithm to preserve critical health numbers even if the unit name is too long. * **Customizable Health Text:** Added a new dropdown in the Healing Options tab that allows users to choose how health text is displayed on unit frames (`Name Only`, `Health Percentage`, `Real Health`, or `Health Deficit`). Includes a smart truncation algorithm to preserve critical health numbers even if the unit name is too long.