Skip to content

Commit 81218c7

Browse files
authored
Fix setVehicleDirtLevel (#3837)
1 parent d6152b8 commit 81218c7

File tree

4 files changed

+164
-37
lines changed

4 files changed

+164
-37
lines changed

Client/game_sa/CModelInfoSA.h

Lines changed: 55 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <game/Common.h>
1515
#include <game/CModelInfo.h>
1616
#include "CRenderWareSA.h"
17+
#include "game/RenderWare.h"
1718

1819
class CPedModelInfoSA;
1920
class CPedModelInfoSAInterface;
@@ -231,6 +232,11 @@ class CBaseModelInfoSAInterface
231232
// +726 = Word array as referenced in CVehicleModelInfo::GetVehicleUpgrade(int)
232233
// +762 = Array of WORD containing something relative to paintjobs
233234
// +772 = Anim file index
235+
236+
void Shutdown()
237+
{
238+
((void(*)())VFTBL->Shutdown)();
239+
}
234240
};
235241
static_assert(sizeof(CBaseModelInfoSAInterface) == 0x20, "Invalid size for CBaseModelInfoSAInterface");
236242

@@ -259,53 +265,66 @@ class CTimeModelInfoSAInterface : public CBaseModelInfoSAInterface
259265
CTimeInfoSAInterface timeInfo;
260266
};
261267

268+
class CVehicleModelUpgradePosnDesc
269+
{
270+
CVector m_vPosition;
271+
RtQuat m_vRotation;
272+
int m_iParentId;
273+
};
274+
262275
class CVehicleModelVisualInfoSAInterface // Not sure about this name. If somebody knows more, please change
263276
{
264277
public:
265-
CVector vecDummies[15];
266-
char m_sUpgrade[18];
278+
CVector vecDummies[15];
279+
CVehicleModelUpgradePosnDesc m_sUpgrade[18];
280+
RpAtomic* m_pExtra[6];
281+
std::uint8_t m_numExtras;
282+
std::uint8_t _pad[3];
283+
int m_maskComponentDamagable;
267284
};
268285

269-
class CVehicleModelInfoSAInterface : public CBaseModelInfoSAInterface
286+
class CVehicleModelInfoSAInterface : public CClumpModelInfoSAInterface
270287
{
271288
public:
272-
uint32 pad1; // +32
273-
RpMaterial* pPlateMaterial; // +36
289+
RpMaterial* pPlateMaterial;
274290
char plateText[8];
275-
char pad[2];
291+
std::uint8_t field_30;
292+
std::uint8_t plateType;
276293
char gameName[8];
277-
char pad2[2];
278-
unsigned int uiVehicleType;
294+
std::uint8_t field_3A[2];
295+
std::uint32_t vehicleType;
279296
float fWheelSizeFront;
280297
float fWheelSizeRear;
281-
short sWheelModel;
282-
short sHandlingID;
283-
byte ucNumDoors;
284-
byte ucVehicleList;
285-
byte ucVehicleFlags;
286-
byte ucWheelUpgradeClass;
287-
byte ucTimesUsed;
288-
short sVehFrequency;
289-
unsigned int uiComponentRules;
290-
float fSteeringAngle;
291-
CVehicleModelVisualInfoSAInterface* pVisualInfo; // +92
292-
char pad3[464];
293-
char pDirtMaterial[64]; // *RwMaterial
294-
char pad4[64];
295-
char primColors[8];
296-
char secondColors[8];
297-
char treeColors[8];
298-
char fourColors[8];
299-
unsigned char ucNumOfColorVariations;
300-
unsigned char ucLastColorVariation;
301-
unsigned char ucPrimColor;
302-
unsigned char ucSecColor;
303-
unsigned char ucTertColor;
304-
unsigned char ucQuatColor;
305-
char upgrades[36];
306-
char anRemapTXDs[8];
307-
char pad5[2];
308-
char pAnimBlock[4];
298+
std::int16_t wheelModelID;
299+
std::int16_t handlingID;
300+
std::uint8_t numDoors;
301+
std::uint8_t vehicleClass;
302+
std::uint8_t vehicleFlags;
303+
std::uint8_t wheelUpgradeClass;
304+
std::uint8_t timesUsed;
305+
std::uint8_t field_51;
306+
std::int16_t vehFrequency;
307+
std::uint32_t componentRules;
308+
float bikeSteeringAngle;
309+
CVehicleModelVisualInfoSAInterface* pVisualInfo; // vehicleStruct
310+
std::uint8_t field_60[464];
311+
RpMaterial** m_dirtMaterials;
312+
std::size_t m_numDirtMaterials;
313+
RpMaterial* m_staticDirtMaterials[30];
314+
std::uint8_t primColors[8];
315+
std::uint8_t secondColors[8];
316+
std::uint8_t treeColors[8];
317+
std::uint8_t fourColors[8];
318+
std::uint8_t numOfColorVariations;
319+
std::uint8_t lastColorVariation;
320+
std::uint8_t primColor;
321+
std::uint8_t secColor;
322+
std::uint8_t tertColor;
323+
std::uint8_t quatColor;
324+
std::uint8_t upgrades[36];
325+
std::uint8_t anRemapTXDs[8];
326+
std::uint8_t field_302[2];
327+
void* pAnimBlock; // CAnimBlock*
309328
};
310329

