Skip to content

Commit 894e6ec

Browse files
committed
feat(extra-natives-rdr3): Add GET_VEHICLE_ADDITIONAL_PROP_SET_HASH native
1 parent eaa1578 commit 894e6ec

File tree

7 files changed

+128
-50
lines changed

7 files changed

+128
-50
lines changed

code/components/extra-natives-five/src/PoolTraversalNatives.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#include <Pool.h>
99

1010
#ifdef IS_RDR3
11-
#include <NativeWrappers.h>
11+
#include <EntitySystem.h>
1212
#endif
1313

1414
#include <Local.h>
Lines changed: 1 addition & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1 @@
1-
#pragma once
2-
3-
#include "StdInc.h"
4-
5-
class fwEntity
6-
{
7-
public:
8-
virtual ~fwEntity() = 0;
9-
10-
virtual bool IsOfType(uint32_t hash) = 0;
11-
12-
template<typename T>
13-
bool IsOfType()
14-
{
15-
return reinterpret_cast<T*>(this->IsOfType(HashString(boost::typeindex::type_id<T>().pretty_name().substr(6).c_str())));
16-
}
17-
18-
inline void* GetNetObject() const
19-
{
20-
static_assert(offsetof(fwEntity, m_netObject) == 224, "wrong GetNetObject");
21-
return m_netObject;
22-
}
23-
24-
private:
25-
char m_pad[216];
26-
void* m_netObject;
27-
};
28-
29-
class CPickup : public fwEntity
30-
{
31-
32-
};
33-
34-
class CObject : public fwEntity
35-
{
36-
37-
};
38-
39-
class CVehicle : public fwEntity
40-
{
41-
42-
};
43-
44-
class CPed : public fwEntity
45-
{
46-
47-
};
1+
#pragma once

code/components/extra-natives-rdr3/src/DoorExtraNatives.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*/
77

88
#include "StdInc.h"
9-
#include "NativeWrappers.h"
9+
#include "EntitySystem.h"
1010

1111
#include <ScriptEngine.h>
1212
#include <ScriptSerialization.h>

code/components/extra-natives-rdr3/src/VehicleNatives.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,52 @@
11
#include <StdInc.h>
22
#include <ScriptEngine.h>
3+
#include <EntitySystem.h>
34

45
#include <Hooking.h>
6+
#include <Pool.h>
57

68
#include <GameInit.h>
79

10+
static fwEntity* getAndCheckVehicle(fx::ScriptContext& context, std::string_view name)
11+
{
12+
auto traceFn = [name](std::string_view msg)
13+
{
14+
trace("%s: %s\n", name, msg);
15+
};
16+
17+
if (context.GetArgumentCount() < 1)
18+
{
19+
traceFn("At least one argument must be passed");
20+
return nullptr;
21+
}
22+
23+
fwEntity* vehicle = rage::fwScriptGuid::GetBaseFromGuid(context.GetArgument<int>(0));
24+
25+
if (!vehicle)
26+
{
27+
traceFn("No such entity");
28+
return nullptr;
29+
}
30+
31+
if (!vehicle->IsOfType<CVehicle>())
32+
{
33+
traceFn("Can not read from an entity that is not a vehicle or draft vehicle");
34+
return nullptr;
35+
}
36+
37+
return vehicle;
38+
}
39+
40+
static hook::FlexStruct* getAndCheckVehicleFlexStruct(fx::ScriptContext& context, std::string_view name)
41+
{
42+
fwEntity* vehicle = getAndCheckVehicle(context, name);
43+
if (!vehicle)
44+
{
45+
return nullptr;
46+
}
47+
return reinterpret_cast<hook::FlexStruct*>(vehicle);
48+
}
49+
850
static bool g_ignoreVehicleOwnershipChecksForStowing = false;
951

