Skip to content

Commit b066bc3

Browse files
author
G_Moris
committed
Refactor AddVehicle and AddTrain
1 parent 9610dbc commit b066bc3

File tree

16 files changed

+188
-198
lines changed

16 files changed

+188
-198
lines changed

Client/game_sa/CModelInfoSA.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -270,20 +270,21 @@ bool CModelInfoSA::IsTrailer()
270270
return bReturn;
271271
}
272272

273-
BYTE CModelInfoSA::GetVehicleType()
273+
BYTE CModelInfoSA::GetVehicleType() const noexcept
274274
{
275275
// This function will return a vehicle type for vehicles or 0xFF on failure
276-
DWORD dwFunction = FUNC_IsVehicleModelType;
277-
DWORD ModelID = m_dwModelID;
278-
BYTE bReturn = -1;
279-
_asm
276+
try
280277
{
281-
push ModelID
282-
call dwFunction
283-
mov bReturn, al
284-
add esp, 4
278+
if (!IsVehicle())
279+
return 0xFF;
280+
281+
auto GetVehicleModelType = reinterpret_cast<BYTE(__cdecl*)(DWORD)>(FUNC_IsVehicleModelType);
282+
return GetVehicleModelType(m_dwModelID);
283+
}
284+
catch (...)
285+
{
286+
return 0xFF;
285287
}
286-
return bReturn;
287288
}
288289

289290
bool CModelInfoSA::IsVehicle() const

Client/game_sa/CModelInfoSA.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ class CModelInfoSA : public CModelInfo
359359

360360
char* GetNameIfVehicle();
361361

362-
BYTE GetVehicleType();
362+
BYTE GetVehicleType() const noexcept;
363363
void Request(EModelRequestType requestType, const char* szTag);
364364
void Remove();
365365
bool UnloadUnused();

Client/game_sa/CPhysicalSA.cpp

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ void CPhysicalSA::RestoreLastGoodPhysicsState()
3939

4040
CVector vecDefault;
4141
SetTurnSpeed(&vecDefault);
42-
SetMoveSpeed(&vecDefault);
42+
SetMoveSpeed(vecDefault);
4343

4444
CPhysicalSAInterface* pInterface = (CPhysicalSAInterface*)GetInterface();
4545
pInterface->m_pad4d = 0;
@@ -100,24 +100,30 @@ CVector* CPhysicalSA::GetTurnSpeedInternal(CVector* vecTurnSpeed)
100100
return vecTurnSpeed;
101101
}
102102

103-
void CPhysicalSA::SetMoveSpeed(CVector* vecMoveSpeed)
103+
void CPhysicalSA::SetMoveSpeed(const CVector& vecMoveSpeed) noexcept
104104
{
105-
DWORD dwFunc = FUNC_GetMoveSpeed;
106-
DWORD dwThis = (DWORD)((CPhysicalSAInterface*)GetInterface());
107-
DWORD dwReturn = 0;
108-
109-
_asm
105+
try
110106
{
111-
mov ecx, dwThis
112-
call dwFunc
113-
mov dwReturn, eax
107+
DWORD dwFunc = FUNC_GetMoveSpeed;
108+
DWORD dwThis = (DWORD)((CPhysicalSAInterface*)GetInterface());
109+
DWORD dwReturn = 0;
110+
111+
__asm
112+
{
113+
mov ecx, dwThis
114+
call dwFunc
115+
mov dwReturn, eax
116+
}
117+
MemCpyFast((void*)dwReturn, &vecMoveSpeed, sizeof(CVector));
118+
119+
if (GetInterface()->nType == ENTITY_TYPE_OBJECT)
120+
{
121+
AddToMovingList();
122+
SetStatic(false);
123+
}
114124
}
115-
MemCpyFast((void*)dwReturn, vecMoveSpeed, sizeof(CVector));
116-
117-
if (GetInterface()->nType == ENTITY_TYPE_OBJECT)
125+
catch (...)
118126
{
119-
AddToMovingList();
120-
SetStatic(false);
121127
}
122128
}
123129

Client/game_sa/CPhysicalSA.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ class CPhysicalSA : public virtual CPhysical, public virtual CEntitySA
121121
CVector* GetTurnSpeed(CVector* vecTurnSpeed);
122122
CVector* GetMoveSpeedInternal(CVector* vecMoveSpeed);
123123
CVector* GetTurnSpeedInternal(CVector* vecTurnSpeed);
124-
void SetMoveSpeed(CVector* vecMoveSpeed);
124+
void SetMoveSpeed(const CVector& vecMoveSpeed) noexcept;
125125
void SetTurnSpeed(CVector* vecTurnSpeed);
126126

127127
float GetMass();

Client/game_sa/CPoolsSA.cpp

