diff --git a/data/plugins/GTAIV.EFLC.FusionFix.ini b/data/plugins/GTAIV.EFLC.FusionFix.ini index 656bc97b..ef8cc27a 100644 --- a/data/plugins/GTAIV.EFLC.FusionFix.ini +++ b/data/plugins/GTAIV.EFLC.FusionFix.ini @@ -50,6 +50,7 @@ TreeAlphaPC = 0.625 TreeAlphaConsole = 4.0 CoronaReflectionIntensity = 1.0 // controls intensity of coronas in reflections ConsoleCarReflectionsAndDirt = 1 +AlwaysDisplayHealthOnReticle = 1 [BudgetedIV] VehicleBudget = 0 // may cause issues, set to e.g. 260000000 to increase budget limit diff --git a/source/fixes.ixx b/source/fixes.ixx index d18a0f2d..f6268d3f 100644 --- a/source/fixes.ixx +++ b/source/fixes.ixx @@ -70,6 +70,8 @@ public: bool bDefaultCameraAngleInTLAD = iniReader.ReadInteger("MISC", "DefaultCameraAngleInTLAD", 0) != 0; bool bPedDeathAnimFixFromTBOGT = iniReader.ReadInteger("MISC", "PedDeathAnimFixFromTBOGT", 1) != 0; + bool bAlwaysDisplayHealthOnReticle = iniReader.ReadInteger("MISC", "AlwaysDisplayHealthOnReticle", 0) != 0; + //fix for zoom flag in tbogt if (nAimingZoomFix) { @@ -514,6 +516,46 @@ public: injector::MakeNOP(pattern.get_first(0), 25, true); } } + + // Always display the ped health on the reticle with free-aim while on foot, used to be a gamepad + multiplayer only feature (PC is always free-aim unless it's melee combat). + if (bAlwaysDisplayHealthOnReticle) + { + auto pattern = hook::pattern("80 3D ? ? ? ? ? 75 64 A1 ? ? ? ? 8B 0C 85"); + if (!pattern.empty()) + { + static auto loc_5C8E93 = (uintptr_t)pattern.get_first(0); + + pattern = hook::pattern("80 BB ? ? ? ? ? 74 61 56 57 E8"); + struct ReticleHealthHook + { + void operator()(injector::reg_pack& regs) + { + if (!(*(uint8_t*)(regs.ebx + 12941)) || !(*(uint8_t*)(regs.ebx + 12940))) + *(uintptr_t*)(regs.esp - 4) = loc_5C8E93; + } + }; injector::MakeInline(pattern.get_first(0), pattern.get_first(9)); + + pattern = hook::pattern("75 0C 38 83 ? ? ? ? 0F 84"); + injector::WriteMemory(pattern.get_first(0), 0xEB, true); + } + else + { + static auto loc_5C8E93 = (uintptr_t)hook::get_pattern("80 3D ? ? ? ? ? 75 6A A1 ? ? ? ? 8B 04 85"); + + pattern = hook::pattern("80 B9 ? ? ? ? ? 74 6D 56 57 E8"); + struct ReticleHealthHook + { + void operator()(injector::reg_pack& regs) + { + if (!(*(uint8_t*)(regs.ecx + 12941)) || !(*(uint8_t*)(regs.ecx + 12940))) + *(uintptr_t*)(regs.esp - 4) = loc_5C8E93; + } + }; injector::MakeInline(pattern.get_first(0), pattern.get_first(9)); + + pattern = hook::pattern("75 0C 38 86 ? ? ? ? 0F 84"); + injector::WriteMemory(pattern.get_first(0), 0xEB, true); + } + } }; } } Fixes; \ No newline at end of file diff --git a/source/shaders.ixx b/source/shaders.ixx index 348c8ee2..131ec4d6 100644 --- a/source/shaders.ixx +++ b/source/shaders.ixx @@ -117,16 +117,31 @@ public: }; injector::MakeInline(pattern.get_first(0), pattern.get_first(7)); } - // Pass the correct value for gAmbientAmount to the rain shader (gta_rmptfx_gpurender). - // The Game reads the rain.* values in visualsettings.dat properly but then overrides them with custom values. - // This makes rain drops more visible, this was done in shader before but moved here instead. + // Actually read the rain lighting settings in the visualsettings.dat { - auto pattern = find_pattern("F3 0F 10 05 ? ? ? ? 6A 10 8B D9 8B 4F 18 F3 0F 11 44 24 ? F3 0F 10 05", "F3 0F 10 05 ? ? ? ? 68 ? ? ? ? F3 0F 11 44 24 ? F3 0F 10 05 ? ? ? ? 50 F3 0F 11 44 24"); + auto pattern = hook::pattern("8D 44 24 2C 50 FF 33 F3 0F 11 44 24 ? 56 E8"); if (!pattern.empty()) { - injector::MakeNOP(pattern.get_first(0), 8, true); // rain.ambient (gAmbientAmount): 0.1 -> 0.4 - pattern = find_pattern("F3 0F 11 44 24 ? F3 0F 10 05 ? ? ? ? 68 ? ? ? ? FF 73 14 F3 0F 11 44 24", "F3 0F 11 44 24 ? F3 0F 10 05 ? ? ? ? 50 F3 0F 11 44 24 ? F3 0F 10 05 ? ? ? ? 8D 5F 14 53 F3 0F 11 44 24"); - injector::MakeNOP(pattern.get_first(0), 6, true); + injector::WriteMemory(pattern.get_first(3), 0x34, true); + pattern = hook::pattern("8D 44 24 2C 50 FF 73 04 F3 0F 11 44 24 ? 56 E8"); + injector::WriteMemory(pattern.get_first(3), 0x30, true); + pattern = hook::pattern("8D 44 24 2C 50 FF 73 08 F3 0F 11 44 24 ? 56 E8"); + injector::WriteMemory(pattern.get_first(3), 0x38, true); + pattern = hook::pattern("8D 44 24 2C 50 FF 73 0C F3 0F 11 44 24 ? 56 E8"); + injector::WriteMemory(pattern.get_first(3), 0x3C, true); + } + else + { + pattern = hook::pattern("F3 0F 10 05 ? ? ? ? 53 56 57 8B 7C 24 10 6A 05"); + injector::MakeNOP(pattern.get_first(0), 8, true); + pattern = hook::pattern("F3 0F 11 44 24 ? F3 0F 10 05 ? ? ? ? 68 ? ? ? ? F3 0F 11 44 24 ? F3 0F 10 05 ? ? ? ? 50"); + injector::MakeNOP(pattern.get_first(0), 14, true); + pattern = hook::pattern("F3 0F 11 44 24 ? F3 0F 10 05 ? ? ? ? 50 F3 0F 11 44 24 ? F3 0F 10 05 ? ? ? ? 8D 5F 14"); + injector::MakeNOP(pattern.get_first(0), 14, true); + pattern = hook::pattern("F3 0F 11 44 24 ? F3 0F 10 05 ? ? ? ? 8D 5F 14 53 F3 0F 11 44 24"); + injector::MakeNOP(pattern.get_first(0), 14, true); + pattern = hook::pattern("F3 0F 11 44 24 ? E8 ? ? ? ? 8B 0D ? ? ? ? 8B 56 10"); + injector::MakeNOP(pattern.get_first(0), 6, true); } }