Skip to content

Commit e82dc11

Browse files
Add get/setVehicleModelWheelSize (#1644)
* Add get/setVehicleModelFrontWheelSize and get/setVehicleModelRearWheelSize These functions, related to issue #719, allow setting the front and rear wheel size of a vehicle model that GTA: SA reads from the vehicle.ide file. Moreover, in combination with #1641, all the wheels can then be visually scaled per vehicle. * Streamline API of new functions The new API takes into account suggestions made by StrixG, LosFaul, qaisjp and others. Thanks! * Fix returning std::variant with std::unordered_map in new function parser This fix is needed for the previous commit to compile. According to @sbx320, the original author of the function parser, it seems correct. * Replace newly introduced NULL by nullptr * Remove optional arguments from getVehicleModelWheelSize * Revert 0765cd3 and fix setVehicleModelFrontWheelSize instead I changed the wrong function because of a mistake.
1 parent 969d497 commit e82dc11

File tree

13 files changed

+193
-1
lines changed

13 files changed

+193
-1
lines changed

Client/game_sa/CGameSA.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,9 @@ void CGameSA::Reset()
473473
CModelInfoSA::RestoreAllObjectsPropertiesGroups();
474474
// restore default properties of all CObjectGroupPhysicalPropertiesSA instances
475475
CObjectGroupPhysicalPropertiesSA::RestoreDefaultValues();
476+
477+
// Restore vehicle model wheel sizes
478+
CModelInfoSA::ResetAllVehiclesWheelSizes();
476479
}
477480
}
478481

Client/game_sa/CModelInfoSA.cpp

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ std::map<DWORD, float> CModelInfo
2222
std::map<DWORD, BYTE> CModelInfoSA::ms_ModelDefaultAlphaTransparencyMap;
2323
std::unordered_map<std::uint32_t, std::map<eVehicleDummies, CVector>> CModelInfoSA::ms_ModelDefaultDummiesPosition;
2424
std::unordered_map<DWORD, unsigned short> CModelInfoSA::ms_OriginalObjectPropertiesGroups;
25+
std::unordered_map<DWORD, std::pair<float, float>> CModelInfoSA::ms_VehicleModelDefaultWheelSizes;
2526

2627
CModelInfoSA::CModelInfoSA()
2728
{
@@ -1014,6 +1015,89 @@ void CModelInfoSA::ResetAllVehicleDummies()
10141015
ms_ModelDefaultDummiesPosition.clear();
10151016
}
10161017

