Skip to content

Commit 65fa9ae

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

File tree

7 files changed

+130
-50
lines changed

7 files changed

+130
-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: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,54 @@
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+
template<typename T>
11+
inline static T readValue(fwEntity* ptr, int offset)
12+
{
13+
return (T)*(T*)((char*)ptr + offset);
14+
}
15+
16+
template<typename T>
17+
inline static void writeValue(fwEntity* ptr, int offset, T value)
18+
{
19+
*(T*)((char*)ptr + offset) = value;
20+
}
21+
22+
static fwEntity* getAndCheckVehicle(fx::ScriptContext& context, std::string_view name)
23+
{
24+
auto traceFn = [name](std::string_view msg)
25+
{
26+
trace("%s: %s\n", name, msg);
27+
};
28+
29+
if (context.GetArgumentCount() < 1)
30+
{
31+
traceFn("At least one argument must be passed");
32+
return nullptr;
33+
}
34+
35+
fwEntity* vehicle = rage::fwScriptGuid::GetBaseFromGuid(context.GetArgument<int>(0));
36+
37+
if (!vehicle)
38+
{
39+
traceFn("No such entity");
40+
return nullptr;
41+
}
42+
43+
if (!vehicle->IsOfType<CVehicle>())
44+
{
45+
traceFn("Can not read from an entity that is not a vehicle or draft vehicle");
46+
return nullptr;
47+
}
48+
49+
return vehicle;
50+
}
51+
852
static bool g_ignoreVehicleOwnershipChecksForStowing = false;
953

1054
static bool (*g_origIsAllowedToInteractWithHuntingWagon)(void*, bool);
@@ -16,6 +60,24 @@ static bool IsAllowedToInteractWithHuntingWagon(void* entity, bool ownershipChec
1660

1761
static bool (*origGetPedOfPlayerOwnerOfNetworkObject)(void* pNetObj);
1862

63+
static InitFunction initFunction([]()
64+
{
65+
66+
fx::ScriptEngine::RegisterNativeHandler("GET_VEHICLE_ADDITIONAL_PROP_SET_HASH", [](fx::ScriptContext& context)
67+
{
68+
if (fwEntity* vehicle = getAndCheckVehicle(context, "GET_VEHICLE_ADDITIONAL_PROP_SET_HASH"))
69+
{
70+
uint32_t propSetHash = readValue<uint32_t>(vehicle, 0xD90);
71+
context.SetResult(propSetHash);
72+
}
73+
else
74+
{
75+
context.SetResult(0);
76+
}
77+
});
78+
79+
});
80+
1981
static HookFunction hookFunction([]()
2082
{
2183
{

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+
void** vtbl = *(void***)this;
29+
return ((bool(*)(fwEntity*, const uint32_t&)) vtbl[1])(this, 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)