From 50788c24731ad91f8eb43848b0983b3a54e15069 Mon Sep 17 00:00:00 2001 From: z3t4s <26795431+z3t4s@users.noreply.github.com> Date: Thu, 1 Feb 2024 17:55:40 +0100 Subject: [PATCH] feat(extra-natives/five): CPortalTracker ScRT CPortalTracker probeLength adjustments via custom ScRT Native Co-authored-by: nikez <1504588+nikez@users.noreply.github.com> Co-authored-by: okqut <38298546+okqut@users.noreply.github.com> --- .../src/InteriorExtraNatives.cpp | 36 +++++++++++++++++ ext/native-decls/SetInteriorProbeLength.md | 39 +++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 ext/native-decls/SetInteriorProbeLength.md diff --git a/code/components/extra-natives-five/src/InteriorExtraNatives.cpp b/code/components/extra-natives-five/src/InteriorExtraNatives.cpp index 910e53df60..473d537d6a 100644 --- a/code/components/extra-natives-five/src/InteriorExtraNatives.cpp +++ b/code/components/extra-natives-five/src/InteriorExtraNatives.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #define DECLARE_ACCESSOR(x) \ decltype(impl.m2060.x)& x() \ @@ -303,8 +304,43 @@ static int GetInteriorRoomIdByHash(CMloModelInfo* arch, int searchHash) return -1; } +static float g_interiorProbeLengthOverride = 0.0; +static bool (*g_CPortalTracker__Probe)(Vector3* pos, CInteriorInst** ppInteriorInstance, int* roomId, Vector3* traceImpactPoint, float traceLength); +bool __fastcall CPortalTracker__Probe(Vector3* pos, CInteriorInst** ppInteriorInstance, int* roomId, Vector3* traceImpactPoint, float traceLength) +{ + // game code has a lot of different special case handlings in CPortalTracker::vft0x8 + // joat('xs_arena_interior') seems to be the case with the longest traceLength override (150.f) + // + if (g_interiorProbeLengthOverride > 0.0f && traceLength < g_interiorProbeLengthOverride) + traceLength = g_interiorProbeLengthOverride; + + return g_CPortalTracker__Probe(pos, ppInteriorInstance, roomId, traceImpactPoint, traceLength); +} + static HookFunction initFunction([]() { + { + auto location = hook::get_pattern("E8 ? ? ? ? 40 8A F8 49 ? ? E8"); + + hook::set_call(&g_CPortalTracker__Probe, location); + hook::call(location, CPortalTracker__Probe); + + fx::ScriptEngine::RegisterNativeHandler("SET_INTERIOR_PROBE_LENGTH", [=](fx::ScriptContext& context) + { + auto length = context.GetArgument(0); + if (std::isnan(length) || std::isinf(length)) + return false; + + g_interiorProbeLengthOverride = std::clamp(length, 0.0f, 150.0f); + return true; + }); + + OnKillNetworkDone.Connect([]() + { + g_interiorProbeLengthOverride = 0.0f; + }); + } + { auto location = hook::get_pattern("BA A1 85 94 52 41 B8 01", 0x34); diff --git a/ext/native-decls/SetInteriorProbeLength.md b/ext/native-decls/SetInteriorProbeLength.md new file mode 100644 index 0000000000..3e428658e4 --- /dev/null +++ b/ext/native-decls/SetInteriorProbeLength.md @@ -0,0 +1,39 @@ +--- +ns: CFX +apiset: client +--- +## SET_INTERIOR_PROBE_LENGTH + +```c +void SET_INTERIOR_PROBE_LENGTH(float probeLength); +``` + +Overwrite the games default CPortalTracker interior detection range. +This fixes potentially unwanted behaviour in the base game and allows you to build custom interiors with larger ceiling heights without running into graphical glitches. + +By default CPortalTracker will probe 4 units downward trying to reach collisions that are part of the interior the entity is in. +If no collision can be found 16 units are used in some circumstances. + +There are 30+ hard coded special cases, only some of them exposed via script (for example `ENABLE_STADIUM_PROBES_THIS_FRAME`). + +This native allows you to extend the probe range up to 150 units which is the same value the game uses for the `xs_arena_interior` + +## Examples + +```lua +RegisterCommand("setInteriorProbeLength", function(src, args, raw) + local probeLength = (tonumber(args[1]) + 0.0) + + print("Extending interior detection probes to: ", probeLength) + SetInteriorProbeLength(probeLength) +end) + +RegisterCommand("resetInteriorProbeLength", function() + print("Resetting interior detection probes to default settings") + SetInteriorProbeLength(0.0) +end) +``` + + +## Parameters +* **probeLength**: The desired probe length (0.0 - 150.0) \ No newline at end of file