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)
This commit is contained in:
Kelsi 2026-02-09 16:03:51 -08:00
parent 251f0ac246
commit 28d009f7db
8 changed files with 10908 additions and 198 deletions

View file

@ -345,6 +345,9 @@ public:
using NpcDeathCallback = std::function<void(uint64_t guid)>;
void setNpcDeathCallback(NpcDeathCallback cb) { npcDeathCallback_ = std::move(cb); }
using NpcAggroCallback = std::function<void(uint64_t guid, const glm::vec3& position)>;
void setNpcAggroCallback(NpcAggroCallback cb) { npcAggroCallback_ = std::move(cb); }
// NPC respawn callback (health 0 → >0, resets animation to idle)
using NpcRespawnCallback = std::function<void(uint64_t guid)>;
void setNpcRespawnCallback(NpcRespawnCallback cb) { npcRespawnCallback_ = std::move(cb); }
@ -361,6 +364,12 @@ public:
using NpcGreetingCallback = std::function<void(uint64_t guid, const glm::vec3& position)>;
void setNpcGreetingCallback(NpcGreetingCallback cb) { npcGreetingCallback_ = std::move(cb); }
using NpcFarewellCallback = std::function<void(uint64_t guid, const glm::vec3& position)>;
void setNpcFarewellCallback(NpcFarewellCallback cb) { npcFarewellCallback_ = std::move(cb); }
using NpcVendorCallback = std::function<void(uint64_t guid, const glm::vec3& position)>;
void setNpcVendorCallback(NpcVendorCallback cb) { npcVendorCallback_ = std::move(cb); }
// XP tracking
uint32_t getPlayerXp() const { return playerXp_; }
uint32_t getPlayerNextLevelXp() const { return playerNextLevelXp_; }
@ -1031,10 +1040,13 @@ private:
void extractSkillFields(const std::map<uint16_t, uint32_t>& fields);
NpcDeathCallback npcDeathCallback_;
NpcAggroCallback npcAggroCallback_;
NpcRespawnCallback npcRespawnCallback_;
MeleeSwingCallback meleeSwingCallback_;
NpcSwingCallback npcSwingCallback_;
NpcGreetingCallback npcGreetingCallback_;
NpcFarewellCallback npcFarewellCallback_;
NpcVendorCallback npcVendorCallback_;
MountCallback mountCallback_;
TaxiPrecacheCallback taxiPrecacheCallback_;
TaxiOrientationCallback taxiOrientationCallback_;