diff --git a/code/components/extra-natives-rdr3/src/PedNatives.cpp b/code/components/extra-natives-rdr3/src/PedNatives.cpp index 88ef787922..c365b4fd19 100644 --- a/code/components/extra-natives-rdr3/src/PedNatives.cpp +++ b/code/components/extra-natives-rdr3/src/PedNatives.cpp @@ -17,6 +17,80 @@ static hook::cdecl_stub GetPedCreatureComponent([]() return hook::get_call(hook::get_pattern("D1 0F 14 FA E8 ? ? ? ? 48 8B C8 4C 8D 44", 4)); }); +static hook::cdecl_stub GetPedScale([]() +{ + return hook::get_pattern("0F 57 C0 0F 2F 81 ? ? ? ? 0F 82 ? ? ? ? 8B 81"); +}); + +static hook::cdecl_stub 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(reinterpret_cast(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) @@ -54,4 +128,103 @@ static HookFunction hookFunction([]() } } }); + + { + g_pedComponentContainer = hook::get_address(hook::get_pattern("48 8B 05 ? ? ? ? 4C 8B 44 01 ? 48 8B 94 01", 3)); + + g_pedComponentIndexOffset = hook::get_address(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(0)); + if (!ped) + { + context.SetResult(0.0f); + return; + } + + auto pedComponent = GetPedComponent(ped); + if (!pedComponent) + { + context.SetResult(0.0f); + return; + } + + float scale = 0.0f; + if (!IsMetaPed(ped)) + { + uintptr_t corePtr = reinterpret_cast(pedComponent->m_core); + corePtr = (corePtr != 0) ? (corePtr & 0xFFFFFFFFFFFFFFFE) : 0; + if (corePtr) + { + scale = *reinterpret_cast(corePtr + 0x48); + } + } + else + { + uintptr_t physicsPtr = reinterpret_cast(pedComponent->m_physics); + physicsPtr = (physicsPtr != 0) ? (physicsPtr & 0xFFFFFFFFFFFFFFFE) : 0; + if (physicsPtr) + { + scale = GetPedScale(physicsPtr); + } + } + + context.SetResult(scale); + }); + + fx::ScriptEngine::RegisterNativeHandler("GET_PED_WETNESS", [](fx::ScriptContext& context) + { + rage::fwEntity* ped = rage::fwScriptGuid::GetBaseFromGuid(context.GetArgument(0)); + if (!ped) + { + context.SetResult(0.0f); + return; + } + + auto pedComponent = GetPedComponent(ped); + if (!pedComponent) + { + context.SetResult(0.0f); + return; + } + + auto wetness = 0.0f; + uintptr_t graphicPtr = reinterpret_cast(pedComponent->m_graphics); + graphicPtr = (graphicPtr != 0) ? (graphicPtr & 0xFFFFFFFFFFFFFFFE) : 0; + if (graphicPtr) + { + wetness = *reinterpret_cast(graphicPtr + 0x3C); + } + context.SetResult(wetness); + }); + + fx::ScriptEngine::RegisterNativeHandler("GET_PED_WETNESS_HEIGHT", [](fx::ScriptContext& context) + { + rage::fwEntity* ped = rage::fwScriptGuid::GetBaseFromGuid(context.GetArgument(0)); + if (!ped) + { + context.SetResult(0.0f); + return; + } + + auto pedComponent = GetPedComponent(ped); + if (!pedComponent) + { + context.SetResult(0.0f); + return; + } + + auto wetnessHeight = 0.0f; + uintptr_t graphicPtr = reinterpret_cast(pedComponent->m_graphics); + graphicPtr = (graphicPtr != 0) ? (graphicPtr & 0xFFFFFFFFFFFFFFFE) : 0; + if (graphicPtr) + { + wetnessHeight = *reinterpret_cast(graphicPtr + 0x34); + } + context.SetResult(wetnessHeight); + }); + } + }); diff --git a/ext/native-decls/GetPedScale.md b/ext/native-decls/GetPedScale.md new file mode 100644 index 0000000000..01f4749dcb --- /dev/null +++ b/ext/native-decls/GetPedScale.md @@ -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) diff --git a/ext/native-decls/GetPedWetness.md b/ext/native-decls/GetPedWetness.md new file mode 100644 index 0000000000..7234967294 --- /dev/null +++ b/ext/native-decls/GetPedWetness.md @@ -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 \ No newline at end of file diff --git a/ext/native-decls/GetPedWetnessHeight.md b/ext/native-decls/GetPedWetnessHeight.md new file mode 100644 index 0000000000..3cfc289e09 --- /dev/null +++ b/ext/native-decls/GetPedWetnessHeight.md @@ -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 \ No newline at end of file