PR #19 (572bb4ef) swapped CharSections.dbc field indices, placing
Texture1-3 at fields 4-6 and VariationIndex/ColorIndex at 8-9. Binary
analysis of the actual DBC files (Classic, TBC, Turtle — all identical
layout, no WotLK-specific override) confirms the correct order is:
Field 4 = VariationIndex
Field 5 = ColorIndex
Field 6 = Texture1 (string)
Field 7 = Texture2 (string)
Field 8 = Texture3 (string)
Field 9 = Flags
With the wrong indices, VariationIndex/ColorIndex reads returned string
offsets (garbage values that never matched), so all CharSections lookups
failed silently — producing white untextured character models at the
login screen and in-world.
Fixes all 4 expansion JSON layouts, hardcoded fallbacks in
character_preview.cpp, application.cpp, and character_create_screen.cpp.
Also handles the single-layer edge case (body skin only, no face/underwear)
by loading the texture directly instead of skipping compositing.
Extend tapped-by-other detection to the focus frame, matching the
target frame and nameplate treatment. All three UI elements (nameplate,
target frame, focus frame) now consistently show grey for tapped mobs.
Extend the tapped-by-other-player check to the target frame. Mobs
tagged by another player now show a grey name color on the target
frame, matching the grey nameplate treatment and WoW's behavior.
Players can now see at a glance on both nameplates AND target frame
whether a mob is tagged.
Check UNIT_DYNFLAG_TAPPED_BY_PLAYER (0x0004) on hostile NPC nameplates.
Mobs tagged by another player now show grey health bars instead of red,
matching WoW's visual indication that the mob won't yield loot/XP.
Mobs with TAPPED_BY_ALL_THREAT_LIST (0x0008) still show red since
those are shared-tag mobs that give loot to everyone.
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.
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.
Extend random property name resolution to the Bids tab and Your Auctions
(seller) tab. All three auction house tabs now display items with their
full suffix names (e.g., "Gloves of the Monkey" instead of "Gloves").
Append suffix name from getRandomPropertyName() to auction browse results
so items display as "Leggings of the Eagle" instead of just "Leggings"
in the auction house search table. Uses the randomPropertyId field from
the SMSG_AUCTION_LIST_RESULT packet data.
Add cancelQueuedSpell() method that clears queuedSpellId_ and
queuedSpellTarget_. Wire /cancelqueuedspell and /stopspellqueue
slash commands. Useful for combat macros that need to prevent
queued spells from firing after a current cast.
/dump <expression> evaluates a Lua expression and prints the result to
chat. For tables, iterates key-value pairs and displays them. Aliases:
/print. Useful for addon development and debugging game state queries
like "/dump GetSpellInfo(133)" or "/dump UnitHealth('player')".
Add AddonManager::reload() which saves all SavedVariables, shuts down the
Lua VM, re-initializes it, rescans .toc files, and reloads all addons.
Wire /reload, /reloadui, /rl slash commands that call reload() and fire
VARIABLES_LOADED + PLAYER_LOGIN + PLAYER_ENTERING_WORLD lifecycle events.
Essential for addon development and troubleshooting.
When the dungeon finder initiates a role check (SMSG_LFG_ROLE_CHECK_UPDATE
state=2), show a centered popup with Tank/Healer/DPS checkboxes and
Accept/Leave Queue buttons. Accept sends CMSG_LFG_SET_ROLES with the
selected role mask. Previously only showed passive "Role check in progress"
text with no way to respond.
Remove unused getPlayerUnit() helper in lua_engine.cpp (-Wunused-function).
Increase countStr buffer from 8 to 16 bytes in action bar item count
display to eliminate -Wformat-truncation warning for %d with int32_t.
Build is now warning-free.
Show [Winning] (green) or [Outbid] (red) labels on the Bids tab based on
bidderGuid vs player GUID comparison. Show [Bid] (gold) indicator on the
seller's Auctions tab when someone has placed a bid on their listing.
Improves auction house usability by making bid status visible at a glance.
Add QuestPoi struct and setQuestPois() to WorldMap, render quest objective
markers as cyan circles with golden outlines and quest title labels. Wire
gossipPois_ (from SMSG_QUEST_POI_QUERY_RESPONSE) through GameScreen to the
world map so quest objectives are visible alongside party dots and taxi nodes.
Foundation for WoW-compatible addon support:
- Vendor Lua 5.1.5 source as a static library (extern/lua-5.1.5)
- TocParser: parses .toc files (## directives + file lists)
- LuaEngine: Lua 5.1 VM with sandboxed stdlib (no io/os/debug),
WoW-compatible print() that outputs to chat, GetTime() stub
- AddonManager: scans Data/interface/AddOns/ for .toc files,
loads .lua files on world entry, skips LoadOnDemand addons
- /run <code> slash command for inline Lua execution
- HelloWorld test addon that prints to chat on load
Integration: AddonManager initialized after asset manager, addons
loaded once on first world entry, reset on logout. XML frame
parsing is deferred to a future step.
When hovering a /use macro whose item's on-use spell isn't in the DBC
(no rich spell tooltip available), the tooltip fell back to showing raw
macro text. Now searches the item info cache and shows the full item
tooltip (stats, quality, binding, description) as a more useful
fallback for /use macros.
Macros with /use ItemName tried to find the item as a spell name for
icon resolution, which fails for items without a matching spell (e.g.
engineering trinkets, quest items). Now falls back to searching the
item info cache by name and showing the item's display icon when no
spell name matches.
Add [target=mouseover] and the @ shorthand syntax (@focus, @pet,
@mouseover, @player, @target) to the /macrohelp output. These are
commonly used for mouseover healing macros and were already supported
but not documented in the in-game help.
The /help text was missing several commonly-used commands: /castsequence,
/use, /threat, /combatlog, /mark, /raidinfo, /assist, /inspect,
/chathelp. Reorganized categories for clarity and added all missing
entries to match the expanded auto-complete list.
Macros with /use ItemName (e.g. /use Healthstone, /use Engineering
trinket) had no icon, cooldown, or tooltip on the action bar because
only /cast and /castsequence were recognized. Now the spell resolution
also handles /use by looking up the item name in the item info cache
and finding its on-use spell ID. Added getItemInfoCache() accessor.
The macro primary spell cache stored 0 (no spell found) when a macro
referenced a spell the player hadn't learned yet. After learning the
spell from a trainer or leveling up, the cache was never refreshed,
so the macro button stayed broken. Now tracks the known spell count
and clears the cache when it changes, ensuring newly learned spells
are resolved on the next frame.
Macros with /castsequence were treated as having no primary spell, so
they showed no icon, cooldown, range, power, or tooltip on the action
bar. Now both resolveMacroPrimarySpellId() and the icon derivation
code recognize /castsequence commands, strip the reset= spec, and
use comma-separation to find the first spell in the sequence. This
gives /castsequence macros the same visual indicators as /cast macros.
The error-flash overlay (red fade on spell cast failure) only applied to
SPELL-type slots. Macro buttons never flashed red when their primary
spell failed to cast. Now resolves the macro's primary spell and checks
the actionFlashEndTimes_ map for a matching flash, completing macro
action bar parity with spell buttons across all 6 visual indicators.
The insufficient-power indicator only applied to SPELL-type slots.
Macro buttons like /cast Fireball never showed the power tint when the
player was out of mana. Now resolves the macro's primary spell and
checks its power cost against the player's current power, giving the
same visual feedback as regular spell buttons.
The out-of-range indicator (red tint) only applied to SPELL-type action
bar slots. Macro buttons like /cast Frostbolt never turned red even when
the target was out of range. Now resolves the macro's primary spell via
the cached lookup and checks its max range against the target distance,
giving the same visual feedback as regular spell buttons.
Hovering a macro button on the action bar previously showed "Macro #N"
with raw macro text. Now resolves the macro's primary spell via the
cached lookup and shows its full rich tooltip (name, school, cost, cast
time, range, description) — same as hovering a regular spell button.
Falls back to the raw text display if no primary spell is found.
Also shows the cooldown remaining in red when the spell is on cooldown.
The macro primary spell cache was keyed by action bar slot index, so
switching characters or rearranging macros could return stale spell IDs
from the previous character's macro in that slot. Now keyed by macro ID,
which is stable per-macro regardless of which slot it occupies.
The macro cooldown display from the previous commit iterated all known
spells (400+) every frame for each macro on the action bar, doing
lowercase string comparisons. Moved the spell name resolution into a
cached lookup (macroPrimarySpellCache_) that only runs once per macro
and is invalidated when macro text is edited. The per-frame path now
just does a single hash map lookup + spellCooldowns check.
Macro buttons on the action bar never showed cooldowns — a /cast
Fireball macro would display no cooldown sweep or timer even when
Fireball was on cooldown. Now resolves the macro's primary spell (from
the first /cast command, stripping conditionals and alternatives) and
checks its cooldown via spellCooldowns. The cooldown sweep overlay and
countdown text display using the resolved spell's remaining time.
FSR2/FSR3 upscaling mode was forcibly reverted to FSR1 on every startup
unless the WOWEE_ALLOW_STARTUP_FSR2 environment variable was set. This
meant users had to re-select FSR 3.x and re-enable frame generation on
every launch. Removed the env var requirement since the deferred
activation (wait until IN_WORLD state) already provides sufficient
startup safety by preventing FSR init during login/character screens.
Chat tabs with unread messages now pulse yellow to attract attention.
The existing unread count "(N)" suffix was text-only and easy to miss,
especially for whisper and guild tabs. The pulsing color clears when
the tab is clicked, matching standard WoW chat tab behavior.
Add commonly-used WoW macro conditionals:
- [raid]/[noraid] — checks if the player is in a raid group (groupType
== 1) vs a regular party. Used for conditional healing/targeting in
raid content.
- [spec:1]/[spec:2] — checks the active talent spec (1-based index).
Used for dual-spec macros that swap gear sets or use different
rotations per spec.
Updated /macrohelp to list the new conditionals.
The /macrohelp listed [target=pet] as supported but the conditional
evaluator didn't handle the "pet" specifier for target= or @ syntax.
Now resolves to the player's active pet GUID (or skips the alternative
if no pet is active). Essential for hunter/warlock macros like:
/cast [target=pet] Mend Pet
/cast [@pet,dead] Revive Pet
Add indoor/outdoor state macro conditionals using the renderer's WMO
interior detection. Essential for mount macros that need to select
ground mounts indoors vs flying mounts outdoors. The Renderer now
caches the insideWmo state in playerIndoors_ and exposes it via
isPlayerIndoors(). Updated /macrohelp to list the new conditionals.
Add frequently-used macro conditionals for pet and group state:
- [pet]/[nopet] — checks if the player has an active pet (hunters,
warlocks, DKs). Essential for pet management macros.
- [group]/[nogroup]/[party] — checks if the player is in a party or
raid. Used for conditional targeting and ability usage.
Updated /macrohelp output to list the new conditionals.
Players can now type /macrohelp to see all supported macro conditionals
grouped by category (state, target, form, keys, aura). Also added to
the /help output and chat auto-complete list. This helps users discover
the macro system without external documentation.
Add commonly-used WoW macro conditionals that were missing:
- [mounted]/[nomounted] — checks isMounted() state
- [swimming]/[noswimming] — checks SWIMMING movement flag
- [flying]/[noflying] — checks CAN_FLY + FLYING movement flags
- [stealthed]/[nostealthed] — checks UNIT_FLAG_SNEAKING (0x02000000)
- [channeling]/[nochanneling] — checks if currently channeling a spell
These are essential for common macros like mount/dismount toggles,
rogue opener macros, and conditional cast sequences.
The proficiency check added in the previous commit only applied to the
ItemDef tooltip variant (inventory items). Vendor, loot, and AH
tooltips use the ItemQueryResponseData variant which was missing the
check. Now both tooltip paths show "You can't use this type of item."
in red when the player lacks weapon or armor proficiency.
Item tooltips now display a red "You can't use this type of item."
warning when the player lacks proficiency for the weapon or armor
subclass (e.g. a mage hovering over a plate item or a two-handed
sword). Uses the existing canUseWeaponSubclass/canUseArmorSubclass
checks against SMSG_SET_PROFICIENCY bitmasks.
Add a "Usable" checkbox to the AH search UI that filters results to
items the player can actually equip/use (server-side filtering via the
usableOnly parameter in CMSG_AUCTION_LIST_ITEMS). Also ensure token
item names for extended costs are queried from the server via
ensureItemInfo() so they display properly instead of "Item#12345".
Load ItemExtendedCost.dbc and show specific costs (e.g. "2000 Honor",
"200 Arena", "30x Badge of Justice") instead of generic "[Tokens]" for
vendor items with extended costs. Items with both gold and token costs
now show both. Token item names are resolved from item info cache.
Classic and TBC lack equipment set opcodes, so sending save/use/delete
packets would transmit wire opcode 0xFFFF and potentially disconnect the
client. Now all three methods check wireOpcode != 0xFFFF before sending,
and the Outfits tab is only shown when the expansion supports equipment
sets (via supportsEquipmentSets() check).
Add saveEquipmentSet() and deleteEquipmentSet() methods that send
CMSG_EQUIPMENT_SET_SAVE and CMSG_DELETEEQUIPMENT_SET packets. The save
packet captures all 19 equipment slot GUIDs via packed GUID encoding.
The Outfits tab now always shows (not just when sets exist), with an
input field to create new sets and Update/Delete buttons per set.
Add PLAYER_FIELD_HONOR_CURRENCY and PLAYER_FIELD_ARENA_CURRENCY to the
update field system for WotLK (indices 1422/1423) and TBC (1505/1506).
Parse values from both CREATE_OBJECT and VALUES update paths, and show
them in the character Stats tab under a PvP Currency section.