mirror of
https://github.com/EricPlayZ/EGameTools.git
synced 2025-07-18 17:37:53 +08:00
- Added One Handed Mode
- Fixed Freeze Time at night making Aiden complain about his immunity lmao - Added Slow Motion, with speed and transition time modifiers
This commit is contained in:
@ -16,6 +16,7 @@
|
||||
<ClCompile Include="source\dllmain.cpp" />
|
||||
<ClCompile Include="source\game_classes.cpp" />
|
||||
<ClCompile Include="source\hook.cpp" />
|
||||
<ClCompile Include="source\ImGuiEx\Animation.cpp" />
|
||||
<ClCompile Include="source\ImGuiEx\ImGuiEx.cpp" />
|
||||
<ClCompile Include="source\ImGuiFileDialog\ImGuiFileDialog.cpp" />
|
||||
<ClCompile Include="source\ImGuiHotkeys\Hotkey.cpp" />
|
||||
@ -46,6 +47,7 @@
|
||||
<ClInclude Include="source\core.h" />
|
||||
<ClInclude Include="source\game_classes.h" />
|
||||
<ClInclude Include="source\hook.h" />
|
||||
<ClInclude Include="source\ImGuiEx\Animation.h" />
|
||||
<ClInclude Include="source\ImGuiEx\ImGuiEx.h" />
|
||||
<ClInclude Include="source\ImGuiFileDialog\dirent\dirent.h" />
|
||||
<ClInclude Include="source\ImGuiFileDialog\ImGuiFileDialog.h" />
|
||||
|
@ -68,6 +68,9 @@
|
||||
<ClCompile Include="source\menu\misc.cpp">
|
||||
<Filter>menu</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="source\ImGuiEx\Animation.cpp">
|
||||
<Filter>ImGuiEx</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="source\memory.h" />
|
||||
@ -167,6 +170,9 @@
|
||||
<ClInclude Include="source\menu\misc.h">
|
||||
<Filter>menu</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="source\ImGuiEx\Animation.h">
|
||||
<Filter>ImGuiEx</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="MinHook">
|
||||
|
37
DL2GameOverhaulScript/source/ImGuiEx/Animation.cpp
Normal file
37
DL2GameOverhaulScript/source/ImGuiEx/Animation.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <cmath>
|
||||
#include <imgui_internal.h>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace ImGui {
|
||||
std::unordered_map<std::string_view, float> AnimValueStack{};
|
||||
|
||||
const float AnimEaseInSine(const float blendPoint) { return 1 - std::cos((blendPoint * static_cast<float>(M_PI)) / 2); }
|
||||
const float AnimEaseOutSine(const float blendPoint) { return std::sin((blendPoint * static_cast<float>(M_PI)) / 2.0f); }
|
||||
|
||||
static const float SetAnimTime(const std::string_view& valueName, const float animSpeed, const bool resetBlendPoint = false, const float (*easingFunction)(float) = nullptr) {
|
||||
const ImGuiContext& g = *GImGui;
|
||||
|
||||
float blendPoint = 0.0f;
|
||||
if (!resetBlendPoint)
|
||||
blendPoint = AnimValueStack[valueName];
|
||||
|
||||
if (blendPoint == 1.0f)
|
||||
return blendPoint;
|
||||
|
||||
blendPoint += g.IO.DeltaTime / animSpeed;
|
||||
blendPoint = ImMin(blendPoint, 1.0f);
|
||||
|
||||
AnimValueStack[valueName] = blendPoint;
|
||||
|
||||
if (easingFunction)
|
||||
blendPoint = easingFunction(blendPoint);
|
||||
|
||||
return blendPoint;
|
||||
}
|
||||
const float AnimateLerp(const std::string_view& valueName, const float a, const float b, const float animSpeed, const bool resetBlendPoint, const float (*easingFunction)(float)) {
|
||||
const float blendPoint = SetAnimTime(valueName, animSpeed, resetBlendPoint, easingFunction);
|
||||
return ImLerp<float>(a, b, blendPoint);
|
||||
}
|
||||
}
|
13
DL2GameOverhaulScript/source/ImGuiEx/Animation.h
Normal file
13
DL2GameOverhaulScript/source/ImGuiEx/Animation.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include <imgui_internal.h>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace ImGui {
|
||||
extern std::unordered_map<std::string_view, float> AnimValueStack;
|
||||
|
||||
const float AnimEaseInSine(const float blendPoint);
|
||||
const float AnimEaseOutSine(const float blendPoint);
|
||||
|
||||
extern const float AnimateLerp(const std::string_view& valueName, const float a, const float b, const float animSpeed, const bool resetBlendPoint = false, const float (*easingFunction)(float) = nullptr);
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
#include <Hotkey.h>
|
||||
#include <imgui_internal.h>
|
||||
#include "..\core.h"
|
||||
|
||||
@ -80,6 +81,11 @@ namespace ImGui {
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (v->GetValue() ? ImGuiItemStatusFlags_Checked : 0));
|
||||
return pressed;
|
||||
}
|
||||
bool CheckboxHotkey(const char* label, KeyBindOption* v) {
|
||||
const bool checkbox = ImGui::Checkbox(label, v);
|
||||
ImGui::Hotkey(std::string(label + std::string("##ToggleKey")), v);
|
||||
return checkbox;
|
||||
}
|
||||
static const float CalculateIndentation(const float& window_width, const float& text_width, const float& min_indentation) {
|
||||
const float indentation = (window_width - text_width) * 0.5f;
|
||||
return indentation > min_indentation ? indentation : min_indentation;
|
||||
|
@ -1,9 +1,11 @@
|
||||
#pragma once
|
||||
#include "..\core.h"
|
||||
#include "Animation.h"
|
||||
|
||||
namespace ImGui {
|
||||
extern void StyleScaleAllSizes(ImGuiStyle* style, float scale_factor);
|
||||
extern bool Checkbox(const char* label, Option* v);
|
||||
extern bool CheckboxHotkey(const char* label, KeyBindOption* v);
|
||||
extern void TextCentered(const char* text);
|
||||
extern void TextCenteredColored(const char* text, const ImU32& col);
|
||||
extern bool ButtonCentered(const char* label, const ImVec2& size = ImVec2(0.0f, 0.0f));
|
||||
|
@ -5,21 +5,40 @@
|
||||
bool ImGui::isAnyHotkeyBtnPressed = false;
|
||||
Utils::Timer ImGui::timeSinceHotkeyBtnPressed{ 250 };
|
||||
|
||||
void ImGui::Hotkey(std::string_view label, KeyBindOption& key, float samelineOffset, const ImVec2& size) {
|
||||
const auto id = ImGui::GetID(label.data());
|
||||
void ImGui::Hotkey(const std::string_view& label, KeyBindOption* key) {
|
||||
ImGuiContext& g = *GImGui;
|
||||
bool wasDisabled = (g.CurrentItemFlags & ImGuiItemFlags_Disabled) != 0;
|
||||
if (wasDisabled)
|
||||
ImGui::EndDisabled();
|
||||
|
||||
const ImGuiID id = ImGui::GetID(label.data());
|
||||
ImGui::PushID(label.data());
|
||||
|
||||
if (!label.contains("##"))
|
||||
ImGui::Text("%s", label.data());
|
||||
ImGui::SameLine(samelineOffset);
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
|
||||
if (!label.contains("##") && !window->SkipItems) {
|
||||
const ImGuiStyle& style = (*GImGui).Style;
|
||||
|
||||
const ImVec2 label_size = CalcTextSize(label.data(), nullptr, true);
|
||||
const ImVec2 pos = window->DC.CursorPos;
|
||||
const ImRect total_bb(pos, pos + ImVec2((label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), label_size.y + style.FramePadding.y * 2.0f));
|
||||
ItemSize(total_bb, style.FramePadding.y);
|
||||
|
||||
if (ItemAdd(total_bb, window->GetID(label.data()))) {
|
||||
const ImVec2 label_pos = ImVec2(pos.x + style.ItemInnerSpacing.x, pos.y + style.FramePadding.y);
|
||||
if (label_size.x > 0.0f)
|
||||
RenderText(label_pos, label.data());
|
||||
}
|
||||
}
|
||||
ImGui::SameLine(0.0f);
|
||||
|
||||
if (ImGui::GetActiveID() == id) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetColorU32(ImGuiCol_ButtonActive));
|
||||
ImGui::Button("...", size);
|
||||
ImGui::Button("...", ImVec2(0.0f, 0.0f));
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
ImGui::GetCurrentContext()->ActiveIdAllowOverlap = true;
|
||||
if ((!ImGui::IsItemHovered() && ImGui::GetIO().MouseClicked[0]) || key.SetToPressedKey()) {
|
||||
if ((!ImGui::IsItemHovered() && ImGui::GetIO().MouseClicked[0]) || key->SetToPressedKey()) {
|
||||
timeSinceHotkeyBtnPressed = Utils::Timer(250);
|
||||
isAnyHotkeyBtnPressed = false;
|
||||
ImGui::ClearActiveID();
|
||||
@ -27,10 +46,13 @@ void ImGui::Hotkey(std::string_view label, KeyBindOption& key, float samelineOff
|
||||
else
|
||||
ImGui::SetActiveID(id, ImGui::GetCurrentWindow());
|
||||
}
|
||||
else if (ImGui::Button(key.ToString(), size)) {
|
||||
else if (ImGui::Button(key->ToString(), ImVec2(0.0f, 0.0f))) {
|
||||
isAnyHotkeyBtnPressed = true;
|
||||
ImGui::SetActiveID(id, ImGui::GetCurrentWindow());
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
|
||||
if (wasDisabled)
|
||||
ImGui::BeginDisabled(wasDisabled);
|
||||
}
|
@ -7,5 +7,5 @@ namespace ImGui {
|
||||
extern bool isAnyHotkeyBtnPressed;
|
||||
extern Utils::Timer timeSinceHotkeyBtnPressed;
|
||||
|
||||
void Hotkey(std::string_view label, KeyBindOption& key, float samelineOffset = 0.0f, const ImVec2& size = { 0.0f, 0.0f });
|
||||
void Hotkey(const std::string_view& label, KeyBindOption* key);
|
||||
}
|
@ -4028,16 +4028,22 @@ namespace Config {
|
||||
{ "Menu:Keybinds", "MenuToggleKey", std::string("VK_F5"), &Menu::menuToggle, String},
|
||||
{ "Menu:Keybinds", "GodModeToggleKey", std::string("VK_F6"), &Menu::Player::godMode, String},
|
||||
{ "Menu:Keybinds", "FreezePlayerToggleKey", std::string("VK_F7"), &Menu::Player::freezePlayer, String},
|
||||
{ "Menu:Keybinds", "DisableOutOfBoundsTimerToggleKey", std::string("VK_NONE"), &Menu::Player::disableOutOfBoundsTimer, String},
|
||||
{ "Menu:Keybinds", "NightrunnerModeToggleKey", std::string("VK_F9"), &Menu::Player::nightrunnerMode, String},
|
||||
{ "Menu:Keybinds", "OneHandedModeToggleKey", std::string("VK_NONE"), &Menu::Player::oneHandedMode, String},
|
||||
{ "Menu:Keybinds", "FreeCamToggleKey", std::string("VK_F3"), &Menu::Camera::freeCam, String},
|
||||
{ "Menu:Keybinds", "TeleportPlayerToCameraToggleKey", std::string("VK_F4"), &Menu::Camera::teleportPlayerToCamera, String},
|
||||
{ "Menu:Keybinds", "ThirdPersonToggleKey", std::string("VK_F1"), &Menu::Camera::thirdPersonCamera, String},
|
||||
{ "Menu:Keybinds", "UseTPPModelToggleKey", std::string("VK_F2"), &Menu::Camera::tpUseTPPModel, String},
|
||||
{ "Menu:Keybinds", "DisablePhotoModeLimits", std::string("VK_NONE"), &Menu::Camera::disablePhotoModeLimits, String},
|
||||
{ "Menu:Keybinds", "DisableSafezoneFOVReduction", std::string("VK_NONE"), &Menu::Camera::disableSafezoneFOVReduction, String},
|
||||
{ "Menu:Keybinds", "DisableHUDToggleKey", std::string("VK_F8"), &Menu::Misc::disableHUD, String},
|
||||
{ "Menu:Keybinds", "FreezeTimeToggleKey", std::string("VK_NONE"), &Menu::World::freezeTime, String},
|
||||
{ "Menu:Keybinds", "SlowMotionToggleKey", std::string("VK_X"), &Menu::World::slowMotion, String},
|
||||
{ "Player:Misc", "GodMode", false, &Menu::Player::godMode, OPTION },
|
||||
{ "Player:Misc", "DisableOutOfBoundsTimer", true, &Menu::Player::disableOutOfBoundsTimer, OPTION },
|
||||
{ "Player:Misc", "NightrunnerMode", false, &Menu::Player::nightrunnerMode, OPTION },
|
||||
{ "Player:Misc", "OneHandedMode", false, &Menu::Player::oneHandedMode, OPTION },
|
||||
{ "Player:PlayerVariables", "Enabled", false, &Menu::Player::playerVariables, OPTION },
|
||||
{ "Player:PlayerVariables", "LastSaveSCRPath", std::string(), &Menu::Player::saveSCRPath, String },
|
||||
{ "Player:PlayerVariables", "LastLoadSCRFilePath", std::string(), &Menu::Player::loadSCRFilePath, String },
|
||||
@ -4049,7 +4055,9 @@ namespace Config {
|
||||
{ "Camera:ThirdPerson", "HeightAbovePlayer", 1.35f, &Menu::Camera::tpHeightAbovePlayer, Float },
|
||||
{ "Camera:ThirdPerson", "HorizontalDistanceFromPlayer", 0.0f, &Menu::Camera::tpHorizontalDistanceFromPlayer, Float },
|
||||
{ "Camera:Misc", "DisablePhotoModeLimits", true, &Menu::Camera::disablePhotoModeLimits, OPTION },
|
||||
{ "Camera:Misc", "DisableSafezoneFOVReduction", true, &Menu::Camera::disableSafezoneFOVReduction, OPTION }
|
||||
{ "Camera:Misc", "DisableSafezoneFOVReduction", true, &Menu::Camera::disableSafezoneFOVReduction, OPTION },
|
||||
{ "World:Time", "SlowMotionSpeed", 0.4f, &Menu::World::slowMotionSpeed, Float },
|
||||
{ "World:Time", "SlowMotionTransitionTime", 1.0f, &Menu::World::slowMotionTransitionTime, Float }
|
||||
});
|
||||
std::vector<ConfigEntry> configVariables(configVariablesDefault.begin(), configVariablesDefault.end());
|
||||
static const char* configFileName = "EGameTools.ini";
|
||||
|
@ -140,22 +140,15 @@ namespace Core {
|
||||
PrintInfo("Initializing MinHook");
|
||||
MH_Initialize();
|
||||
|
||||
PrintInfo("Hooking ReadVideoSettings");
|
||||
const auto readVidSettingsHook = std::find_if(Hook::HookBase::GetInstances()->begin(), Hook::HookBase::GetInstances()->end(), [](const auto& item) { return item->name == "ReadVideoSettings"; });
|
||||
if (readVidSettingsHook != Hook::HookBase::GetInstances()->end()) {
|
||||
(*readVidSettingsHook)->HookLoop();
|
||||
Hook::HookBase::GetInstances()->erase(readVidSettingsHook);
|
||||
PrintSuccess("Hooked ReadVideoSettings!");
|
||||
}
|
||||
|
||||
PrintInfo("Hooking DX11/DX12 renderer");
|
||||
LoopHookRenderer();
|
||||
PrintSuccess("Hooked DX11/DX12 renderer!");
|
||||
std::thread([]() {
|
||||
LoopHookRenderer();
|
||||
PrintSuccess("Hooked DX11/DX12 renderer!");
|
||||
}).detach();
|
||||
|
||||
for (auto& hook : *Hook::HookBase::GetInstances()) {
|
||||
PrintInfo("Hooking %s", hook->name.data());
|
||||
hook->HookLoop();
|
||||
PrintSuccess("Hooked %s!", hook->name.data());
|
||||
std::thread([hook]() { hook->HookLoop(); }).detach();
|
||||
}
|
||||
|
||||
const HANDLE proc = GetCurrentProcess();
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "menu\camera.h"
|
||||
#include "menu\misc.h"
|
||||
#include "menu\player.h"
|
||||
#include "menu\world.h"
|
||||
#include "print.h"
|
||||
#include "sigscan\offsets.h"
|
||||
#include "utils.h"
|
||||
@ -29,6 +30,7 @@ namespace GamePH {
|
||||
static void detourMoveCameraFromForwardUpPos(LPVOID pCBaseCamera, float* a3, float* a4, Vector3* pos);
|
||||
static bool detourIsNotOutOfBounds(LPVOID pInstance, DWORD64 a2);
|
||||
static void detourShowUIManager(LPVOID pLevelDI, bool enabled);
|
||||
static DWORD64 detourPlaySoundEvent(LPVOID pCoAudioEventControl, DWORD64 name, DWORD64 a3);
|
||||
static DWORD64 detourFsOpen(DWORD64 file, DWORD a2, DWORD a3);
|
||||
|
||||
#pragma region CreatePlayerHealthModule
|
||||
@ -240,6 +242,20 @@ namespace GamePH {
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
#pragma region PlaySoundEvent
|
||||
static Hook::MHook<LPVOID, DWORD64(*)(LPVOID, DWORD64, DWORD64)> PlaySoundEventHook{ "PlaySoundEvent", &Offsets::Get_PlaySoundEvent, &detourPlaySoundEvent };
|
||||
|
||||
static DWORD64 detourPlaySoundEvent(LPVOID pCoAudioEventControl, DWORD64 name, DWORD64 a3) {
|
||||
const char* soundName = reinterpret_cast<const char*>(name);
|
||||
if (Menu::World::freezeTime.GetValue() &&
|
||||
(!strcmp(soundName, "set_gp_infection_start") || !strcmp(soundName, "set_gp_infection_immune"))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return PlaySoundEventHook.pOriginal(pCoAudioEventControl, name, a3);
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
#pragma region fs::open
|
||||
static LPVOID GetFsOpen() {
|
||||
return Utils::GetProcAddr("filesystem_x64_rwdi.dll", "?open@fs@@YAPEAUSFsFile@@V?$string_const@D@ttl@@W4TYPE@EFSMode@@W45FFSOpenFlags@@@Z");
|
||||
@ -254,19 +270,19 @@ namespace GamePH {
|
||||
if (fileName.empty())
|
||||
return FsOpenHook.pOriginal(file, a2, a3);
|
||||
|
||||
for (const auto& entry : std::filesystem::directory_iterator("EGameTools\\FilesToLoad")) {
|
||||
if (fileName.contains(".rpack"))
|
||||
return FsOpenHook.pOriginal(file, a2, a3);
|
||||
if (fileName.contains("player_anims_pc"))
|
||||
return FsOpenHook.pOriginal(file, a2, a3);
|
||||
if (fileName.contains("sfx"))
|
||||
return FsOpenHook.pOriginal(file, a2, a3);
|
||||
if (entry.path().filename().string().contains(fileName)) {
|
||||
std::string finalPath = std::string("EGameTools\\FilesToLoad\\") + fileName;
|
||||
const char* filePath2 = finalPath.c_str();
|
||||
for (const auto& entry : std::filesystem::recursive_directory_iterator("EGameTools\\FilesToLoad")) {
|
||||
const std::filesystem::path pathToFile = entry.path();
|
||||
if (!std::filesystem::is_regular_file(pathToFile))
|
||||
continue;
|
||||
|
||||
return FsOpenHook.pOriginal(firstByte != 0x0 ? (reinterpret_cast<DWORD64>(filePath2) | (firstByte << 56)) : reinterpret_cast<DWORD64>(filePath2), a2, a3); // restores first byte of addr if first byte was not 0
|
||||
}
|
||||
const std::filesystem::path pathToFilename = pathToFile.filename();
|
||||
if (!pathToFilename.string().contains(fileName))
|
||||
continue;
|
||||
|
||||
std::string finalPath = pathToFile.string();
|
||||
const char* filePath2 = finalPath.c_str();
|
||||
|
||||
return FsOpenHook.pOriginal(firstByte != 0x0 ? (reinterpret_cast<DWORD64>(filePath2) | (firstByte << 56)) : reinterpret_cast<DWORD64>(filePath2), a2, a3); // restores first byte of addr if first byte was not 0
|
||||
}
|
||||
return FsOpenHook.pOriginal(file, a2, a3);
|
||||
}
|
||||
@ -694,6 +710,28 @@ namespace GamePH {
|
||||
return;
|
||||
}
|
||||
}
|
||||
float LevelDI::TimerGetSpeedUp() {
|
||||
__try {
|
||||
float(*pTimerGetSpeedUp)(LPVOID iLevel) = (decltype(pTimerGetSpeedUp))Utils::GetProcAddr("engine_x64_rwdi.dll", "?TimerGetSpeedUp@ILevel@@QEBAMXZ");
|
||||
if (!pTimerGetSpeedUp)
|
||||
return -1.0f;
|
||||
|
||||
return pTimerGetSpeedUp(this);
|
||||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
return -1.0f;
|
||||
}
|
||||
}
|
||||
void LevelDI::TimerSetSpeedUp(float timeScale) {
|
||||
__try {
|
||||
void(*pTimerSetSpeedUp)(LPVOID iLevel, float timeScale) = (decltype(pTimerSetSpeedUp))Utils::GetProcAddr("engine_x64_rwdi.dll", "?TimerSetSpeedUp@ILevel@@QEAAXM@Z");
|
||||
if (!pTimerSetSpeedUp)
|
||||
return;
|
||||
|
||||
pTimerSetSpeedUp(this, timeScale);
|
||||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
TimeWeather::CSystem* LevelDI::GetTimeWeatherSystem() {
|
||||
__try {
|
||||
TimeWeather::CSystem*(*pGetTimeWeatherSystem)(LevelDI* iLevel) = (decltype(pGetTimeWeatherSystem))Utils::GetProcAddr("engine_x64_rwdi.dll", "?GetTimeWeatherSystem@ILevel@@QEBAPEAVCSystem@TimeWeather@@XZ");
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "core.h"
|
||||
#include "hook.h"
|
||||
#include "utils.h"
|
||||
|
||||
@ -145,6 +146,9 @@ namespace GamePH {
|
||||
static void ChangePlayerVar(const std::string& playerVar, const T value) {
|
||||
static_assert(std::is_same<T, bool>::value || std::is_same<T, float>::value || std::is_same<T, std::string>::value, "Invalid type: value must be bool, float or string");
|
||||
|
||||
if (!gotPlayerVars)
|
||||
return;
|
||||
|
||||
auto it = std::find_if(PlayerVariables::playerVars.begin(), PlayerVariables::playerVars.end(), [&playerVar](const auto& pair) {
|
||||
return pair.first == playerVar;
|
||||
});
|
||||
@ -176,6 +180,24 @@ namespace GamePH {
|
||||
*(varValue + 1) = value;
|
||||
}
|
||||
}
|
||||
template <typename T>
|
||||
static void ManagePlayerVarOption(const std::string& playerVar, const T valueIfTrue, const T valueIfFalse, Option* option, const bool& usePreviousVal = true) {
|
||||
if (!gotPlayerVars)
|
||||
return;
|
||||
|
||||
static T previousPlayerVarValue = GamePH::PlayerVariables::GetPlayerVar<T>(playerVar);
|
||||
|
||||
if (option->GetValue()) {
|
||||
if (!option->GetPrevValue())
|
||||
previousPlayerVarValue = GamePH::PlayerVariables::GetPlayerVar<T>(playerVar);
|
||||
|
||||
GamePH::PlayerVariables::ChangePlayerVar(playerVar, valueIfTrue);
|
||||
option->SetPrevValue(true);
|
||||
} else if (option->GetPrevValue()) {
|
||||
option->SetPrevValue(false);
|
||||
GamePH::PlayerVariables::ChangePlayerVar(playerVar, usePreviousVal ? previousPlayerVarValue : valueIfFalse);
|
||||
}
|
||||
}
|
||||
|
||||
static PlayerVariables* Get();
|
||||
};
|
||||
@ -268,6 +290,8 @@ namespace GamePH {
|
||||
void SetViewCamera(LPVOID viewCam);
|
||||
float GetTimePlayed();
|
||||
void ShowUIManager(bool enabled);
|
||||
float TimerGetSpeedUp();
|
||||
void TimerSetSpeedUp(float timeScale);
|
||||
TimeWeather::CSystem* GetTimeWeatherSystem();
|
||||
|
||||
static LevelDI* Get();
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <functional>
|
||||
#include <set>
|
||||
#include "MinHook\include\MinHook.h"
|
||||
#include "print.h"
|
||||
|
||||
namespace Hook {
|
||||
struct DETOUR_INFO {
|
||||
@ -68,6 +69,8 @@ namespace Hook {
|
||||
|
||||
Sleep(250);
|
||||
}
|
||||
|
||||
PrintSuccess("Hooked %s!", name.data());
|
||||
}
|
||||
|
||||
OrigType pOriginal = nullptr;
|
||||
@ -95,6 +98,8 @@ namespace Hook {
|
||||
|
||||
Sleep(250);
|
||||
}
|
||||
|
||||
PrintSuccess("Hooked %s!", name.data());
|
||||
}
|
||||
|
||||
OrigType pOriginal = nullptr;
|
||||
|
@ -23,8 +23,8 @@ namespace Menu {
|
||||
float tpHeightAbovePlayer = 1.35f;
|
||||
float tpHorizontalDistanceFromPlayer = 0.0f;
|
||||
|
||||
Option disablePhotoModeLimits{};
|
||||
Option disableSafezoneFOVReduction{};
|
||||
KeyBindOption disablePhotoModeLimits{ VK_NONE };
|
||||
KeyBindOption disableSafezoneFOVReduction{ VK_NONE };
|
||||
|
||||
static const int baseFOV = 57;
|
||||
static const float baseSafezoneFOVReduction = -10.0f;
|
||||
@ -104,13 +104,7 @@ namespace Menu {
|
||||
if (!GamePH::PlayerVariables::gotPlayerVars)
|
||||
return;
|
||||
|
||||
if (disableSafezoneFOVReduction.GetValue()) {
|
||||
GamePH::PlayerVariables::ChangePlayerVar("CameraDefaultFOVReduction", 0.0f);
|
||||
disableSafezoneFOVReduction.SetPrevValue(true);
|
||||
} else if (disableSafezoneFOVReduction.GetPrevValue()) {
|
||||
disableSafezoneFOVReduction.SetPrevValue(false);
|
||||
GamePH::PlayerVariables::ChangePlayerVar("CameraDefaultFOVReduction", baseSafezoneFOVReduction);
|
||||
}
|
||||
GamePH::PlayerVariables::ManagePlayerVarOption("CameraDefaultFOVReduction", 0.0f, baseSafezoneFOVReduction, &disableSafezoneFOVReduction);
|
||||
}
|
||||
static void UpdateDisabledOptions() {
|
||||
GamePH::LevelDI* iLevel = GamePH::LevelDI::Get();
|
||||
@ -130,28 +124,24 @@ namespace Menu {
|
||||
void Tab::Render() {
|
||||
ImGui::SeparatorText("Free Camera");
|
||||
ImGui::BeginDisabled(freeCam.GetChangesAreDisabled() || photoMode.GetValue()); {
|
||||
ImGui::Checkbox("Enabled##FreeCam", &freeCam);
|
||||
ImGui::CheckboxHotkey("Enabled##FreeCam", &freeCam);
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
ImGui::Hotkey("##FreeCamToggleKey", freeCam);
|
||||
ImGui::SliderFloat("Speed##FreeCam", &freeCamSpeed, 0.1f, 200.0f, "%.3f", ImGuiSliderFlags_AlwaysClamp);
|
||||
ImGui::BeginDisabled(teleportPlayerToCamera.GetChangesAreDisabled()); {
|
||||
ImGui::Checkbox("Teleport Player to Camera", &teleportPlayerToCamera);
|
||||
ImGui::CheckboxHotkey("Teleport Player to Camera", &teleportPlayerToCamera);
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
ImGui::Hotkey("##TeleportPlayerToCamToggleKey", teleportPlayerToCamera);
|
||||
|
||||
ImGui::SeparatorText("Third Person Camera");
|
||||
ImGui::BeginDisabled(thirdPersonCamera.GetChangesAreDisabled()); {
|
||||
ImGui::Checkbox("Enabled##ThirdPerson", &thirdPersonCamera);
|
||||
ImGui::CheckboxHotkey("Enabled##ThirdPerson", &thirdPersonCamera);
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
ImGui::Hotkey("##ThirdPersonToggleKey", thirdPersonCamera);
|
||||
ImGui::BeginDisabled(tpUseTPPModel.GetChangesAreDisabled()); {
|
||||
ImGui::Checkbox("Use Third Person Player (TPP) Model", &tpUseTPPModel);
|
||||
ImGui::CheckboxHotkey("Use Third Person Player (TPP) Model", &tpUseTPPModel);
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
ImGui::Hotkey("##TPPModelToggleKey", tpUseTPPModel);
|
||||
ImGui::SliderFloat("Distance behind player", &tpDistanceBehindPlayer, 1.0f, 10.0f);
|
||||
ImGui::SliderFloat("Height above player", &tpHeightAbovePlayer, 1.0f, 3.0f);
|
||||
ImGui::SliderFloat("Horizontal distance from player", &tpHorizontalDistanceFromPlayer, -2.0f, 2.0f);
|
||||
@ -165,8 +155,8 @@ namespace Menu {
|
||||
FOV = static_cast<int>(pCVideoSettings->extraFOV) + baseFOV;
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
ImGui::Checkbox("Disable Photo Mode Limits", &disablePhotoModeLimits);
|
||||
ImGui::Checkbox("Disable Safezone FOV Reduction", &disableSafezoneFOVReduction);
|
||||
ImGui::CheckboxHotkey("Disable Photo Mode Limits", &disablePhotoModeLimits);
|
||||
ImGui::CheckboxHotkey("Disable Safezone FOV Reduction", &disableSafezoneFOVReduction);
|
||||
}
|
||||
}
|
||||
}
|
@ -18,8 +18,8 @@ namespace Menu {
|
||||
extern float tpHeightAbovePlayer;
|
||||
extern float tpHorizontalDistanceFromPlayer;
|
||||
|
||||
extern Option disablePhotoModeLimits;
|
||||
extern Option disableSafezoneFOVReduction;
|
||||
extern KeyBindOption disablePhotoModeLimits;
|
||||
extern KeyBindOption disableSafezoneFOVReduction;
|
||||
|
||||
class Tab : MenuTab {
|
||||
public:
|
||||
|
@ -135,7 +135,7 @@ namespace Menu {
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::Hotkey("Menu Toggle Key", menuToggle);
|
||||
ImGui::Hotkey("Menu Toggle Key", &menuToggle);
|
||||
ImGui::SliderFloat("Menu Transparency", &transparency, 0.0f, 100.0f, "%.1f%%", ImGuiSliderFlags_AlwaysClamp);
|
||||
if (ImGui::SliderFloat("Menu Scale", &scale, 1.0f, 2.5f, "%.1f%%", ImGuiSliderFlags_AlwaysClamp)) {
|
||||
ImGui::StyleScaleAllSizes(style, scale);
|
||||
|
@ -35,8 +35,7 @@ namespace Menu {
|
||||
void Tab::Render() {
|
||||
ImGui::SeparatorText("Misc##Misc");
|
||||
ImGui::BeginDisabled(disableHUD.GetChangesAreDisabled()); {
|
||||
ImGui::Checkbox("Disable HUD", &disableHUD);
|
||||
ImGui::Hotkey("##DisableHUDToggleKey", disableHUD);
|
||||
ImGui::CheckboxHotkey("Disable HUD", &disableHUD);
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
}
|
||||
|
@ -6003,9 +6003,10 @@ namespace Menu {
|
||||
float playerMaxHealth = 80.0f;
|
||||
KeyBindOption godMode{ VK_F6 };
|
||||
KeyBindOption freezePlayer{ VK_F7 };
|
||||
Option playerVariables{};
|
||||
Option disableOutOfBoundsTimer{};
|
||||
KeyBindOption disableOutOfBoundsTimer{ VK_NONE };
|
||||
KeyBindOption nightrunnerMode{ VK_F9 };
|
||||
KeyBindOption oneHandedMode{ VK_NONE };
|
||||
Option playerVariables{};
|
||||
|
||||
std::string saveSCRPath{};
|
||||
std::string loadSCRFilePath{};
|
||||
@ -6047,47 +6048,138 @@ namespace Menu {
|
||||
|
||||
Utils::str_replace(str, value, newValue);
|
||||
}
|
||||
static void SaveVariablesToSCR() {
|
||||
if (!std::filesystem::exists(saveSCRPath))
|
||||
return;
|
||||
|
||||
std::string tempPlayerVarsSCR = playerVarsSCR;
|
||||
static void PlayerPositionUpdate() {
|
||||
Engine::CBulletPhysicsCharacter* playerCharacter = Engine::CBulletPhysicsCharacter::Get();
|
||||
if (!playerCharacter)
|
||||
return;
|
||||
|
||||
std::istringstream iss(tempPlayerVarsSCR);
|
||||
std::string line{};
|
||||
while (std::getline(iss, line)) {
|
||||
if (freezePlayer.GetValue() || (Camera::freeCam.GetValue() && !Camera::teleportPlayerToCamera.GetValue())) {
|
||||
playerCharacter->FreezeCharacter();
|
||||
return;
|
||||
}
|
||||
|
||||
Engine::CBulletPhysicsCharacter::posBeforeFreeze = playerCharacter->playerPos;
|
||||
|
||||
if (!Camera::freeCam.GetValue() || !Camera::teleportPlayerToCamera.GetValue())
|
||||
return;
|
||||
|
||||
GamePH::FreeCamera* freeCam = GamePH::FreeCamera::Get();
|
||||
if (!freeCam)
|
||||
return;
|
||||
|
||||
Vector3 camPos{};
|
||||
freeCam->GetPosition(&camPos);
|
||||
if (camPos.isDefault())
|
||||
return;
|
||||
|
||||
playerCharacter->MoveCharacter(camPos);
|
||||
}
|
||||
static void PlayerVarsUpdate() {
|
||||
if (!playerVariables.GetValue())
|
||||
return;
|
||||
|
||||
auto bgn = GamePH::PlayerVariables::playerVars.begin();
|
||||
for (auto it = bgn; it != GamePH::PlayerVariables::playerVars.end(); ++it) {
|
||||
if (!it->second.first)
|
||||
continue;
|
||||
|
||||
try {
|
||||
auto& valDef = GamePH::PlayerVariables::playerVarsDefault.at(it - bgn);
|
||||
|
||||
if (it->second.second == "float") {
|
||||
float* varAddr = reinterpret_cast<float*>(it->second.first);
|
||||
if (!Utils::are_same(*varAddr, *(varAddr + 1)) && !Utils::are_same(*(varAddr + 1), std::any_cast<float>(valDef.second.first)))
|
||||
*varAddr = *(varAddr + 1);
|
||||
} else if (it->second.second == "bool") {
|
||||
bool* varAddr = reinterpret_cast<bool*>(it->second.first);
|
||||
if (*varAddr != *(varAddr + 1) && *(varAddr + 1) != std::any_cast<bool>(valDef.second.first))
|
||||
*varAddr = *(varAddr + 1);
|
||||
}
|
||||
} catch (std::out_of_range& e) {
|
||||
UNREFERENCED_PARAMETER(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
static void PlayerHealthUpdate() {
|
||||
GamePH::PlayerHealthModule* playerHealthModule = GamePH::PlayerHealthModule::Get();
|
||||
if (!playerHealthModule)
|
||||
return;
|
||||
|
||||
playerMaxHealth = playerHealthModule->maxHealth;
|
||||
|
||||
if (menuToggle.GetValue())
|
||||
return;
|
||||
GamePH::LevelDI* iLevel = GamePH::LevelDI::Get();
|
||||
if (!iLevel || !iLevel->IsLoaded())
|
||||
return;
|
||||
|
||||
playerHealth = playerHealthModule->health;
|
||||
}
|
||||
static void UpdatePlayerVars() {
|
||||
if (!GamePH::PlayerVariables::gotPlayerVars)
|
||||
return;
|
||||
|
||||
GamePH::PlayerVariables::ManagePlayerVarOption("NightRunnerItemForced", nightrunnerMode.GetValue(), !nightrunnerMode.GetValue(), &nightrunnerMode);
|
||||
GamePH::PlayerVariables::ManagePlayerVarOption("NightRunnerFurySmashEnabled", nightrunnerMode.GetValue(), !nightrunnerMode.GetValue(), &nightrunnerMode);
|
||||
GamePH::PlayerVariables::ManagePlayerVarOption("NightRunnerFuryGroundPoundEnabled", nightrunnerMode.GetValue(), !nightrunnerMode.GetValue(), &nightrunnerMode);
|
||||
|
||||
GamePH::PlayerVariables::ManagePlayerVarOption("LeftHandDisabled", oneHandedMode.GetValue(), !oneHandedMode.GetValue(), &oneHandedMode);
|
||||
}
|
||||
static void UpdateDisabledOptions() {
|
||||
freezePlayer.SetChangesAreDisabled(!Engine::CBulletPhysicsCharacter::Get());
|
||||
}
|
||||
|
||||
Tab Tab::instance{};
|
||||
void Tab::Update() {
|
||||
PlayerPositionUpdate();
|
||||
PlayerVarsUpdate();
|
||||
PlayerHealthUpdate();
|
||||
UpdateDisabledOptions();
|
||||
UpdatePlayerVars();
|
||||
}
|
||||
|
||||
static void SaveVariablesToSCR() {
|
||||
if (!std::filesystem::exists(saveSCRPath))
|
||||
return;
|
||||
|
||||
std::string tempPlayerVarsSCR = playerVarsSCR;
|
||||
|
||||
std::istringstream iss(tempPlayerVarsSCR);
|
||||
std::string line{};
|
||||
while (std::getline(iss, line)) {
|
||||
const std::string origLine = line;
|
||||
const std::string paramName = getParamName(line);
|
||||
if (paramName.empty())
|
||||
continue;
|
||||
const std::string paramName = getParamName(line);
|
||||
if (paramName.empty())
|
||||
continue;
|
||||
|
||||
auto it = std::find_if(GamePH::PlayerVariables::playerVars.begin(), GamePH::PlayerVariables::playerVars.end(), [¶mName](const auto& pair) {
|
||||
return pair.first == paramName;
|
||||
});
|
||||
if (it == GamePH::PlayerVariables::playerVars.end())
|
||||
continue;
|
||||
if (it == GamePH::PlayerVariables::playerVars.end())
|
||||
continue;
|
||||
|
||||
if (it->second.second == "float") {
|
||||
float value = *reinterpret_cast<float*>(it->second.first);
|
||||
replaceParamValue(line, std::to_string(value));
|
||||
|
||||
} else {
|
||||
bool value = *reinterpret_cast<bool*>(it->second.first);
|
||||
replaceParamValue(line, value ? "true" : "false");
|
||||
}
|
||||
if (it->second.second == "float") {
|
||||
float value = *reinterpret_cast<float*>(it->second.first);
|
||||
replaceParamValue(line, std::to_string(value));
|
||||
|
||||
} else {
|
||||
bool value = *reinterpret_cast<bool*>(it->second.first);
|
||||
replaceParamValue(line, value ? "true" : "false");
|
||||
}
|
||||
Utils::str_replace(tempPlayerVarsSCR, origLine, line);
|
||||
}
|
||||
}
|
||||
|
||||
std::ofstream outFile(std::string(saveSCRPath) + "\\player_variables.scr", std::ios::binary);
|
||||
std::ofstream outFile(std::string(saveSCRPath) + "\\player_variables.scr", std::ios::binary);
|
||||
if (!outFile.is_open()) {
|
||||
ImGui::OpenPopup("Failed saving player variables.");
|
||||
return;
|
||||
}
|
||||
outFile << tempPlayerVarsSCR;
|
||||
outFile.close();
|
||||
outFile << tempPlayerVarsSCR;
|
||||
outFile.close();
|
||||
|
||||
ImGui::OpenPopup("Saved player variables!");
|
||||
}
|
||||
}
|
||||
static void LoadPlayerVariablesSCR() {
|
||||
if (!std::filesystem::exists(loadSCRFilePath))
|
||||
return;
|
||||
@ -6169,150 +6261,12 @@ namespace Menu {
|
||||
else
|
||||
GamePH::PlayerVariables::ChangePlayerVar(varName, std::any_cast<bool>(itDef->second.first));
|
||||
}
|
||||
|
||||
static void PlayerPositionUpdate() {
|
||||
Engine::CBulletPhysicsCharacter* playerCharacter = Engine::CBulletPhysicsCharacter::Get();
|
||||
if (!playerCharacter)
|
||||
return;
|
||||
|
||||
if (freezePlayer.GetValue() || (Camera::freeCam.GetValue() && !Camera::teleportPlayerToCamera.GetValue())) {
|
||||
playerCharacter->FreezeCharacter();
|
||||
return;
|
||||
}
|
||||
|
||||
Engine::CBulletPhysicsCharacter::posBeforeFreeze = playerCharacter->playerPos;
|
||||
|
||||
if (!Camera::freeCam.GetValue() || !Camera::teleportPlayerToCamera.GetValue())
|
||||
return;
|
||||
|
||||
GamePH::FreeCamera* freeCam = GamePH::FreeCamera::Get();
|
||||
if (!freeCam)
|
||||
return;
|
||||
|
||||
Vector3 camPos{};
|
||||
freeCam->GetPosition(&camPos);
|
||||
if (camPos.isDefault())
|
||||
return;
|
||||
|
||||
playerCharacter->MoveCharacter(camPos);
|
||||
}
|
||||
static void PlayerVarsUpdate() {
|
||||
static void HandlePlayerVariablesList() {
|
||||
if (!playerVariables.GetValue())
|
||||
return;
|
||||
|
||||
auto bgn = GamePH::PlayerVariables::playerVars.begin();
|
||||
for (auto it = bgn; it != GamePH::PlayerVariables::playerVars.end(); ++it) {
|
||||
if (!it->second.first)
|
||||
continue;
|
||||
|
||||
try {
|
||||
auto& valDef = GamePH::PlayerVariables::playerVarsDefault.at(it - bgn);
|
||||
|
||||
if (it->second.second == "float") {
|
||||
float* varAddr = reinterpret_cast<float*>(it->second.first);
|
||||
if (!Utils::are_same(*varAddr, *(varAddr + 1)) && !Utils::are_same(*(varAddr + 1), std::any_cast<float>(valDef.second.first)))
|
||||
*varAddr = *(varAddr + 1);
|
||||
} else if (it->second.second == "bool") {
|
||||
bool* varAddr = reinterpret_cast<bool*>(it->second.first);
|
||||
if (*varAddr != *(varAddr + 1) && *(varAddr + 1) != std::any_cast<bool>(valDef.second.first))
|
||||
*varAddr = *(varAddr + 1);
|
||||
}
|
||||
} catch (std::out_of_range& e) {
|
||||
UNREFERENCED_PARAMETER(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
static void PlayerHealthUpdate() {
|
||||
GamePH::PlayerHealthModule* playerHealthModule = GamePH::PlayerHealthModule::Get();
|
||||
if (!playerHealthModule)
|
||||
return;
|
||||
|
||||
playerMaxHealth = playerHealthModule->maxHealth;
|
||||
|
||||
if (menuToggle.GetValue())
|
||||
return;
|
||||
GamePH::LevelDI* iLevel = GamePH::LevelDI::Get();
|
||||
if (!iLevel || !iLevel->IsLoaded())
|
||||
return;
|
||||
|
||||
playerHealth = playerHealthModule->health;
|
||||
}
|
||||
static void UpdatePlayerVars() {
|
||||
if (!GamePH::PlayerVariables::gotPlayerVars)
|
||||
return;
|
||||
|
||||
static bool previousNightRunnerItemForced{};
|
||||
static bool previousNightRunnerFurySmashEnabled{};
|
||||
static bool previousNightRunnerFuryGroundPoundEnabled{};
|
||||
|
||||
if (nightrunnerMode.GetValue()) {
|
||||
if (!nightrunnerMode.GetPrevValue()) {
|
||||
previousNightRunnerItemForced = GamePH::PlayerVariables::GetPlayerVar<bool>("NightRunnerItemForced");
|
||||
previousNightRunnerFurySmashEnabled = GamePH::PlayerVariables::GetPlayerVar<bool>("NightRunnerFurySmashEnabled");
|
||||
previousNightRunnerFuryGroundPoundEnabled = GamePH::PlayerVariables::GetPlayerVar<bool>("NightRunnerFuryGroundPoundEnabled");
|
||||
}
|
||||
|
||||
GamePH::PlayerVariables::ChangePlayerVar("NightRunnerItemForced", true);
|
||||
GamePH::PlayerVariables::ChangePlayerVar("NightRunnerFurySmashEnabled", true);
|
||||
GamePH::PlayerVariables::ChangePlayerVar("NightRunnerFuryGroundPoundEnabled", true);
|
||||
nightrunnerMode.SetPrevValue(true);
|
||||
} else if (nightrunnerMode.GetPrevValue()) {
|
||||
nightrunnerMode.SetPrevValue(false);
|
||||
GamePH::PlayerVariables::ChangePlayerVar("NightRunnerItemForced", previousNightRunnerItemForced);
|
||||
GamePH::PlayerVariables::ChangePlayerVar("NightRunnerFurySmashEnabled", previousNightRunnerFurySmashEnabled);
|
||||
GamePH::PlayerVariables::ChangePlayerVar("NightRunnerFuryGroundPoundEnabled", previousNightRunnerFuryGroundPoundEnabled);
|
||||
}
|
||||
}
|
||||
static void UpdateDisabledOptions() {
|
||||
freezePlayer.SetChangesAreDisabled(!Engine::CBulletPhysicsCharacter::Get());
|
||||
}
|
||||
|
||||
Tab Tab::instance{};
|
||||
void Tab::Update() {
|
||||
PlayerPositionUpdate();
|
||||
PlayerVarsUpdate();
|
||||
PlayerHealthUpdate();
|
||||
UpdateDisabledOptions();
|
||||
UpdatePlayerVars();
|
||||
}
|
||||
void Tab::Render() {
|
||||
ImGui::SeparatorText("Misc");
|
||||
GamePH::PlayerHealthModule* playerHealthModule = GamePH::PlayerHealthModule::Get();
|
||||
ImGui::BeginDisabled(!playerHealthModule); {
|
||||
if (ImGui::SliderFloat("Player Health", &playerHealth, 0.0f, playerMaxHealth, "%.2f") && playerHealthModule)
|
||||
playerHealthModule->health = playerHealth;
|
||||
else if (playerHealthModule)
|
||||
playerHealth = playerHealthModule->health;
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
ImGui::Checkbox("God Mode", &godMode);
|
||||
ImGui::Hotkey("##GodModeToggleKey", godMode);
|
||||
ImGui::SameLine();
|
||||
ImGui::BeginDisabled(freezePlayer.GetChangesAreDisabled()); {
|
||||
ImGui::Checkbox("Freeze Player", &freezePlayer);
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
ImGui::Hotkey("##FreezePlayerToggleKey", freezePlayer);
|
||||
|
||||
ImGui::Checkbox("Disable Out of Bounds Timer", &disableOutOfBoundsTimer);
|
||||
ImGui::Checkbox("Nightrunner Mode", &nightrunnerMode);
|
||||
ImGui::Hotkey("##NightrunnerModeToggleKey", nightrunnerMode);
|
||||
|
||||
ImGui::SeparatorText("Player Jump Parameters");
|
||||
if (ImGui::Button("Reload Jump Params")) {
|
||||
if (Utils::FileExistsInDir("jump_parameters.scr", "EGameTools\\FilesToLoad")) {
|
||||
GamePH::ReloadJumps();
|
||||
ImGui::OpenPopup("Reloaded player jump parameters!");
|
||||
} else
|
||||
ImGui::OpenPopup("Failed reloading player jump parameters.");
|
||||
}
|
||||
|
||||
ImGui::SeparatorText("Player Variables");
|
||||
ImGui::Checkbox("Enabled##PlayerVars", &playerVariables);
|
||||
if (!playerVariables.GetValue())
|
||||
return;
|
||||
|
||||
ImGui::BeginDisabled(!GamePH::PlayerVariables::gotPlayerVars); {
|
||||
ImGui::BeginDisabled(!GamePH::PlayerVariables::gotPlayerVars);
|
||||
{
|
||||
if (ImGui::CollapsingHeader("Player variables list", ImGuiTreeNodeFlags_None)) {
|
||||
ImGui::Indent();
|
||||
if (ImGui::Button("Save variables to file"))
|
||||
@ -6331,8 +6285,7 @@ namespace Menu {
|
||||
SaveVariablesAsDefault();
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::InputTextWithHint("##VarsSearch", "Search variables", playerVarsSearchFilter, 64);
|
||||
ImGui::InputTextWithHint("##VarsSearch", "Search variables", playerVarsSearchFilter, 64);
|
||||
|
||||
std::string restoreBtnName{};
|
||||
for (auto const& [key, val] : GamePH::PlayerVariables::playerVars) {
|
||||
@ -6348,7 +6301,6 @@ namespace Menu {
|
||||
|
||||
if (val.second == "float") {
|
||||
float* varAddr = reinterpret_cast<float*>(val.first);
|
||||
|
||||
float newValue = *varAddr;
|
||||
|
||||
if (ImGui::InputFloat(key.data(), &newValue)) {
|
||||
@ -6365,7 +6317,6 @@ namespace Menu {
|
||||
}
|
||||
} else if (val.second == "bool") {
|
||||
bool* varAddr = reinterpret_cast<bool*>(val.first);
|
||||
|
||||
bool newValue = *varAddr;
|
||||
|
||||
if (ImGui::Checkbox(key.data(), &newValue)) {
|
||||
@ -6386,7 +6337,8 @@ namespace Menu {
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
}
|
||||
void HandleDialogs() {
|
||||
if (ImGuiFileDialog::Instance()->Display("ChooseSCRPath", ImGuiWindowFlags_NoCollapse, ImVec2(600.0f, 400.0f))) {
|
||||
if (ImGuiFileDialog::Instance()->IsOk()) {
|
||||
const std::string filePath = ImGuiFileDialog::Instance()->GetCurrentPath();
|
||||
@ -6453,5 +6405,42 @@ namespace Menu {
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
void Tab::Render() {
|
||||
ImGui::SeparatorText("Misc");
|
||||
GamePH::PlayerHealthModule* playerHealthModule = GamePH::PlayerHealthModule::Get();
|
||||
ImGui::BeginDisabled(!playerHealthModule); {
|
||||
if (ImGui::SliderFloat("Player Health", &playerHealth, 0.0f, playerMaxHealth, "%.2f") && playerHealthModule)
|
||||
playerHealthModule->health = playerHealth;
|
||||
else if (playerHealthModule)
|
||||
playerHealth = playerHealthModule->health;
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
ImGui::CheckboxHotkey("God Mode", &godMode);
|
||||
ImGui::SameLine();
|
||||
ImGui::BeginDisabled(freezePlayer.GetChangesAreDisabled()); {
|
||||
ImGui::CheckboxHotkey("Freeze Player", &freezePlayer);
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
ImGui::CheckboxHotkey("Disable Out of Bounds Timer", &disableOutOfBoundsTimer);
|
||||
ImGui::CheckboxHotkey("Nightrunner Mode", &nightrunnerMode);
|
||||
ImGui::CheckboxHotkey("One-handed Mode", &oneHandedMode);
|
||||
|
||||
ImGui::SeparatorText("Player Jump Parameters");
|
||||
if (ImGui::Button("Reload Jump Params")) {
|
||||
if (Utils::FileExistsInDir("jump_parameters.scr", "EGameTools\\FilesToLoad")) {
|
||||
GamePH::ReloadJumps();
|
||||
ImGui::OpenPopup("Reloaded player jump parameters!");
|
||||
} else
|
||||
ImGui::OpenPopup("Failed reloading player jump parameters.");
|
||||
}
|
||||
|
||||
ImGui::SeparatorText("Player Variables");
|
||||
ImGui::Checkbox("Enabled##PlayerVars", &playerVariables);
|
||||
HandlePlayerVariablesList();
|
||||
|
||||
HandleDialogs();
|
||||
}
|
||||
}
|
||||
}
|
@ -9,9 +9,10 @@ namespace Menu {
|
||||
extern float playerMaxHealth;
|
||||
extern KeyBindOption godMode;
|
||||
extern KeyBindOption freezePlayer;
|
||||
extern Option playerVariables;
|
||||
extern Option disableOutOfBoundsTimer;
|
||||
extern KeyBindOption disableOutOfBoundsTimer;
|
||||
extern KeyBindOption nightrunnerMode;
|
||||
extern KeyBindOption oneHandedMode;
|
||||
extern Option playerVariables;
|
||||
|
||||
extern std::string saveSCRPath;
|
||||
extern std::string loadSCRFilePath;
|
||||
|
@ -8,7 +8,13 @@ namespace Menu {
|
||||
namespace World {
|
||||
float time = 0.0f;
|
||||
static float timeBeforeFreeze = 0.0f;
|
||||
float gameSpeed = 1.0f;
|
||||
static float gameSpeedBeforeSlowMo = gameSpeed;
|
||||
KeyBindOption freezeTime{ VK_NONE };
|
||||
KeyBindOption slowMotion{ 'X' };
|
||||
float slowMotionSpeed = 0.4f;
|
||||
static float slowMotionSpeedLerp = gameSpeed;
|
||||
float slowMotionTransitionTime = 1.0f;
|
||||
|
||||
EWeather::TYPE weather = EWeather::TYPE::Default;
|
||||
static const char* const weatherItems[7] = {
|
||||
@ -21,6 +27,13 @@ namespace Menu {
|
||||
"Stormy"
|
||||
};
|
||||
|
||||
static void UpdateDisabledOptions() {
|
||||
GamePH::DayNightCycle* dayNightCycle = GamePH::DayNightCycle::Get();
|
||||
GamePH::LevelDI* iLevel = GamePH::LevelDI::Get();
|
||||
freezeTime.SetChangesAreDisabled(!iLevel || !iLevel->IsLoaded() || !dayNightCycle);
|
||||
slowMotion.SetChangesAreDisabled(!iLevel || !iLevel->IsLoaded() || !dayNightCycle);
|
||||
}
|
||||
|
||||
Tab Tab::instance{};
|
||||
void Tab::Update() {
|
||||
GamePH::DayNightCycle* dayNightCycle = GamePH::DayNightCycle::Get();
|
||||
@ -33,52 +46,87 @@ namespace Menu {
|
||||
if (freezeTime.HasChangedTo(true)) {
|
||||
timeBeforeFreeze = time;
|
||||
freezeTime.SetPrevValue(true);
|
||||
} else if (freezeTime.HasChangedTo(false)) {
|
||||
dayNightCycle->SetDaytime(timeBeforeFreeze);
|
||||
freezeTime.SetPrevValue(false);
|
||||
}
|
||||
|
||||
if (slowMotion.HasChangedTo(false)) {
|
||||
static bool slowMoHasChanged = true;
|
||||
slowMotionSpeedLerp = ImGui::AnimateLerp("slowMotionSpeedLerp", slowMotionSpeed, gameSpeedBeforeSlowMo, slowMotionTransitionTime, slowMoHasChanged, &ImGui::AnimEaseOutSine);
|
||||
iLevel->TimerSetSpeedUp(slowMotionSpeedLerp);
|
||||
slowMoHasChanged = false;
|
||||
|
||||
if (Utils::are_same(gameSpeed, gameSpeedBeforeSlowMo)) {
|
||||
slowMoHasChanged = true;
|
||||
slowMotion.SetPrevValue(false);
|
||||
}
|
||||
} else if (slowMotion.GetValue()) {
|
||||
if (slowMotion.HasChanged()) {
|
||||
gameSpeedBeforeSlowMo = gameSpeed;
|
||||
slowMotionSpeedLerp = gameSpeed;
|
||||
}
|
||||
slowMotionSpeedLerp = ImGui::AnimateLerp("slowMotionSpeedLerp", gameSpeedBeforeSlowMo, slowMotionSpeed, slowMotionTransitionTime, slowMotion.HasChanged(), &ImGui::AnimEaseOutSine);
|
||||
iLevel->TimerSetSpeedUp(slowMotionSpeedLerp);
|
||||
if (slowMotion.HasChanged())
|
||||
slowMotion.SetPrevValue(slowMotion.GetValue());
|
||||
}
|
||||
|
||||
if (!menuToggle.GetValue()) {
|
||||
if (!freezeTime.GetValue()) {
|
||||
if (freezeTime.HasChangedTo(false)) {
|
||||
dayNightCycle->SetDaytime(time);
|
||||
freezeTime.SetPrevValue(false);
|
||||
}
|
||||
time = dayNightCycle->time1 * 24;
|
||||
} else if (!Utils::are_same(time, timeBeforeFreeze))
|
||||
time = dayNightCycle->time1 * 24;
|
||||
if (freezeTime.GetValue() && !Utils::are_same(time, timeBeforeFreeze, 0.009f))
|
||||
dayNightCycle->SetDaytime(timeBeforeFreeze);
|
||||
|
||||
if (!slowMotion.GetValue() && !slowMotion.HasChanged())
|
||||
iLevel->TimerSetSpeedUp(gameSpeed);
|
||||
if (!Utils::are_same(iLevel->TimerGetSpeedUp(), 1.0f))
|
||||
gameSpeed = iLevel->TimerGetSpeedUp();
|
||||
}
|
||||
}
|
||||
void Tab::Render() {
|
||||
GamePH::DayNightCycle* dayNightCycle = GamePH::DayNightCycle::Get();
|
||||
GamePH::LevelDI* iLevel = GamePH::LevelDI::Get();
|
||||
ImGui::SeparatorText("Misc##World");
|
||||
ImGui::BeginDisabled(!iLevel || !iLevel->IsLoaded() || !dayNightCycle || dayNightCycle->time1 == 0.0f); {
|
||||
static bool sliderBeingPressed = false;
|
||||
if (ImGui::SliderFloat("Time", &time, 0.01f, 24.0f, "%.2f", ImGuiSliderFlags_AlwaysClamp) && dayNightCycle)
|
||||
sliderBeingPressed = true;
|
||||
else if (dayNightCycle) {
|
||||
if (sliderBeingPressed) {
|
||||
sliderBeingPressed = false;
|
||||
ImGui::SeparatorText("Time##World");
|
||||
ImGui::BeginDisabled(!iLevel || !iLevel->IsLoaded() || !dayNightCycle); {
|
||||
static bool timeSliderBeingPressed = false;
|
||||
if (ImGui::SliderFloat("Time", &time, 0.01f, 24.0f, "%.2f", ImGuiSliderFlags_AlwaysClamp))
|
||||
timeSliderBeingPressed = true;
|
||||
else if (iLevel && iLevel->IsLoaded() && dayNightCycle) {
|
||||
if (timeSliderBeingPressed) {
|
||||
timeSliderBeingPressed = false;
|
||||
timeBeforeFreeze = time;
|
||||
dayNightCycle->SetDaytime(time);
|
||||
}
|
||||
if (!freezeTime.GetValue()) {
|
||||
if (freezeTime.HasChangedTo(false)) {
|
||||
dayNightCycle->SetDaytime(timeBeforeFreeze);
|
||||
freezeTime.SetPrevValue(false);
|
||||
}
|
||||
time = dayNightCycle->time1 * 24;
|
||||
} else if (!Utils::are_same(time, timeBeforeFreeze))
|
||||
time = dayNightCycle->time1 * 24;
|
||||
if (freezeTime.GetValue() && !Utils::are_same(time, timeBeforeFreeze, 0.009f))
|
||||
dayNightCycle->SetDaytime(timeBeforeFreeze);
|
||||
}
|
||||
|
||||
ImGui::Checkbox("Freeze Time", &freezeTime);
|
||||
ImGui::Hotkey("##FreezeTimeToggleKey", freezeTime);
|
||||
ImGui::BeginDisabled(slowMotion.GetValue()); {
|
||||
if (ImGui::SliderFloat("Game Speed", &gameSpeed, 0.0f, 2.0f, "%.2f"))
|
||||
iLevel->TimerSetSpeedUp(gameSpeed);
|
||||
else if (iLevel && iLevel->IsLoaded()) {
|
||||
if (!slowMotion.GetValue() && !slowMotion.HasChanged())
|
||||
iLevel->TimerSetSpeedUp(gameSpeed);
|
||||
if (!Utils::are_same(iLevel->TimerGetSpeedUp(), 1.0f))
|
||||
gameSpeed = iLevel->TimerGetSpeedUp();
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
ImGui::CheckboxHotkey("Freeze Time", &freezeTime);
|
||||
ImGui::SameLine();
|
||||
ImGui::CheckboxHotkey("Slow Motion", &slowMotion);
|
||||
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
ImGui::SliderFloat("Slow Motion Speed", &slowMotionSpeed, 0.01f, 0.99f, "%.2f", ImGuiSliderFlags_AlwaysClamp);
|
||||
ImGui::SliderFloat("Slow Motion Transition Time", &slowMotionTransitionTime, 0.00f, 5.00f, "%.2f", ImGuiSliderFlags_AlwaysClamp);
|
||||
|
||||
GamePH::TimeWeather::CSystem* timeWeatherSystem = GamePH::TimeWeather::CSystem::Get();
|
||||
const bool weatherDisabledFlag = !iLevel || !iLevel->IsLoaded() || !timeWeatherSystem;
|
||||
|
||||
ImGui::SeparatorText("Weather");
|
||||
ImGui::SeparatorText("Weather##World");
|
||||
ImGui::BeginDisabled(weatherDisabledFlag); {
|
||||
if (ImGui::Combo("Weather", reinterpret_cast<int*>(&weather), weatherItems, IM_ARRAYSIZE(weatherItems)) && timeWeatherSystem)
|
||||
timeWeatherSystem->SetForcedWeather(static_cast<EWeather::TYPE>(weather - 1));
|
||||
|
@ -5,7 +5,11 @@
|
||||
namespace Menu {
|
||||
namespace World {
|
||||
extern float time;
|
||||
extern float gameSpeed;
|
||||
extern KeyBindOption freezeTime;
|
||||
extern KeyBindOption slowMotion;
|
||||
extern float slowMotionSpeed;
|
||||
extern float slowMotionTransitionTime;
|
||||
|
||||
extern EWeather::TYPE weather;
|
||||
|
||||
|
@ -62,6 +62,7 @@ struct Offsets {
|
||||
//AddOffset(CalculateOutOfBoundsTimer, "gamedll_ph_x64_rwdi.dll", "48 89 5C 24 ?? 48 89 74 24 ?? 57 48 81 EC ?? ?? ?? ?? 0F B6 99", PatternType::Address, LPVOID)
|
||||
AddOffset(IsNotOutOfBounds, "gamedll_ph_x64_rwdi.dll", "48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 56 41 57 48 83 EC ?? 4C 8B F9 48 85 D2", PatternType::Address, LPVOID)
|
||||
AddOffset(ReloadJumps, "gamedll_ph_x64_rwdi.dll", "48 83 EC ?? E8 ?? ?? ?? ?? 48 8D 15", PatternType::Address, LPVOID)
|
||||
AddOffset(PlaySoundEvent, "gamedll_ph_x64_rwdi.dll", "4C 8B DC 49 89 5B ?? 49 89 73 ?? 57 48 81 EC ?? ?? ?? ?? 4C 8B 4C 24 ?? 48 8B F9 4D 8B D0 66 C7 84 24 ?? ?? ?? ?? ?? ?? 49 8B C1 66 C7 84 24", PatternType::Address, LPVOID)
|
||||
//AddOffset(GetTimeWeatherSystem, "engine_x64_rwdi.dll", "E8 [?? ?? ?? ?? 33 D2 48 8B C8 E8 ?? ?? ?? ?? 49 8D 4F 38", PatternType::RelativePointer, LPVOID)
|
||||
//AddOffset(SetForcedWeather, "engine_x64_rwdi.dll", "89 51 68 C3 CC CC CC CC CC CC CC CC CC CC CC CC", PatternType::Address, LPVOID)
|
||||
//AddOffset(GetCurrentWeather, "engine_x64_rwdi.dll", "48 8B 41 78 48 85 C0 75 0F", PatternType::Address, LPVOID)
|
||||
|
@ -40,8 +40,12 @@ namespace Utils {
|
||||
return timePassed;
|
||||
}
|
||||
|
||||
bool are_same(float a, float b) {
|
||||
return abs(a - b) < 0.0001f;
|
||||
bool are_same(float a, float b, float precision) {
|
||||
return abs(a - b) < precision;
|
||||
}
|
||||
float round_dec(float value, int decimal_places) {
|
||||
const float multiplier = std::pow(10.0f, decimal_places);
|
||||
return std::roundf(value * multiplier) / multiplier;
|
||||
}
|
||||
|
||||
bool str_replace(std::string& str, const std::string& from, const std::string& to) {
|
||||
@ -75,15 +79,27 @@ namespace Utils {
|
||||
|
||||
return path;
|
||||
}
|
||||
std::filesystem::path GetCurrentProcDirectoryFS() {
|
||||
char buffer[MAX_PATH];
|
||||
GetModuleFileNameA(nullptr, buffer, sizeof(buffer));
|
||||
return std::filesystem::path(buffer).parent_path();
|
||||
}
|
||||
std::string GetCurrentProcDirectory() {
|
||||
char buffer[MAX_PATH];
|
||||
GetModuleFileNameA(nullptr, buffer, sizeof(buffer));
|
||||
return std::filesystem::path(buffer).parent_path().string();
|
||||
}
|
||||
bool FileExistsInDir(const char* fileName, const char* dir) {
|
||||
for (const auto& entry : std::filesystem::directory_iterator(dir)) {
|
||||
if (entry.path().filename().string() == fileName)
|
||||
return true;
|
||||
for (const auto& entry : std::filesystem::recursive_directory_iterator(dir)) {
|
||||
const std::filesystem::path pathToFile = entry.path();
|
||||
if (!std::filesystem::is_regular_file(pathToFile))
|
||||
continue;
|
||||
|
||||
const std::filesystem::path pathToFilename = pathToFile.filename();
|
||||
if (!pathToFilename.string().contains(fileName))
|
||||
continue;
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -25,7 +25,8 @@ namespace Utils {
|
||||
bool timePassed;
|
||||
};
|
||||
|
||||
extern bool are_same(float a, float b);
|
||||
extern bool are_same(float a, float b, float precision = 0.0001f);
|
||||
extern float round_dec(float value, int decimal_places = 2);
|
||||
|
||||
extern bool str_replace(std::string& str, const std::string& from, const std::string& to);
|
||||
template <typename T>
|
||||
@ -40,6 +41,7 @@ namespace Utils {
|
||||
|
||||
extern std::string_view GetDesktopDir();
|
||||
extern std::string_view GetDocumentsDir();
|
||||
extern std::filesystem::path GetCurrentProcDirectoryFS();
|
||||
extern std::string GetCurrentProcDirectory();
|
||||
extern bool FileExistsInDir(const char* fileName, const char* dir);
|
||||
extern WindowsVersion GetWindowsVersion();
|
||||
|
Reference in New Issue
Block a user