Commit graph

280 commits

Author SHA1 Message Date
Kelsi
6b1f3e3637 Remove debug logging and add negative texture cache to fix lag spikes
Remove PPM composite dumps, MODEL1_BOUNDS vertex analysis, TEX_REGION
logging, FOUNTAIN_PARTICLES debug output, and verbose chat/warden gate
logging. Add negative cache for failed texture loads to prevent repeated
file I/O for missing textures like deathknighteyeglow.blp.
2026-02-16 00:45:47 -08:00
Kelsi
08189df528 Fix composite cache clearing to not delete NPC textures
clearCompositeCache() now only clears the lookup map without deleting
GPU textures, preventing NPC and other instance textures from being
accidentally destroyed during player equipment changes.
2026-02-16 00:19:07 -08:00
Kelsi
b0d989bce7 Clean up bare shin geoset comments 2026-02-15 20:59:29 -08:00
Kelsi
1a5c43d18a Fix character geoset mapping and texture corruption on equipment change
Corrected CharGeosets group assignments verified via vertex bounding boxes:
- Group 4 (401+) = gloves/forearms, Group 5 (501+) = boots/shins,
  Group 8 (801+) = sleeves (chest-controlled), Group 9 = kneepads,
  Group 13 (1301+) = pants/trousers, Group 20 (2002) = bare feet
- Changed bare shin default from 501 to 502 for better width match
  with thigh mesh (0.39 vs 0.32, thighs are 0.42)
- Added clearCompositeCache() to prevent stale composite textures
  from being reused across equipment changes
- Fixed character preview geoset defaults to match corrected mapping
2026-02-15 20:53:01 -08:00
Kelsi
27d6150ecb Add mailbox system and fix logging performance stutter
Implement full mail send/receive: SMSG_SHOW_MAILBOX, CMSG_GET_MAIL_LIST,
SMSG_MAIL_LIST_RESULT, CMSG_SEND_MAIL, SMSG_SEND_MAIL_RESULT, mail take
money/item/delete/mark-as-read, and inbox/compose UI windows.

Fix periodic stuttering in Stormwind caused by synchronous per-line disk
flushes in the logger — remove fileStream.flush() and std::endl, downgrade
high-volume per-packet/per-model/per-texture LOG_INFO to LOG_DEBUG.
2026-02-15 14:00:41 -08:00
Kelsi
eeb053a854 Fix character texture compositing and add YouTube video to README
Use authoritative WoW Model Viewer atlas coordinates (256x256 reference)
for face, underwear, and body region placement. Previously all coordinates
were hardcoded at 512x512 scale causing overlays to be clipped on the
256x256 base skin. Also include face upper+lower textures from
CharSections.dbc in compositing for both player and other-player characters.
2026-02-15 12:53:15 -08:00
Kelsi
1b33f47cf4 Fix PopStyleVar mismatches and character geoset IDs
Fix 9 PopStyleVar(2) calls that should be PopStyleVar(1) across
player frame, target frame, cast bar, party frames, buff bar, escape
menu, death dialog, and resurrect dialog. Fix action bar from
PopStyleVar(2) to PopStyleVar(4) to match 4 pushes.

Fix character geoset defaults: 301→302 (bare hands), 701→702 (ears),
1501→1502 (back/cloak), add 802 (wristbands). No WoW character model
uses geoset 301/701/1501; all use 302/702/1502 as base. This fixes
missing hands/arms on undead and other races with separate hand meshes.
2026-02-15 06:09:38 -08:00
Kelsi
6dff088361 Add original music to login rotation and zone playlists
11 original tracks in assets/Original Music/ now play on the login
screen and in thematically matched zones across Eastern Kingdoms and
Kalimdor. Added crossfadeToFile to MusicManager for local file
playback during zone transitions. New zones: Tirisfal, Undercity,
Barrens, STV, Duskwood, Burning Steppes, Searing Gorge, Ironforge,
Loch Modan, Orgrimmar, Durotar, Mulgore, Thunder Bluff, Darkshore,
Teldrassil, Darnassus.
2026-02-15 05:53:27 -08:00
Kelsi
a0a327c96c Fix particle glow transparency for textures without alpha 2026-02-14 22:32:12 -08:00
Kelsi
d9c317afaf Fix grey WMO curtains by skipping window/sky materials, fix /unstuck
- Skip WMO batches with material flags F_SIDN (0x20) or F_WINDOW (0x40)
  which are transparent sky/window panes that render as grey curtains
