mirror of
https://github.com/EricPlayZ/EGameTools.git
synced 2025-07-18 09:27:51 +08:00
backup commit :D
This commit is contained in:
@ -222,7 +222,7 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<TargetExt>.asi</TargetExt>
|
||||
<TargetName>EGameTools</TargetName>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
<GenerateManifest>true</GenerateManifest>
|
||||
<LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64)</LibraryPath>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
|
||||
</PropertyGroup>
|
||||
|
@ -53,6 +53,8 @@ Thank you everyone for the support <3)" },
|
||||
{ "v1.1.4",
|
||||
R"(- Added compatibility with v1.16.1 hotfix update
|
||||
- Fixed God Mode staying enabled after toggling FreeCam off
|
||||
- Fixed player variables saving and loading using old version of player_variables.scr (which makes Max Health drop to negative infinite))" }
|
||||
- Fixed player variables saving and loading using old version of player_variables.scr (which makes Max Health drop to negative infinite)
|
||||
- Fixed long paths to mods inside UserModFiles causing a game crash or causing the mods to not load at all
|
||||
- Added the possibility of adding more than 8 paks (up to 200 paks!) in "ph\source" (e.g. data8.pak, data9.pak, data10.pak, etc.))" }
|
||||
};
|
||||
}
|
@ -220,25 +220,12 @@ namespace Core {
|
||||
|
||||
//AddVectoredExceptionHandler(0, &VectoredExceptionHandler);
|
||||
|
||||
spdlog::warn("Initializing config");
|
||||
Config::InitConfig();
|
||||
CreateSymlinkForLoadingFiles();
|
||||
spdlog::warn("Sorting Player Variables");
|
||||
GamePH::PlayerVariables::SortPlayerVars();
|
||||
spdlog::info("Player Variables sorted");
|
||||
|
||||
spdlog::warn("Initializing MinHook");
|
||||
MH_Initialize();
|
||||
spdlog::info("Initialized MinHook");
|
||||
|
||||
spdlog::warn("Getting game version");
|
||||
GameVersionCheck();
|
||||
|
||||
spdlog::warn("Hooking DX11/DX12 renderer");
|
||||
std::thread([]() {
|
||||
LoopHookRenderer();
|
||||
spdlog::info("Hooked \"DX11/DX12 renderer\"!");
|
||||
}).detach();
|
||||
spdlog::warn("Initializing config");
|
||||
Config::InitConfig();
|
||||
CreateSymlinkForLoadingFiles();
|
||||
|
||||
for (auto& hook : *Utils::Hook::HookBase::GetInstances()) {
|
||||
spdlog::warn("Hooking \"{}\"", hook->name.data());
|
||||
@ -248,11 +235,14 @@ namespace Core {
|
||||
}).detach();
|
||||
}
|
||||
|
||||
std::thread([]() {
|
||||
while (!Engine::GameSpeedHandler::initialized)
|
||||
Engine::GameSpeedHandler::Setup();
|
||||
spdlog::warn("Sorting Player Variables");
|
||||
GamePH::PlayerVariables::SortPlayerVars();
|
||||
spdlog::info("Player Variables sorted");
|
||||
|
||||
spdlog::info("GameSpeedHandler has been set up successfully!");
|
||||
spdlog::warn("Hooking DX11/DX12 renderer");
|
||||
std::thread([]() {
|
||||
LoopHookRenderer();
|
||||
spdlog::info("Hooked \"DX11/DX12 renderer\"!");
|
||||
}).detach();
|
||||
|
||||
const HANDLE proc = GetCurrentProcess();
|
||||
|
@ -7,11 +7,30 @@ namespace Core {
|
||||
extern void Cleanup();
|
||||
}
|
||||
|
||||
namespace Engine {
|
||||
namespace Hooks {
|
||||
extern Utils::Hook::MHook<LPVOID, DWORD64(*)(DWORD64, UINT, UINT, DWORD64*, DWORD64(*)(DWORD64, DWORD, DWORD64, char*, int), INT16, DWORD64, UINT)> MountDataPaksHook;
|
||||
extern Utils::Hook::MHook<LPVOID, DWORD64(*)(DWORD64, DWORD, DWORD)> FsOpenHook;
|
||||
extern Utils::Hook::MHook<LPVOID, bool(*)(LPVOID, LPVOID)> FsCalcFileCrcHook;
|
||||
extern Utils::Hook::MHook<LPVOID, LPVOID(*)(LPVOID)> AuthenticateDataAddNewFileHook;
|
||||
extern Utils::Hook::MHook<LPVOID, void(*)(LPVOID)> AuthenticateDataAnalyzeHook;
|
||||
extern Utils::Hook::MHook<LPVOID, bool(*)(LPVOID)> FsCheckZipCrcHook;
|
||||
}
|
||||
}
|
||||
|
||||
static HANDLE hMainThread{};
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD64 ul_reason_for_call, LPVOID lpReserved) {
|
||||
switch (ul_reason_for_call) {
|
||||
case DLL_PROCESS_ATTACH: {
|
||||
MH_Initialize();
|
||||
Engine::Hooks::MountDataPaksHook.HookLoop();
|
||||
Engine::Hooks::AuthenticateDataAnalyzeHook.HookLoop();
|
||||
Engine::Hooks::AuthenticateDataAddNewFileHook.HookLoop();
|
||||
Engine::Hooks::FsCheckZipCrcHook.HookLoop();
|
||||
Engine::Hooks::FsCalcFileCrcHook.HookLoop();
|
||||
Engine::Hooks::FsOpenHook.HookLoop();
|
||||
|
||||
DisableThreadLibraryCalls(hModule);
|
||||
hMainThread = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)Core::MainThread, hModule, 0, nullptr);
|
||||
|
||||
|
@ -5,7 +5,7 @@ namespace Engine {
|
||||
float speed = 1.0;
|
||||
bool initialized = false;
|
||||
|
||||
#pragma region GetTickCount64Hook
|
||||
/*#pragma region GetTickCount64Hook
|
||||
ULONGLONG GTC64_BaseTime = 0;
|
||||
ULONGLONG GTC64_OffsetTime = 0;
|
||||
|
||||
@ -62,6 +62,6 @@ namespace Engine {
|
||||
}
|
||||
|
||||
speed = gameSpeed;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ namespace Engine {
|
||||
extern float speed;
|
||||
extern bool initialized;
|
||||
|
||||
void Setup();
|
||||
void SetGameSpeed(float gameSpeed);
|
||||
/*void Setup();
|
||||
void SetGameSpeed(float gameSpeed);*/
|
||||
}
|
||||
}
|
@ -67,6 +67,8 @@ namespace Engine {
|
||||
#pragma endregion
|
||||
|
||||
#pragma region fs::open
|
||||
static const std::string userModFilesFullPath = "\\\\?\\" + std::filesystem::absolute("..\\..\\..\\source\\data\\EGameTools\\UserModFiles").string();
|
||||
|
||||
static std::vector<std::string> cachedUserModDirs{};
|
||||
static Utils::Time::Timer timeSinceCache{ 0 };
|
||||
static void CacheUserModDirs() {
|
||||
@ -75,15 +77,18 @@ namespace Engine {
|
||||
if (!cachedUserModDirs.empty())
|
||||
cachedUserModDirs.clear();
|
||||
|
||||
const char* userModFilesPath = "..\\..\\..\\source\\data\\EGameTools\\UserModFiles";
|
||||
cachedUserModDirs.push_back(userModFilesFullPath);
|
||||
try {
|
||||
const auto rdi = std::filesystem::recursive_directory_iterator(userModFilesFullPath);
|
||||
for (auto entry = std::filesystem::begin(rdi); entry != std::filesystem::end(rdi); ++entry) {
|
||||
const std::filesystem::path pathToDir = entry->path();
|
||||
if (!std::filesystem::is_directory(pathToDir))
|
||||
continue;
|
||||
|
||||
cachedUserModDirs.push_back(userModFilesPath);
|
||||
for (const auto& entry : std::filesystem::recursive_directory_iterator(userModFilesPath)) {
|
||||
const std::filesystem::path pathToDir = entry.path();
|
||||
if (!std::filesystem::is_directory(pathToDir))
|
||||
continue;
|
||||
|
||||
cachedUserModDirs.push_back(pathToDir.string());
|
||||
cachedUserModDirs.push_back(pathToDir.string());
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
spdlog::error("Exception thrown while caching user mod directories: {}", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,7 +96,7 @@ namespace Engine {
|
||||
return Utils::Memory::GetProcAddr("filesystem_x64_rwdi.dll", "?open@fs@@YAPEAUSFsFile@@V?$string_const@D@ttl@@W4TYPE@EFSMode@@W45FFSOpenFlags@@@Z");
|
||||
}
|
||||
static DWORD64 detourFsOpen(DWORD64 file, DWORD a2, DWORD a3);
|
||||
static Utils::Hook::MHook<LPVOID, DWORD64(*)(DWORD64, DWORD, DWORD)> FsOpenHook{ "fs::open", &GetFsOpen, &detourFsOpen };
|
||||
Utils::Hook::MHook<LPVOID, DWORD64(*)(DWORD64, DWORD, DWORD)> FsOpenHook{ "fs::open", &GetFsOpen, &detourFsOpen };
|
||||
|
||||
static DWORD64 detourFsOpen(DWORD64 file, DWORD a2, DWORD a3) {
|
||||
const DWORD64 firstByte = (file >> 56) & 0xFF; // get first byte of addr
|
||||
@ -107,22 +112,22 @@ namespace Engine {
|
||||
}
|
||||
|
||||
std::string finalPath{};
|
||||
|
||||
try {
|
||||
for (const auto& entry : cachedUserModDirs) {
|
||||
finalPath = entry + "\\" + fileName;
|
||||
if (!std::filesystem::exists(finalPath))
|
||||
continue;
|
||||
|
||||
const std::string finalPath2 = std::filesystem::absolute(finalPath).string();
|
||||
const char* filePath2 = finalPath2.c_str();
|
||||
|
||||
finalPath.replace(0, userModFilesFullPath.size() + 1, ""); // replace entire path until mod folder with nothing
|
||||
const char* filePath2 = finalPath.c_str();
|
||||
spdlog::warn("Loading user mod file \"{}\"", finalPath.c_str());
|
||||
|
||||
const DWORD64 finalAddr = firstByte != 0x0 ? (reinterpret_cast<DWORD64>(filePath2) | (firstByte << 56)) : reinterpret_cast<DWORD64>(filePath2); // restores first byte of addr if first byte was not 0
|
||||
|
||||
const DWORD64 result = FsOpenHook.pOriginal(finalAddr, a2, a3);
|
||||
if (!result)
|
||||
spdlog::error("fs::open returned 0! Something went wrong with loading user mod file \"{}\"!", finalPath.c_str());
|
||||
if (!result) {
|
||||
spdlog::error("fs::open returned 0! Something went wrong with loading user mod file \"{}\"!\nPlease make sure the path to the file is no longer than 260 characters!", finalPath.c_str());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
@ -131,5 +136,128 @@ namespace Engine {
|
||||
return FsOpenHook.pOriginal(file, a2, a3);
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
/*#pragma region FsNativeOpen
|
||||
static LPVOID GetFsNativeOpen() {
|
||||
return Utils::Memory::GetProcAddr("filesystem_x64_rwdi.dll", "?open@native@fs@@YAPEAUSFsFile@@PEAVCFsMount@@V?$string_const@D@ttl@@W4TYPE@EFSMode@@W47FFSOpenFlags@@@Z");
|
||||
}
|
||||
static DWORD64 detourFsNativeOpen(DWORD64 a1, DWORD64 a2, UINT a3, UINT a4);
|
||||
static Utils::Hook::MHook<LPVOID, DWORD64(*)(DWORD64, DWORD64, UINT, UINT)> FsNativeOpenHook{ "FsNativeOpen", &GetFsNativeOpen, &detourFsNativeOpen };
|
||||
|
||||
static DWORD64 detourFsNativeOpen(DWORD64 a1, DWORD64 a2, UINT a3, UINT a4) {
|
||||
return FsNativeOpenHook.pOriginal(a1, a2, a3, a4);
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
#pragma region LoadDataPaks
|
||||
struct CPath {
|
||||
public:
|
||||
union {
|
||||
const char* gamePath;
|
||||
buffer<0x8, const char*> pakPath;
|
||||
buffer<0x10, const char*> fullPakPath;
|
||||
};
|
||||
};
|
||||
static LPVOID GetLoadDataPaks() {
|
||||
return reinterpret_cast<LPVOID>(reinterpret_cast<DWORD64>(GetModuleHandleA("filesystem_x64_rwdi.dll")) + 0x29580);
|
||||
}
|
||||
static bool detourLoadDataPaks(DWORD64 a1, DWORD64 a2, DWORD64 a3);
|
||||
static Utils::Hook::MHook<LPVOID, bool(*)(DWORD64, DWORD64, DWORD64)> LoadDataPaksHook{ "LoadDataPaks", &GetLoadDataPaks, &detourLoadDataPaks };
|
||||
|
||||
static bool detourLoadDataPaks(DWORD64 a1, DWORD64 a2, DWORD64 a3) {
|
||||
CPath* cPath = reinterpret_cast<CPath*>(a2);
|
||||
if ((cPath->fullPakPath & 0x1FFFFFFFFFFFFFFF) != 0) {
|
||||
const DWORD64 firstByte = (cPath->fullPakPath >> 56) & 0xFF; // get first byte of addr
|
||||
std::string gamePath = reinterpret_cast<const char*>(reinterpret_cast<DWORD64>(cPath->gamePath) & 0x1FFFFFFFFFFFFFFF);
|
||||
DWORD64 origPakPath = reinterpret_cast<DWORD64>(const_cast<char*>(cPath->pakPath.data));
|
||||
std::string pakPath = reinterpret_cast<const char*>(cPath->pakPath & 0x1FFFFFFFFFFFFFFF);
|
||||
DWORD64 origFullPakPath = reinterpret_cast<DWORD64>(const_cast<char*>(cPath->fullPakPath.data));
|
||||
std::string fullPakPath = reinterpret_cast<const char*>(cPath->fullPakPath & 0x1FFFFFFFFFFFFFFF);
|
||||
|
||||
if (pakPath == "ph/source/data0.pak") {
|
||||
pakPath = "ph/source/data/EGameTools/UserModFiles/data8.pak";
|
||||
const char* pakPathCStr = pakPath.c_str();
|
||||
fullPakPath.replace(gamePath.size() + 1, fullPakPath.size(), "ph/source/data/EGameTools/UserModFiles/data8.pak");
|
||||
const char* fullPakPathCStr = fullPakPath.c_str();
|
||||
|
||||
const DWORD64 finalAddrPakPath = firstByte != 0x0 ? (reinterpret_cast<DWORD64>(pakPathCStr) | (firstByte << 56)) : reinterpret_cast<DWORD64>(pakPathCStr);
|
||||
const DWORD64 finalAddrFullPakPath= firstByte != 0x0 ? (reinterpret_cast<DWORD64>(fullPakPathCStr) | (firstByte << 56)) : reinterpret_cast<DWORD64>(fullPakPathCStr);
|
||||
|
||||
cPath->pakPath = reinterpret_cast<const char*>(finalAddrPakPath);
|
||||
cPath->fullPakPath = reinterpret_cast<const char*>(finalAddrFullPakPath);
|
||||
bool ret = LoadDataPaksHook.pOriginal(a1, a2, a3);
|
||||
cPath->pakPath = reinterpret_cast<const char*>(origPakPath);
|
||||
cPath->fullPakPath = reinterpret_cast<const char*>(origFullPakPath);
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
}
|
||||
|
||||
return LoadDataPaksHook.pOriginal(a1, a2, a3);
|
||||
}
|
||||
#pragma endregion*/
|
||||
|
||||
#pragma region MountDataPaks
|
||||
static DWORD64 detourMountDataPaks(DWORD64 a1, UINT a2, UINT a3, DWORD64* a4, DWORD64(*a5)(DWORD64, DWORD, DWORD64, char*, int), INT16 a6, DWORD64 a7, UINT a8);
|
||||
Utils::Hook::MHook<LPVOID, DWORD64(*)(DWORD64, UINT, UINT, DWORD64*, DWORD64(*)(DWORD64, DWORD, DWORD64, char*, int), INT16, DWORD64, UINT)> MountDataPaksHook{ "MountDataPaks", &Offsets::Get_MountDataPaks, &detourMountDataPaks };
|
||||
|
||||
static DWORD64 detourMountDataPaks(DWORD64 a1, UINT a2, UINT a3, DWORD64* a4, DWORD64(*a5)(DWORD64, DWORD, DWORD64, char*, int), INT16 a6, DWORD64 a7, UINT a8) {
|
||||
return MountDataPaksHook.pOriginal(a1, a2, a3, a4, a5, a6, a7, 200);
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
#pragma region FsCalcFileCrc
|
||||
static LPVOID GetFsCalcFileCrc() {
|
||||
return Utils::Memory::GetProcAddr("filesystem_x64_rwdi.dll", "?calc_file_crc@fs@@YA_NAEAUcrc_calc_args@1@@Z");
|
||||
}
|
||||
static bool detourFsCalcFileCrc(LPVOID instance, LPVOID crcCalcArgs);
|
||||
Utils::Hook::MHook<LPVOID, bool(*)(LPVOID, LPVOID)> FsCalcFileCrcHook{ "FsCalcFileCrc", &GetFsCalcFileCrc, &detourFsCalcFileCrc };
|
||||
|
||||
static bool detourFsCalcFileCrc(LPVOID instance, LPVOID crcCalcArgs) {
|
||||
return true;
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
#pragma region FsCheckZipCrc
|
||||
static LPVOID GetFsCheckZipCrc() {
|
||||
return Utils::Memory::GetProcAddr("filesystem_x64_rwdi.dll", "?check_zip_crc@izipped_buffer_file@fs@@QEAA_NXZ");
|
||||
}
|
||||
static bool detourFsCheckZipCrc(LPVOID instance);
|
||||
Utils::Hook::MHook<LPVOID, bool(*)(LPVOID)> FsCheckZipCrcHook{ "FsCheckZipCrc", &GetFsCheckZipCrc, &detourFsCheckZipCrc };
|
||||
|
||||
static bool detourFsCheckZipCrc(LPVOID instance) {
|
||||
return true;
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
#pragma region AuthenticateDataAddNewFile
|
||||
static LPVOID GetAuthenticateDataAddNewFile() {
|
||||
return Utils::Memory::GetProcAddr("engine_x64_rwdi.dll", "?AddNewFile@Results@AuthenticateData@@QEAAAEAVFile@12@XZ");
|
||||
}
|
||||
static void AuthenticateDataResultsClear(LPVOID instance) {
|
||||
void(*func)(LPVOID instance) = reinterpret_cast<decltype(func)>(Utils::Memory::GetProcAddr("engine_x64_rwdi.dll", "?Clear@Results@AuthenticateData@@QEAAXXZ"));
|
||||
func(instance);
|
||||
}
|
||||
static LPVOID detourAuthenticateDataAddNewFile(LPVOID instance);
|
||||
Utils::Hook::MHook<LPVOID, LPVOID(*)(LPVOID)> AuthenticateDataAddNewFileHook{ "AuthenticateDataAddNewFile", &GetAuthenticateDataAddNewFile, &detourAuthenticateDataAddNewFile };
|
||||
|
||||
static LPVOID detourAuthenticateDataAddNewFile(LPVOID instance) {
|
||||
LPVOID result = AuthenticateDataAddNewFileHook.pOriginal(instance);
|
||||
AuthenticateDataResultsClear(instance);
|
||||
return result;
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
#pragma region AuthenticateDataAnalyze
|
||||
static LPVOID GetAuthenticateDataAnalyze() {
|
||||
return Utils::Memory::GetProcAddr("engine_x64_rwdi.dll", "?Analyze@Results@AuthenticateData@@QEAAXXZ");
|
||||
}
|
||||
static void detourAuthenticateDataAnalyze(LPVOID instance);
|
||||
Utils::Hook::MHook<LPVOID, void(*)(LPVOID)> AuthenticateDataAnalyzeHook{ "AuthenticateDataAnalyze", &GetAuthenticateDataAnalyze, &detourAuthenticateDataAnalyze };
|
||||
|
||||
static void detourAuthenticateDataAnalyze(LPVOID instance) {
|
||||
AuthenticateDataAnalyzeHook.pOriginal(instance);
|
||||
}
|
||||
#pragma endregion
|
||||
}
|
||||
}
|
@ -3,10 +3,16 @@
|
||||
|
||||
template<size_t size, typename T> class buffer {
|
||||
char buffer[size];
|
||||
T data;
|
||||
public:
|
||||
T data;
|
||||
|
||||
operator T() { return data; }
|
||||
T operator->() { return data; }
|
||||
|
||||
DWORD64 operator&(const DWORD64 other) const { return reinterpret_cast<DWORD64>(data) & other; }
|
||||
DWORD64 operator>>(const int shift) const { return reinterpret_cast<DWORD64>(data) >> shift; }
|
||||
DWORD64 operator<<(const int shift) const { return reinterpret_cast<DWORD64>(data) << shift; }
|
||||
|
||||
T& operator=(const T& other) { data = other; return data; }
|
||||
T& operator*=(const T& other) { data *= other; return data; }
|
||||
T operator*(const T& other) const { return data * other; }
|
||||
|
@ -10,6 +10,8 @@ namespace Menu {
|
||||
float time = 0.0f;
|
||||
static float timeBeforeFreeze = 0.0f;
|
||||
float gameSpeed = 1.0f;
|
||||
static float actualGameSpeed = gameSpeed;
|
||||
static float gameSpeedBeforeSlowMo = gameSpeed;
|
||||
KeyBindOption freezeTime{ VK_NONE };
|
||||
KeyBindOption slowMotion{ '4' };
|
||||
float slowMotionSpeed = 0.4f;
|
||||
@ -52,25 +54,29 @@ namespace Menu {
|
||||
}
|
||||
|
||||
static bool slowMoHasChanged = true;
|
||||
static float initialGameSpeed = Engine::GameSpeedHandler::speed;
|
||||
if (slowMotion.HasChangedTo(false)) {
|
||||
static float gameSpeedAfterChange = 0.0f;
|
||||
if (slowMoHasChanged)
|
||||
initialGameSpeed = Engine::GameSpeedHandler::speed;
|
||||
gameSpeedAfterChange = actualGameSpeed;
|
||||
|
||||
slowMotionSpeedLerp = ImGui::AnimateLerp("slowMotionSpeedLerp", initialGameSpeed, gameSpeed, slowMotionTransitionTime, slowMoHasChanged, &ImGui::AnimEaseInOutSine);
|
||||
Engine::GameSpeedHandler::SetGameSpeed(slowMotionSpeedLerp);
|
||||
slowMotionSpeedLerp = ImGui::AnimateLerp("slowMotionSpeedLerp", gameSpeedAfterChange, gameSpeedBeforeSlowMo, slowMotionTransitionTime, slowMoHasChanged, &ImGui::AnimEaseInOutSine);
|
||||
iLevel->TimerSetSpeedUp(slowMotionSpeedLerp);
|
||||
slowMoHasChanged = false;
|
||||
|
||||
if (Utils::Values::are_samef(Engine::GameSpeedHandler::speed, gameSpeed)) {
|
||||
if (Utils::Values::are_samef(actualGameSpeed, gameSpeedBeforeSlowMo)) {
|
||||
slowMoHasChanged = true;
|
||||
slowMotion.SetPrevValue(false);
|
||||
}
|
||||
} else if (slowMotion.GetValue()) {
|
||||
if (slowMotion.HasChanged())
|
||||
initialGameSpeed = Engine::GameSpeedHandler::speed;
|
||||
static float gameSpeedAfterChange = 0.0f;
|
||||
if (slowMotion.HasChanged()) {
|
||||
if (slowMoHasChanged)
|
||||
gameSpeedBeforeSlowMo = actualGameSpeed;
|
||||
gameSpeedAfterChange = actualGameSpeed;
|
||||
}
|
||||
|
||||
slowMotionSpeedLerp = ImGui::AnimateLerp("slowMotionSpeedLerp", initialGameSpeed, slowMotionSpeed, slowMotionTransitionTime, slowMotion.HasChanged(), &ImGui::AnimEaseInOutSine);
|
||||
Engine::GameSpeedHandler::SetGameSpeed(slowMotionSpeedLerp);
|
||||
slowMotionSpeedLerp = ImGui::AnimateLerp("slowMotionSpeedLerp", gameSpeedAfterChange, slowMotionSpeed, slowMotionTransitionTime, slowMotion.HasChanged(), &ImGui::AnimEaseInOutSine);
|
||||
iLevel->TimerSetSpeedUp(slowMotionSpeedLerp);
|
||||
|
||||
if (slowMotion.HasChanged()) {
|
||||
slowMoHasChanged = true;
|
||||
@ -82,13 +88,18 @@ namespace Menu {
|
||||
time = dayNightCycle->time1 * 24.0f;
|
||||
if (freezeTime.GetValue() && !Utils::Values::are_samef(time, timeBeforeFreeze, 0.009999f))
|
||||
dayNightCycle->SetDaytime(timeBeforeFreeze);
|
||||
|
||||
if (!slowMotion.GetValue() && !slowMotion.HasChanged() && !Utils::Values::are_samef(gameSpeed, 1.0f))
|
||||
iLevel->TimerSetSpeedUp(gameSpeed);
|
||||
actualGameSpeed = iLevel->TimerGetSpeedUp();
|
||||
}
|
||||
}
|
||||
void Tab::Render() {
|
||||
GamePH::DayNightCycle* dayNightCycle = GamePH::DayNightCycle::Get();
|
||||
GamePH::LevelDI* iLevel = GamePH::LevelDI::Get();
|
||||
ImGui::SeparatorText("Time##World");
|
||||
ImGui::BeginDisabled(!iLevel || !iLevel->IsLoaded() || !dayNightCycle); {
|
||||
ImGui::BeginDisabled(!iLevel || !iLevel->IsLoaded() || !dayNightCycle);
|
||||
{
|
||||
static bool timeSliderBeingPressed = false;
|
||||
if (ImGui::SliderFloat("Time", &time, 0.01f, 24.0f, "%.2f", ImGuiSliderFlags_AlwaysClamp))
|
||||
timeSliderBeingPressed = true;
|
||||
@ -103,9 +114,15 @@ namespace Menu {
|
||||
dayNightCycle->SetDaytime(timeBeforeFreeze);
|
||||
}
|
||||
|
||||
ImGui::BeginDisabled(slowMotion.GetValue()); {
|
||||
ImGui::BeginDisabled(slowMotion.GetValue());
|
||||
{
|
||||
if (ImGui::SliderFloat("Game Speed", &gameSpeed, 0.0f, 2.0f, "%.2fx"))
|
||||
Engine::GameSpeedHandler::SetGameSpeed(gameSpeed);
|
||||
iLevel->TimerSetSpeedUp(gameSpeed);
|
||||
else if (iLevel && iLevel->IsLoaded()) {
|
||||
if (!slowMotion.GetValue() && !slowMotion.HasChanged() && !Utils::Values::are_samef(gameSpeed, 1.0f))
|
||||
iLevel->TimerSetSpeedUp(gameSpeed);
|
||||
actualGameSpeed = iLevel->TimerGetSpeedUp();
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
@ -122,7 +139,8 @@ namespace Menu {
|
||||
const bool weatherDisabledFlag = !iLevel || !iLevel->IsLoaded() || !timeWeatherSystem;
|
||||
|
||||
ImGui::SeparatorText("Weather##World");
|
||||
ImGui::BeginDisabled(weatherDisabledFlag); {
|
||||
ImGui::BeginDisabled(weatherDisabledFlag);
|
||||
{
|
||||
if (ImGui::Combo("Weather", reinterpret_cast<int*>(&weather), weatherItems, IM_ARRAYSIZE(weatherItems)) && timeWeatherSystem)
|
||||
timeWeatherSystem->SetForcedWeather(static_cast<GamePH::TimeWeather::EWeather::TYPE>(weather - 1));
|
||||
ImGui::Text("Setting weather to: %s", !weatherDisabledFlag ? weatherItems[weather] : "");
|
||||
|
@ -49,6 +49,7 @@ struct Offsets {
|
||||
|
||||
// Functions
|
||||
AddOffset(ReadVideoSettings, "engine_x64_rwdi.dll", "48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC ?? 48 8B FA 48 8B D9 45 84 C0", Utils::SigScan::PatternType::Address, LPVOID)
|
||||
AddOffset(MountDataPaks, "engine_x64_rwdi.dll", "4C 8B DC 4D 89 4B ?? 45 89 43 ?? 89 54 24 ?? 49 89 4B", Utils::SigScan::PatternType::Address, LPVOID)
|
||||
AddOffset(MoveCameraFromForwardUpPos, "engine_x64_rwdi.dll", "48 89 5C 24 ?? 57 48 83 EC ?? 49 8B C1 48 8B F9", Utils::SigScan::PatternType::Address, LPVOID)
|
||||
AddOffset(CalculateFreeCamCollision, "gamedll_ph_x64_rwdi.dll", "48 8B C4 55 53 56 57 48 8D A8 ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? 83 B9", Utils::SigScan::PatternType::Address, LPVOID)
|
||||
AddOffset(AllowCameraMovement, "gamedll_ph_x64_rwdi.dll", "89 91 ?? ?? ?? ?? C3 CC CC CC CC CC CC CC CC CC 48 8B C4 55 56", Utils::SigScan::PatternType::Address, LPVOID)
|
||||
|
@ -38,6 +38,8 @@ namespace Utils {
|
||||
MHook(const std::string_view& name, GetTargetOffsetRetType(*pGetOffsetFunc)(), OrigType pDetour) : HookBase(name), pGetOffsetFunc(pGetOffsetFunc), pDetour(pDetour) {}
|
||||
|
||||
void HookLoop() override {
|
||||
if (pOriginal)
|
||||
return;
|
||||
timeSpentHooking = Utils::Time::Timer(60000);
|
||||
|
||||
while (true) {
|
||||
@ -71,6 +73,8 @@ namespace Utils {
|
||||
VTHook(const std::string_view& name, GetTargetOffsetRetType(*pGetOffsetFunc)(), OrigType pDetour, DWORD offset) : HookBase(name), pGetOffsetFunc(pGetOffsetFunc), pDetour(pDetour), offset(offset) {}
|
||||
|
||||
void HookLoop() override {
|
||||
if (pOriginal)
|
||||
return;
|
||||
timeSpentHooking = Utils::Time::Timer(60000);
|
||||
|
||||
while (true) {
|
||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user