Lines changed: 104 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -75,68 +75,67 @@ CVehicle* CPoolsSA::AddVehicle(CClientVehicle* pClientVehicle, std::uint16_t mod
7575
{
7676
try
7777
{
78-
CVehicleSA* pVehicle = nullptr;
78+
if (m_vehiclePool.ulCount >= MAX_VEHICLES)
79+
return nullptr;
7980

80-
if (m_vehiclePool.ulCount < MAX_VEHICLES)
81-
{
82-
MemSetFast((void*)VAR_CVehicle_Variation1, variation, 1);
83-
MemSetFast((void*)VAR_CVehicle_Variation2, variation2, 1);
84-
85-
// CCarCtrl::CreateCarForScript
86-
CVehicleSAInterface* pInterface =
87-
((CVehicleSAInterface*(__cdecl*)(int, CVector, unsigned char)) FUNC_CCarCtrlCreateCarForScript)(model, CVector(0, 0, 0), 0);
81+
MemSetFast((void*)VAR_CVehicle_Variation1, variation, 1);
82+
MemSetFast((void*)VAR_CVehicle_Variation2, variation2, 1);
8883

89-
auto vehicleClass = static_cast<VehicleClass>(pGame->GetModelInfo(model)->GetVehicleType());
84+
// CCarCtrl::CreateCarForScript
85+
auto* pInterface = ((CVehicleSAInterface*(__cdecl*)(int, CVector, std::uint8_t))FUNC_CCarCtrlCreateCarForScript)(model, CVector(), 0);
86+
if (!pInterface)
87+
return nullptr;
9088

91-
switch (vehicleClass)
92-
{
93-
case VehicleClass::MONSTER_TRUCK:
94-
pVehicle = new CMonsterTruckSA(reinterpret_cast<CMonsterTruckSAInterface*>(pInterface));
95-
break;
96-
case VehicleClass::QUAD:
97-
pVehicle = new CQuadBikeSA(reinterpret_cast<CQuadBikeSAInterface*>(pInterface));
98-
break;
99-
case VehicleClass::HELI:
100-
pVehicle = new CHeliSA(reinterpret_cast<CHeliSAInterface*>(pInterface));
101-
break;
102-
case VehicleClass::PLANE:
103-
pVehicle = new CPlaneSA(reinterpret_cast<CPlaneSAInterface*>(pInterface));
104-
break;
105-
case VehicleClass::BOAT:
106-
pVehicle = new CBoatSA(reinterpret_cast<CBoatSAInterface*>(pInterface));
107-
break;
108-
case VehicleClass::TRAIN:
109-
pVehicle = new CTrainSA(reinterpret_cast<CTrainSAInterface*>(pInterface));
110-
break;
111-
case VehicleClass::BIKE:
112-
pVehicle = new CBikeSA(reinterpret_cast<CBikeSAInterface*>(pInterface));
113-
break;
114-
case VehicleClass::BMX:
115-
pVehicle = new CBmxSA(reinterpret_cast<CBmxSAInterface*>(pInterface));
116-
break;
117-
case VehicleClass::TRAILER:
118-
pVehicle = new CTrailerSA(reinterpret_cast<CTrailerSAInterface*>(pInterface));
119-
break;
120-
default:
121-
pVehicle = new CAutomobileSA(reinterpret_cast<CAutomobileSAInterface*>(pInterface));
122-
break;
123-
}
89+
const auto* modelInfo = pGame->GetModelInfo(model);
90+
if (!modelInfo || !modelInfo->IsVehicle())
91+
return nullptr;
12492

125-
if (pVehicle && AddVehicleToPool(pClientVehicle, pVehicle))
126-
{
127-
pVehicle->m_ucVariant = variation;
128-
pVehicle->m_ucVariant2 = variation2;
93+
auto vehicleClass = static_cast<VehicleClass>(modelInfo->GetVehicleType());
12994

130-
pVehicle->DumpVehicleFrames();
131-
}
132-
else
133-
{
134-
delete pVehicle;
135-
pVehicle = nullptr;
136-
}
95+
std::unique_ptr<CVehicleSA> vehicle = nullptr;
96+
switch (vehicleClass)
97+
{
98+
case VehicleClass::MONSTER_TRUCK:
99+
vehicle = std::make_unique<CMonsterTruckSA>(reinterpret_cast<CMonsterTruckSAInterface*>(pInterface));
100+
break;
101+
case VehicleClass::QUAD:
102+
vehicle = std::make_unique<CQuadBikeSA>(reinterpret_cast<CQuadBikeSAInterface*>(pInterface));
103+
break;
104+
case VehicleClass::HELI:
105+
vehicle = std::make_unique<CHeliSA>(reinterpret_cast<CHeliSAInterface*>(pInterface));
106+
break;
107+
case VehicleClass::PLANE:
108+
vehicle = std::make_unique<CPlaneSA>(reinterpret_cast<CPlaneSAInterface*>(pInterface));
109+
break;
110+
case VehicleClass::BOAT:
111+
vehicle = std::make_unique<CBoatSA>(reinterpret_cast<CBoatSAInterface*>(pInterface));
112+
break;
113+
case VehicleClass::TRAIN:
114+
vehicle = std::make_unique<CTrainSA>(reinterpret_cast<CTrainSAInterface*>(pInterface));
115+
break;
116+
case VehicleClass::BIKE:
117+
vehicle = std::make_unique<CBikeSA>(reinterpret_cast<CBikeSAInterface*>(pInterface));
118+
break;
119+
case VehicleClass::BMX:
120+
vehicle = std::make_unique<CBmxSA>(reinterpret_cast<CBmxSAInterface*>(pInterface));
121+
break;
122+
case VehicleClass::TRAILER:
123+
vehicle = std::make_unique<CTrailerSA>(reinterpret_cast<CTrailerSAInterface*>(pInterface));
124+
break;
125+
default:
126+
vehicle = std::make_unique<CAutomobileSA>(reinterpret_cast<CAutomobileSAInterface*>(pInterface));
127+
break;
137128
}
138129

139-
return pVehicle;
130+
if (!vehicle || !AddVehicleToPool(pClientVehicle, vehicle.get()))
131+
return nullptr;
132+
133+
vehicle->m_ucVariant = variation;
134+
vehicle->m_ucVariant2 = variation2;
135+
136+
vehicle->DumpVehicleFrames();
137+
138+
return vehicle.release();
140139
}
141140
catch (...)
142141
{
@@ -571,108 +570,85 @@ CClientEntity* CPoolsSA::GetClientEntity(DWORD* pGameInterface)
571570
return NULL;
572571
}
573572

574-
CVehicle* CPoolsSA::AddTrain(CClientVehicle* pClientVehicle, CVector* vecPosition, DWORD dwModels[], int iSize, bool bDirection, uchar ucTrackId)
573+
static void CreateMissionTrain(const CVector& vecPos, bool bDirection, std::uint32_t uiTrainType, CTrainSAInterface** ppTrainBeginning,
574+
CTrainSAInterface** ppTrainEnd, int iNodeIndex, int iTrackId, bool bMissionTrain) noexcept
575+
{
576+
try
577+
{
578+
auto createMissionTrain = reinterpret_cast<void(__cdecl*)(CVector, bool, std::uint32_t, CTrainSAInterface**, CTrainSAInterface**,
579+
int, int, bool)>(FUNC_CTrain_CreateMissionTrain);
580+
581+
createMissionTrain(vecPos, bDirection, uiTrainType, ppTrainBeginning, ppTrainEnd, iNodeIndex, iTrackId, bMissionTrain);
582+
}
583+
catch (...)
584+
{
585+
}
586+
}
587+
588+
CVehicle* CPoolsSA::AddTrain(CClientVehicle* pClientVehicle, const CVector& vecPosition, std::vector<DWORD> Models, bool bDirection,
589+
std::uint8_t ucTrackId) noexcept
575590
{
576591
// clean the existing array
577592
MemSetFast((void*)VAR_TrainModelArray, 0, 32 * sizeof(DWORD));
578593

579594
// now load the models we're going to use and add them to the array
580-
for (int i = 0; i < iSize; i++)
595+
std::size_t count = 0;
596+
for (const auto model : Models)
581597
{
582-
if (dwModels[i] == 449 || dwModels[i] == 537 || dwModels[i] == 538 || dwModels[i] == 569 || dwModels[i] == 590 || dwModels[i] == 570)
598+
if (model == 449 || model == 537 || model == 538 || model == 569 || model == 590 || model == 570)
583599
{
584-
MemPutFast<DWORD>(VAR_TrainModelArray + i * 4, dwModels[i]);
600+
MemPutFast<DWORD>(VAR_TrainModelArray + count * 4, model);
601+
count += 1;
585602
}
586603
}
587604

588-
CTrainSAInterface* pTrainBeginning = nullptr;
589-
CTrainSAInterface* pTrainEnd = nullptr;
590-
591-
float fX = vecPosition->fX;
592-
float fY = vecPosition->fY;
593-
float fZ = vecPosition->fZ;
594-
595605
// Disable GetVehicle because CreateMissionTrain calls it before our CVehicleSA instance is inited
596606
m_bGetVehicleEnabled = false;
597607

598608
// Find closest track node
599609
float fRailDistance;
600-
int iNodeId = pGame->GetWorld()->FindClosestRailTrackNode(*vecPosition, ucTrackId, fRailDistance);
610+
int iNodeId = pGame->GetWorld()->FindClosestRailTrackNode(vecPosition, ucTrackId, fRailDistance);
601611
int iDesiredTrackId = ucTrackId;
602612

603-
DWORD dwFunc = FUNC_CTrain_CreateMissionTrain;
604-
_asm
605-
{
606-
push 0 // place as close to point as possible (rather than at node)? (maybe) (actually seems to have an effect on the speed, so changed from
607-
// 1 to 0)
608-
push iDesiredTrackId // track ID
609-
push iNodeId // node to start at (-1 for closest node)
610-
lea ecx, pTrainEnd
611-
push ecx // end of train
612-
lea ecx, pTrainBeginning
613-
push ecx // begining of train
614-
push 0 // train type (always use 0 as thats where we're writing to)
615-
push bDirection // direction
616-
push fZ // z
617-
push fY // y
618-
push fX // x
619-
call dwFunc
620-
add esp, 0x28
621-
}
613+
CTrainSAInterface* pTrainBeginning = nullptr;
614+
CTrainSAInterface* pTrainEnd = nullptr;
615+
616+
CreateMissionTrain(vecPosition, bDirection, 0, &pTrainBeginning, &pTrainEnd, iNodeId, iDesiredTrackId, false);
622617

623618
// Enable GetVehicle
624619
m_bGetVehicleEnabled = true;
625620

626-
CVehicleSA* trainHead = NULL;
627-
if (pTrainBeginning)
628-
{
629-
DWORD vehicleIndex = 0;
621+
if (!pTrainBeginning || m_vehiclePool.ulCount >= MAX_VEHICLES)
622+
return nullptr;
630623

631-
if (m_vehiclePool.ulCount < MAX_VEHICLES)
632-
{
633-
trainHead = new CTrainSA(pTrainBeginning);
634-
if (!AddVehicleToPool(pClientVehicle, trainHead))
635-
{
636-
delete trainHead;
637-
trainHead = NULL;
638-
}
639-
else
640-
++vehicleIndex;
641-
}
624+
std::size_t vehicleIndex = 0;
625+
626+
std::unique_ptr<CVehicleSA> train = std::make_unique<CTrainSA>(pTrainBeginning);
627+
if (!train || !AddVehicleToPool(pClientVehicle, train.get()))
628+
return nullptr;
629+
630+
++vehicleIndex;
642631

643-
CVehicleSA* carriage = trainHead;
632+
CVehicleSA* pCarriage = train.get();
633+
while (m_vehiclePool.ulCount < MAX_VEHICLES && pCarriage && pCarriage->GetNextCarriageInTrain())
634+
{
635+
CTrainSAInterface* pVehCarriage = pCarriage->GetNextCarriageInTrain();
636+
if (!pVehCarriage)
637+
break;
644638

645-
while (carriage)
639+
auto newCarriage = std::make_unique<CTrainSA>(pVehCarriage);
640+
if (!newCarriage || !AddVehicleToPool(pClientVehicle, newCarriage.get()))
646641
{
647-
if (m_vehiclePool.ulCount < MAX_VEHICLES)
648-
{
649-
CTrainSAInterface* vehCarriage = carriage->GetNextCarriageInTrain();
650-
if (vehCarriage)
651-
{
652-
carriage = new CTrainSA(vehCarriage);
653-
if (!AddVehicleToPool(pClientVehicle, carriage))
654-
{
655-
delete carriage;
656-
carriage = NULL;
657-
}
658-
else
659-
++vehicleIndex;
660-
}
661-
else
662-
carriage = NULL;
663-
}
642+
newCarriage.reset();
643+
break;
664644
}
665-
}
666645

667-
// Stops the train from moving at ludacrist speeds right after creation
668-
// due to some glitch in the node finding in CreateMissionTrain
669-
CVector vec(0, 0, 0);
670-
if (trainHead)
671-
{
672-
trainHead->SetMoveSpeed(&vec);
646+
pCarriage = newCarriage.release();
647+
++vehicleIndex;
673648
}
674649

675-
return trainHead;
650+
train->SetMoveSpeed(CVector());
651+
return train.release();
676652
}
677653

678654
DWORD CPoolsSA::GetPedPoolIndex(std::uint8_t* pInterface)

Client/game_sa/CPoolsSA.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ class CPoolsSA : public CPools
7676
uint GetModelIdFromClump(RpClump* pRpClump);
7777

7878
// Others
79-
CVehicle* AddTrain(CClientVehicle* pClientVehicle, CVector* vecPosition, DWORD dwModels[], int iSize, bool bDirection, uchar ucTrackId = 0xFF);
79+
CVehicle* AddTrain(CClientVehicle* pClientVehicle, const CVector& vecPosition, std::vector<DWORD> Models, bool bDirection,
80+
std::uint8_t ucTrackId = 255) noexcept;
8081

8182
DWORD GetPedPoolIndex(std::uint8_t* pInterface);
8283
DWORD GetVehiclePoolIndex(std::uint8_t* pInterfacee);

0 commit comments

Comments
 (0)