1052
static bool (*g_origIsAllowedToInteractWithHuntingWagon)(void*, bool);
@@ -16,6 +58,24 @@ static bool IsAllowedToInteractWithHuntingWagon(void* entity, bool ownershipChec
1658

1759
static bool (*origGetPedOfPlayerOwnerOfNetworkObject)(void* pNetObj);
1860

61+
static InitFunction initFunction([]()
62+
{
63+
64+
fx::ScriptEngine::RegisterNativeHandler("GET_VEHICLE_ADDITIONAL_PROP_SET_HASH", [](fx::ScriptContext& context)
65+
{
66+
if (hook::FlexStruct* flexStruct = getAndCheckVehicleFlexStruct(context, "GET_VEHICLE_ADDITIONAL_PROP_SET_HASH"))
67+
{
68+
uint32_t propSetHash = flexStruct->Get<uint32_t>(0xD90);
69+
context.SetResult(propSetHash);
70+
}
71+
else
72+
{
73+
context.SetResult(0);
74+
}
75+
});
76+
77+
});
78+
1979
static HookFunction hookFunction([]()
2080
{
2181
{

code/components/gta-streaming-rdr3/include/EntitySystem.h

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#pragma once
22

33
#include <directxmath.h>
4+
#include <boost/type_index/ctti_type_index.hpp>
5+
#include "StdInc.h"
46

57
#ifdef COMPILING_GTA_STREAMING_RDR3
68
#define STREAMING_EXPORT DLL_EXPORT
@@ -99,7 +101,27 @@ class STREAMING_EXPORT fwEntity : public rage::fwRefAwareBase
99101
public:
100102
virtual ~fwEntity() = default;
101103

102-
virtual bool IsOfType(uint32_t hash) = 0;
104+
inline bool IsOfType(uint32_t hash) {
105+
return IsOfTypeH(hash);
106+
}
107+
108+
template<typename T>
109+
bool IsOfType()
110+
{
111+
auto typeName = std::string_view{
112+
boost::typeindex::ctti_type_index::type_id<T>().raw_name()
113+
};
114+
115+
// Parse mangled name like "class CVehicle>::n(void) noexcept"
116+
auto className = typeName.substr(6);
117+
size_t endPos = className.find('>');
118+
if (endPos != std::string_view::npos) {
119+
className = className.substr(0, endPos);
120+
}
121+
122+
auto typeHash = HashString(className);
123+
return this->IsOfType(typeHash);
124+
}
103125

104126
private:
105127
template<typename TMember>
@@ -129,6 +151,9 @@ class STREAMING_EXPORT fwEntity : public rage::fwRefAwareBase
129151
void** vtbl = *(void***)(this); \
130152
return (this->*(get_member<TFn>(vtbl[(offset / 8)])))(__VA_ARGS__);
131153

154+
private:
155+
bool IsOfTypeH(uint32_t hash);
156+
132157
public:
133158
inline float GetRadius()
134159
{

code/components/gta-streaming-rdr3/src/EntitySystem.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,9 @@ fwArchetype* rage::fwArchetypeManager::GetArchetypeFromHashKey(uint32_t hash, fw
2222
{
2323
return getArchetype(hash, id);
2424
}
25+
26+
bool fwEntity::IsOfTypeH(uint32_t hash)
27+
{
28+
hook::FlexStruct* flexStruct = reinterpret_cast<hook::FlexStruct*>(this);
29+
return flexStruct->CallVirtual<bool, const uint32_t&>(sizeof(void*), hash);
30+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
ns: CFX
3+
apiset: client
4+
game: rdr3
5+
---
6+
## GET_VEHICLE_ADDITIONAL_PROP_SET_HASH
7+
8+
```c
9+
int GET_VEHICLE_ADDITIONAL_PROP_SET_HASH(Vehicle vehicle);
10+
```
11+
12+
Gets the additional prop set hash for the specified vehicle.
13+
14+
## Parameters
15+
* **vehicle**: The vehicle's entity handle.
16+
17+
## Return value
18+
Returns the additional prop set hash, or 0 if the vehicle is invalid.
19+
20+
## Examples
21+
```lua
22+
local vehicle = GetVehiclePedIsIn(PlayerPedId(), false)
23+
if vehicle ~= 0 then
24+
local propSetHash = GetVehicleAdditionalPropSetHash(vehicle)
25+
print("Additional Prop Set Hash: " .. propSetHash)
26+
end
27+
```
28+
29+
## Notes
30+
- The vehicle must be a valid entity and must be of type CVehicle
31+
- Returns 0 if the vehicle handle is invalid or the entity is not a vehicle
32+
- The hash value can be used to identify specific prop sets applied to vehicles
33+

0 commit comments

Comments
 (0)