Skip to content

Commit

Permalink
Fix setVehicleDirtLevel (#3837)
Browse files Browse the repository at this point in the history
  • Loading branch information
FileEX authored Dec 14, 2024
1 parent d6152b8 commit 81218c7
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 37 deletions.
91 changes: 55 additions & 36 deletions Client/game_sa/CModelInfoSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <game/Common.h>
#include <game/CModelInfo.h>
#include "CRenderWareSA.h"
#include "game/RenderWare.h"

class CPedModelInfoSA;
class CPedModelInfoSAInterface;
Expand Down Expand Up @@ -231,6 +232,11 @@ class CBaseModelInfoSAInterface
// +726 = Word array as referenced in CVehicleModelInfo::GetVehicleUpgrade(int)
// +762 = Array of WORD containing something relative to paintjobs
// +772 = Anim file index

void Shutdown()
{
((void(*)())VFTBL->Shutdown)();
}
};
static_assert(sizeof(CBaseModelInfoSAInterface) == 0x20, "Invalid size for CBaseModelInfoSAInterface");

Expand Down Expand Up @@ -259,53 +265,66 @@ class CTimeModelInfoSAInterface : public CBaseModelInfoSAInterface
CTimeInfoSAInterface timeInfo;
};

class CVehicleModelUpgradePosnDesc
{
CVector m_vPosition;
RtQuat m_vRotation;
int m_iParentId;
};

class CVehicleModelVisualInfoSAInterface // Not sure about this name. If somebody knows more, please change
{
public:
CVector vecDummies[15];
char m_sUpgrade[18];
CVector vecDummies[15];
CVehicleModelUpgradePosnDesc m_sUpgrade[18];
RpAtomic* m_pExtra[6];
std::uint8_t m_numExtras;
std::uint8_t _pad[3];
int m_maskComponentDamagable;
};

class CVehicleModelInfoSAInterface : public CBaseModelInfoSAInterface
class CVehicleModelInfoSAInterface : public CClumpModelInfoSAInterface
{
public:
uint32 pad1; // +32
RpMaterial* pPlateMaterial; // +36
RpMaterial* pPlateMaterial;
char plateText[8];
char pad[2];
std::uint8_t field_30;
std::uint8_t plateType;
char gameName[8];
char pad2[2];
unsigned int uiVehicleType;
std::uint8_t field_3A[2];
std::uint32_t vehicleType;
float fWheelSizeFront;
float fWheelSizeRear;
short sWheelModel;
short sHandlingID;
byte ucNumDoors;
byte ucVehicleList;
byte ucVehicleFlags;
byte ucWheelUpgradeClass;
byte ucTimesUsed;
short sVehFrequency;
unsigned int uiComponentRules;
float fSteeringAngle;
CVehicleModelVisualInfoSAInterface* pVisualInfo; // +92
char pad3[464];
char pDirtMaterial[64]; // *RwMaterial
char pad4[64];
char primColors[8];
char secondColors[8];
char treeColors[8];
char fourColors[8];
unsigned char ucNumOfColorVariations;
unsigned char ucLastColorVariation;
unsigned char ucPrimColor;
unsigned char ucSecColor;
unsigned char ucTertColor;
unsigned char ucQuatColor;
char upgrades[36];
char anRemapTXDs[8];
char pad5[2];
char pAnimBlock[4];
std::int16_t wheelModelID;
std::int16_t handlingID;
std::uint8_t numDoors;
std::uint8_t vehicleClass;
std::uint8_t vehicleFlags;
std::uint8_t wheelUpgradeClass;
std::uint8_t timesUsed;
std::uint8_t field_51;
std::int16_t vehFrequency;
std::uint32_t componentRules;
float bikeSteeringAngle;
CVehicleModelVisualInfoSAInterface* pVisualInfo; // vehicleStruct
std::uint8_t field_60[464];
RpMaterial** m_dirtMaterials;
std::size_t m_numDirtMaterials;
RpMaterial* m_staticDirtMaterials[30];
std::uint8_t primColors[8];
std::uint8_t secondColors[8];
std::uint8_t treeColors[8];
std::uint8_t fourColors[8];
std::uint8_t numOfColorVariations;
std::uint8_t lastColorVariation;
std::uint8_t primColor;
std::uint8_t secColor;
std::uint8_t tertColor;
std::uint8_t quatColor;
std::uint8_t upgrades[36];
std::uint8_t anRemapTXDs[8];
std::uint8_t field_302[2];
void* pAnimBlock; // CAnimBlock*
};

