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!
This commit is contained in:
Kelsi 2026-02-09 16:42:15 -08:00
parent da249d5be0
commit 3a3e9f3c79
2 changed files with 189 additions and 0 deletions

View file

@ -50,6 +50,18 @@ public:
// Emote sounds
void playClap();
// Player character vocals
enum class PlayerRace {
BLOOD_ELF_MALE,
BLOOD_ELF_FEMALE,
DRAENEI_MALE,
DRAENEI_FEMALE
};
void playPlayerAttackGrunt(PlayerRace race);
void playPlayerWound(PlayerRace race, bool isCrit = false);
void playPlayerDeath(PlayerRace race);
private:
struct CombatSample {
std::string path;
@ -83,6 +95,26 @@ private:
// Emote sounds
std::vector<CombatSample> clapSounds_;
// Player character vocal libraries
std::vector<CombatSample> bloodElfMaleAttackSounds_;
std::vector<CombatSample> bloodElfMaleWoundSounds_;
std::vector<CombatSample> bloodElfMaleWoundCritSounds_;
std::vector<CombatSample> bloodElfMaleDeathSounds_;
std::vector<CombatSample> bloodElfFemaleAttackSounds_;
std::vector<CombatSample> bloodElfFemaleWoundSounds_;
std::vector<CombatSample> bloodElfFemaleDeathSounds_;
std::vector<CombatSample> draeneiMaleAttackSounds_;
std::vector<CombatSample> draeneiMaleWoundSounds_;
std::vector<CombatSample> draeneiMaleWoundCritSounds_;
std::vector<CombatSample> draeneiMaleDeathSounds_;
std::vector<CombatSample> draeneiFemaleAttackSounds_;
std::vector<CombatSample> draeneiFemaleWoundSounds_;
std::vector<CombatSample> draeneiFemaleWoundCritSounds_;
std::vector<CombatSample> draeneiFemaleDeathSounds_;
// State tracking
float volumeScale_ = 1.0f;
bool initialized_ = false;