Files
Outfitter/OutfitterClientMods.lua
2026-10-30 16:59:08 +00:00

158 lines
4.7 KiB
Lua

-- OutfitterClientMods.lua
--
-- Optional integration with 1.12.1 client mods. Every helper here has a
-- plain-vanilla fallback, so Outfitter behaves exactly as before when no
-- client mod is installed.
--
-- SuperWoW : UnitBuff() 3rd return = aura spell ID, IsMounted(),
-- IsSwimming(), UnitExists() 2nd return = GUID
-- ClassicAPI : C_UnitAuras.GetAuraDataByIndex() (spellId + name),
-- IsMounted(), IsSwimming(), UnitGUID()
-- Nampower : detected and reported only. Its item/cast/spell-queue API
-- has no task inside Outfitter that it does better.
-- UnitXP SP3 : detected and reported only. Distance, line of sight and
-- camera functions have no use in an equipment manager.
--
-- Lua 5.0 (no select(), no #, no varargs expressions).
Outfitter_ClientMods = {
SuperWoW = false,
ClassicAPI = false,
Nampower = false,
UnitXP = false,
Detected = false,
};
local OCM = Outfitter_ClientMods;
function Outfitter_DetectClientMods()
OCM.SuperWoW = (SUPERWOW_VERSION ~= nil) or (SUPERWOW_STRING ~= nil);
OCM.ClassicAPI = (CLASSIC_API_VERSION ~= nil)
or (type(C_UnitAuras) == "table" and type(C_UnitAuras.GetAuraDataByIndex) == "function");
OCM.Nampower = type(GetNampowerVersion) == "function";
OCM.UnitXP = false;
if type(UnitXP) == "function" then
-- UnitXP("nop", "nop") is the documented presence check; it raises if the dll is missing
local vOK = pcall(UnitXP, "nop", "nop");
OCM.UnitXP = vOK and true or false;
end
-- Capabilities actually used by Outfitter
OCM.HasIsMounted = type(IsMounted) == "function" and (OCM.SuperWoW or OCM.ClassicAPI);
OCM.HasIsSwimming = type(IsSwimming) == "function" and (OCM.SuperWoW or OCM.ClassicAPI);
OCM.HasAuraSpellID = OCM.SuperWoW or OCM.ClassicAPI;
OCM.HasGUID = OCM.SuperWoW or (OCM.ClassicAPI and type(UnitGUID) == "function");
OCM.Detected = true;
end
-- Returns texture, spellID[, name] for the player's buff at pIndex (1-based).
-- spellID is nil when no client mod provides it.
function Outfitter_GetPlayerBuffInfo(pIndex)
if OCM.SuperWoW then
local vTexture, vCount, vSpellID = UnitBuff("player", pIndex);
return vTexture, vSpellID;
end
if OCM.ClassicAPI then
local vTexture = UnitBuff("player", pIndex);
if not vTexture then
return nil;
end
local vOK, vData = pcall(C_UnitAuras.GetAuraDataByIndex, "player", pIndex, "HELPFUL");
if vOK and type(vData) == "table" then
-- name lets the caller confirm the two APIs agree on this index
return vTexture, vData.spellId, vData.name;
end
return vTexture, nil;
end
return UnitBuff("player", pIndex), nil;
end
-- Returns true/false when a client mod can answer, nil when unknown
function Outfitter_ClientIsMounted()
if not OCM.HasIsMounted then
return nil;
end
local vOK, vResult = pcall(IsMounted);
if not vOK then
return nil;
end
return vResult and vResult ~= 0 and true or false;
end
function Outfitter_ClientIsSwimming()
if not OCM.HasIsSwimming then
return nil;
end
local vOK, vResult = pcall(IsSwimming);
if not vOK then
return nil;
end
return vResult and vResult ~= 0 and true or false;
end
-- Stable identity for a unit: GUID when available, otherwise name..level
function Outfitter_GetUnitIdentity(pUnit)
if not UnitExists(pUnit) then
return nil;
end
if OCM.ClassicAPI and type(UnitGUID) == "function" then
local vOK, vGUID = pcall(UnitGUID, pUnit);
if vOK and vGUID then
return vGUID;
end
end
if OCM.SuperWoW then
local vExists, vGUID = UnitExists(pUnit);
if vGUID then
return vGUID;
end
end
return (UnitName(pUnit) or "?") .. ":" .. (UnitLevel(pUnit) or 0);
end
function Outfitter_ClientModsSummary()
if not OCM.Detected then
Outfitter_DetectClientMods();
end
local function YesNo(pValue)
if pValue then
return GREEN_FONT_COLOR_CODE .. "yes" .. FONT_COLOR_CODE_CLOSE;
end
return GRAY_FONT_COLOR_CODE .. "no" .. FONT_COLOR_CODE_CLOSE;
end
DEFAULT_CHAT_FRAME:AddMessage(NORMAL_FONT_COLOR_CODE .. "Outfitter client mod support:" .. FONT_COLOR_CODE_CLOSE);
DEFAULT_CHAT_FRAME:AddMessage(" SuperWoW: " .. YesNo(OCM.SuperWoW) .. " ClassicAPI: " .. YesNo(OCM.ClassicAPI)
.. " Nampower: " .. YesNo(OCM.Nampower) .. " UnitXP SP3: " .. YesNo(OCM.UnitXP));
DEFAULT_CHAT_FRAME:AddMessage(" Mount detection: " .. (OCM.HasIsMounted and "client flag" or "buff tooltip text"));
DEFAULT_CHAT_FRAME:AddMessage(" Swimming detection: " .. (OCM.HasIsSwimming and "client flag (surface + underwater)" or "breath timer (underwater only)"));
DEFAULT_CHAT_FRAME:AddMessage(" Buff tooltip scans: " .. (OCM.HasAuraSpellID and "cached per spell ID" or "every aura change"));
DEFAULT_CHAT_FRAME:AddMessage(" Target identity: " .. (OCM.HasGUID and "GUID" or "name + level"));
end