Add SpellDataResolver that lazily loads Spell.dbc, SpellCastTimes.dbc,
and SpellRange.dbc to provide cast time and range data. GetSpellInfo()
now returns real castTime (ms), minRange, and maxRange instead of
hardcoded 0 values.
This enables spell tooltip addons, cast bar addons (Quartz), and range
check addons to display accurate spell information. The DBC chain is:
Spell.dbc[CastingTimeIndex] → SpellCastTimes.dbc[Base ms]
Spell.dbc[RangeIndex] → SpellRange.dbc[MinRange, MaxRange]
Follows the same lazy-loading pattern as SpellIconPathResolver and
ItemIconPathResolver.
Add playerClassRaceCache_ that stores classId and raceId from
SMSG_NAME_QUERY_RESPONSE. This enables UnitClass and UnitRace to return
correct data for players who were previously seen but are now out of
UPDATE_OBJECT range.
Fallback chain for UnitClass/UnitRace is now:
1. Entity update fields (UNIT_FIELD_BYTES_0) — for nearby entities
2. Name query cache — for previously queried players
3. getPlayerClass/Race() — for the local player
This improves class-colored names in chat, unit frames, and nameplates
for players who move out of view range.
Previously UnitHealth, UnitHealthMax, UnitPower, UnitPowerMax, UnitLevel,
UnitName, and UnitExists returned 0/"Unknown"/false for party members in
other zones because the entity doesn't exist in the entity manager.
Now these functions fall back to SMSG_PARTY_MEMBER_STATS data stored in
GroupMember structs, which provides health, power, level, and name for
all party members regardless of distance. UnitName also falls back to
the player name cache.
This fixes raid frame addons (Grid, Healbot, VuhDo) showing blank/zero
data for party members who are out of UPDATE_OBJECT range.
Add 6 commonly needed unit state functions:
- UnitIsGhost(unit) checks ghost flag from UNIT_FIELD_FLAGS
- UnitIsDeadOrGhost(unit) combines dead + ghost checks
- UnitIsAFK(unit) / UnitIsDND(unit) check player flags
- UnitPlayerControlled(unit) true for players and player pets
- UnitSex(unit) reads gender from UNIT_FIELD_BYTES_0 byte 2
Fix UnitAffectingCombat to check UNIT_FLAG_IN_COMBAT (0x00080000)
from entity update fields for any unit, not just "player". Previously
returned false for all non-player units.
These functions are needed by unit frame addons (SUF, Pitbull, oUF)
to properly display ghost state, AFK/DND status, and combat state.
Previously UnitClass() only returned the correct class for "player" and
returned "Unknown" for all other units (target, focus, party1-4, etc.).
UnitRace() had the same bug.
Now both functions read UNIT_FIELD_BYTES_0 from the entity's update
fields to resolve class (byte 1) and race (byte 0) for any unit. This
fixes unit frame addons, class-colored names, and race-based logic for
all unit IDs.
Also fix UnitRace to return 3 values (localized, English, raceId) to
match WoW's API signature — previously it only returned 1.
When typing commands like /w, /whisper, /invite, /trade, /duel, /follow,
/inspect, etc., pressing Tab now cycles through matching player names.
Name sources (in priority order):
1. Last whisper sender (most likely target for /r follow-ups)
2. Party/raid members
3. Friends list
4. Nearby visible players
Tab cycles through all matches; single match auto-appends a space.
Complements the existing slash-command tab-completion.
Fix bug where NPCs receiving moveType=4 (FacingAngle) or moveType=3
(FacingTarget) monster move packets with zero waypoints would not
rotate in place. The handler only processed orientation when hasDest
was true, but facing-only updates have no destination waypoints.
Now NPCs properly rotate when:
- moveType=4: server specifies an exact facing angle (e.g., NPC turns
to face the player during dialogue or scripted events)
- moveType=3: NPC should face a specific target entity
This fixes NPCs appearing frozen/unresponsive during scripted events,
quest interactions, and patrol waypoint facing changes.
Implement 5 guild-related WoW Lua API functions:
- IsInGuild() returns whether the player is in a guild
- GetGuildInfo("player") returns guildName, rankName, rankIndex
- GetNumGuildMembers() returns totalMembers, onlineMembers
- GetGuildRosterInfo(index) returns full 11-value tuple: name, rank,
rankIndex, level, class, zone, note, officerNote, online, status, classId
- GetGuildRosterMOTD() returns the guild message of the day
Data sourced from SMSG_GUILD_ROSTER and SMSG_GUILD_QUERY_RESPONSE.
Enables guild management addons (GreenWall, officer tools, roster UIs).
Implement the addon messaging API used by virtually every multiplayer
addon (DBM, BigWigs, EPGP, RC Loot Council, WeakAuras, etc.):
- SendAddonMessage(prefix, text, chatType, target) sends an addon
message encoded as "prefix\ttext" via the appropriate chat channel
- RegisterAddonMessagePrefix(prefix) registers a prefix for filtering
incoming addon messages
- IsAddonMessagePrefixRegistered(prefix) checks registration status
- C_ChatInfo table with aliases for the above functions (newer API compat)
Without these functions, all inter-addon communication between players
fails, breaking boss mods, loot distribution, and group coordination.
Fire PLAYER_UPDATE_RESTING when the player enters or leaves a resting
area (inn/capital city). Fires from both the SET_REST_START packet and
the QUEST_FORCE_REMOVE rest-state update path. Used by XP bar addons
and rest state indicator addons.
The Escape key now properly closes these windows before showing the
escape menu:
- Mail window (closeMailbox)
- Auction house (closeAuctionHouse)
- Quest details dialog (declineQuest)
- Quest offer reward dialog (closeQuestOfferReward)
- Quest request items dialog (closeQuestRequestItems)
- Trade window (cancelTrade)
Previously these windows required clicking their close button since
Escape would skip directly to the escape menu.
Apply at-rest values from M2 color alpha and transparency animation
tracks to batch rendering opacity. This fixes models that should render
as semi-transparent (ghosts, ethereal effects, fading doodads) but were
previously rendering at full opacity.
The fix multiplies colorAlphas[batch.colorIndex] and
textureWeights[batch.transparencyIndex] into batchOpacity during model
setup. Zero values are skipped to avoid the edge case where animated
tracks start at 0 (invisible) and animate up — baking that first
keyframe would make the entire batch permanently invisible.
Implement friend and ignore list query functions for social addons:
- GetNumFriends() returns friend count from contacts list
- GetFriendInfo(index) returns 7-value tuple: name, level, class, area,
connected, status (AFK/DND), note
- GetNumIgnores() returns ignore count
- GetIgnoreName(index) returns ignored player's name
Data sourced from the contacts list populated by SMSG_FRIEND_LIST and
SMSG_CONTACT_LIST. Area names resolved from AreaTable.dbc.
Fire GUILD_ROSTER_UPDATE from SMSG_GUILD_ROSTER and from guild events
(member join/leave/kick, promotions, leader changes, online/offline,
disbanded). Fire GUILD_MOTD with the MOTD text when received.
These events are needed by guild management addons (GuildGreet,
GuildRoster replacements, officer tools) to refresh their UI.
Fire FRIENDLIST_UPDATE from all three friend list packet handlers:
- SMSG_FRIEND_LIST (Classic format)
- SMSG_CONTACT_LIST (WotLK format)
- SMSG_FRIEND_STATUS (add/remove/online/offline updates)
Fire IGNORELIST_UPDATE when SMSG_CONTACT_LIST includes ignore entries.
These events are used by social addons to refresh their UI when the
friend/ignore list changes.
Fire UNIT_NAME_UPDATE for target/focus/player when SMSG_NAME_QUERY_RESPONSE
resolves a player's name. Nameplate and unit frame addons use this event
to update displayed names when they become available asynchronously.
Add missing addon events for three gameplay systems:
Loot rolls:
- START_LOOT_ROLL fires on SMSG_LOOT_START_ROLL with slot and countdown
- LOOT_SLOT_CLEARED fires when a loot item is removed (SMSG_LOOT_REMOVED)
Trade:
- TRADE_REQUEST when another player initiates a trade
- TRADE_SHOW when the trade window opens
- TRADE_CLOSED when trade is cancelled, declined, or completed
- TRADE_ACCEPT_UPDATE when the trade partner accepts
Duels:
- DUEL_REQUESTED with challenger name on incoming duel challenge
- DUEL_FINISHED when a duel completes or is cancelled
Add ItemIconPathResolver that lazily loads ItemDisplayInfo.dbc to map
displayInfoId → icon texture path. This fixes three Lua API functions
that previously returned nil for item icons:
- GetItemInfo() field 10 (texture) now returns the icon path
- GetActionTexture() for item-type action bar slots now returns icons
- GetLootSlotInfo() field 1 (texture) now returns proper item icons
instead of incorrectly using the spell icon resolver
Follows the same lazy-loading pattern as SpellIconPathResolver. The DBC
is loaded once on first query and cached for all subsequent lookups.
Implement the SavedVariablesPerCharacter TOC directive that many addons
use to store different settings per character (Bartender, Dominos,
MoveAnything, WeakAuras, etc.). Without this, all characters share the
same addon data file.
Per-character files are stored as <AddonName>.<CharacterName>.lua.saved
alongside the existing account-wide <AddonName>.lua.saved files. The
character name is resolved from the player GUID at world entry time.
Changes:
- TocFile::getSavedVariablesPerCharacter() parses the TOC directive
- AddonManager loads/saves per-character vars alongside account-wide vars
- Character name set from game handler before addon loading
Add commonly called frame methods as no-ops or with basic state tracking
on the frame metatable, so any CreateFrame result supports them:
Layout: SetFrameLevel/Get, SetFrameStrata/Get, SetScale/Get/GetEffective,
ClearAllPoints, SetID/GetID, GetLeft/Right/Top/Bottom, GetNumPoints,
GetPoint, SetHitRectInsets
Behavior: EnableMouse, EnableMouseWheel, SetMovable, SetResizable,
RegisterForDrag, SetClampedToScreen, SetToplevel, Raise, Lower,
StartMoving, StopMovingOrSizing, RegisterForClicks, IsMouseOver
Visual: SetBackdrop, SetBackdropColor, SetBackdropBorderColor
Scripting: HookScript (chains with existing SetScript handlers),
SetAttribute/GetAttribute, GetObjectType
Sizing: SetMinResize, SetMaxResize
These prevent the most common addon errors when addons call standard
WoW frame methods on CreateFrame results.
Add commonly used WoW global utility functions that many addons depend on:
Table: tContains, tInvert, CopyTable, tDeleteItem
String: strupper, strlower, strfind, strsub, strlen, strrep, strbyte,
strchar, strrev, gsub, gmatch, strjoin
Math: Clamp, Round
Bit ops: bit.band, bit.bor, bit.bxor, bit.bnot, bit.lshift, bit.rshift
(pure Lua implementation for Lua 5.1 which lacks native bit ops)
These prevent nil-reference errors and missing-function crashes in
addons that use standard WoW utility globals.
Add the UIDropDownMenu compatibility framework used by virtually every
addon with settings or selection menus: UIDropDownMenu_Initialize,
CreateInfo, AddButton, SetWidth, SetText, GetText, SetSelectedID, etc.
Add global font object stubs (GameFontNormal, GameFontHighlight, etc.)
referenced by CreateFontString template arguments.
Add UISpecialFrames table, InterfaceOptionsFrame for addon panels,
InterfaceOptions_AddCategory, and common font color constants
(GRAY_FONT_COLOR, NORMAL_FONT_COLOR, etc.).
These globals prevent nil-reference errors in most popular addons.
Fire PLAYER_ENTER_COMBAT when the player's auto-attack starts
(SMSG_ATTACKSTART) and PLAYER_LEAVE_COMBAT when auto-attack stops.
These events are distinct from PLAYER_REGEN_DISABLED/ENABLED — they
specifically track physical melee combat state and are used by
combat-aware addons for weapon swing timers and attack state tracking.
Fix bug where learning a talent caused an early return before firing
LEARNED_SPELL_IN_TAB and SPELLS_CHANGED events, leaving talent addons
unaware of changes. Now talent learning fires CHARACTER_POINTS_CHANGED,
PLAYER_TALENT_UPDATE, LEARNED_SPELL_IN_TAB, and SPELLS_CHANGED.
Also fire CHARACTER_POINTS_CHANGED, ACTIVE_TALENT_GROUP_CHANGED, and
PLAYER_TALENT_UPDATE from handleTalentsInfo (SMSG_TALENTS_INFO), so
talent addons update when the full talent state is received from the
server (login, spec switch, respec).
Also fire UNIT_HEALTH/UNIT_POWER events from SMSG_HEALTH_UPDATE and
SMSG_POWER_UPDATE packets for real-time unit frame updates.
SMSG_HEALTH_UPDATE and SMSG_POWER_UPDATE are high-frequency WotLK
packets that update entity health/power values but weren't firing
addon events. Unit frame addons (Pitbull, oUF, SUF) depend on these
events to update health/mana bars in real-time.
Now fire UNIT_HEALTH for player/target/focus on SMSG_HEALTH_UPDATE
and UNIT_POWER on SMSG_POWER_UPDATE, matching the events already
fired from the UPDATE_OBJECT path.
Implement 5 talent-related WoW Lua API functions:
- GetNumTalentTabs() returns class-specific talent tree count (usually 3)
- GetTalentTabInfo(tab) returns name, icon, pointsSpent, background
- GetNumTalents(tab) returns talent count in a specific tree
- GetTalentInfo(tab, index) returns full 8-value tuple with name, tier,
column, current rank, max rank, and availability
- GetActiveTalentGroup() returns active spec (1 or 2)
Data sourced from Talent.dbc, TalentTab.dbc, and the server-sent talent
info packet. Enables talent addons and spec display addons.
Implement skill line API functions that profession and tradeskill addons
need to display player skills:
- GetNumSkillLines() returns count of player skills
- GetSkillLineInfo(index) returns full 12-value tuple: name, isHeader,
isExpanded, rank, tempPoints, modifier, maxRank, isAbandonable, etc.
Data comes from SMSG_SKILLS_INFO update fields and SkillLine.dbc names.
Implement LibStub — the universal library version management system that
virtually every WoW addon framework depends on (Ace3, LibDataBroker,
LibSharedMedia, etc.). Without LibStub, most popular addons fail to load.
Also implement CallbackHandler-1.0 — the standard event callback library
used by Ace3-based addons for inter-module communication. Supports
RegisterCallback, UnregisterCallback, UnregisterAllCallbacks, and Fire.
These two libraries unlock the entire Ace3 addon ecosystem.
Fire UNIT_SPELLCAST_SENT when the player initiates a spell cast (before
server confirms), enabling cast bar addons like Quartz to show latency.
Includes target name and spell ID as arguments.
Fire UNIT_SPELLCAST_STOP whenever a cast bar should disappear:
- On successful cast completion (SMSG_SPELL_GO)
- On cast failure (SMSG_CAST_RESULT with error)
- On spell interrupt (SMSG_SPELL_FAILURE/SMSG_SPELL_FAILED_OTHER)
- On manual cast cancel
These events are essential for cast bar replacement addons to properly
track when casts begin and end.
Implement 3 critical gameplay Lua API functions:
- UseAction(slot) activates an action bar slot (spell/item), enabling
action bar addons like Bartender/Dominos to fire abilities
- CancelUnitBuff("player", index) cancels a buff by index, enabling
auto-cancel and buff management addons
- CastSpellByID(id) casts a spell by numeric ID, enabling macro addons
and spell queuing systems
Fire UNIT_HEALTH, UNIT_POWER, and UNIT_AURA events from
SMSG_PARTY_MEMBER_STATS with proper unit IDs (party1..4, raid1..40).
Previously, health/power changes for party members via the stats packet
were silent — raid frame addons never got notified.
Also fix closeLoot() not firing LOOT_CLOSED event when the loot window
is closed by the player (only handleLootReleaseResponse fired it).
Fix GetScreenWidth/GetScreenHeight/GetNumLootItems/GetFramerate being
overridden by hardcoded Lua stubs that ran after the C functions were
registered. Now the real C implementations correctly take effect.
Add GameTooltip global frame with 20+ methods (SetOwner, ClearLines,
AddLine, AddDoubleLine, SetText, NumLines, GetText, SetHyperlink, etc.)
and ShoppingTooltip1/2 — critical for virtually all WoW addons.
Add frame:CreateTexture() and frame:CreateFontString() methods returning
stub objects with common API methods, enabling UI creation addons.
Add real GetFramerate() returning actual FPS from ImGui.
Support compound unit IDs that resolve an entity's current target via
UNIT_FIELD_TARGET_LO/HI update fields. This enables addons to query
target-of-target info (e.g., UnitName("targettarget"), UnitHealth("focustarget"))
which is essential for threat meters and unit frame addons.
Fire the following events for addon compatibility:
- LOOT_OPENED, LOOT_CLOSED on loot window open/close
- GOSSIP_SHOW, GOSSIP_CLOSED on gossip/quest-list window open/close
- QUEST_DETAIL when quest details are shown to the player
- QUEST_COMPLETE when quest offer reward dialog opens
- TRAINER_SHOW, TRAINER_CLOSED on trainer window open/close
Implement 10 new WoW Lua API functions for addon compatibility:
- GetComboPoints, UnitReaction, UnitIsConnected for unit frames/raid addons
- HasAction, GetActionTexture, IsCurrentAction, IsUsableAction, GetActionCooldown
for action bar addons (Bartender, Dominos, etc.)
- UnitMana/UnitManaMax as Classic-era aliases for UnitPower/UnitPowerMax
Add "mouseover" as a valid unit ID in resolveUnitGuid so Lua API functions
like UnitName("mouseover"), UnitHealth("mouseover") etc. work for addons.
Fire UPDATE_MOUSEOVER_UNIT event when the mouseover target changes, and
PLAYER_FOCUS_CHANGED event when focus is set or cleared.
Fire MAIL_SHOW when mailbox opens (SMSG_SHOW_MAILBOX) and MAIL_CLOSED
when it closes. Fire AUCTION_HOUSE_SHOW when AH opens and AUCTION_HOUSE_CLOSED
when it closes. Used by mail addons (Postal) and AH addons (Auctionator).
Fire BANKFRAME_OPENED when bank window opens and BANKFRAME_CLOSED when
it closes. Used by bank management addons (Bagnon, BankItems) to detect
when the player is interacting with their bank.
Fire MERCHANT_SHOW when vendor window opens (SMSG_LIST_INVENTORY) and
MERCHANT_CLOSED when vendor is closed. Used by vendor price addons and
auto-sell addons that need to detect vendor interaction state.
Fire when SMSG_ACTION_BUTTONS populates the action bar on login and when
SMSG_SUPERCEDED_SPELL upgrades spell ranks on the bar. Used by action bar
addons (Bartender, Dominos) to refresh their displays.
Detect changes in player skill values after extractSkillFields() and fire
SKILL_LINES_CHANGED when any skill value changes. Used by profession
tracking addons and skill bar displays.
Fire CHAT_MSG_MONEY when gold is looted (used by gold tracking addons
like MoneyFu, Titan Panel). Fire CHAT_MSG_COMBAT_XP_GAIN when XP is
earned (used by XP tracking addons and leveling speed calculators).
Fire CHAT_MSG_LOOT addon event from SMSG_ITEM_PUSH_RESULT with the loot
message text, item ID, and count. Used by loot tracking addons (AutoLootPlus,
Loot Appraiser) and damage meters that track loot distribution.
Fires when AFK/DND status, PvP flag, ghost state, or other player flags
change via PLAYER_FLAGS update field. Enables addons that track player
status changes (FlagRSP, TRP3, etc.).
Parse randomPropertyId from SMSG_AUCTION_OWNER_NOTIFICATION to display
full item names in sold/bid/expired messages like "Your auction of
Gloves of the Monkey has sold!" Completes suffix resolution across
all 9 item display contexts.
Apply getRandomPropertyName() to SMSG_AUCTION_BIDDER_NOTIFICATION and
SMSG_AUCTION_REMOVED_NOTIFICATION so outbid/expired messages show full
item names like "You have been outbid on Leggings of the Eagle" instead
of just "Leggings". Completes suffix name resolution across all AH contexts.
Formats copper amounts into "Xg Ys Zc" strings for addon display.
GetCoinText is aliased to GetCoinTextureString. Used by money display
addons (Titan Panel, MoneyFu) and auction/vendor price formatting.