Commit Graph

246 Commits

Author SHA1 Message Date
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
7fee4c91af Fix transport update handling, add desktop/icon resources, and clean repo artifacts 2026-02-11 15:24:05 -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
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
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
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
Kelsi
c782df0348 Fix mount sounds with real MPQ paths and family detection
Mount Sound System:
- Use actual creature sounds from MPQ (Horse, Ram, Wolf, Tiger, Dragons)
- Separate sound pools: jump (attack), landing (wound), rear-up (aggro)
- Mount family detection: HORSE, RAM, WOLF, TIGER, RAPTOR, DRAGON
- Family logged on mount for future per-family sound selection

Sound Mappings:
- Flying mounts: Dragon wing flaps + DragonHawk screeches
- Ground mounts: Horse attack (jump), wound (land), aggro (rear-up)
- Ready for family-specific sound selection (TODO)

Mount Lean:
- Procedural lean into turns for ground mounts
- Physics-based: turn rate × 0.15, max ±14°, 6x/sec blend
- Returns to upright when not turning or when flying
- Rider follows mount roll automatically via bone attachment
2026-02-10 19:49:07 -08:00
Kelsi
d0d42193c8 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
9d9b34ddca Optimize M2 and terrain rendering for 60fps target
Implements aggressive performance optimizations to improve frame rate from 29fps to 40fps:

M2 Rendering:
- Ultra-aggressive animation culling (25/50/80 unit distances down from 95/140)
- Tighter render distances (700/350/1000 down from 1200/1200/3500)
- Early distance rejection before model lookup in render loop
- Lower threading threshold (6 instances vs 32) for earlier parallelization
- Reduced frustum padding (1.5x vs 2.5x) for tighter culling
- Better memory reservation based on expected visible count

Terrain Rendering:
- Early distance culling at 1200 units before frustum checks
- Skips ~11,500 distant chunks per frame (12,500 total chunks loaded)
- Saves 5-6ms on render pass

Performance Impact:
- Render time: 20ms → 14-15ms (30% faster)
- Frame rate: 29fps → 40fps (+11fps)
- Total savings: ~9ms per frame
2026-02-10 17:23:41 -08:00
Kelsi
7d44d2211d Implement WoW-accurate DBC-driven sky system with lore-faithful celestial bodies
Add SkySystem coordinator that follows WoW's actual architecture where skyboxes
are authoritative and procedural elements serve as fallbacks. Integrate lighting
system across all renderers (terrain, WMO, M2, character) with unified parameters.

Sky System:
- SkySystem coordinator manages skybox, celestial bodies, stars, clouds, lens flare
- Skybox is authoritative (baked stars from M2 models, procedural fallback only)
- skyboxHasStars flag gates procedural star rendering (prevents double-star bug)

Celestial Bodies (Lore-Accurate):
- Two moons: White Lady (30-day cycle, pale white) + Blue Child (27-day cycle, pale blue)
- Deterministic moon phases from server gameTime (not deltaTime toys)
- Sun positioning driven by LightingManager directionalDir (DBC-sourced)
- Camera-locked sky dome (translation ignored, rotation applied)

Lighting Integration:
- Apply LightingManager params to WMO, M2, character renderers
- Unified lighting: directional light, diffuse color, ambient color, fog
- Star occlusion by cloud density (70% weight) and fog density (30% weight)

Documentation:
- Add comprehensive SKY_SYSTEM.md technical guide
- Update MEMORY.md with sky system architecture and anti-patterns
- Update README.md with WoW-accurate descriptions

Critical design decisions:
- NO latitude-based star rotation (Azeroth not modeled as spherical planet)
- NO always-on procedural stars (skybox authority prevents zone identity loss)
- NO universal dual-moon setup (map-specific celestial configurations)
2026-02-10 14:36:17 -08:00
Kelsi
c3170eebb2 Integrate lighting system with renderer and shaders
Wire DBC-driven lighting to terrain shaders:
- Add LightingManager to Renderer
- Initialize lighting manager with AssetManager
- Update lighting each frame with player position
- Feed lighting params to terrain shader uniforms:
  * Ambient color
  * Diffuse (sun) color and direction
  * Fog color, start, end distances
- Fallback to skybox-based fog if lighting unavailable

