Skip to content

Commit

Permalink
feat(extra-natives/five): CPortalTracker ScRT
Browse files Browse the repository at this point in the history
CPortalTracker probeLength adjustments via custom ScRT Native

Co-authored-by: nikez <[email protected]>
Co-authored-by: okqut <[email protected]>
  • Loading branch information
3 people committed Jun 6, 2024
1 parent 79839e4 commit aab84c4
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 0 deletions.
61 changes: 61 additions & 0 deletions code/components/extra-natives-five/src/InteriorExtraNatives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <atPool.h>
#include <DirectXMath.h>
#include <CrossBuildRuntime.h>
#include <GameInit.h>

#define DECLARE_ACCESSOR(x) \
decltype(impl.m2060.x)& x() \
Expand Down Expand Up @@ -303,8 +304,37 @@ static int GetInteriorRoomIdByHash(CMloModelInfo* arch, int searchHash)
return -1;
}

float* g_emitterAudioEntityProbeLength = nullptr;
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 handling in CPortalTracker::vft0x8
// joaat('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<void>("E8 ? ? ? ? 40 8A F8 49 ? ? E8");
hook::set_call(&g_CPortalTracker__Probe, location);
hook::call(location, CPortalTracker__Probe);
}

{
auto location = hook::get_pattern<uint32_t>("33 ED 39 A9 ? ? ? ? 0F 86 ? ? ? ? F3", 18);
g_emitterAudioEntityProbeLength = (float*) hook::AllocateStubMemory(sizeof(float));
hook::put<int32_t>(location, (intptr_t)g_emitterAudioEntityProbeLength - (intptr_t)location - 4);
}

{
auto location = hook::get_pattern<char>("BA A1 85 94 52 41 B8 01", 0x34);

Expand Down Expand Up @@ -389,6 +419,30 @@ static HookFunction initFunction([]()
});
#endif

fx::ScriptEngine::RegisterNativeHandler("SET_INTERIOR_PROBE_LENGTH", [=](fx::ScriptContext& context)
{
auto length = context.GetArgument<float>(0);
if (!std::isfinite(length))
{
return false;
}

g_interiorProbeLengthOverride = std::clamp(length, 0.0f, 150.0f);
return true;
});

fx::ScriptEngine::RegisterNativeHandler("SET_EMITTER_PROBE_LENGTH", [=](fx::ScriptContext& context)
{
auto length = context.GetArgument<float>(0);
if (!std::isfinite(length))
{
return false;
}

*g_emitterAudioEntityProbeLength = std::clamp(length, 20.0f, 150.0f);
return true;
});

fx::ScriptEngine::RegisterNativeHandler("GET_INTERIOR_ROOM_INDEX_BY_HASH", [=](fx::ScriptContext& context)
{
auto interiorId = context.GetArgument<int>(0);
Expand Down Expand Up @@ -865,4 +919,11 @@ static HookFunction initFunction([]()

return true;
});

// Sharing OnKillNetworkDone for probe lengths
OnKillNetworkDone.Connect([]()
{
g_interiorProbeLengthOverride = 0.0f;
*g_emitterAudioEntityProbeLength = 0.0f;
});
});
34 changes: 34 additions & 0 deletions ext/native-decls/SetEmitterProbeLength.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
ns: CFX
apiset: client
game: gta5
---
## SET_EMITTER_PROBE_LENGTH

```c
void SET_EMITTER_PROBE_LENGTH(float probeLength);
```
Allows StaticEmitter's without a linked entity to make use of environment features like occlusion and reverb even if they are located higher than 20.0 units above any static collision inside interiors.
This native allows you to extend the probe range up to 150.0 units.
## Examples
```lua
RegisterCommand("setEmitterProbeLength", function(src, args, raw)
local probeLength = (tonumber(args[1]) + 0.0)
print("Extending emitter probes to: ", probeLength)
SetEmitterProbeLength(probeLength)
end)
RegisterCommand("resetEmitterProbeLength", function()
print("Resetting emitter probes to default settings")
SetEmitterProbeLength(20.0)
end)
```


## Parameters
* **probeLength**: The desired probe length (20.0 - 150.0)
40 changes: 40 additions & 0 deletions ext/native-decls/SetInteriorProbeLength.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
ns: CFX
apiset: client
game: gta5
---
## 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)

0 comments on commit aab84c4

Please sign in to comment.