Files
ClassicAPI/src/classes/Color.cpp
T
brues-code b7a78565f7 docs: an API descriptor for every registration (#144)
* docs(container): describe the C_Container functions

Descriptors for the 17 undocumented C_Container functions and the
ItemQuestInfo structure. SwapItems, MoveItem, AutoStoreItem,
GetContainerItemCharges, GetContainerItemRepairCost and
IsContainerItemOpenable are not in retail's API and are marked as
ClassicAPI extensions.

* docs(aura): describe the C_UnitAuras functions

Descriptors for the 16 undocumented C_UnitAuras functions, plus the
AuraData structure that GetAuraDataByAuraInstanceID already named but
nothing defined. The four positional getters share the Classic Era
UnitAura return list.

* docs(equipmentset): describe the C_EquipmentSet functions

Descriptors for the 18 undocumented C_EquipmentSet functions,
GameTooltip:SetEquipmentSet, and the EQUIPMENT_SETS_CHANGED,
EQUIPMENT_SWAP_PENDING and EQUIPMENT_SWAP_FINISHED events. They
describe what the functions return here, which differs from retail in
places: an icon path, not a file ID; numMissing, not numLost;
GetIgnoredSlots lists slot numbers.

* docs(faction): describe the reputation functions

Descriptors for GetFactionIDByIndex, GetFactionInfoByID,
GetFactionParentID, the 17 undocumented C_Reputation functions, the
FactionData structure, and the FACTION_STANDING_CHANGED event.
C_Reputation.IsFactionInactive and SetFactionInactive mirror stock
globals, but no Blizzard client has them under C_Reputation, so they
are marked as ClassicAPI extensions.

* docs(player): describe the player functions and events

Descriptors for C_PlayerInfo.CanUseItem, GetName, GetClass, GetRace,
GetSex and IsConnected; GetPlayerFacing, GetPlayerInfoByGUID,
UnitNameFromGUID and IsLoggedIn; the four C_PlayerCache functions; and
the PLAYER_EQUIPMENT_CHANGED, UPDATE_INVENTORY_DURABILITY,
HEARTHSTONE_BOUND and six PLAYER_STARTED/STOPPED_MOVING, LOOKING and
TURNING events. They describe what the functions return here: sex is 2
or 3, not the UnitSex enum, and GetPlayerInfoByGUID has no level.
C_PlayerCache is ours, so its functions are marked as extensions.

GetCritChance and GetRangedCritChance move from system "PaperDollInfo"
to "PlayerGlobals": PaperDollInfo is the C_PaperDollInfo namespace's
system, and a global must not share it.

* docs(map): describe the C_Map functions

Descriptors for the 30 undocumented C_Map and C_MapExplorationInfo
functions, the UiMapDetails, UiMapLayerInfo, UiMapPoint,
AreaTriggerInfo, MapOverlayInfo and MapOverlayTile structures, and the
USER_WAYPOINT_UPDATED event. mapType is a plain number because no
Enum.UIMapType is registered, and flags is always 0. GetAreaTriggerInfo,
GetAreaTriggers, GetAreas, GetMapAreaIDs, GetMapOverlays and
GetUnexploredMapTextures are marked as ClassicAPI extensions.

* docs(loot): describe the C_Loot and C_LootHistory functions

Descriptors for the six C_Loot functions and the four C_LootHistory
functions, the LootableUnit, ScannedCorpse and ScannedLootItem
structures, and the LOOT_SCAN_COMPLETED and three LOOT_HISTORY_* events.
Every C_Loot function here and C_LootHistory.Clear are marked as
ClassicAPI extensions; Blizzard's C_Loot has none of them.

* docs(sound): describe the sound functions

Descriptors for the six undocumented C_Sound functions, the PlaySound,
PlaySoundFile, StopSound, MuteSoundFile and UnmuteSoundFile globals, the
PlaySoundParams and RecentSoundFile structures, the ItemSoundType and
Vocalerrorsounds enums, and the SOUNDKIT_FINISHED event.
C_Sound.PlaySound's second argument is documented as the channel name it
takes here, not retail's UISoundSubType. GetRecentSoundFiles is marked as
a ClassicAPI extension.

* docs(console): describe the console functions

Descriptors for ConsoleExec, ConsoleEcho, ConsoleIsActive,
ConsoleGetColorFromType, ConsoleGetFontHeight, SetConsoleKey,
CalculateStringEditDistance, ConsoleGetAllCommands and
ConsolePrintAllMatchingCommands, the ConsoleCommandInfo structure, and
the ConsoleCommandType and ConsoleCategory enums. The game and glue
registrations of each function share one descriptor. ConsoleExec and
ConsoleEcho return nothing here, and SetConsoleKey takes a key code.

* docs(voicechat): describe the text-to-speech functions

Descriptors for the four C_VoiceChat text-to-speech functions, the ten
C_TTSSettings functions, the VoiceTtsVoiceType structure, and the five
VOICE_CHAT_TTS_* events. The event payloads follow the shapes the
client sends here. GetSpeechVoiceID, SetVoiceOptionByName and
RefreshVoices are marked as ClassicAPI extensions.

* docs(api): correct entries that drifted from the code

Fixes entries that the descriptor pass found to differ from what the
functions do: C_PlayerInfo.GetSex never returns 1, the name and race
getters need a visible unit for unit locations too, RememberPlayer
raises on missing arguments, mutes outlive a reload, scan results fill
in during a scan, LootHistory names can be nil and ROLL_CHANGED can
carry playerIndex 0, GetMapRectOnMap's fallback and Kalimdor ID, dungeon
maps have no parent, and GetBestMapForUnit gives zones, not subzones.

HEARTHSTONE_BOUND and the player input-state events now describe only
their behavior; the packet handlers, engine addresses and hook notes
are gone.

* docs(loot): say when LOOT_HISTORY_FULL_UPDATE fires

The comment above the loot-history event names said FULL_UPDATE was
never fired from C++, but FireFullUpdate sends it when a roll opens a
new item, when the 128-item ring evicts the oldest entry, and from
C_LootHistory.Clear.

* docs(api): describe behavior, not implementation

API.md is the contract for addon authors, so it no longer names engine
addresses, struct offsets, internal type and field names, packet
opcodes, hook mechanics, source files or our C++ modules, and drops
provenance notes and remarks about which client version lacks what.
Where that text carried a real behavior, the behavior stays in plain
words: "when the server answers" in place of an opcode, "ignores the
merchant and repair cursor modes" in place of the function it skips.

Also: C_Spell.GetSpellPowerCost no longer calls GetSpellInfo's cost the
base cost (both are the effective cost), the C_Spell cast-info note no
longer calls the functions player-only, the name-cache intro says the
game empties its cache on each world entry, and examples use a generic
realm name.

* docs(item): describe the item functions

Descriptors for the 95 undocumented item registrations: the C_Item
readers, lock, use and equip calls, the GetItemInfo family, the
Get*ItemID companions, the GameTooltip item methods, the ItemData,
ItemSetInfo and ItemEnchantInfo structures, the InventoryType,
ItemClass and ItemQuality enums, and the ITEM_DATA_LOAD_RESULT and
GET_ITEM_INFO_RECEIVED events. They describe what the functions return
here where it differs from retail: GetItemSetInfo returns a table,
GetWeaponEnchantInfo returns twelve values, and RequestLoadItemData
returns whether the request went out. GetItemIDForItemInfo's return is
now optional, since input that names no item returns nothing.

* docs(unit): describe the unit functions

Descriptors for the 49 undocumented unit functions, the PowerType enum,
and the PLAYER_FOCUS_CHANGED and UPDATE_SHAPESHIFT_FORM events. They
describe what the functions do here: UnitHealthMissing has no
usePredicted argument, IsFalling and IsSwimming take no unit,
UnitPowerType returns no color, and UnitPosition keeps its Y-first
return order.

* docs(baselib): describe the Lua library additions

Descriptors for the Lua 5.1 functions added to the game's Lua: select,
unpack with a range, xpcall with arguments, collectgarbage options,
debugstack, the math hyperbolics, fmod and modf, string.match, gmatch,
reverse, byte, split, join and trim with their global aliases, and
strreplace, plus Mixin and CreateFromMixins. strreplace is the one
ClassicAPI extension; retail binds the other aliases itself.

* docs(api): correct entries the item and unit descriptors contradicted

UnitIsMinion, UnitIsPet and UnitIsOtherPlayersPet raise on a string that
is not a unit token; only a token that names no unit, or a non-string,
returns false. GetItemCooldown does not take item names. A full request
queue makes RequestLoadItemData return false. GetInventoryItemID needs a
player, so pets and totems return nil. GetItemNameByID keeps a link's
random suffix. GetInventoryItemRepairCost raises on a non-number slot.
The Get*ItemID intro no longer calls the companions stock functions.

Also settles two entries that contradicted themselves: the summoning
ritual's channel events do fire, and GetSecondsUntilDailyReset counts to
UTC midnight. C_PlayerInfo.UnitPosition gets a line under UnitPosition.

* fix(docs): map the remaining widget method registries to systems

Methods registered on the Button, Slider, StatusBar, MessageFrame,
SimpleHTML, ScrollingMessageFrame, PlayerModel and DressUpModel
registries had descriptors, but the browser listed them as an unmapped
registry. The five Blizzard has use its names (SimpleButtonAPI and so
on); the other three are named the same way.

* docs(ui): describe the frame, texture and input functions

Descriptors for the texture, region, frame, button, editbox and tooltip
methods ClassicAPI adds, the C_Texture atlas, C_XMLUtil, C_ColorUtil,
C_UIColor and C_NamePlate functions, the binding, modifier-key, cursor
and screen globals, the AtlasInfo, XML template and DBColorExport
structures, Enum.UICursorType, and the nameplate, cursor and
MODIFIER_STATE_CHANGED events. IsMouseButtonDown, GetMouseButtonName and
GetCursorDelta move to the InputGlobals system.

* docs(spell): describe the spell, action and creature functions

Descriptors for the remaining spell, spellbook, tracking, action bar,
talent, totem, loss-of-control, macro, combat, tradeskill, targeting,
GUID, class, C_CreatureInfo and C_GameObjectInfo registrations, their
structures, and the LEARNED_SPELL_IN_SKILL_LINE, PLAYER_TOTEM_UPDATE,
LOSS_OF_CONTROL_*, CREATURE_DATA_LOAD_RESULT and
GAMEOBJECT_DATA_LOAD_RESULT events. The IsItemAction,
HasBonusActionBar and IsStackableAction globals move from the
C_ActionBar system to ActionBarGlobals.

* docs(world): describe the gossip, quest, social and vendor functions

Descriptors for C_GossipInfo, the friends and /who functions, C_QuestLog
and the quest globals, C_TaxiMap, C_MerchantFrame, C_AuctionHouse.PostItem,
the mail, group, instance, coin-text, chat, character-order and
expansion globals, their structures, the FlightPath enums, and the
QUEST_DATA_LOAD_RESULT and AUCTION_MULTISELL_* events. Globals that
named a namespaced system (QuestLog, PartyInfo, CurrencyInfo) move to
the matching *Globals system, and GetCoinText gets separate global and
C_CurrencyInfo descriptors.

* docs(lua): describe the cvar, encoding, time, addon and Lua functions

Descriptors for the cvar, C_EncodingUtil, C_DateAndTime, C_Timer,
C_AddOns, coroutine, table, security-account, event, script, clipboard
and hooksecurefunc registrations, the CalendarTime and SavedAccountInfo
structures, and the Base64Variant, CompressionMethod and
AddOnSecurityStatus enums.

* docs(api): correct entries the last descriptor pass contradicted

SelectOption takes an optional password for boxCoded options.
IsWhoQueryPending clears when the answer arrives, not after a timer, and
SendWhoQueryByName raises on a nil or non-string name. SetTalentByID
raises on a nil or non-number talentID. The gossip getters also read the
quest greeting window. GetPoint returns three values for an anchor with
no relative frame. RegisterAtlas's rectangle is optional.
GetSecondsUntilDailyReset returns nothing before login.

CopyToClipboard is a Blizzard function, not an extension, and always
returns the length. ConvertHSLToRGB, DoesTemplateExist,
GetNamePlateForGUID, GetNamePlateGUIDs and SetModernScriptArgs are
labelled as ClassicAPI extensions, and C_AuctionHouse.PostItem is
described as retail's function plus a numStacks argument.
IsAddOnLoadable's descriptor notes the nil reason for an unknown name.

* docs: start every function and event summary with a verb

Function summaries now read "Returns …", "Returns whether …" and so on,
not a bare "Whether …", "The …" or "How many …", and event summaries
read "Fires when …" instead of describing the past ("A cast ended").
A few two-sentence summaries become one sentence, and the two range
check toggles say what they do rather than "Used with …".

* refactor(lua): require a descriptor on every registration

The registrars and Event::Custom::AutoReserve no longer default their
doc argument, so a function, method table, enum, alias or custom event
registered without a descriptor does not compile. The _classicapi_
debug functions, which the documentation export skips, pass nullptr
explicitly.

* docs: stop calling namespaced Blizzard globals extensions

A function is a ClassicAPI extension only when no Blizzard client ships
it under any name. C_XMLUtil.DoesTemplateExist (the global
DoesTemplateExist), C_PlayerInfo.UnitPosition, C_Reputation.
IsFactionInactive and SetFactionInactive, and C_Macro.CreateMacro and
EditMacro are Blizzard globals under a namespace Blizzard never gave
them, so their descriptors and API.md no longer label them extensions.

* refactor(baselib): register newproxy through the registrars

newproxy set its global by hand so its C closure could carry the weak
table of valid metatables as an upvalue, which left it the one global
with no descriptor. The weak table now lives in the registry (made on
first use in each Lua state), so newproxy is a plain C function that
RegisterGlobalFunction and RegisterGlueFunction bind with a descriptor.
Behavior is unchanged.

* docs(api): drop the C++ module name from the aura timing heading

* docs(api): fix descriptor errors found in review

- UnitSpellTargetName is a Blizzard function (Unit system): drop the
  extension flag and file it under UnitGlobals.
- Flag the ClassicAPI-only spell functions as extensions: GetSpellRadius
  (global and C_Spell), GetSpellReagents, GetSpellDispelType,
  IsNextMeleeSpell, ResetsMeleeSwing, GetSpellMechanicByID,
  GetSpellEffectMechanics, GetSpellEffectInfo, GetSpellRequiredTargetLevel,
  GetSpellLevelInfo and C_SpellBook.GetPlayerSpellsByAura. No Blizzard
  client ships any of them.
- Name the Region registry SimpleScriptRegionAPI, as retail does, and
  make the no-counterpart comment cover all three rows it applies to.
- Start the VOICE_CHAT_TTS_SPEAK_TEXT_UPDATE summary with a verb.
- Type GetCurrentChatEvent's guid return as WOWGUID, matching
  GetCurrentChatGUID.
- Say that the itemInfo argument also accepts an item string.

* docs(api): document the methods the source count missed

_classicapi_UndocumentedAPI() still listed 23 names. Each sat in a method
array that already had a partial doc array, so the source count read it
as documented.

- GameTooltip: SetUnitAura, SetUnit, GetUnit, GetUnitGUID, HasUnit.
  GetUnitGUID and HasUnit are extensions; no Blizzard client ships them.
- FontString: GetStringHeight, GetUnboundedStringWidth, GetWrappedWidth,
  GetNumLines, GetLineHeight, IsTruncated, SetMaxLines, GetMaxLines,
  GetFieldSize.
- ModelScene actor: GetObjectType, IsObjectType, GetName, GetParent,
  HasScript, GetScript, SetScript, HookScript, as our object methods
  return them (1/nil, no HookScript result).
- GetAverageItemLevel moves to PaperDollInfoGlobals: PaperDollInfo is the
  C_PaperDollInfo namespace.

The in-game check now reports 0.
2026-11-13 13:52:12 -06:00

85 lines
3.4 KiB
C++

// This file is part of ClassicAPI.
//
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
// of the GNU General Public License as published by the Free Software Foundation, either
// version 3 of the License, or (at your option) any later version.
//
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
// `C_ClassColor.GetClassColor(className)` — a class's color as a ColorMixin.
//
// Modern clients keep the class colors in the engine and let FrameXML read
// them out through this function. Neither half of that exists here: 1.12's
// `ChrClasses.dbc` has no color column (17 columns, all accounted for), and
// the binary carries no class-color table — searched it for the class float
// triples and for the hex strings, no hits.
//
// What this client does have is `RAID_CLASS_COLORS`, defined by FrameXML in
// `Fonts.xml` and given the mixin by `!!!ClassicAPI/Util/Color*.lua`. Every
// UI on the client already colors classes from it, so this reads that table
// instead of carrying a second copy of the nine colors — the same choice
// `C_UnitAuras.GetAuraDispelTypeColor` makes with the `DEBUFF_TYPE_*_COLOR`
// globals. One source of truth, one shared object per class, and a class
// another addon recolors stays recolored here (this client's stand-in for
// CUSTOM_CLASS_COLORS).
//
// The lookup goes through metamethods, so a `RAID_CLASS_COLORS` that answers
// for unknown keys answers here too — the pfUI shim in `Util/AddOnCompat.lua`
// hands back grey. A name that is not a string, and a missing table, both
// return nil.
#include "Game.h"
namespace Classes::Color {
namespace {
int __fastcall Script_GetClassColor(void *L) {
if (Game::Lua::Type(L, 1) != Game::Lua::TYPE_STRING) {
Game::Lua::PushNil(L);
return 1;
}
Game::Lua::PushString(L, "RAID_CLASS_COLORS");
Game::Lua::GetTable(L, Game::Lua::GLOBALS_INDEX);
if (Game::Lua::Type(L, -1) != Game::Lua::TYPE_TABLE) {
Game::Lua::PushNil(L);
return 1;
}
// Index with the argument itself rather than with a `const char *` read
// off the stack: the string stays anchored at index 1, so nothing it
// points at can be collected while we look it up.
Game::Lua::PushValue(L, 1);
Game::Lua::GetTable(L, -2);
return 1;
}
// --- Documentation ----------------------------------------------------------
const Game::Doc::Field kArgs[] = {
Game::Doc::Req("className", "string", "A class file name, such as \"WARRIOR\"."),
};
const Game::Doc::Field kRets[] = {
Game::Doc::Opt("classColor", "colorRGB", nullptr,
"The color for that class, or nil when the name is not a class."),
};
const Game::Doc::Function kGetClassColor{
"Returns the color a class is drawn in.", kArgs, kRets};
} // namespace
static void RegisterLuaFunctions() {
Game::Lua::RegisterTableFunction("C_ClassColor", "GetClassColor",
&Script_GetClassColor, &kGetClassColor);
}
static const Game::ModuleAutoRegister _autoreg{&RegisterLuaFunctions};
} // namespace Classes::Color