311330
class CModelInfoSA : public CModelInfo

Client/game_sa/gamesa_renderware.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ typedef RpHAnimHierarchy*(__cdecl* GetAnimHierarchyFromSkinClump_t)(RpClump*);
105105
typedef int(__cdecl* RpHAnimIDGetIndex_t)(RpHAnimHierarchy*, int);
106106
typedef RwMatrix*(__cdecl* RpHAnimHierarchyGetMatrixArray_t)(RpHAnimHierarchy*);
107107
typedef RtQuat*(__cdecl* RtQuatRotate_t)(RtQuat* quat, const RwV3d* axis, float angle, RwOpCombineType combineOp);
108+
typedef RpGeometry*(__cdecl* RpGeometryForAllMaterials_t)(RpGeometry* geom, void* callback, void* data);
108109

109110
/*****************************************************************************/
110111
/** Renderware function mappings **/
@@ -195,6 +196,7 @@ RWFUNC(GetAnimHierarchyFromSkinClump_t GetAnimHierarchyFromSkinClump, (GetAnimHi
195196
RWFUNC(RpHAnimIDGetIndex_t RpHAnimIDGetIndex, (RpHAnimIDGetIndex_t)0xDEAD)
196197
RWFUNC(RpHAnimHierarchyGetMatrixArray_t RpHAnimHierarchyGetMatrixArray, (RpHAnimHierarchyGetMatrixArray_t)0xDEAD)
197198
RWFUNC(RtQuatRotate_t RtQuatRotate, (RtQuatRotate_t)0xDEAD)
199+
RWFUNC(RpGeometryForAllMaterials_t RpGeometryForAllMaterials, (RpGeometryForAllMaterials_t)0xDEAD)
198200

199201
/*****************************************************************************/
200202
/** GTA function definitions and mappings **/

Client/game_sa/gamesa_renderware.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ void InitRwFunctions()
8989
RpHAnimIDGetIndex = (RpHAnimIDGetIndex_t)0x7C51A0;
9090
RpHAnimHierarchyGetMatrixArray = (RpHAnimHierarchyGetMatrixArray_t)0x7C5120;
9191
RtQuatRotate = (RtQuatRotate_t)0x7EB7C0;
92-
92+
RpGeometryForAllMaterials = (RpGeometryForAllMaterials_t)0x74C790;
93+
9394
SetTextureDict = (SetTextureDict_t)0x007319C0;
9495
LoadClumpFile = (LoadClumpFile_t)0x005371F0;
9596
LoadModel = (LoadModel_t)0x0040C6B0;

Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@
99
*****************************************************************************/
1010

1111
#include "StdInc.h"
12+
#include "..\game_sa\gamesa_renderware.h"
13+
14+
#define FUNC_CBaseModelInfo_Shutdown 0x4C4D50
15+
#define IN_PLACE_BUFFER_DIRT_SIZE 30
16+
17+
static RwTexture** const ms_aDirtTextures = (RwTexture**)0xC02BD0;
1218

1319
static bool __fastcall AreVehicleDoorsUndamageable(CVehicleSAInterface* vehicle)
1420
{
@@ -107,6 +113,100 @@ static void _declspec(naked) HOOK_CAEVehicleAudioEntity__Initialise()
107113
}
108114
}
109115

116+
static void __fastcall CVehicleModelInfo_Shutdown(CVehicleModelInfoSAInterface* mi)
117+
{
118+
if (!mi)
119+
return;
120+
121+
mi->Shutdown();
122+
123+
delete[] mi->m_dirtMaterials;
124+
mi->m_dirtMaterials = nullptr;
125+
}
126+
127+
static void SetDirtTextures(CVehicleModelInfoSAInterface* mi, std::uint32_t level)
128+
{
129+
RpMaterial** materials = mi->m_numDirtMaterials > IN_PLACE_BUFFER_DIRT_SIZE ? mi->m_dirtMaterials : mi->m_staticDirtMaterials;
130+
for (std::uint32_t i = 0; i < mi->m_numDirtMaterials; i++)
131+
RpMaterialSetTexture(materials[i], ms_aDirtTextures[level]);
132+
}
133+
134+
#define HOOKPOS_CVehicleModelInfo_SetDirtTextures 0x5D5DBB
135+
#define HOOKSIZE_CVehicleModelInfo_SetDirtTextures 6
136+
static constexpr DWORD CONTINUE_CVehicleModelInfo_SetDirtTextures = 0x5D5DE3;
137+
static void _declspec(naked) HOOK_CVehicleModelInfo_SetDirtTextures()
138+
{
139+
_asm
140+
{
141+
push ebx
142+
push esi
143+
call SetDirtTextures
144+
add esp, 8
145+
146+
jmp CONTINUE_CVehicleModelInfo_SetDirtTextures
147+
}
148+
}
149+
150+
static RpMaterial* GetAtomicGeometryMaterialsCB(RpMaterial* material, void* data)
151+
{
152+
RwTexture* texture = material->texture;
153+
if (!texture)
154+
return nullptr;
155+
156+
auto cbData = static_cast<std::vector<RpMaterial*>*>(data);
157+
if (texture->name && std::strcmp(texture->name, "vehiclegrunge256") == 0)
158+
cbData->push_back(material);
159+
160+
return material;
161+
}
162+
163+
static bool GetEditableMaterialListCB(RpAtomic* atomic, void* data)
164+
{
165+
RpGeometryForAllMaterials(atomic->geometry, &GetAtomicGeometryMaterialsCB, data);
166+
return true;
167+
}
168+
169+
static void __fastcall FindEditableMaterialList(CVehicleModelInfoSAInterface* mi)
170+
{
171+
std::vector<RpMaterial*> list;
172+
RpClumpForAllAtomics(reinterpret_cast<RpClump*>(mi->pRwObject), &GetEditableMaterialListCB, &list);
173+
174+
for (std::uint32_t i = 0; i < mi->pVisualInfo->m_numExtras; i++)
175+
GetEditableMaterialListCB(mi->pVisualInfo->m_pExtra[i], &list);
176+
177+
mi->m_numDirtMaterials = list.size();
178+
if (mi->m_numDirtMaterials > IN_PLACE_BUFFER_DIRT_SIZE)
179+
{
180+
mi->m_dirtMaterials = new RpMaterial*[mi->m_numDirtMaterials];
181+
std::copy(list.begin(), list.end(), mi->m_dirtMaterials);
182+
}
183+
else
184+
{
185+
mi->m_dirtMaterials = nullptr;
186+
std::copy(list.begin(), list.end(), mi->m_staticDirtMaterials);
187+
}
188+
189+
mi->primColor = 255;
190+
mi->secColor = 255;
191+
mi->tertColor = 255;
192+
mi->quatColor = 255;
193+
}
194+
195+
#define HOOKPOS_CVehicleModelInfo_SetClump 0x4C9648
196+
#define HOOKSIZE_CVehicleModelInfo_SetClump 24
197+
static constexpr DWORD CONTINUE_CVehicleModelInfo_SetClump = 0x4C9660;
198+
static void _declspec(naked) HOOK_CVehicleModelInfo_SetClump()
199+
{
200+
_asm
201+
{
202+
push ecx
203+
call FindEditableMaterialList
204+
pop ecx
205+
206+
jmp CONTINUE_CVehicleModelInfo_SetClump
207+
}
208+
}
209+
110210
//////////////////////////////////////////////////////////////////////////////////////////
111211
//
112212
// CMultiplayerSA::InitHooks_Vehicles
@@ -118,4 +218,9 @@ void CMultiplayerSA::InitHooks_Vehicles()
118218
{
119219
EZHookInstall(CDamageManager__ProgressDoorDamage);
120220
EZHookInstall(CAEVehicleAudioEntity__Initialise);
221+
222+
// Fix vehicle dirt level
223+
EZHookInstall(CVehicleModelInfo_SetClump);
224+
EZHookInstall(CVehicleModelInfo_SetDirtTextures);
225+
MemCpy((void*)0x85C5E4, &CVehicleModelInfo_Shutdown, 4);
121226
}

0 commit comments

Comments
 (0)