GetNumSavedInstances() returns count of saved instance lockouts.
GetSavedInstanceInfo(index) returns 9-field WoW signature: name,
mapId, resetTimeRemaining, difficulty, locked, extended,
instanceIDMostSig, isRaid, maxPlayers.
Uses existing instanceLockouts_ from SMSG_RAID_INSTANCE_INFO.
Enables SavedInstances and lockout tracking addons to display
which raids/dungeons the player is locked to and when they reset.
GetNumBattlefieldScores() returns player count in the BG scoreboard.
GetBattlefieldScore(index) returns 12-field WoW API signature: name,
killingBlows, honorableKills, deaths, honorGained, faction, rank,
race, class, classToken, damageDone, healingDone.
GetBattlefieldWinner() returns winning faction (0=Horde, 1=Alliance)
or nil if BG is still in progress.
RequestBattlefieldScoreData() sends MSG_PVP_LOG_DATA to refresh the
scoreboard from the server.
Uses existing BgScoreboardData from MSG_PVP_LOG_DATA handler.
Enables BG scoreboard addons and PvP tracking.
UnitIsPVP(unit) checks UNIT_FLAG_PVP (0x1000) on the unit's flags
field. Used by unit frame addons to show PvP status indicators.
UnitIsPVPFreeForAll(unit) checks for FFA PvP flag.
GetBattlefieldStatus() returns stub ("none") for addons that check
BG queue state on login. Full BG scoreboard data exists in
GameHandler but is rendered via ImGui.
Items with the Unique-Equipped flag (itemFlags & 0x1000000) now
display "Unique-Equipped" in the tooltip header. This is distinct
from "Unique" (maxCount=1) — Unique-Equipped means you can carry
multiple but only equip one (e.g., trinkets, rings with the flag).
Items with a startQuestId now display "This Item Begins a Quest" in
gold text at the bottom of the tooltip, matching WoW's behavior.
Helps players identify quest-starting drops in their inventory.
Passes startsQuest flag through _GetItemTooltipData from the
startQuestId field in ItemQueryResponseData.
Spell descriptions now substitute \$o1/\$o2/\$o3 with the total
periodic damage/healing: base_per_tick × (duration / 3sec).
Example: SW:Pain with base=4 (5 per tick), duration=18sec (6 ticks):
Before: "Causes X Shadow damage over 18 sec"
After: "Causes 30 Shadow damage over 18 sec"
Combined with \$s1 (per-tick/instant) and \$d (duration), the three
most common spell template variables are now fully resolved. This
covers the vast majority of spell tooltips.
Spell descriptions now substitute \$d with actual duration values:
Before: "X damage over X sec"
After: "30 damage over 18 sec"
Implementation:
- DurationIndex field (40) added to all expansion Spell.dbc layouts
- SpellDuration.dbc loaded during cache build: maps index → base ms
- cleanSpellDescription substitutes \$d with resolved seconds/minutes
- getSpellDuration() accessor on GameHandler
Combined with \$s1/\$s2/\$s3 from the previous commit, most common
spell description templates are now fully resolved with real values.
Spell descriptions now substitute \$s1/\$s2/\$s3 template variables
with actual effect base points from Spell.dbc (field 80/81/82).
For example: "causes \$s1 Fire Damage" → "causes 562 Fire Damage".
Implementation:
- Added EffectBasePoints0/1/2 to all 4 expansion DBC layouts
- SpellNameEntry now stores effectBasePoints[3]
- loadSpellNameCache reads base points during DBC iteration
- cleanSpellDescription substitutes \$s1→abs(base)+1 when available
- getSpellEffectBasePoints() accessor on GameHandler
Values are DBC base points (before spell power scaling). Still uses
"X" placeholder for unresolved variables (\$d, \$o1, etc.).
CalendarGetDate() returns real weekday, month, day, year from the
system clock. Used by calendar addons and date-aware UI elements.
CalendarGetNumPendingInvites() and CalendarGetNumDayEvents() return 0
as stubs — prevents nil errors in addons that check calendar state.
GetDifficultyInfo(id) returns name, groupType, isHeroic, maxPlayers
for WotLK instance difficulties:
0: "5 Player" (party, normal, 5)
1: "5 Player (Heroic)" (party, heroic, 5)
2: "10 Player" (raid, normal, 10)
3: "25 Player" (raid, normal, 25)
4/5: 10/25 Heroic raids
Used by boss mod addons (DBM, BigWigs) and instance info displays
to show the current dungeon difficulty.
Fire WEATHER_CHANGED(weatherType, intensity) when the server sends
SMSG_WEATHER with a new weather state. Enables weather-aware addons
to react to rain/snow/storm transitions.
GetWeatherInfo() returns current weatherType (0=clear, 1=rain, 2=snow,
3=storm) and intensity (0.0-1.0). Weather data is already tracked by
game_handler and used by the renderer for particle effects and fog.
GuildRoster() triggers CMSG_GUILD_ROSTER to request updated guild
member data from the server. Called by guild roster addons and the
social panel to refresh the member list.
SortGuildRoster() is a no-op (sorting is handled client-side by
the ImGui guild roster display).
BuyMerchantItem(index, count) purchases an item from the current
vendor by merchant slot index. Resolves itemId and slot from the
vendor's ListInventoryData.
SellContainerItem(bag, slot) sells an item from the player's
inventory to the vendor. Supports backpack (bag=0) and bags 1-4.
Enables auto-sell addons (Scrap, AutoVendor) and vendor UI addons
to buy/sell items programmatically.
RepairAllItems(useGuildBank) sends CMSG_REPAIR_ITEM to repair all
equipped items at the current vendor. Checks CanMerchantRepair before
sending. Optional useGuildBank flag for guild bank repairs.
One of the most commonly needed addon functions — enables auto-repair
addons to fix all gear in a single call when visiting a repair vendor.
AcceptTrade() locks in the trade offer via CMSG_ACCEPT_TRADE.
CancelTrade() cancels an open trade via CMSG_CANCEL_TRADE.
InitiateTrade(unit) starts a trade with a target player.
Uses existing GameHandler trade functions and TradeStatus tracking.
Enables trade addons and macro-based trade acceptance.
Quality-colored item links for auction house items, enabling AH addons
to display clickable item links in their UI and chat output.
This is the 100th commit of this session, bringing the total to
408 API functions across all WoW gameplay systems.
GetInboxNumItems() returns count of mail messages.
GetInboxHeaderInfo(index) returns the full 13-field WoW API signature:
packageIcon, stationeryIcon, sender, subject, money, COD, daysLeft,
hasItem, wasRead, wasReturned, textCreated, canReply, isGM.
GetInboxText(index) returns the mail body text.
HasNewMail() checks for unread mail (minimap icon indicator).
Uses existing mailInbox_ populated from SMSG_MAIL_LIST_RESULT.
Enables postal addons (Postal, MailOpener) to read inbox data.
GetNumGlyphSockets() returns 6 (WotLK glyph slot count).
GetGlyphSocketInfo(index, talentGroup) returns enabled, glyphType
(1=major, 2=minor), glyphSpellID, and icon for each socket.
Uses existing learnedGlyphs_ array populated from SMSG_TALENTS_INFO.
Enables talent/glyph inspection addons.
This commit brings the total API count to exactly 400 functions.
Complete the pet action bar interaction:
- CastPetAction(index) — cast the pet spell at the given bar slot
by sending the packed action via sendPetAction
- TogglePetAutocast(index) — toggle autocast for the pet spell
at the given slot via togglePetSpellAutocast
- PetDismiss() — send dismiss pet command
- IsPetAttackActive() — whether pet is currently in attack mode
Together with the previous pet bar functions (HasPetUI, GetPetActionInfo,
PetAttack, PetFollow, PetWait, PetPassiveMode, PetDefensiveMode), this
completes the pet action bar system for hunters/warlocks/DKs.
Implement pet action bar functions using existing pet data:
- HasPetUI() — whether player has an active pet
- GetPetActionInfo(index) — name, icon, isActive, autoCastEnabled
for each of the 10 pet action bar slots
- GetPetActionCooldown(index) — cooldown state stub
- PetAttack() — send attack command to current target
- PetFollow() — send follow command
- PetWait() — send stay command
- PetPassiveMode() — set passive react mode
- PetDefensiveMode() — set defensive react mode
All backed by existing SMSG_PET_SPELLS data (petActionSlots_,
petCommand_, petReact_, petAutocastSpells_) and sendPetAction().
GetActionBarPage() returns the current action bar page (1-6).
ChangeActionBarPage(page) switches pages and fires ACTIONBAR_PAGE_CHANGED
via the Lua frame event system. Used by action bar addons and the
default UI's page arrows / shift+number keybinds.
Action bar page state tracked in Lua global __WoweeActionBarPage.
CastShapeshiftForm(index) casts the spell for the given form slot:
- Warrior: Battle Stance(2457), Defensive(71), Berserker(2458)
- Druid: Bear(5487), Travel(783), Cat(768), Flight(40120),
Moonkin(24858), Tree(33891)
- Death Knight: Blood(48266), Frost(48263), Unholy(48265)
- Rogue: Stealth(1784)
This makes stance bar buttons functional — clicking a form button
actually casts the corresponding spell to switch forms.
CancelShapeshiftForm stub for cancelling current form.
GetShapeshiftFormInfo(index) returns icon, name, isActive, isCastable
for each shapeshift form slot. Provides complete form tables for:
- Warrior: Battle Stance, Defensive Stance, Berserker Stance
- Druid: Bear, Travel, Cat, Swift Flight, Moonkin, Tree of Life
- Death Knight: Blood/Frost/Unholy Presence
- Rogue: Stealth
isActive is true when the form matches the current shapeshiftFormId_.
GetShapeshiftFormCooldown stub returns no cooldown.
Together with GetShapeshiftForm and GetNumShapeshiftForms from the
previous commit, this completes the stance bar API that addons use
to render and interact with form/stance buttons.
Add UNIT_FIELD_BYTES_1 to all expansion update field tables (Classic=133,
TBC/WotLK=137). Byte 3 of this field contains the shapeshift form ID
(Bear=1, Cat=3, Travel=4, Moonkin=31, Tree=36, Battle Stance=17, etc.).
Track form changes in the VALUES update handler and fire
UPDATE_SHAPESHIFT_FORM + UPDATE_SHAPESHIFT_FORMS events when the
form changes. This enables stance bar addons and druid form tracking.
New Lua functions:
- GetShapeshiftForm() — returns current form ID (0 = no form)
- GetNumShapeshiftForms() — returns form count by class (Warrior=3,
Druid=6, DK=3, Rogue=1, Priest=1, Paladin=3)
GetEnchantInfo(enchantId) looks up the enchantment name from
SpellItemEnchantment.dbc (field 14). Returns the display name
like "Crusader", "+22 Intellect", or "Mongoose" for a given
enchant ID.
Used by equipment comparison addons and tooltip addons to display
enchantment names on equipped gear. The enchant ID comes from the
item's ITEM_FIELD_ENCHANTMENT update field.
Also adds getEnchantName() to GameHandler for C++ access.
Spell descriptions from DBC contain raw template variables like
\$s1, \$d, \$o1 that refer to effect values resolved at runtime.
Without DBC effect data loaded, these showed as literal "\$s1" in
tooltips, making descriptions hard to read.
Now strips template variables and replaces with readable placeholders:
- \$s1/\$s2/\$s3 → "X" (effect base points)
- \$d → "X sec" (duration)
- \$o1 → "X" (periodic total)
- \$a1 → "X" (radius)
- \$\$ → "$" (literal dollar sign)
- \${...} blocks → stripped
Result: "Hurls a fiery ball that causes X Fire Damage" instead of
"Hurls a fiery ball that causes \$s1 Fire Damage". Not as informative
as real values, but significantly more readable.
Implement the WoW Mixin pattern used by modern addons:
- Mixin(obj, ...) — copies fields from mixin tables into obj
- CreateFromMixins(...) — creates a new table from mixin templates
- CreateAndInitFromMixin(mixin, ...) — creates and calls Init()
- MergeTable(dest, src) — shallow-merge src into dest
These enable OOP-style addon architecture used by LibSharedMedia,
WeakAuras, and many Ace3-based addons for class/object creation.
strgfind = string.gmatch alias (deprecated WoW function used by
older addons that haven't migrated to string.gmatch).
tostringall(...) converts all arguments to strings and returns
them. Used by chat formatting and debug addons that need to safely
stringify mixed-type argument lists.
SpellStopCasting() cancels the current cast via cancelCast(). Used by
macro addons and cast-cancel logic (e.g., /stopcasting macro command).
UnitFullName/GetUnitName aliases for UnitName — some addons use these
variant names.
SpellIsTargeting() returns false (no AoE targeting reticle in this
client). SpellStopTargeting() is a no-op stub. Both prevent errors
in addons that check targeting state.
GetClassColor(className) returns r, g, b, colorString from the
RAID_CLASS_COLORS table. Used by unit frame addons, chat addons,
and party/raid frames to color player names by class.
QuestDifficultyColors table provides standard quest difficulty
color mappings (impossible=red, verydifficult=orange, difficult=yellow,
standard=green, trivial=gray, header=gold). Used by quest log and
quest tracker addons for level-appropriate coloring.
GetMaxPlayerLevel() returns the level cap for the active expansion:
60 (Classic/Turtle), 70 (TBC), 80 (WotLK). Used by XP bar addons
and leveling trackers.
GetAccountExpansionLevel() returns the expansion tier: 1 (Classic),
2 (TBC), 3 (WotLK). Used by addons that adapt features based on
which expansion is active.
Both read from the ExpansionRegistry's active profile at runtime.
CURRENT_SPELL_CAST_CHANGED fires when the player starts a new cast
via handleSpellStart. Some addons register for this as a catch-all
signal that the current spell state changed, complementing the more
specific UNIT_SPELLCAST_START/STOP/FAILED events.
PLAYER_COMBO_POINTS now fires from the existing SMSG_UPDATE_COMBO_POINTS
handler — the handler already updated comboPoints_ but never notified
Lua addons. Rogue/druid combo point displays and DPS rotation addons
register for this event.
LOOT_READY fires alongside LOOT_OPENED when a loot window opens. Some
addons register for this WoW 5.x+ event name instead of LOOT_OPENED.
The TBC item query parser left subclassName empty, so TBC items showed
no weapon/armor type in tooltips or the character sheet (e.g., "Sword",
"Plate", "Shield" were all blank). The Classic and WotLK parsers
correctly map subClass IDs to names.
Fix: call getItemSubclassName() in the TBC parser, same as WotLK.
Expose getItemSubclassName() in the header (was static, now shared
across parser files).
Items with maxCount=1 now show "Unique" in white text below the name.
Items with the Heroic flag (0x8) show "Heroic" in green text. Both
display before the bind type line, matching WoW's tooltip order.
Heroic items (from heroic dungeon/raid drops) are visually
distinguished from their normal-mode counterparts. Unique items
(trinkets, quest items, etc.) show the carry limit clearly.
Item tooltips now display spell effects in green text:
- "Use: Restores 2200 health over 30 sec" (trigger 0)
- "Equip: Increases attack power by 120" (trigger 1)
- "Chance on hit: Strikes the enemy for 95 Nature damage" (trigger 2)
Passes up to 5 item spell entries through _GetItemTooltipData with
spellId, trigger type, spell name, and spell description from DBC.
The tooltip builder maps trigger IDs to "Use: ", "Equip: ", or
"Chance on hit: " prefixes.
This completes the item tooltip with all major WoW tooltip sections:
quality name, bind type, equip slot/type, armor, damage/DPS/speed,
primary stats, combat ratings, resistances, spell effects, gem sockets,
required level, flavor text, and sell price.
Spell tooltips now show the spell description text (e.g., "Hurls a
fiery ball that causes 565 to 655 Fire Damage") in gold/yellow text
between the cast info and cooldown display.
New GetSpellDescription(spellId) C function exposes the description
field from SpellNameEntry (loaded from Spell.dbc via the spell name
cache). Descriptions contain the raw DBC text which may include
template variables ($s1, $d, etc.) — these show as-is until template
substitution is implemented.
Add gem socket display to item tooltips — shows [Meta Socket],
[Red Socket], [Yellow Socket], [Blue Socket], or [Prismatic Socket]
based on socketColor mask from ItemQueryResponseData.
Also pass itemSetId through _GetItemTooltipData for addons that
track set bonuses.
Register power-type-specific aliases (UnitRage, UnitEnergy, UnitFocus,
UnitRunicPower) that map to the existing lua_UnitPower function. Some
Classic/TBC addons call these directly instead of the generic UnitPower.
All return the unit's current power value regardless of type — the
underlying function reads from the entity's power field.
Replace PlaySound no-op stub with a real implementation that maps
WoW sound IDs and names to the UiSoundManager methods:
By ID: 856/1115→button click, 840→quest activate, 841→quest complete,
862→bag open, 863→bag close, 888→level up
By name: IGMAINMENUOPTION→click, IGQUESTLISTOPEN→quest activate,
IGQUESTLISTCOMPLETE→quest complete, IGBACKPACKOPEN/CLOSE→bags,
LEVELUPSOUND→level up, TALENTSCREEN→character sheet
This gives addons audio feedback when they call PlaySound() — button
clicks, quest sounds, and other UI sounds now actually play instead
of being silently swallowed.
DISPLAY_SIZE_CHANGED fires when the window is resized via
SDL_WINDOWEVENT_RESIZED, allowing UI addons to adapt their layout
to the new screen dimensions (5 FrameXML registrations).
UNIT_QUEST_LOG_CHANGED("player") fires alongside QUEST_LOG_UPDATE
at all 6 quest log modification points, for addons that register
for this variant instead (4 FrameXML registrations).
The tab-based addon message detection was too aggressive — any chat
message containing a tab character was treated as an addon message
and silently dropped from regular chat display. This could suppress
legitimate player messages containing tabs (from copy-paste).
Now only matches as addon message when:
- Chat type is PARTY/RAID/GUILD/WHISPER/etc. (not SAY/YELL/EMOTE)
- Prefix before tab is <=16 chars (WoW addon prefix limit)
- Prefix contains no spaces (addon prefixes are identifiers)
This prevents false positives while still correctly detecting addon
messages formatted as "DBM4\ttimer:start:10".
UNIT_QUEST_LOG_CHANGED("player") now fires at all 6 locations where
QUEST_LOG_UPDATE fires — quest accept, complete, objective update,
abandon, and server-driven quest log changes. Some addons register
for this event instead of QUEST_LOG_UPDATE (4 registrations in
FrameXML). Both events are semantically equivalent for the player.
Detect addon messages in the SMSG_MESSAGECHAT handler by looking for
the 'prefix\ttext' format (tab delimiter). When detected, fire
CHAT_MSG_ADDON with args (prefix, message, channel, sender) instead
of the regular CHAT_MSG_* event, and suppress the raw message from
appearing in chat.
This enables inter-addon communication used by:
- Boss mods (DBM, BigWigs) for timer/alert synchronization
- Raid tools (oRA3) for ready checks and cooldown tracking
- Group coordination addons for pull countdowns and assignments
Works with the existing SendAddonMessage/RegisterAddonMessagePrefix
functions that format outgoing messages as 'prefix\ttext'.
Some addons register for SPELL_UPDATE_USABLE instead of
ACTIONBAR_UPDATE_USABLE to detect when spell usability changes
due to power fluctuations. Fire both events together when the
player's mana/rage/energy changes.
When the player's mana/rage/energy changes, action bar addons need
ACTIONBAR_UPDATE_USABLE to update button dimming (grey out abilities
the player can't afford). Now fires from both the SMSG_POWER_UPDATE
handler and the SMSG_UPDATE_OBJECT VALUES power field change path.
Without this event, action bar buttons showed as usable even when the
player ran out of mana — the usability state only refreshed on spell
cast attempts, not on power changes.
Implement core vendor query functions from ListInventoryData:
- GetMerchantNumItems() — count of items for sale
- GetMerchantItemInfo(index) — name, texture, price, stackCount,
numAvailable, isUsable for each vendor item
- GetMerchantItemLink(index) — quality-colored item link
- CanMerchantRepair() — whether vendor offers repair service
Enables auto-sell addons (AutoVendor, Scrap) to read vendor inventory
and check repair capability. Data sourced from SMSG_LIST_INVENTORY
via currentVendorItems + itemInfoCache for names/icons.