Skip to content

feat(extra-natives-rdr3): add GET_PED_SCALE GET_PED_WETNESS GET_PED_WETNESS_HEIGHT for RedM #3325

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 173 additions & 0 deletions code/components/extra-natives-rdr3/src/PedNatives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,80 @@ static hook::cdecl_stub<void*(rage::fwEntity*)> GetPedCreatureComponent([]()
return hook::get_call(hook::get_pattern("D1 0F 14 FA E8 ? ? ? ? 48 8B C8 4C 8D 44", 4));
});

static hook::cdecl_stub<float(uintptr_t)> GetPedScale([]()
{
return hook::get_pattern("0F 57 C0 0F 2F 81 ? ? ? ? 0F 82 ? ? ? ? 8B 81");
});

static hook::cdecl_stub<bool(rage::fwEntity*)> IsMetaPed([]()
{
return hook::get_pattern("40 53 48 83 EC ? 8B 15 ? ? ? ? 48 8B D9 48 83 C1 ? E8 ? ? ? ? 33 D2");
});

struct PedComponentsContainer
{
void* m_animal;
void* m_animalAudio;
void* m_animalEars;
void* m_animalTail;
void* m_animation;
void* m_attribute;
void* m_audio;
void* m_avoidance;
void* m_breathe;
void* m_cloth;
void* m_core;
void* m_creature;
void* m_distraction;
void* m_driving;
void* m_dummy;
void* m_event;
void* m_facial;
void* m_footstep;
void* m_gameplay;
void* m_graphics;
void* m_health;
void* m_horse;
void* m_humanAudio;
void* m_intelligence;
void* m_inventory;
void* m_lookAt;
void* m_motion;
void* m_motivation;
void* m_physics;
void* m_projDecal;
void* m_player;
void* m_ragdoll;
void* m_scriptData;
void* m_stamina;
void* m_targetting;
void* m_threatResponse;
void* m_transport;
void* m_transportUser;
void* m_vfxComponent;
void* m_visibility;
void* m_weapon;
};


static PedComponentsContainer** g_pedComponentContainer;

static int32_t* g_pedComponentIndexOffset;

static PedComponentsContainer* GetPedComponent(rage::fwEntity* ped)
{
if (!ped || !g_pedComponentContainer || !g_pedComponentIndexOffset)
return nullptr;

uint32_t entityComponents = *reinterpret_cast<uint32_t*>(reinterpret_cast<uintptr_t>(ped) + 0x9C);
int32_t componentIndex = (entityComponents & 0x1FFFF) - *g_pedComponentIndexOffset;

if (componentIndex < 0)
return nullptr;

return &(*g_pedComponentContainer)[componentIndex];
}

static HookFunction hookFunction([]()
{
fx::ScriptEngine::RegisterNativeHandler("GET_PED_BONE_MATRIX", [](fx::ScriptContext& context)
Expand Down Expand Up @@ -54,4 +128,103 @@ static HookFunction hookFunction([]()
}
}
});

{
g_pedComponentContainer = hook::get_address<PedComponentsContainer**>(hook::get_pattern("48 8B 05 ? ? ? ? 4C 8B 44 01 ? 48 8B 94 01", 3));

g_pedComponentIndexOffset = hook::get_address<int32_t*>(hook::get_pattern("2B 0D ? ? ? ? 84 C0 8B C1 74 ? 48 69 C8 ? ? ? ? 0F 28 CE", 2));


fx::ScriptEngine::RegisterNativeHandler("GET_PED_SCALE", [](fx::ScriptContext& context)
{
rage::fwEntity* ped = rage::fwScriptGuid::GetBaseFromGuid(context.GetArgument<int>(0));
if (!ped)
{
context.SetResult<float>(0.0f);
return;
}

auto pedComponent = GetPedComponent(ped);
if (!pedComponent)
{
context.SetResult<float>(0.0f);
return;
}

float scale = 0.0f;
if (!IsMetaPed(ped))
{
uintptr_t corePtr = reinterpret_cast<uintptr_t>(pedComponent->m_core);
corePtr = (corePtr != 0) ? (corePtr & 0xFFFFFFFFFFFFFFFE) : 0;
if (corePtr)
{
scale = *reinterpret_cast<float*>(corePtr + 0x48);
}
}
else
{
uintptr_t physicsPtr = reinterpret_cast<uintptr_t>(pedComponent->m_physics);
physicsPtr = (physicsPtr != 0) ? (physicsPtr & 0xFFFFFFFFFFFFFFFE) : 0;
if (physicsPtr)
{
scale = GetPedScale(physicsPtr);
}
}

context.SetResult<float>(scale);
});

fx::ScriptEngine::RegisterNativeHandler("GET_PED_WETNESS", [](fx::ScriptContext& context)
{
rage::fwEntity* ped = rage::fwScriptGuid::GetBaseFromGuid(context.GetArgument<int>(0));
if (!ped)
{
context.SetResult<float>(0.0f);
return;
}

auto pedComponent = GetPedComponent(ped);
if (!pedComponent)
{
context.SetResult<float>(0.0f);
return;
}

auto wetness = 0.0f;
uintptr_t graphicPtr = reinterpret_cast<uintptr_t>(pedComponent->m_graphics);
graphicPtr = (graphicPtr != 0) ? (graphicPtr & 0xFFFFFFFFFFFFFFFE) : 0;
if (graphicPtr)
{
wetness = *reinterpret_cast<float*>(graphicPtr + 0x3C);
}
context.SetResult<float>(wetness);
});

fx::ScriptEngine::RegisterNativeHandler("GET_PED_WETNESS_HEIGHT", [](fx::ScriptContext& context)
{
rage::fwEntity* ped = rage::fwScriptGuid::GetBaseFromGuid(context.GetArgument<int>(0));
if (!ped)
{
context.SetResult<float>(0.0f);
return;
}

auto pedComponent = GetPedComponent(ped);
if (!pedComponent)
{
context.SetResult<float>(0.0f);
return;
}

auto wetnessHeight = 0.0f;
uintptr_t graphicPtr = reinterpret_cast<uintptr_t>(pedComponent->m_graphics);
graphicPtr = (graphicPtr != 0) ? (graphicPtr & 0xFFFFFFFFFFFFFFFE) : 0;
if (graphicPtr)
{
wetnessHeight = *reinterpret_cast<float*>(graphicPtr + 0x34);
}
context.SetResult<float>(wetnessHeight);
});
}

});
16 changes: 16 additions & 0 deletions ext/native-decls/GetPedScale.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
ns: CFX
apiset: client
game: rdr3
---
## GET_PED_SCALE

```c
float GET_PED_SCALE(Ped ped);
```

## Parameters
* **ped**: The target ped

## Return value
Returns scale of ped set by [SET_PED_SCALE](#_0x25ACFC650B65C538)
16 changes: 16 additions & 0 deletions ext/native-decls/GetPedWetness.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
ns: CFX
apiset: client
game: rdr3
---
## GET_PED_WETNESS

```c
float GET_PED_WETNESS(Ped ped);
```

## Parameters
* **ped**: The target ped

## Return value
Returns current ped wetness level
16 changes: 16 additions & 0 deletions ext/native-decls/GetPedWetnessHeight.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
ns: CFX
apiset: client
game: rdr3
---
## GET_PED_WETNESS_HEIGHT

```c
float GET_PED_WETNESS_HEIGHT(Ped ped);
```

## Parameters
* **ped**: The target ped

## Return value
Returns current ped wetness height level
Loading