Commit graph

137 commits

Author SHA1 Message Date
Kelsi
5afd1b65a8 Fix Turtle/Classic parsing and online player textures 2026-02-13 19:40:54 -08:00
Kelsi
fb0ae26fe6 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
430c2bdcfa 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
81e082dc46 World auth: include realmId in AUTH_SESSION 2026-02-13 01:51:49 -08:00
Kelsi
f247d53309 Add expansion DBC CSVs, Turtle support, and server-specific login 2026-02-13 00:10:01 -08:00
Kelsi
7092844b5e 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
652f9e64fc Always notify TransportManager for server-marked transports 2026-02-12 15:45:53 -08:00
Kelsi
76edd3260f Infer and animate elevator transport paths 2026-02-12 15:38:39 -08:00
Kelsi
c5ecf7d475 Log transport registration mode (client vs server) 2026-02-12 15:35:31 -08:00
Kelsi
e4e61c5f3d Fix Thunder Bluff elevator transport overrides 2026-02-12 15:11:23 -08:00
Kelsi
3dac9ae657 Fix yaw conversions for online movement/entities 2026-02-12 15:08:21 -08:00
Kelsi
275914b4db Fix character appearance, previews, mount seat, and online unequip 2026-02-12 14:55:27 -08:00
Kelsi
615efd01b7 Harden packet framing/logging and checkpoint current workspace state 2026-02-12 02:27:59 -08:00
Kelsi
ef6be2f186 Auto-unsheath weapons on combat engage 2026-02-12 00:15:51 -08:00
Kelsi
5d63bb0988 Queue transport pre-spawn moves and add Z weapon sheath toggle 2026-02-12 00:14:39 -08:00
Kelsi
d6e7b0809c Fix transport sync and stabilize WMO/tunnel grounding 2026-02-12 00:04:53 -08:00
Kelsi
5171f9cad4 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
40b50454ce Stabilize taxi/state sync and creature spawn handling 2026-02-11 21:14:35 -08:00
Kelsi
38cef8d9c6 Fix taxi startup/attachment and reduce taxi streaming hitches 2026-02-11 19:28:15 -08:00
Kelsi
f752a4f517 Fix NPC visibility and stabilize world transport/taxi updates 2026-02-11 18:25:04 -08:00
Kelsi
5dae994830 Stabilize transports and correct minimap orientation 2026-02-11 17:30:57 -08:00
Kelsi
c20d5441d0 Fix transport update handling, add desktop/icon resources, and clean repo artifacts 2026-02-11 15:24:05 -08:00
Kelsi
55a40fc3aa 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
f3f3b62880 Transport hell 2026-02-11 00:54:38 -08:00
Kelsi
2e923311d0 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
c623fcef51 Add property-based mount animation discovery and procedural lean
Mount Animation System:
- Property-based jump animation discovery using sequence metadata
- Chain linkage scoring (nextAnimation/aliasNext) for accurate detection
- Correct loop detection: flags & 0x01 == 0 means looping
- Avoids brake/stop animations via blendTime penalties
- Works on any mount model without hardcoded animation IDs

Mount Physics:
- Physics-based jump height: vz = sqrt(2 * g * h)
- Configurable MOUNT_JUMP_HEIGHT constant (1.0m default)
- Procedural lean into turns for ground mounts
- Smooth roll based on turn rate (±14° max, 6x/sec blend)

Audio Improvements:
- State-machine driven mount sounds (jump, land, rear-up)
- Semantic sound methods (no animation ID dependencies)
- Debug logging for missing sound files

Bug Fixes:
- Fixed mount animation sequencing (JumpStart → JumpLoop → JumpEnd)
- Fixed animation loop flag interpretation (0x20 vs 0x21)
- Rider bone attachment working correctly during all mount actions
2026-02-10 19:30:45 -08:00
Kelsi
71d14b77c9 Implement WoW-style 3D billboard quest markers
Replace 2D ImGui text markers with proper 3D billboard sprites using BLP textures.