TODOs for full integration:
- Wire actual map ID from game state
- Wire server game time from login packets
- Add weather/underwater state detection
- Apply lighting to WMO/M2/skybox shaders

Current state: Uses local time + Eastern Kingdoms map (0)
Next: Hook up SMSG_LOGIN_SETTIMESPEED for real game time
2026-02-10 13:48:50 -08:00
Kelsi
453e41674c Implement WoW 3.3.5a DBC-driven lighting system
Add complete Blizzard-style time-of-day lighting pipeline:

Spatial Volume System (Light.dbc):
- Light volumes with position + inner/outer radius
- Distance-based weighting with smoothstep falloff
- Multi-volume blending (top 2 with normalized weights)
- X,Z,Y coordinate handling + LIGHT_COORD_SCALE for ×36 quirk
- Smooth zone transitions without popping

Profile Selection (LightParams.dbc):
- Weather variants: clear/rain/underwater
- Links to 18 color + 6 float band curves per profile
- Block indexing: LightParamsID × 18/6 + channel

Time-of-Day Band Sampling (LightIntBand/LightFloatBand):
- Half-minutes format (0-2879) with time clamping
- Keyframe interpolation with midnight wrap
- Wrap-safe initialization for edge cases
- BGR color unpacking

Multi-Volume Blending:
- Weighted sum of all lighting params
- Proper direction blending: normalize(sum(dir × weight))
- Blends ambient, diffuse, fog, sky, cloud density

Temporal Smoothing:
- Exponential blend to prevent frame snapping
- Smooths ALL parameters (colors, fog, direction, sky)

Game Time Support:
- Accepts server-sent game time (WoW standard)
- Falls back to local time if not provided
- Manual override for testing

Debug Features:
- Volume distance/weight logging
- Fog params logging
- Coordinate scale verification

Also: Move buff bar to top-left under player frame
2026-02-10 13:44:22 -08:00
Kelsi
a193da4ed9 Fix talent system packet parsing and rank logic
- Parse SMSG_TALENTS_INFO with correct byte-for-byte structure:
  * Header: uint8 spec, uint8 unspent, be32 talentCount, be16 entryCount
  * Entries: entryCount × (le32 id + uint8 rank)
  * Glyphs: uint8 glyphSlots + glyphSlots × le16 glyphId
- Fix rank storage: store all talents from packet (rank 0 = first point)
- Fix UI rank logic: send rank 0 for new, rank+1 for upgrades
- Fix rank display: show (rank+1) for learned talents
- Add sanity checks: entryCount max 64, glyphSlots max 12
- Add network boundary logging for packet debugging
2026-02-10 13:16:38 -08:00
Kelsi
ba79374689 Implement complete talent system with dual spec support
Network Protocol:
- Add SMSG_TALENTS_INFO (0x4C0) packet parsing for talent data
- Add CMSG_LEARN_TALENT (0x251) to request learning talents
- Add MSG_TALENT_WIPE_CONFIRM (0x2AB) opcode for spec switching
- Parse talent spec, unspent points, and learned talent ranks

DBC Parsing:
- Load Talent.dbc: talent grid positions, ranks, prerequisites, spell IDs
- Load TalentTab.dbc: talent tree definitions with correct field indices
- Fix localized string field handling (17 fields per string)
- Load Spell.dbc and SpellIcon.dbc for talent icons and tooltips
- Class mask filtering using bitwise operations (1 << (class - 1))

UI Implementation:
- Complete talent tree UI with tabbed interface for specs
- Display talent icons from spell data with proper tinting/borders
- Enhanced tooltips: spell name, rank, current/next descriptions, prereqs
- Visual states: green (maxed), yellow (partial), white (available), gray (locked)
- Tier unlock system (5 points per tier requirement)
- Rank overlay on icons with shadow text
- Click to learn talents with validation

