Skip to content

Commit 03b4914

Browse files
forkererpatrikjuvonen
authored andcommitted
Add possibility of modifying dynamic objects behavior (#784)
* Basic implementation of required classes * Possibility to get object properties group from CModelInfo * Ability to change model id -> object properties group relations * enum definition * moved function to the end of CGame*, small cleanup * Fixed issues with not starting, a lot of changes - changed the way of how backup ObjectDynamicInfo works - added functions to get/set/restore model dynamic properties group - some other small changes * Basic functions, starting renaming * The giant renaming * model update * model/naming changes, rest of setters from lua. * naming, code shortening thanks to botder * Enums cleanup, to their own namespace they go also added missing property change * Added missing restore function, naming changes * enums namespace change * Ability to get properties from lua * enum memory layout issues fix * Added ability to change fx system used by object group * Additional safety checks in lua functions * Restore object data changes, refactored lua methods * adjust properties count to real 160, instead of 255, * Ability to restore default group properties from lua * Enum class name change * Stuff i've noticed when making pull request * Moved stuff * Formatting fix * Clean up project comments * Changes recommended in code review 1. Added const modfier to functions where possible 2. Changed constructor to use initializer list 3. Removed unnecessary call to ChangeSafeguard() from one of the getters * Changes suggested in pull request review Calling of internal functions without _asm blocks Const specifier in range loops where needed Replaced pointers with std::unique_ptrs Fixed inconsistency with bad arguments checking in some lua functions * Change warnings to errors
1 parent 901ed44 commit 03b4914

17 files changed

+1261
-50
lines changed

Client/game_sa/CFxManagerSA.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,18 @@ void CFxManagerSA::OnFxSystemSAInterfaceDestroyed(CFxSystemSAInterface* pFxSyste
6767
delete pFxSystemSA;
6868
}
6969

70+
CFxSystemBPSAInterface* CFxManagerSA::GetFxSystemBlueprintByName(SString sName)
71+
{
72+
using func_t = CFxSystemBPSAInterface*(__thiscall*)(CFxManagerSAInterface * pInterface, const char* pChars);
73+
auto func = reinterpret_cast<func_t>(FUNC_FxManager_c__GetSystemByName);
74+
return func(m_pInterface, sName);
75+
}
76+
77+
bool CFxManagerSA::IsValidFxSystemBlueprintName(SString sName)
78+
{
79+
return GetFxSystemBlueprintByName(sName) != nullptr;
80+
}
81+
7082
//
7183
// AddToList/RemoveFromList called from CFxSystemSA constructor/destructor
7284
//

Client/game_sa/CFxManagerSA.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#define FUNC_FxManager_c__CreateFxSystem 0x4A9BE0
1616
#define FUNC_FxManager_c__DestroyFxSystem 0x4A9810
17+
#define FUNC_FxManager_c__GetSystemByName 0x4A9360
1718

1819
class CFxSystemBPSAInterface;
1920
class CFxSystemSAInterface;
@@ -61,10 +62,12 @@ class CFxManagerSA : public CFxManager
6162
public:
6263
CFxManagerSA(CFxManagerSAInterface* pInterface) { m_pInterface = pInterface; }
6364
// CFxManager interface
64-
CFxSystem* CreateFxSystem(const char* szBlueprint, const CVector& vecPosition, RwMatrix* pRwMatrixTag, unsigned char bSkipCameraFrustumCheck,
65-
bool bSoundEnable);
66-
void DestroyFxSystem(CFxSystem* pFxSystem);
67-
void OnFxSystemSAInterfaceDestroyed(CFxSystemSAInterface* pFxSystemSAInterface);
65+
CFxSystem* CreateFxSystem(const char* szBlueprint, const CVector& vecPosition, RwMatrix* pRwMatrixTag, unsigned char bSkipCameraFrustumCheck,
66+
bool bSoundEnable);
67+
void DestroyFxSystem(CFxSystem* pFxSystem);
68+
void OnFxSystemSAInterfaceDestroyed(CFxSystemSAInterface* pFxSystemSAInterface);
69+
CFxSystemBPSAInterface* GetFxSystemBlueprintByName(SString sName);
70+
bool IsValidFxSystemBlueprintName(SString sName);
6871

6972
// CFxManagerSA methods
7073
CFxSystemSA* GetFxSystem(CFxSystemSAInterface* pFxSystemSAInterface);

Client/game_sa/CGameSA.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ CGameSA::CGameSA()
6565
ModelInfo[i].SetModelID(i);
6666
}
6767