Features:
- Billboard rendering using Interface\GossipFrame\ BLP textures (yellow !, yellow ?, grey ?)
- WoW-style visual effects: bob animation, distance-based scaling, glow pass, distance fade
- Proper NPC height positioning with bounding box detection
- Camera-facing quads with depth testing but no depth write
- Shader-based alpha modulation for glow and fade effects

Technical changes:
- Created QuestMarkerRenderer class with billboard sprite system
- Integrated into Renderer initialization for both online and offline terrain loading
- Rewrote updateQuestMarkers() to use billboard system instead of M2 models
- Disabled old 2D ImGui renderQuestMarkers() in game_screen.cpp
- Added debug logging for initialization and marker tracking

Quest markers now render with proper WoW visual fidelity.
2026-02-09 23:41:38 -08:00
Kelsi
084a79a6bc Document that quest markers are billboard sprites, not M2 models
In WoW 3.3.5a, quest markers are NOT M2 models. They are billboard
sprites using BLP textures:
- Interface\GossipFrame\AvailableQuestIcon.blp (yellow !)
- Interface\GossipFrame\ActiveQuestIcon.blp (silver ?)
- Interface\GossipFrame\IncompleteQuestIcon.blp (gray ?)

The M2 files (QuestGiver.m2, QuestExclamation.m2, etc.) don't exist
in retail WotLK MPQs - they're from fan projects or later expansions.

Proper implementation requires billboard sprite renderer with camera-
facing quads. For now, 2D ImGui markers continue to work.
2026-02-09 23:25:22 -08:00
Kelsi
1e0c03f389 Fix quest marker M2 paths to use Spells\Quest location
Changed from World\Generic\PassiveDoodads\Quest to Spells\Quest:
- QuestGiver.m2 (yellow ! for available quests)
- QuestGiverTurnIn.m2 (silver ? for completable quests)

These are the actual paths used in WoW 3.3.5a MPQ archives.
2026-02-09 23:14:00 -08:00
Kelsi
c61a662524 Add debug logging for quest marker system troubleshooting 2026-02-09 23:08:30 -08:00
Kelsi
a4c5f35397 Implement 3D quest markers using M2 models
Loads and renders actual quest marker M2 models from
World\Generic\PassiveDoodads\Quest\ as floating 3D objects above NPCs
based on quest status, replacing 2D ImGui text markers.

Features:
- Loads QuestExclamation.m2 (yellow !) for available quests
- Loads QuestQuestionMark.m2 (silver ?) for completable quests
- Updates marker positions dynamically as NPCs move
- Automatically spawns/despawns markers based on quest status changes
- Positions markers above NPC heads using render bounds

Quest markers are now proper 3D assets consistent with WoW 3.3.5a client.
2026-02-09 23:05:23 -08:00
Kelsi
5afc9a57d1 Auto-select newly created character in selection screen
After creating a character, automatically select it in the character
list instead of defaulting to the previously selected character.

Changes:
- Added selectCharacterByName() method to CharacterScreen
- Store created character name in Application
- On creation success, auto-select the new character by name
- Falls back to saved selection if new character name doesn't match
2026-02-09 22:51:13 -08:00
Kelsi
5e0d62c2a4 Fix NPC spawning at initial player position
NPCs were not spawning when the player first entered the world because
spawnNpcs() was defined but never called. Added call to spawnNpcs() in
Application::update() when in IN_GAME state.

The function has a guard (npcsSpawned flag) so it only runs once. NPCs now
appear immediately at spawn instead of requiring the player to walk away first.

Added logging to help debug spawn preconditions.
2026-02-09 21:59:00 -08:00
Kelsi
d8002955a3 Add debug logging for GameObject spawns to diagnose duplicate cathedral
Added detailed logging in spawnOnlineGameObject() to help identify duplicate
game object spawns. Logs displayId, guid, model path, and position for both
new spawns and position updates. This will help diagnose the floating
cathedral model issue in Stormwind by showing which GUIDs are being spawned
and their coordinates.
2026-02-09 18:04:20 -08:00
Kelsi
28aa88608f Fix game object rotation - remove incorrect 90 degree offset
Game objects (wreaths, guild vaults, mailboxes, etc) were being rotated 90 degrees incorrectly due to an unnecessary orientation offset when spawning.