Dual Spec Support:
- Store unspent points and learned talents per spec (0 and 1)
- Track active spec and display its talents
- Spec switching UI with buttons for Spec 1/Spec 2
- Handle both SMSG_TALENTS_INFO packets from server at login
- Display unspent points for both specs in header
- Independent talent trees for each specialization
2026-02-10 02:00:13 -08:00
Kelsi
5f2eef42d2 Fix trainer system and add critical spell/quest opcodes
Trainer System Fixes:
- Fix CMSG_TRAINER_BUY_SPELL packet: remove incorrect trainerType field (12 bytes not 16)
- Correct spell state interpretation: 0=available, 1=unavailable, 2=known
- Add dynamic prerequisite re-evaluation in real-time as spells are learned
- Immediately update knownSpells on SMSG_TRAINER_BUY_SUCCEEDED
- Add "Show unavailable spells" checkbox filter to trainer window
- Override server state when prerequisites become met client-side

New Spell Opcodes:
- SMSG_SUPERCEDED_SPELL (0x12C): handle spell rank upgrades
- SMSG_SEND_UNLEARN_SPELLS (0x41F): handle bulk unlearning (respec/dual-spec)
- CMSG_TRAINER_LIST (0x1B0): trainer request opcode

Quest System:
- SMSG_QUESTUPDATE_COMPLETE (0x195): mark quests complete when objectives done
- Show "Quest Complete" message and enable turn-in UI

Detailed logging:
- SMSG_INITIAL_SPELLS now logs packet size and first 10 spell IDs
- Money values logged during trainer purchases
- Trainer spell states and prerequisites logged for debugging

This enables proper spell progression chains, spec changes, and quest completion
notifications matching retail WoW 3.3.5a behavior.
2026-02-10 01:24:37 -08:00
Kelsi
0779e5ab2c Fix quest turn-in by populating quest log from gossip data
The quest log was empty because the client never requested quest data from the server.
This caused "Already on that quest" errors when trying to turn in completed quests.

Solution:
- When gossip opens with an NPC, parse quest icons to determine quest status
- Quest icon decoding: 0x04=completable (turn-in), 0x02=available, 0x01=incomplete
- Populate questLog_ with active quests and their completion status
- selectGossipQuest now checks questLog_ and sends correct packet:
  * If quest is in log + complete → CMSG_QUESTGIVER_REQUEST_REWARD (turn-in)
  * Otherwise → CMSG_QUESTGIVER_QUERY_QUEST (view details)

Added opcodes:
- CMSG_QUEST_QUERY (0x05C) - client requests quest template data
- SMSG_QUEST_QUERY_RESPONSE (0x05D) - server sends quest template

Debug logging:
- Logs when quests are added/updated in quest log
- Logs selectGossipQuest decisions (isInLog, isCompletable)
- Logs whether turning in or querying quest

Also lowered quest marker height by 1 unit (HEIGHT_OFFSET 2.1 → 1.1).

Quest turn-in now works correctly!
2026-02-09 23:53:17 -08:00
Kelsi
4bef9602bc 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
4c37acaaaf Fix quest opcode mapping for WoW 3.3.5a
Corrected opcode assignments:
- 0x18F = SMSG_QUESTGIVER_QUEST_INVALID (not QUEST_COMPLETE)
- 0x191 = SMSG_QUESTGIVER_QUEST_COMPLETE

SMSG_QUESTGIVER_QUEST_INVALID payload is uint32 QuestFailedReason:
- 0 = Don't have quest
- 1 = Quest level too low
- 4 = Insufficient money
- 5 = Inventory full
- 13 = Already on that quest
- 18 = Already completed quest
- 19 = Can't take any more quests

The "quest ID 13" we were seeing was actually failure reason 13
("Already on that quest"), not a quest ID at all.
2026-02-09 23:22:14 -08:00
Kelsi
3e4181f4d2 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
0715cd3c7d Fix SMSG_QUESTGIVER_QUEST_COMPLETE opcode value
Corrected opcode from 0x191 to 0x18F for WoW 3.3.5a. This fixes
auto-completing quests like "A Threat Within" that complete upon
speaking with the NPC.
2026-02-09 22:59:05 -08:00
Kelsi
e8c930f0bb 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
540b3cde45 Make InvisibleTrap objects invisible and non-collidable
Event objects like Fire Festival Fury Trap and Mercutio Post use
SpellObject_InvisibleTrap.m2 models which were rendering as white
tiles using WHITE1.BLP texture. These are meant to be invisible
spell trigger objects that should not obstruct player movement.

