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

Allow allocating models server-side #2533

Open
wants to merge 60 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
5698387
Some basic progress
TheNormalnij Jan 30, 2022
e4bfd86
Refactor handling, vehicle manager
TheNormalnij May 22, 2022
dc5bbf6
Update vehicle config
TheNormalnij May 29, 2022
b7be58e
Restructure configs
TheNormalnij Jun 4, 2022
be0d106
Merge remote-tracking branch 'mta_main/master' into TheNormalnij/mode…
TheNormalnij Jun 4, 2022
231ca90
Fix dependencies
TheNormalnij Jun 5, 2022
b83eba2
Fix linux build
TheNormalnij Jun 8, 2022
84cc9e5
Fix client-server packet desync
TheNormalnij Jun 8, 2022
bb32626
Implement all base lua API
TheNormalnij Jun 12, 2022
e7a8dfc
Peds and object, fix getFreeModels
TheNormalnij Jun 12, 2022
2fe28e6
Fix out of limits allocating
TheNormalnij Jun 12, 2022
9b244ba
fix getType
TheNormalnij Jun 12, 2022
4f49306
Fix GetVehicleModel crashes
TheNormalnij Jun 12, 2022
b1b19c2
Handle model conflicts
TheNormalnij Jun 12, 2022
7cc086f
Little refactor
TheNormalnij Jun 12, 2022
8c69d0c
Backup new configs
TheNormalnij Jun 12, 2022
f6a2701
Change HasDoors check for SetVehicleDoorState
TheNormalnij Jun 13, 2022
a53f37a
Remove GetInitialDoorStates hardcoded part
TheNormalnij Jun 14, 2022
5a879d8
Merge remote-tracking branch 'mta_main/master' into TheNormalnij/mode…
TheNormalnij Oct 22, 2022
faf18c5
Fix server crash with invalid allocateModelFromParent arguments
TheNormalnij Oct 23, 2022
e69562d
Fix collision with engineFreeModel
TheNormalnij Oct 23, 2022
c926786
Fix clientside desync issues
TheNormalnij Oct 23, 2022
d94c450
Merge remote-tracking branch 'mta_main/master' into TheNormalnij/mode…
TheNormalnij Nov 28, 2022
51e3497
Merge branch 'master' into TheNormalnij/model_allocation_server
patrikjuvonen Dec 25, 2022
90d000f
Merge branch 'master' into TheNormalnij/model_allocation_server
patrikjuvonen Apr 8, 2023
2d06b28
Update CLuaFunctionParseHelpers.cpp
patrikjuvonen Apr 8, 2023
f290bf1
Update CVehiclesConfig.h
patrikjuvonen Apr 8, 2023
f88cb0b
Update CLuaEngineDefs.cpp
patrikjuvonen Apr 8, 2023
695cdf3
Update CClientModelManager.h
patrikjuvonen Apr 8, 2023
5ebc232
Rename SimpleModelAllocationg to SimpleModelAllocation
patrikjuvonen Apr 8, 2023
51c25c9
Update CHandlingConfig.h
patrikjuvonen Apr 8, 2023
e3d3d71
Update CHandlingConfig.cpp
patrikjuvonen Apr 8, 2023
fc710c3
Update CGame.cpp
patrikjuvonen Apr 8, 2023
ea20924
Merge branch 'master' into TheNormalnij/model_allocation_server
patrikjuvonen Apr 8, 2023
e42b687
Apply win-apply-clang-format.bat
patrikjuvonen Apr 8, 2023
4e96f2f
Merge branch 'master' into TheNormalnij/model_allocation_server
patrikjuvonen Apr 8, 2023
cee659c
Update CVehicleColors.cpp
patrikjuvonen Apr 8, 2023
e50f7b7
Update CPedConfig.cpp
patrikjuvonen Apr 8, 2023
2e13146
Update CObjectConfig.cpp
patrikjuvonen Apr 8, 2023
aeb3a12
Update CGame.cpp
patrikjuvonen Apr 8, 2023
edbb2a7
Update CPedConfig.h
patrikjuvonen Apr 8, 2023
e63ff7b
Update CObjectConfig.h
patrikjuvonen Apr 8, 2023
2b60f79
Update CModelVehicle.h
patrikjuvonen Apr 8, 2023
4e6c087
Update CModelVehicle.h
patrikjuvonen Apr 8, 2023
11ec287
Update CModelVehicle.cpp
patrikjuvonen Apr 8, 2023
323970e
Update CPlayerJoinCompletePacket.cpp
patrikjuvonen Apr 8, 2023
b2c7172
Fix header comments
patrikjuvonen Apr 8, 2023
e07956c
Fix header comments
patrikjuvonen Apr 8, 2023
8af33b3
Fix header comments
patrikjuvonen Apr 8, 2023
309f5b1
Fix header comments
patrikjuvonen Apr 8, 2023
5f018f6
Fix header comments
patrikjuvonen Apr 8, 2023
a1a3a5e
Fix header comments
patrikjuvonen Apr 8, 2023
911b091
Fix header comments
patrikjuvonen Apr 8, 2023
04f6f98
Fix header comments
patrikjuvonen Apr 8, 2023
1288dae
Fix header comments
patrikjuvonen Apr 8, 2023
9b534e9
Fix header comments
patrikjuvonen Apr 8, 2023
791dd4c
Merge remote-tracking branch 'mta_main/master' into TheNormalnij/mode…
TheNormalnij Jul 15, 2023
ddb35c7
Fix file headers
TheNormalnij Jul 15, 2023
4edb200
Merge branch 'master' into TheNormalnij/model_allocation_server
TheNormalnij Oct 9, 2023
4dab556
Fix conflicts
TheNormalnij Oct 9, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 8 additions & 8 deletions Client/game_sa/CModelInfoSA.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto v1.0
* PROJECT: Multi Theft Auto
* LICENSE: See LICENSE in the top level directory
* FILE: game_sa/CModelInfoSA.cpp
* PURPOSE: Entity model information handler
*
* Multi Theft Auto is available from http://www.multitheftauto.com/
* Multi Theft Auto is available from https://multitheftauto.com/
*
*****************************************************************************/

