Add fog fixes and skip intro fix. Update game name.
This commit is contained in:
@@ -10,11 +10,12 @@
|
||||
#include "UEngine.hpp";
|
||||
#include "SDK/Basic.hpp"
|
||||
#include "SDK/Engine_classes.hpp"
|
||||
#include "SDK/LVL_SplashScreens_classes.hpp"
|
||||
|
||||
using namespace SDK;
|
||||
|
||||
// Constants
|
||||
const std::string PLUGIN_NAME = "LittleNightmareIII";
|
||||
const std::string PLUGIN_NAME = "LittleNightmaresIII";
|
||||
const std::string PLUGIN_LOG = PLUGIN_NAME + ".log";
|
||||
const std::string gameExecutable = "LittleNightmaresIII.exe";
|
||||
|
||||
@@ -29,6 +30,8 @@ static bool g_ultrawide_fix_enabled = false;
|
||||
static bool g_DOF_fix_enabled = false;
|
||||
static bool g_CA_fix_enabled = false;
|
||||
static bool g_Vignetting_fix_enabled = false;
|
||||
static bool g_Fog_fix_enabled = false;
|
||||
static bool g_VolumetricFog_fix_enabled = false;
|
||||
static int g_AdditionalFOVValue = 0;
|
||||
|
||||
// Shared values
|
||||
@@ -47,12 +50,16 @@ static uint8_t* FOVaddress = nullptr;
|
||||
static uint8_t* DOFaddress = nullptr;
|
||||
static uint8_t* CAaddress = nullptr;
|
||||
static uint8_t* Vignettingaddress = nullptr;
|
||||
static uint8_t* VolumetricFogaddress = nullptr;
|
||||
static uint8_t* Fogaddress = nullptr;
|
||||
static uint8_t* CameraComponentaddress = nullptr;
|
||||
static uint8_t* ConstrainAspectRatioaddress = nullptr;
|
||||
static uint8_t* AspectRatioAxisConstraintaddress = nullptr;
|
||||
|
||||
// Hooking
|
||||
static SafetyHookMid FOVHook{};
|
||||
static SafetyHookMid FogHook{};
|
||||
static SafetyHookMid ProcessEventHook{};
|
||||
|
||||
// Prototypes
|
||||
static void FOVFixEnabled();
|
||||
@@ -60,7 +67,10 @@ static void UltraWideFixEnabled();
|
||||
static void DOFFixEnabled();
|
||||
static void CAFixEnabled();
|
||||
static void VignettingFixEnabled();
|
||||
static void FogFixEnabled();
|
||||
static void VolumetricFogFixEnabled();
|
||||
static void EnableConsole();
|
||||
static void SkipIntro();
|
||||
|
||||
extern "C" __declspec(dllexport) void SetFixEnabled(bool enabled)
|
||||
{
|
||||
@@ -130,8 +140,28 @@ extern "C" __declspec(dllexport) void SetFixEnabled(bool enabled)
|
||||
logger->info("Vignetting signature found at address: 0x{:X}.", reinterpret_cast<uintptr_t>(Vignettingaddress));
|
||||
}
|
||||
|
||||
if (CameraComponentaddress && FOVaddress && DOFaddress && CAaddress && Vignettingaddress
|
||||
&& ConstrainAspectRatioaddress && AspectRatioAxisConstraintaddress) {
|
||||
if (!Fogaddress) {
|
||||
constexpr auto FogStringObfuscated = make_obfuscated<0x4A>("83 ?? ?? ?? 75 ?? B3 ?? EB ?? 32 ?? 48 8B");
|
||||
Fogaddress = Memory::AOBScan(gameExecutable, FogStringObfuscated.decrypt(), PAGE_EXECUTE_READ);
|
||||
|
||||
if (!Fogaddress)
|
||||
logger->warn("Fog signature not found. Maybe your game has been updated and is no more compatible with this plugin.");
|
||||
else
|
||||
logger->info("Fog signature found at address: 0x{:X}.", reinterpret_cast<uintptr_t>(Fogaddress));
|
||||
}
|
||||
|
||||
if (!VolumetricFogaddress){
|
||||
constexpr auto VolumetricFogStringObfuscated = make_obfuscated<0x4A>("74 ?? F7 47 ?? ?? ?? ?? ?? 74 ?? 83 BB");
|
||||
VolumetricFogaddress = Memory::AOBScan(gameExecutable, VolumetricFogStringObfuscated.decrypt(), PAGE_EXECUTE_READ);
|
||||
|
||||
if (!VolumetricFogaddress)
|
||||
logger->warn("Volumetric fog signature not found. Maybe your game has been updated and is no more compatible with this plugin.");
|
||||
else
|
||||
logger->info("Volumetric fog signature found at address: 0x{:X}.", reinterpret_cast<uintptr_t>(VolumetricFogaddress));
|
||||
}
|
||||
|
||||
if (CameraComponentaddress && FOVaddress && DOFaddress && CAaddress && Vignettingaddress &&
|
||||
Fogaddress && VolumetricFogaddress && ConstrainAspectRatioaddress && AspectRatioAxisConstraintaddress) {
|
||||
logger->info("All AOB signatures found. Ready to patch...");
|
||||
AOBScanDone = true;
|
||||
}
|
||||
@@ -180,6 +210,8 @@ extern "C" __declspec(dllexport) void SetFixEnabled(bool enabled)
|
||||
if (DOFaddress) DOFFixEnabled();
|
||||
if (CAaddress) CAFixEnabled();
|
||||
if (Vignettingaddress) VignettingFixEnabled();
|
||||
if (Fogaddress) FogFixEnabled();
|
||||
if (VolumetricFogaddress) VolumetricFogFixEnabled();
|
||||
if (AspectRatioAxisConstraintaddress && ConstrainAspectRatioaddress) UltraWideFixEnabled();
|
||||
if (!g_Console_Enabled && GObjectsaddress && GNamesaddress && ProcessEventaddress)
|
||||
EnableConsole();
|
||||
@@ -216,6 +248,24 @@ extern "C" __declspec(dllexport) void SetVignettingFixEnabled(bool enabled, bool
|
||||
if (!init) VignettingFixEnabled();
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) void SetFogFixEnabled(bool enabled, bool init)
|
||||
{
|
||||
g_Fog_fix_enabled = enabled;
|
||||
if (!init) FogFixEnabled();
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) void SetVolumetricFogFixEnabled(bool enabled, bool init)
|
||||
{
|
||||
g_VolumetricFog_fix_enabled = enabled;
|
||||
if (!init) VolumetricFogFixEnabled();
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) void SetSkipIntroEnabled(bool enabled)
|
||||
{
|
||||
if (enabled) SkipIntro();
|
||||
}
|
||||
|
||||
|
||||
extern "C" __declspec(dllexport) void SetFOV(int fov)
|
||||
{
|
||||
g_AdditionalFOVValue = fov;
|
||||
@@ -250,6 +300,45 @@ static void FOVFixEnabled() {
|
||||
}
|
||||
}
|
||||
|
||||
static void FogFixEnabled() {
|
||||
if (g_fix_enabled && g_Fog_fix_enabled && Fogaddress) {
|
||||
if (!FogHook) {
|
||||
FogHook = safetyhook::create_mid(Fogaddress,
|
||||
[](SafetyHookContext& ctx) {
|
||||
if (!ctx.rax) return;
|
||||
uintptr_t* rax = reinterpret_cast<uintptr_t*>(ctx.rax);
|
||||
bool* bFog = reinterpret_cast<bool*>(reinterpret_cast<uint8_t*>(rax) + 0x04);
|
||||
*bFog = g_fix_enabled && g_Fog_fix_enabled ? false : true;
|
||||
});
|
||||
}
|
||||
logger->info("Fog fix enabled");
|
||||
}
|
||||
if (!(g_fix_enabled && g_Fog_fix_enabled) && Fogaddress)
|
||||
logger->info("Fog fix disabled");
|
||||
}
|
||||
|
||||
static void SkipIntro() {
|
||||
if (!ProcessEventHook && ProcessEventaddress) {
|
||||
ProcessEventHook = safetyhook::create_mid(ProcessEventaddress + 0xc,
|
||||
[](SafetyHookContext& ctx) {
|
||||
auto* object = reinterpret_cast<UObject*>(ctx.rcx);
|
||||
auto* function = reinterpret_cast<UFunction*>(ctx.rdx);
|
||||
// Hook ProcessEvent to skip intros
|
||||
if (object && function) {
|
||||
std::string className = object->GetName();
|
||||
std::string functionName = function->GetName();
|
||||
|
||||
if (className.contains("LVL_SplashScreens_C_0") && functionName.contains("ReceiveBeginPlay")) {
|
||||
if (object->IsA(ALVL_SplashScreens_C::StaticClass())) {
|
||||
auto* SplashScreen = static_cast<ALVL_SplashScreens_C*>(object);
|
||||
if (SplashScreen) SplashScreen->GoToMainMenuLevel(); // skip intros
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Memory patch fixes
|
||||
static void UltraWideFixEnabled() {
|
||||
if (g_fix_enabled && g_ultrawide_fix_enabled && AspectRatioAxisConstraintaddress && ConstrainAspectRatioaddress) {
|
||||
@@ -297,6 +386,17 @@ static void VignettingFixEnabled() {
|
||||
}
|
||||
}
|
||||
|
||||
static void VolumetricFogFixEnabled() {
|
||||
if (g_fix_enabled && g_VolumetricFog_fix_enabled && VolumetricFogaddress) {
|
||||
Memory::PatchBytes(VolumetricFogaddress, "\xEB", 1); // je-> jmp r.Fog=0
|
||||
logger->info("Volumetric fog fix enabled");
|
||||
}
|
||||
if (!(g_fix_enabled && g_VolumetricFog_fix_enabled) && VolumetricFogaddress) {
|
||||
Memory::RestoreBytes(VolumetricFogaddress);
|
||||
logger->info("Volumetric fog fix disabled");
|
||||
}
|
||||
}
|
||||
|
||||
// UE Console creation
|
||||
static void EnableConsole()
|
||||
{
|
||||
@@ -356,7 +456,7 @@ static void InitializeLogger()
|
||||
std::filesystem::path log_path = std::filesystem::absolute(PLUGIN_LOG);
|
||||
if (std::filesystem::exists(log_path))
|
||||
std::filesystem::remove(log_path);
|
||||
logger = std::make_shared<spdlog::logger>("Little Nightmare III", std::make_shared<spdlog::sinks::rotating_file_sink_st>(PLUGIN_LOG, 10 * 1024 * 1024, 1));
|
||||
logger = std::make_shared<spdlog::logger>("Little Nightmares III", std::make_shared<spdlog::sinks::rotating_file_sink_st>(PLUGIN_LOG, 10 * 1024 * 1024, 1));
|
||||
logger->set_level(spdlog::level::debug);
|
||||
logger->flush_on(spdlog::level::debug); // Flush automatically
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user