chore(renderer): extract AnimationController and remove audio pass-throughs

Extract ~1,500 lines of character animation state from Renderer into a dedicated
AnimationController class, and complete the AudioCoordinator migration by removing
all 10 audio pass-through getters from Renderer.

AnimationController:
- New: include/rendering/animation_controller.hpp (182 lines)
- New: src/rendering/animation_controller.cpp (1,703 lines)
- Moves: locomotion state machine (50+ members), mount animation (40+ members),
  emote system, footstep triggering, surface detection, melee combat animations
- Renderer holds std::unique_ptr<AnimationController> and delegates completely
- AnimationController accesses audio via renderer_->getAudioCoordinator()

Audio caller migration:
- Migrate ~60 external callers from renderer->getXManager() to AudioCoordinator
  directly, grouped by access pattern:
  - UIServices: settings_panel, game_screen, toast_manager, chat_panel,
    combat_ui, window_manager
  - GameServices: game_handler, spell_handler, inventory_handler, quest_handler,
    social_handler, combat_handler
  - Application singleton: application.cpp, auth_screen.cpp, lua_engine.cpp
- Remove 10 pass-through getter definitions from renderer.cpp
- Remove 10 pass-through getter declarations from renderer.hpp
- Remove individual audio manager forward declarations from renderer.hpp
- Redirect 69 internal renderer.cpp audio calls to audioCoordinator_ directly
- game_handler.cpp: withSoundManager template uses services_.audioCoordinator;
  MFP changed from &Renderer::getUiSoundManager to &AudioCoordinator::getUiSoundManager
- GameServices struct: add AudioCoordinator* audioCoordinator member
- settings_panel: applyAudioVolumes(Renderer*) -> applyAudioVolumes(AudioCoordinator*)
This commit is contained in:
Paul 2026-04-02 13:06:31 +03:00
parent 5ef600098a
commit 5af9f7aa4b
22 changed files with 2208 additions and 1958 deletions

View file

@ -17,6 +17,7 @@
#include "game/update_field_table.hpp"
#include "game/expansion_profile.hpp"
#include "rendering/renderer.hpp"
#include "audio/audio_coordinator.hpp"
#include "audio/activity_sound_manager.hpp"
#include "audio/combat_sound_manager.hpp"
#include "audio/spell_sound_manager.hpp"
@ -599,8 +600,8 @@ static QuestQueryRewards tryParseQuestRewards(const std::vector<uint8_t>& data,
template<typename ManagerGetter, typename Callback>
void GameHandler::withSoundManager(ManagerGetter getter, Callback cb) {
if (auto* renderer = services_.renderer) {
if (auto* mgr = (renderer->*getter)()) cb(mgr);
if (auto* ac = services_.audioCoordinator) {
if (auto* mgr = (ac->*getter)()) cb(mgr);
}
}
@ -1198,9 +1199,9 @@ void GameHandler::updateTimers(float deltaTime) {
}
if (!alreadyAnnounced && pendingLootMoneyAmount_ > 0) {
addSystemChatMessage("Looted: " + formatCopperAmount(pendingLootMoneyAmount_));
auto* renderer = services_.renderer;
if (renderer) {
if (auto* sfx = renderer->getUiSoundManager()) {
auto* ac = services_.audioCoordinator;
if (ac) {
if (auto* sfx = ac->getUiSoundManager()) {
if (pendingLootMoneyAmount_ >= 10000) {
sfx->playLootCoinLarge();
} else {
@ -1974,7 +1975,7 @@ void GameHandler::registerOpcodeHandlers() {
ping.age = 0.0f;
minimapPings_.push_back(ping);
if (senderGuid != playerGuid) {
withSoundManager(&rendering::Renderer::getUiSoundManager, [](auto* sfx) { sfx->playMinimapPing(); });
withSoundManager(&audio::AudioCoordinator::getUiSoundManager, [](auto* sfx) { sfx->playMinimapPing(); });
}
};
dispatchTable_[Opcode::SMSG_ZONE_UNDER_ATTACK] = [this](network::Packet& packet) {
@ -2124,7 +2125,7 @@ void GameHandler::registerOpcodeHandlers() {
if (info && info->type == 17) {
addUIError("A fish is on your line!");
addSystemChatMessage("A fish is on your line!");
withSoundManager(&rendering::Renderer::getUiSoundManager, [](auto* sfx) { sfx->playQuestUpdate(); });
withSoundManager(&audio::AudioCoordinator::getUiSoundManager, [](auto* sfx) { sfx->playQuestUpdate(); });
}
}
}
@ -2350,7 +2351,7 @@ void GameHandler::registerOpcodeHandlers() {
}
if (newLevel > oldLevel) {
addSystemChatMessage("You have reached level " + std::to_string(newLevel) + "!");
withSoundManager(&rendering::Renderer::getUiSoundManager, [](auto* sfx) { sfx->playLevelUp(); });
withSoundManager(&audio::AudioCoordinator::getUiSoundManager, [](auto* sfx) { sfx->playLevelUp(); });
if (levelUpCallback_) levelUpCallback_(newLevel);
fireAddonEvent("PLAYER_LEVEL_UP", {std::to_string(newLevel)});
}