- Fix /unstuck: always nudge 5 units forward first, then sample floor at
  destination instead of teleporting back to last safe position (which
  could be the stuck location itself)
2026-02-14 21:15:28 -08:00
Kelsi
edc7177144 Skip individual untextured WMO batches to fix grey mesh in Orgrimmar
The previous fix only skipped groups where ALL batches were untextured.
Groups with a mix of textured and untextured batches still rendered the
untextured ones as solid grey geometry. Now skip each untextured batch
individually during rendering.
2026-02-14 21:05:51 -08:00
Kelsi
beb99bff3f Fix mount sounds, grey WMO meshes, taxi landing, tree animations, and classic dismount
- Per-family mount sounds (kodo, tallstrider, mechanostrider, etc.) detected from M2 model path
- Skip WMO groups with SHOW_SKYBOX flag or all-untextured batches (grey mesh in Orgrimmar)
- Freeze physics during taxi landing until terrain loads to prevent falling through void
- Disable bone animations on tropical vegetation (palm, bamboo, banana, etc.) to fix wiggling
- Snap player to final taxi waypoint on flight completion
- Extract mount aura spell ID from classic UNIT_FIELD_AURAS for CMSG_CANCEL_AURA dismount
- Increase /unstuck forward nudge to 5 units
2026-02-14 21:04:20 -08:00
Kelsi
b76527c2f7 Add MCLQ water, TaxiPathNode transports, and vanilla M2 particles
- Parse MCLQ sub-chunks in vanilla ADTs for water rendering (WotLK uses MH2O)
- Load TaxiPathNode.dbc for MO_TRANSPORT world-coordinate paths (vanilla boats)
- Parse data[] from SMSG_GAMEOBJECT_QUERY_RESPONSE (taxiPathId for transports)
- Support vanilla M2 particle emitters (504-byte struct, different from WotLK 476)
- Add character preview texture diagnostic logging
- Fix disconnect handling on character screen (show error only when no chars)
2026-02-14 20:20:43 -08:00
Kelsi
54ad8f38b2 docs: update README and guides for multi-expansion direction 2026-02-14 18:05:37 -08:00
Kelsi
8395f77325 Improve equipment texture performance and accuracy
Cache composite textures by input key so identical NPC equipment
combos share one GPU texture. Use DBC layout system for
ItemDisplayInfo texture component fields instead of hardcoded
indices (cross-expansion support). Selective player equipment
re-emission on item query response instead of broadcasting to
all players.
2026-02-14 15:48:58 -08:00
Kelsi
2d1b2b0539 Resolve emote text from DBC for other players' text emotes
Load third-person emote text templates (othersTarget/othersNoTarget)
from EmotesText.dbc fields 3 and 7 alongside existing sender text.
Build reverse lookup map from dbcId to EmoteInfo for incoming
SMSG_TEXT_EMOTE resolution. Other players now show proper emote
descriptions like "Player dances with Target" instead of generic
"Player performs an emote" text.
2026-02-14 15:11:43 -08:00
Kelsi
a3ae03606b Add chat tabs, networked text emotes, channel system, and chat bubbles
Chat tabs filter messages into General/Combat/Whispers/Trade tabs. Text
emotes now send CMSG_TEXT_EMOTE to server and display incoming emotes
from other players. Channel system auto-joins General/Trade on login with
/join, /leave, and /1-/9 shortcuts. Chat bubbles render as ImGui overlays
above entities for SAY/YELL messages with fade-out animation.
2026-02-14 14:30:09 -08:00
Kelsi
71a3cb4de3 Fix mesh artifacts on vanilla/TBC M2 models when using expansion overlays
Vanilla (v256) and TBC (v263) M2 files embed skin data directly, parsed
during M2Loader::load(). The code unconditionally loaded external .skin
files afterwards, which resolved to WotLK-format .skin files (48-byte
submeshes) from the base manifest — overwriting the correctly parsed
embedded skin (32-byte submeshes) and causing mesh corruption on all
character models. Guard all 13 loadSkin() call sites with version >= 264
so external .skin files are only loaded for WotLK M2s that need them.
2026-02-14 13:57:54 -08:00
Kelsi
7d115aaa70 Add per-expansion asset overlay system and fix CharSections DBC layout
Expansion overlays allow each expansion to supplement the base asset data
via an assetManifest field in expansion.json, loaded at priority 50 (below
HD packs). The asset extractor gains --reference-manifest for delta-only
extraction. Also fixes CharSections field indices (VariationIndex=4,
ColorIndex=5, Texture1=6) across all DBC layout references.
2026-02-14 00:00:26 -08:00
Kelsi
9376fea2e6 Fix weapon attachments and inspect fallback 2026-02-13 20:26:55 -08:00
Kelsi
bcfc075e1e Fix Turtle/Classic parsing and online player textures 2026-02-13 19:40:54 -08:00
Kelsi
d9cbf1ffc8 Vanilla/Turtle WoW compatibility: fix UPDATE_OBJECT, chat, equipment, creatures
- Route SMSG_UPDATE_OBJECT through polymorphic parsers for correct
  vanilla format (uint8 updateFlags, 6 speeds vs WotLK uint16/9)
