From 56e512be145bf260f66015df62dbe36a6be94d1d Mon Sep 17 00:00:00 2001 From: Daniel GP <96537843+DaniGP17@users.noreply.github.com> Date: Thu, 30 Jan 2025 20:53:58 +0100 Subject: [PATCH] feat(extra-natives-five): add DrawCorona native --- .../extra-natives-five/src/VfxNatives.cpp | 41 ++++++++++++++ ext/native-decls/DrawCorona.md | 53 +++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 ext/native-decls/DrawCorona.md diff --git a/code/components/extra-natives-five/src/VfxNatives.cpp b/code/components/extra-natives-five/src/VfxNatives.cpp index 8ccb13660d..4c45582a95 100644 --- a/code/components/extra-natives-five/src/VfxNatives.cpp +++ b/code/components/extra-natives-five/src/VfxNatives.cpp @@ -24,6 +24,13 @@ namespace rage using Vec4V = DirectX::XMVECTOR; } +static hook::cdecl_stub addLightCorona([]() +{ + return hook::get_call(hook::get_pattern("F3 0F 11 44 24 28 F3 0F 11 7C 24 20 E8 ? ? ? ? E8", 12)); +}); + +static void* g_coronas; + static hook::cdecl_stub _getExhaustMatrix([]() { return hook::get_pattern("4D 8B E1 49 8B F0 48 8B D9 44 0F 29 48", -0x33); @@ -92,6 +99,10 @@ static HookFunction hookFunction([]() { g_vfxNitrousOverride.Reset(); }); + + { + g_coronas = hook::get_address(hook::get_pattern("F3 0F 11 44 24 28 F3 0F 11 7C 24 20 E8 ? ? ? ? E8", -4)); + } }); static InitFunction initFunction([]() @@ -110,6 +121,36 @@ static InitFunction initFunction([]() } }); + fx::ScriptEngine::RegisterNativeHandler("DRAW_CORONA", [](fx::ScriptContext& context) + { + float x = context.GetArgument(0); + float y = context.GetArgument(1); + float z = context.GetArgument(2); + float size = context.GetArgument(3); + + uint32_t color = ( + (std::clamp(context.GetArgument(4), 0, 255) << 24) | + (std::clamp(context.GetArgument(5), 0, 255) << 16) | + (std::clamp(context.GetArgument(6), 0, 255) << 8) | + (std::clamp(context.GetArgument(7), 0, 255) << 0) + ); + + float intensity = context.GetArgument(8); + float zBias = std::clamp(context.GetArgument(9), 0.0f, 1.0f); + float directionX = context.GetArgument(10); + float directionY = context.GetArgument(11); + float directionZ = context.GetArgument(12); + float viewThreshold = context.GetArgument(13); + float innerAngle = context.GetArgument(14); + float outerAngle = context.GetArgument(15); + uint16_t flags = context.GetArgument(16); + + Vector3 position = { x, y, z }; + Vector3 direction = { directionX, directionY, directionZ }; + + addLightCorona(g_coronas, &position, size, color, intensity, zBias, &direction, viewThreshold, innerAngle, outerAngle, flags); + }); + // GH-2003: Backport b3095 vehicle exhaust bone getters to earlier builds if (!xbr::IsGameBuildOrGreater<3095>()) { diff --git a/ext/native-decls/DrawCorona.md b/ext/native-decls/DrawCorona.md new file mode 100644 index 0000000000..aef876ed7a --- /dev/null +++ b/ext/native-decls/DrawCorona.md @@ -0,0 +1,53 @@ +--- +ns: CFX +apiset: client +game: gta5 +--- +## DRAW_CORONA + +```c +void DRAW_CORONA(float posX, float posY, float posZ, float size, int red, int green, int blue, int alpha, float intensity, float zBias, float dirX, float dirY, float dirZ, float viewThreshold, float innerAngle, float outerAngle, int flags); +``` + +Allows drawing advanced light effects, known as coronas, which support flares, volumetric lighting, and customizable glow properties. + +## Parameters +* **posX**: The X position of the corona origin. +* **posY**: The Y position of the corona origin. +* **posZ**: The Z position of the corona origin. +* **size**: The size of the corona. +* **red**: The red component of the marker color, on a scale from 0-255. +* **green**: The green component of the marker color, on a scale from 0-255. +* **blue**: The blue component of the marker color, on a scale from 0-255. +* **alpha**: The alpha component of the marker color, on a scale from 0-255. +* **intensity**: The intensity of the corona. +* **zBias**: zBias slightly shifts the depth of surfaces to make sure they don’t overlap or cause visual glitches when they are very close together. The zBias value are usually in the range of 0.0 to 1.0. +* **dirX**: The X direction of the corona. +* **dirY**: The Y direction of the corona. +* **dirZ**: The Z direction of the corona. +* **viewThreshold**: The view threshold is to determine the fading of the corona based on the distance. +* **innerAngle**: The inner angle of the corona. +* **outerAngle**: The outer angle of the corona. +* **flags**: The corona flags. + +```cpp +enum eCoronaFlags +{ + CF_HAS_DIRECTION = 2, // Only render the corona in the direction of dirX, dirY, dirZ + CF_NO_RENDER_UNDERWATER = 4, // Disable rendering of the corona underwater + CF_NO_RENDER_UNDERGROUND = 8, // This keep drawing the corona in underground zones (like tunnels) + CF_NO_RENDER_FLARE = 16, // Disable rendering of the corona flare +} +``` + +## Examples + +```lua +local pedCoords = GetEntityCoords(PlayerPedId()) +Citizen.CreateThread(function() + while true do + DrawCorona(pedCoords.x, pedCoords.y, pedCoords.z, 5.0, 255, 255, 255, 255, 4.0, 0.2, pedCoords.x, pedCoords.y, pedCoords.z, 1.0, 0.0, 90.0, 2) + Wait(0) + end +end) +```