Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
29 changes: 26 additions & 3 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 @@ -259,11 +260,22 @@ 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
Expand All @@ -290,7 +302,18 @@ class CVehicleModelInfoSAInterface : public CBaseModelInfoSAInterface
float fSteeringAngle;
CVehicleModelVisualInfoSAInterface* pVisualInfo; // +92
char pad3[464];
char pDirtMaterial[64]; // *RwMaterial

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

char pad4[64];
char primColors[8];
char secondColors[8];
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
111 changes: 111 additions & 0 deletions Client/multiplayer_sa/CMultiplayerSA_Vehicles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@
*****************************************************************************/

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

#define FUNC_CVehicleModelInfo_ResetColors 0x4C8490
#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 +114,105 @@ static void _declspec(naked) HOOK_CAEVehicleAudioEntity__Initialise()
}
}

static void CVehicleModelInfo_Shutdown()
{
CVehicleModelInfoSAInterface* mi = nullptr;
_asm
{
mov mi, ecx
}

if (!mi)
return;

((void(__cdecl*)(void*))FUNC_CBaseModelInfo_Shutdown)(mi);

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
{
pushad
push ebx
push esi
call SetDirtTextures
add esp, 8
popad

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);
}

((void(__thiscall*)(CVehicleModelInfoSAInterface*))FUNC_CVehicleModelInfo_ResetColors)(mi);
}

#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
{
pushad
call FindEditableMaterialList
popad

jmp CONTINUE_CVehicleModelInfo_SetClump
}
}

//////////////////////////////////////////////////////////////////////////////////////////
//
// CMultiplayerSA::InitHooks_Vehicles
Expand All @@ -118,4 +224,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);
}
Loading