- Fix SMSG_DESTROY_OBJECT for vanilla (8 bytes, no isDeath field)
- Add MSG_MOVE_* handlers for other player movement relay
- Add ClassicPacketParsers::parseMessageChat with targetGuid read
  and monster-type name handling
- Resolve chat sender names from player name cache before display
- Fix CSV DBC field 0 always treated as numeric ID (fixes 16+ garbled
  Turtle CSVs including Map, AreaTable, Spell, CreatureDisplayInfo)
- Add CSV DBC validation: reject garbled CSVs (>80% zero IDs) and
  fall back to binary DBC files
- Fix ItemDisplayInfo texture component field index (14+ not 15+)
  for binary DBC with gender-aware suffix resolution
- Spawn other players as visible M2 models via creature callback
- Map name cache dedup prevents overwrites from duplicate CSV records
2026-02-13 18:59:09 -08:00
Kelsi
f136de101e Vanilla/Turtle WoW support: M2 loading, bone parsing, textures, auth
- Vanilla M2 bone struct (108 bytes) with 28-byte animation tracks
- Version-aware bone parsing (vanilla vs WotLK format detection)
- Fix CharSections.dbc field layout for vanilla (variation/color at 4-5)
- Remove broken CharSections.csv files (all fields marked as strings)
- Expansion data reload on profile switch (DBC cache clear, layout reload)
- Vanilla packet encryption (VanillaCrypt XOR-based header crypt)
- Extended character preview geoset range (0-99) for vanilla models
- DBC cache clear support in AssetManager
2026-02-13 16:53:28 -08:00
Kelsi
90a1aa8a92 Add multi-expansion support with data-driven protocol layer
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
2026-02-12 22:56:36 -08:00
Kelsi
4b24736113 Replace MPQ runtime with loose file asset system
Extract assets from MPQ archives into organized loose files indexed by
manifest.json, enabling fully parallel reads without StormLib serialization.
Add asset_extract and blp_convert tools, PNG texture override support.
2026-02-12 20:32:14 -08:00
Kelsi
5eb40e455d Bound MPQ archive lookup cache; remove always-on composite dumps; track texture cache entries 2026-02-12 16:29:36 -08:00
Kelsi
8cbbd3c6be Normalize texture cache keys to prevent duplicate GPU textures 2026-02-12 16:15:25 -08:00
Kelsi
0ff0f2f995 Fix character appearance, previews, mount seat, and online unequip 2026-02-12 14:55:27 -08:00
Kelsi
cb735f3137 Harden packet framing/logging and checkpoint current workspace state 2026-02-12 02:27:59 -08:00
Kelsi
8e95b69949 Harden transport updates and fix waterfall particle tint 2026-02-12 00:45:24 -08:00
Kelsi
a0f8120157 Fix transport sync and stabilize WMO/tunnel grounding 2026-02-12 00:04:53 -08:00
Kelsi
8bf63b1f06 Fix taxi state sync and transport authority; reduce runtime log overhead; restore first-person self-hide 2026-02-11 22:27:02 -08:00
Kelsi
74062aa25f Stabilize taxi/state sync and creature spawn handling 2026-02-11 21:14:35 -08:00
Kelsi
41a33249a5 Fix taxi startup/attachment and reduce taxi streaming hitches 2026-02-11 19:28:15 -08:00
Kelsi
b0af2c928d Fix NPC visibility and stabilize world transport/taxi updates 2026-02-11 18:25:04 -08:00
Kelsi
6ff27e789b Stabilize transports and correct minimap orientation 2026-02-11 17:30:57 -08:00
Kelsi
6274e29b45 Add transport registration to movement packets (WIP - awaiting server MOVEMENT updates)
- Added transport fields to MovementInfo struct (transportGuid, transportX/Y/Z/O, transportTime)
- Updated MovementPacket::build() to serialize transport data when ONTRANSPORT flag set
- Modified GameHandler::sendMovement() to include transport info when player on transport
- Fixed coordinate conversion for transport offsets (server↔canonical)
- Added transport tracking in both CREATE_OBJECT and MOVEMENT update handlers
- Connected M2Renderer to WMORenderer for hierarchical doodad transforms
- Server-authoritative transport movement (no client-side animation)

