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.
Tracks PLAYER_FIELD_MOD_DAMAGE_DONE_POS (7 schools at field 1171) and
PLAYER_FIELD_MOD_HEALING_DONE_POS (field 1192) from server update fields.
getSpellPower() returns the max damage bonus across magic schools 1-6.
getHealingPower() returns the raw healing bonus.
Both values displayed in the character screen Combat section alongside
the previously added attack power, dodge, parry, crit, and rating fields.
Adds update field tracking for WotLK secondary combat statistics:
- UNIT_FIELD_ATTACK_POWER / RANGED_ATTACK_POWER (fields 123, 126)
- PLAYER_DODGE/PARRY/BLOCK/CRIT_PERCENTAGE (fields 1025-1029)
- PLAYER_RANGED_CRIT_PERCENTAGE, PLAYER_SPELL_CRIT_PERCENTAGE1 (1030, 1032)
- PLAYER_FIELD_COMBAT_RATING_1 (25 slots at 1231, hit/expertise/haste/etc.)
Both CREATE_OBJECT and VALUES update paths now populate these fields.
The Character screen Stats tab shows them when received from the server,
with graceful fallback when not available (Classic/TBC expansions).
Field indices verified against AzerothCore 3.3.5a UpdateFields.h.
Track player titles from SMSG_TITLE_EARNED into knownTitleBits_ set,
read active title from PLAYER_CHOSEN_TITLE update field (WotLK index
1349), expose via getFormattedTitle()/sendSetTitle() on GameHandler.
Add SetTitlePacket builder (CMSG_SET_TITLE: int32 titleBit, -1=clear).
Titles window (H key) lists all earned titles from CharTitles.dbc,
highlights the active one in gold, and lets the player click to equip
or unequip a title with a single server round-trip.
The REST_STATE_EXPERIENCE field was erroneously set to the same index as
PLAYER_SKILL_INFO_START in all four expansion JSON files, causing the
rested XP tracker to read the first skill slot ID as the rested XP value.
Correct indices derived from layout: EXPLORED_ZONES_START + 128 zone
fields (or 64 for Classic) immediately precede PLAYER_FIELD_COINAGE, with
REST_STATE_EXPERIENCE in the one slot between them.
- WotLK: 636 → 1169 (1041 + 128 = 1169, before COINAGE=1170)
- Classic: 718 → 1175 (1111 + 64 = 1175, before COINAGE=1176)
- TBC: 928 → 1440 (1312 + 128 = 1440, before COINAGE=1441)
- Turtle: 718 → 1175 (same as Classic layout)
Add UNIT_FIELD_STAT0-4 (STR/AGI/STA/INT/SPI) to the UF enum and wire up
per-expansion indices in all four expansion JSON files (WotLK: 84-88,
Classic/Turtle: 138-142, TBC: 159-163). Read the values in both CREATE
and VALUES player update handlers and store in playerStats_[5].
renderStatsPanel now uses the server-authoritative totals when available,
falling back to the previous 20+level estimate only if the server hasn't
sent UNIT_FIELD_STAT* yet. Item-query bonuses are still shown as (+N)
alongside the server total for both paths.
Reads OBJECT_FIELD_SCALE_X (field 4, cross-expansion) from CREATE_OBJECT
update fields and passes it through the full creature and game object spawn
chain: game_handler callbacks → pending spawn structs → async load results
→ createInstance() calls. This gives boss giants, gnomes, children, and
other non-unit-scale NPCs correct visual size, and ensures scaled GOs
(e.g. large treasure chests, oversized plants) render at the server-specified
scale rather than always at 1.0.
- Added OBJECT_FIELD_SCALE_X to UF enum and all expansion update_fields.json
- Added float scale to CreatureSpawnCallback and GameObjectSpawnCallback
- Propagated scale through PendingCreatureSpawn, PreparedCreatureModel,
PendingGameObjectSpawn, PreparedGameObjectWMO
- Used scale in charRenderer/m2Renderer/wmoRenderer createInstance() calls
- Sanity-clamped raw float to [0.01, 100.0] range before use
- Add ITEM_FIELD_DURABILITY (60) and ITEM_FIELD_MAXDURABILITY (61) to
update_field_table.hpp enum and wotlk/update_fields.json
- Add curDurability/maxDurability to OnlineItemInfo and ItemDef structs
- Parse durability fields in OBJECT_CREATE and OBJECT_VALUES handlers;
preserve existing values on partial updates (fixes stale durability
being reset to 0 on stack-count-only updates)
- Propagate durability to ItemDef in all 5 rebuildOnlineInventory() paths
- Implement GameHandler::repairItem() and repairAll() via CMSG_REPAIR_ITEM
(itemGuid=0 repairs all equipped items per WotLK protocol)
- Add canRepair flag to ListInventoryData; set it when player selects
GOSSIP_OPTION_ARMORER in gossip window
- Show "Repair All" button in vendor window header when canRepair=true
- Display color-coded durability in item tooltip (green >50%, yellow
>25%, red <=25%)
- Track PLAYER_REST_STATE_EXPERIENCE update field for all expansions
(WotLK=636, Classic=718, TBC=928, Turtle=718)
- Set isResting_ flag from SMSG_SET_REST_START packet
- XP bar shows rested bonus as a lighter purple overlay extending
beyond the current fill to (currentXp + restedXp) position
- Tooltip text changes to "%u / %u XP (+%u rested)" when bonus exists
- "zzz" indicator shown at bar right edge while resting
- Fix shutdown hang: skip vmaDestroyAllocator (walked thousands of allocations),
replace unsafe pthread_timedjoin_np with plain join + early-exit checks in workers
- Bank window: full icon rendering, click-and-hold pickup (0.10s), drag-drop for
all bank slots including bank bag equip slots, same-slot drop detection
- Loading screen: process one tile per frame for live progress updates
- Camera reset: trust server position in online mode to avoid spawning under WMOs
- Fix PLAYER_BYTES/PLAYER_BYTES_2 field indices, preserve purchasedBankBagSlots
across inventory rebuilds, fix bank slot purchase result codes
- Correct UNIT_FIELD_BYTES_0 to index 23 (was incorrectly 56) in update fields JSON and table
- Replace single power/maxPower with powers[7]/maxPowers[7] arrays indexed by power type
- Add setPowerByType/setMaxPowerByType helpers for setting specific power types
The character stats panel was showing Armor: 0 because summing armor
from item query responses is fragile (depends on correct BuyCount/damage
block parsing). Instead, read the server-authoritative total armor
directly from UNIT_FIELD_RESISTANCES (physical resistance, index 0)
in the player entity update fields.
Added UNIT_FIELD_RESISTANCES to the UF enum and all four expansion
JSON files with correct wire indices:
WotLK 3.3.5a: 99 (NPC_FLAGS=82 + emotestate + stat×5 + posstat×5 + negstat×5)
TBC 2.4.3: 185 (NPC_FLAGS=168 + same relative layout)
Classic 1.12: 154 (NPC_FLAGS=147 + emotestate + stat×5, no posstat/negstat)
Turtle WoW: 154 (same as Classic)
Stats panel uses server armor when > 0, falls back to summed item-query
armor otherwise. Armor rating resets to 0 on world entry and is updated
from both CREATE_OBJECT and VALUES update blocks.
Vanilla CMSG_CAST_SPELL target mask is uint16 (not uint32 like WotLK),
the extra 2 bytes were corrupting packets. Also implement full bag
content tracking: extract container slot GUIDs from CONTAINER update
objects, set proper bag sizes, and populate bag items in inventory
rebuild.
Replace hardcoded WotLK protocol constants with a data-driven architecture
supporting Classic 1.12.1, TBC 2.4.3, and WotLK 3.3.5a. Each expansion
has JSON profiles for opcodes, update fields, and DBC layouts, plus C++
polymorphic packet parsers for binary format differences (movement flags,
speed fields, transport data, spline format, char enum layout).
Key components:
- ExpansionRegistry: scans Data/expansions/*/expansion.json at startup
- OpcodeTable: logical enum <-> wire values loaded from JSON
- UpdateFieldTable: field indices loaded from JSON per expansion
- DBCLayout: schema-driven DBC field lookups replacing magic numbers
- PacketParsers: WotLK/TBC/Classic parsers with correct flag positions
- Multi-manifest AssetManager: layered manifests with priority ordering
- HDPackManager: overlay texture packs with expansion compatibility
- Auth screen expansion picker replacing hardcoded version dropdown