1018+
float CModelInfoSA::GetVehicleWheelSize(eResizableVehicleWheelGroup eWheelGroup)
1019+
{
1020+
if (!IsVehicle())
1021+
return 0.0f;
1022+
1023+
auto pVehicleModel = reinterpret_cast<CVehicleModelInfoSAInterface*>(m_pInterface);
1024+
switch (eWheelGroup)
1025+
{
1026+
case eResizableVehicleWheelGroup::FRONT_AXLE:
1027+
return pVehicleModel->fWheelSizeFront;
1028+
case eResizableVehicleWheelGroup::REAR_AXLE:
1029+
return pVehicleModel->fWheelSizeRear;
1030+
}
1031+
1032+
return 0.0f;
1033+
}
1034+
1035+
void CModelInfoSA::SetVehicleWheelSize(eResizableVehicleWheelGroup eWheelGroup, float fWheelSize)
1036+
{
1037+
if (!IsVehicle())
1038+
return;
1039+
1040+
auto pVehicleModel = reinterpret_cast<CVehicleModelInfoSAInterface*>(m_pInterface);
1041+
1042+
// Store default wheel sizes in map
1043+
if (!MapFind(ms_VehicleModelDefaultWheelSizes, m_dwModelID))
1044+
MapSet(ms_VehicleModelDefaultWheelSizes, m_dwModelID, std::make_pair(pVehicleModel->fWheelSizeFront, pVehicleModel->fWheelSizeRear));
1045+
1046+
switch (eWheelGroup)
1047+
{
1048+
case eResizableVehicleWheelGroup::FRONT_AXLE:
1049+
pVehicleModel->fWheelSizeFront = fWheelSize;
1050+
break;
1051+
case eResizableVehicleWheelGroup::REAR_AXLE:
1052+
pVehicleModel->fWheelSizeRear = fWheelSize;
1053+
break;
1054+
case eResizableVehicleWheelGroup::ALL_WHEELS:
1055+
pVehicleModel->fWheelSizeFront = fWheelSize;
1056+
pVehicleModel->fWheelSizeRear = fWheelSize;
1057+
break;
1058+
}
1059+
}
1060+
1061+
void CModelInfoSA::ResetVehicleWheelSizes(std::pair<float, float>* defaultSizes)
1062+
{
1063+
if (!IsVehicle())
1064+
return;
1065+
1066+
std::pair<float, float>* sizesPair;
1067+
if (!defaultSizes)
1068+
{
1069+
sizesPair = MapFind(ms_VehicleModelDefaultWheelSizes, m_dwModelID);
1070+
MapRemove(ms_VehicleModelDefaultWheelSizes, m_dwModelID);
1071+
}
1072+
else
1073+
{
1074+
sizesPair = defaultSizes;
1075+
}
1076+
1077+
// Default values not found in map
1078+
if (!sizesPair)
1079+
return;
1080+
1081+
auto pVehicleModel = reinterpret_cast<CVehicleModelInfoSAInterface*>(m_pInterface);
1082+
pVehicleModel->fWheelSizeFront = sizesPair->first;
1083+
pVehicleModel->fWheelSizeRear = sizesPair->second;
1084+
}
1085+
1086+
void CModelInfoSA::ResetAllVehiclesWheelSizes()
1087+
{
1088+
CGame* game = g_pCore->GetGame();
1089+
for (auto& info : ms_VehicleModelDefaultWheelSizes)
1090+
{
1091+
CModelInfo* modelInfo = game->GetModelInfo(info.first);
1092+
if (modelInfo)
1093+
{
1094+
modelInfo->ResetVehicleWheelSizes(&info.second);
1095+
}
1096+
}
1097+
1098+
ms_VehicleModelDefaultWheelSizes.clear();
1099+
}
1100+
10171101
void CModelInfoSA::SetCustomModel(RpClump* pClump)
10181102
{
10191103
// Error

Client/game_sa/CModelInfoSA.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ class CModelInfoSA : public CModelInfo
280280
static std::map<DWORD, BYTE> ms_ModelDefaultAlphaTransparencyMap;
281281
static std::unordered_map<std::uint32_t, std::map<eVehicleDummies, CVector>> ms_ModelDefaultDummiesPosition;
282282
static std::unordered_map<DWORD, unsigned short> ms_OriginalObjectPropertiesGroups;
283+
static std::unordered_map<DWORD, std::pair<float, float>> ms_VehicleModelDefaultWheelSizes;
283284
bool m_bAddedRefForCollision;
284285
SVehicleSupportedUpgrades m_ModelSupportedUpgrades;
285286

@@ -354,6 +355,10 @@ class CModelInfoSA : public CModelInfo
354355
void SetVehicleDummyPosition(eVehicleDummies eDummy, const CVector& vecPosition) override;
355356
void ResetVehicleDummies(bool bRemoveFromDummiesMap);
356357
static void ResetAllVehicleDummies();
358+
float GetVehicleWheelSize(eResizableVehicleWheelGroup eWheelGroup) override;
359+
void SetVehicleWheelSize(eResizableVehicleWheelGroup eWheelGroup, float fWheelSize) override;
360+
void ResetVehicleWheelSizes(std::pair<float, float>* defaultSizes = nullptr) override;
361+
static void ResetAllVehiclesWheelSizes();
357362

358363
// ONLY use for peds
359364
void GetVoice(short* psVoiceType, short* psVoice);

Client/mods/deathmatch/logic/CClientDFF.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ void CClientDFF::InternalRestoreModel(unsigned short usModel)
264264
// Restore all the models we replaced.
265265
CModelInfo* pModelInfo = g_pGame->GetModelInfo(usModel);
266266
pModelInfo->ResetVehicleDummies(true);
267+
pModelInfo->ResetVehicleWheelSizes();
267268
pModelInfo->RestoreOriginalModel();
268269
pModelInfo->ResetAlphaTransparency();
269270

@@ -352,6 +353,8 @@ bool CClientDFF::ReplaceVehicleModel(RpClump* pClump, ushort usModel, bool bAlph
352353
CModelInfo* pModelInfo = g_pGame->GetModelInfo(usModel);
353354
pModelInfo->SetCustomModel(pClump);
354355

356+
pModelInfo->ResetVehicleWheelSizes();
357+
355358
pModelInfo->SetAlphaTransparencyEnabled(bAlphaTransparency);
356359

357360
// Remember that we've replaced that vehicle model

Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3603,6 +3603,23 @@ bool CStaticFunctionDefinitions::SetVehicleWindowOpen(CClientVehicle& Vehicle, u
36033603
return Vehicle.SetWindowOpen(ucWindow, bOpen);
36043604
}
36053605

3606+
bool CStaticFunctionDefinitions::SetVehicleModelWheelSize(unsigned short usModel, eResizableVehicleWheelGroup eWheelGroup, float fWheelSize)
3607+
{
3608+
if (CClientVehicleManager::IsValidModel(usModel))
3609+
{
3610+
auto pModelInfo = g_pGame->GetModelInfo(usModel);
3611+
if (pModelInfo)
3612+
{
3613+
pModelInfo->SetVehicleWheelSize(eWheelGroup, fWheelSize);
3614+
// Restream needed to update ride height
3615+
m_pVehicleManager->RestreamVehicles(usModel);
3616+
3617+
return true;
3618+
}
3619+
}
3620+
return false;
3621+
}
3622+
36063623
bool CStaticFunctionDefinitions::IsVehicleWindowOpen(CClientVehicle& Vehicle, uchar ucWindow)
36073624
{
36083625
return Vehicle.IsWindowOpen(ucWindow);
@@ -3636,6 +3653,20 @@ bool CStaticFunctionDefinitions::GetVehicleModelDummyPosition(unsigned short usM
36363653
return false;
36373654
}
36383655

3656+
bool CStaticFunctionDefinitions::GetVehicleModelWheelSize(unsigned short usModel, eResizableVehicleWheelGroup eWheelGroup, float& fWheelSize)
3657+
{
3658+
if (CClientVehicleManager::IsValidModel(usModel) && eWheelGroup != eResizableVehicleWheelGroup::ALL_WHEELS)
3659+
{
3660+
auto pModelInfo = g_pGame->GetModelInfo(usModel);
3661+
if (pModelInfo)
3662+
{
3663+
fWheelSize = pModelInfo->GetVehicleWheelSize(eWheelGroup);
3664+
return true;
3665+
}
3666+
}
3667+
return false;
3668+
}
3669+
36393670
bool CStaticFunctionDefinitions::SetVehicleModelExhaustFumesPosition(unsigned short usModel, CVector& vecPosition)
36403671
{
36413672
if (CClientVehicleManager::IsValidModel(usModel))

Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ class CStaticFunctionDefinitions
226226
static bool GetVehicleModelExhaustFumesPosition(unsigned short usModel, CVector& vecPosition);
227227
static bool SetVehicleModelDummyPosition(unsigned short usModel, eVehicleDummies eDummy, CVector& vecPosition);
228228
static bool GetVehicleModelDummyPosition(unsigned short usModel, eVehicleDummies eDummy, CVector& vecPosition);
229+
static bool GetVehicleModelWheelSize(unsigned short usModel, eResizableVehicleWheelGroup eWheelGroup, float& fWheelSize);
229230

230231
// Vehicle set functions
231232
static bool FixVehicle(CClientEntity& Entity);
@@ -270,6 +271,7 @@ class CStaticFunctionDefinitions
270271
static bool SetVehiclePlateText(CClientEntity& Entity, const SString& strText);
271272
static bool SetHeliBladeCollisionsEnabled(CClientVehicle& Vehicle, bool bEnabled);
272273
static bool SetVehicleWindowOpen(CClientVehicle& Vehicle, uchar ucWindow, bool bOpen);
274+
static bool SetVehicleModelWheelSize(unsigned short usModel, eResizableVehicleWheelGroup eWheelGroup, float fWheelSize);
273275

274276
// Object get funcs
275277
static CClientObject* CreateObject(CResource& Resource, unsigned short usModelID, const CVector& vecPosition, const CVector& vecRotation, bool bLowLod);

Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,12 @@ ADD_ENUM(WING_AIRTRAIL, "wing_airtrail")
581581
ADD_ENUM(VEH_GUN, "veh_gun")
582582
IMPLEMENT_ENUM_END("vehicle-dummy")
583583

584+
IMPLEMENT_ENUM_CLASS_BEGIN(eResizableVehicleWheelGroup)
585+
ADD_ENUM(eResizableVehicleWheelGroup::FRONT_AXLE, "front_axle")
586+
ADD_ENUM(eResizableVehicleWheelGroup::REAR_AXLE, "rear_axle")
587+
ADD_ENUM(eResizableVehicleWheelGroup::ALL_WHEELS, "all_wheels")
588+
IMPLEMENT_ENUM_CLASS_END("resizable-vehicle-wheel-group")
589+
584590
IMPLEMENT_ENUM_BEGIN(eSurfaceProperties)
585591
ADD_ENUM(SURFACE_PROPERTY_AUDIO, "audio")
586592
ADD_ENUM(SURFACE_PROPERTY_STEPWATERSPLASH, "stepwatersplash")

Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ DECLARE_ENUM(eCursorType)
5757
DECLARE_ENUM(eWheelPosition)
5858
DECLARE_ENUM(D3DPRIMITIVETYPE);
5959
DECLARE_ENUM(eVehicleDummies);
60+
DECLARE_ENUM_CLASS(eResizableVehicleWheelGroup);
6061
DECLARE_ENUM(eSurfaceProperties);
6162
DECLARE_ENUM(eSurfaceAudio);
6263
DECLARE_ENUM(eSurfaceBulletEffect);

Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ void CLuaVehicleDefs::LoadFunctions()
8383
{"getVehicleComponents", GetVehicleComponents},
8484
{"getVehicleModelExhaustFumesPosition", GetVehicleModelExhaustFumesPosition},
8585
{"getVehicleModelDummyPosition", GetVehicleModelDummyPosition},
86+
{"getVehicleModelWheelSize", ArgumentParser<GetVehicleModelWheelSize>},
8687

8788
// Vehicle set funcs
8889
{"createVehicle", CreateVehicle},
@@ -139,6 +140,7 @@ void CLuaVehicleDefs::LoadFunctions()
139140
{"setVehicleWindowOpen", SetVehicleWindowOpen},
140141
{"setVehicleModelExhaustFumesPosition", SetVehicleModelExhaustFumesPosition},
141142
{"setVehicleModelDummyPosition", SetVehicleModelDummyPosition },
143+
{"setVehicleModelWheelSize", ArgumentParser<SetVehicleModelWheelSize>},
142144
};
143145

144146
// Add functions
@@ -221,6 +223,7 @@ void CLuaVehicleDefs::AddClass(lua_State* luaVM)
221223
lua_classfunction(luaVM, "getUpgradeOnSlot", "getVehicleUpgradeOnSlot");
222224
lua_classfunction(luaVM, "getModelExhaustFumesPosition", OOP_GetVehicleModelExhaustFumesPosition);
223225
lua_classfunction(luaVM, "getVehicleModelDummyPosition", OOP_GetVehicleModelDummyPosition);
226+
lua_classfunction(luaVM, "getModelWheelSize", "getVehicleModelWheelSize");
224227

225228
lua_classfunction(luaVM, "setComponentVisible", "setVehicleComponentVisible");
226229
lua_classfunction(luaVM, "setSirensOn", "setVehicleSirensOn");
@@ -264,6 +267,7 @@ void CLuaVehicleDefs::AddClass(lua_State* luaVM)
264267
lua_classfunction(luaVM, "setGravity", "setVehicleGravity");
265268
lua_classfunction(luaVM, "setModelExhaustFumesPosition", "setVehicleModelExhaustFumesPosition");
266269
lua_classfunction(luaVM, "setVehicleModelDummyPosition", "setVehicleModelDummyPosition");
270+
lua_classfunction(luaVM, "setModelWheelSize", "setVehicleModelWheelSize");
267271

268272
lua_classfunction(luaVM, "resetComponentPosition", "resetVehicleComponentPosition");
269273
lua_classfunction(luaVM, "resetComponentRotation", "resetVehicleComponentRotation");
@@ -4052,3 +4056,42 @@ int CLuaVehicleDefs::OOP_GetVehicleModelExhaustFumesPosition(lua_State* luaVM)
40524056
lua_pushboolean(luaVM, false);
40534057
return 1;
40544058
}
4059+
4060+
std::variant<float, std::unordered_map<std::string, float>> CLuaVehicleDefs::GetVehicleModelWheelSize(
4061+
const unsigned short usModel, const std::optional<eResizableVehicleWheelGroup> eWheelGroup)
4062+
{
4063+
eResizableVehicleWheelGroup eActualWheelGroup = eWheelGroup.value_or(eResizableVehicleWheelGroup::ALL_WHEELS);
4064+
4065+
if (eActualWheelGroup == eResizableVehicleWheelGroup::ALL_WHEELS)
4066+
{
4067+
float fFrontWheelSize;
4068+
if (!CStaticFunctionDefinitions::GetVehicleModelWheelSize(usModel, eResizableVehicleWheelGroup::FRONT_AXLE, fFrontWheelSize))
4069+
throw std::invalid_argument("Invalid model ID");
4070+
4071+
float fRearWheelSize;
4072+
if (!CStaticFunctionDefinitions::GetVehicleModelWheelSize(usModel, eResizableVehicleWheelGroup::REAR_AXLE, fRearWheelSize))
4073+
throw std::invalid_argument("Invalid model ID");
4074+
4075+
// Return a table like { ["front_axle"] = 0.7, ["rear_axle"] = 0.8 }
4076+
return std::unordered_map<std::string, float>{
4077+
{"front_axle", fFrontWheelSize},
4078+
{"rear_axle", fRearWheelSize},
4079+
};
4080+
}
4081+
else
4082+
{
4083+
float fWheelSize;
4084+
if (!CStaticFunctionDefinitions::GetVehicleModelWheelSize(usModel, eActualWheelGroup, fWheelSize))
4085+
throw std::invalid_argument("Invalid model ID");
4086+
4087+
return fWheelSize;
4088+
}
4089+
}
4090+
4091+
bool CLuaVehicleDefs::SetVehicleModelWheelSize(const unsigned short usModel, const eResizableVehicleWheelGroup eWheelGroup, const float fWheelSize)
4092+
{
4093+
if (fWheelSize <= 0)
4094+
throw std::invalid_argument("Invalid wheel size");
4095+
4096+
return CStaticFunctionDefinitions::SetVehicleModelWheelSize(usModel, eWheelGroup, fWheelSize);
4097+
}

Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,10 @@ class CLuaVehicleDefs : public CLuaDefs
143143
LUA_DECLARE(SetVehicleModelExhaustFumesPosition);
144144
LUA_DECLARE_OOP(GetVehicleModelExhaustFumesPosition);
145145

146+
static std::variant<float, std::unordered_map<std::string, float>> GetVehicleModelWheelSize(const unsigned short usModel,
147+
const std::optional<eResizableVehicleWheelGroup> eWheelGroup);
148+
static bool SetVehicleModelWheelSize(const unsigned short usModel, const eResizableVehicleWheelGroup eWheelGroup, const float fWheelSize);
149+
146150
// Components
147151
LUA_DECLARE(SetVehicleComponentPosition);
148152
LUA_DECLARE_OOP(GetVehicleComponentPosition);

0 commit comments

Comments
 (0)