Issue: Server not sending MOVEMENT updates for transports, so they remain stationary.
Transports register successfully but don't animate without server position updates.
2026-02-11 02:23:37 -08:00
Kelsi
30c1f3709c Transport hell 2026-02-11 00:54:38 -08:00
Kelsi
6bca624e98 Add transport system, fix NPC spawning, and improve water rendering
Transport System (Phases 1-7):
- Implement TransportManager with Catmull-Rom spline path interpolation
- Add WMO dynamic transforms for moving transport instances
- Implement player attachment via world position composition
- Add test transport with circular path around Stormwind harbor
- Add /transport board and /transport leave console commands
- Reuse taxi flight spline system and external follow camera mode

NPC Spawn Fixes:
- Add smart ocean spawn filter: blocks land creatures at high altitude over water (Z>50)
- Allow legitimate water creatures at sea level (Z≤50) to spawn correctly
- Fixes Elder Grey Bears, Highland Striders, and Plainscreepers spawning over ocean
- Snap online creatures to terrain height when valid ground exists

NpcManager Removal:
- Remove deprecated NpcManager (offline mode no longer supported)
- Delete npc_manager.hpp and npc_manager.cpp
- Simplify NPC animation callbacks to use only creatureInstances_ map
- Move NPC callbacks to game initialization in application.cpp

Water Rendering:
- Fix tile seam gaps caused by per-vertex wave randomization
- Add distance-based blending: seamless waves up close (<150u), grid effect far away (>400u)
- Smooth transition between seamless and grid modes (150-400 unit range)
- Preserves aesthetic grid pattern at horizon while eliminating gaps when swimming
2026-02-10 21:29:10 -08:00
Kelsi
55e12032ae Immediately cancel mount fidgets when movement starts
Fidget animations were continuing to play for a frame when movement started.
Now forces immediate switch to run animation.

Changes:
- Check for movement + active fidget at start of animation logic
- Force play run animation immediately to stop fidget
- Only check fidget completion when not moving (optimization)
- Removed duplicate mountActiveFidget_ = 0 in movement branch

Fidgets now stop instantly when player starts moving on mount.
2026-02-10 20:46:46 -08:00
Kelsi
4f8667e23f Add steep slope limiting to prevent terrain clipping
Added slope normal checking to reject surfaces too steep to walk.
Prevents character/mount from clipping through steep terrain.

Changes:
- Added MIN_WALKABLE_NORMAL threshold (0.7 = ~45° max slope)
- WMO collision: query surface normal, reject if normalZ < 0.7
- M2 collision: query surface normal, reject if normalZ < 0.7
- Updated M2Renderer::getFloorHeight to output surface normal
- M2 already had internal 0.35 check (~70°), new 0.7 is more restrictive

Steep slopes now block movement instead of allowing clipping.
2026-02-10 20:45:25 -08:00
Kelsi
f544e42438 Reduce idle sound frequency and restore fidget discovery
Idle sounds were too frequent and strict criteria blocked all fidgets.

Changes:
- Idle sounds now 45-90 seconds apart (was 20-40)
- Fidget criteria back to OR (frequency OR replay) instead of AND
- Keeps all ID exclusions: 2-3, 5-9, 11-21 to prevent battle animations
- Should now discover proper fidgets while filtering problematic ones
2026-02-10 20:36:12 -08:00
Kelsi
995998882c Disable pained sounds and tighten fidget criteria
Removed jump/land sounds (attack/wound sounds had pained growls).
Made fidget discovery much stricter to exclude jerky battle animations.

