#pragma once #include #include #include #include #include #include #include namespace wowee { namespace pipeline { class AssetManager; } namespace audio { struct VoiceSample { std::string path; std::vector data; }; // NPC voice types (based on creature model/gender) enum class VoiceType { HUMAN_MALE, HUMAN_FEMALE, DWARF_MALE, DWARF_FEMALE, NIGHTELF_MALE, NIGHTELF_FEMALE, ORC_MALE, ORC_FEMALE, TAUREN_MALE, TAUREN_FEMALE, TROLL_MALE, TROLL_FEMALE, UNDEAD_MALE, UNDEAD_FEMALE, GNOME_MALE, GNOME_FEMALE, GOBLIN_MALE, GOBLIN_FEMALE, GENERIC, // Fallback }; class NpcVoiceManager { public: NpcVoiceManager(); ~NpcVoiceManager(); bool initialize(pipeline::AssetManager* assets); void shutdown(); // Play NPC interaction sounds void playGreeting(uint64_t npcGuid, VoiceType voiceType, const glm::vec3& position); void playFarewell(uint64_t npcGuid, VoiceType voiceType, const glm::vec3& position); void playVendor(uint64_t npcGuid, VoiceType voiceType, const glm::vec3& position); void playPissed(uint64_t npcGuid, VoiceType voiceType, const glm::vec3& position); // Play NPC combat sounds void playAggro(uint64_t npcGuid, VoiceType voiceType, const glm::vec3& position); void playFlee(uint64_t npcGuid, VoiceType voiceType, const glm::vec3& position); void setVolumeScale(float scale) { volumeScale_ = scale; } float getVolumeScale() const { return volumeScale_; } private: enum class SoundCategory { GREETING, FAREWELL, VENDOR, PISSED, AGGRO, FLEE }; void loadVoiceSounds(); bool loadSound(const std::string& path, VoiceSample& sample); void playSound(uint64_t npcGuid, VoiceType voiceType, SoundCategory category, const glm::vec3& position); pipeline::AssetManager* assetManager_ = nullptr; float volumeScale_ = 1.0f; // Voice samples grouped by type and category std::unordered_map> greetingLibrary_; std::unordered_map> farewellLibrary_; std::unordered_map> vendorLibrary_; std::unordered_map> pissedLibrary_; std::unordered_map> aggroLibrary_; std::unordered_map> fleeLibrary_; // Cooldown tracking (prevent spam clicking same NPC) std::unordered_map lastPlayTime_; std::unordered_map clickCount_; // Track clicks for pissed sounds static constexpr float GREETING_COOLDOWN = 2.0f; // seconds static constexpr int PISSED_CLICK_THRESHOLD = 5; // clicks before pissed std::mt19937 rng_; }; } // namespace audio } // namespace wowee