Fixed by removing the glm::radians(90.0f) offset from renderYaw calculation. Objects now use the correct server-provided orientation directly.

Affects both WMO and M2 game object rendering.
2026-02-09 17:18:05 -08:00
Kelsi
28d009f7db Add comprehensive NPC voice system with interaction and combat sounds
Implements full NPC voice interaction system supporting 6 different sound categories
for all playable races/genders. System loads ~450+ voice clips from MPQ archives.

Voice Categories:
- Greeting: Play on NPC right-click interaction
- Farewell: Play when closing gossip/dialog windows
- Vendor: Play when opening merchant/vendor windows
- Pissed: Play after clicking NPC 5+ times (spam protection)
- Aggro: Play when NPC enters combat with player
- Flee: Play when NPC is fleeing (ready for low-health triggers)

Features:
- Race/gender detection from NPC display IDs via CreatureDisplayInfoExtra.dbc
- Intelligent click tracking for pissed sounds
- Combat sounds use player character vocal files for humanoid NPCs
- Cooldown system prevents voice spam (2s default, combat sounds bypass)
- Generic fallback voices for unsupported NPC types
- 3D positional audio support

Voice Support:
- All playable races: Human, Dwarf, Gnome, Night Elf, Orc, Tauren, Troll, Undead
- Male and female variants for each race
- StandardNPC sounds for social interactions
- Character vocal sounds for combat

Technical Changes:
- Refactored NpcVoiceManager to support multiple sound categories
- Added callbacks: NpcFarewell, NpcVendor, NpcAggro
- Extended voice loading to parse both StandardNPC and Character vocal paths
- Integrated with GameHandler for gossip, vendor, and combat events
- Added detailed voice detection logging for debugging

Also includes:
- Sound manifest files added to docs/ for reference
- Blacksmith hammer pitch increased to 1.6x (was 1.4x)
- Blacksmith volume reduced 30% to 0.25 (was 0.35)
2026-02-09 16:03:51 -08:00
Kelsi
dab23f1895 Add ambient sound system and eliminate log spam
- Implement AmbientSoundManager with tavern/outdoor ambience
- Fix audio buffer limit (5s → 60s) for long ambient loops
- Set log level to INFO to eliminate DEBUG spam (130MB → 3.2MB logs)
- Remove excessive terrain/model/network logging
- Fix ambient sound timer sharing and pitch parameter bugs
2026-02-09 14:50:14 -08:00
Kelsi
4a7e599764 Fix NPC voices to use correct WAV format and gender detection
WotLK 3.3.5a uses .wav files for NPC voices, not .ogg as shown in retail Wowhead. Fixed audio engine to preserve original sample rate from WAV files (preventing chipmunk playback). Implemented race/gender detection using CreatureDisplayInfo.dbc and CreatureDisplayInfoExtra.dbc to play correct voice types for each NPC.
2026-02-09 02:22:20 -08:00
Kelsi
eb288d2064 Implement NPC greeting voice lines
Added NPC voice manager that plays greeting sounds when clicking on NPCs:

Features:
- Voice line library with multiple race/gender voice types (Human, Dwarf,
  Night Elf, etc.)
- 3D positional audio - voice comes from NPC location
- Cooldown system prevents spam clicking same NPC
- Randomized pitch/volume for variety
- Loads greeting sounds from character voice files in MPQ
- Generic fallback voices for NPCs without specific voice types

Voice lines trigger automatically when gossip window opens (SMSG_GOSSIP_MESSAGE).
Uses same audio system as other sound effects with ma_sound_set_position.
2026-02-09 01:29:44 -08:00
Kelsi
0fed931aa0 Implement mount ambient sounds
Added full mount sound system with:
- Wing flap sounds for flying mounts (gryphon/wyvern) when moving
- Wing idle/hovering sounds when stationary in air
- Breathing/snorting sounds for ground mounts when idle
- Occasional whinny sounds for ground mounts when moving

