diff --git a/include/core/application.hpp b/include/core/application.hpp index 9fbdc2b2..eb6daf4b 100644 --- a/include/core/application.hpp +++ b/include/core/application.hpp @@ -58,6 +58,7 @@ public: // Single-player mode void startSinglePlayer(); bool isSinglePlayer() const { return singlePlayerMode; } + void logoutToLogin(); // Weapon loading (called at spawn and on equipment change) void loadEquippedWeapons(); diff --git a/src/core/application.cpp b/src/core/application.cpp index 28c9bce9..0e853f21 100644 --- a/src/core/application.cpp +++ b/src/core/application.cpp @@ -19,6 +19,7 @@ #include "rendering/wmo_renderer.hpp" #include "rendering/minimap.hpp" #include "rendering/loading_screen.hpp" +#include "audio/music_manager.hpp" #include #include "pipeline/m2_loader.hpp" #include "pipeline/wmo_loader.hpp" @@ -346,6 +347,23 @@ void Application::setState(AppState newState) { } } +void Application::logoutToLogin() { + LOG_INFO("Logout requested"); + if (gameHandler) { + gameHandler->disconnect(); + gameHandler->setSinglePlayerMode(false); + } + singlePlayerMode = false; + npcsSpawned = false; + world.reset(); + if (renderer) { + if (auto* music = renderer->getMusicManager()) { + music->stopMusic(0.0f); + } + } + setState(AppState::AUTHENTICATION); +} + void Application::update(float deltaTime) { // Update based on current state switch (state) { diff --git a/src/ui/game_screen.cpp b/src/ui/game_screen.cpp index 83146ddc..faccb89a 100644 --- a/src/ui/game_screen.cpp +++ b/src/ui/game_screen.cpp @@ -650,6 +650,12 @@ void GameScreen::sendChatMessage(game::GameHandler& gameHandler) { // Convert to lowercase for (char& c : command) c = std::tolower(c); + if (command == "logout") { + core::Application::getInstance().logoutToLogin(); + chatInputBuffer[0] = '\0'; + return; + } + std::string emoteText = rendering::Renderer::getEmoteText(command); if (!emoteText.empty()) { // Play the emote animation