Changes:
- Added isInvisibleTrap flag to M2ModelGPU struct
- Detect models with "invisibletrap" in name during loading
- Skip rendering invisible trap instances in render loop
- Disable all collision checks (floor/wall/occlusion) for invisible traps
- Objects remain functional for spell casting but are now invisible
2026-02-09 22:31:36 -08:00
Kelsi
0f38268c24 Fix misleading comment in TrainerSpell state field
The comment incorrectly stated state values as:
  0=known(green), 1=available, 2=unavailable(red)

Actual correct values are:
  0=unavailable(grey), 1=available(green), 2=known(green)

This was causing confusion when debugging trainer issues.
2026-02-09 22:19:13 -08:00
Kelsi
db368d8329 Fix Stormwind cathedral LOD shell and extend view distance
- Add distance-based + backface culling for STORMWIND.WMO LOD shell groups
- Hide floating cathedral shell when within 185 units of group center
- Enable backface culling for LOD shell to reduce artifacts from inside
- Increase WMO view distance from 160 to 500 units for better visibility
- Extend fog distances to 3000-4000 units for clearer long-range views
- Add fog support to water renderer matching WMO fog settings
2026-02-09 19:57:22 -08:00
Kelsi
7ffb5f1de1 Fix WMO instance duplication causing 16x Stormwind rendering
Added deduplication for WMO instances based on uniqueId, matching the
existing M2 doodad deduplication logic. This prevents creating multiple
instances of the same WMO when it's referenced from multiple ADT tiles.

Before: STORMWIND.WMO (uniqueId=10047) was being rendered 16 times
        (one instance per ADT tile that references it)
After:  Only 1 instance is created and shared across all tiles

Changes:
- Added placedWmoIds set to TerrainManager (like placedDoodadIds)
- Check uniqueId before creating WMO instance
- Skip duplicate WMO placements across tile boundaries
- Log dedup statistics: 'X instances, Y dedup skipped'

This should fix the floating cathedral visual issue if it was caused by
rendering artifacts from 16x overdraw, and will massively improve
performance in Stormwind.
2026-02-09 18:38:45 -08:00
Kelsi
7c28b80135 Add body type selection for nonbinary characters and reduce preview rotation sensitivity
Nonbinary characters can now choose between masculine and feminine body types in character creation, with real-time preview updates and full appearance customization. Body type preference is saved to character config and persists across sessions. Also reduces character preview drag-to-rotate sensitivity from 0.5 to 0.2 for better control.
2026-02-09 17:56:04 -08:00
Kelsi
9f3a7d962e Add nonbinary gender support with pronoun system and server compatibility
Extends gender system beyond WoW's binary male/female to support nonbinary characters with proper they/them pronouns. Implements client-side gender mapping (nonbinary→male) for 3.3.5a server compatibility while preserving player identity through local config persistence. Adds pronoun placeholders ($p/$o/$s/$S) and three-option gender text parsing ($g<male>:<female>:<nonbinary>;) for inclusive quest and dialog text.
2026-02-09 17:39:21 -08:00
Kelsi
49326e35df Add goblin voice support for NPCs
- Added GOBLIN_MALE and GOBLIN_FEMALE to VoiceType enum
- Load greeting, farewell, vendor, and pissed sounds for goblin NPCs
- Prevents goblins from falling back to generic voice flag
- Uses proper goblin sound files from Goblin character folder
2026-02-09 17:14:34 -08:00
Kelsi
447f008e75 Implement comprehensive audio control panel with tabbed settings interface
Adds complete audio volume controls for all 11 audio systems with master volume. Reorganizes settings window into Video, Audio, and Gameplay tabs for better UX.

Audio Features:
- Master volume control affecting all audio systems
- Individual volume sliders for: Music, Ambient, UI, Combat, Spell, Movement, Footsteps, NPC Voices, Mounts, Activity sounds
- Real-time volume adjustment with master volume multiplier
- Restore defaults button per tab