Changes:
- Disabled playJumpSound for ground mounts (attack sounds too aggressive)
- Disabled playLandSound for ground mounts (wound sounds have growls)
- Fidget criteria now requires BOTH frequency AND replay (not OR)
- Excluded IDs 11-15 (attacks) in addition to 16-21 (combat)
- Only animations with proper idle metadata will be selected
2026-02-10 20:32:43 -08:00
Kelsi
d1bf792f03 Add comprehensive fidget animation logging for debugging
Added debug logging to show ALL non-looping, short, stationary animations
regardless of metadata, so we can identify hoof stamps and head tosses.

Shows:
- All potential fidgets (no metadata filter)
- Animation ID, duration, frequency, replay timers, flags, next animation
- Helps identify which IDs are the shuffles/stamps/tosses on Palomino
2026-02-10 20:28:56 -08:00
Kelsi
66ab3aa84d Exclude death and wound animations from fidget discovery
Horse was playing death animation on idle. Added explicit filtering
to exclude death (5-6), wounds (7-9), combat (16-21), and specials (2-3).

Changes:
- Check animation ID ranges before adding to fidget list
- Prevents death/wound animations from being selected as idle fidgets
- Keeps metadata-based discovery but adds safety exclusions
2026-02-10 20:28:13 -08:00
Kelsi
895045dd00 Add dedicated snort and whinny idle sounds with longer intervals
Created specific idle sound pool using only horse snorts and whinnies.
Re-enabled idle sounds with much longer interval (20-40 seconds).

Changes:
- Added horseIdleSounds_ pool: mHorseStand3A (snort) + mHorseAggroA (whinny)
- Updated playIdleSound() to use dedicated pool instead of mixed breath sounds
- Increased idle sound interval from 8-15s to 20-40s (less frequent)
- Removed flying mount idle sounds (too aggressive)
- Increased volume slightly (0.35x) for better audibility
2026-02-10 20:20:26 -08:00
Kelsi
c39f6f2144 Disable mount idle sounds and relax fidget discovery
Idle sounds were too frequent/upsetting, and strict criteria found no fidgets.

Changes:
- Disabled idle sounds entirely (commented out in updateCharacterAnimation)
- Relaxed fidget criteria: frequency OR replay (not both required)
- Keeps proper metadata-based discovery (frequency/replay fields)
- Comprehensive logging shows candidates and selections
2026-02-10 20:13:42 -08:00
Kelsi
92786ce32d Tighten fidget discovery to exclude combat animations
Previous criteria caught combat animations with grunts instead of subtle fidgets.
Now using strict filtering and comprehensive logging to identify real fidgets.

Changes:
- Duration: 500-1200ms (very short movements only)
- Movement: <0.01 speed (nearly stationary)
- Exclude: IDs 2-3 (specials), 16-21 (combat/attack range)
- Added candidate logging: shows ALL potential fidgets for debugging
- Removed upper ID limit to catch fidgets at any position
2026-02-10 20:01:32 -08:00
Kelsi
ceea647c96 Fix mount idle fidget animations playing fully without interruption
Fidgets were stuttering because normal animation updates immediately overrode them.
Now tracks active fidget and prevents normal animation updates until fidget completes.

Changes:
- Added mountActiveFidget_ to track currently playing fidget animation
- Check fidget completion using getAnimationState before allowing normal updates
- Only trigger new fidgets when no fidget is active
- Cancel active fidget on movement
- Expanded fidget search criteria: duration up to 3000ms, ID range 1-20
- Added debug logging to show discovered fidgets and when they complete
2026-02-10 19:59:01 -08:00
Kelsi
60be823c94 Add mount idle fidget animations and ambient sounds
Implements WoW-style mount idle behavior when player is stationary:
- Fidget animations: discovered via property search (non-looping, 500-1500ms, stationary, IDs 1-10)
- Triggers random fidget every 6-12 seconds when standing still
- Ambient idle sounds: snorts/breaths for ground mounts, soft wing sounds for flyers
- Triggers random idle sound every 8-15 seconds when stationary
- Both systems reset timers on movement to avoid triggering while riding
2026-02-10 19:53:23 -08:00