11
22#include " StdInc.h"
33
4- #include < atArray.h>
54#include < Local.h>
65#include < Hooking.h>
76#include < ScriptEngine.h>
87#include < nutsnbolts.h>
98#include " NativeWrappers.h"
109
10+ class CPedHeadBlendData
11+ {
12+ public:
13+ void * vtable; // +0
14+ DWORD unk_0; // +8
15+ BYTE unk_1; // +12
16+ BYTE unk_2; // +13
17+ char pad_0[26 ]; // +14
18+ float shapeMix; // +40
19+ float skinMix; // +44
20+ float unknownMix; // +48
21+ DWORD unk_3; // +52
22+ float overlayAlpha[13 ]; // +56
23+ float overlayAlphaCopy[13 ]; // +108
24+ float faceFeature[20 ]; // +160
25+ uint8_t overlayColorId[13 ]; // +240
26+ uint8_t overlayHighlightId[13 ]; // +253
27+ uint8_t overlayColorType[13 ]; // +266
28+ uint8_t firstShapeId; // +279
29+ uint8_t secondShapeId; // +280
30+ uint8_t thirdShapeId; // +281
31+ uint8_t firstSkinId; // +282
32+ uint8_t secondSkinId; // +283
33+ uint8_t thirdSkinId; // +284
34+ uint8_t overlayValue[13 ]; // +285
35+ uint8_t palleteColorR0; // +298
36+ uint8_t palleteColorR1; // +299
37+ uint8_t palleteColorR2; // +300
38+ uint8_t palleteColorR3; // +301
39+ uint8_t palleteColorG0; // +302
40+ uint8_t palleteColorG1; // +303
41+ uint8_t palleteColorG2; // +304
42+ uint8_t palleteColorG3; // +305
43+ uint8_t palleteColorB0; // +306
44+ uint8_t palleteColorB1; // +307
45+ uint8_t palleteColorB2; // +308
46+ uint8_t palleteColorB3; // +309
47+ uint16_t eyeColour; // +310
48+ uint8_t hairColour; // +312
49+ uint8_t hairHighlight; // +313
50+ BYTE unk_4; // +314
51+ BYTE unk_5; // +315
52+ BYTE unk_6; // +316
53+ };
54+
55+ static uint64_t * _id_CPedHeadBlendData;
56+
1157static hook::cdecl_stub<uint64_t (void * entity, uint64_t list)> g_extensionList_get ([]()
1258{
1359 return hook::get_pattern (" 41 83 E0 1F 8B 44 81 08 44 0F A3 C0" , -31 );
1460});
1561
62+ static CPedHeadBlendData* GetPedHeadBlendData (fwEntity* entity)
63+ {
64+ auto address = (char *)entity;
65+ if (*(BYTE *)(*(uint64_t *)(address + 32 ) + 646 ) & 2 )
66+ {
67+ auto data = (CPedHeadBlendData*)g_extensionList_get (address + 16 , *_id_CPedHeadBlendData);
68+ return data;
69+ }
70+
71+ return nullptr ;
72+ }
73+
1674static HookFunction initFunction ([]()
1775{
18- uint64_t * _id_CPedHeadBlendData = hook::get_address<uint64_t *>(hook::get_pattern (" 48 39 5E 38 74 1B 8B 15 ? ? ? ? 48 8D 4F 10 E8" , 8 ));
76+ _id_CPedHeadBlendData = hook::get_address<uint64_t *>(hook::get_pattern (" 48 39 5E 38 74 1B 8B 15 ? ? ? ? 48 8D 4F 10 E8" , 8 ));
1977
2078 fx::ScriptEngine::RegisterNativeHandler (" GET_PED_EYE_COLOR" , [=](fx::ScriptContext& context)
2179 {
2280 int result = -1 ;
2381
2482 fwEntity* entity = rage::fwScriptGuid::GetBaseFromGuid (context.GetArgument <int >(0 ));
83+
2584 if (entity && entity->IsOfType <CPed>())
2685 {
27- auto address = (char *)entity + 16 ;
28- auto table = g_extensionList_get (address, *_id_CPedHeadBlendData);
29- if (table)
86+ CPedHeadBlendData* data = GetPedHeadBlendData (entity);
87+ if (data != nullptr )
3088 {
31- result = *( uint8_t *)(table + 310 ) ;
89+ result = data-> eyeColour ;
3290 }
3391 }
3492
@@ -42,16 +100,12 @@ static HookFunction initFunction([]()
42100 fwEntity* entity = rage::fwScriptGuid::GetBaseFromGuid (context.GetArgument <int >(0 ));
43101 int index = context.GetArgument <int >(1 );
44102
45- if (index < 20 && entity && entity->IsOfType <CPed>())
103+ if (index >= 0 && index < 20 && entity && entity->IsOfType <CPed>())
46104 {
47- auto address = ( char *) entity;
48- if (*( BYTE *)(*( uint64_t *)(address + 32 ) + 646 ) & 2 )
105+ CPedHeadBlendData* data = GetPedHeadBlendData ( entity) ;
106+ if (data != nullptr )
49107 {
50- auto table = g_extensionList_get (address + 16 , *_id_CPedHeadBlendData);
51- if (table)
52- {
53- result = *(float *)(table + 4 * index + 160 );
54- }
108+ result = data->faceFeature [index];
55109 }
56110 }
57111
@@ -65,22 +119,18 @@ static HookFunction initFunction([]()
65119 fwEntity* entity = rage::fwScriptGuid::GetBaseFromGuid (context.GetArgument <int >(0 ));
66120 int index = context.GetArgument <int >(1 );
67121
68- if (entity && entity->IsOfType <CPed>())
122+ if (index >= 0 && index <= 13 && entity && entity->IsOfType <CPed>())
69123 {
70- auto address = ( char *) entity;
71- if (*( BYTE *)(*( uint64_t *)(address + 32 ) + 646 ) & 2 )
124+ CPedHeadBlendData* data = GetPedHeadBlendData ( entity) ;
125+ if (data != nullptr )
72126 {
73- auto table = g_extensionList_get (address + 16 , *_id_CPedHeadBlendData);
74- if (table)
75- {
76- *context.GetArgument <int *>(2 ) = *(uint8_t *)(table + 285 + index); // overlay value
77- *context.GetArgument <int *>(3 ) = *(uint8_t *)(table + 266 + index); // colour type
78- *context.GetArgument <int *>(4 ) = *(uint8_t *)(table + 240 + index); // main colour
79- *context.GetArgument <int *>(5 ) = *(uint8_t *)(table + 253 + index); // secondary colour
80- *context.GetArgument <float *>(6 ) = *(float *)(table + 56 + 4 * index); // overlay alpha
81-
82- result = true ;
83- }
127+ *context.GetArgument <int *>(2 ) = data->overlayValue [index];
128+ *context.GetArgument <int *>(3 ) = data->overlayColorType [index];
129+ *context.GetArgument <int *>(4 ) = data->overlayColorId [index];
130+ *context.GetArgument <int *>(5 ) = data->overlayHighlightId [index];
131+ *context.GetArgument <float *>(6 ) = data->overlayAlpha [index];
132+
133+ result = true ;
84134 }
85135 }
86136
@@ -94,11 +144,10 @@ static HookFunction initFunction([]()
94144 fwEntity* entity = rage::fwScriptGuid::GetBaseFromGuid (context.GetArgument <int >(0 ));
95145 if (entity && entity->IsOfType <CPed>())
96146 {
97- auto address = (char *)entity + 16 ;
98- auto table = g_extensionList_get (address, *_id_CPedHeadBlendData);
99- if (table)
147+ CPedHeadBlendData* data = GetPedHeadBlendData (entity);
148+ if (data != nullptr )
100149 {
101- result = *( uint8_t *)(table + 312 ) ;
150+ result = data-> hairColour ;
102151 }
103152 }
104153
@@ -112,11 +161,10 @@ static HookFunction initFunction([]()
112161
113162 if (entity && entity->IsOfType <CPed>())
114163 {
115- auto address = (char *)entity + 16 ;
116- auto table = g_extensionList_get (address, *_id_CPedHeadBlendData);
117- if (table)
164+ CPedHeadBlendData* data = GetPedHeadBlendData (entity);
165+ if (data != nullptr )
118166 {
119- result = *( uint8_t *)(table + 313 ) ;
167+ result = data-> hairHighlight ;
120168 }
121169 }
122170
0 commit comments