Technical Changes:
- Added getVolumeScale() getters to all audio managers
- Integrated all 10 audio managers into renderer (UI, Combat, Spell, Movement added)
- Expanded game_screen.hpp with 11 pending volume variables
- Reorganized settings window using ImGui tab bars (Video/Audio/Gameplay)
- Audio settings uses scrollable child window for 11 volume controls
- Settings window expanded to 520x720px to accommodate comprehensive controls
2026-02-09 17:07:22 -08:00
Kelsi
41e680e328 Add movement sound manager for water splashes and jump/land vocalizations
Implements water splash sounds (enter water + footsteps) with size-based intensity and jump/land vocalizations for all 16 race/gender combinations.
2026-02-09 16:50:37 -08:00
Kelsi
6971f1815e Add comprehensive spell sound manager with 35+ magic sounds
Implemented complete spell casting audio system with all magic schools:

Magic schools supported:
- Fire: Precast (Low/Medium/High), Cast, Fireball impacts
- Frost: Precast (Low/Medium/High), Cast, Blizzard impacts
- Holy: Precast (Low/Medium/High), Cast, Holy impacts (4 levels)
- Nature: Precast (Low/Medium/High), Cast
- Shadow: Precast (Low/Medium/High), Cast
- Arcane: Precast, Arcane Missile impacts
- Physical: Non-magical abilities

Spell phases:
- Precast: Channeling/preparation sounds (before cast)
- Cast: Spell release sounds (when spell fires)
- Impact: Spell hit sounds (when spell hits target)

Power levels:
- Low: Weak spells, low level abilities
- Medium: Standard power spells
- High: Powerful high-level spells

Sound coverage (35+ sounds):
- 16 precast sounds (Fire/Frost/Holy/Nature/Shadow × Low/Med/High + Arcane)
- 5 cast sounds (one per school)
- 16 impact sounds (Fireball ×3, Blizzard ×6, Holy ×4, Arcane Missile ×3)

Technical details:
- Loads 35+ sound files from Sound\Spells directory
- Simple API: playPrecast(school, power), playCast(school), playImpact(school, power)
- Convenience methods: playFireball(), playFrostbolt(), playHeal(), etc.
- Random variation selection for impacts
- Volume at 0.75 with global scale control
- Ready for integration with spell casting system

Usage examples:
```cpp
// Full spell sequence
spellSoundManager->playPrecast(MagicSchool::FIRE, SpellPower::HIGH);
// ... cast time ...
spellSoundManager->playCast(MagicSchool::FIRE);
// ... projectile travel ...
spellSoundManager->playImpact(MagicSchool::FIRE, SpellPower::HIGH);

// Convenience methods
spellSoundManager->playFireball();
spellSoundManager->playHeal();
```

This adds essential magic feedback for spell casting gameplay!
2026-02-09 16:45:30 -08:00
Kelsi
f60848871c Add player character combat vocals with 60+ voice lines
Implemented player combat vocals for Blood Elf and Draenei races:

Player vocal types:
- Attack grunts: Multiple variations per race/gender
- Wound sounds: Pain reactions when hit
- Wound crits: Special sounds for critical hits taken
- Death cries: Final sounds when player dies

Race coverage (60+ voice lines):
- Blood Elf Male: 9 attacks, 8 wounds, 3 crit wounds, 2 deaths
- Blood Elf Female: 5 attacks, 7 wounds, 1 death
- Draenei Male: 7 attacks, 8 wounds, 3 crit wounds, 2 deaths
- Draenei Female: 7 attacks, 4 wounds, 3 crit wounds, 1 death

Technical details:
- Loads 60+ vocal sound files from Sound\Character\*PC folders
- Simple API: playPlayerAttackGrunt(race), playPlayerWound(race, crit), playPlayerDeath(race)
- Random variation selection for immersion
- Volume at 0.9-1.1 depending on sound type
- Crit wounds play 1.1x louder for emphasis
- Extensible design ready for other races
- Only BC races have dedicated PC vocal folders in WotLK 3.3.5a

Usage examples:
```cpp
combatSoundManager->playPlayerAttackGrunt(PlayerRace::BLOOD_ELF_MALE);
combatSoundManager->playPlayerWound(PlayerRace::DRAENEI_FEMALE, true);  // Crit
combatSoundManager->playPlayerDeath(PlayerRace::BLOOD_ELF_FEMALE);
```

This adds essential combat immersion with player character reactions!
2026-02-09 16:42:15 -08:00
Kelsi
d35b8eb633 Add comprehensive combat sound manager with weapon swings and impacts
Implemented complete combat audio system with 40+ combat sounds:

Weapon swing sounds (whooshes):
- Small weapons (1H): 3 variations + crit
- Medium weapons (2H): 3 variations + crit
- Large weapons (heavy 2H): 3 variations + crit
- Miss whooshes: separate 1H/2H sounds

Impact sounds by armor type:
- Flesh (unarmored/cloth): 3 variations + crit
- Chain armor: 3 variations + crit
- Plate armor: 3 variations + crit
- Shield blocks: 3 variations + crit
- Metal weapon parries: 1 sound
- Wood impacts: 3 variations
- Stone impacts: 3 variations

Emote sounds:
- Clap: 7 variations

Technical details:
- Loads 40+ sound files from Sound\Item\Weapons and Sound\Character
- Simple API: playWeaponSwing(size, isCrit), playImpact(size, type, isCrit)
- Random variation selection for non-crit sounds
- Volume at 0.8 with global scale control
- Crit sounds play 1.2x louder for emphasis
- Uses 1H axe impact sounds as base (similar across weapon types)
- Ready for integration with combat system

Usage examples:
```cpp
combatSoundManager->playWeaponSwing(WeaponSize::SMALL, false);
combatSoundManager->playImpact(WeaponSize::MEDIUM, ImpactType::PLATE, true);
combatSoundManager->playWeaponMiss(true);  // 2H miss
combatSoundManager->playClap();
```

This adds essential combat audio feedback for melee combat!
2026-02-09 16:38:50 -08:00
Kelsi
d8b86294d2 Make city bell tolls mark real server time like actual clock towers
Changed bell tolls from random intervals to proper timekeeping mechanism:

How it works:
- Bells now toll at the top of every hour (minute == 0)
- Number of tolls indicates the hour in 12-hour format:
  * 1 AM/PM = 1 toll
  * 2 AM/PM = 2 tolls
  * 12 AM/PM = 12 tolls
- 1.5 second delay between individual tolls
- Uses system time (server time for single-player mode)

Technical details:
- Detects hour changes via std::chrono and localtime()
- Tracks lastHourTolled_ to prevent duplicate tolling
- remainingTolls_ counter for sequential toll playback
- bellTollDelay_ for 1.5s spacing between tolls
- Only tolls when currentCity_ is set (in a city)
- Resets bell state when changing cities
- Converts 24-hour to 12-hour format (0 and 12 both become 12)

Example: At 3:00 PM in Stormwind, the Alliance bell will toll 3 times
with 1.5s between each toll, marking the hour like a real clock tower.

This makes bells actually useful for tracking real time while playing!
2026-02-09 16:33:53 -08:00
Kelsi
84863edda8 Add comprehensive UI sound manager for interface interactions
Implemented complete UI sound system with 32+ interface sounds:

Window sounds (10 types):
- Bag open/close (backpack, containers)
- Quest log open/close
- Character sheet open/close
- Auction house open/close
- Guild bank open/close

Button sounds (2 types):
- Interface button clicks
- Main menu button clicks

Quest sounds (4 types):
- Quest activate (new quest accepted)
- Quest complete (quest turned in)
- Quest failed
- Quest update (progress notification)

Loot sounds (3 types):
- Coin pickup (small/large amounts)
- Item loot from creatures

Item sounds (6 types):
- Drop item on ground
- Pickup sounds by item type: bags, books, cloth, food, gems

Eating/Drinking (2 types):
- Eating food sound
- Drinking potion/water sound

Special sounds:
- Level up fanfare
- Error/invalid action feedback
- Target select/deselect

Technical details:
- Loads 32 sound files from Sound\Interface directory
- Volume at 0.7 with global scale control
- Simple API: playBagOpen(), playQuestComplete(), etc.
- Ready for integration with UI systems and game events
- Can be hooked to ImGui windows, inventory actions, quest system
2026-02-09 16:30:47 -08:00
Kelsi
9a19355c58 Add fountain positional ambient sounds
Implemented fountain sounds as positional audio emitters:

