4 Commits
16 changed files with 518 additions and 81 deletions
+50 -13
View File
@@ -203,22 +203,59 @@ end
-- Spell parsing and casting functions moved to HealBot_Controller_Spells.lua -- Spell parsing and casting functions moved to HealBot_Controller_Spells.lua
HealBot_ClassMap = nil
function HealBot_InitClassMap()
HealBot_ClassMap = {
["DRUID"] = "DRUID", ["Druid"] = "DRUID",
["HUNTER"] = "HUNTER", ["Hunter"] = "HUNTER",
["MAGE"] = "MAGE", ["Mage"] = "MAGE",
["PALADIN"] = "PALADIN", ["Paladin"] = "PALADIN",
["PRIEST"] = "PRIEST", ["Priest"] = "PRIEST",
["ROGUE"] = "ROGUE", ["Rogue"] = "ROGUE",
["SHAMAN"] = "SHAMAN", ["Shaman"] = "SHAMAN",
["WARLOCK"] = "WARLOCK", ["Warlock"] = "WARLOCK",
["WARRIOR"] = "WARRIOR", ["Warrior"] = "WARRIOR",
}
if HEALBOT_DRUID then HealBot_ClassMap[HEALBOT_DRUID] = "DRUID" end
if HEALBOT_HUNTER then HealBot_ClassMap[HEALBOT_HUNTER] = "HUNTER" end
if HEALBOT_MAGE then HealBot_ClassMap[HEALBOT_MAGE] = "MAGE" end
if HEALBOT_PALADIN then HealBot_ClassMap[HEALBOT_PALADIN] = "PALADIN" end
if HEALBOT_PRIEST then HealBot_ClassMap[HEALBOT_PRIEST] = "PRIEST" end
if HEALBOT_ROGUE then HealBot_ClassMap[HEALBOT_ROGUE] = "ROGUE" end
if HEALBOT_SHAMAN then HealBot_ClassMap[HEALBOT_SHAMAN] = "SHAMAN" end
if HEALBOT_WARLOCK then HealBot_ClassMap[HEALBOT_WARLOCK] = "WARLOCK" end
if HEALBOT_WARRIOR then HealBot_ClassMap[HEALBOT_WARRIOR] = "WARRIOR" end
end
-- HealBot_UnitClass: Returns English class string for a unit. -- HealBot_UnitClass: Returns English class string for a unit.
function HealBot_UnitClass(unit) function HealBot_UnitClass(unit)
local locClass, enClass = UnitClass(unit) if not unit then return nil end
if enClass then return string.upper(enClass) end if not HealBot_ClassMap then HealBot_InitClassMap() end
-- Fallback for Vanilla 1.12 where enClass is nil -- 1. If player self, query "player" directly
if locClass == HEALBOT_DRUID then return "DRUID" if unit == "player" or UnitIsUnit(unit, "player") then
elseif locClass == HEALBOT_HUNTER then return "HUNTER" local locClass, enClass = UnitClass("player")
elseif locClass == HEALBOT_MAGE then return "MAGE" if enClass and enClass ~= "" then return string.upper(enClass) end
elseif locClass == HEALBOT_PALADIN then return "PALADIN" if locClass and HealBot_ClassMap[locClass] then return HealBot_ClassMap[locClass] end
elseif locClass == HEALBOT_PRIEST then return "PRIEST" if locClass then return string.upper(locClass) end
elseif locClass == HEALBOT_ROGUE then return "ROGUE"
elseif locClass == HEALBOT_SHAMAN then return "SHAMAN"
elseif locClass == HEALBOT_WARLOCK then return "WARLOCK"
elseif locClass == HEALBOT_WARRIOR then return "WARRIOR"
end end
-- 2. If raid member, query GetRaidRosterInfo (server authoritative English class token)
local _, _, raidIdx = string.find(unit, "^raid(%d+)$")
if raidIdx and GetNumRaidMembers() > 0 then
local _, _, _, _, class, fileName = GetRaidRosterInfo(tonumber(raidIdx))
if fileName and fileName ~= "" then
return string.upper(fileName)
elseif class and HealBot_ClassMap[class] then
return HealBot_ClassMap[class]
end
end
-- 3. General fallback via UnitClass API
local locClass, enClass = UnitClass(unit)
if enClass and enClass ~= "" then return string.upper(enClass) end
if locClass and HealBot_ClassMap[locClass] then return HealBot_ClassMap[locClass] end
return locClass return locClass
end end
+1 -1
View File
@@ -1,6 +1,6 @@
## Interface: 11200 ## Interface: 11200
## Title: HealBotBlue ## Title: HealBotBlue
## Version: 1.7.5 ## Version: 1.7.6
## Author: Bluewhale ## Author: Bluewhale
## Notes: Raidframe replacement for healing, decursing, resource tracking and buffing with optional support for SuperWow, ClassicAPI, UnitXP_SP3 and Nampower. ## Notes: Raidframe replacement for healing, decursing, resource tracking and buffing with optional support for SuperWow, ClassicAPI, UnitXP_SP3 and Nampower.
## SavedVariablesPerCharacter: HealBot_Config ## SavedVariablesPerCharacter: HealBot_Config
+25 -32
View File
@@ -166,17 +166,6 @@ 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,
}
local HealBot_DebuffTypeMap = nil local HealBot_DebuffTypeMap = nil
local HealBot_AuraWarningPlayed = {} local HealBot_AuraWarningPlayed = {}
@@ -190,6 +179,9 @@ function HealBot_OnEvent_UnitAura(this, unit)
[HEALBOT_POISON] = HEALBOT_POISON_en, [HEALBOT_POISON] = HEALBOT_POISON_en,
[HEALBOT_CURSE] = HEALBOT_CURSE_en [HEALBOT_CURSE] = HEALBOT_CURSE_en
} }
if HealBot_Init_TrackedAuras then
HealBot_Init_TrackedAuras()
end
end end
local DebuffType; local DebuffType;
@@ -280,13 +272,26 @@ function HealBot_OnEvent_UnitAura(this, unit)
local buff = UnitBuff(unit, b) local buff = UnitBuff(unit, b)
if not buff then break end if not buff then break end
activeBuffs[buff] = true activeBuffs[buff] = true
if HealBot_TrackedHoTs[buff] and iconCount < 10 then if HealBot_TrackedAura_Textures and HealBot_TrackedAura_Textures[buff] and iconCount < 10 then
iconCount = iconCount + 1 iconCount = iconCount + 1
HealBot_UnitIcons[unit][iconCount] = buff HealBot_UnitIcons[unit][iconCount] = buff
end end
b = b + 1 b = b + 1
end end
local d = 1
local activeDebuffs = HealBot_GetTable()
while true do
local debuff = UnitDebuff(unit, d)
if not debuff then break end
activeDebuffs[debuff] = true
if HealBot_TrackedAura_Textures and HealBot_TrackedAura_Textures[debuff] and iconCount < 10 then
iconCount = iconCount + 1
HealBot_UnitIcons[unit][iconCount] = debuff
end
d = d + 1
end
if HealBot_Integrations_Nampower_Active and HealBot_Nampower_Auras then if HealBot_Integrations_Nampower_Active and HealBot_Nampower_Auras then
local guid = HealBot_GetUnitGUID and HealBot_GetUnitGUID(unit) local guid = HealBot_GetUnitGUID and HealBot_GetUnitGUID(unit)
if guid then if guid then
@@ -294,33 +299,21 @@ function HealBot_OnEvent_UnitAura(this, unit)
HealBot_Nampower_NameCache[guid] = UnitName(unit) HealBot_Nampower_NameCache[guid] = UnitName(unit)
if HealBot_Nampower_Auras[guid] then if HealBot_Nampower_Auras[guid] then
local validHoTs = {
["Renew"] = "Interface\\Icons\\Spell_Holy_Renew",
["Rejuvenation"] = "Interface\\Icons\\Spell_Nature_Rejuvenation",
["Regrowth"] = "Interface\\Icons\\Spell_Nature_ResistNature",
["Power Word: Shield"] = "Interface\\Icons\\Spell_Holy_PowerWordShield",
}
for spellName, _ in pairs(HealBot_Nampower_Auras[guid]) do for spellName, _ in pairs(HealBot_Nampower_Auras[guid]) do
local tex = validHoTs[spellName] local auraInfo = HealBot_TrackedAura_Spells and HealBot_TrackedAura_Spells[spellName]
if tex and not activeBuffs[tex] then if auraInfo then
HealBot_Nampower_Auras[guid][spellName] = nil local tex = auraInfo.texture
local isActive = auraInfo.isDebuff and activeDebuffs[tex] or activeBuffs[tex]
if not isActive then
HealBot_Nampower_Auras[guid][spellName] = nil
end
end end
end end
end end
end end
end end
HealBot_ReleaseTable(activeBuffs) HealBot_ReleaseTable(activeBuffs)
HealBot_ReleaseTable(activeDebuffs)
local d = 1
while true do
local debuff = UnitDebuff(unit, d)
if not debuff then break end
if HealBot_TrackedHoTs[debuff] and iconCount < 10 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, 40) == 1 then if DebuffType and HealBot_Range_Check(unit, 40) == 1 then
+37 -1
View File
@@ -172,7 +172,19 @@ function HealBot_OnUpdate(this, arg1)
for unitID in pairs(powerToRefresh) do for unitID in pairs(powerToRefresh) do
HealBot_Action_RefreshPower(unitID) HealBot_Action_RefreshPower(unitID)
end end
-- Periodic resolution of units with missing class identity
if HealBot_Model and HealBot_Model.unresolvedUnits and next(HealBot_Model.unresolvedUnits) then
HealBot_UnresolvedTimer = (HealBot_UnresolvedTimer or 0) + arg1
if HealBot_UnresolvedTimer >= 0.5 then
HealBot_UnresolvedTimer = 0
for u in pairs(HealBot_Model.unresolvedUnits) do
if HealBot_Model:UpdateUnitIdentity(u) then
HealBot_View_DirtyUnits[u] = true
end
end
end
end
if HealBot_EquipChangeTimer > 0 then if HealBot_EquipChangeTimer > 0 then
HealBot_EquipChangeTimer = HealBot_EquipChangeTimer - arg1 HealBot_EquipChangeTimer = HealBot_EquipChangeTimer - arg1
if HealBot_EquipChangeTimer <= 0 then if HealBot_EquipChangeTimer <= 0 then
@@ -185,6 +197,28 @@ function HealBot_OnUpdate(this, arg1)
if HealBot_Config.HealBot_Integrations_ShowHoTTimers == 1 then if HealBot_Config.HealBot_Integrations_ShowHoTTimers == 1 then
if not HealBot_HoT_Update_Timer or GetTime() >= HealBot_HoT_Update_Timer then if not HealBot_HoT_Update_Timer or GetTime() >= HealBot_HoT_Update_Timer then
HealBot_HoT_Update_Timer = GetTime() + 0.25 HealBot_HoT_Update_Timer = GetTime() + 0.25
local displayMode = HealBot_Config.HealBot_Integrations_HoTTimerDisplayMode or 0
if displayMode == 1 then
-- Icon Overlay mode: dirty-flag units with active Nampower auras
if HealBot_Integrations_Nampower_Active and HealBot_Nampower_Auras then
local now = GetTime()
for guid, auras in pairs(HealBot_Nampower_Auras) do
local hasActive = false
for _, exp in pairs(auras) do
if exp > now then hasActive = true; break end
end
if hasActive then
local unitID = (HealBot_Model and HealBot_Model:GetUnitByGUID(guid))
if not unitID and HealBot_PlayerGUID and guid == HealBot_PlayerGUID then
unitID = "player"
end
if unitID and not string.find(unitID, "pet") then
HealBot_View_DirtyUnits[unitID] = true
end
end
end
end
end
if HealBot_Action_UpdatePlayerHoTs then if HealBot_Action_UpdatePlayerHoTs then
HealBot_Action_UpdatePlayerHoTs() HealBot_Action_UpdatePlayerHoTs()
end end
@@ -274,6 +308,7 @@ local HealBot_EventHandlers = {
HealBot_OnEvent_PlayerTargetChanged(this) HealBot_OnEvent_PlayerTargetChanged(this)
end, end,
["PARTY_MEMBERS_CHANGED"] = function(this) ["PARTY_MEMBERS_CHANGED"] = function(this)
HealBot_Model:RefreshUnit("player")
for _, unit in ipairs(HealBot_Model.partyMembers) do for _, unit in ipairs(HealBot_Model.partyMembers) do
HealBot_Model:RefreshUnit(unit) HealBot_Model:RefreshUnit(unit)
end end
@@ -284,6 +319,7 @@ local HealBot_EventHandlers = {
HealBot_OnEvent_PartyMembersChanged(this) HealBot_OnEvent_PartyMembersChanged(this)
end, end,
["RAID_ROSTER_UPDATE"] = function(this) ["RAID_ROSTER_UPDATE"] = function(this)
HealBot_Model:RefreshUnit("player")
for _, unit in ipairs(HealBot_Model.partyMembers) do for _, unit in ipairs(HealBot_Model.partyMembers) do
HealBot_Model:RefreshUnit(unit) HealBot_Model:RefreshUnit(unit)
end end
+1 -1
View File
@@ -33,7 +33,7 @@ function HealBot_Range_Check(unit, range)
return _rangeCache[range][unit] return _rangeCache[range][unit]
end end
if ( unit == "player" or string.find(unit, "^Test") ) then if ( unit and (unit == "player" or UnitIsUnit(unit, "player") or string.find(unit, "^Test")) ) then
return_val = 1; return_val = 1;
elseif HealBot_Integrations_ClassicAPI_Active and UnitDistanceSquared and UnitInLineOfSight then elseif HealBot_Integrations_ClassicAPI_Active and UnitDistanceSquared and UnitInLineOfSight then
local inSight = UnitInLineOfSight("player", unit) local inSight = UnitInLineOfSight("player", unit)
+35
View File
@@ -269,6 +269,8 @@ HealBot_ConfigDefaults = {
HealBot_Integrations_SuperWoW = 0, HealBot_Integrations_SuperWoW = 0,
HealBot_Integrations_ClassicAPI = 0, HealBot_Integrations_ClassicAPI = 0,
HealBot_Integrations_ShowHoTTimers = 0, HealBot_Integrations_ShowHoTTimers = 0,
HealBot_Integrations_HoTTimerPosition = "BELOW",
HealBot_Integrations_HoTTimerDisplayMode = 0,
}; };
HealBot_Config = {}; HealBot_Config = {};
@@ -603,3 +605,36 @@ function HealBot_ReleaseTable(t)
end end
end end
HealBot_TrackedAuras = {
["Renew"] = { texture = "Interface\\Icons\\Spell_Holy_Renew", isDebuff = false, showTimer = true, locKey = "HEALBOT_RENEW" },
["Rejuvenation"] = { texture = "Interface\\Icons\\Spell_Nature_Rejuvenation", isDebuff = false, showTimer = true, locKey = "HEALBOT_REJUVENATION" },
["Regrowth"] = { texture = "Interface\\Icons\\Spell_Nature_ResistNature", isDebuff = false, showTimer = true, locKey = "HEALBOT_REGROWTH" },
["Power Word: Shield"] = { texture = "Interface\\Icons\\Spell_Holy_PowerWordShield", isDebuff = false, showTimer = true, locKey = "HEALBOT_POWER_WORD_SHIELD" },
["Fear Ward"] = { texture = "Interface\\Icons\\Spell_Holy_Excorcism", isDebuff = false, showTimer = true, locKey = "HEALBOT_FEAR_WARD" },
["Abolish Disease"] = { texture = "Interface\\Icons\\Spell_Nature_NullifyDisease",isDebuff = false, showTimer = true, locKey = "HEALBOT_ABOLISH_DISEASE" },
["Abolish Poison"] = { texture = "Interface\\Icons\\Spell_Nature_NullifyPoison", isDebuff = false, showTimer = true, locKey = "HEALBOT_ABOLISH_POISON" },
["Weakened Soul"] = { texture = "Interface\\Icons\\Spell_Holy_AshesToAshes", isDebuff = true, showTimer = true, locKey = "HEALBOT_WEAKENED_SOUL" },
["Blessing of Protection"] = { texture = "Interface\\Icons\\Spell_Holy_SealOfProtection", isDebuff = false, showTimer = false },
["Holy Scriptures"] = { texture = "Interface\\Icons\\btnholyscriptures", isDebuff = false, showTimer = false },
};
HealBot_TrackedAura_Textures = {};
HealBot_TrackedAura_Spells = {};
function HealBot_Init_TrackedAuras()
for spell, info in pairs(HealBot_TrackedAuras) do
info.spell = spell
HealBot_TrackedAura_Textures[info.texture] = info
HealBot_TrackedAura_Spells[spell] = info
if info.locKey then
local locName = getglobal(info.locKey)
if locName and locName ~= "" then
info.locName = locName
HealBot_TrackedAura_Spells[locName] = info
end
end
end
end
HealBot_Init_TrackedAuras();
+3
View File
@@ -145,5 +145,8 @@ end
HealBot_Options_Integrations_ShowHoTTimers:SetChecked(0) HealBot_Options_Integrations_ShowHoTTimers:SetChecked(0)
HealBot_Config.HealBot_Integrations_ShowHoTTimers = 0 HealBot_Config.HealBot_Integrations_ShowHoTTimers = 0
end end
if HealBot_Options_Integrations_UpdateDropdownStates then
HealBot_Options_Integrations_UpdateDropdownStates()
end
end end
end end
+1
View File
@@ -154,6 +154,7 @@ HEALBOT_BUFF_REGROWTH = "Interface\\Icons\\Spell_Nature_ResistNature"
HEALBOT_BUFF_RENEW = "Interface\\Icons\\Spell_Holy_Renew"; HEALBOT_BUFF_RENEW = "Interface\\Icons\\Spell_Holy_Renew";
HEALBOT_BUFF_FEAR_WARD = "Interface\\Icons\\Spell_Holy_Excorcism"; HEALBOT_BUFF_FEAR_WARD = "Interface\\Icons\\Spell_Holy_Excorcism";
HEALBOT_DEBUFF_WEAKENED_SOUL = "Interface\\Icons\\Spell_Holy_AshesToAshes"; HEALBOT_DEBUFF_WEAKENED_SOUL = "Interface\\Icons\\Spell_Holy_AshesToAshes";
HEALBOT_WEAKENED_SOUL = "Geschw\195\164chte Seele";
HEALBOT_DEBUFF_RECENTLY_BANDAGED = "Interface\\Icons\\INV_Misc_Bandage_08"; HEALBOT_DEBUFF_RECENTLY_BANDAGED = "Interface\\Icons\\INV_Misc_Bandage_08";
+1
View File
@@ -171,6 +171,7 @@ HEALBOT_BUFF_REGROWTH = "Interface\\Icons\\Spell_Nature_ResistNature"
HEALBOT_BUFF_RENEW = "Interface\\Icons\\Spell_Holy_Renew"; HEALBOT_BUFF_RENEW = "Interface\\Icons\\Spell_Holy_Renew";
HEALBOT_BUFF_FEAR_WARD = "Interface\\Icons\\Spell_Holy_Excorcism"; HEALBOT_BUFF_FEAR_WARD = "Interface\\Icons\\Spell_Holy_Excorcism";
HEALBOT_DEBUFF_WEAKENED_SOUL = "Interface\\Icons\\Spell_Holy_AshesToAshes"; HEALBOT_DEBUFF_WEAKENED_SOUL = "Interface\\Icons\\Spell_Holy_AshesToAshes";
HEALBOT_WEAKENED_SOUL = "Weakened Soul";
HEALBOT_DEBUFF_RECENTLY_BANDAGED = "Interface\\Icons\\INV_Misc_Bandage_08"; HEALBOT_DEBUFF_RECENTLY_BANDAGED = "Interface\\Icons\\INV_Misc_Bandage_08";
+1
View File
@@ -72,6 +72,7 @@ HEALBOT_LESSER_HEAL = "Soins inf\195\169rieurs";
HEALBOT_LESSER_HEALING_WAVE = "Vague de soins mineurs"; HEALBOT_LESSER_HEALING_WAVE = "Vague de soins mineurs";
HEALBOT_MEND_PET = "Soigner un Familier"; HEALBOT_MEND_PET = "Soigner un Familier";
HEALBOT_POWER_WORD_SHIELD = "Mot de pouvoir : Bouclier"; HEALBOT_POWER_WORD_SHIELD = "Mot de pouvoir : Bouclier";
HEALBOT_WEAKENED_SOUL = "\195\130me affaiblie";
HEALBOT_REGROWTH = "R\195\169tablissement"; HEALBOT_REGROWTH = "R\195\169tablissement";
HEALBOT_RENEW = "R\195\169novation"; HEALBOT_RENEW = "R\195\169novation";
HEALBOT_REJUVENATION = "R\195\169cup\195\169ration"; HEALBOT_REJUVENATION = "R\195\169cup\195\169ration";
+1
View File
@@ -54,6 +54,7 @@ if (GetLocale() == "koKR") then
HEALBOT_LESSER_HEALING_WAVE = "하급 치유의 물결"; HEALBOT_LESSER_HEALING_WAVE = "하급 치유의 물결";
HEALBOT_MEND_PET = "동물 치료"; HEALBOT_MEND_PET = "동물 치료";
HEALBOT_POWER_WORD_SHIELD = "신의 권능: 보호막"; HEALBOT_POWER_WORD_SHIELD = "신의 권능: 보호막";
HEALBOT_WEAKENED_SOUL = "신체 취약";
HEALBOT_REGROWTH = "재생"; HEALBOT_REGROWTH = "재생";
HEALBOT_RENEW = "소생"; HEALBOT_RENEW = "소생";
HEALBOT_REJUVENATION = "회복"; HEALBOT_REJUVENATION = "회복";
+34 -1
View File
@@ -47,7 +47,10 @@ HealBot_Model = {
-- Integration maps -- Integration maps
unitGUIDs = {}, -- unit -> GUID unitGUIDs = {}, -- unit -> GUID
guidUnits = {} -- GUID -> unit guidUnits = {}, -- GUID -> unit
-- Delayed resolution queue
unresolvedUnits = {}
} }
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@@ -87,6 +90,7 @@ end
-- HealBot_Model:Initialize: Pre-allocates the unit state dictionary. -- HealBot_Model:Initialize: Pre-allocates the unit state dictionary.
function HealBot_Model:Initialize() function HealBot_Model:Initialize()
for k in pairs(self.unresolvedUnits) do self.unresolvedUnits[k] = nil end
self:InitUnitState("player") self:InitUnitState("player")
self:InitUnitState("target") self:InitUnitState("target")
self:InitUnitState("pet") self:InitUnitState("pet")
@@ -149,7 +153,36 @@ function HealBot_Model:UpdateUnitIdentity(unit)
local oldName = self.units[unit].name local oldName = self.units[unit].name
local oldEnglishClass = self.units[unit].englishClass local oldEnglishClass = self.units[unit].englishClass
local name = UnitName(unit) local name = UnitName(unit)
-- If UnitName is not ready, attempt raid roster fallback for raid units
if not name or name == "Unknown" then
local _, _, raidIdx = string.find(unit, "^raid(%d+)$")
if raidIdx and GetNumRaidMembers() > 0 then
local rName = GetRaidRosterInfo(tonumber(raidIdx))
if rName and rName ~= "" and rName ~= "Unknown" then
name = rName
end
end
end
-- If name is still nil, retain oldName if unit exists
if not name and oldName and UnitExists(unit) then
name = oldName
end
local englishClass = HealBot_UnitClass(unit) local englishClass = HealBot_UnitClass(unit)
-- If name is identical, do NOT overwrite an existing valid englishClass with nil
if oldName and name == oldName and not englishClass and oldEnglishClass then
englishClass = oldEnglishClass
end
-- Track unresolved units (unit exists with a name, but missing englishClass)
if name and not englishClass then
self.unresolvedUnits[unit] = true
else
self.unresolvedUnits[unit] = nil
end
if oldName ~= name or oldEnglishClass ~= englishClass then if oldName ~= name or oldEnglishClass ~= englishClass then
self.units[unit].name = name self.units[unit].name = name
+119
View File
@@ -1,3 +1,34 @@
-- HealBot_Options_Integrations.lua
local function HealBot_Options_SetDropDownState(frame, enabled)
if not frame then return end
local button = getglobal(frame:GetName() .. "Button")
local text = getglobal(frame:GetName() .. "Text")
if button then
if enabled then
button:Enable()
else
button:Disable()
end
end
if text then
if enabled then
text:SetTextColor(1, 1, 1)
else
text:SetTextColor(0.5, 0.5, 0.5)
end
end
end
-- Update enabled/disabled state of dropdowns based on current config
function HealBot_Options_Integrations_UpdateDropdownStates()
local timersEnabled = HealBot_Config.HealBot_Integrations_ShowHoTTimers == 1
local displayMode = HealBot_Config.HealBot_Integrations_HoTTimerDisplayMode or 0
HealBot_Options_SetDropDownState(HealBot_Options_Integrations_DisplayModeDropdown, timersEnabled)
HealBot_Options_SetDropDownState(HealBot_Options_Integrations_PositionDropdown, timersEnabled and (displayMode == 0))
end
-- HealBot_Options_Integrations_OnShow: UI handler for OnShow options panel. -- HealBot_Options_Integrations_OnShow: UI handler for OnShow options panel.
function HealBot_Options_Integrations_OnShow(this) function HealBot_Options_Integrations_OnShow(this)
HealBot_Options_Integrations_UnitXP:SetChecked(HealBot_Config.HealBot_Integrations_UnitXP); HealBot_Options_Integrations_UnitXP:SetChecked(HealBot_Config.HealBot_Integrations_UnitXP);
@@ -5,4 +36,92 @@ function HealBot_Options_Integrations_OnShow(this)
HealBot_Options_Integrations_SuperWoW:SetChecked(HealBot_Config.HealBot_Integrations_SuperWoW); HealBot_Options_Integrations_SuperWoW:SetChecked(HealBot_Config.HealBot_Integrations_SuperWoW);
HealBot_Options_Integrations_ClassicAPI:SetChecked(HealBot_Config.HealBot_Integrations_ClassicAPI); HealBot_Options_Integrations_ClassicAPI:SetChecked(HealBot_Config.HealBot_Integrations_ClassicAPI);
HealBot_Options_Integrations_ShowHoTTimers:SetChecked(HealBot_Config.HealBot_Integrations_ShowHoTTimers); HealBot_Options_Integrations_ShowHoTTimers:SetChecked(HealBot_Config.HealBot_Integrations_ShowHoTTimers);
-- Set display mode dropdown text
local displayMode = HealBot_Config.HealBot_Integrations_HoTTimerDisplayMode or 0
if displayMode == 1 then
UIDropDownMenu_SetText("Icon Overlay", HealBot_Options_Integrations_DisplayModeDropdown)
else
UIDropDownMenu_SetText("List", HealBot_Options_Integrations_DisplayModeDropdown)
end
-- Set position dropdown text
local pos = HealBot_Config.HealBot_Integrations_HoTTimerPosition or "BELOW"
local posLabels = { BELOW = "Below", ABOVE = "Above", LEFT = "Left", RIGHT = "Right" }
UIDropDownMenu_SetText(posLabels[pos] or "Below", HealBot_Options_Integrations_PositionDropdown)
-- Update enabled/disabled state
HealBot_Options_Integrations_UpdateDropdownStates()
end
-- Display Mode dropdown click handler (relying on global this)
function HealBot_Options_Integrations_DisplayModeDropdown_OnClick()
UIDropDownMenu_SetSelectedID(HealBot_Options_Integrations_DisplayModeDropdown, this:GetID())
HealBot_Config.HealBot_Integrations_HoTTimerDisplayMode = this.value
UIDropDownMenu_SetText(this:GetText(), HealBot_Options_Integrations_DisplayModeDropdown)
HealBot_Options_Integrations_UpdateDropdownStates()
if HealBot_Action_UnitButtons then
for u in pairs(HealBot_Action_UnitButtons) do
HealBot_View_DirtyUnits[u] = true
end
end
if HealBot_Action_UpdatePlayerHoTs then
HealBot_Action_UpdatePlayerHoTs()
end
end
-- Display Mode dropdown init
function HealBot_Options_Integrations_DisplayModeDropdown_Init()
local mode = HealBot_Config.HealBot_Integrations_HoTTimerDisplayMode or 0
local info
info = {}
info.text = "List"
info.value = 0
info.func = HealBot_Options_Integrations_DisplayModeDropdown_OnClick
if mode == 0 then
info.checked = 1
end
UIDropDownMenu_AddButton(info)
info = {}
info.text = "Icon Overlay"
info.value = 1
info.func = HealBot_Options_Integrations_DisplayModeDropdown_OnClick
if mode == 1 then
info.checked = 1
end
UIDropDownMenu_AddButton(info)
end
-- Position dropdown click handler (relying on global this)
function HealBot_Options_Integrations_PositionDropdown_OnClick()
UIDropDownMenu_SetSelectedID(HealBot_Options_Integrations_PositionDropdown, this:GetID())
HealBot_Config.HealBot_Integrations_HoTTimerPosition = this.value
UIDropDownMenu_SetText(this:GetText(), HealBot_Options_Integrations_PositionDropdown)
if HealBot_Action_UpdatePlayerHoTs then
HealBot_Action_UpdatePlayerHoTs()
end
end
-- Position dropdown init
function HealBot_Options_Integrations_PositionDropdown_Init()
local positions = {
{ value = "BELOW", label = "Below" },
{ value = "ABOVE", label = "Above" },
{ value = "LEFT", label = "Left" },
{ value = "RIGHT", label = "Right" },
}
local currentPos = HealBot_Config.HealBot_Integrations_HoTTimerPosition or "BELOW"
for _, p in ipairs(positions) do
local info = {}
info.text = p.label
info.value = p.value
info.func = HealBot_Options_Integrations_PositionDropdown_OnClick
if currentPos == p.value then
info.checked = 1
end
UIDropDownMenu_AddButton(info)
end
end end
+74 -2
View File
@@ -94,9 +94,81 @@
</OnLoad> </OnLoad>
<OnClick> <OnClick>
HealBot_Config.HealBot_Integrations_ShowHoTTimers = this:GetChecked() and 1 or 0; HealBot_Config.HealBot_Integrations_ShowHoTTimers = this:GetChecked() and 1 or 0;
HealBot_Options_Integrations_UpdateDropdownStates();
if HealBot_Action_UnitButtons then
for u in pairs(HealBot_Action_UnitButtons) do
HealBot_View_DirtyUnits[u] = true;
end
end
if HealBot_Action_UpdatePlayerHoTs then
HealBot_Action_UpdatePlayerHoTs();
end
</OnClick> </OnClick>
</Scripts> </Scripts>
</CheckButton> </CheckButton>
<!-- HoT Timer Display Mode Dropdown -->
<Frame name="HealBot_Options_Integrations_DisplayModeDropdown" inherits="UIDropDownMenuTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HealBot_Options_Integrations_ShowHoTTimers" relativePoint="BOTTOMLEFT">
<Offset>
<AbsDimension x="-15" y="-22"/>
</Offset>
</Anchor>
</Anchors>
<Layers>
<Layer level="ARTWORK">
<FontString name="HealBot_Options_Integrations_DisplayModeLabel" inherits="GameFontHighlightSmall" justifyH="LEFT" text="Timer Display Mode:">
<Anchors>
<Anchor point="BOTTOMLEFT" relativePoint="TOPLEFT">
<Offset>
<AbsDimension x="20" y="2"/>
</Offset>
</Anchor>
</Anchors>
<Color r="1" g="0.82" b="0"/>
</FontString>
</Layer>
</Layers>
<Scripts>
<OnLoad>
UIDropDownMenu_SetWidth(120, this);
UIDropDownMenu_Initialize(this, HealBot_Options_Integrations_DisplayModeDropdown_Init);
</OnLoad>
</Scripts>
</Frame>
<!-- HoT Timer Position Dropdown -->
<Frame name="HealBot_Options_Integrations_PositionDropdown" inherits="UIDropDownMenuTemplate">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="HealBot_Options_Integrations_DisplayModeDropdown" relativePoint="BOTTOMLEFT">
<Offset>
<AbsDimension x="0" y="-22"/>
</Offset>
</Anchor>
</Anchors>
<Layers>
<Layer level="ARTWORK">
<FontString name="HealBot_Options_Integrations_PositionLabel" inherits="GameFontHighlightSmall" justifyH="LEFT" text="Timer List Position:">
<Anchors>
<Anchor point="BOTTOMLEFT" relativePoint="TOPLEFT">
<Offset>
<AbsDimension x="20" y="2"/>
</Offset>
</Anchor>
</Anchors>
<Color r="1" g="0.82" b="0"/>
</FontString>
</Layer>
</Layers>
<Scripts>
<OnLoad>
UIDropDownMenu_SetWidth(120, this);
UIDropDownMenu_Initialize(this, HealBot_Options_Integrations_PositionDropdown_Init);
</OnLoad>
</Scripts>
</Frame>
<Frame setAllPoints="true"> <Frame setAllPoints="true">
<Layers> <Layers>
<Layer level="ARTWORK"> <Layer level="ARTWORK">
@@ -114,9 +186,9 @@
<FontString name="HealBot_Options_Integrations_HoTInfo" inherits="GameFontHighlightSmall" justifyH="LEFT" justifyV="TOP" text="Note: HoT Timers require Nampower to be enabled and active to provide accurate aura times."> <FontString name="HealBot_Options_Integrations_HoTInfo" inherits="GameFontHighlightSmall" justifyH="LEFT" justifyV="TOP" text="Note: HoT Timers require Nampower to be enabled and active to provide accurate aura times.">
<Size x="340" y="30"/> <Size x="340" y="30"/>
<Anchors> <Anchors>
<Anchor point="TOPLEFT" relativeTo="HealBot_Options_Integrations_ShowHoTTimers" relativePoint="BOTTOMLEFT"> <Anchor point="TOPLEFT" relativeTo="HealBot_Options_Integrations_PositionDropdown" relativePoint="BOTTOMLEFT">
<Offset> <Offset>
<AbsDimension x="20" y="-4"/> <AbsDimension x="20" y="-6"/>
</Offset> </Offset>
</Anchor> </Anchor>
</Anchors> </Anchors>
+129 -30
View File
@@ -69,10 +69,20 @@ function HealBot_HealthColor(unit, hlth, maxhlth)
end end
local colorMode = HealBot_Config.bcolormode[HealBot_Config.Current_Skin] or 1 local colorMode = HealBot_Config.bcolormode[HealBot_Config.Current_Skin] or 1
local engClass = nil
if colorMode == 2 and not string.find(unit, "pet") then
engClass = HealBot_Model and HealBot_Model.units[unit] and HealBot_Model.units[unit].englishClass
if not engClass then
engClass = HealBot_UnitClass(unit)
if engClass and HealBot_Model and HealBot_Model.units[unit] then
HealBot_Model.units[unit].englishClass = engClass
end
end
end
if colorMode == 2 and string.find(unit, "pet") then if colorMode == 2 and string.find(unit, "pet") then
r, g, b = 0.4, 0.9, 0.6 -- Mint color r, g, b = 0.4, 0.9, 0.6 -- Mint color
elseif colorMode == 2 and HealBot_Model and HealBot_Model.units[unit] and HealBot_Model.units[unit].englishClass and RAID_CLASS_COLORS and RAID_CLASS_COLORS[HealBot_Model.units[unit].englishClass] then elseif colorMode == 2 and engClass and RAID_CLASS_COLORS and RAID_CLASS_COLORS[engClass] then
local engClass = HealBot_Model.units[unit].englishClass
r = RAID_CLASS_COLORS[engClass].r r = RAID_CLASS_COLORS[engClass].r
g = RAID_CLASS_COLORS[engClass].g g = RAID_CLASS_COLORS[engClass].g
b = RAID_CLASS_COLORS[engClass].b b = RAID_CLASS_COLORS[engClass].b
@@ -273,6 +283,10 @@ function HealBot_Action_EnableButton(button)
end end
local iconSize = HealBot_Config.biconsize[HealBot_Config.Current_Skin] or 12 local iconSize = HealBot_Config.biconsize[HealBot_Config.Current_Skin] or 12
local isPet = string.find(unit, "pet") ~= nil
local overlayMode = (HealBot_Config.HealBot_Integrations_ShowHoTTimers == 1) and ((HealBot_Config.HealBot_Integrations_HoTTimerDisplayMode or 0) == 1) and not isPet
local unitGUID = overlayMode and ((HealBot_GetUnitGUID and HealBot_GetUnitGUID(unit)) or (unit == "player" and HealBot_PlayerGUID))
local currentTime = overlayMode and GetTime()
for i = 1, 10 do for i = 1, 10 do
local icon = button["icon"..i] local icon = button["icon"..i]
if not icon then if not icon then
@@ -295,10 +309,54 @@ function HealBot_Action_EnableButton(button)
if not icon:IsVisible() then if not icon:IsVisible() then
icon:Show() icon:Show()
end end
-- Icon overlay timer text
local iconText = button["iconText"..i]
if not iconText then
iconText = button:CreateFontString(nil, "OVERLAY")
iconText:SetFont("Fonts\\ARIALN.TTF", 10, "OUTLINE")
iconText:SetPoint("CENTER", icon, "CENTER", 0, 0)
iconText:SetTextColor(1, 1, 1, 1)
button["iconText"..i] = iconText
end
if overlayMode and unitGUID and HealBot_Nampower_Auras and HealBot_Nampower_Auras[unitGUID] then
local texturePath = HealBot_UnitIcons[unit][i]
local auraInfo = HealBot_TrackedAura_Textures and HealBot_TrackedAura_Textures[texturePath]
if auraInfo and auraInfo.showTimer then
local expiration = (auraInfo.locName and HealBot_Nampower_Auras[unitGUID][auraInfo.locName])
or (auraInfo.spell and HealBot_Nampower_Auras[unitGUID][auraInfo.spell])
if not expiration and HealBot_TrackedAura_Spells then
for spellName, spInfo in pairs(HealBot_TrackedAura_Spells) do
if spInfo.texture == texturePath and spInfo.showTimer then
expiration = HealBot_Nampower_Auras[unitGUID][spellName]
if expiration then break end
end
end
end
if expiration and expiration > currentTime then
local timeLeft = math.floor(expiration - currentTime)
iconText:SetText(timeLeft)
iconText:Show()
else
iconText:SetText("")
iconText:Hide()
end
else
iconText:SetText("")
iconText:Hide()
end
else
iconText:SetText("")
iconText:Hide()
end
else else
if icon:IsVisible() then if icon:IsVisible() then
icon:Hide() icon:Hide()
end end
local iconText = button["iconText"..i]
if iconText and iconText:IsVisible() then
iconText:Hide()
end
end end
end end
end end
@@ -845,14 +903,15 @@ function HealBot_Action_PartyChanged()
if GetNumRaidMembers() > 0 then if GetNumRaidMembers() > 0 then
for j = 1, 40 do for j = 1, 40 do
local unit = "raid" .. j; local unit = "raid" .. j;
local Class = UnitClass(unit);
local ProcessUnit = 0;
local PossibleEmerg = 1;
local name, rank, subgroup, level, class, fileName, zone, online, isDead = GetRaidRosterInfo(j); local name, rank, subgroup, level, class, fileName, zone, online, isDead = GetRaidRosterInfo(j);
if not name then name = "not known" end if not name then name = "not known" end
if not class then class = "not known" end if not class then class = "not known" end
if not subgroup then subgroup = "not known" end if not subgroup then subgroup = "not known" end
local Class = UnitClass(unit) or class;
local ProcessUnit = 0;
local PossibleEmerg = 1;
if HealBot_EmergInc[Class] == 1 then if HealBot_EmergInc[Class] == 1 then
ProcessUnit = 1; ProcessUnit = 1;
end end
@@ -1361,12 +1420,7 @@ end
local HealBot_PlayerHoTsListFrame = nil local HealBot_PlayerHoTsListFrame = nil
local HealBot_PlayerHoTFrames = {} local HealBot_PlayerHoTFrames = {}
local HealBot_PlayerHoTs_ValidHoTs = {
["Renew"] = "Interface\\Icons\\Spell_Holy_Renew",
["Rejuvenation"] = "Interface\\Icons\\Spell_Nature_Rejuvenation",
["Regrowth"] = "Interface\\Icons\\Spell_Nature_ResistNature",
["Power Word: Shield"] = "Interface\\Icons\\Spell_Holy_PowerWordShield",
}
local HealBot_PlayerHoTs_ListCache = {} local HealBot_PlayerHoTs_ListCache = {}
@@ -1374,22 +1428,65 @@ local function HealBot_PlayerHoTs_SortComparator(a, b)
return (a.expires or 0) < (b.expires or 0) return (a.expires or 0) < (b.expires or 0)
end end
-- Reposition the HoT timer list frame based on config
local function HealBot_HoTTimerList_Reanchor()
if not HealBot_PlayerHoTsListFrame then return end
local pos = HealBot_Config.HealBot_Integrations_HoTTimerPosition or "BELOW"
HealBot_PlayerHoTsListFrame:ClearAllPoints()
if pos == "ABOVE" then
HealBot_PlayerHoTsListFrame:SetPoint("BOTTOMLEFT", HealBot_Action, "TOPLEFT", 0, 2)
elseif pos == "RIGHT" then
HealBot_PlayerHoTsListFrame:SetPoint("TOPLEFT", HealBot_Action, "TOPRIGHT", 2, 0)
elseif pos == "LEFT" then
HealBot_PlayerHoTsListFrame:SetPoint("TOPRIGHT", HealBot_Action, "TOPLEFT", -2, 0)
else -- BELOW (default)
HealBot_PlayerHoTsListFrame:SetPoint("TOPLEFT", HealBot_Action, "BOTTOMLEFT", 0, -2)
end
end
-- Reposition child HoT frames for stacking direction
local function HealBot_HoTTimerList_StackChild(frame, index)
local pos = HealBot_Config.HealBot_Integrations_HoTTimerPosition or "BELOW"
frame:ClearAllPoints()
if pos == "ABOVE" then
if index == 1 then
frame:SetPoint("BOTTOMLEFT", HealBot_PlayerHoTsListFrame, "BOTTOMLEFT", 0, 0)
else
frame:SetPoint("BOTTOMLEFT", HealBot_PlayerHoTFrames[index-1], "TOPLEFT", 0, 2)
end
else
if index == 1 then
frame:SetPoint("TOPLEFT", HealBot_PlayerHoTsListFrame, "TOPLEFT", 0, 0)
else
frame:SetPoint("TOPLEFT", HealBot_PlayerHoTFrames[index-1], "BOTTOMLEFT", 0, -2)
end
end
end
function HealBot_Action_UpdatePlayerHoTs() function HealBot_Action_UpdatePlayerHoTs()
if not HealBot_PlayerHoTsListFrame then if not HealBot_PlayerHoTsListFrame then
HealBot_PlayerHoTsListFrame = CreateFrame("Frame", "HealBot_PlayerHoTsListFrame", HealBot_Action) HealBot_PlayerHoTsListFrame = CreateFrame("Frame", "HealBot_PlayerHoTsListFrame", HealBot_Action)
HealBot_PlayerHoTsListFrame:SetWidth(128) HealBot_PlayerHoTsListFrame:SetWidth(128)
HealBot_PlayerHoTsListFrame:SetHeight(1) HealBot_PlayerHoTsListFrame:SetHeight(1)
HealBot_PlayerHoTsListFrame:SetPoint("TOPLEFT", HealBot_Action, "BOTTOMLEFT", 0, -2)
HealBot_PlayerHoTsListFrame:Show() HealBot_PlayerHoTsListFrame:Show()
end end
HealBot_HoTTimerList_Reanchor()
if HealBot_Config.HealBot_Integrations_ShowHoTTimers ~= 1 then if HealBot_Config.HealBot_Integrations_ShowHoTTimers ~= 1 then
HealBot_PlayerHoTsListFrame:Hide() HealBot_PlayerHoTsListFrame:Hide()
return return
else
HealBot_PlayerHoTsListFrame:Show()
end end
-- If display mode is Icon Overlay, hide the list and return
local displayMode = HealBot_Config.HealBot_Integrations_HoTTimerDisplayMode or 0
if displayMode == 1 then
HealBot_PlayerHoTsListFrame:Hide()
return
end
HealBot_PlayerHoTsListFrame:Show()
local currentTime = GetTime() local currentTime = GetTime()
-- Clear cache instead of reallocating -- Clear cache instead of reallocating
@@ -1397,16 +1494,20 @@ function HealBot_Action_UpdatePlayerHoTs()
if HealBot_Integrations_Nampower_Active and HealBot_Nampower_Auras then if HealBot_Integrations_Nampower_Active and HealBot_Nampower_Auras then
for targetName, auras in pairs(HealBot_Nampower_Auras) do for targetName, auras in pairs(HealBot_Nampower_Auras) do
for spellName, expiration in pairs(auras) do local unitID = HealBot_Model:GetUnitByGUID(targetName) or HealBot_Model:GetUnitIDByName(targetName)
if HealBot_PlayerHoTs_ValidHoTs[spellName] then if not (unitID and string.find(unitID, "pet")) then
if expiration > currentTime then for spellName, expiration in pairs(auras) do
numHoTs = numHoTs + 1 local auraInfo = HealBot_TrackedAura_Spells and HealBot_TrackedAura_Spells[spellName]
if not HealBot_PlayerHoTs_ListCache[numHoTs] then if auraInfo and auraInfo.showTimer then
HealBot_PlayerHoTs_ListCache[numHoTs] = {} if expiration > currentTime then
numHoTs = numHoTs + 1
if not HealBot_PlayerHoTs_ListCache[numHoTs] then
HealBot_PlayerHoTs_ListCache[numHoTs] = {}
end
HealBot_PlayerHoTs_ListCache[numHoTs].name = targetName
HealBot_PlayerHoTs_ListCache[numHoTs].spell = spellName
HealBot_PlayerHoTs_ListCache[numHoTs].expires = expiration
end end
HealBot_PlayerHoTs_ListCache[numHoTs].name = targetName
HealBot_PlayerHoTs_ListCache[numHoTs].spell = spellName
HealBot_PlayerHoTs_ListCache[numHoTs].expires = expiration
end end
end end
end end
@@ -1428,11 +1529,6 @@ function HealBot_Action_UpdatePlayerHoTs()
frame = CreateFrame("Frame", "HealBot_PlayerHoT" .. i, HealBot_PlayerHoTsListFrame) frame = CreateFrame("Frame", "HealBot_PlayerHoT" .. i, HealBot_PlayerHoTsListFrame)
frame:SetWidth(128) frame:SetWidth(128)
frame:SetHeight(16) frame:SetHeight(16)
if i == 1 then
frame:SetPoint("TOPLEFT", HealBot_PlayerHoTsListFrame, "TOPLEFT", 0, 0)
else
frame:SetPoint("TOPLEFT", HealBot_PlayerHoTFrames[i-1], "BOTTOMLEFT", 0, -2)
end
local icon = frame:CreateTexture(nil, "ARTWORK") local icon = frame:CreateTexture(nil, "ARTWORK")
icon:SetWidth(14) icon:SetWidth(14)
@@ -1447,6 +1543,9 @@ function HealBot_Action_UpdatePlayerHoTs()
HealBot_PlayerHoTFrames[i] = frame HealBot_PlayerHoTFrames[i] = frame
end end
-- Reposition child for stacking direction
HealBot_HoTTimerList_StackChild(frame, i)
local hot = HealBot_PlayerHoTs_ListCache[i] local hot = HealBot_PlayerHoTs_ListCache[i]
local timeLeft = math.floor(hot.expires - currentTime) local timeLeft = math.floor(hot.expires - currentTime)
@@ -1493,7 +1592,7 @@ function HealBot_Action_UpdatePlayerHoTs()
end end
local spellId = HealBot_GetSpellId and HealBot_GetSpellId(hot.spell) or nil local spellId = HealBot_GetSpellId and HealBot_GetSpellId(hot.spell) or nil
local tex = HealBot_PlayerHoTs_ValidHoTs[hot.spell] or "Interface\\Icons\\INV_Misc_QuestionMark" local tex = (HealBot_TrackedAura_Spells and HealBot_TrackedAura_Spells[hot.spell] and HealBot_TrackedAura_Spells[hot.spell].texture) or "Interface\\Icons\\INV_Misc_QuestionMark"
if spellId then if spellId then
tex = GetSpellTexture(spellId, "BOOKTYPE_SPELL") or tex tex = GetSpellTexture(spellId, "BOOKTYPE_SPELL") or tex
end end
+6
View File
@@ -50,6 +50,10 @@ Default installation path: `C:\Program Files\World of Warcraft\Interface\AddOns\
### Change Log ### Change Log
**v1.7.6**
* **Feature - HoT Timer Position & Icon Overlay Display Modes** - Added configurable HoT Timer list position dropdown (`Below`, `Above`, `Left`, `Right`) relative to raid frames. Added alternative `Icon Overlay` display mode rendering countdown numbers directly on unit bar HoT icons. Excluded pets from timer lists and overlay numbers. Optimized expiration lookup with O(1) cached texture-to-spell mappings.
* **Refactor & Feature - Unified Aura & HoT Tracking** - Unified bar icons and HoT timers into a single master dictionary (`HealBot_TrackedAuras`) in `HealBot_Data.lua`. Added Weakened Soul, Fear Ward, Abolish Disease, and Abolish Poison to active timer bars with localized client support and debuff-aware pruning.
**v1.7.5** **v1.7.5**
* **Feature - Test Bars** - Implemented a "Test Bars" button and slider in the Skins options tab, allowing you to spawn and adjust a dummy raid group of up to 40 members without being in a real raid. This allows for easy layout and appearance customization out of combat. * **Feature - Test Bars** - Implemented a "Test Bars" button and slider in the Skins options tab, allowing you to spawn and adjust a dummy raid group of up to 40 members without being in a real raid. This allows for easy layout and appearance customization out of combat.
* **UI - Skins Options & Custom Health Gradients** - Added configurable Max HP and Min HP colour pickers with descriptive labels for custom gradient support. Fixed colour picker button click interceptors and hooked ColorPickerFrame callbacks. Integrated global font selector across raid frame text, headers, Options button, and preview bars. Reorganized Skins tab layout to anchor Test Bars cleanly in Column 2. * **UI - Skins Options & Custom Health Gradients** - Added configurable Max HP and Min HP colour pickers with descriptive labels for custom gradient support. Fixed colour picker button click interceptors and hooked ColorPickerFrame callbacks. Integrated global font selector across raid frame text, headers, Options button, and preview bars. Reorganized Skins tab layout to anchor Test Bars cleanly in Column 2.
@@ -102,6 +106,8 @@ Default installation path: `C:\Program Files\World of Warcraft\Interface\AddOns\
* **Feature - Shapeshift Spell Queue** - Built a native spell queue system for Druid auto-unshifting. Bypasses the "Cannot cast while shapeshifted" error and server lag when AutoUnshift is enabled, firing the heal seamlessly the exact millisecond the form is dropped. Now completely unified to use the standard casting API for maximum reliability across all client setups. * **Feature - Shapeshift Spell Queue** - Built a native spell queue system for Druid auto-unshifting. Bypasses the "Cannot cast while shapeshifted" error and server lag when AutoUnshift is enabled, firing the heal seamlessly the exact millisecond the form is dropped. Now completely unified to use the standard casting API for maximum reliability across all client setups.
* **Bug Fix - CDC Config List** - Fixed an uninitialized dropdown list array that prevented the CDC class monitor configuration from saving correctly. * **Bug Fix - CDC Config List** - Fixed an uninitialized dropdown list array that prevented the CDC class monitor configuration from saving correctly.
* **Bug Fix - Color Picker Accuracy** - Removed an undocumented multiplier hack on default textures that was artificially brightening debuff bar colors and overriding the user's selected colors from the color picker. * **Bug Fix - Color Picker Accuracy** - Removed an undocumented multiplier hack on default textures that was artificially brightening debuff bar colors and overriding the user's selected colors from the color picker.
* **Bug Fix - Raid Self-Range & Transparency** - Fixed player health bar appearing transparent in raid instances by checking `UnitIsUnit(unit, "player")` in range detection, preventing false out-of-range failures when player is represented by a `raidX` token.
* **Bug Fix - Raid Class Coloring & Identity Cache** - Fixed missing and delayed raid class colors by querying authoritative server data (`GetRaidRosterInfo`) for raid members, preventing model identity cache wipes, adding a throttled resolution retry in `OnUpdate`, and providing on-demand class color fallbacks in `HealBot_HealthColor`.
**v1.6.5** **v1.6.5**
* **Performance Update - Mana Tracking** - Added a fast-path redraw pipeline for unit power changes. This optimization prevents full frame redraws when players naturally regenerate or consume mana, resolving severe FPS drops in 40-man raids while tracking mana. * **Performance Update - Mana Tracking** - Added a fast-path redraw pipeline for unit power changes. This optimization prevents full frame redraws when players naturally regenerate or consume mana, resolving severe FPS drops in 40-man raids while tracking mana.