class CModelInfoSA : public CModelInfo
Expand Down
2 changes: 2 additions & 0 deletions Client/game_sa/gamesa_renderware.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ typedef RpHAnimHierarchy*(__cdecl* GetAnimHierarchyFromSkinClump_t)(RpClump*);
typedef int(__cdecl* RpHAnimIDGetIndex_t)(RpHAnimHierarchy*, int);
typedef RwMatrix*(__cdecl* RpHAnimHierarchyGetMatrixArray_t)(RpHAnimHierarchy*);
typedef RtQuat*(__cdecl* RtQuatRotate_t)(RtQuat* quat, const RwV3d* axis, float angle, RwOpCombineType combineOp);
typedef RpGeometry*(__cdecl* RpGeometryForAllMaterials_t)(RpGeometry* geom, void* callback, void* data);

/*****************************************************************************/
/** Renderware function mappings **/
Expand Down Expand Up @@ -195,6 +196,7 @@ RWFUNC(GetAnimHierarchyFromSkinClump_t GetAnimHierarchyFromSkinClump, (GetAnimHi
RWFUNC(RpHAnimIDGetIndex_t RpHAnimIDGetIndex, (RpHAnimIDGetIndex_t)0xDEAD)
RWFUNC(RpHAnimHierarchyGetMatrixArray_t RpHAnimHierarchyGetMatrixArray, (RpHAnimHierarchyGetMatrixArray_t)0xDEAD)
RWFUNC(RtQuatRotate_t RtQuatRotate, (RtQuatRotate_t)0xDEAD)
RWFUNC(RpGeometryForAllMaterials_t RpGeometryForAllMaterials, (RpGeometryForAllMaterials_t)0xDEAD)

/*****************************************************************************/
/** GTA function definitions and mappings **/
Expand Down
3 changes: 2 additions & 1 deletion Client/game_sa/gamesa_renderware.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ void InitRwFunctions()
RpHAnimIDGetIndex = (RpHAnimIDGetIndex_t)0x7C51A0;
RpHAnimHierarchyGetMatrixArray = (RpHAnimHierarchyGetMatrixArray_t)0x7C5120;
RtQuatRotate = (RtQuatRotate_t)0x7EB7C0;

RpGeometryForAllMaterials = (RpGeometryForAllMaterials_t)0x74C790;

SetTextureDict = (SetTextureDict_t)0x007319C0;
LoadClumpFile = (LoadClumpFile_t)0x005371F0;
LoadModel = (LoadModel_t)0x0040C6B0;
Expand Down
105 changes: 105 additions & 0 deletions Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
*****************************************************************************/

#include "StdInc.h"
#include "..\game_sa\gamesa_renderware.h"

#define FUNC_CBaseModelInfo_Shutdown 0x4C4D50
#define IN_PLACE_BUFFER_DIRT_SIZE 30

static RwTexture** const ms_aDirtTextures = (RwTexture**)0xC02BD0;

static bool __fastcall AreVehicleDoorsUndamageable(CVehicleSAInterface* vehicle)
{
Expand Down Expand Up @@ -107,6 +113,100 @@ static void _declspec(naked) HOOK_CAEVehicleAudioEntity__Initialise()
}
}

static void __fastcall CVehicleModelInfo_Shutdown(CVehicleModelInfoSAInterface* mi)
{
if (!mi)
return;

mi->Shutdown();

delete[] mi->m_dirtMaterials;
mi->m_dirtMaterials = nullptr;
}

static void SetDirtTextures(CVehicleModelInfoSAInterface* mi, std::uint32_t level)
{
RpMaterial** materials = mi->m_numDirtMaterials > IN_PLACE_BUFFER_DIRT_SIZE ? mi->m_dirtMaterials : mi->m_staticDirtMaterials;
for (std::uint32_t i = 0; i < mi->m_numDirtMaterials; i++)
RpMaterialSetTexture(materials[i], ms_aDirtTextures[level]);
}

#define HOOKPOS_CVehicleModelInfo_SetDirtTextures 0x5D5DBB
#define HOOKSIZE_CVehicleModelInfo_SetDirtTextures 6
static constexpr DWORD CONTINUE_CVehicleModelInfo_SetDirtTextures = 0x5D5DE3;
static void _declspec(naked) HOOK_CVehicleModelInfo_SetDirtTextures()
{
_asm
{
push ebx
push esi
call SetDirtTextures
add esp, 8

jmp CONTINUE_CVehicleModelInfo_SetDirtTextures
}
}

static RpMaterial* GetAtomicGeometryMaterialsCB(RpMaterial* material, void* data)
{
RwTexture* texture = material->texture;
if (!texture)
return nullptr;

auto cbData = static_cast<std::vector<RpMaterial*>*>(data);
if (texture->name && std::strcmp(texture->name, "vehiclegrunge256") == 0)
cbData->push_back(material);

return material;
}

static bool GetEditableMaterialListCB(RpAtomic* atomic, void* data)
{
RpGeometryForAllMaterials(atomic->geometry, &GetAtomicGeometryMaterialsCB, data);
return true;
}

static void __fastcall FindEditableMaterialList(CVehicleModelInfoSAInterface* mi)
{
std::vector<RpMaterial*> list;
RpClumpForAllAtomics(reinterpret_cast<RpClump*>(mi->pRwObject), &GetEditableMaterialListCB, &list);

for (std::uint32_t i = 0; i < mi->pVisualInfo->m_numExtras; i++)
GetEditableMaterialListCB(mi->pVisualInfo->m_pExtra[i], &list);

mi->m_numDirtMaterials = list.size();
if (mi->m_numDirtMaterials > IN_PLACE_BUFFER_DIRT_SIZE)
{
mi->m_dirtMaterials = new RpMaterial*[mi->m_numDirtMaterials];
std::copy(list.begin(), list.end(), mi->m_dirtMaterials);
}
else
{
mi->m_dirtMaterials = nullptr;
std::copy(list.begin(), list.end(), mi->m_staticDirtMaterials);
}

mi->primColor = 255;
mi->secColor = 255;
mi->tertColor = 255;
mi->quatColor = 255;
}

#define HOOKPOS_CVehicleModelInfo_SetClump 0x4C9648
#define HOOKSIZE_CVehicleModelInfo_SetClump 24
static constexpr DWORD CONTINUE_CVehicleModelInfo_SetClump = 0x4C9660;
static void _declspec(naked) HOOK_CVehicleModelInfo_SetClump()
{
_asm
{
push ecx
call FindEditableMaterialList
pop ecx

jmp CONTINUE_CVehicleModelInfo_SetClump
}
}

//////////////////////////////////////////////////////////////////////////////////////////
//
// CMultiplayerSA::InitHooks_Vehicles
Expand All @@ -118,4 +218,9 @@ void CMultiplayerSA::InitHooks_Vehicles()
{
EZHookInstall(CDamageManager__ProgressDoorDamage);
EZHookInstall(CAEVehicleAudioEntity__Initialise);

// Fix vehicle dirt level
EZHookInstall(CVehicleModelInfo_SetClump);
EZHookInstall(CVehicleModelInfo_SetDirtTextures);
MemCpy((void*)0x85C5E4, &CVehicleModelInfo_Shutdown, 4);
}

0 comments on commit 81218c7

Please sign in to comment.