You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

956 lines
28 KiB

local sIsRestoredAfterDc = false;
VUHDO_IN_COMBAT_RELOG = false;
VUHDO_DEBUG = { };
VUHDO_RAID = { };
local VUHDO_RAID;
VUHDO_RAID_NAMES = { };
local VUHDO_RAID_NAMES = VUHDO_RAID_NAMES;
VUHDO_GROUPS = { };
local VUHDO_GROUPS = VUHDO_GROUPS;
VUHDO_RAID_GUIDS = { };
local VUHDO_RAID_GUIDS = VUHDO_RAID_GUIDS;
VUHDO_EMERGENCIES = { };
local VUHDO_EMERGENCIES = VUHDO_EMERGENCIES;
VUHDO_CLUSTER_BASE_RAID = { };
local VUHDO_CLUSTER_BASE_RAID = VUHDO_CLUSTER_BASE_RAID;
VUHDO_PLAYER_TARGETS = { };
local VUHDO_IS_SUSPICIOUS_ROSTER = false;
local VUHDO_RAID_SORTED = { };
local VUHDO_MAINTANKS = { };
local VUHDO_INTERNAL_TOGGLES = { };
local VUHDO_PANEL_UNITS = { };
setmetatable(VUHDO_PANEL_UNITS, VUHDO_META_NEW_ARRAY);
-- TODO: make local
VUHDO_BOSS_UNITS = { };
local VUHDO_MAX_BOSS_FRAMES = 8;
for i = 1, VUHDO_MAX_BOSS_FRAMES do -- FIXME: Blizzard forgot to update the MAX_BOSS_FRAMES constant for 9.2
local bossUnitId = format("boss%d", i);
VUHDO_BOSS_UNITS[bossUnitId] = true;
end
VUHDO_PLAYER_CLASS = nil;
VUHDO_PLAYER_NAME = nil;
VUHDO_PLAYER_RAID_ID = nil;
VUHDO_PLAYER_GROUP = nil;
-- Backdrops
BACKDROP_VUHDO_TOOLTIP = {
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true,
tileSize = 8,
edgeSize = 8,
insets = { left = 3, right = 3, top = 3, bottom = 3 },
};
-- BURST CACHE ---------------------------------------------------
local VUHDO_CONFIG;
local VUHDO_PET_2_OWNER;
local VUHDO_OWNER_2_PET;
local VUHDO_getUnitIds;
local VUHDO_getUnitNo;
local VUHDO_isInRange;
local VUHDO_determineDebuff;
local VUHDO_getUnitGroup;
local VUHDO_tableUniqueAdd;
local VUHDO_getTargetUnit;
local VUHDO_updateHealthBarsFor;
local VUHDO_trimInspected;
local VUHDO_getPlayerRaidUnit;
local VUHDO_getModelType;
local VUHDO_isConfigDemoUsers;
local VUHDO_updateBouquetsForEvent;
local VUHDO_resetClusterCoordDeltas;
local VUHDO_getUnitZoneName;
local VUHDO_isModelInPanel;
local VUHDO_isAltPowerActive;
local VUHDO_isModelConfigured;
local VUHDO_determineRole;
local VUHDO_getUnitHealthPercent;
local VUHDO_isUnitInModel;
local VUHDO_isUnitInModelIterative;
local VUHDO_isUnitInPanel;
local VUHDO_initDynamicPanelModels;
local VUHDO_updateBuffRaidGroup;
local GetRaidTargetIndex = GetRaidTargetIndex;
local UnitIsDeadOrGhost = UnitIsDeadOrGhost;
local UnitIsFeignDeath = UnitIsFeignDeath;
local UnitExists = UnitExists;
local UnitHealth = UnitHealth;
-- Disable local alias so function can be overloaded by Velhari Health Fix addon
--local UnitHealthMax = UnitHealthMax;
local string = string;
local UnitIsAFK = UnitIsAFK;
local UnitIsConnected = UnitIsConnected;
local UnitIsCharmed = UnitIsCharmed;
local UnitInRaid = UnitInRaid;
local UnitHasVehicleUI = UnitHasVehicleUI;
local UnitTargetsVehicleInRaidUI = UnitTargetsVehicleInRaidUI;
local UnitCanAttack = UnitCanAttack;
local GetNumGroupMembers = GetNumGroupMembers;
local UnitName = UnitName;
local UnitPower = UnitPower;
local UnitPowerMax = UnitPowerMax;
local UnitThreatSituation = UnitThreatSituation;
local UnitClass = UnitClass;
local UnitPowerType = UnitPowerType;
local UnitHasVehicleUI = UnitHasVehicleUI;
local UnitGroupRolesAssigned = UnitGroupRolesAssigned;
local GetRaidRosterInfo = GetRaidRosterInfo;
local InCombatLockdown = InCombatLockdown;
local IsInRaid = IsInRaid;
local table = table;
local UnitGUID = UnitGUID;
local tinsert = tinsert;
local tremove = tremove;
local strfind = strfind;
--local VUHDO_PANEL_MODELS;
local GetTime = GetTime;
local pairs = pairs;
local ipairs = ipairs;
local twipe = table.wipe;
local tsort = table.sort;
local _;
local sTrigger;
local sCurrentMode;
function VUHDO_vuhdoInitLocalOverrides()
VUHDO_CONFIG = _G["VUHDO_CONFIG"];
VUHDO_RAID = _G["VUHDO_RAID"];
VUHDO_PET_2_OWNER = _G["VUHDO_PET_2_OWNER"];
VUHDO_OWNER_2_PET = _G["VUHDO_OWNER_2_PET"];
VUHDO_getUnitIds = _G["VUHDO_getUnitIds"];
VUHDO_getUnitNo = _G["VUHDO_getUnitNo"];
VUHDO_isInRange = _G["VUHDO_isInRange"];
VUHDO_determineDebuff = _G["VUHDO_determineDebuff"];
VUHDO_getUnitGroup = _G["VUHDO_getUnitGroup"];
VUHDO_updateHealthBarsFor = _G["VUHDO_updateHealthBarsFor"];
VUHDO_tableUniqueAdd = _G["VUHDO_tableUniqueAdd"];
VUHDO_trimInspected = _G["VUHDO_trimInspected"];
VUHDO_getTargetUnit = _G["VUHDO_getTargetUnit"];
VUHDO_getModelType = _G["VUHDO_getModelType"];
VUHDO_isModelInPanel = _G["VUHDO_isModelInPanel"];
VUHDO_isAltPowerActive = _G["VUHDO_isAltPowerActive"];
VUHDO_getPlayerRaidUnit = _G["VUHDO_getPlayerRaidUnit"];
VUHDO_isModelConfigured = _G["VUHDO_isModelConfigured"];
VUHDO_isUnitInModel = _G["VUHDO_isUnitInModel"];
VUHDO_isUnitInModelIterative = _G["VUHDO_isUnitInModelIterative"];
VUHDO_isUnitInPanel = _G["VUHDO_isUnitInPanel"];
VUHDO_initDynamicPanelModels = _G["VUHDO_initDynamicPanelModels"];
VUHDO_updateBuffRaidGroup = _G["VUHDO_updateBuffRaidGroup"];
--VUHDO_PANEL_MODELS = _G["VUHDO_PANEL_MODELS"];
VUHDO_determineRole = _G["VUHDO_determineRole"];
VUHDO_getUnitHealthPercent = _G["VUHDO_getUnitHealthPercent"];
VUHDO_isConfigDemoUsers = _G["VUHDO_isConfigDemoUsers"];
VUHDO_updateBouquetsForEvent = _G["VUHDO_updateBouquetsForEvent"];
VUHDO_resetClusterCoordDeltas = _G["VUHDO_resetClusterCoordDeltas"];
VUHDO_getUnitZoneName = _G["VUHDO_getUnitZoneName"];
VUHDO_INTERNAL_TOGGLES = _G["VUHDO_INTERNAL_TOGGLES"];
VUHDO_PANEL_UNITS = _G["VUHDO_PANEL_UNITS"];
sTrigger = VUHDO_CONFIG["EMERGENCY_TRIGGER"];
sCurrentMode = VUHDO_CONFIG["MODE"];
VUHDO_DEFAULT_PROFILE = _G["VUHDO_DEFAULT_PROFILE"];
VUHDO_DEFAULT_LAYOUT = _G["VUHDO_DEFAULT_LAYOUT"];
end
----------------------------------------------------
local VUHDO_UNIT_AFK_DC = { };
--
local function VUHDO_updateAllRaidNames()
twipe(VUHDO_RAID_NAMES);
for tUnit, tInfo in pairs(VUHDO_RAID) do
if not VUHDO_isSpecialUnit(tUnit) then
-- ensure not to overwrite a player name with a pet's identical name
if not VUHDO_RAID_NAMES[tInfo["name"]] or not tInfo["isPet"] then
VUHDO_RAID_NAMES[tInfo["name"]] = tUnit;
end
end
end
end
--
local function VUHDO_isValidEmergency(anInfo)
return not anInfo["isPet"] and anInfo["range"] and not anInfo["dead"]
and anInfo["connected"] and not anInfo["charmed"];
end
--
local function VUHDO_setTopEmergencies(aMaxAnz)
twipe(VUHDO_EMERGENCIES);
for tIndex, tUnit in ipairs(VUHDO_RAID_SORTED) do
VUHDO_EMERGENCIES[tUnit] = tIndex;
if tIndex == aMaxAnz then return; end
end
end
--
local VUHDO_EMERGENCY_SORTERS = {
[VUHDO_MODE_EMERGENCY_MOST_MISSING]
= function(aUnit, anotherUnit)
return VUHDO_RAID[aUnit]["healthmax"] - VUHDO_RAID[aUnit]["health"]
> VUHDO_RAID[anotherUnit]["healthmax"] - VUHDO_RAID[anotherUnit]["health"];
end,
[VUHDO_MODE_EMERGENCY_PERC]
= function(aUnit, anotherUnit)
return VUHDO_RAID[aUnit]["health"] / VUHDO_RAID[aUnit]["healthmax"]
< VUHDO_RAID[anotherUnit]["health"] / VUHDO_RAID[anotherUnit]["healthmax"];
end,
[VUHDO_MODE_EMERGENCY_LEAST_LEFT]
= function(aUnit, anotherUnit)
return VUHDO_RAID[aUnit]["health"] < VUHDO_RAID[anotherUnit]["health"];
end,
}
--
local function VUHDO_sortEmergencies()
twipe(VUHDO_RAID_SORTED);
for tUnit, tInfo in pairs(VUHDO_RAID) do
if not VUHDO_isSpecialUnit(tUnit)
and VUHDO_getUnitHealthPercent(tInfo) < sTrigger and VUHDO_isValidEmergency(tInfo) then
VUHDO_RAID_SORTED[#VUHDO_RAID_SORTED + 1] = tUnit;
end
end
tsort(VUHDO_RAID_SORTED, VUHDO_EMERGENCY_SORTERS[sCurrentMode]);
VUHDO_setTopEmergencies(VUHDO_CONFIG["MAX_EMERGENCIES"]);
end
-- Avoid reordering sorting by max-health if someone dies or gets offline
local tEmptyInfo = {};
local function VUHDO_getUnitSortMaxHp(aUnit)
return VUHDO_RAID[aUnit][
((VUHDO_RAID[aUnit] or tEmptyInfo)["sortMaxHp"] ~= nil and InCombatLockdown())
and "sortMaxHp" or "healthmax"
];
end
--
local tIsAfk;
local tIsConnected;
local function VUHDO_updateAfkDc(aUnit)
tIsAfk = UnitIsAFK(aUnit);
tIsConnected = UnitIsConnected(aUnit);
if tIsAfk or not tIsConnected then
if not VUHDO_UNIT_AFK_DC[aUnit] then VUHDO_UNIT_AFK_DC[aUnit] = GetTime(); end
else
VUHDO_UNIT_AFK_DC[aUnit] = nil;
end
return tIsAfk, tIsConnected, VUHDO_RAID[aUnit] ~= nil and tIsConnected ~= VUHDO_RAID[aUnit]["connected"];
end
--
function VUHDO_getAfkDcTime(aUnit)
return VUHDO_UNIT_AFK_DC[aUnit];
end
-- Sets a Member info into raid array
local tUnitId;
local tIsPet;
local tClassName;
local tPowerType;
local tIsAfk, tIsConnected;
local tLocalClass;
local tIsDead;
local tClassId;
local tInfo;
local tNewHealth;
local tName, tRealm;
local tIsDcChange;
local tOwner;
function VUHDO_setHealth(aUnit, aMode)
tInfo = VUHDO_RAID[aUnit];
tUnitId = VUHDO_getUnitIds();
tOwner = VUHDO_PET_2_OWNER[aUnit];
tIsPet = tOwner ~= nil;
if strfind(aUnit, tUnitId, 1, true) or tIsPet or aUnit == "player" or VUHDO_isSpecialUnit(aUnit) then
tIsDead = UnitIsDeadOrGhost(aUnit) and not UnitIsFeignDeath(aUnit);
if tIsDead then
VUHDO_removeAllDebuffIcons(aUnit);
VUHDO_removeHots(aUnit);
VUHDO_initEventBouquetsFor(aUnit);
end
if 1 == aMode then -- VUHDO_UPDATE_ALL
tLocalClass, tClassName = UnitClass(aUnit);
tPowerType = UnitPowerType(aUnit);
tIsAfk, tIsConnected, _ = VUHDO_updateAfkDc(aUnit);
if not VUHDO_RAID[aUnit] then VUHDO_RAID[aUnit] = { }; end
tInfo = VUHDO_RAID[aUnit];
tInfo["ownerUnit"] = tOwner;
if tIsPet and tClassId then
if VUHDO_USER_CLASS_COLORS["petClassColor"] and VUHDO_RAID[tInfo["ownerUnit"]] then
tClassId = VUHDO_RAID[tInfo["ownerUnit"]]["classId"] or VUHDO_ID_PETS;
else
tClassId = VUHDO_ID_PETS;
end
else
tClassId = VUHDO_CLASS_IDS[tClassName];
end
tName, tRealm = UnitName(aUnit);
tInfo["healthmax"] = UnitHealthMax(aUnit);
tInfo["health"] = UnitHealth(aUnit);
tInfo["name"] = tName;
tInfo["number"] = VUHDO_getUnitNo(aUnit);
tInfo["unit"] = aUnit;
tInfo["class"] = tClassName;
tInfo["range"] = VUHDO_isInRange(aUnit);
tInfo["debuff"], tInfo["debuffName"] = VUHDO_determineDebuff(aUnit);
tInfo["isPet"] = tIsPet;
tInfo["powertype"] = tonumber(tPowerType);
tInfo["power"] = UnitPower(aUnit);
tInfo["powermax"] = UnitPowerMax(aUnit);
tInfo["charmed"] = UnitIsCharmed(aUnit) and UnitCanAttack("player", aUnit);
tInfo["aggro"] = false;
tInfo["group"] = VUHDO_getUnitGroup(aUnit, tIsPet);
tInfo["dead"] = tIsDead;
tInfo["afk"] = tIsAfk;
tInfo["connected"] = tIsConnected;
tInfo["threat"] = UnitThreatSituation(aUnit) or 0;
tInfo["threatPerc"] = 0;
tInfo["isVehicle"] = UnitHasVehicleUI(aUnit);
tInfo["petUnit"] = VUHDO_OWNER_2_PET[aUnit];
tInfo["targetUnit"] = VUHDO_getTargetUnit(aUnit);
tInfo["classId"] = tClassId;
tInfo["sortMaxHp"] = VUHDO_getUnitSortMaxHp(aUnit);
tInfo["role"] = VUHDO_determineRole(aUnit);
tInfo["fullName"] = (tRealm or "") ~= "" and (tName .. "-" .. tRealm) or tName;
tInfo["raidIcon"] = GetRaidTargetIndex(aUnit);
tInfo["visible"] = UnitIsVisible(aUnit); -- Reihenfolge beachten
tInfo["zone"], tInfo["map"] = VUHDO_getUnitZoneName(aUnit); -- ^^
tInfo["baseRange"] = UnitInRange(aUnit) or "player" == aUnit;
tInfo["isAltPower"] = VUHDO_isAltPowerActive(aUnit);
--[[tInfo["missbuff"] = nil;
tInfo["mibucateg"] = nil;
tInfo["mibuvariants"] = nil;]]
if tLocalClass == tName then
tInfo["className"] = UnitCreatureType(aUnit) or "";
else
tInfo["className"] = tLocalClass or "";
end
if not VUHDO_isSpecialUnit(aUnit) then
if not tIsPet and tInfo["fullName"] == tName and VUHDO_RAID_NAMES[tName] then
VUHDO_IS_SUSPICIOUS_ROSTER = true;
end
-- ensure not to overwrite a player name with a pet's identical name
if not VUHDO_RAID_NAMES[tName] or not tIsPet then
VUHDO_RAID_NAMES[tName] = aUnit;
end
end
elseif tInfo then
tIsAfk, tInfo["connected"], tIsDcChange = VUHDO_updateAfkDc(aUnit);
if tIsDcChange then
VUHDO_updateBouquetsForEvent(aUnit, 19); -- VUHDO_UPDATE_DC
end
if 2 == aMode then -- VUHDO_UPDATE_HEALTH
tNewHealth = UnitHealth(aUnit);
if not tIsDead and tInfo["health"] > 0 then
tInfo["lifeLossPerc"] = tNewHealth / tInfo["health"];
end
tInfo["health"] = tNewHealth;
if tInfo["dead"] ~= tIsDead then
if not tIsDead then
tInfo["healthmax"] = UnitHealthMax(aUnit);
end
tInfo["dead"] = tIsDead;
VUHDO_updateHealthBarsFor(aUnit, 10); -- VUHDO_UPDATE_ALIVE
VUHDO_updateBouquetsForEvent(aUnit, 10); -- VUHDO_UPDATE_ALIVE
end
elseif 3 == aMode then -- VUHDO_UPDATE_HEALTH_MAX
tInfo["dead"] = tIsDead;
tInfo["healthmax"] = UnitHealthMax(aUnit);
tInfo["sortMaxHp"] = VUHDO_getUnitSortMaxHp(aUnit);
elseif 6 == aMode then -- VUHDO_UPDATE_AFK
tInfo["afk"] = tIsAfk;
end
tInfo["dead"] = tIsDead;
end
end
end
local VUHDO_setHealth = VUHDO_setHealth;
--
local function VUHDO_setHealthSafe(aUnit, aMode)
if UnitExists(aUnit) then VUHDO_setHealth(aUnit, aMode); end
end
-- Callback for UNIT_HEALTH / UNIT_MAXHEALTH events
local tOwner;
local tIsPet;
function VUHDO_updateHealth(aUnit, aMode)
-- as of patch 7.1 we are seeing empty units on health related events
if not aUnit then
return;
end
tIsPet = VUHDO_RAID[aUnit] and VUHDO_RAID[aUnit]["isPet"];
if not tIsPet or VUHDO_INTERNAL_TOGGLES[26] then -- VUHDO_UPDATE_PETS -- Enth�lt nur Pets als eigene Balken, vehicles werden ?ber owner dargestellt s.unten
VUHDO_setHealth(aUnit, aMode);
VUHDO_updateHealthBarsFor(aUnit, aMode);
end
if tIsPet then -- Vehikel?
tOwner = VUHDO_RAID[aUnit]["ownerUnit"];
-- tOwner may not be present when leaving a vehicle
if VUHDO_RAID[tOwner] and VUHDO_RAID[tOwner]["isVehicle"] then
VUHDO_setHealth(tOwner, aMode);
VUHDO_updateHealthBarsFor(tOwner, aMode);
end
end
if 1 ~= sCurrentMode -- VUHDO_MODE_NEUTRAL
and (2 == aMode or 3 == aMode) then -- VUHDO_UPDATE_HEALTH -- VUHDO_UPDATE_HEALTH_MAX
-- Remove old emergencies
VUHDO_FORCE_RESET = true;
for tUnit, _ in pairs(VUHDO_EMERGENCIES) do
VUHDO_updateHealthBarsFor(tUnit, 11); -- VUHDO_UPDATE_EMERGENCY
end
VUHDO_sortEmergencies();
-- Set new Emergencies
VUHDO_FORCE_RESET = false;
for tUnit, _ in pairs(VUHDO_EMERGENCIES) do
VUHDO_updateHealthBarsFor(tUnit, 11); -- VUHDO_UPDATE_EMERGENCY
end
end
end
--
local tIcon;
function VUHDO_updateAllRaidTargetIndices()
for tUnit, tInfo in pairs(VUHDO_RAID) do
tIcon = GetRaidTargetIndex(tUnit);
if tInfo["raidIcon"] ~= tIcon then
tInfo["raidIcon"] = tIcon;
VUHDO_updateBouquetsForEvent(tUnit, 24); -- VUHDO_UPDATE_RAID_TARGET
end
end
end
-- Add to groups 1-8
local function VUHDO_addUnitToGroup(aUnit, aGroupNum)
if "player" ~= aUnit or not VUHDO_CONFIG["OMIT_SELF"] then
if not VUHDO_CONFIG["OMIT_OWN_GROUP"] or aGroupNum ~= VUHDO_PLAYER_GROUP then
tinsert(VUHDO_GROUPS[aGroupNum] or {}, aUnit);
end
if VUHDO_PLAYER_GROUP == aGroupNum then tinsert(VUHDO_GROUPS[10], aUnit); end -- VUHDO_ID_GROUP_OWN
end
end
--
local function VUHDO_addUnitToClass(aUnit, aClassId)
if ("player" ~= aUnit or not VUHDO_CONFIG["OMIT_SELF"]) and aClassId then
tinsert(VUHDO_GROUPS[aClassId], aUnit);
end
end
--
local function VUHDO_removeUnitFromRaidGroups(aUnit)
for tModelId, tAllUnits in pairs(VUHDO_GROUPS) do
if tModelId ~= 41 and tModelId ~= 42 and tModelId ~= 43 and tModelId ~= 44 then -- VUHDO_ID_MAINTANKS -- VUHDO_ID_PRIVATE_TANKS -- VUHDO_ID_MAIN_ASSISTS -- VUHDO_ID_BOSSES
for tIndex, tUnit in pairs(tAllUnits) do
if tUnit == aUnit then tremove(tAllUnits, tIndex); end
end
end
end
end
--
local function VUHDO_removeSpecialFromAllRaidGroups()
for tUnit, tInfo in pairs(VUHDO_RAID) do
if VUHDO_CONFIG["OMIT_MAIN_TANKS"] and VUHDO_isModelConfigured(41) and VUHDO_isUnitInModelIterative(tUnit, 41) then -- VUHDO_ID_MAINTANKS
VUHDO_removeUnitFromRaidGroups(tUnit); -- VUHDO_ID_MAINTANKS
elseif VUHDO_CONFIG["OMIT_PLAYER_TARGETS"] and VUHDO_isModelConfigured(42) and VUHDO_isUnitInModelIterative(tUnit, 42) then -- VUHDO_ID_PRIVATE_TANKS
VUHDO_removeUnitFromRaidGroups(tUnit); -- VUHDO_ID_PRIVATE_TANKS
elseif VUHDO_CONFIG["OMIT_MAIN_ASSIST"] and VUHDO_isModelConfigured(43) and VUHDO_isUnitInModelIterative(tUnit, 43) then -- VUHDO_ID_MAIN_ASSISTS
VUHDO_removeUnitFromRaidGroups(tUnit); -- VUHDO_ID_MAIN_ASSISTS
elseif VUHDO_isModelConfigured(44) and VUHDO_isUnitInModelIterative(tUnit, 44) then -- VUHDO_ID_BOSSES
VUHDO_removeUnitFromRaidGroups(tUnit); -- VUHDO_ID_BOSSES
end
end
end
--
local tRole;
local function VUHDO_addUnitToSpecial(aUnit)
if VUHDO_CONFIG["OMIT_DFT_MTS"] and "TANK" == (UnitGroupRolesAssigned(aUnit)) then
tinsert(VUHDO_GROUPS[41], aUnit); -- VUHDO_ID_MAINTANKS
return;
end
if not IsInRaid() then return; end
_, _, _, _, _, _, _, _, _, tRole = GetRaidRosterInfo(VUHDO_RAID[aUnit]["number"]);
if "MAINTANK" == tRole then tinsert(VUHDO_GROUPS[41], aUnit); -- VUHDO_ID_MAINTANKS
elseif "MAINASSIST" == tRole then tinsert(VUHDO_GROUPS[43], aUnit); end -- VUHDO_ID_MAIN_ASSISTS
end
--
local function VUHDO_addUnitToCtraMainTanks()
local tUnit;
for tCnt = 1, 8 do -- VUHDO_MAX_MTS
tUnit = VUHDO_MAINTANKS[tCnt];
if tUnit then VUHDO_tableUniqueAdd(VUHDO_GROUPS[41], tUnit); end -- VUHDO_ID_MAINTANKS
end
end
--
local function VUHDO_addUnitToPrivateTanks()
if not VUHDO_CONFIG["OMIT_TARGET"] then tinsert(VUHDO_GROUPS[42], "target"); end -- VUHDO_ID_PRIVATE_TANKS
if not VUHDO_CONFIG["OMIT_FOCUS"] then tinsert(VUHDO_GROUPS[42], "focus"); end -- VUHDO_ID_PRIVATE_TANKS
local tUnit;
for tName, _ in pairs(VUHDO_PLAYER_TARGETS) do
tUnit = VUHDO_RAID_NAMES[tName];
if tUnit then VUHDO_tableUniqueAdd(VUHDO_GROUPS[42], tUnit); -- VUHDO_ID_PRIVATE_TANKS
else VUHDO_PLAYER_TARGETS[tName] = nil; end
end
end
--
local function VUHDO_addUnitToBosses()
for bossUnitId, _ in pairs(VUHDO_BOSS_UNITS) do
VUHDO_tableUniqueAdd(VUHDO_GROUPS[44], bossUnitId); -- VUHDO_ID_BOSSES
end
end
--
local tVehicleInfo = { ["isVehicle"] = true };
local function VUHDO_addUnitToPets(aPetUnit)
if (VUHDO_RAID[VUHDO_RAID[aPetUnit]["ownerUnit"]] or tVehicleInfo)["isVehicle"] then return; end
tinsert(VUHDO_GROUPS[40], aPetUnit); -- VUHDO_ID_PETS
end
--
local tRole;
local function VUHDO_addUnitToRole(aUnit)
if "player" == aUnit and VUHDO_CONFIG["OMIT_SELF"] then return; end
tRole = VUHDO_RAID[aUnit]["role"] or 62; -- -- VUHDO_ID_RANGED_DAMAGE
tinsert(VUHDO_GROUPS[tRole], aUnit);
if tRole == 63 or tRole == 62 then tinsert(VUHDO_GROUPS[51], aUnit); -- VUHDO_ID_RANGED_HEAL -- VUHDO_ID_RANGED_DAMAGE -- VUHDO_ID_RANGED
elseif tRole == 61 or tRole == 60 then tinsert(VUHDO_GROUPS[50], aUnit); end -- VUHDO_ID_MELEE_DAMAGE -- VUHDO_ID_MELEE_TANK -- VUHDO_ID_MELEE
end
--
local function VUHDO_addUnitToVehicles(aUnit)
if VUHDO_RAID[aUnit]["petUnit"] then tinsert(VUHDO_GROUPS[70], VUHDO_RAID[aUnit]["petUnit"]); end -- VUHDO_ID_VEHICLES
end
--
local function VUHDO_updateGroupArrays(anWasMacroRestore)
-- Get an empty array for each group
for tType, tTypeMembers in pairs(VUHDO_ID_TYPE_MEMBERS) do
for _, tMember in pairs(tTypeMembers) do
if not VUHDO_GROUPS[tMember] then VUHDO_GROUPS[tMember] = { };
else twipe(VUHDO_GROUPS[tMember]); end
end
end
for tUnit, tInfo in pairs(VUHDO_RAID) do
if not tInfo["isPet"] then
if not VUHDO_isSpecialUnit(tUnit) then
VUHDO_addUnitToGroup(tUnit, tInfo["group"]);
VUHDO_addUnitToClass(tUnit, tInfo["classId"]);
VUHDO_addUnitToVehicles(tUnit);
VUHDO_addUnitToSpecial(tUnit);
end
else
VUHDO_addUnitToPets(tUnit);
end
end
VUHDO_GROUPS[80][1] = "player"; -- VUHDO_ID_SELF
VUHDO_GROUPS[81][1] = "pet"; -- VUHDO_ID_SELF_PET
VUHDO_GROUPS[82][1] = "target"; -- VUHDO_ID_TARGET
VUHDO_GROUPS[83][1] = "focus"; -- VUHDO_ID_FOCUS
VUHDO_addUnitToCtraMainTanks();
VUHDO_addUnitToPrivateTanks();
VUHDO_addUnitToBosses();
-- Need MTs for role estimation
for tUnit, tInfo in pairs(VUHDO_RAID) do
if not VUHDO_isSpecialUnit(tUnit) and not tInfo["isPet"] then
VUHDO_addUnitToRole(tUnit);
end
end
if not anWasMacroRestore then
VUHDO_removeSpecialFromAllRaidGroups();
end
VUHDO_initDynamicPanelModels();
end
-- Uniquely buffer all units defined in a panel
local tPanelUnits = { };
local tHasVehicles;
local tVehicleUnit;
local function VUHDO_updateAllPanelUnits()
VUHDO_resetRemoveFromRaidGroupsCache();
for tPanelNum = 1, 10 do -- VUHDO_MAX_PANELS
twipe(VUHDO_PANEL_UNITS[tPanelNum]);
if VUHDO_PANEL_MODELS[tPanelNum] then
tHasVehicles = VUHDO_isModelInPanel(tPanelNum, 70); -- VUHDO_ID_VEHICLES
twipe(tPanelUnits);
for tUnit, _ in pairs(VUHDO_RAID) do
if VUHDO_isUnitInPanel(tPanelNum, tUnit) then tPanelUnits[tUnit] = tUnit; end
if tHasVehicles and not VUHDO_RAID[tUnit]["isPet"] then
tVehicleUnit = VUHDO_RAID[tUnit]["petUnit"];
if tVehicleUnit then tPanelUnits[tVehicleUnit] = tVehicleUnit end -- e.g. "focus", "target"
end
end
if VUHDO_isModelInPanel(tPanelNum, 42) then -- VUHDO_ID_PRIVATE_TANKS
if not VUHDO_CONFIG["OMIT_TARGET"] then tPanelUnits["target"] = "target"; end
if not VUHDO_CONFIG["OMIT_FOCUS"] then tPanelUnits["focus"] = "focus"; end
end
for _, tUnit in pairs(tPanelUnits) do
tinsert(VUHDO_PANEL_UNITS[tPanelNum], tUnit);
end
end
end
end
--
local function VUHDO_updateAllGuids()
twipe(VUHDO_RAID_GUIDS);
for tUnit, _ in pairs(VUHDO_RAID) do
if tUnit ~= "focus" and tUnit ~= "target" then
VUHDO_RAID_GUIDS[UnitGUID(tUnit) or 0] = tUnit;
end
end
end
--
local function VUHDO_convertMainTanks()
-- Discard deprecated
for tCnt = 1, 8 do -- VUHDO_MAX_MTS
if not VUHDO_RAID_NAMES[VUHDO_MAINTANK_NAMES[tCnt] or "*"] then
VUHDO_MAINTANK_NAMES[tCnt] = nil;
end
end
-- Convert to units instead of names
twipe(VUHDO_MAINTANKS);
for tCnt, tName in pairs(VUHDO_MAINTANK_NAMES) do
VUHDO_MAINTANKS[tCnt] = VUHDO_RAID_NAMES[tName];
end
end
--
local function VUHDO_createClusterUnits()
twipe(VUHDO_CLUSTER_BASE_RAID);
VUHDO_resetClusterCoordDeltas();
for tUnit, tInfo in pairs(VUHDO_RAID) do
if not tInfo["isPet"] and "focus" ~= tUnit and "target" ~= tUnit then
VUHDO_CLUSTER_BASE_RAID[#VUHDO_CLUSTER_BASE_RAID + 1] = tInfo;
end
end
end
--
-- Reload all raid members into the raid array e.g. in case of raid roster change
function VUHDO_reloadRaidMembers()
local tPlayer;
local tMaxMembers;
local tUnit, tPetUnit;
local tWasRestored = false;
VUHDO_IS_SUSPICIOUS_ROSTER = false;
if GetNumGroupMembers() == 0 and not UnitExists("party1") and not sIsRestoredAfterDc then
VUHDO_IN_COMBAT_RELOG = true;
tWasRestored = VUHDO_buildRaidFromMacro();
VUHDO_updateAllRaidNames();
if (tWasRestored) then
VUHDO_normalRaidReload(true);
end
sIsRestoredAfterDc = true;
elseif VUHDO_isConfigDemoUsers() then
VUHDO_demoSetupResetUsers();
VUHDO_reloadRaidDemoUsers();
VUHDO_updateAllRaidNames();
else
VUHDO_PLAYER_RAID_ID = VUHDO_getPlayerRaidUnit();
VUHDO_IN_COMBAT_RELOG = false;
sIsRestoredAfterDc = true;
tUnit, tPetUnit = VUHDO_getUnitIds();
tMaxMembers = ("raid" == tUnit) and GetNumGroupMembers() or ("party" == tUnit) and 4 or 0;
twipe(VUHDO_RAID);
twipe(VUHDO_RAID_NAMES);
for tCnt = 1, tMaxMembers do
tPlayer = tUnit .. tCnt;
if UnitExists(tPlayer) and tPlayer ~= VUHDO_PLAYER_RAID_ID then
VUHDO_setHealth(tPlayer, 1); -- VUHDO_UPDATE_ALL
VUHDO_setHealthSafe(tPetUnit .. tCnt, 1); -- VUHDO_UPDATE_ALL
end
end
VUHDO_setHealthSafe("player", 1); -- VUHDO_UPDATE_ALL
VUHDO_setHealthSafe("pet", 1); -- VUHDO_UPDATE_ALL
VUHDO_setHealthSafe("focus", 1); -- VUHDO_UPDATE_ALL
if VUHDO_INTERNAL_TOGGLES[27] then -- VUHDO_UPDATE_PLAYER_TARGET
VUHDO_setHealthSafe("target", 1); -- VUHDO_UPDATE_ALL
end
for bossUnitId, _ in pairs(VUHDO_BOSS_UNITS) do
if UnitExists(bossUnitId) then
VUHDO_setHealth(bossUnitId, 1); -- VUHDO_UPDATE_ALL
else
-- FIXME: find a more efficient way to trigger boss removal
VUHDO_removeHots(bossUnitId);
VUHDO_resetDebuffsFor(bossUnitId);
VUHDO_removeAllDebuffIcons(bossUnitId);
VUHDO_updateTargetBars(bossUnitId);
table.wipe(VUHDO_RAID[bossUnitId] or tEmptyInfo);
VUHDO_RAID[bossUnitId] = nil;
VUHDO_updateHealthBarsFor(bossUnitId, 1); -- VUHDO_UPDATE_ALL
VUHDO_initEventBouquetsFor(bossUnitId);
end
end
VUHDO_TIMERS["MIRROR_TO_MACRO"] = 8;
end
VUHDO_PLAYER_GROUP = VUHDO_getUnitGroup(VUHDO_PLAYER_RAID_ID, false);
VUHDO_trimInspected();
VUHDO_convertMainTanks();
VUHDO_updateGroupArrays(tWasRestored);
VUHDO_updateAllPanelUnits();
VUHDO_updateAllGuids();
VUHDO_updateBuffRaidGroup();
VUHDO_updateBuffPanel();
if sCurrentMode ~= 1 then VUHDO_sortEmergencies(); end -- VUHDO_MODE_NEUTRAL
VUHDO_createClusterUnits();
if VUHDO_IS_SUSPICIOUS_ROSTER then VUHDO_normalRaidReload(); end
end
--
local tPlayer;
local tMaxMembers;
local tUnitType = "foo";
local tPetUnitType;
local tInfo;
local tIsDcChange;
local tName, tRealm;
local tOldUnitType;
local tPet;
function VUHDO_refreshRaidMembers()
VUHDO_PLAYER_RAID_ID = VUHDO_getPlayerRaidUnit();
VUHDO_IN_COMBAT_RELOG = false;
tOldUnitType = tUnitType;
tUnitType, tPetUnitType = VUHDO_getUnitIds();
tMaxMembers = ("raid" == tUnitType) and 40 or ("party" == tUnitType) and 4 or 0;
for tCnt = 1, tMaxMembers do
tPlayer = tUnitType .. tCnt;
if UnitExists(tPlayer) and tPlayer ~= VUHDO_PLAYER_RAID_ID then
tInfo = VUHDO_RAID[tPlayer];
if not tInfo or VUHDO_RAID_GUIDS[UnitGUID(tPlayer)] ~= tPlayer then
--VUHDO_xMsg("VUHDO_refreshRaidMembers", "VUHDO_setHealth", tPlayer or "no player", tInfo and "in raid" or "not in raid", VUHDO_RAID_GUIDS[UnitGUID(tPlayer)] or "no raid guid");
VUHDO_setHealth(tPlayer, 1); -- VUHDO_UPDATE_ALL
else
tInfo["group"] = VUHDO_getUnitGroup(tPlayer, false);
tInfo["isVehicle"] = UnitHasVehicleUI(tPlayer);
if ( tInfo["isVehicle"] ) then
local tRaidId = UnitInRaid(tPlayer);
if ( tRaidId and not UnitTargetsVehicleInRaidUI(tPlayer) ) then
tInfo["isVehicle"] = false;
end
end
tInfo["afk"], tInfo["connected"], tIsDcChange = VUHDO_updateAfkDc(tPlayer);
if tIsDcChange then
VUHDO_updateBouquetsForEvent(tPlayer, 19); -- VUHDO_UPDATE_DC
end
VUHDO_setHealthSafe(tPetUnitType .. tCnt, 1); -- VUHDO_UPDATE_ALL
end
elseif VUHDO_RAID[tPlayer] then
VUHDO_RAID[tPlayer]["connected"] = false;
tPet = VUHDO_RAID[tPlayer]["petUnit"];
if VUHDO_RAID[tPet] then
VUHDO_RAID[tPet]["connected"] = false;
end
end
end
VUHDO_setHealthSafe("player", 1); -- VUHDO_UPDATE_ALL
VUHDO_setHealthSafe("pet", 1); -- VUHDO_UPDATE_ALL
VUHDO_setHealthSafe("focus", 1); -- VUHDO_UPDATE_ALL
if VUHDO_INTERNAL_TOGGLES[27] then -- VUHDO_UPDATE_PLAYER_TARGET
VUHDO_setHealthSafe("target", 1); -- VUHDO_UPDATE_ALL
end
for bossUnitId, _ in pairs(VUHDO_BOSS_UNITS) do
if UnitExists(bossUnitId) then -- and UnitIsFriend("player", bossUnitId) then
tInfo = VUHDO_RAID[bossUnitId];
if not tInfo or VUHDO_RAID_GUIDS[UnitGUID(bossUnitId)] ~= bossUnitId then
VUHDO_setHealth(bossUnitId, 1); -- VUHDO_UPDATE_ALL
else
tInfo["group"] = VUHDO_getUnitGroup(bossUnitId, false);
tInfo["isVehicle"] = UnitHasVehicleUI(bossUnitId);
tInfo["afk"] = false;
tInfo["connected"] = true;
end
else
-- FIXME: find a more efficient way to trigger boss removal
VUHDO_removeHots(bossUnitId);
VUHDO_resetDebuffsFor(bossUnitId);
VUHDO_removeAllDebuffIcons(bossUnitId);
VUHDO_updateTargetBars(bossUnitId);
table.wipe(VUHDO_RAID[bossUnitId] or tEmptyInfo);
VUHDO_RAID[bossUnitId] = nil;
VUHDO_updateHealthBarsFor(bossUnitId, 1); -- VUHDO_UPDATE_ALL
VUHDO_initEventBouquetsFor(bossUnitId);
end
end
VUHDO_PLAYER_GROUP = VUHDO_getUnitGroup(VUHDO_PLAYER_RAID_ID, false);
VUHDO_updateAllRaidNames();
VUHDO_trimInspected();
VUHDO_convertMainTanks();
VUHDO_updateGroupArrays(false);
VUHDO_updateAllPanelUnits();
VUHDO_updateAllGuids();
VUHDO_updateBuffRaidGroup();
if sCurrentMode ~= 1 then VUHDO_sortEmergencies(); end -- VUHDO_MODE_NEUTRAL
VUHDO_createClusterUnits();
end