Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix setVehicleDirtLevel #3837

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 63 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,74 @@ 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];

union
{
struct
{
RpMaterial** m_dirtMaterials;
size_t m_numDirtMaterials;
RpMaterial* m_staticDirtMaterials[30];
};
};

FileEX marked this conversation as resolved.
Show resolved Hide resolved
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);
FileEX marked this conversation as resolved.
Show resolved Hide resolved
}
Loading