68+
// Prepare all object dynamic infos for CObjectGroupPhysicalPropertiesSA instances
69+
for (int i = 0; i < OBJECTDYNAMICINFO_MAX; i++)
70+
{
71+
ObjectGroupsInfo[i].SetGroup(i);
72+
}
73+
6874
DEBUG_TRACE("CGameSA::CGameSA()");
6975
this->m_pAudioEngine = new CAudioEngineSA((CAudioEngineSAInterface*)CLASS_CAudioEngine);
7076
this->m_pAEAudioHardware = new CAEAudioHardwareSA((CAEAudioHardwareSAInterface*)CLASS_CAEAudioHardware);
@@ -464,6 +470,9 @@ void CGameSA::Reset()
464470

465471
// Restore model dummies' positions
466472
CModelInfoSA::ResetAllVehicleDummies();
473+
CModelInfoSA::RestoreAllObjectsPropertiesGroups();
474+
// restore default properties of all CObjectGroupPhysicalPropertiesSA instances
475+
CObjectGroupPhysicalPropertiesSA::RestoreDefaultValues();
467476
}
468477
}
469478

@@ -862,3 +871,12 @@ CPed* CGameSA::GetPedContext()
862871
m_pPedContext = pGame->GetPools()->GetPedFromRef((DWORD)1);
863872
return m_pPedContext;
864873
}
874+
875+
CObjectGroupPhysicalProperties* CGameSA::GetObjectGroupPhysicalProperties(unsigned char ucObjectGroup)
876+
{
877+
DEBUG_TRACE("CObjectGroupPhysicalProperties * CGameSA::GetObjectGroupPhysicalProperties(unsigned char ucObjectGroup)");
878+
if (ucObjectGroup < OBJECTDYNAMICINFO_MAX && ObjectGroupsInfo[ucObjectGroup].IsValid())
879+
return &ObjectGroupsInfo[ucObjectGroup];
880+
881+
return nullptr;
882+
}

Client/game_sa/CGameSA.h

Lines changed: 40 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#pragma once
1313

1414
#include "CModelInfoSA.h"
15+
#include "CObjectGroupPhysicalPropertiesSA.h"
1516
#include "CFxManagerSA.h"
1617

1718
#define MAX_MEMORY_OFFSET_1_0 0xCAF008
@@ -33,6 +34,7 @@
3334
#define NUM_WeaponInfosTotal (NUM_WeaponInfosStdSkill + (3*NUM_WeaponInfosOtherSkill)) // std, (poor, pro, special)
3435

3536
#define MODELINFO_MAX 26000 // Actual max is 25755
37+
#define OBJECTDYNAMICINFO_MAX 160
3638

3739
#define FUNC_GetLevelFromPosition 0x4DD300
3840

@@ -103,6 +105,7 @@ class CGameSA : public CGame
103105
private:
104106
CWeaponInfo* WeaponInfos[NUM_WeaponInfosTotal];
105107
CModelInfoSA ModelInfo[MODELINFO_MAX];
108+
CObjectGroupPhysicalPropertiesSA ObjectGroupsInfo[OBJECTDYNAMICINFO_MAX];
106109

107110
public:
108111
ZERO_ON_NEW
@@ -305,8 +308,9 @@ class CGameSA : public CGame
305308
CRenderWareSA* GetRenderWareSA() { return m_pRenderWare; }
306309
CFxManagerSA* GetFxManagerSA() { return m_pFxManager; }
307310

308-
CWeaponInfo* GetWeaponInfo(eWeaponType weapon, eWeaponSkill skill = WEAPONSKILL_STD);
309-
CModelInfo* GetModelInfo(DWORD dwModelID);
311+
CWeaponInfo* GetWeaponInfo(eWeaponType weapon, eWeaponSkill skill = WEAPONSKILL_STD);
312+
CModelInfo* GetModelInfo(DWORD dwModelID);
313+
CObjectGroupPhysicalProperties* GetObjectGroupPhysicalProperties(unsigned char ucObjectGroup);
310314

