fix: resolve raid class coloring, identity cache, and player range detection issues

This commit is contained in:
Bluewhale1337
2026-10-14 17:55:30 +02:00
parent d949b7489a
commit aea1f734ca
6 changed files with 118 additions and 21 deletions
+50 -13
View File
@@ -203,22 +203,59 @@ end
-- 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.
function HealBot_UnitClass(unit)
local locClass, enClass = UnitClass(unit)
if enClass then return string.upper(enClass) end
-- Fallback for Vanilla 1.12 where enClass is nil
if locClass == HEALBOT_DRUID then return "DRUID"
elseif locClass == HEALBOT_HUNTER then return "HUNTER"
elseif locClass == HEALBOT_MAGE then return "MAGE"
elseif locClass == HEALBOT_PALADIN then return "PALADIN"
elseif locClass == HEALBOT_PRIEST then return "PRIEST"
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"
if not unit then return nil end
if not HealBot_ClassMap then HealBot_InitClassMap() end
-- 1. If player self, query "player" directly
if unit == "player" or UnitIsUnit(unit, "player") then
local locClass, enClass = UnitClass("player")
if enClass and enClass ~= "" then return string.upper(enClass) end
if locClass and HealBot_ClassMap[locClass] then return HealBot_ClassMap[locClass] end
if locClass then return string.upper(locClass) 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
end
+15 -1
View File
@@ -172,7 +172,19 @@ function HealBot_OnUpdate(this, arg1)
for unitID in pairs(powerToRefresh) do
HealBot_Action_RefreshPower(unitID)
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
HealBot_EquipChangeTimer = HealBot_EquipChangeTimer - arg1
if HealBot_EquipChangeTimer <= 0 then
@@ -274,6 +286,7 @@ local HealBot_EventHandlers = {
HealBot_OnEvent_PlayerTargetChanged(this)
end,
["PARTY_MEMBERS_CHANGED"] = function(this)
HealBot_Model:RefreshUnit("player")
for _, unit in ipairs(HealBot_Model.partyMembers) do
HealBot_Model:RefreshUnit(unit)
end
@@ -284,6 +297,7 @@ local HealBot_EventHandlers = {
HealBot_OnEvent_PartyMembersChanged(this)
end,
["RAID_ROSTER_UPDATE"] = function(this)
HealBot_Model:RefreshUnit("player")
for _, unit in ipairs(HealBot_Model.partyMembers) do
HealBot_Model:RefreshUnit(unit)
end
+1 -1
View File
@@ -33,7 +33,7 @@ function HealBot_Range_Check(unit, range)
return _rangeCache[range][unit]
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;
elseif HealBot_Integrations_ClassicAPI_Active and UnitDistanceSquared and UnitInLineOfSight then
local inSight = UnitInLineOfSight("player", unit)
+34 -1
View File
@@ -47,7 +47,10 @@ HealBot_Model = {
-- Integration maps
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.
function HealBot_Model:Initialize()
for k in pairs(self.unresolvedUnits) do self.unresolvedUnits[k] = nil end
self:InitUnitState("player")
self:InitUnitState("target")
self:InitUnitState("pet")
@@ -149,7 +153,36 @@ function HealBot_Model:UpdateUnitIdentity(unit)
local oldName = self.units[unit].name
local oldEnglishClass = self.units[unit].englishClass
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)
-- 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
self.units[unit].name = name
+16 -5
View File
@@ -69,10 +69,20 @@ function HealBot_HealthColor(unit, hlth, maxhlth)
end
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
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
local engClass = HealBot_Model.units[unit].englishClass
elseif colorMode == 2 and engClass and RAID_CLASS_COLORS and RAID_CLASS_COLORS[engClass] then
r = RAID_CLASS_COLORS[engClass].r
g = RAID_CLASS_COLORS[engClass].g
b = RAID_CLASS_COLORS[engClass].b
@@ -845,14 +855,15 @@ function HealBot_Action_PartyChanged()
if GetNumRaidMembers() > 0 then
for j = 1, 40 do
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);
if not name then name = "not known" end
if not class then class = "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
ProcessUnit = 1;
end
+2
View File
@@ -102,6 +102,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.
* **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 - 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**
* **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.