Sounds are loaded from MPQ files and played via AudioEngine with
randomized pitch/volume variation. Mount sound manager tracks mount
type, movement state, and flying state to play appropriate ambient
sounds at natural intervals.

Updated setMounted() to accept creature display ID and notify the
mount sound manager, which uses display ID ranges to detect mount
type (flying vs ground).
2026-02-09 01:19:35 -08:00
Kelsi
c047446fb7 Add dynamic memory-based asset caching and aggressive loading
- Add MemoryMonitor class for dynamic cache sizing based on available RAM
- Increase terrain load radius to 8 tiles (17x17 grid, 289 tiles)
- Scale worker threads to 75% of logical cores (no cap)
- Increase cache budget to 80% of available RAM, max file size to 50%
- Increase M2 render distance: 1200 units during taxi, 800 when >2000 instances
- Fix camera positioning during taxi flights (external follow mode)
- Add 2-second landing cooldown to prevent re-entering taxi mode on lag
- Update interval reduced to 33ms for faster streaming responsiveness

Optimized for high-memory systems while scaling gracefully to lower-end hardware.
Cache and render distances now fully utilize available VRAM on minimum spec GPUs.
2026-02-08 23:15:26 -08:00
Kelsi
71b52046e0 Keep M2 models permanently in VRAM to eliminate loading hitches
Modern GPUs have 8-16GB VRAM - leverage this to cache all M2 models permanently.

Changes:
- Disabled cleanupUnusedModels() call when tiles unload
- Models now stay in VRAM after initial load, even when tiles unload
- Increased taxi mounting delay from 3s to 5s for more precache time
- Added logging: M2 model count, instance count, and GPU upload duration
- Added debug logging when M2 models are uploaded per tile

This fixes the "building pops up then pause" issue - models were being:
1. Loaded when tile loads
2. Unloaded when tile unloads (behind taxi)
3. Re-loaded when flying through again (causing hitch)

Now models persist in VRAM permanently (few hundred MB for typical session).
First pass loads to VRAM, subsequent passes are instant.
2026-02-08 22:08:42 -08:00
Kelsi
92031102e4 Add mount pitch and roll for realistic taxi flight animation
Flying mounts now tilt and bank realistically during taxi flights:
- Pitch (up/down): calculated from spline tangent's z-component (altitude change)
- Roll (banking): proportional to turn rate, clamped to ~40 degrees
- Yaw: existing horizontal orientation from spline direction

Implementation:
- Added mountPitch_ and mountRoll_ to Renderer (radians)
- Updated TaxiOrientationCallback to pass yaw, pitch, roll
- Calculate pitch using asin(tangent.z) for altitude tilt
- Calculate roll from yaw change rate: -orientDiff * 2.5, clamped to ±0.7 rad
- Applied to mount rotation: glm::vec3(pitch, roll, yaw)

This fixes the "weirdness" where mounts flew sideways or without natural banking.
2026-02-08 22:05:38 -08:00
Kelsi
2e0a7e0039 Fix taxi mount orientation and eliminate tile loading hitches
Fixes two critical taxi flight issues:

1. Mount orientation now correctly faces flight direction:
   - Prevent camera controller from updating facingYaw during taxi (externalFollow_ check)
   - Taxi orientation callback system updates mount rotation from spline tangent
   - Initial orientation set when flight starts
   - Smooth Catmull-Rom spline interpolation for natural curved paths

2. Eliminate frame hitches from tile loading during flight:
   - New taxiFlightStartCallback uploads ALL precached tiles to GPU before flight begins
   - Previously tiles loaded async during 3s mount delay but uploaded 1/frame during flight
   - Now processAllReadyTiles() blocks briefly after mount delay to batch upload everything
   - Combined with 2.0s terrain update interval and aggressive culling for smooth flight

