From b17ce3e9a97f6a4f3db036c8faed5015f4c593ba Mon Sep 17 00:00:00 2001 From: EricPlayZ Date: Sat, 11 May 2024 01:45:05 +0300 Subject: [PATCH] - Added "Teleport to Coords" with X, Y, Z inputs (Teleport) - Added "Saved Locations" section in Teleport menu, with the ability of saving, deleting and teleporting to said locations; these locations are saved in the config file and will contain a name and a set of coordinates for each location --- EGameTools/EGameTools.vcxproj | 2 + EGameTools/EGameTools.vcxproj.filters | 6 + EGameTools/source/changelog.h | 4 +- EGameTools/source/config/config.cpp | 4 +- .../source/game/Engine/engine_hooks.cpp | 10 +- EGameTools/source/game/Vector3.cpp | 3 + EGameTools/source/game/Vector3.h | 5 +- EGameTools/source/menu/debug.h | 2 +- EGameTools/source/menu/menu.cpp | 2 +- EGameTools/source/menu/misc.h | 2 +- EGameTools/source/menu/player.cpp | 2 +- EGameTools/source/menu/teleport.cpp | 261 ++++++++++++++++++ EGameTools/source/menu/teleport.h | 22 ++ EGameTools/source/menu/weapon.cpp | 4 +- EGameTools/source/menu/world.h | 2 +- 15 files changed, 316 insertions(+), 15 deletions(-) create mode 100644 EGameTools/source/menu/teleport.cpp create mode 100644 EGameTools/source/menu/teleport.h diff --git a/EGameTools/EGameTools.vcxproj b/EGameTools/EGameTools.vcxproj index 25e38e7..b52e0ee 100644 --- a/EGameTools/EGameTools.vcxproj +++ b/EGameTools/EGameTools.vcxproj @@ -99,6 +99,7 @@ + @@ -184,6 +185,7 @@ + diff --git a/EGameTools/EGameTools.vcxproj.filters b/EGameTools/EGameTools.vcxproj.filters index 8834c63..454d1a9 100644 --- a/EGameTools/EGameTools.vcxproj.filters +++ b/EGameTools/EGameTools.vcxproj.filters @@ -209,6 +209,9 @@ game\GamePH + + menu + @@ -447,6 +450,9 @@ game\GamePH + + menu + diff --git a/EGameTools/source/changelog.h b/EGameTools/source/changelog.h index 07ba123..cc992bc 100644 --- a/EGameTools/source/changelog.h +++ b/EGameTools/source/changelog.h @@ -57,7 +57,7 @@ Thank you everyone for the support <3)" }, - Added "Old World Money" slider (Player) - Added "Unlimited Immunity" (Player) - Added "Unlimited Stamina" (Player) -- Added "Unlimited Items" (Player) - Stops the game from lowering the amount of items such as consumables / throwables when using them, alongside other inventory items such as ammo, lockpicks and other items; WARNING: This will not stop the item from getting removed from your inventory if you drop the entire amount +- Added "Unlimited Items" (Player) - Stops the game from lowering the amount of items such as consumables / throwables when using them, alongside other inventory items such as ammo, lockpicks and other items; WARNING: This will not stop the item from getting removed from your inventory if you drop the entire amount; currently, if the amount of item is 1, it will still drop from your inventory unfortunately - Added "One-Hit Kill" (Player) - Added "Invisible to Enemies" (Player) - Added "Allow Grapple Hook in Safezone" (Player) @@ -70,6 +70,8 @@ Thank you everyone for the support <3)" }, - Added "Instant Reload" (Weapon) - Added "Lens Distortion" slider (Camera) - Added "Disable Head Correction" (Camera) - disables centering of the player's hands to the center of the camera +- Added "Teleport to Coords" with X, Y, Z inputs (Teleport) +- Added "Saved Locations" section in Teleport menu, with the ability of saving, deleting and teleporting to said locations; these locations are saved in the config file and will contain a name and a set of coordinates for each location - Added "Increase Data PAKs Limit" (Misc; requires game restart to apply) - you can now add more than 8 data PAKs, e.g. data8.pak, data9.pak, data10.pak, etc, up to 200 PAKs in total - Added "Disable Data PAKs CRC Check" (Misc; requires game restart to apply) - stops the game from scanning data PAKs, which allows you to use data PAK mods in multiplayer as well - Added "Disable Savegame CRC Check" (Misc; requires game restart to apply) - stops the game from falsely saying your savegame is corrupt whenever you modify it diff --git a/EGameTools/source/config/config.cpp b/EGameTools/source/config/config.cpp index 8e18b07..991d2fe 100644 --- a/EGameTools/source/config/config.cpp +++ b/EGameTools/source/config/config.cpp @@ -3,6 +3,7 @@ #include "..\menu\menu.h" #include "..\menu\misc.h" #include "..\menu\player.h" +#include "..\menu\teleport.h" #include "..\menu\weapon.h" #include "..\menu\world.h" #include "config.h" @@ -11,7 +12,8 @@ namespace Config { enum ValueType { OPTION, Float, - String + String, + TPLocations }; struct VKey { diff --git a/EGameTools/source/game/Engine/engine_hooks.cpp b/EGameTools/source/game/Engine/engine_hooks.cpp index 5215091..2139e8b 100644 --- a/EGameTools/source/game/Engine/engine_hooks.cpp +++ b/EGameTools/source/game/Engine/engine_hooks.cpp @@ -171,8 +171,8 @@ namespace Engine { std::string gamePath = userModFilesFullPath; Utils::Values::str_replace(gamePath, "\\ph\\source\\data\\EGameTools\\UserModFiles", ""); - std::unique_ptr pathPtr = std::make_unique(); - pathPtr->gamePath = gamePath.c_str(); + fs::mount_path pathPtr = fs::mount_path(); + pathPtr.gamePath = gamePath.c_str(); try { const auto rdi = std::filesystem::recursive_directory_iterator(userModFilesFullPath); @@ -186,11 +186,11 @@ namespace Engine { std::string pakPath = fullPakPath; pakPath.erase(0, gamePath.size() + 1); - pathPtr->pakPath = pakPath.c_str(); - pathPtr->fullPakPath = fullPakPath.c_str(); + pathPtr.pakPath = pakPath.c_str(); + pathPtr.fullPakPath = fullPakPath.c_str(); spdlog::warn("Loading user PAK mod file \"{}\"", pakPath.c_str()); - if (!fs::mount(pathPtr.get(), 1, nullptr)) + if (!fs::mount(&pathPtr, 1, nullptr)) spdlog::error("fs::mount returned 0! Something went wrong with loading user PAK mod file \"{}\"!\nPlease make sure the path to the file is no longer than 260 characters, and make sure the file is valid!", pakPath.c_str()); } } catch (const std::exception& e) { diff --git a/EGameTools/source/game/Vector3.cpp b/EGameTools/source/game/Vector3.cpp index c18ed54..b105b9b 100644 --- a/EGameTools/source/game/Vector3.cpp +++ b/EGameTools/source/game/Vector3.cpp @@ -39,6 +39,9 @@ Vector3 Vector3::cross(const Vector3& v) const { X * v.Y - Y * v.X }; } +Vector3 Vector3::round() { + return { std::roundf(X), std::roundf(Y), std::roundf(Z) }; +} bool Vector3::isDefault() const { return Utils::Values::are_samef(X, 0.0f) && Utils::Values::are_samef(Y, 0.0f) && Utils::Values::are_samef(Z, 0.0f); diff --git a/EGameTools/source/game/Vector3.h b/EGameTools/source/game/Vector3.h index 97ff2d0..eaebf02 100644 --- a/EGameTools/source/game/Vector3.h +++ b/EGameTools/source/game/Vector3.h @@ -1,6 +1,8 @@ #pragma once struct Vector3 { - float X, Y, Z; + float X = 0.0f; + float Y = 0.0f; + float Z = 0.0f; bool operator==(const Vector3& v) const; Vector3& operator+=(const Vector3& v); @@ -12,6 +14,7 @@ struct Vector3 { Vector3 normalize(); Vector3 cross(const Vector3& v) const; + Vector3 round(); bool isDefault() const; }; \ No newline at end of file diff --git a/EGameTools/source/menu/debug.h b/EGameTools/source/menu/debug.h index 899e795..be4f383 100644 --- a/EGameTools/source/menu/debug.h +++ b/EGameTools/source/menu/debug.h @@ -5,7 +5,7 @@ namespace Menu { namespace Debug { class Tab : MenuTab { public: - Tab() : MenuTab("Debug", 5) {} + Tab() : MenuTab("Debug", 6) {} void Update() override; void Render() override; diff --git a/EGameTools/source/menu/menu.cpp b/EGameTools/source/menu/menu.cpp index 99e4ac7..fe0f763 100644 --- a/EGameTools/source/menu/menu.cpp +++ b/EGameTools/source/menu/menu.cpp @@ -10,7 +10,7 @@ namespace Menu { static ImVec2 EGTLogoSize = defEGTLogoSize; static constexpr ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoScrollbar; - static constexpr ImVec2 defMinWndSize = ImVec2(500.0f, 725.0f); + static constexpr ImVec2 defMinWndSize = ImVec2(575.0f, 725.0f); static ImVec2 minWndSize = defMinWndSize; static constexpr ImVec2 defMaxWndSize = ImVec2(900.0f, 725.0f); static ImVec2 maxWndSize = defMaxWndSize; diff --git a/EGameTools/source/menu/misc.h b/EGameTools/source/menu/misc.h index 3f148a0..f565943 100644 --- a/EGameTools/source/menu/misc.h +++ b/EGameTools/source/menu/misc.h @@ -11,7 +11,7 @@ namespace Menu { class Tab : MenuTab { public: - Tab() : MenuTab("Misc", 3) {} + Tab() : MenuTab("Misc", 4) {} void Update() override; void Render() override; diff --git a/EGameTools/source/menu/player.cpp b/EGameTools/source/menu/player.cpp index f49118a..71a4575 100644 --- a/EGameTools/source/menu/player.cpp +++ b/EGameTools/source/menu/player.cpp @@ -6963,7 +6963,7 @@ namespace Menu { ImGui::CheckboxHotkey("Unlimited Immunity", &unlimitedImmunity, "Stops immunity from draining"); ImGui::SameLine(); ImGui::CheckboxHotkey("Unlimited Stamina", &unlimitedStamina, "Stops stamina from draining"); - ImGui::CheckboxHotkey("Unlimited Items", &unlimitedItems, "Stops the game from lowering the amount of items such as consumables / throwables when using them, alongside other inventory items such as ammo, lockpicks and other items;\nWARNING: This will not stop the item from getting removed from your inventory if you drop the entire amount"); + ImGui::CheckboxHotkey("Unlimited Items", &unlimitedItems, "Stops the game from lowering the amount of items such as consumables / throwables when using them, alongside other inventory items such as ammo, lockpicks and other items;\nWARNING: This will not stop the item from getting removed from your inventory if you drop the entire amount\nCurrently, if the amount of item is 1, it will still drop from your inventory unfortunately"); ImGui::SameLine(); ImGui::CheckboxHotkey("One-Hit Kill", &oneHitKill, "Makes the player one-hit kill EVERYTHING and EVERYONE RAWRRR"); ImGui::CheckboxHotkey("Invisible to Enemies", &invisibleToEnemies, "Makes the player invisible to the enemies"); diff --git a/EGameTools/source/menu/teleport.cpp b/EGameTools/source/menu/teleport.cpp new file mode 100644 index 0000000..7aabb2a --- /dev/null +++ b/EGameTools/source/menu/teleport.cpp @@ -0,0 +1,261 @@ +#include +#include "..\game\Engine\CBulletPhysicsCharacter.h" +#include "..\game\GamePH\FreeCamera.h" +#include "..\game\GamePH\LevelDI.h" +#include "camera.h" +#include "player.h" +#include "teleport.h" + +namespace Menu { + namespace Teleport { + std::vector savedTeleportLocations; + static std::vector savedTeleportLocationNames; + static int selectedTPLocation = -1; + static char newLocationName[25]{}; + + static Vector3 teleportPos{}; + + static bool isTeleportationDisabled() { + GamePH::LevelDI* iLevel = GamePH::LevelDI::Get(); + if (!iLevel || !iLevel->IsLoaded()) + return true; + if (!Camera::freeCam.GetValue() && !Engine::CBulletPhysicsCharacter::Get()) + return true; + else if (Camera::freeCam.GetValue() && !GamePH::FreeCamera::Get()) + return true; + + return false; + } + + static void SyncTPCoordsToPlayer() { + if (isTeleportationDisabled()) + return; + + if (Camera::freeCam.GetValue()) { + GamePH::FreeCamera* freeCam = GamePH::FreeCamera::Get(); + if (!freeCam) + return; + + Vector3 camPos{}; + freeCam->GetPosition(&camPos); + if (camPos.isDefault()) + return; + + teleportPos = camPos; + } else { + Engine::CBulletPhysicsCharacter* playerCharacter = Engine::CBulletPhysicsCharacter::Get(); + if (!playerCharacter) + return; + + teleportPos = playerCharacter->playerPos; + } + } + static void TeleportPlayerTo(const Vector3& pos) { + if (isTeleportationDisabled()) + return; + + Engine::CBulletPhysicsCharacter* playerCharacter = Engine::CBulletPhysicsCharacter::Get(); + + if (Player::freezePlayer.GetValue()) { + if (!playerCharacter) + return; + + playerCharacter->posBeforeFreeze = pos; + playerCharacter->MoveCharacter(pos); + } else if (Camera::freeCam.GetValue()) { + GamePH::FreeCamera* freeCam = GamePH::FreeCamera::Get(); + if (!freeCam) + return; + + Vector3 camPos{}; + freeCam->GetPosition(&camPos); + if (camPos.isDefault()) + return; + + // need to implement camera teleportation here :( + } else { + if (!playerCharacter) + return; + + playerCharacter->MoveCharacter(pos); + } + } + static void UpdateTeleportPos() { + if (isTeleportationDisabled()) { + if (!teleportPos.isDefault()) + teleportPos = Vector3(); + return; + } + if (!teleportPos.isDefault()) + return; + + if (Camera::freeCam.GetValue()) { + GamePH::FreeCamera* freeCam = GamePH::FreeCamera::Get(); + if (!freeCam) + return; + + Vector3 camPos{}; + freeCam->GetPosition(&camPos); + if (camPos.isDefault()) + return; + + teleportPos = camPos; + } else { + Engine::CBulletPhysicsCharacter* playerCharacter = Engine::CBulletPhysicsCharacter::Get(); + if (!playerCharacter) + return; + + teleportPos = playerCharacter->playerPos; + } + } + + static void SaveTeleportLocation(const char* locationName) { + if (isTeleportationDisabled()) { + ImGui::OpenPopup("Couldn't add location"); + return; + } + + auto savedLocIt = std::find_if(savedTeleportLocations.begin(), savedTeleportLocations.end(), [&locationName](const auto& loc) { + return loc.name == locationName; + }); + if (savedLocIt != savedTeleportLocations.end()) { + ImGui::OpenPopup("The location you have entered already exists, if you want to change it then please remove it and add it again."); + return; + } + + Vector3 playerPos{}; + + if (Camera::freeCam.GetValue()) { + GamePH::FreeCamera* freeCam = GamePH::FreeCamera::Get(); + if (!freeCam) { + ImGui::OpenPopup("Couldn't add location"); + return; + } + + Vector3 camPos{}; + freeCam->GetPosition(&camPos); + if (camPos.isDefault()) { + ImGui::OpenPopup("Couldn't add location"); + return; + } + + playerPos = camPos; + } else { + Engine::CBulletPhysicsCharacter* playerCharacter = Engine::CBulletPhysicsCharacter::Get(); + if (!playerCharacter) { + ImGui::OpenPopup("Couldn't add location"); + return; + } + + playerPos = playerCharacter->playerPos; + } + playerPos = playerPos.round(); + + if (savedLocIt != savedTeleportLocations.end() && savedLocIt->pos == playerPos) { + ImGui::OpenPopup("The location you have entered already exists. Either the name of the location, or the position of the location is already inside the list. If you want to change it then please remove it and add it again."); + return; + } + + TeleportLocation tpLocation = TeleportLocation(locationName, playerPos); + + savedTeleportLocations.push_back(tpLocation); + savedTeleportLocationNames.push_back(locationName); + } + static void HandleDialogs() { + if (ImGui::BeginPopupModal("Give the location a name", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { + if (ImGui::InputTextWithHint("##TPLocationNameInputText", "Location name", newLocationName, IM_ARRAYSIZE(newLocationName), ImGuiInputTextFlags_EnterReturnsTrue) || ImGui::Button("OK", ImVec2(120.0f, 0.0f))) { + SaveTeleportLocation(newLocationName); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + if (ImGui::BeginPopupModal("Location already exists", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { + ImGui::Text("The location you have entered already exists, if you want to change it then please remove it and add it again."); + if (ImGui::Button("OK", ImVec2(120.0f, 0.0f))) + ImGui::CloseCurrentPopup(); + ImGui::EndPopup(); + } + if (ImGui::BeginPopupModal("Couldn't add location", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { + ImGui::Text("Something went wrong trying to add a location. Either the player class or camera class are not found, or you're in a place in the game where the character or camera isn't properly loaded. If this happens, even though you know it should work fine, please contact @EricPlayZ on NexusMods, GitHub or Discord."); + if (ImGui::Button("OK", ImVec2(120.0f, 0.0f))) + ImGui::CloseCurrentPopup(); + ImGui::EndPopup(); + } + } + + Tab Tab::instance{}; + void Tab::Update() { + UpdateTeleportPos(); + } + void Tab::Render() { + ImGui::SeparatorText("Saved Locations##Teleport"); + ImGui::BeginDisabled(isTeleportationDisabled()); { + ImGui::PushItemWidth(-FLT_MIN); + ImGui::ListBox("##SavedTPLocationsListBox", &selectedTPLocation, savedTeleportLocationNames.data(), static_cast(savedTeleportLocationNames.size()), 5); + ImGui::PopItemWidth(); + + ImGui::BeginDisabled(selectedTPLocation < 0 || selectedTPLocation >= savedTeleportLocations.size()); { + if (ImGui::Button("Teleport to Selected Location")) + TeleportPlayerTo(savedTeleportLocations[selectedTPLocation].pos); + ImGui::SameLine(); + if (ImGui::Button("Remove Selected Location")) { + savedTeleportLocations.erase(savedTeleportLocations.begin() + selectedTPLocation); + savedTeleportLocationNames.erase(savedTeleportLocationNames.begin() + selectedTPLocation); + selectedTPLocation = -1; + } + ImGui::EndDisabled(); + } + ImGui::SameLine(); + if (ImGui::Button("Save Current Location")) + ImGui::OpenPopup("Give the location a name"); + + ImGui::EndDisabled(); + } + + ImGui::SeparatorText("Custom##Teleport"); + ImGui::BeginDisabled(isTeleportationDisabled()); { + static std::string playerPos = "Player Position = X: 0.00, Y: 0.00, Z: 0.00"; + Engine::CBulletPhysicsCharacter* playerCharacter = Engine::CBulletPhysicsCharacter::Get(); + if (!playerCharacter) + playerPos = "Player Position = X: 0.00, Y: 0.00, Z: 0.00"; + else { + playerPos = "Player Position = X: " + std::format("{:.2f}", playerCharacter->playerPos.data.X) + ", Y: " + std::format("{:.2f}", playerCharacter->playerPos.data.Y) + ", Z: " + std::format("{:.2f}", playerCharacter->playerPos.data.Z); + } + + static std::string cameraPos = "Free Camera Position = X: 0.00, Y: 0.00, Z: 0.00"; + GamePH::FreeCamera* freeCam = GamePH::FreeCamera::Get(); + if (!Camera::freeCam.GetValue() || !freeCam) + cameraPos = "Free Camera Position = X: 0.00, Y: 0.00, Z: 0.00"; + else { + Vector3 camPos{}; + freeCam->GetPosition(&camPos); + if (camPos.isDefault()) + cameraPos = "Free Camera Position = X: 0.00, Y: 0.00, Z: 0.00"; + else + cameraPos = "Free Camera Position = X: " + std::format("{:.2f}", camPos.X) + ", Y: " + std::format("{:.2f}", camPos.Y) + ", Z: " + std::format("{:.2f}", camPos.Z); + } + + ImGui::Text(playerPos.data()); + ImGui::Text(cameraPos.data()); + + ImGui::PushItemWidth(200.0f); + ImGui::InputFloat("X", &teleportPos.X, 1.0f, 10.0f, "%.3f"); + ImGui::SameLine(); + ImGui::InputFloat("Y", &teleportPos.Y, 1.0f, 10.0f, "%.3f"); + ImGui::SameLine(); + ImGui::InputFloat("Z", &teleportPos.Z, 1.0f, 10.0f, "%.3f"); + ImGui::PopItemWidth(); + + if (ImGui::Button("Teleport to Coords")) + TeleportPlayerTo(teleportPos); + ImGui::SameLine(); + if (ImGui::Button("Get Player Coords")) + SyncTPCoordsToPlayer(); + + ImGui::EndDisabled(); + } + + HandleDialogs(); + } + } +} \ No newline at end of file diff --git a/EGameTools/source/menu/teleport.h b/EGameTools/source/menu/teleport.h new file mode 100644 index 0000000..d00c936 --- /dev/null +++ b/EGameTools/source/menu/teleport.h @@ -0,0 +1,22 @@ +#pragma once +#include "menu.h" + +namespace Menu { + namespace Teleport { + struct TeleportLocation { + std::string name; + Vector3 pos; + }; + + extern std::vector savedTeleportLocations; + + class Tab : MenuTab { + public: + Tab() : MenuTab("Teleport", 3) {} + void Update() override; + void Render() override; + + static Tab instance; + }; + } +} \ No newline at end of file diff --git a/EGameTools/source/menu/weapon.cpp b/EGameTools/source/menu/weapon.cpp index f578496..97c3f97 100644 --- a/EGameTools/source/menu/weapon.cpp +++ b/EGameTools/source/menu/weapon.cpp @@ -97,7 +97,7 @@ namespace Menu { UpdatePlayerVars(); } void Tab::Render() { - ImGui::SeparatorText("Current Weapon"); + ImGui::SeparatorText("Current Weapon##Weapon"); ImGui::BeginDisabled(isWeaponInteractionDisabled() || currentWeaponDurability <= 0.0f); { if (ImGui::SliderFloat("Weapon Durability", "Currently only works while your weapon is physically equipped in your hand", ¤tWeaponDurability, 0.1f, 999.0f, "%.2f", ImGuiSliderFlags_AlwaysClamp)) UpdateWeaponDurability(false); @@ -106,7 +106,7 @@ namespace Menu { ImGui::EndDisabled(); } - ImGui::SeparatorText("Misc"); + ImGui::SeparatorText("Misc##Weapon"); ImGui::CheckboxHotkey("Unlimited Durability", &unlimitedDurability, "Enables unlimited durability for all weapons"); ImGui::SameLine(); ImGui::CheckboxHotkey("Unlimited Ammo", &unlimitedAmmo, "Enables unlimited ammo for all firearms and bows"); diff --git a/EGameTools/source/menu/world.h b/EGameTools/source/menu/world.h index 6acb8db..fcba43d 100644 --- a/EGameTools/source/menu/world.h +++ b/EGameTools/source/menu/world.h @@ -15,7 +15,7 @@ namespace Menu { class Tab : MenuTab { public: - Tab() : MenuTab("World", 4) {} + Tab() : MenuTab("World", 5) {} void Update() override; void Render() override;