Skip to content

Commit fefb204

Browse files
authored
Merge branch 'master' into TheNormalnij/allow_dyn_buildings
2 parents e54af29 + 779183f commit fefb204

File tree

12 files changed

+194
-41
lines changed

12 files changed

+194
-41
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/CPlayerPedSA.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "CPlayerInfoSA.h"
1919
#include "CPlayerPedSA.h"
2020
#include "CWorldSA.h"
21+
#include "CProjectileInfoSA.h"
2122

2223
extern CCoreInterface* g_pCore;
2324
extern CGameSA* pGame;
@@ -137,6 +138,7 @@ CPlayerPedSA::~CPlayerPedSA()
137138
if ((DWORD)GetInterface()->vtbl != VTBL_CPlaceable)
138139
{
139140
CWorldSA* world = (CWorldSA*)pGame->GetWorld();
141+
pGame->GetProjectileInfo()->RemoveEntityReferences(this);
140142
world->Remove(m_pInterface, CPlayerPed_Destructor);
141143

142144
DWORD dwThis = (DWORD)m_pInterface;

Client/game_sa/CProjectileInfoSA.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,3 +180,18 @@ DWORD CProjectileInfoSA::GetCounter()
180180
{
181181
return internalInterface->dwCounter - pGame->GetSystemTime();
182182
}
183+
184+
void CProjectileInfoSA::RemoveEntityReferences(CEntity* entity)
185+
{
186+
const CEntitySAInterface* entityInterface = entity->GetInterface();
187+
for (int i = 0; i < PROJECTILE_INFO_COUNT; i++)
188+
{
189+
auto projectileInterface = projectileInfo[i]->internalInterface;
190+
191+
if (projectileInterface->pEntProjectileOwner == entityInterface)
192+
projectileInterface->pEntProjectileOwner = nullptr;
193+
194+
if (projectileInterface->pEntProjectileTarget == entityInterface)
195+
projectileInterface->pEntProjectileTarget = nullptr;
196+
}
197+
}

Client/game_sa/CProjectileInfoSA.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ class CProjectileInfoSAInterface
4242
};
4343
// #pragma pack(pop)
4444

45-
class CProjectileInfoSA : public CProjectileInfo
45+
// TODO extract manager class
46+
class CProjectileInfoSA final : public CProjectileInfo
4647
{
4748
private:
4849
CProjectileInfoSA* projectileInfo[PROJECTILE_INFO_COUNT];
@@ -65,6 +66,7 @@ class CProjectileInfoSA : public CProjectileInfo
6566
CProjectileInfo* GetProjectileInfo(DWORD dwIndex);
6667
bool AddProjectile(CEntity* creator, eWeaponType eWeapon, CVector vecOrigin, float fForce, CVector* target, CEntity* targetEntity);
6768
CProjectile* GetProjectile(void* projectilePointer);
69+
void RemoveEntityReferences(CEntity* entity);
6870

6971
CEntity* GetTarget();
7072
void SetTarget(CEntity* pEntity);

Client/game_sa/CVehicleSA.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ CVehicleSA::~CVehicleSA()
224224
}
225225

226226
CWorldSA* pWorld = (CWorldSA*)pGame->GetWorld();
227+
pGame->GetProjectileInfo()->RemoveEntityReferences(this);
227228
pWorld->Remove(m_pInterface, CVehicle_Destructor);
228229
pWorld->RemoveReferencesToDeletedObject(m_pInterface);
229230

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/mods/deathmatch/logic/CClientGUIManager.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ void CClientGUIManager::DeleteAll()
4343

4444
bool CClientGUIManager::Exists(CClientGUIElement* pGUIElement)
4545
{
46-
return m_Elements.Contains(pGUIElement);
46+
return pGUIElement ? m_Elements.Contains(pGUIElement) : false;
4747
}
4848

4949
bool CClientGUIManager::Exists(CGUIElement* pCGUIElement)

Client/mods/deathmatch/logic/CClientGame.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <game/Task.h>
3535
#include <game/CBuildingRemoval.h>
3636
#include "game/CClock.h"
37+
#include <game/CProjectileInfo.h>
3738
#include <windowsx.h>
3839
#include "CServerInfo.h"
3940

@@ -403,6 +404,10 @@ CClientGame::CClientGame(bool bLocalPlay) : m_ServerInfo(new CServerInfo())
403404
CClientGame::~CClientGame()
404405
{
405406
m_bBeingDeleted = true;
407+
// Remove active projectile references to local player
408+
if (auto pLocalPlayer = g_pClientGame->GetLocalPlayer())
409+
g_pGame->GetProjectileInfo()->RemoveEntityReferences(pLocalPlayer->GetGameEntity());
410+
406411
// Stop all explosions. Unfortunately this doesn't fix the crash
407412
// if a vehicle is destroyed while it explodes.
408413
g_pGame->GetExplosionManager()->RemoveAllExplosions();

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)