Additional optimizations:
   - Aggressive taxi culling: skip models <15 units, all foliage/trees, underwater objects
   - Max render distance reduced to 150 units during taxi
   - Movement heartbeat packets disabled during taxi (server controls position)
   - Reduced taxi speed from 32 to 18 units/sec to prevent streaming overload
2026-02-08 22:00:33 -08:00
Kelsi
536b3cea48 Implement comprehensive taxi flight optimizations and proper spline paths
Major improvements:
- Load TaxiPathNode.dbc for actual curved flight paths (no more flying through terrain)
- Add 3-second mounting delay with terrain precaching for entire route
- Implement LOD system for M2 models with distance-based quality reduction
- Add circular terrain loading pattern (13 tiles vs 25, 48% reduction)
- Increase terrain cache from 2GB to 8GB for modern systems

Performance optimizations during taxi:
- Cull small M2 models (boundRadius < 3.0) - not visible from altitude
- Disable particle systems (weather, smoke, M2 emitters) - saves ~7000 particles
- Disable specular lighting on M2 models - saves Blinn-Phong calculations
- Disable shadow mapping on M2 models - saves shadow map sampling and PCF

Technical details:
- Parse TaxiPathNode.dbc spline waypoints for curved paths around terrain
- Build full path from node pairs using TaxiPathEdge lookup
- Precache callback triggers during mounting delay for smooth takeoff
- Circular tile loading uses Euclidean distance check (dx²+dy² <= r²)
- LOD fallback to base mesh when higher LODs unavailable

Result: Buttery smooth taxi flights with no terrain clipping or performance hitches
2026-02-08 21:32:38 -08:00
Kelsi
cbbf819c0d Increase terrain load radius during taxi for aggressive caching
During taxi flights, increased terrain load radius from 2 to 4 tiles
(5x5 to 9x9 grid) to pre-cache more tiles ahead of flight path. Returns
to normal 5x5 after landing. 2GB cache stores loaded tiles for fast
retrieval. WMO/M2 models already cached in RAM once loaded.
2026-02-08 20:51:17 -08:00
Kelsi
36834332eb Enable terrain streaming during taxi flights with RAM cache
Changed taxi terrain streaming from frozen (9999s) to active (0.3s
interval). The 2GB tile cache now serves tiles from RAM without
blocking, making terrain rendering safe and smooth during flight paths.
2026-02-08 20:05:04 -08:00
Kelsi
ef54f62df0 Add multi-tier unstuck system with void fall detection
Replace broken hardcoded-coordinate unstuck with tiered fallbacks:
last safe position > hearth bind > map spawn. Track safe positions
only on real geometry, let player fall after 500ms with no ground,
and auto-trigger unstuck after 5s of continuous falling.
2026-02-08 15:37:34 -08:00
Kelsi
8fee55f99f Fix /unstuckgy hang by skipping WMO floor search
Add CameraController::teleportTo() that directly places the player at
the target position without the expensive floor-search loop in reset().
The loop does hundreds of WMO collision checks which hangs in cities.
2026-02-08 15:13:55 -08:00
Kelsi
046d4615ea Fix M2 texture loading, /unstuckgy, and WMO floor detection
- Add mutex to AssetManager::loadTexture/loadDBC/fileExists to prevent
  StormLib thread-safety races that silently fail texture reads; stop
  caching texture load failures so transient errors are retried.
- Replace /unstuckgy DBC lookup (which used wrong coordinate transform)
  with hardcoded safe locations per map.
- Widen WMO floor raycast from single grid cell to ±1 unit range query
  to catch bridge/walkway triangles at cell boundaries.
- Tighten swept collision hit threshold (0.5 → 0.15) and grid query
  margin (2.5 → 1.5) to prevent false-positive wall pushes.
- Tighten post-wall-push Z snap lower bound (-1.0 → -0.3) to prevent
  gradual floor sinking.
2026-02-08 14:17:04 -08:00