@@ -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
678654DWORD CPoolsSA::GetPedPoolIndex (std::uint8_t * pInterface)
0 commit comments