Expand Down Expand Up @@ -538,7 +538,7 @@ void CModelInfoSA::SetIdeFlags(unsigned int uiFlags)
switch (GetModelType())
{
case eModelInfoType::ATOMIC:
case eModelInfoType::TIME:
case eModelInfoType::TIMED_OBJECT:
{
// SetAtomicModelInfoFlags
m_pInterface->bIsRoad = ideFlags.bIsRoad;
Expand Down Expand Up @@ -842,7 +842,7 @@ bool CModelInfoSA::SetTime(char cHourOn, char cHourOff)
if (!m_pInterface)
return false;

if (GetModelType() != eModelInfoType::TIME)
if (GetModelType() != eModelInfoType::TIMED_OBJECT)
return false;

CTimeInfoSAInterface* pTime = &static_cast<CTimeModelInfoSAInterface*>(m_pInterface)->timeInfo;
Expand All @@ -861,7 +861,7 @@ bool CModelInfoSA::GetTime(char& cHourOn, char& cHourOff)
if (!m_pInterface)
return false;

if (GetModelType() != eModelInfoType::TIME)
if (GetModelType() != eModelInfoType::TIMED_OBJECT)
return false;

CTimeInfoSAInterface* pTime = &static_cast<CTimeModelInfoSAInterface*>(m_pInterface)->timeInfo;
Expand Down Expand Up @@ -1498,7 +1498,7 @@ bool CModelInfoSA::SetCustomModel(RpClump* pClump)
break;
case eModelInfoType::ATOMIC:
case eModelInfoType::LOD_ATOMIC:
case eModelInfoType::TIME:
case eModelInfoType::TIMED_OBJECT:
success = pGame->GetRenderWare()->ReplaceAllAtomicsInModel(pClump, static_cast<unsigned short>(m_dwModelID));
break;
default:
Expand Down Expand Up @@ -1804,7 +1804,7 @@ void CModelInfoSA::DeallocateModel(void)
case eModelInfoType::CLUMP:
delete reinterpret_cast<CClumpModelInfoSAInterface*>(ppModelInfo[m_dwModelID]);
break;
case eModelInfoType::TIME:
case eModelInfoType::TIMED_OBJECT:
delete reinterpret_cast<CTimeModelInfoSAInterface*>(ppModelInfo[m_dwModelID]);
break;
default:
Expand Down Expand Up @@ -2022,7 +2022,7 @@ void CModelInfoSA::RestoreAllObjectsPropertiesGroups()

eModelInfoType CModelInfoSA::GetModelType()
{
return ((eModelInfoType(*)())m_pInterface->VFTBL->GetModelType)();
return (eModelInfoType)((uint8_t(*)())m_pInterface->VFTBL->GetModelType)();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change std::uint8_t to uint8_t. Let's stick to C++ headers and namespaces

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer uint8_t in all cases. cstdint types are standard these days.
I think std:: for numbers adds too much noise.

Copy link
Contributor

@TracerDS TracerDS Jun 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer uint8_t in all cases. cstdint types are standard these days. I think std:: for numbers adds too much noise.

cstdint doesnt guarantee standard types in the global namespace but does guarantee having them in the std namespace
stdint.h doesnt guarantee standard types in the std namespace but does guarantee having them in the global namespace

If we go with cstdint (as we should) then std:: is required by a C++ standard (unless you do using on them)

In the end, its the matter of preference, right?

}

bool CModelInfoSA::IsTowableBy(CModelInfo* towingModel)
Expand Down
5 changes: 3 additions & 2 deletions Client/mods/deathmatch/logic/CClientModel.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto
* (Shared logic for modifications)
* LICENSE: See LICENSE in the top level directory
* FILE: mods/deathmatch/logic/CClientModel.h
* PURPOSE: Model handling class
*
* Multi Theft Auto is available from https://multitheftauto.com/
*
*****************************************************************************/

#include "StdInc.h"
Expand Down Expand Up @@ -152,8 +153,8 @@ void CClientModel::RestoreDFF(CModelInfo* pModelInfo)
unloadModelsAndCallEvents(pPedManager->IterBegin(), pPedManager->IterEnd(), 0, [](auto& element) { element.SetModel(0); });
break;
}
case eClientModelType::CLUMP:
case eClientModelType::OBJECT:
case eClientModelType::CLUMP:
case eClientModelType::TIMED_OBJECT:
{
const auto& objects = &g_pClientGame->GetManager()->GetObjectManager()->GetObjects();
Expand Down
5 changes: 3 additions & 2 deletions Client/mods/deathmatch/logic/CClientModel.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto
* (Shared logic for modifications)
* LICENSE: See LICENSE in the top level directory
* FILE: mods/deathmatch/logic/CClientModel.h
* PURPOSE: Model handling class
*
* Multi Theft Auto is available from https://multitheftauto.com/
*
*****************************************************************************/

class CClientModel;
Expand Down Expand Up @@ -33,7 +34,7 @@ class CClientModel final

public:
CClientModel(CClientManager* pManager, int iModelID, eClientModelType eModelType);
~CClientModel(void);
~CClientModel();

int GetModelID(void) const { return m_iModelID; };
eClientModelType GetModelType(void) const { return m_eModelType; };
Expand Down
60 changes: 56 additions & 4 deletions Client/mods/deathmatch/logic/CClientModelManager.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto
* (Shared logic for modifications)
* LICENSE: See LICENSE in the top level directory
* FILE: mods/deathmatch/logic/CClientModelManager.cpp
* PURPOSE: Model manager class
*
*****************************************************************************/

#include "StdInc.h"

CClientModelManager::CClientModelManager() : m_Models(std::make_unique<std::shared_ptr<CClientModel>[]>(g_pGame->GetBaseIDforCOL()))
{
const unsigned int uiMaxModelID = g_pGame->GetBaseIDforCOL();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

auto or std::uint32_t?

Expand Down Expand Up @@ -44,9 +44,8 @@ void CClientModelManager::Add(const std::shared_ptr<CClientModel>& pModel)
m_modelCount++;
}

bool CClientModelManager::Remove(const std::shared_ptr<CClientModel>& pModel)
bool CClientModelManager::Remove(const int modelId)
{
int modelId = pModel->GetModelID();
if (m_Models[modelId] != nullptr)
{
m_Models[modelId]->RestoreEntitiesUsingThisModel();
Expand All @@ -57,6 +56,18 @@ bool CClientModelManager::Remove(const std::shared_ptr<CClientModel>& pModel)
return false;
}

bool CClientModelManager::RemoveClientModel(const int modelId)
{
if (m_Models[modelId] == nullptr)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (!m_Models[modelId])

return false;

// Model was allocated clientside
if (!m_Models[modelId]->GetParentResource())
return false;

return Remove(modelId);
}

int CClientModelManager::GetFirstFreeModelID(void)
{
const unsigned int uiMaxModelID = g_pGame->GetBaseIDforCOL();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

auto or std::uint32_t?

Expand Down Expand Up @@ -124,6 +135,47 @@ void CClientModelManager::DeallocateModelsAllocatedByResource(CResource* pResour
for (unsigned int i = 0; i < uiMaxModelID; i++)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

auto maybe?

{
if (m_Models[i] != nullptr && m_Models[i]->GetParentResource() == pResource)
Remove(m_Models[i]);
Remove(i);
}
}

bool CClientModelManager::AllocateModelFromParent(uint32_t uiNewModelID, uint32_t uiParentModelID)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std::uint32_t instead of uint32_t

{
eModelInfoType eModelType = g_pGame->GetModelInfo(uiParentModelID)->GetModelType();

std::shared_ptr<CClientModel> pModel = FindModelByID(uiNewModelID);
if (pModel)
return false;

eClientModelType clientModelType;

switch (eModelType)
{
case eModelInfoType::ATOMIC:
clientModelType = eClientModelType::OBJECT;
break;
case eModelInfoType::TIMED_OBJECT:
clientModelType = eClientModelType::TIMED_OBJECT;
break;
case eModelInfoType::CLUMP:
clientModelType = eClientModelType::CLUMP;
break;
case eModelInfoType::VEHICLE:
clientModelType = eClientModelType::VEHICLE;
break;
case eModelInfoType::PED:
clientModelType = eClientModelType::PED;
break;
default:
return false;
}

pModel = std::make_shared<CClientModel>(g_pClientGame->GetManager(), uiNewModelID, clientModelType);

Add(pModel);

if (pModel->Allocate(uiParentModelID))
return true;

return false;
}
7 changes: 5 additions & 2 deletions Client/mods/deathmatch/logic/CClientModelManager.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto
* (Shared logic for modifications)
* LICENSE: See LICENSE in the top level directory
* FILE: mods/deathmatch/logic/CClientModelManager.h
* PURPOSE: Model manager class
*
* Multi Theft Auto is available from https://multitheftauto.com/
*
*****************************************************************************/

class CClientModelManager;
Expand All @@ -32,7 +33,8 @@ class CClientModelManager
void RemoveAll(void);

void Add(const std::shared_ptr<CClientModel>& pModel);
bool Remove(const std::shared_ptr<CClientModel>& pModel);
bool Remove(const int modelId);
bool RemoveClientModel(const int modelId);

int GetFirstFreeModelID(void);
int GetFreeTxdModelID();
Expand All @@ -43,6 +45,7 @@ class CClientModelManager
std::vector<std::shared_ptr<CClientModel>> GetModelsByType(eClientModelType type, const unsigned int minModelID = 0);

void DeallocateModelsAllocatedByResource(CResource* pResource);
bool AllocateModelFromParent(uint32_t usModelID, uint32_t usParentModel);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std::uint32_t instead of uint32_t


private:
std::unique_ptr<std::shared_ptr<CClientModel>[]> m_Models;
Expand Down
2 changes: 1 addition & 1 deletion Client/mods/deathmatch/logic/CClientObjectManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ bool CClientObjectManager::IsValidModel(unsigned long ulObjectModel)
return false;

eModelInfoType eType = pModelInfo->GetModelType();
return (eType == eModelInfoType::CLUMP || eType == eModelInfoType::ATOMIC || eType == eModelInfoType::WEAPON || eType == eModelInfoType::TIME);
return (eType == eModelInfoType::CLUMP || eType == eModelInfoType::ATOMIC || eType == eModelInfoType::WEAPON || eType == eModelInfoType::TIMED_OBJECT);
}

bool CClientObjectManager::IsBreakableModel(unsigned long ulObjectModel)
Expand Down
33 changes: 22 additions & 11 deletions Client/mods/deathmatch/logic/CClientVehicleManager.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto v1.0
* (Shared logic for modifications)
* PROJECT: Multi Theft Auto
* LICENSE: See LICENSE in the top level directory
* FILE: mods/shared_logic/CClientVehicleManager.cpp
* FILE: mods/deathmatch/logic/CClientVehicleManager.cpp
* PURPOSE: Vehicle entity manager class
*
* Multi Theft Auto is available from https://multitheftauto.com/
*
*****************************************************************************/

#include "StdInc.h"
Expand Down Expand Up @@ -432,6 +433,14 @@ bool CClientVehicleManager::IsStandardModel(unsigned long ulModel)
return ulModel >= 400 && ulModel <= 611;
}

unsigned long CClientVehicleManager::GetRootModelId(unsigned long ulModel)
{
if (IsStandardModel(ulModel))
return ulModel;

return g_pGame->GetModelInfo(ulModel)->GetParentID();
}

Comment on lines +436 to +443
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to change unsigned long to std::uint32_t or std::uint64_t?

eClientVehicleType CClientVehicleManager::GetVehicleType(unsigned long ulModel)
{
// Valid vehicle id?
Expand Down Expand Up @@ -625,42 +634,42 @@ unsigned char CClientVehicleManager::ConvertIndexToGameSeat(unsigned long ulMode

bool CClientVehicleManager::HasTurret(unsigned long ulModel)
{
return (IsStandardModel(ulModel) && (g_ulVehicleAttributes[ulModel - 400] & VEHICLE_HAS_TURRENT));
return ((g_ulVehicleAttributes[GetRootModelId(ulModel) - 400] & VEHICLE_HAS_TURRENT));
}

bool CClientVehicleManager::HasSirens(unsigned long ulModel)
{
return (IsStandardModel(ulModel) && (g_ulVehicleAttributes[ulModel - 400] & VEHICLE_HAS_SIRENS));
return ((g_ulVehicleAttributes[GetRootModelId(ulModel) - 400] & VEHICLE_HAS_SIRENS));
}

bool CClientVehicleManager::HasTaxiLight(unsigned long ulModel)
{
return (IsStandardModel(ulModel) && (g_ulVehicleAttributes[ulModel - 400] & VEHICLE_HAS_TAXI_LIGHTS));
return ((g_ulVehicleAttributes[GetRootModelId(ulModel) - 400] & VEHICLE_HAS_TAXI_LIGHTS));
}

bool CClientVehicleManager::HasSearchLight(unsigned long ulModel)
{
return (IsStandardModel(ulModel) && (g_ulVehicleAttributes[ulModel - 400] & VEHICLE_HAS_SEARCH_LIGHT));
return ((g_ulVehicleAttributes[GetRootModelId(ulModel) - 400] & VEHICLE_HAS_SEARCH_LIGHT));
}

bool CClientVehicleManager::HasLandingGears(unsigned long ulModel)
{
return (IsStandardModel(ulModel) && (g_ulVehicleAttributes[ulModel - 400] & VEHICLE_HAS_LANDING_GEARS));
return ((g_ulVehicleAttributes[GetRootModelId(ulModel) - 400] & VEHICLE_HAS_LANDING_GEARS));
}

bool CClientVehicleManager::HasAdjustableProperty(unsigned long ulModel)
{
return (IsStandardModel(ulModel) && (g_ulVehicleAttributes[ulModel - 400] & VEHICLE_HAS_ADJUSTABLE_PROPERTY));
return ((g_ulVehicleAttributes[GetRootModelId(ulModel) - 400] & VEHICLE_HAS_ADJUSTABLE_PROPERTY));
}

bool CClientVehicleManager::HasSmokeTrail(unsigned long ulModel)
{
return (IsStandardModel(ulModel) && (g_ulVehicleAttributes[ulModel - 400] & VEHICLE_HAS_SMOKE_TRAIL));
return ((g_ulVehicleAttributes[GetRootModelId(ulModel) - 400] & VEHICLE_HAS_SMOKE_TRAIL));
}

bool CClientVehicleManager::HasDamageModel(unsigned long ulModel)
{
return HasDamageModel(GetVehicleType(ulModel));
return HasDamageModel(GetVehicleType(GetRootModelId(ulModel)));
}

bool CClientVehicleManager::HasDamageModel(eClientVehicleType Type)
Expand All @@ -681,6 +690,8 @@ bool CClientVehicleManager::HasDamageModel(eClientVehicleType Type)

bool CClientVehicleManager::HasDoors(unsigned long ulModel)
{
ulModel = GetRootModelId(ulModel);

bool bHasDoors = false;

if (HasDamageModel(ulModel) == true)
Expand Down
8 changes: 5 additions & 3 deletions Client/mods/deathmatch/logic/CClientVehicleManager.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto v1.0
* (Shared logic for modifications)
* PROJECT: Multi Theft Auto
* LICENSE: See LICENSE in the top level directory
* FILE: mods/shared_logic/CClientVehicleManager.h
* FILE: mods/deathmatch/logic/CClientVehicleManager.h
* PURPOSE: Vehicle entity manager class header
*
* Multi Theft Auto is available from https://multitheftauto.com/
*
*****************************************************************************/

#pragma once
Expand Down Expand Up @@ -35,6 +36,7 @@ class CClientVehicleManager
static bool IsTrainModel(unsigned long ulModel);
static bool IsValidModel(unsigned long ulModel);
static bool IsStandardModel(unsigned long ulModel);
static unsigned long GetRootModelId(unsigned long ulModel);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to change unsigned long to std::uint32_t or std::uint64_t?

static eClientVehicleType GetVehicleType(unsigned long ulModel);
static unsigned char GetMaxPassengerCount(unsigned long ulModel);
static unsigned char ConvertIndexToGameSeat(unsigned long ulModel, unsigned char ucIndex);
Expand Down