From b17295c99363ebd0da53a9a5fbdfc175cceceb92 Mon Sep 17 00:00:00 2001 From: Deewarz Date: Fri, 15 Mar 2024 18:36:32 +0100 Subject: [PATCH] Rework UI --- code/client/CMakeLists.txt | 17 +- code/client/src/core/application.cpp | 72 +++-- code/client/src/core/application.h | 19 +- code/client/src/core/dev_features.cpp | 250 ++++++-------- code/client/src/core/dev_features.h | 49 ++- code/client/src/core/modules/human.cpp | 2 +- code/client/src/core/states/main_menu.cpp | 6 +- .../src/core/states/session_connected.cpp | 17 +- .../src/core/states/session_disconnection.cpp | 3 + code/client/src/core/ui/audio_debug.h | 21 -- code/client/src/core/ui/chat.cpp | 70 ++-- code/client/src/core/ui/chat.h | 40 ++- code/client/src/core/ui/console.cpp | 18 +- code/client/src/core/ui/console.h | 12 +- .../src/core/ui/{ => devs}/camera_studio.cpp | 21 +- .../src/core/ui/{ => devs}/camera_studio.h | 32 +- .../{audio_debug.cpp => devs/debug_audio.cpp} | 25 +- code/client/src/core/ui/devs/debug_audio.h | 17 + code/client/src/core/ui/devs/debug_player.cpp | 137 ++++++++ code/client/src/core/ui/devs/debug_player.h | 17 + .../debug_vehicle.cpp} | 30 +- code/client/src/core/ui/devs/debug_vehicle.h | 17 + code/client/src/core/ui/devs/debug_world.cpp | 304 ++++++++++++++++++ code/client/src/core/ui/devs/debug_world.h | 26 ++ .../src/core/ui/{ => devs}/entity_browser.cpp | 30 +- .../src/core/ui/{ => devs}/entity_browser.h | 46 +-- .../src/core/ui/{ => devs}/network_stats.cpp | 25 +- code/client/src/core/ui/devs/network_stats.h | 23 ++ code/client/src/core/ui/network_stats.h | 28 -- code/client/src/core/ui/player_debug.cpp | 136 -------- code/client/src/core/ui/player_debug.h | 23 -- code/client/src/core/ui/ui_base.cpp | 17 + code/client/src/core/ui/ui_base.h | 15 + code/client/src/core/ui/vehicle_debug.h | 23 -- code/client/src/core/ui/world_debug.cpp | 304 ------------------ code/client/src/core/ui/world_debug.h | 32 -- 36 files changed, 966 insertions(+), 958 deletions(-) delete mode 100644 code/client/src/core/ui/audio_debug.h rename code/client/src/core/ui/{ => devs}/camera_studio.cpp (95%) rename code/client/src/core/ui/{ => devs}/camera_studio.h (52%) rename code/client/src/core/ui/{audio_debug.cpp => devs/debug_audio.cpp} (79%) create mode 100644 code/client/src/core/ui/devs/debug_audio.h create mode 100644 code/client/src/core/ui/devs/debug_player.cpp create mode 100644 code/client/src/core/ui/devs/debug_player.h rename code/client/src/core/ui/{vehicle_debug.cpp => devs/debug_vehicle.cpp} (92%) create mode 100644 code/client/src/core/ui/devs/debug_vehicle.h create mode 100644 code/client/src/core/ui/devs/debug_world.cpp create mode 100644 code/client/src/core/ui/devs/debug_world.h rename code/client/src/core/ui/{ => devs}/entity_browser.cpp (96%) rename code/client/src/core/ui/{ => devs}/entity_browser.h (52%) rename code/client/src/core/ui/{ => devs}/network_stats.cpp (72%) create mode 100644 code/client/src/core/ui/devs/network_stats.h delete mode 100644 code/client/src/core/ui/network_stats.h delete mode 100644 code/client/src/core/ui/player_debug.cpp delete mode 100644 code/client/src/core/ui/player_debug.h create mode 100644 code/client/src/core/ui/ui_base.cpp create mode 100644 code/client/src/core/ui/ui_base.h delete mode 100644 code/client/src/core/ui/vehicle_debug.h delete mode 100644 code/client/src/core/ui/world_debug.cpp delete mode 100644 code/client/src/core/ui/world_debug.h diff --git a/code/client/CMakeLists.txt b/code/client/CMakeLists.txt index b6004d6b..3da32c28 100644 --- a/code/client/CMakeLists.txt +++ b/code/client/CMakeLists.txt @@ -3,19 +3,20 @@ set(MAFIAMP_CLIENT_FILES src/core/luavm.cpp src/core/application.cpp src/core/dev_features.cpp - src/core/ui/audio_debug.cpp - src/core/ui/console.cpp + src/core/ui/ui_base.cpp src/core/ui/chat.cpp - src/core/ui/camera_studio.cpp - src/core/ui/entity_browser.cpp - src/core/ui/network_stats.cpp - src/core/ui/player_debug.cpp - src/core/ui/vehicle_debug.cpp + src/core/ui/console.cpp + src/core/ui/devs/camera_studio.cpp + src/core/ui/devs/debug_audio.cpp + src/core/ui/devs/debug_player.cpp + src/core/ui/devs/debug_vehicle.cpp + src/core/ui/devs/debug_world.cpp + src/core/ui/devs/entity_browser.cpp + src/core/ui/devs/network_stats.cpp src/core/ui/web/manager.cpp src/core/ui/web/clipboard.cpp src/core/ui/web/sdk.cpp src/core/ui/web/view.cpp - src/core/ui/world_debug.cpp src/core/states/initialize.cpp src/core/states/main_menu.cpp src/core/states/session_connected.cpp diff --git a/code/client/src/core/application.cpp b/code/client/src/core/application.cpp index 11a26592..4f25719b 100644 --- a/code/client/src/core/application.cpp +++ b/code/client/src/core/application.cpp @@ -60,9 +60,9 @@ namespace MafiaMP::Core { _commandProcessor = std::make_shared(); _input = std::make_shared(); - _console = std::make_shared(_commandProcessor, _input); + _console = std::make_shared(_commandProcessor); _chat = std::make_shared(); - _webManager = std::make_shared(); + _webManager = std::make_shared(); if (_webManager) { if (!_webManager->Init()) { @@ -142,21 +142,29 @@ namespace MafiaMP::Core { discordApi->SetPresence("Freeroam", "Screwing around", discord::ActivityType::Playing); } -#if 1 + // Console UI Core::gApplication->GetImGUI()->PushWidget([&]() { - using namespace Framework::External::ImGUI::Widgets; - const auto networkClient = Core::gApplication->GetNetworkingEngine()->GetNetworkClient(); - const auto connState = networkClient->GetConnectionState(); - const auto ping = networkClient->GetPing(); - _console->Update(); - _devFeatures.Update(); if (_input->IsKeyPressed(FW_KEY_F8)) { _console->Toggle(); } + }); - const char *connStateNames[] = {"Connecting", "Online", "Offline"}; +#ifdef FW_DEBUG + Core::gApplication->GetImGUI()->PushWidget([&]() { + _devFeatures.Update(); + + using namespace Framework::External::ImGUI::Widgets; // For DrawCornerText() and Corner enum + + // Bypass locked controls + if (AreControlsLocked()) { + DrawCornerText(CORNER_RIGHT_TOP, fmt::format("Press APPS to {} controls locked", AreControlsLockedBypassed() ? "RESTORE" : "BYPASS")); + + if (_input->IsKeyPressed(FW_KEY_APPS)) { + ToggleLockControlsBypass(); + } + } // versioning DrawCornerText(CORNER_RIGHT_BOTTOM, "Mafia: Multiplayer"); @@ -164,6 +172,11 @@ namespace MafiaMP::Core { DrawCornerText(CORNER_RIGHT_BOTTOM, fmt::format("MafiaMP version: {} ({})", MafiaMP::Version::rel, MafiaMP::Version::git)); // connection details + const auto networkClient = Core::gApplication->GetNetworkingEngine()->GetNetworkClient(); + const auto connState = networkClient->GetConnectionState(); + const auto ping = networkClient->GetPing(); + const char *connStateNames[] = {"Connecting", "Online", "Offline"}; + DrawCornerText(CORNER_LEFT_BOTTOM, fmt::format("Connection: {}", connStateNames[connState])); DrawCornerText(CORNER_LEFT_BOTTOM, fmt::format("Ping: {}", ping)); }); @@ -265,28 +278,41 @@ namespace MafiaMP::Core { ImGui::GetStyle().WindowTitleAlign = {0.5f, 0.5f}; } + void Application::ProcessLockControls(bool lock) { + Game::Helpers::Controls::Lock(lock); + + GetImGUI()->SetProcessEventEnabled(lock); + GetImGUI()->ShowCursor(lock); + } + void Application::LockControls(bool lock) { if (lock) { - _controlsLocked++; + if (_lockControlsCounter == 0) { + ProcessLockControls(true); + } + + _lockControlsCounter++; } else { - _controlsLocked = std::max(--_controlsLocked, 0); - } + _lockControlsCounter = std::max(--_lockControlsCounter, 0); - if (_controlsLocked) { - // Lock game controls - Game::Helpers::Controls::Lock(true); + if (_lockControlsCounter == 0) { + ProcessLockControls(false); - // Enable cursor - GetImGUI()->ShowCursor(true); + // Reset bypass + _lockControlsBypassed = false; + } } - else { - // Unlock game controls - Game::Helpers::Controls::Lock(false); + } - // Disable cursor - GetImGUI()->ShowCursor(false); + void Application::ToggleLockControlsBypass() { + if (!AreControlsLocked()) { + Framework::Logging::GetLogger("Application")->error("[ToggleLockControlsBypass] Controls are not locked."); + return; } + + ProcessLockControls(_lockControlsBypassed); + _lockControlsBypassed = !_lockControlsBypassed; } uint64_t Application::GetLocalPlayerID() { diff --git a/code/client/src/core/application.h b/code/client/src/core/application.h index b6802404..d1ed7cd6 100644 --- a/code/client/src/core/application.h +++ b/code/client/src/core/application.h @@ -23,9 +23,8 @@ namespace MafiaMP::Core { class Application: public Framework::Integrations::Client::Instance { private: - friend class DevFeatures; std::shared_ptr _stateMachine; - std::shared_ptr _console; + std::shared_ptr _console; std::shared_ptr _chat; std::shared_ptr _webManager; std::shared_ptr _entityFactory; @@ -34,14 +33,19 @@ namespace MafiaMP::Core { std::shared_ptr _luaVM; flecs::entity _localPlayer; DevFeatures _devFeatures; + float _tickInterval = 0.01667f; - int _controlsLocked = 0; + + int _lockControlsCounter = 0; + bool _lockControlsBypassed = false; int _mainMenuViewId = -1; private: Game::Helpers::Districts _lastDistrictID = Game::Helpers::Districts::UNSPECIFIED; + void ProcessLockControls(bool lock); + public: bool PostInit() override; bool PreShutdown() override; @@ -52,9 +56,14 @@ namespace MafiaMP::Core { void InitRPCs(); void PimpMyImGUI(); + void LockControls(bool lock); bool AreControlsLocked() const { - return _controlsLocked > 0; + return _lockControlsCounter > 0; + } + void ToggleLockControlsBypass(); + bool AreControlsLockedBypassed() const { + return _lockControlsBypassed; } std::shared_ptr GetStateMachine() const { @@ -77,7 +86,7 @@ namespace MafiaMP::Core { return _input; } - std::shared_ptr GetDevConsole() const { + std::shared_ptr GetConsole() const { return _console; } diff --git a/code/client/src/core/dev_features.cpp b/code/client/src/core/dev_features.cpp index 1bec5144..ad7d9e69 100644 --- a/code/client/src/core/dev_features.cpp +++ b/code/client/src/core/dev_features.cpp @@ -1,12 +1,9 @@ -/* - * MafiaHub OSS license - * Copyright (c) 2022, MafiaHub. All rights reserved. - * - * This file comes from MafiaHub, hosted at https://github.com/MafiaHub/Framework. - * See LICENSE file in the source repository for information regarding licensing. - */ - #include "dev_features.h" + +#include +#include +#include + #include "application.h" #include @@ -20,22 +17,17 @@ #include "sdk/entities/c_player_2.h" #include "sdk/mafia/framework/c_mafia_framework_interfaces.h" -#include - -#include -#include - #include "shared/rpc/chat_message.h" namespace MafiaMP::Core { DevFeatures::DevFeatures() { - _audioDebug = std::make_shared(); - _cameraStudio = std::make_shared(); - _entityBrowser = std::make_shared(); - _networkStats = std::make_shared(); - _playerDebug = std::make_shared(); - _vehicleDebug = std::make_shared(); - _worldDebug = std::make_shared(); + _cameraStudio = std::make_shared(); + _debugAudio = std::make_shared(); + _debugPlayer = std::make_shared(); + _debugVehicle = std::make_shared(); + _debugWorld = std::make_shared(); + _entityBrowser = std::make_shared(); + _networkStats = std::make_shared(); } void DevFeatures::Init() { @@ -44,59 +36,36 @@ namespace MafiaMP::Core { } void DevFeatures::Update() { - if (_audioDebug->IsVisible()) { - _audioDebug->Update(); - } - - if (_entityBrowser->IsVisible()) { - _entityBrowser->Update(); - } - - if (_cameraStudio->IsVisible()) { - _cameraStudio->Update(); - } - - if (_playerDebug->IsVisible()) { - _playerDebug->Update(); - } - - if (_vehicleDebug->IsVisible()) { - _vehicleDebug->Update(); - } - - if (_networkStats->IsVisible()) { - _networkStats->Update(); - } - - if (_worldDebug->IsVisible()) { - _worldDebug->Update(); - } + _cameraStudio->Update(); + _debugAudio->Update(); + _debugPlayer->Update(); + _debugVehicle->Update(); + _debugWorld->Update(); + _entityBrowser->Update(); + _networkStats->Update(); /** * F8 is for console * F9 is for main menu * F12 is for Steam screenshot */ - - if (gApplication->_input->IsKeyPressed(FW_KEY_F1)) { - ToggleWorldDebug(); + if (gApplication->GetInput()->IsKeyPressed(FW_KEY_F1)) { + ToggleDebugWorld(); } - if (gApplication->_input->IsKeyPressed(FW_KEY_F2)) { - TogglePlayerDebug(); + if (gApplication->GetInput()->IsKeyPressed(FW_KEY_F2)) { + ToggleDebugPlayer(); } - if (gApplication->_input->IsKeyPressed(FW_KEY_F3)) { - ToggleVehicleDebug(); + if (gApplication->GetInput()->IsKeyPressed(FW_KEY_F3)) { + ToggleDebugVehicle(); } - if (gApplication->_input->IsKeyPressed(FW_KEY_F4)) { - gApplication->GetImGUI()->ShowCursor(!_cameraStudio->IsVisible()); - MafiaMP::Game::Helpers::Controls::Lock(!_cameraStudio->IsVisible()); + if (gApplication->GetInput()->IsKeyPressed(FW_KEY_F4)) { ToggleCameraStudio(); } - if (gApplication->_input->IsKeyPressed(FW_KEY_F5)) { + if (gApplication->GetInput()->IsKeyPressed(FW_KEY_F5)) { // If human is already created, delete it first if (_TEMP_HUMAN) { gApplication->GetEntityFactory()->ReturnEntity(_TEMP_HUMAN); @@ -155,7 +124,7 @@ namespace MafiaMP::Core { _TEMP_HUMAN->SetReturnCallback(OnHumanReturned); } - if (gApplication->_input->IsKeyPressed(FW_KEY_F6)) { + if (gApplication->GetInput()->IsKeyPressed(FW_KEY_F6)) { if (!_TEMP_HUMAN) { return; } @@ -174,15 +143,15 @@ namespace MafiaMP::Core { Framework::Logging::GetLogger("Playground")->debug("Aiming : {}", human->GetHumanWeaponController()->IsAiming()); } - if (gApplication->_input->IsKeyPressed(FW_KEY_F7)) { + if (gApplication->GetInput()->IsKeyPressed(FW_KEY_F7)) { SpawnCrashObject(); } - if (gApplication->_input->IsKeyPressed(FW_KEY_F10)) { + if (gApplication->GetInput()->IsKeyPressed(FW_KEY_F10)) { ToggleNetworkStats(); } - if (gApplication->_input->IsKeyPressed(FW_KEY_F11)) { + if (gApplication->GetInput()->IsKeyPressed(FW_KEY_F11)) { ToggleEntityBrowser(); } } @@ -190,18 +159,18 @@ namespace MafiaMP::Core { void DevFeatures::Shutdown() {} void DevFeatures::SetupCommands() { - gApplication->_commandProcessor->RegisterCommand( + gApplication->GetCommandProcessor()->RegisterCommand( "help", {}, [this](cxxopts::ParseResult &) { std::stringstream ss; - for (const auto &name : gApplication->_commandProcessor->GetCommandNames()) { - ss << fmt::format("{} {:>8}\n", name, gApplication->_commandProcessor->GetCommandInfo(name)->options->help()); + for (const auto &name : gApplication->GetCommandProcessor()->GetCommandNames()) { + ss << fmt::format("{} {:>8}\n", name, gApplication->GetCommandProcessor()->GetCommandInfo(name)->options->help()); } Framework::Logging::GetLogger("Debug")->info("Available commands:\n{}", ss.str()); }, "prints all available commands"); - gApplication->_commandProcessor->RegisterCommand( + gApplication->GetCommandProcessor()->RegisterCommand( "test", {{"a,aargument", "Test argument 1", cxxopts::value()}, {"b,bargument", "Test argument 2", cxxopts::value()}}, [this](const cxxopts::ParseResult &result) { if (result.count("aargument")) { @@ -215,14 +184,14 @@ namespace MafiaMP::Core { }, "Testing command"); - gApplication->_commandProcessor->RegisterCommand( + gApplication->GetCommandProcessor()->RegisterCommand( "test", {}, [this](cxxopts::ParseResult &) { }, "crashes the game"); - gApplication->_commandProcessor->RegisterCommand( + gApplication->GetCommandProcessor()->RegisterCommand( "echo", {}, [this](const cxxopts::ParseResult &result) { std::string argsConcat; @@ -234,26 +203,26 @@ namespace MafiaMP::Core { }, "[args] - prints the arguments back"); - gApplication->_commandProcessor->RegisterCommand( + gApplication->GetCommandProcessor()->RegisterCommand( "exit", {}, [this](cxxopts::ParseResult &) { CloseGame(); }, "quits the game"); - gApplication->_commandProcessor->RegisterCommand( + gApplication->GetCommandProcessor()->RegisterCommand( "disconnect", {}, [this](const cxxopts::ParseResult &) { Disconnect(); }, "disconnect from server"); - gApplication->_commandProcessor->RegisterCommand( + gApplication->GetCommandProcessor()->RegisterCommand( "lua", {{"c,command", "command to execute", cxxopts::value()->default_value("")}, {"f,file", "file to execute", cxxopts::value()->default_value("")}}, [this](const cxxopts::ParseResult &result) { std::string command = result["command"].as(); if (!command.empty()) { - gApplication->_luaVM->ExecuteString(command.c_str()); + gApplication->GetLuaVM()->ExecuteString(command.c_str()); } std::string filename = result["file"].as(); if (!filename.empty()) { @@ -272,39 +241,39 @@ namespace MafiaMP::Core { Framework::Logging::GetLogger(LOG_LUA)->warn("Script is empty"); return; } - gApplication->_luaVM->ExecuteString(content.c_str()); + gApplication->GetLuaVM()->ExecuteString(content.c_str()); } }, "executes Lua commands"); - gApplication->_commandProcessor->RegisterCommand( + gApplication->GetCommandProcessor()->RegisterCommand( + "chat", {{"m,msg", "message to send", cxxopts::value()->default_value("")}}, + [this](const cxxopts::ParseResult &result) { + const auto net = gApplication->GetNetworkingEngine()->GetNetworkClient(); + if (net->GetConnectionState() == Framework::Networking::CONNECTED) { + MafiaMP::Shared::RPC::ChatMessage chatMessage {}; + chatMessage.FromParameters(result["msg"].as()); + net->SendRPC(chatMessage, SLNet::UNASSIGNED_RAKNET_GUID); + } + }, + "sends a chat message"); + + gApplication->GetCommandProcessor()->RegisterCommand( "spawnCar", {{"m,model", "model name of the car", cxxopts::value()->default_value("berkley_810")}}, [this](const cxxopts::ParseResult &result) { std::string modelName = result["model"].as(); - _worldDebug->SpawnCar(modelName); + _debugWorld->SpawnCar(modelName); }, "spawn a car of a given model"); - gApplication->_commandProcessor->RegisterCommand( + gApplication->GetCommandProcessor()->RegisterCommand( "spawnCrashObject", {}, [this](const cxxopts::ParseResult &result) { SpawnCrashObject(); }, "spawn a crash object"); - gApplication->_commandProcessor->RegisterCommand( - "chat", {{"m,msg", "message to send", cxxopts::value()->default_value("")}}, - [this](const cxxopts::ParseResult &result) { - const auto net = gApplication->GetNetworkingEngine()->GetNetworkClient(); - if (net->GetConnectionState() == Framework::Networking::CONNECTED) { - MafiaMP::Shared::RPC::ChatMessage chatMessage {}; - chatMessage.FromParameters(result["msg"].as()); - net->SendRPC(chatMessage, SLNet::UNASSIGNED_RAKNET_GUID); - } - }, - "sends a chat message"); - - gApplication->_commandProcessor->RegisterCommand( + gApplication->GetCommandProcessor()->RegisterCommand( "wep", {{"w,wep", "weapon id", cxxopts::value()->default_value("85")}, {"a,ammo", "ammo count", cxxopts::value()->default_value("200")}}, [this](const cxxopts::ParseResult &result) { const auto human = Game::Helpers::Controls::GetLocalPlayer(); @@ -317,58 +286,49 @@ namespace MafiaMP::Core { }, "give weapon"); - /*gApplication->_commandProcessor->RegisterCommand( - "camFPV", {}, - [this](const cxxopts::ParseResult &result) { - static bool fpvOn = false; - fpvOn = !fpvOn; - MafiaMP::Game::Helpers::Camera::SetFPV(fpvOn); - }, - "toggles camera first person view");*/ - - gApplication->_commandProcessor->RegisterCommand( - "showEntityBrowser", {}, + gApplication->GetCommandProcessor()->RegisterCommand( + "showCameraStudio", {}, [this](const cxxopts::ParseResult &result) { - ToggleEntityBrowser(); + ToggleCameraStudio(); }, - "toggles entity browser dialog"); + "toggles camera studio dialog"); - gApplication->_commandProcessor->RegisterCommand( - "showAudioDebug", {}, + gApplication->GetCommandProcessor()->RegisterCommand( + "showDebugAudio", {}, [this](const cxxopts::ParseResult &result) { - ToggleAudioDebug(); + ToggleDebugAudio(); }, "toggles audio debug dialog"); - gApplication->_commandProcessor->RegisterCommand( - "showCameraStudio", {}, + gApplication->GetCommandProcessor()->RegisterCommand( + "showDebugPlayer", {}, [this](const cxxopts::ParseResult &result) { - ToggleCameraStudio(); - }, - "toggles camera studio dialog"); - - gApplication->_commandProcessor->RegisterCommand( - "showPlayerDebug", {}, - [this](const cxxopts::ParseResult &result) { - TogglePlayerDebug(); + ToggleDebugPlayer(); }, "toggles player debug dialog"); - gApplication->_commandProcessor->RegisterCommand( - "showVehicleDebug", {}, + gApplication->GetCommandProcessor()->RegisterCommand( + "showDebugVehicle", {}, [this](const cxxopts::ParseResult &result) { - ToggleVehicleDebug(); + ToggleDebugVehicle(); }, "toggles vehicle debug dialog"); - gApplication->_commandProcessor->RegisterCommand( - "showWorldDebug", {}, + gApplication->GetCommandProcessor()->RegisterCommand( + "showDebugWorld", {}, [this](const cxxopts::ParseResult &result) { - ToggleWorldDebug(); + ToggleDebugWorld(); }, "toggles world debug dialog"); - gApplication->_commandProcessor->RegisterCommand( + gApplication->GetCommandProcessor()->RegisterCommand( + "showEntityBrowser", {}, + [this](const cxxopts::ParseResult &result) { + ToggleEntityBrowser(); + }, + "toggles entity browser dialog"); + + gApplication->GetCommandProcessor()->RegisterCommand( "showNetworkStats", {}, [this](const cxxopts::ParseResult &result) { ToggleNetworkStats(); @@ -377,14 +337,14 @@ namespace MafiaMP::Core { } void DevFeatures::SetupMenuBar() { - gApplication->_console->RegisterMenuBarDrawer([this]() { - if (ImGui::BeginMenu("Debug")) { + gApplication->GetConsole()->RegisterMenuBarDrawer([this]() { + if (ImGui::BeginMenu("Quick commands")) { if (ImGui::MenuItem("Spawn car")) { - _worldDebug->SpawnCar(); + _debugWorld->SpawnCar(); } if (ImGui::MenuItem("Spawn 50 cars")) { for (size_t i = 0; i < 50; i++) { - _worldDebug->SpawnCar(); + _debugWorld->SpawnCar(); } } if (ImGui::MenuItem("Disconnect")) { @@ -402,21 +362,21 @@ namespace MafiaMP::Core { ImGui::EndMenu(); } - if (ImGui::BeginMenu("Editors")) { + if (ImGui::BeginMenu("Dialogs")) { if (ImGui::MenuItem("World debug", "F1")) { - ToggleWorldDebug(); + ToggleDebugWorld(); } if (ImGui::MenuItem("Player debug", "F2")) { - TogglePlayerDebug(); + ToggleDebugPlayer(); } if (ImGui::MenuItem("Vehicle debug", "F3")) { - ToggleVehicleDebug(); + ToggleDebugVehicle(); } if (ImGui::MenuItem("Camera Studio", "F4")) { ToggleCameraStudio(); } if (ImGui::MenuItem("Audio debug")) { - ToggleAudioDebug(); + ToggleDebugAudio(); } if (ImGui::MenuItem("Network stats", "F10")) { ToggleNetworkStats(); @@ -430,32 +390,32 @@ namespace MafiaMP::Core { }); } - void DevFeatures::ToggleAudioDebug() { - _audioDebug->SetVisible(!_audioDebug->IsVisible()); + void DevFeatures::ToggleCameraStudio() { + _cameraStudio->Toggle(); } - void DevFeatures::ToggleEntityBrowser() { - _entityBrowser->SetVisible(!_entityBrowser->IsVisible()); + void DevFeatures::ToggleDebugAudio() { + _debugAudio->Toggle(); } - void DevFeatures::ToggleNetworkStats() { - _networkStats->SetVisible(!_networkStats->IsVisible()); + void DevFeatures::ToggleDebugPlayer() { + _debugPlayer->Toggle(); } - void DevFeatures::ToggleCameraStudio() { - _cameraStudio->SetVisible(!_playerDebug->IsVisible()); + void DevFeatures::ToggleDebugVehicle() { + _debugVehicle->Toggle(); } - void DevFeatures::TogglePlayerDebug() { - _playerDebug->SetVisible(!_playerDebug->IsVisible()); + void DevFeatures::ToggleDebugWorld() { + _debugWorld->Toggle(); } - void DevFeatures::ToggleVehicleDebug() { - _vehicleDebug->SetVisible(!_vehicleDebug->IsVisible()); + void DevFeatures::ToggleEntityBrowser() { + _entityBrowser->Toggle(); } - void DevFeatures::ToggleWorldDebug() { - _worldDebug->SetVisible(!_worldDebug->IsVisible()); + void DevFeatures::ToggleNetworkStats() { + _networkStats->Toggle(); } void DevFeatures::Disconnect() { diff --git a/code/client/src/core/dev_features.h b/code/client/src/core/dev_features.h index d01b9b38..7d7810f7 100644 --- a/code/client/src/core/dev_features.h +++ b/code/client/src/core/dev_features.h @@ -1,47 +1,36 @@ -/* - * MafiaHub OSS license - * Copyright (c) 2022, MafiaHub. All rights reserved. - * - * This file comes from MafiaHub, hosted at https://github.com/MafiaHub/Framework. - * See LICENSE file in the source repository for information regarding licensing. - */ - #pragma once -#include "game/streaming/entity_tracking_info.h" - #include #include -#include -#include "ui/audio_debug.h" -#include "ui/camera_studio.h" -#include "ui/entity_browser.h" -#include "ui/network_stats.h" -#include "ui/player_debug.h" -#include "ui/vehicle_debug.h" -#include "ui/world_debug.h" +#include "game/streaming/entity_tracking_info.h" -#include "sdk/entities/c_human_2.h" +#include "ui/devs/camera_studio.h" +#include "ui/devs/debug_audio.h" +#include "ui/devs/debug_player.h" +#include "ui/devs/debug_vehicle.h" +#include "ui/devs/debug_world.h" +#include "ui/devs/entity_browser.h" +#include "ui/devs/network_stats.h" namespace MafiaMP::Core { class DevFeatures final { private: Game::Streaming::EntityTrackingInfo *_TEMP_HUMAN = nullptr; - std::shared_ptr _audioDebug {}; + std::shared_ptr _cameraStudio {}; - std::shared_ptr _entityBrowser {}; + std::shared_ptr _debugAudio {}; - std::shared_ptr _cameraStudio {}; + std::shared_ptr _debugPlayer {}; - std::shared_ptr _playerDebug {}; + std::shared_ptr _debugVehicle {}; - std::shared_ptr _vehicleDebug {}; + std::shared_ptr _debugWorld {}; - std::shared_ptr _worldDebug {}; + std::shared_ptr _entityBrowser {}; - std::shared_ptr _networkStats {}; + std::shared_ptr _networkStats {}; public: DevFeatures(); @@ -53,13 +42,13 @@ namespace MafiaMP::Core { void SetupCommands(); void SetupMenuBar(); - void ToggleAudioDebug(); void ToggleCameraStudio(); + void ToggleDebugAudio(); + void ToggleDebugPlayer(); + void ToggleDebugVehicle(); + void ToggleDebugWorld(); void ToggleEntityBrowser(); void ToggleNetworkStats(); - void TogglePlayerDebug(); - void ToggleVehicleDebug(); - void ToggleWorldDebug(); void Disconnect(); void CrashMe(); diff --git a/code/client/src/core/modules/human.cpp b/code/client/src/core/modules/human.cpp index 0bee6a20..889b7675 100644 --- a/code/client/src/core/modules/human.cpp +++ b/code/client/src/core/modules/human.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include diff --git a/code/client/src/core/states/main_menu.cpp b/code/client/src/core/states/main_menu.cpp index 19217b3c..2ce0ee6f 100644 --- a/code/client/src/core/states/main_menu.cpp +++ b/code/client/src/core/states/main_menu.cpp @@ -29,7 +29,7 @@ namespace MafiaMP::Core::States { _shouldProceedOfflineDebug = false; _shouldProceedConnection = false; - // Lock game controls + // Lock controls gApplication->LockControls(true); // Grab the view from the application @@ -105,9 +105,7 @@ namespace MafiaMP::Core::States { view->Display(false); view->Focus(false); - // Unlock the game controls - Game::Helpers::Controls::Lock(false); - + // Unlock controls gApplication->LockControls(false); return true; } diff --git a/code/client/src/core/states/session_connected.cpp b/code/client/src/core/states/session_connected.cpp index a5592589..f0ecf4a0 100644 --- a/code/client/src/core/states/session_connected.cpp +++ b/code/client/src/core/states/session_connected.cpp @@ -1,8 +1,6 @@ #include "session_connected.h" #include "states.h" -#include "../../game/helpers/controls.h" - #include #include @@ -23,29 +21,30 @@ namespace MafiaMP::Core::States { } bool SessionConnectedState::OnEnter(Framework::Utils::States::Machine *) { - // Reset camera by player - //TODO + // Open Chat without disabling controls + gApplication->GetChat()->Open(false); + return true; } bool SessionConnectedState::OnExit(Framework::Utils::States::Machine *) { + gApplication->GetChat()->Close(); + return true; } bool SessionConnectedState::OnUpdate(Framework::Utils::States::Machine *) { gApplication->GetImGUI()->PushWidget([]() { - using namespace Framework::External::ImGUI::Widgets; - - if (!gApplication->GetDevConsole()->IsOpen()) { - gApplication->GetChat()->Update(); - } + gApplication->GetChat()->Update(); + using namespace Framework::External::ImGUI::Widgets; // For DrawCornerText() and Corner enum DrawCornerText(CORNER_RIGHT_TOP, "YOU ARE CONNECTED"); DrawCornerText(CORNER_RIGHT_TOP, "Press F9 to disconnect"); }); if (gApplication->GetInput()->IsKeyPressed(FW_KEY_F9)) { gApplication->GetNetworkingEngine()->GetNetworkClient()->Disconnect(); + return true; } return false; } diff --git a/code/client/src/core/states/session_disconnection.cpp b/code/client/src/core/states/session_disconnection.cpp index e76c7589..5a10b553 100644 --- a/code/client/src/core/states/session_disconnection.cpp +++ b/code/client/src/core/states/session_disconnection.cpp @@ -3,6 +3,8 @@ #include +#include "core/application.h" + namespace MafiaMP::Core::States { SessionDisconnectionState::SessionDisconnectionState() {} @@ -18,6 +20,7 @@ namespace MafiaMP::Core::States { bool SessionDisconnectionState::OnEnter(Framework::Utils::States::Machine *machine) { machine->RequestNextState(StateIds::MainMenu); + return true; } diff --git a/code/client/src/core/ui/audio_debug.h b/code/client/src/core/ui/audio_debug.h deleted file mode 100644 index 60b9ec73..00000000 --- a/code/client/src/core/ui/audio_debug.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -namespace MafiaMP::Core::UI { - class AudioDebug final { - public: - AudioDebug(); - - void Update(); - - bool IsVisible() const { - return _visible; - } - - void SetVisible(bool visible) { - _visible = visible; - } - - private: - bool _visible = false; - }; -} // namespace MafiaMP::Core::UI diff --git a/code/client/src/core/ui/chat.cpp b/code/client/src/core/ui/chat.cpp index 4fba896c..d0e9c91a 100644 --- a/code/client/src/core/ui/chat.cpp +++ b/code/client/src/core/ui/chat.cpp @@ -1,46 +1,53 @@ #include "chat.h" +#include + #include "core/application.h" + #include "game/helpers/controls.h" -#include +namespace MafiaMP::Core::UI { + void Chat::OnOpen() {} -#include + void Chat::OnClose() {} + + void Chat::OnUpdate() { + bool _wasFocused = _isFocused; -namespace MafiaMP::Core::UI { - void Chat::Update() { ImGui::SetNextWindowSize(ImVec2(400, 300)); ImGui::SetNextWindowPos(ImVec2(20, 20)); - ImGui::Begin("Chat", nullptr, ImGuiWindowFlags_NoScrollbar); - ImGui::BeginChild("##scrolling", ImVec2(ImGui::GetWindowWidth() * 0.95f, ImGui::GetWindowHeight() * 0.80f)); + ImGui::Begin("Chat", NULL, ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize); + + { + ImGui::PushFontShadow(0xFF000000); + ImGui::BeginChild("##scrolling", ImVec2(ImGui::GetWindowWidth() * 0.95f, ImGui::GetWindowHeight() * 0.80f), false, _isFocused ? 0 : ImGuiWindowFlags_NoScrollbar); - if (!_chatMessages.empty()) { - for (const auto &msg : _chatMessages) { - ImGui::TextWrapped("%s", msg.c_str()); + if (!_chatMessages.empty()) { + for (const auto &msg : _chatMessages) { + ImGui::TextWrapped("%s", msg.c_str()); + } } - } - if (_newMsgArrived) { - if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) - ImGui::SetScrollHereY(1.0f); - _newMsgArrived = false; - } + if (_newMsgArrived) { + if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) { + ImGui::SetScrollHereY(1.0f); + } + _newMsgArrived = false; + } - bool _wasFocused = _isFocused; + if (gApplication->GetInput()->IsKeyPressed(FW_KEY_RETURN) && !_isFocused) { + _isFocused = true; + LockControls(true); + if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) { + ImGui::SetScrollHereY(1.0f); + } + } - if (gApplication->GetInput()->IsKeyPressed(FW_KEY_RETURN) && !_isFocused) { - _isFocused = true; - gApplication->LockControls(true); - if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) - ImGui::SetScrollHereY(1.0f); + ImGui::EndChild(); + ImGui::PopFontShadow(); } - ImGui::EndChild(); - if (_isFocused) { - ImGui::SetNextItemWidth(ImGui::GetWindowWidth() * 0.95f); - ImGui::SetKeyboardFocusHere(0); - auto inputEditCallback = [&](ImGuiInputTextCallbackData *data) { if (data->EventFlag == ImGuiInputTextFlags_CallbackHistory && data->EventKey == ImGuiKey_UpArrow) { if (_history.empty()) @@ -77,7 +84,9 @@ namespace MafiaMP::Core::UI { return 0; }; - ImGui::InputText("##chatinput", _inputText, sizeof(_inputText), ImGuiInputTextFlags_CallbackHistory, Framework::External::ImGUI::getCallback(inputEditCallback), &inputEditCallback); + ImGui::SetNextItemWidth(ImGui::GetWindowWidth() * 0.95f); + ImGui::SetKeyboardFocusHere(0); + ImGui::InputText("##input_text", _inputText, sizeof(_inputText), ImGuiInputTextFlags_CallbackHistory, Framework::External::ImGUI::getCallback(inputEditCallback), &inputEditCallback); if (_wasFocused && gApplication->GetInput()->IsKeyPressed(FW_KEY_RETURN)) { if (strlen(_inputText)) { @@ -87,11 +96,14 @@ namespace MafiaMP::Core::UI { } _isFocused = false; - gApplication->LockControls(false); - if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) + LockControls(false); + + if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) { ImGui::SetScrollHereY(1.0f); + } } } + ImGui::End(); } } // namespace MafiaMP::Core::UI diff --git a/code/client/src/core/ui/chat.h b/code/client/src/core/ui/chat.h index f785a0f3..1f3ab7bb 100644 --- a/code/client/src/core/ui/chat.h +++ b/code/client/src/core/ui/chat.h @@ -1,20 +1,41 @@ #pragma once -#include "utils/safe_win32.h" +#include "ui_base.h" #include - #include #include namespace MafiaMP::Core::UI { - class Chat final { + class Chat final: public UIBase { public: using OnMessageSentProc = fu2::function; - Chat() = default; + private: + OnMessageSentProc onMessageSentProc {}; + + bool _newMsgArrived = false; + + bool _isFocused = false; + + std::vector _chatMessages; + + char _inputText[1024] {}; + + std::vector _history; + + std::string _tempInputText; + + int _historyPos = -1; + + virtual void OnOpen() override; + + virtual void OnClose() override; - void Update(); + virtual void OnUpdate() override; + + public: + Chat(): UIBase() {}; inline void SetOnMessageSentCallback(OnMessageSentProc proc) { onMessageSentProc = proc; @@ -24,14 +45,5 @@ namespace MafiaMP::Core::UI { _chatMessages.push_back(msg); _newMsgArrived = true; } - private: - OnMessageSentProc onMessageSentProc {}; - bool _newMsgArrived = false; - bool _isFocused = false; - std::vector _chatMessages; - char _inputText[1024] {}; - std::vector _history; - std::string _tempInputText; - int _historyPos = -1; }; } // namespace MafiaMP::Core::UI diff --git a/code/client/src/core/ui/console.cpp b/code/client/src/core/ui/console.cpp index dd3a3146..fdf248da 100644 --- a/code/client/src/core/ui/console.cpp +++ b/code/client/src/core/ui/console.cpp @@ -1,21 +1,7 @@ #include "console.h" -#include "../application.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../../game/helpers/controls.h" +#include namespace MafiaMP::Core::UI { - MafiaConsole::MafiaConsole(std::shared_ptr commandProcessor, std::shared_ptr input): Framework::External::ImGUI::Widgets::Console(commandProcessor, input) {} - - void MafiaConsole::LockControls(bool lock) { - gApplication->LockControls(lock); - } + Console::Console(std::shared_ptr commandProcessor): Framework::External::ImGUI::Widgets::Console(commandProcessor), Core::UI::UIBase() {} } // namespace MafiaMP::Core::UI diff --git a/code/client/src/core/ui/console.h b/code/client/src/core/ui/console.h index 4cfc9d2d..c6f42504 100644 --- a/code/client/src/core/ui/console.h +++ b/code/client/src/core/ui/console.h @@ -2,15 +2,17 @@ #include +#include "ui_base.h" + #include #include namespace MafiaMP::Core::UI { - class MafiaConsole: public Framework::External::ImGUI::Widgets::Console { + class Console + : public Framework::External::ImGUI::Widgets::Console + , public Core::UI::UIBase { public: - MafiaConsole(std::shared_ptr commandProcessor, std::shared_ptr input); - ~MafiaConsole() = default; - - virtual void LockControls(bool lock) override; + Console(std::shared_ptr commandProcessor); + ~Console() = default; }; } // namespace MafiaMP::Core::UI diff --git a/code/client/src/core/ui/camera_studio.cpp b/code/client/src/core/ui/devs/camera_studio.cpp similarity index 95% rename from code/client/src/core/ui/camera_studio.cpp rename to code/client/src/core/ui/devs/camera_studio.cpp index f65e4f22..b055d132 100644 --- a/code/client/src/core/ui/camera_studio.cpp +++ b/code/client/src/core/ui/devs/camera_studio.cpp @@ -1,15 +1,14 @@ #include "camera_studio.h" + +#include +#include + #include "game/helpers/controls.h" #include "sdk/entities/c_actor.h" #include "sdk/mafia/framework/c_mafia_framework.h" #include "sdk/mafia/framework/c_mafia_framework_interfaces.h" -#include - -#include -#include - // todo move to hooks typedef void(__fastcall *C_GameCameraMafia__LockTarget_t)(void *_this, void *targetSceneObject, void *targetSceneObject2, void *unk, float distance); C_GameCameraMafia__LockTarget_t C_GameCameraMafia__LockTarget_Original = nullptr; @@ -31,11 +30,13 @@ static InitFunction init([]() { MH_CreateHook((LPVOID)C_GameCameraMafia__LockTargetAddr, (PBYTE)C_GameCameraMafia__LockTarget, reinterpret_cast(&C_GameCameraMafia__LockTarget_Original)); }); -namespace MafiaMP::Core::UI { - CameraStudio::CameraStudio() {} +namespace MafiaMP::Core::UI::Devs { + void CameraStudio::OnOpen() {} + + void CameraStudio::OnClose() {} - void CameraStudio::Update() { - ImGui::Begin("Camera studio", &_visible); + void CameraStudio::OnUpdate() { + ImGui::Begin("Camera studio", &_open); { if (ImGui::Button("Enable")) { auto addr1 = hook::get_opcode_address("E8 ? ? ? ? 33 F6 EB 9F"); @@ -123,4 +124,4 @@ namespace MafiaMP::Core::UI { C_GameCameraMafia__LockTarget_Original(C_GameCameraPtr, _camera, 0, 0, 0.0f); } } -} // namespace MafiaMP::Core::UI +} // namespace MafiaMP::Core::UI::Devs diff --git a/code/client/src/core/ui/camera_studio.h b/code/client/src/core/ui/devs/camera_studio.h similarity index 52% rename from code/client/src/core/ui/camera_studio.h rename to code/client/src/core/ui/devs/camera_studio.h index dc960bac..f83be056 100644 --- a/code/client/src/core/ui/camera_studio.h +++ b/code/client/src/core/ui/devs/camera_studio.h @@ -2,27 +2,14 @@ #include "utils/safe_win32.h" +#include "../ui_base.h" + #include "sdk/ue/sys/core/c_scene_object.h" #include "sdk/ue/sys/math/c_vector.h" -namespace MafiaMP::Core::UI { - class CameraStudio final { - public: - CameraStudio(); - - void Update(); - - bool IsVisible() const { - return _visible; - } - - void SetVisible(bool visible) { - _visible = visible; - } - +namespace MafiaMP::Core::UI::Devs { + class CameraStudio final: public UIBase { private: - bool _visible = false; - SDK::ue::sys::core::C_SceneObject *_camera = nullptr; SDK::ue::sys::math::C_Vector _camForward = {1.0f, 0.0f, 0.0f}; @@ -30,5 +17,14 @@ namespace MafiaMP::Core::UI { POINT _mouseDelta {}; POINT _lastMousePos {}; + + virtual void OnOpen() override; + + virtual void OnClose() override; + + virtual void OnUpdate() override; + + public: + CameraStudio(): UIBase() {}; }; -} // namespace MafiaMP::Core::UI +} // namespace MafiaMP::Core::UI::Devs diff --git a/code/client/src/core/ui/audio_debug.cpp b/code/client/src/core/ui/devs/debug_audio.cpp similarity index 79% rename from code/client/src/core/ui/audio_debug.cpp rename to code/client/src/core/ui/devs/debug_audio.cpp index de175133..e76e9881 100644 --- a/code/client/src/core/ui/audio_debug.cpp +++ b/code/client/src/core/ui/devs/debug_audio.cpp @@ -1,18 +1,19 @@ -#include "audio_debug.h" - -#include +#include "debug_audio.h" #include "sdk/c_game_audio_module.h" -namespace MafiaMP::Core::UI { - AudioDebug::AudioDebug() {} +namespace MafiaMP::Core::UI::Devs { + void DebugAudio::OnOpen() {} - void AudioDebug::Update() { - const auto pAudioModule = SDK::C_GameAudioModule::GetAudioModule(); + void DebugAudio::OnClose() {} - ImGui::Begin("Audio debug", &_visible, ImGuiWindowFlags_AlwaysAutoResize); + void DebugAudio::OnUpdate() { + const auto pAudioModule = SDK::C_GameAudioModule::GetAudioModule(); + if (!pAudioModule) { + return; + } - if (pAudioModule) { + auto windowContent = [&]() { ImGui::Text("Audio Device Pointer : 0x%p\n", pAudioModule->m_pAudioDevice); float masterVolume = pAudioModule->m_fMasterVolume; @@ -41,8 +42,8 @@ namespace MafiaMP::Core::UI { } ImGui::Text("Dynamic Range: %i\n", pAudioModule->m_iDynamicRange); - } + }; - ImGui::End(); + CreateUIWindow("Audio debug", windowContent, &_open); } -}; // namespace MafiaMP::Core::UI +}; // namespace MafiaMP::Core::UI::Devs diff --git a/code/client/src/core/ui/devs/debug_audio.h b/code/client/src/core/ui/devs/debug_audio.h new file mode 100644 index 00000000..e370e2eb --- /dev/null +++ b/code/client/src/core/ui/devs/debug_audio.h @@ -0,0 +1,17 @@ +#pragma once + +#include "../ui_base.h" + +namespace MafiaMP::Core::UI::Devs { + class DebugAudio final: public UIBase { + private: + virtual void OnOpen() override; + + virtual void OnClose() override; + + virtual void OnUpdate() override; + + public: + DebugAudio(): UIBase() {}; + }; +} // namespace MafiaMP::Core::UI::Devs diff --git a/code/client/src/core/ui/devs/debug_player.cpp b/code/client/src/core/ui/devs/debug_player.cpp new file mode 100644 index 00000000..89082238 --- /dev/null +++ b/code/client/src/core/ui/devs/debug_player.cpp @@ -0,0 +1,137 @@ +#include "debug_player.h" + +#include "sdk/c_player_teleport_module.h" +#include "sdk/entities/c_player_2.h" + +#include "game/helpers/controls.h" + +namespace MafiaMP::Core::UI::Devs { + void DebugPlayer::OnOpen() {} + + void DebugPlayer::OnClose() {} + + void DebugPlayer::OnUpdate() { + /** + * TODO + * - Implement GetScale/SetScale => see https://github.com/MafiaHub/MafiaMP/issues/49 + * - Implement kill player => see https://github.com/MafiaHub/MafiaMP/issues/52 + */ + + const auto pActivePlayer = Game::Helpers::Controls::GetLocalPlayer(); + if (!pActivePlayer) { + return; + } + + auto windowContent = [&]() { + auto position = pActivePlayer->GetPos(); + if (ImGui::DragFloat3("Pos", (float *)&position, 0.1f, -4500.0f, 4500.0f)) { + pActivePlayer->SetPos(position); + } + + auto dir = pActivePlayer->GetDir(); + if (ImGui::DragFloat3("Dir", (float *)&dir, 0.01f, -1.0f, 1.0f)) { + pActivePlayer->SetDir(dir); + } + + auto rot = pActivePlayer->GetRot(); + if (ImGui::DragFloat4("Rot", (float *)&rot, 0.01f, -1.0f, 1.0f)) { + pActivePlayer->SetRot(rot); + } + + float transparency = pActivePlayer->GetTransparency(); + if (ImGui::SliderFloat("Transparency", &transparency, 0.0f, 1.0f)) { + pActivePlayer->SetTransparency(transparency); + } + + uint64_t defaultSpawnProfile = 335218123840277515; + ImGuiInputTextFlags_ defaultSpawnProfileGuiFlags = ImGuiInputTextFlags_ReadOnly; + ImGui::InputScalar("Default SpawnProfile", ImGuiDataType_U64, &defaultSpawnProfile, NULL, &defaultSpawnProfileGuiFlags); + + uint64_t spawnProfile = Game::Helpers::Controls::GetLocalPlayerSpawnProfile(); + if (ImGui::InputScalar("SpawnProfile", ImGuiDataType_U64, &spawnProfile, NULL)) { + Game::Helpers::Controls::PlayerChangeSpawnProfile(spawnProfile); + } + + ImGui::Text("RightHandWeaponID: %i\n", pActivePlayer->GetHumanWeaponController()->GetRightHandWeaponID()); + ImGui::Text("IsThrownWeapon: %s\n", pActivePlayer->GetHumanWeaponController()->IsThrownWeapon() ? "true" : "false"); + + ImGui::Text("IsDeath: %s\n", pActivePlayer->IsDeath() ? "true" : "false"); + + ImGui::Text("IsInVehicle: %s\n", pActivePlayer->IsInVehicle() ? "true" : "false"); + ImGui::Text("IsInCar: %s\n", pActivePlayer->IsInCar() ? "true" : "false"); + ImGui::Text("IsInBoat: %s\n", pActivePlayer->IsInBoat() ? "true" : "false"); + + ImGui::Text("IsCrouch: %s\n", pActivePlayer->IsCrouch() ? "true" : "false"); + + ImGui::Text("IsAiming: %s\n", pActivePlayer->GetHumanWeaponController()->IsAiming() ? "true" : "false"); + + ImGui::Text("IsInCover: %s\n", pActivePlayer->IsInCover() ? "true" : "false"); + ImGui::Text("IsInCoverFull(true): %s\n", pActivePlayer->IsInCoverFull(true) ? "true" : "false"); + ImGui::Text("IsInCoverFull(false): %s\n", pActivePlayer->IsInCoverFull(false) ? "true" : "false"); + + bool lockedControls = Game::Helpers::Controls::AreControlsLocked(); + if (ImGui::Checkbox("Lock Controls", &lockedControls)) { + Game::Helpers::Controls::Lock(lockedControls); + } + + bool demigod = pActivePlayer->GetHumanScript()->IsDemigod(); + if (ImGui::Checkbox("Demigod", &demigod)) { + pActivePlayer->GetHumanScript()->SetDemigod(demigod); + } + + bool invulnerable = pActivePlayer->GetHumanScript()->GetInvulnerabilityByScript(); + if (ImGui::Checkbox("Invulnerable", &invulnerable)) { + pActivePlayer->GetHumanScript()->SetInvulnerabilityByScript(invulnerable); + } + + float health = pActivePlayer->GetHumanScript()->GetHealth(); + if (ImGui::SliderFloat("Health", &health, 0.0f, pActivePlayer->GetHumanScript()->GetHealthMax())) { + pActivePlayer->GetHumanScript()->SetHealth(health); + (health); + } + + // SetHealthMax is explicitly disabled for the player + ImGui::Text("Health Max: %f\n", pActivePlayer->GetHumanScript()->GetHealthMax()); + + { + if (ImGui::Button("Heal")) { + float healthMax = pActivePlayer->GetHumanScript()->GetHealthMax(); + pActivePlayer->GetHumanScript()->SetHealth(healthMax); + } + + ImGui::SameLine(); + + if (ImGui::Button("Heal to -1.0f")) { + pActivePlayer->GetHumanScript()->SetHealth(-1.0f); // Doesn't kill the player + } + } + + { + if (ImGui::Button("Give weapons")) { + pActivePlayer->GetInventoryWrapper()->AddWeapon(85, 300); // Give Golden Tommy Gun (smg_trench_a_v2) + pActivePlayer->GetInventoryWrapper()->AddWeapon(3, 200); // Give Gold Pistol (p_mast_a_v2) + + pActivePlayer->GetHumanWeaponController()->DoWeaponSelectByItemId(85, true); // probably not the best way to do it (double hands guns are handled with one) + } + + ImGui::SameLine(); + + if (ImGui::Button("Throw weapon")) { + // Not sync + pActivePlayer->ThrowWeapon(); + } + } + + if (ImGui::Button("Teleport to Salieri's Bar")) { + SDK::ue::C_CntPtr syncObject; + auto pos = SDK::ue::sys::math::C_Vector(-916.0, -210.0, 2.605); + auto dir = SDK::ue::sys::math::C_Vector(1.0, 0.0, 0.0); + SDK::GetPlayerTeleportModule()->TeleportPlayer(syncObject, pos, dir, false, false, false, false); + } + + ImGui::Text("Player Ptr: %p", pActivePlayer); + }; + + CreateUIWindow("Player debug", windowContent, &_open); + } +}; // namespace MafiaMP::Core::UI::Devs diff --git a/code/client/src/core/ui/devs/debug_player.h b/code/client/src/core/ui/devs/debug_player.h new file mode 100644 index 00000000..28c78435 --- /dev/null +++ b/code/client/src/core/ui/devs/debug_player.h @@ -0,0 +1,17 @@ +#pragma once + +#include "../ui_base.h" + +namespace MafiaMP::Core::UI::Devs { + class DebugPlayer final: public UIBase { + private: + virtual void OnOpen() override; + + virtual void OnClose() override; + + virtual void OnUpdate() override; + + public: + DebugPlayer(): UIBase() {}; + }; +} // namespace MafiaMP::Core::UI::Devs diff --git a/code/client/src/core/ui/vehicle_debug.cpp b/code/client/src/core/ui/devs/debug_vehicle.cpp similarity index 92% rename from code/client/src/core/ui/vehicle_debug.cpp rename to code/client/src/core/ui/devs/debug_vehicle.cpp index d6dbeacc..9ca78c8a 100644 --- a/code/client/src/core/ui/vehicle_debug.cpp +++ b/code/client/src/core/ui/devs/debug_vehicle.cpp @@ -1,6 +1,4 @@ -#include "vehicle_debug.h" - -#include +#include "debug_vehicle.h" #include @@ -11,20 +9,25 @@ #include "game/helpers/controls.h" -namespace MafiaMP::Core::UI { - VehicleDebug::VehicleDebug() {} +namespace MafiaMP::Core::UI::Devs { + void DebugVehicle::OnOpen() {} + + void DebugVehicle::OnClose() {} - void VehicleDebug::Update() { + void DebugVehicle::OnUpdate() { const auto pActivePlayer = Game::Helpers::Controls::GetLocalPlayer(); SDK::C_Car *currentCar = pActivePlayer ? reinterpret_cast(pActivePlayer->GetOwner()) : nullptr; - ImGui::Begin("Vehicle debug", &_visible, ImGuiWindowFlags_AlwaysAutoResize); + auto windowContent = [&]() { + if (!currentCar) { + ImGui::Text("You're not in a vehicle!"); + return; + } - if (currentCar) { auto currentVehicle = currentCar->GetVehicle(); if (ImGui::Button("Print Pointers")) { - Framework::Logging::GetLogger("bite")->info("Car Ptr: 0x{}, Vehicle Ptr: 0x{}", fmt::ptr(currentCar), fmt::ptr(currentVehicle)); + Framework::Logging::GetLogger("debug")->info("Car Ptr: 0x{}, Vehicle Ptr: 0x{}", fmt::ptr(currentCar), fmt::ptr(currentVehicle)); } auto position = currentCar->GetPos(); @@ -193,11 +196,8 @@ namespace MafiaMP::Core::UI { if (ImGui::Button("UnlockEntryPoints")) { currentCar->UnlockEntryPoints(); } - } - else { - ImGui::Text("You're not in a vehicle!"); - } + }; - ImGui::End(); + CreateUIWindow("Vehicle debug", windowContent, &_open, ImGuiWindowFlags_AlwaysAutoResize); } -}; // namespace MafiaMP::Core::UI +}; // namespace MafiaMP::Core::UI::Devs diff --git a/code/client/src/core/ui/devs/debug_vehicle.h b/code/client/src/core/ui/devs/debug_vehicle.h new file mode 100644 index 00000000..4516c5af --- /dev/null +++ b/code/client/src/core/ui/devs/debug_vehicle.h @@ -0,0 +1,17 @@ +#pragma once + +#include "../ui_base.h" + +namespace MafiaMP::Core::UI::Devs { + class DebugVehicle final: public UIBase { + private: + virtual void OnOpen() override; + + virtual void OnClose() override; + + virtual void OnUpdate() override; + + public: + DebugVehicle(): UIBase() {}; + }; +} // namespace MafiaMP::Core::UI::Devs diff --git a/code/client/src/core/ui/devs/debug_world.cpp b/code/client/src/core/ui/devs/debug_world.cpp new file mode 100644 index 00000000..ace0b6cc --- /dev/null +++ b/code/client/src/core/ui/devs/debug_world.cpp @@ -0,0 +1,304 @@ +#include "debug_world.h" + +#include + +#include "core/application.h" + +#include "sdk/c_game_gfx_env_eff_module.h" +#include "sdk/entities/c_car.h" +#include "sdk/entities/c_player_2.h" +#include "sdk/entities/c_vehicle.h" +#include "sdk/mafia/framework/c_mafia_dbs.h" +#include "sdk/ue/game/traffic/c_streaming_traffic_module.h" +#include "sdk/ue/gfx/environmenteffects/c_gfx_environment_effects.h" + +#include "game/helpers/controls.h" +#include "game/helpers/human.h" + +namespace MafiaMP::Core::UI::Devs { + void DebugWorld::OnOpen() {} + + void DebugWorld::OnClose() {} + + void DebugWorld::OnUpdate() { + const auto pActivePlayer = Game::Helpers::Controls::GetLocalPlayer(); + if (!pActivePlayer) { + return; + } + + const auto gfxEnvironmentEffects = SDK::ue::gfx::environmenteffects::C_GfxEnvironmentEffects::GetInstance(); + if (!gfxEnvironmentEffects) { + return; + } + const auto weatherManager = gfxEnvironmentEffects->GetWeatherManager(); + if (!weatherManager) { + return; + } + + const auto streamingTrafficModule = SDK::ue::game::traffic::C_StreamingTrafficModule::GetInstance(); + if (!streamingTrafficModule) { + return; + } + + auto windowContent = [&]() { + if (ImGui::CollapsingHeader("Vehicle spawner")) { + if (ImGui::Button("Despawn all")) { + for (const auto &vehicle : _spawnedVehicles) { + gApplication->GetEntityFactory()->ReturnEntity(vehicle); + } + _spawnedVehicles.clear(); + } + + ImGui::Spacing(); + ImGui::Separator(); + ImGui::Spacing(); + + static const char *_selectedVehicleModelName = "berkley_810"; + + static bool _showSupportedOnly = true; + ImGui::Checkbox("Show supported by MafiaMP only", &_showSupportedOnly); + + static char _modelNameFilter[100] = ""; + ImGui::InputText("ModelName filter", _modelNameFilter, 100); + + { + const auto mafiaDB = SDK::mafia::framework::GetMafiaDBs(); + if (!mafiaDB) { + return; + } + + const auto vehiclesDB = mafiaDB->GetVehiclesDatabase(); + if (!vehiclesDB.IsValid()) { + return; + } + + const auto vehiclesDBCount = vehiclesDB->GetVehiclesCount(); + + if (ImGui::BeginListBox("Vehicle list")) { + for (int n = 0; n < vehiclesDBCount; n++) { + using namespace SDK::mafia::framework; + const C_VehiclesDatabase::TItemAccessorConst &vehicleAccessor = vehiclesDB->GetVehicleByIndex(n); + + if (const auto *vehicle = vehicleAccessor.Get()) { + const auto vehicleID = vehicle->GetID(); + + // Unused index, nothing to spawn + if (vehicle->GetID() == 0) { + continue; + } + + const char *modelName = vehicle->GetModelName(); + if (!modelName) { + Framework::Logging::GetLogger("Debug")->info("Skipping ID {}, encountered m_ModelName which is nullptr", vehicleID); + continue; + } + + if (_showSupportedOnly && vehicle->HasVehicleFlags(SDK::mafia::traffic::E_TrafficVehicleFlags::E_TVF_CAR) == false) { + continue; + } + + if (strlen(_modelNameFilter) > 0 && strstr(modelName, _modelNameFilter) == nullptr) { + continue; + } + + const bool isSelected = (strcmp(_selectedVehicleModelName, modelName) == 0); + + auto itemName = fmt::format("{} (id: {})", modelName, vehicleID); + if (ImGui::Selectable(itemName.c_str(), isSelected)) { + _selectedVehicleModelName = modelName; + } + + if (isSelected) { + ImGui::SetItemDefaultFocus(); + } + } + } + + ImGui::EndListBox(); + } + } + + static bool _putPlayerIn = true; + ImGui::Checkbox("Put player in", &_putPlayerIn); + + static bool _replacePreviousVehicleSpawned = true; + ImGui::Checkbox("Replace previous vehicle spawned", &_replacePreviousVehicleSpawned); + + if (ImGui::Button("Spawn")) { + SpawnCar(_selectedVehicleModelName, _putPlayerIn, _replacePreviousVehicleSpawned); + } + } + + if (ImGui::CollapsingHeader("Weather Set")) { + static float _weatherSetTransitionSpeed = 1.0f; + ImGui::InputFloat("Transition speed", &_weatherSetTransitionSpeed); + + static const char *_weatherSetNames[] = {"__test_all_cloud", "__test_cloud", "__test_high_cloud", "_default_editor", "_default_game", "_default_game_cloudy", "_default_game_foggy", "_default_game_morning_sunny", "_default_game_overcast", "_default_game_rainy", + "_test_jakub", "_time_of_day", "cine_0495_intermission_one_morello", "cine_0997", "cine_1195_omerta_funeral_night", "cine_1195_omerta_funeral_night_emiss_off", "cine_1700_afternoon2", "cine_1700_night_rain", "cine_1700_noon", "cine_1700_sunset", + "day_cycle_01", "lh_gui_menu_default", "main_menu", "mm_000_prolgue_cp_240_norman_stairs", "mm_000_prologue_cp_000", "mm_000_prologue_cp_00_lighthouse_cliff", "mm_000_prologue_cp_00_lihgthouse", "mm_000_prologue_cp_050_church_open", + "mm_000_prologue_cp_060_church_edge", "mm_000_prologue_cp_070_church_city", "mm_000_prologue_cp_080_city_look_up", "mm_000_prologue_cp_090_city_look_down", "mm_000_prologue_cp_100_italy_metro", "mm_000_prologue_cp_110_italy_market", + "mm_000_prologue_cp_120_italy_street", "mm_000_prologue_cp_130_city_to_work", "mm_000_prologue_cp_150_work_boat", "mm_000_prologue_cp_170_work_truck", "mm_000_prologue_cp_180_crowd", "mm_000_prologue_cp_190_boat_reveal", "mm_000_prologue_cp_200_boat_boat", + "mm_000_prologue_cp_210_boat_bridge", "mm_000_prologue_cp_220_norman_bridge", "mm_000_prologue_cp_260_crowd", "mm_000_prologue_cp_300_norman_feet", "mm_00_prologue_cp_00_lighthouse_car", "mm_00_prologue_cp_00_lighthouse_house", "mm_010_chase_cp_020_escape", + "mm_010_chase_cp_020_escape_gi_off", "mm_020_taxi_cp_010_arrival", "mm_020_taxi_cp_010_arrival_gi_off", "mm_020_taxi_cp_070_cine_0200_taxi", "mm_030_molotov_cp_010_cine", "mm_030_molotov_cp_010_cinematic_intro", "mm_040_motel_cp_005_meet_salieri", + "mm_050_race_cp_010", "mm_050_race_cp_110", "mm_050_race_cp_120", "mm_050_race_cp_140", "mm_060_sarah_cp_010_cine_0600_sarah_intro", "mm_070_hoodlums_cp_010", "mm_070_hoodlums_cp_086_cover_paulie", "mm_080_brothel_cp_010_cs_start", + "mm_080_brothel_cp_110_cine_0850_brothel_funera", "mm_100_farm_cp_000", "mm_100_farm_cp_050", "mm_100_farm_cp_080", "mm_100_farm_cp_140", "mm_110_omerta_cp_010_cs_cs_park", "mm_110_omerta_cp_050_cs_safehouse", "mm_110_omerta_cp_120_cine_funeral", + "mm_110_omerta_cp_120_cs_funeral", "mm_120_mansion_cp_010_cs_salvatore", "mm_130_parking_cp_010_cine_parking", "mm_140_salieri_cp_010_cine_salieri", "mm_140_salieri_cp_100_salieri_outro", "mm_150_boat_cp_010", "mm_150_boat_cp_080_explore_the_ship", + "mm_150_boat_cp_120", "mm_160_harbor_cp_000_cinematic_night", "mm_160_harbor_cp_010_cinematic_start", "mm_160_harbor_cp_080_harbour_entrance_cutscene", "mm_170_plane_cp_010_cine_1700_plane", "mm_170_plane_cp_060_cine_1750_plane_airport", + "mm_170_plane_cp_080_cine_1760_plane_shoot", "mm_180_sniper_cp_010", "mm_180_sniper_cp_010_2", "mm_190_cigars_cp_010_cs_intro", "mm_190_cigars_cp_030_drive_to_harbor", "mm_200_bank_cp_010_bank_arrival", "mm_210_gallery_cp_010", "mm_210_gallery_cp_050", + "mm_cine_0005_prologue", "mm_cine_0995_intermission_two", "mm_cine_1395_intermission_three", "mm_cine_1795_intermission_four", "mm_prologue_cp_290_cross_road", "outro_cine_2210_salieri", "outro_cine_2210_tommy_death", "outro_cine_2210_tommy_prison", + "outro_cine_2210_vincenzo_ralph", "outro_cine_2210_wedding", "temp_teaser_trailer", "test_for_screenshots_alpha", "test_no_color_grading_day", "test_no_color_grading_night", "test_no_color_grading_overcast", "trailer_comp_02", "trailer_comp_02b", + "trailer_comp_02c", "trailer_comp_03"}; + + const char *currentWeatherSet = SDK::C_GameGfxEnvEffModule::GetCurrentWeatherSetName(); + if (ImGui::BeginCombo("Name", currentWeatherSet)) { + for (int n = 0; n < IM_ARRAYSIZE(_weatherSetNames); n++) { + const bool isSelected = (strcmp(currentWeatherSet, _weatherSetNames[n]) == 0); + + if (ImGui::Selectable(_weatherSetNames[n], isSelected)) { + std::string selectedItem(_weatherSetNames[n]); + weatherManager->SetWeatherSet(selectedItem.c_str(), _weatherSetTransitionSpeed); + } + + if (isSelected) { + ImGui::SetItemDefaultFocus(); + } + } + ImGui::EndCombo(); + } + } + + if (ImGui::CollapsingHeader("Time")) { + float defaultTimeFlowSpeedMult = weatherManager->GetDefaultTimeFlowSpeedMult(); + if (ImGui::SliderFloat("DefaultTimeFlowSpeedMult", &defaultTimeFlowSpeedMult, 0.0f, 100.0f)) { + weatherManager->SetDefaultTimeFlowSpeedMult(defaultTimeFlowSpeedMult); + } + + float userTimeFlowSpeedMult = weatherManager->GetUserTimeFlowSpeedMult(); + if (ImGui::SliderFloat("UserTimeFlowSpeedMult", &userTimeFlowSpeedMult, 0.0f, 100.0f)) { + weatherManager->SetUserTimeFlowSpeedMult(userTimeFlowSpeedMult); + } + + bool isTimeFlowEnabled = weatherManager->IsTimeFlowEnabled(); + if (ImGui::Checkbox("Enable TimeFlow", &isTimeFlowEnabled)) { + weatherManager->EnableTimeFlow(isTimeFlowEnabled); + } + + float dayTimeHours = weatherManager->GetDayTimeHours(); + if (ImGui::SliderFloat("DayTimeHours", &dayTimeHours, 0.0f, 24.0f)) { + weatherManager->SetDayTimeHours(dayTimeHours); + } + + float dayTimeRel = weatherManager->GetDayTimeRel(); + ImGui::Text("DayTimeRel: %f", dayTimeRel); + + float dayTimeSec = *reinterpret_cast(weatherManager + 3212); + if (ImGui::InputFloat("DayTimeSec", &dayTimeSec)) { + weatherManager->SetDayTimeSec(dayTimeSec); + } + } + + if (ImGui::CollapsingHeader("Season")) { + if (ImGui::Button("Close Season")) { + streamingTrafficModule->CloseSeason(true); + } + + bool isSeasonOpened = streamingTrafficModule->GetSeasonOpened(); + ImGui::Text("Is Season Opened: %s\n", isSeasonOpened ? "true" : "false"); + + ImGui::Text("PreviousSeasonID: %i\n", streamingTrafficModule->GetPreviousSeasonID()); + + int currentSeasonID = streamingTrafficModule->GetCurrentSeasonID(); + ImGui::Text("CurrentSeasonID: %i\n", currentSeasonID); + + static const std::map _seasonMap = {{"No season", -1}, {"1930", 1}, {"1932", 2}, {"1933", 3}, {"1935", 4}, {"1938", 5}, {"Freeride", 100}}; + + auto foundSeasonID = std::find_if(_seasonMap.begin(), _seasonMap.end(), [currentSeasonID](const auto &pair) { + return pair.second == currentSeasonID; + }); + + const char *selectedSeasonName = (foundSeasonID != _seasonMap.end()) ? foundSeasonID->first : nullptr; + + if (ImGui::BeginCombo("##seasonId", selectedSeasonName)) { + for (auto it = _seasonMap.begin(); it != _seasonMap.end(); ++it) { + const bool isSelected = (currentSeasonID == it->second); + + if (ImGui::Selectable(it->first, isSelected)) { + streamingTrafficModule->CloseSeason(true); + streamingTrafficModule->OpenSeason(it->second, true); + } + + if (isSelected) { + ImGui::SetItemDefaultFocus(); + } + } + + ImGui::EndCombo(); + } + } + + if (ImGui::CollapsingHeader("Traffic")) { + int m_iMaxHumanElements = streamingTrafficModule->GetMaxHumanElements(); + if (ImGui::InputInt("MaxHumanElements", &m_iMaxHumanElements)) { + streamingTrafficModule->SetMaxHumanElements(m_iMaxHumanElements); + } + } + }; + + CreateUIWindow("World debug", windowContent, &_open); + } + + void DebugWorld::SpawnCar(std::string modelName, bool putPlayerIn, bool replacePrevious) { + auto info = gApplication->GetEntityFactory()->RequestVehicle(modelName); + + if (replacePrevious && !_spawnedVehicles.empty()) { + auto previousVehicle = _spawnedVehicles.back(); + gApplication->GetEntityFactory()->ReturnEntity(previousVehicle); + _spawnedVehicles.pop_back(); + } + + _spawnedVehicles.push_back(info); + + const auto OnCarRequestFinish = [putPlayerIn](Game::Streaming::EntityTrackingInfo *info, bool success) { + if (success) { + auto car = reinterpret_cast(info->GetEntity()); + if (!car) { + return; + } + car->GameInit(); + car->Activate(); + car->Unlock(); + + auto localPlayer = Game::Helpers::Controls::GetLocalPlayer(); + + SDK::ue::sys::math::C_Vector newPos = localPlayer->GetPos(); + SDK::ue::sys::math::C_Quat newRot = localPlayer->GetRot(); + SDK::ue::sys::math::C_Matrix transform = {}; + transform.Identity(); + transform.SetRot(newRot); + transform.SetPos(newPos); + car->GetVehicle()->SetVehicleMatrix(transform, SDK::ue::sys::core::E_TransformChangeType::DEFAULT); + car->GetVehicle()->SetSPZText("DEBUG", true); + + if (putPlayerIn) { + auto characterController = reinterpret_cast(localPlayer->GetCharacterController()); + Game::Helpers::Human::PutIntoCar(characterController, car, 0, true); + } + } + }; + + const auto OnCarReturned = [](Game::Streaming::EntityTrackingInfo *info, bool wasCreated) { + if (!info) { + return; + } + auto car = reinterpret_cast(info->GetEntity()); + if (wasCreated && car) { + car->Deactivate(); + car->GameDone(); + car->Release(); + } + }; + + info->SetRequestFinishCallback(OnCarRequestFinish); + info->SetReturnCallback(OnCarReturned); + } +}; // namespace MafiaMP::Core::UI::Devs diff --git a/code/client/src/core/ui/devs/debug_world.h b/code/client/src/core/ui/devs/debug_world.h new file mode 100644 index 00000000..a2901cf1 --- /dev/null +++ b/code/client/src/core/ui/devs/debug_world.h @@ -0,0 +1,26 @@ +#pragma once + +#include "../ui_base.h" + +#include +#include + +#include "game/streaming/entity_tracking_info.h" + +namespace MafiaMP::Core::UI::Devs { + class DebugWorld final: public UIBase { + private: + std::vector _spawnedVehicles; + + virtual void OnOpen() override; + + virtual void OnClose() override; + + virtual void OnUpdate() override; + + public: + DebugWorld(): UIBase() {}; + + void SpawnCar(std::string modelName = "berkley_810", bool putPlayerIn = false, bool replacePrevious = false); + }; +} // namespace MafiaMP::Core::UI::Devs diff --git a/code/client/src/core/ui/entity_browser.cpp b/code/client/src/core/ui/devs/entity_browser.cpp similarity index 96% rename from code/client/src/core/ui/entity_browser.cpp rename to code/client/src/core/ui/devs/entity_browser.cpp index e4538743..cc3a5d2a 100644 --- a/code/client/src/core/ui/entity_browser.cpp +++ b/code/client/src/core/ui/devs/entity_browser.cpp @@ -1,7 +1,6 @@ #include "entity_browser.h" -#include "../application.h" -#include +#include "core/application.h" #include #include @@ -10,24 +9,30 @@ #include "core/modules/human.h" #include "core/modules/vehicle.h" + #include "game/helpers/controls.h" -namespace MafiaMP::Core::UI { - EntityBrowser::EntityBrowser() { +namespace MafiaMP::Core::UI::Devs { + EntityBrowser::EntityBrowser(): UIBase() { InitialiseEntityTypes(); } - void EntityBrowser::Update() { + void EntityBrowser::OnOpen() {} + + void EntityBrowser::OnClose() {} + + void EntityBrowser::OnUpdate() { auto entityList = SDK::GetEntityList(); - if (!entityList) + if (!entityList) { return; + } auto localPlayer = Game::Helpers::Controls::GetLocalPlayer(); - if (!localPlayer) + if (!localPlayer) { return; + } - ImGui::Begin("Entity Browser", &_visible); - { + auto windowContent = [&]() { if (ImGui::Button("Select all")) { for (size_t i = 0; i < (sizeof(_checkedTypes) / sizeof(_checkedTypes[0])); i++) _checkedTypes[i] = true; @@ -186,8 +191,9 @@ namespace MafiaMP::Core::UI { } } } - } - ImGui::End(); + }; + + CreateUIWindow("Entity Browser", windowContent, &_open); } void EntityBrowser::InitialiseEntityTypes() { @@ -210,4 +216,4 @@ namespace MafiaMP::Core::UI { {E_EntityType::E_ENTITY_HEAD_QUARTERS, "E_ENTITY_HEAD_QUARTERS"}, {E_EntityType::E_ENTITY_CRIME_BUSINESS, "E_ENTITY_CRIME_BUSINESS"}, {E_EntityType::E_ENTITY_BED, "E_ENTITY_BED"}, {E_EntityType::E_ENTITY_PROJECTILE_EXPLOSIVE, "E_ENTITY_PROJECTILE_EXPLOSIVE"}, {E_EntityType::E_ENTITY_SATCHEL_CHARGE, "E_ENTITY_SATCHEL_CHARGE"}, {E_EntityType::E_ENTITY_LAST_ID, "E_ENTITY_LAST_ID"}}; } -}; // namespace MafiaMP::Core::UI +}; // namespace MafiaMP::Core::UI::Devs diff --git a/code/client/src/core/ui/entity_browser.h b/code/client/src/core/ui/devs/entity_browser.h similarity index 52% rename from code/client/src/core/ui/entity_browser.h rename to code/client/src/core/ui/devs/entity_browser.h index 1b0fec8b..54006ac5 100644 --- a/code/client/src/core/ui/entity_browser.h +++ b/code/client/src/core/ui/devs/entity_browser.h @@ -1,8 +1,6 @@ #pragma once -#include "utils/safe_win32.h" - -#include +#include "../ui_base.h" #include #include @@ -10,36 +8,38 @@ #include "sdk/entities/c_entity.h" -namespace MafiaMP::Core::UI { - class EntityBrowser final { - public: - EntityBrowser(); - - void Update(); - - bool IsVisible() const { - return _visible; - } - - void SetVisible(bool visible) { - _visible = visible; - } - +namespace MafiaMP::Core::UI::Devs { + class EntityBrowser final: public UIBase { private: - bool _visible = false; - int _selectedIndex = 0; + std::unordered_map _allTypes {}; bool _checkedTypes[66] {}; + std::vector _filterList {}; - float _entityRange = 200.0f; + float _entityRange = 200.0f; + char _entityFilter[100] = ""; void InitialiseEntityTypes(); - enum class StreamFilter { NONE, STREAMED, OWNED }; + enum class StreamFilter { + NONE, + STREAMED, + OWNED + }; + StreamFilter _streamFilter = StreamFilter::NONE; + + virtual void OnOpen() override; + + virtual void OnClose() override; + + virtual void OnUpdate() override; + + public: + EntityBrowser(); }; -} // namespace MafiaMP::Core::UI +} // namespace MafiaMP::Core::UI::Devs diff --git a/code/client/src/core/ui/network_stats.cpp b/code/client/src/core/ui/devs/network_stats.cpp similarity index 72% rename from code/client/src/core/ui/network_stats.cpp rename to code/client/src/core/ui/devs/network_stats.cpp index 7c0e644e..462de0eb 100644 --- a/code/client/src/core/ui/network_stats.cpp +++ b/code/client/src/core/ui/devs/network_stats.cpp @@ -1,29 +1,29 @@ #include "network_stats.h" -#include "../application.h" #include #include -#include +#include "core/application.h" #include "game/helpers/controls.h" -namespace MafiaMP::Core::UI { - NetworkStats::NetworkStats() {} +namespace MafiaMP::Core::UI::Devs { + void NetworkStats::OnOpen() {} - void NetworkStats::Update() { + void NetworkStats::OnClose() {} + + void NetworkStats::OnUpdate() { auto localPlayer = Game::Helpers::Controls::GetLocalPlayer(); - if (!localPlayer) + if (!localPlayer) { return; + } - ImGui::Begin("Network Stats", &_visible, ImGuiWindowFlags_AlwaysAutoResize); - { + auto windowContent = [&]() { const auto net = gApplication->GetNetworkingEngine()->GetNetworkClient(); const auto state = net->GetConnectionState(); if (state != Framework::Networking::CONNECTED) { ImGui::Text("You are currently not connected to a server!"); - ImGui::End(); return; } @@ -37,7 +37,8 @@ namespace MafiaMP::Core::UI { } ImGui::Text("%s", _stats); - } - ImGui::End(); + }; + + CreateUIWindow("Network Stats", windowContent, &_open, ImGuiWindowFlags_AlwaysAutoResize); } -} // namespace MafiaMP::Core::UI +} // namespace MafiaMP::Core::UI::Devs diff --git a/code/client/src/core/ui/devs/network_stats.h b/code/client/src/core/ui/devs/network_stats.h new file mode 100644 index 00000000..34d88723 --- /dev/null +++ b/code/client/src/core/ui/devs/network_stats.h @@ -0,0 +1,23 @@ +#pragma once + +#include "../ui_base.h" + +#include + +namespace MafiaMP::Core::UI::Devs { + class NetworkStats final: public UIBase { + private: + int64_t _nextStatsUpdate = 0; + + char _stats[8192] = {0}; + + virtual void OnOpen() override; + + virtual void OnClose() override; + + virtual void OnUpdate() override; + + public: + NetworkStats(): UIBase() {}; + }; +} // namespace MafiaMP::Core::UI::Devs diff --git a/code/client/src/core/ui/network_stats.h b/code/client/src/core/ui/network_stats.h deleted file mode 100644 index 6b7264d2..00000000 --- a/code/client/src/core/ui/network_stats.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include "utils/safe_win32.h" -#include - -namespace MafiaMP::Core::UI { - class NetworkStats final { - public: - NetworkStats(); - - void Update(); - - bool IsVisible() const { - return _visible; - } - - void SetVisible(bool visible) { - _visible = visible; - } - - private: - bool _visible = false; - - int64_t _nextStatsUpdate = 0; - - char _stats[8192] = {0}; - }; -} // namespace MafiaMP::Core::UI diff --git a/code/client/src/core/ui/player_debug.cpp b/code/client/src/core/ui/player_debug.cpp deleted file mode 100644 index ef1e532e..00000000 --- a/code/client/src/core/ui/player_debug.cpp +++ /dev/null @@ -1,136 +0,0 @@ -#include "player_debug.h" - -#include - -#include "sdk/c_player_teleport_module.h" -#include "sdk/entities/c_player_2.h" - -#include "game/helpers/controls.h" - -namespace MafiaMP::Core::UI { - PlayerDebug::PlayerDebug() {} - - void PlayerDebug::Update() { - /** - * TODO - * - Implement GetScale/SetScale => see https://github.com/MafiaHub/MafiaMP/issues/49 - * - Implement kill player => see https://github.com/MafiaHub/MafiaMP/issues/52 - */ - - const auto pActivePlayer = Game::Helpers::Controls::GetLocalPlayer(); - if (!pActivePlayer) - return; - - ImGui::Begin("Player debug", &_visible); - - auto position = pActivePlayer->GetPos(); - if (ImGui::DragFloat3("Pos", (float *)&position, 0.1f, -4500.0f, 4500.0f)) { - pActivePlayer->SetPos(position); - } - - auto dir = pActivePlayer->GetDir(); - if (ImGui::DragFloat3("Dir", (float *)&dir, 0.01f, -1.0f, 1.0f)) { - pActivePlayer->SetDir(dir); - } - - auto rot = pActivePlayer->GetRot(); - if (ImGui::DragFloat4("Rot", (float *)&rot, 0.01f, -1.0f, 1.0f)) { - pActivePlayer->SetRot(rot); - } - - float transparency = pActivePlayer->GetTransparency(); - if (ImGui::SliderFloat("Transparency", &transparency, 0.0f, 1.0f)) { - pActivePlayer->SetTransparency(transparency); - } - - uint64_t defaultSpawnProfile = 335218123840277515; - ImGuiInputTextFlags_ defaultSpawnProfileGuiFlags = ImGuiInputTextFlags_ReadOnly; - ImGui::InputScalar("Default SpawnProfile", ImGuiDataType_U64, &defaultSpawnProfile, NULL, &defaultSpawnProfileGuiFlags); - - uint64_t spawnProfile = Game::Helpers::Controls::GetLocalPlayerSpawnProfile(); - if (ImGui::InputScalar("SpawnProfile", ImGuiDataType_U64, &spawnProfile, NULL)) { - Game::Helpers::Controls::PlayerChangeSpawnProfile(spawnProfile); - } - - ImGui::Text("RightHandWeaponID: %i\n", pActivePlayer->GetHumanWeaponController()->GetRightHandWeaponID()); - ImGui::Text("IsThrownWeapon: %s\n", pActivePlayer->GetHumanWeaponController()->IsThrownWeapon() ? "true" : "false"); - - ImGui::Text("IsDeath: %s\n", pActivePlayer->IsDeath() ? "true" : "false"); - - ImGui::Text("IsInVehicle: %s\n", pActivePlayer->IsInVehicle() ? "true" : "false"); - ImGui::Text("IsInCar: %s\n", pActivePlayer->IsInCar() ? "true" : "false"); - ImGui::Text("IsInBoat: %s\n", pActivePlayer->IsInBoat() ? "true" : "false"); - - ImGui::Text("IsCrouch: %s\n", pActivePlayer->IsCrouch() ? "true" : "false"); - - ImGui::Text("IsAiming: %s\n", pActivePlayer->GetHumanWeaponController()->IsAiming() ? "true" : "false"); - - ImGui::Text("IsInCover: %s\n", pActivePlayer->IsInCover() ? "true" : "false"); - ImGui::Text("IsInCoverFull(true): %s\n", pActivePlayer->IsInCoverFull(true) ? "true" : "false"); - ImGui::Text("IsInCoverFull(false): %s\n", pActivePlayer->IsInCoverFull(false) ? "true" : "false"); - - bool lockedControls = Game::Helpers::Controls::AreControlsLocked(); - if (ImGui::Checkbox("Lock Controls", &lockedControls)) { - Game::Helpers::Controls::Lock(lockedControls); - } - - bool demigod = pActivePlayer->GetHumanScript()->IsDemigod(); - if (ImGui::Checkbox("Demigod", &demigod)) { - pActivePlayer->GetHumanScript()->SetDemigod(demigod); - } - - bool invulnerable = pActivePlayer->GetHumanScript()->GetInvulnerabilityByScript(); - if (ImGui::Checkbox("Invulnerable", &invulnerable)) { - pActivePlayer->GetHumanScript()->SetInvulnerabilityByScript(invulnerable); - } - - float health = pActivePlayer->GetHumanScript()->GetHealth(); - if (ImGui::SliderFloat("Health", &health, 0.0f, pActivePlayer->GetHumanScript()->GetHealthMax())) { - pActivePlayer->GetHumanScript()->SetHealth(health); - (health); - } - - // SetHealthMax is explicitly disabled for the player - ImGui::Text("Health Max: %f\n", pActivePlayer->GetHumanScript()->GetHealthMax()); - - { - if (ImGui::Button("Heal")) { - float healthMax = pActivePlayer->GetHumanScript()->GetHealthMax(); - pActivePlayer->GetHumanScript()->SetHealth(healthMax); - } - - ImGui::SameLine(); - - if (ImGui::Button("Heal to -1.0f")) { - pActivePlayer->GetHumanScript()->SetHealth(-1.0f); // Doesn't kill the player - } - } - - { - if (ImGui::Button("Give weapons")) { - pActivePlayer->GetInventoryWrapper()->AddWeapon(85, 300); // Give Golden Tommy Gun (smg_trench_a_v2) - pActivePlayer->GetInventoryWrapper()->AddWeapon(3, 200); // Give Gold Pistol (p_mast_a_v2) - - pActivePlayer->GetHumanWeaponController()->DoWeaponSelectByItemId(85, true); // probably not the best way to do it (double hands guns are handled with one) - } - - ImGui::SameLine(); - - if (ImGui::Button("Throw weapon")) { - // Not sync - pActivePlayer->ThrowWeapon(); - } - } - - if (ImGui::Button("Teleport to Salieri's Bar")) { - SDK::ue::C_CntPtr syncObject; - auto pos = SDK::ue::sys::math::C_Vector(-916.0, -210.0, 2.605); - auto dir = SDK::ue::sys::math::C_Vector(1.0, 0.0, 0.0); - SDK::GetPlayerTeleportModule()->TeleportPlayer(syncObject, pos, dir, false, false, false, false); - } - - ImGui::Text("Player Ptr: %p", pActivePlayer); - - ImGui::End(); - } -}; // namespace MafiaMP::Core::UI diff --git a/code/client/src/core/ui/player_debug.h b/code/client/src/core/ui/player_debug.h deleted file mode 100644 index 24f310ec..00000000 --- a/code/client/src/core/ui/player_debug.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include "utils/safe_win32.h" - -namespace MafiaMP::Core::UI { - class PlayerDebug final { - public: - PlayerDebug(); - - void Update(); - - bool IsVisible() const { - return _visible; - } - - void SetVisible(bool visible) { - _visible = visible; - } - - private: - bool _visible = false; - }; -} // namespace MafiaMP::Core::UI diff --git a/code/client/src/core/ui/ui_base.cpp b/code/client/src/core/ui/ui_base.cpp new file mode 100644 index 00000000..05959899 --- /dev/null +++ b/code/client/src/core/ui/ui_base.cpp @@ -0,0 +1,17 @@ +#include "ui_base.h" + +#include "core/application.h" + +namespace MafiaMP::Core::UI { + bool UIBase::AreControlsLocked() const { + if (gApplication->AreControlsLockedBypassed()) { + return false; + } + + return gApplication->AreControlsLocked(); + } + + void UIBase::LockControls(bool lock) const { + gApplication->LockControls(lock); + } +} // namespace MafiaMP::Core::UI diff --git a/code/client/src/core/ui/ui_base.h b/code/client/src/core/ui/ui_base.h new file mode 100644 index 00000000..5b16baf7 --- /dev/null +++ b/code/client/src/core/ui/ui_base.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +namespace MafiaMP::Core::UI { + class UIBase: virtual public Framework::External::ImGUI::Widgets::UIBase { + protected: + virtual bool AreControlsLocked() const override; + + virtual void LockControls(bool lock) const override; + + public: + UIBase(): Framework::External::ImGUI::Widgets::UIBase() {}; + }; +} // namespace MafiaMP::Core::UI diff --git a/code/client/src/core/ui/vehicle_debug.h b/code/client/src/core/ui/vehicle_debug.h deleted file mode 100644 index 18b8fdad..00000000 --- a/code/client/src/core/ui/vehicle_debug.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include "utils/safe_win32.h" - -namespace MafiaMP::Core::UI { - class VehicleDebug final { - public: - VehicleDebug(); - - void Update(); - - bool IsVisible() const { - return _visible; - } - - void SetVisible(bool visible) { - _visible = visible; - } - - private: - bool _visible = false; - }; -} // namespace MafiaMP::Core::UI diff --git a/code/client/src/core/ui/world_debug.cpp b/code/client/src/core/ui/world_debug.cpp deleted file mode 100644 index 9a855c15..00000000 --- a/code/client/src/core/ui/world_debug.cpp +++ /dev/null @@ -1,304 +0,0 @@ -#include "world_debug.h" - -#include "../application.h" - -#include - -#include - -#include "sdk/c_game_gfx_env_eff_module.h" -#include "sdk/entities/c_player_2.h" -#include "sdk/mafia/framework/c_mafia_dbs.h" -#include "sdk/ue/game/traffic/c_streaming_traffic_module.h" -#include "sdk/ue/gfx/environmenteffects/c_gfx_environment_effects.h" - -#include "sdk/entities/c_car.h" -#include "sdk/entities/c_vehicle.h" - -#include "game/helpers/controls.h" -#include "game/helpers/human.h" - -namespace MafiaMP::Core::UI { - WorldDebug::WorldDebug() {} - - void WorldDebug::Update() { - const auto pActivePlayer = Game::Helpers::Controls::GetLocalPlayer(); - if (!pActivePlayer) { - return; - } - - const auto gfxEnvironmentEffects = SDK::ue::gfx::environmenteffects::C_GfxEnvironmentEffects::GetInstance(); - if (!gfxEnvironmentEffects) { - return; - } - const auto weatherManager = gfxEnvironmentEffects->GetWeatherManager(); - if (!weatherManager) { - return; - } - - const auto streamingTrafficModule = SDK::ue::game::traffic::C_StreamingTrafficModule::GetInstance(); - if (!streamingTrafficModule) { - return; - } - - ImGui::Begin("World debug", &_visible); - - if (ImGui::CollapsingHeader("Vehicle spawner")) { - if (ImGui::Button("Despawn all")) { - for (const auto &vehicle : _spawnedVehicles) { - gApplication->GetEntityFactory()->ReturnEntity(vehicle); - } - _spawnedVehicles.clear(); - } - - ImGui::Spacing(); - ImGui::Separator(); - ImGui::Spacing(); - - static const char *selectedVehicleModelName = "berkley_810"; - - static bool toggleShowSupportedOnly = true; - ImGui::Checkbox("Show supported by MafiaMP only", &toggleShowSupportedOnly); - - static char modelNameFilter[100] = ""; - ImGui::InputText("ModelName filter", modelNameFilter, 100); - - { - const auto mafiaDB = SDK::mafia::framework::GetMafiaDBs(); - if (!mafiaDB) { - return; - } - - const auto vehiclesDB = mafiaDB->GetVehiclesDatabase(); - if (!vehiclesDB.IsValid()) { - return; - } - - const auto vehiclesDBCount = vehiclesDB->GetVehiclesCount(); - - if (ImGui::BeginListBox("Vehicle list")) { - for (int n = 0; n < vehiclesDBCount; n++) { - using namespace SDK::mafia::framework; - const C_VehiclesDatabase::TItemAccessorConst &vehicleAccessor = vehiclesDB->GetVehicleByIndex(n); - - if (const auto *vehicle = vehicleAccessor.Get()) { - const auto vehicleID = vehicle->GetID(); - - // Unused index, nothing to spawn - if (vehicle->GetID() == 0) { - continue; - } - - const char *modelName = vehicle->GetModelName(); - if (!modelName) { - Framework::Logging::GetLogger("Debug")->info("Skipping ID {}, encountered m_ModelName which is nullptr", vehicleID); - continue; - } - - if (toggleShowSupportedOnly && vehicle->HasVehicleFlags(SDK::mafia::traffic::E_TrafficVehicleFlags::E_TVF_CAR) == false) { - continue; - } - - if (strlen(modelNameFilter) > 0 && strstr(modelName, modelNameFilter) == nullptr) { - continue; - } - - const bool isSelected = (strcmp(selectedVehicleModelName, modelName) == 0); - - auto itemName = fmt::format("{} (id: {})", modelName, vehicleID); - if (ImGui::Selectable(itemName.c_str(), isSelected)) { - selectedVehicleModelName = modelName; - } - - if (isSelected) { - ImGui::SetItemDefaultFocus(); - } - } - } - - ImGui::EndListBox(); - } - } - - static bool togglePutPlayerIn = true; - ImGui::Checkbox("Put player in", &togglePutPlayerIn); - - static bool toggleReplacePreviousVehicleSpawned = true; - ImGui::Checkbox("Replace previous vehicle spawned", &toggleReplacePreviousVehicleSpawned); - - if (ImGui::Button("Spawn")) { - SpawnCar(selectedVehicleModelName, togglePutPlayerIn, toggleReplacePreviousVehicleSpawned); - } - } - - if (ImGui::CollapsingHeader("Weather Set")) { - static float weatherSetTransitionSpeed = 1.0f; - ImGui::InputFloat("Transition speed", &weatherSetTransitionSpeed); - - static const char *weatherSetNames[] = {"__test_all_cloud", "__test_cloud", "__test_high_cloud", "_default_editor", "_default_game", "_default_game_cloudy", "_default_game_foggy", "_default_game_morning_sunny", "_default_game_overcast", "_default_game_rainy", - "_test_jakub", "_time_of_day", "cine_0495_intermission_one_morello", "cine_0997", "cine_1195_omerta_funeral_night", "cine_1195_omerta_funeral_night_emiss_off", "cine_1700_afternoon2", "cine_1700_night_rain", "cine_1700_noon", "cine_1700_sunset", "day_cycle_01", - "lh_gui_menu_default", "main_menu", "mm_000_prolgue_cp_240_norman_stairs", "mm_000_prologue_cp_000", "mm_000_prologue_cp_00_lighthouse_cliff", "mm_000_prologue_cp_00_lihgthouse", "mm_000_prologue_cp_050_church_open", "mm_000_prologue_cp_060_church_edge", - "mm_000_prologue_cp_070_church_city", "mm_000_prologue_cp_080_city_look_up", "mm_000_prologue_cp_090_city_look_down", "mm_000_prologue_cp_100_italy_metro", "mm_000_prologue_cp_110_italy_market", "mm_000_prologue_cp_120_italy_street", - "mm_000_prologue_cp_130_city_to_work", "mm_000_prologue_cp_150_work_boat", "mm_000_prologue_cp_170_work_truck", "mm_000_prologue_cp_180_crowd", "mm_000_prologue_cp_190_boat_reveal", "mm_000_prologue_cp_200_boat_boat", "mm_000_prologue_cp_210_boat_bridge", - "mm_000_prologue_cp_220_norman_bridge", "mm_000_prologue_cp_260_crowd", "mm_000_prologue_cp_300_norman_feet", "mm_00_prologue_cp_00_lighthouse_car", "mm_00_prologue_cp_00_lighthouse_house", "mm_010_chase_cp_020_escape", "mm_010_chase_cp_020_escape_gi_off", - "mm_020_taxi_cp_010_arrival", "mm_020_taxi_cp_010_arrival_gi_off", "mm_020_taxi_cp_070_cine_0200_taxi", "mm_030_molotov_cp_010_cine", "mm_030_molotov_cp_010_cinematic_intro", "mm_040_motel_cp_005_meet_salieri", "mm_050_race_cp_010", "mm_050_race_cp_110", - "mm_050_race_cp_120", "mm_050_race_cp_140", "mm_060_sarah_cp_010_cine_0600_sarah_intro", "mm_070_hoodlums_cp_010", "mm_070_hoodlums_cp_086_cover_paulie", "mm_080_brothel_cp_010_cs_start", "mm_080_brothel_cp_110_cine_0850_brothel_funera", "mm_100_farm_cp_000", - "mm_100_farm_cp_050", "mm_100_farm_cp_080", "mm_100_farm_cp_140", "mm_110_omerta_cp_010_cs_cs_park", "mm_110_omerta_cp_050_cs_safehouse", "mm_110_omerta_cp_120_cine_funeral", "mm_110_omerta_cp_120_cs_funeral", "mm_120_mansion_cp_010_cs_salvatore", - "mm_130_parking_cp_010_cine_parking", "mm_140_salieri_cp_010_cine_salieri", "mm_140_salieri_cp_100_salieri_outro", "mm_150_boat_cp_010", "mm_150_boat_cp_080_explore_the_ship", "mm_150_boat_cp_120", "mm_160_harbor_cp_000_cinematic_night", - "mm_160_harbor_cp_010_cinematic_start", "mm_160_harbor_cp_080_harbour_entrance_cutscene", "mm_170_plane_cp_010_cine_1700_plane", "mm_170_plane_cp_060_cine_1750_plane_airport", "mm_170_plane_cp_080_cine_1760_plane_shoot", "mm_180_sniper_cp_010", - "mm_180_sniper_cp_010_2", "mm_190_cigars_cp_010_cs_intro", "mm_190_cigars_cp_030_drive_to_harbor", "mm_200_bank_cp_010_bank_arrival", "mm_210_gallery_cp_010", "mm_210_gallery_cp_050", "mm_cine_0005_prologue", "mm_cine_0995_intermission_two", - "mm_cine_1395_intermission_three", "mm_cine_1795_intermission_four", "mm_prologue_cp_290_cross_road", "outro_cine_2210_salieri", "outro_cine_2210_tommy_death", "outro_cine_2210_tommy_prison", "outro_cine_2210_vincenzo_ralph", "outro_cine_2210_wedding", - "temp_teaser_trailer", "test_for_screenshots_alpha", "test_no_color_grading_day", "test_no_color_grading_night", "test_no_color_grading_overcast", "trailer_comp_02", "trailer_comp_02b", "trailer_comp_02c", "trailer_comp_03"}; - - const char *currentWeatherSet = SDK::C_GameGfxEnvEffModule::GetCurrentWeatherSetName(); - if (ImGui::BeginCombo("Name", currentWeatherSet)) { - for (int n = 0; n < IM_ARRAYSIZE(weatherSetNames); n++) { - const bool isSelected = (strcmp(currentWeatherSet, weatherSetNames[n]) == 0); - - if (ImGui::Selectable(weatherSetNames[n], isSelected)) { - std::string selectedItem(weatherSetNames[n]); - weatherManager->SetWeatherSet(selectedItem.c_str(), weatherSetTransitionSpeed); - } - - if (isSelected) { - ImGui::SetItemDefaultFocus(); - } - } - ImGui::EndCombo(); - } - } - - if (ImGui::CollapsingHeader("Time")) { - float defaultTimeFlowSpeedMult = weatherManager->GetDefaultTimeFlowSpeedMult(); - if (ImGui::SliderFloat("DefaultTimeFlowSpeedMult", &defaultTimeFlowSpeedMult, 0.0f, 100.0f)) { - weatherManager->SetDefaultTimeFlowSpeedMult(defaultTimeFlowSpeedMult); - } - - float userTimeFlowSpeedMult = weatherManager->GetUserTimeFlowSpeedMult(); - if (ImGui::SliderFloat("UserTimeFlowSpeedMult", &userTimeFlowSpeedMult, 0.0f, 100.0f)) { - weatherManager->SetUserTimeFlowSpeedMult(userTimeFlowSpeedMult); - } - - bool isTimeFlowEnabled = weatherManager->IsTimeFlowEnabled(); - if (ImGui::Checkbox("Enable TimeFlow", &isTimeFlowEnabled)) { - weatherManager->EnableTimeFlow(isTimeFlowEnabled); - } - - float dayTimeHours = weatherManager->GetDayTimeHours(); - if (ImGui::SliderFloat("DayTimeHours", &dayTimeHours, 0.0f, 24.0f)) { - weatherManager->SetDayTimeHours(dayTimeHours); - } - - float dayTimeRel = weatherManager->GetDayTimeRel(); - ImGui::Text("DayTimeRel: %f", dayTimeRel); - - float dayTimeSec = *reinterpret_cast(weatherManager + 3212); - if (ImGui::InputFloat("DayTimeSec", &dayTimeSec)) { - weatherManager->SetDayTimeSec(dayTimeSec); - } - } - - if (ImGui::CollapsingHeader("Season")) { - if (ImGui::Button("Close Season")) { - streamingTrafficModule->CloseSeason(true); - } - - bool isSeasonOpened = streamingTrafficModule->GetSeasonOpened(); - ImGui::Text("Is Season Opened: %s\n", isSeasonOpened ? "true" : "false"); - - ImGui::Text("PreviousSeasonID: %i\n", streamingTrafficModule->GetPreviousSeasonID()); - - int currentSeasonID = streamingTrafficModule->GetCurrentSeasonID(); - ImGui::Text("CurrentSeasonID: %i\n", currentSeasonID); - - static const std::map seasonMap = {{"No season", -1}, {"1930", 1}, {"1932", 2}, {"1933", 3}, {"1935", 4}, {"1938", 5}, {"Freeride", 100}}; - - auto foundSeasonID = std::find_if(seasonMap.begin(), seasonMap.end(), [currentSeasonID](const auto &pair) { - return pair.second == currentSeasonID; - }); - - const char *selectedSeasonName = (foundSeasonID != seasonMap.end()) ? foundSeasonID->first : nullptr; - - if (ImGui::BeginCombo("##seasonId", selectedSeasonName)) { - for (auto it = seasonMap.begin(); it != seasonMap.end(); ++it) { - const bool isSelected = (currentSeasonID == it->second); - - if (ImGui::Selectable(it->first, isSelected)) { - streamingTrafficModule->CloseSeason(true); - streamingTrafficModule->OpenSeason(it->second, true); - } - - if (isSelected) { - ImGui::SetItemDefaultFocus(); - } - } - - ImGui::EndCombo(); - } - } - - if (ImGui::CollapsingHeader("Traffic")) { - int m_iMaxHumanElements = streamingTrafficModule->GetMaxHumanElements(); - if (ImGui::InputInt("MaxHumanElements", &m_iMaxHumanElements)) { - streamingTrafficModule->SetMaxHumanElements(m_iMaxHumanElements); - } - } - - ImGui::End(); - } - - void WorldDebug::SpawnCar(std::string modelName, bool putPlayerIn, bool replacePrevious) { - auto info = Core::gApplication->GetEntityFactory()->RequestVehicle(modelName); - - if (replacePrevious && !_spawnedVehicles.empty()) { - auto previousVehicle = _spawnedVehicles.back(); - gApplication->GetEntityFactory()->ReturnEntity(previousVehicle); - _spawnedVehicles.pop_back(); - } - - _spawnedVehicles.push_back(info); - - const auto OnCarRequestFinish = [putPlayerIn](Game::Streaming::EntityTrackingInfo *info, bool success) { - if (success) { - auto car = reinterpret_cast(info->GetEntity()); - if (!car) { - return; - } - car->GameInit(); - car->Activate(); - car->Unlock(); - - auto localPlayer = Game::Helpers::Controls::GetLocalPlayer(); - - SDK::ue::sys::math::C_Vector newPos = localPlayer->GetPos(); - SDK::ue::sys::math::C_Quat newRot = localPlayer->GetRot(); - SDK::ue::sys::math::C_Matrix transform = {}; - transform.Identity(); - transform.SetRot(newRot); - transform.SetPos(newPos); - car->GetVehicle()->SetVehicleMatrix(transform, SDK::ue::sys::core::E_TransformChangeType::DEFAULT); - car->GetVehicle()->SetSPZText("DEBUG", true); - - if (putPlayerIn) { - auto characterController = reinterpret_cast(localPlayer->GetCharacterController()); - Game::Helpers::Human::PutIntoCar(characterController, car, 0, true); - } - } - }; - - const auto OnCarReturned = [](Game::Streaming::EntityTrackingInfo *info, bool wasCreated) { - if (!info) { - return; - } - auto car = reinterpret_cast(info->GetEntity()); - if (wasCreated && car) { - car->Deactivate(); - car->GameDone(); - car->Release(); - } - }; - - info->SetRequestFinishCallback(OnCarRequestFinish); - info->SetReturnCallback(OnCarReturned); - } -}; // namespace MafiaMP::Core::UI diff --git a/code/client/src/core/ui/world_debug.h b/code/client/src/core/ui/world_debug.h deleted file mode 100644 index cb362ad7..00000000 --- a/code/client/src/core/ui/world_debug.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include "utils/safe_win32.h" - -#include -#include - -#include "game/streaming/entity_tracking_info.h" - -namespace MafiaMP::Core::UI { - class WorldDebug final { - public: - WorldDebug(); - - void Update(); - - bool IsVisible() const { - return _visible; - } - - void SetVisible(bool visible) { - _visible = visible; - } - - void SpawnCar(std::string modelName = "berkley_810", bool putPlayerIn = false, bool replacePrevious = false); - - private: - bool _visible = false; - - std::vector _spawnedVehicles; - }; -} // namespace MafiaMP::Core::UI