311315
DWORD GetSystemTime()
312316
{
@@ -429,39 +433,40 @@ class CGameSA : public CGame
429433
TaskSimpleBeHitHandler* m_pTaskSimpleBeHitHandler;
430434

431435
private:
432-
CPools* m_pPools;
433-
CPlayerInfo* m_pPlayerInfo;
434-
CProjectileInfo* m_pProjectileInfo;
435-
CRadar* m_pRadar;
436-
CRestart* m_pRestart;
437-
CClock* m_pClock;
438-
CCoronas* m_pCoronas;
439-
CCheckpoints* m_pCheckpoints;
440-
CEventList* m_pEventList;
441-
CFireManager* m_pFireManager;
442-
CGarages* m_pGarages;
443-
CHud* m_pHud;
444-
CWanted* m_pWanted;
445-
CWeather* m_pWeather;
446-
CWorld* m_pWorld;
447-
CCamera* m_pCamera;
448-
CModelInfo* m_pModelInfo;
449-
CPickups* m_pPickups;
450-
CWeaponInfo* m_pWeaponInfo;
451-
CExplosionManager* m_pExplosionManager;
452-
C3DMarkers* m_p3DMarkers;
453-
CRenderWareSA* m_pRenderWare;
454-
CHandlingManager* m_pHandlingManager;
455-
CAnimManager* m_pAnimManager;
456-
CStreaming* m_pStreaming;
457-
CVisibilityPlugins* m_pVisibilityPlugins;
458-
CKeyGen* m_pKeyGen;
459-
CRopes* m_pRopes;
460-
CFx* m_pFx;
461-
CFxManagerSA* m_pFxManager;
462-
CWaterManager* m_pWaterManager;
463-
CWeaponStatManager* m_pWeaponStatsManager;
464-
CPointLights* m_pPointLights;
436+
CPools* m_pPools;
437+
CPlayerInfo* m_pPlayerInfo;
438+
CProjectileInfo* m_pProjectileInfo;
439+
CRadar* m_pRadar;
440+
CRestart* m_pRestart;
441+
CClock* m_pClock;
442+
CCoronas* m_pCoronas;
443+
CCheckpoints* m_pCheckpoints;
444+
CEventList* m_pEventList;
445+
CFireManager* m_pFireManager;
446+
CGarages* m_pGarages;
447+
CHud* m_pHud;
448+
CWanted* m_pWanted;
449+
CWeather* m_pWeather;
450+
CWorld* m_pWorld;
451+
CCamera* m_pCamera;
452+
CModelInfo* m_pModelInfo;
453+
CPickups* m_pPickups;
454+
CWeaponInfo* m_pWeaponInfo;
455+
CExplosionManager* m_pExplosionManager;
456+
C3DMarkers* m_p3DMarkers;
457+
CRenderWareSA* m_pRenderWare;
458+
CHandlingManager* m_pHandlingManager;
459+
CAnimManager* m_pAnimManager;
460+
CStreaming* m_pStreaming;
461+
CVisibilityPlugins* m_pVisibilityPlugins;
462+
CKeyGen* m_pKeyGen;
463+
CRopes* m_pRopes;
464+
CFx* m_pFx;
465+
CFxManagerSA* m_pFxManager;
466+
CWaterManager* m_pWaterManager;
467+
CWeaponStatManager* m_pWeaponStatsManager;
468+
CPointLights* m_pPointLights;
469+
CObjectGroupPhysicalProperties* m_pObjectGroupPhysicalProperties;
465470

466471
CPad* m_pPad;
467472
CTheCarGenerators* m_pTheCarGenerators;

Client/game_sa/CModelInfoSA.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ std::map<unsigned short, int>
2020
std::map<DWORD, float> CModelInfoSA::ms_ModelDefaultLodDistanceMap;
2121
std::map<DWORD, BYTE> CModelInfoSA::ms_ModelDefaultAlphaTransparencyMap;
2222
std::unordered_map<CVehicleModelInfoSAInterface*, std::map<eVehicleDummies, CVector>> CModelInfoSA::ms_ModelDefaultDummiesPosition;
23+
std::unordered_map<DWORD, unsigned short> CModelInfoSA::ms_OriginalObjectPropertiesGroups;
2324

2425
CModelInfoSA::CModelInfoSA()
2526
{
@@ -1373,6 +1374,46 @@ void CModelInfoSA::ResetSupportedUpgrades()
13731374
m_ModelSupportedUpgrades.Reset();
13741375
}
13751376

1377+
void CModelInfoSA::SetObjectPropertiesGroup(unsigned short usNewGroup)
1378+
{
1379+
unsigned short usOrgGroup = GetObjectPropertiesGroup();
1380+
if (usOrgGroup == usNewGroup)
1381+
return;
1382+
1383+
if (!MapFind(ms_OriginalObjectPropertiesGroups, m_dwModelID))
1384+
MapSet(ms_OriginalObjectPropertiesGroups, m_dwModelID, usOrgGroup);
1385+
1386+
GetInterface()->usDynamicIndex = usNewGroup;
1387+
}
1388+
1389+
unsigned short CModelInfoSA::GetObjectPropertiesGroup()
1390+
{
1391+
unsigned short usGroup = GetInterface()->usDynamicIndex;
1392+
if (usGroup == 0xFFFF)
1393+
usGroup = 0;
1394+
1395+
return usGroup;
1396+
}
1397+
1398+
void CModelInfoSA::RestoreObjectPropertiesGroup()
1399+
{
1400+
unsigned short* usGroupInMap = MapFind(ms_OriginalObjectPropertiesGroups, m_dwModelID);
1401+
if (usGroupInMap)
1402+
{
1403+
GetInterface()->usDynamicIndex = *usGroupInMap;
1404+
MapRemove(ms_OriginalObjectPropertiesGroups, m_dwModelID);
1405+
}
1406+
}
1407+
1408+
void CModelInfoSA::RestoreAllObjectsPropertiesGroups()
1409+
{
1410+
for (const auto& pair : ms_OriginalObjectPropertiesGroups)
1411+
{
1412+
pGame->GetModelInfo(pair.first)->GetInterface()->usDynamicIndex = pair.second;
1413+
}
1414+
ms_OriginalObjectPropertiesGroups.clear();
1415+
}
1416+
13761417
eModelInfoType CModelInfoSA::GetModelType()
13771418
{
13781419
return ((eModelInfoType(*)())m_pInterface->VFTBL->GetModelType)();

Client/game_sa/CModelInfoSA.h

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -139,16 +139,7 @@ class CBaseModelInfoSAInterface
139139
unsigned char ucNumOf2DEffects : 8; // +13
140140
unsigned short usUnknown : 16; // +14 Something with 2d effects
141141

142-
unsigned char ucDynamicIndex : 8; // +16
143-
144-
unsigned char dwUnknownFlag9 : 1; // +17
145-
unsigned char dwUnknownFlag10 : 1;
146-
unsigned char dwUnknownFlag11 : 1;
147-
unsigned char dwUnknownFlag12 : 1;
148-
unsigned char dwUnknownFlag13 : 1;
149-
unsigned char dwUnknownFlag14 : 1;
150-
unsigned char dwUnknownFlag15 : 1;
151-
unsigned char dwUnknownFlag16 : 1;
142+
unsigned short usDynamicIndex : 16; // +16
152143

153144
// Flags used by CBaseModelInfo
154145
unsigned char bHasBeenPreRendered : 1; // +18
@@ -277,6 +268,7 @@ class CModelInfoSA : public CModelInfo
277268
static std::map<DWORD, float> ms_ModelDefaultLodDistanceMap;
278269
static std::map<DWORD, BYTE> ms_ModelDefaultAlphaTransparencyMap;
279270
static std::unordered_map<CVehicleModelInfoSAInterface*, std::map<eVehicleDummies, CVector>> ms_ModelDefaultDummiesPosition;
271+
static std::unordered_map<DWORD, unsigned short> ms_OriginalObjectPropertiesGroups;
280272
bool m_bAddedRefForCollision;
281273
SVehicleSupportedUpgrades m_ModelSupportedUpgrades;
282274

@@ -375,6 +367,11 @@ class CModelInfoSA : public CModelInfo
375367
void InitialiseSupportedUpgrades(RpClump* pClump);
376368
void ResetSupportedUpgrades();
377369

370+
void SetObjectPropertiesGroup(unsigned short usObjectGroup);
371+
unsigned short GetObjectPropertiesGroup();
372+
void RestoreObjectPropertiesGroup();
373+
static void RestoreAllObjectsPropertiesGroups();
374+
378375
private:
379376
void RwSetSupportedUpgrades(RwFrame* parent, DWORD dwModel);
380377
};

0 commit comments

Comments
 (0)