Technical details:
- Added fountainSounds_ library (FountainSmallMediumLoop.wav)
- Fountain type already existed in AmbientType enum but was unused
- 6 second loop interval for fountain sounds
- Volume at 0.8x water volume for gentle bubbling effect
- Max distance: 35 units (same as other water sources)
- Counted in activeWaterCount limit (max 3 water sources at once)
- Spatial 3D audio based on fountain position
- Can be placed via addEmitter(position, AmbientType::FOUNTAIN)
2026-02-09 16:27:16 -08:00
Kelsi
cd2861c75b Add bell tolls for major cities marking time
Implemented periodic bell chimes that add atmosphere to major cities:

Bell types by faction:
- Alliance bell: Stormwind, Ironforge
- Night Elf bell: Darnassus
- Horde bell: Orgrimmar, Undercity
- Tribal bell: Thunder Bluff

Technical details:
- Loads 4 bell toll sound files from Sound\Doodad
- Plays every 120-180 seconds (2-3 minutes) with random variation
- First bell toll 60-90 seconds after entering city
- Volume at 0.5 for noticeable but not overpowering effect
- Only plays when currentCity_ is set (not in wilderness)
- Each city uses faction-appropriate bell sound
- Separate timer (bellTollTime_) from regular city ambience
- State logging for debugging bell events
2026-02-09 16:25:59 -08:00
Kelsi
d8e2e51f49 Add major city ambient audio with day/night variations
Implemented city-specific ambient soundscapes for all six major cities:

Alliance cities:
- Stormwind: day/night crowd and marketplace sounds
- Ironforge: underground forge ambience (no day/night)
- Darnassus: day/night elven city sounds

Horde cities:
- Orgrimmar: day/night orcish city atmosphere
- Undercity: underground undead ambience (no day/night)
- Thunder Bluff: day/night tauren plateau sounds

Technical details:
- Added CityType enum (NONE, STORMWIND, IRONFORGE, DARNASSUS, ORGRIMMAR, UNDERCITY, THUNDERBLUFF)
- Loads 12 city sound files from Sound\Ambience\WMOAmbience
- Underground cities (Ironforge, Undercity) use single sound without day/night variants
- 20s loop interval for city ambience (more frequent than zone ambience)
- Volume at 0.4 for noticeable but not overwhelming urban atmosphere
- Cities take priority over zone ambience to prevent mixing
- updateZoneAmbience() now checks for active city and skips if in city
- State change logging for debugging city transitions
2026-02-09 16:14:03 -08:00
Kelsi
979d5db602 Add comprehensive weather, water, and zone ambient audio systems
Implemented three new ambient audio systems with automatic day/night transitions:

Weather ambience:
- Rain sounds (light/medium/heavy intensity based on weather system)
- Snow sounds (light/medium/heavy intensity)
- Automatically syncs with visual weather system in renderer
- Different loop intervals based on intensity (18-30s)
- Disabled indoors

Water ambience:
- Underwater swimming sounds (18s loop)
- Ocean surface sounds
- State tracking for entering/exiting water

Zone ambience:
- Forest (normal and snow variants)
- Beach sounds
- Grasslands
- Jungle
- Marsh/swamp
- Desert (canyon and plains variants)
- All zones have separate day/night sound files
- 30s loop interval for subtle background atmosphere
- Disabled indoors

Technical details:
- Added WeatherType enum (NONE, RAIN/SNOW LIGHT/MEDIUM/HEAVY)
- Added ZoneType enum (NONE, FOREST_NORMAL, FOREST_SNOW, BEACH, GRASSLANDS, JUNGLE, MARSH, DESERT_CANYON, DESERT_PLAINS)
- Loads 26 new sound files from Sound\Ambience\Weather and Sound\Ambience\ZoneAmbience
- Weather intensity thresholds: <0.33 = light, 0.33-0.66 = medium, >0.66 = heavy
- Renderer automatically converts Weather::Type + intensity to AmbientSoundManager::WeatherType
- All ambience respects volumeScale_ and indoor state
- State change logging for debugging transitions
2026-02-09 16:12:06 -08:00
Kelsi
e7daa71063 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
d071ca08e7 Increase blacksmith hammer sound pitch to 1.6x
Raises pitch from 1.4f to 1.6f for more distinct metallic clink in blacksmith ambience.
2026-02-09 15:21:07 -08:00
Kelsi
b7a18447b0 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