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

Optimization Handling (part 3) and Remove big use eVehicleTypes #3848

Open
wants to merge 30 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
394df3a
Update
Moris-Onz Nov 8, 2024
b84fa60
Update 2
Moris-Onz Nov 8, 2024
6e8565e
Update 3
Moris-Onz Nov 8, 2024
203fb7c
Fix by TracerDS 1
Moris-Onz Nov 8, 2024
8ca57f0
Update 4
Moris-Onz Nov 9, 2024
1e6992d
Update 4 (mini fix)
Moris-Onz Nov 9, 2024
9610dbc
Fix crash
Moris-Onz Nov 9, 2024
b066bc3
Refactor AddVehicle and AddTrain
Moris-Onz Nov 10, 2024
e5113de
Update 5
Moris-Onz Nov 10, 2024
ffd2ba7
Update 5 (Fix)
Moris-Onz Nov 10, 2024
434457a
Update 6
Moris-Onz Nov 10, 2024
bea11d6
std::shared_ptr from CHandlingManagerSA
Moris-Onz Nov 10, 2024
96a3cc4
std::shared_ptr for CPoolsSA (Test)
Moris-Onz Nov 10, 2024
0f6246e
Revert "std::shared_ptr for CPoolsSA (Test)"
Moris-Onz Nov 10, 2024
3d0b407
std::unique_ptr for CPoolsSA
Moris-Onz Nov 10, 2024
f901042
Update 7
Moris-Onz Nov 11, 2024
bd79171
Add CModelInfoSA::IsVehicleModel
Moris-Onz Nov 11, 2024
0462828
Merge branch 'master' into clean-eVehicleTypes
G-Moris Nov 12, 2024
4888066
Merge branch 'master' into clean-eVehicleTypes
G-Moris Nov 15, 2024
1e87d4a
Merge branch 'master' into clean-eVehicleTypes
G-Moris Nov 16, 2024
e3b6707
Merge branch 'master' into clean-eVehicleTypes
G-Moris Nov 20, 2024
77efe2d
Merge branch 'master' into clean-eVehicleTypes
Dutchman101 Nov 21, 2024
55098d6
Merge branch 'master' into clean-eVehicleTypes
G-Moris Nov 21, 2024
fcc2c93
Merge branch 'master' into clean-eVehicleTypes
G-Moris Nov 22, 2024
8641aba
Merge branch 'master' into clean-eVehicleTypes
G-Moris Nov 27, 2024
d46c9df
Merge branch 'master' into clean-eVehicleTypes
G-Moris Nov 29, 2024
47068d4
Fixes by TheNormalnij
Moris-Onz Nov 29, 2024
b0cddf5
Merge branch 'clean-eVehicleTypes' of https://github.com/G-Moris/mtas…
Moris-Onz Nov 29, 2024
0486d25
Fix style
Moris-Onz Nov 29, 2024
ece4318
Merge branch 'master' into clean-eVehicleTypes
G-Moris Dec 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions Client/game_sa/CModelInfoSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,20 +270,21 @@ bool CModelInfoSA::IsTrailer()
return bReturn;
}

BYTE CModelInfoSA::GetVehicleType()
BYTE CModelInfoSA::GetVehicleType() const noexcept
{
// This function will return a vehicle type for vehicles or 0xFF on failure
DWORD dwFunction = FUNC_IsVehicleModelType;
DWORD ModelID = m_dwModelID;
BYTE bReturn = -1;
_asm
try
{
push ModelID
call dwFunction
mov bReturn, al
add esp, 4
if (!IsVehicle())
return 0xFF;
G-Moris marked this conversation as resolved.
Show resolved Hide resolved

auto GetVehicleModelType = reinterpret_cast<BYTE(__cdecl*)(DWORD)>(FUNC_IsVehicleModelType);
return GetVehicleModelType(m_dwModelID);
G-Moris marked this conversation as resolved.
Show resolved Hide resolved
}
catch (...)
{
return 0xFF;
G-Moris marked this conversation as resolved.
Show resolved Hide resolved
}
return bReturn;
}

bool CModelInfoSA::IsVehicle() const
Expand Down
2 changes: 1 addition & 1 deletion Client/game_sa/CModelInfoSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ class CModelInfoSA : public CModelInfo

char* GetNameIfVehicle();

BYTE GetVehicleType();
BYTE GetVehicleType() const noexcept;
void Request(EModelRequestType requestType, const char* szTag);
void Remove();
bool UnloadUnused();
Expand Down
36 changes: 21 additions & 15 deletions Client/game_sa/CPhysicalSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ void CPhysicalSA::RestoreLastGoodPhysicsState()

CVector vecDefault;
SetTurnSpeed(&vecDefault);
SetMoveSpeed(&vecDefault);
SetMoveSpeed(vecDefault);

CPhysicalSAInterface* pInterface = (CPhysicalSAInterface*)GetInterface();
pInterface->m_pad4d = 0;
Expand Down Expand Up @@ -100,24 +100,30 @@ CVector* CPhysicalSA::GetTurnSpeedInternal(CVector* vecTurnSpeed)
return vecTurnSpeed;
}

void CPhysicalSA::SetMoveSpeed(CVector* vecMoveSpeed)
void CPhysicalSA::SetMoveSpeed(const CVector& vecMoveSpeed) noexcept
{
DWORD dwFunc = FUNC_GetMoveSpeed;
DWORD dwThis = (DWORD)((CPhysicalSAInterface*)GetInterface());
DWORD dwReturn = 0;

_asm
try
{
mov ecx, dwThis
call dwFunc
mov dwReturn, eax
DWORD dwFunc = FUNC_GetMoveSpeed;
DWORD dwThis = (DWORD)((CPhysicalSAInterface*)GetInterface());
DWORD dwReturn = 0;

__asm
{
mov ecx, dwThis
call dwFunc
mov dwReturn, eax
}
MemCpyFast((void*)dwReturn, &vecMoveSpeed, sizeof(CVector));

if (GetInterface()->nType == ENTITY_TYPE_OBJECT)
{
AddToMovingList();
SetStatic(false);
}
}
MemCpyFast((void*)dwReturn, vecMoveSpeed, sizeof(CVector));

if (GetInterface()->nType == ENTITY_TYPE_OBJECT)
catch (...)
{
AddToMovingList();
SetStatic(false);
}
}

Expand Down
2 changes: 1 addition & 1 deletion Client/game_sa/CPhysicalSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ class CPhysicalSA : public virtual CPhysical, public virtual CEntitySA
CVector* GetTurnSpeed(CVector* vecTurnSpeed);
CVector* GetMoveSpeedInternal(CVector* vecMoveSpeed);
CVector* GetTurnSpeedInternal(CVector* vecTurnSpeed);
void SetMoveSpeed(CVector* vecMoveSpeed);
void SetMoveSpeed(const CVector& vecMoveSpeed) noexcept;
void SetTurnSpeed(CVector* vecTurnSpeed);

float GetMass();
Expand Down
232 changes: 104 additions & 128 deletions Client/game_sa/CPoolsSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,68 +75,67 @@ CVehicle* CPoolsSA::AddVehicle(CClientVehicle* pClientVehicle, std::uint16_t mod
{
try
{
CVehicleSA* pVehicle = nullptr;
if (m_vehiclePool.ulCount >= MAX_VEHICLES)
return nullptr;

if (m_vehiclePool.ulCount < MAX_VEHICLES)
{
MemSetFast((void*)VAR_CVehicle_Variation1, variation, 1);
MemSetFast((void*)VAR_CVehicle_Variation2, variation2, 1);

// CCarCtrl::CreateCarForScript
CVehicleSAInterface* pInterface =
((CVehicleSAInterface*(__cdecl*)(int, CVector, unsigned char)) FUNC_CCarCtrlCreateCarForScript)(model, CVector(0, 0, 0), 0);
MemSetFast((void*)VAR_CVehicle_Variation1, variation, 1);
MemSetFast((void*)VAR_CVehicle_Variation2, variation2, 1);

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

switch (vehicleClass)
{
case VehicleClass::MONSTER_TRUCK:
pVehicle = new CMonsterTruckSA(reinterpret_cast<CMonsterTruckSAInterface*>(pInterface));
break;
case VehicleClass::QUAD:
pVehicle = new CQuadBikeSA(reinterpret_cast<CQuadBikeSAInterface*>(pInterface));
break;
case VehicleClass::HELI:
pVehicle = new CHeliSA(reinterpret_cast<CHeliSAInterface*>(pInterface));
break;
case VehicleClass::PLANE:
pVehicle = new CPlaneSA(reinterpret_cast<CPlaneSAInterface*>(pInterface));
break;
case VehicleClass::BOAT:
pVehicle = new CBoatSA(reinterpret_cast<CBoatSAInterface*>(pInterface));
break;
case VehicleClass::TRAIN:
pVehicle = new CTrainSA(reinterpret_cast<CTrainSAInterface*>(pInterface));
break;
case VehicleClass::BIKE:
pVehicle = new CBikeSA(reinterpret_cast<CBikeSAInterface*>(pInterface));
break;
case VehicleClass::BMX:
pVehicle = new CBmxSA(reinterpret_cast<CBmxSAInterface*>(pInterface));
break;
case VehicleClass::TRAILER:
pVehicle = new CTrailerSA(reinterpret_cast<CTrailerSAInterface*>(pInterface));
break;
default:
pVehicle = new CAutomobileSA(reinterpret_cast<CAutomobileSAInterface*>(pInterface));
break;
}
const auto* modelInfo = pGame->GetModelInfo(model);
if (!modelInfo || !modelInfo->IsVehicle())
return nullptr;

if (pVehicle && AddVehicleToPool(pClientVehicle, pVehicle))
{
pVehicle->m_ucVariant = variation;
pVehicle->m_ucVariant2 = variation2;
auto vehicleClass = static_cast<VehicleClass>(modelInfo->GetVehicleType());

pVehicle->DumpVehicleFrames();
}
else
{
delete pVehicle;
pVehicle = nullptr;
}
std::unique_ptr<CVehicleSA> vehicle = nullptr;
switch (vehicleClass)
{
case VehicleClass::MONSTER_TRUCK:
vehicle = std::make_unique<CMonsterTruckSA>(reinterpret_cast<CMonsterTruckSAInterface*>(pInterface));
break;
case VehicleClass::QUAD:
vehicle = std::make_unique<CQuadBikeSA>(reinterpret_cast<CQuadBikeSAInterface*>(pInterface));
break;
case VehicleClass::HELI:
vehicle = std::make_unique<CHeliSA>(reinterpret_cast<CHeliSAInterface*>(pInterface));
break;
case VehicleClass::PLANE:
vehicle = std::make_unique<CPlaneSA>(reinterpret_cast<CPlaneSAInterface*>(pInterface));
break;
case VehicleClass::BOAT:
vehicle = std::make_unique<CBoatSA>(reinterpret_cast<CBoatSAInterface*>(pInterface));
break;
case VehicleClass::TRAIN:
vehicle = std::make_unique<CTrainSA>(reinterpret_cast<CTrainSAInterface*>(pInterface));
break;
case VehicleClass::BIKE:
vehicle = std::make_unique<CBikeSA>(reinterpret_cast<CBikeSAInterface*>(pInterface));
break;
case VehicleClass::BMX:
vehicle = std::make_unique<CBmxSA>(reinterpret_cast<CBmxSAInterface*>(pInterface));
break;
case VehicleClass::TRAILER:
vehicle = std::make_unique<CTrailerSA>(reinterpret_cast<CTrailerSAInterface*>(pInterface));
break;
default:
vehicle = std::make_unique<CAutomobileSA>(reinterpret_cast<CAutomobileSAInterface*>(pInterface));
break;
}

return pVehicle;
if (!vehicle || !AddVehicleToPool(pClientVehicle, vehicle.get()))
return nullptr;

vehicle->m_ucVariant = variation;
vehicle->m_ucVariant2 = variation2;

vehicle->DumpVehicleFrames();

return vehicle.release();
}
catch (...)
{
Expand Down Expand Up @@ -571,108 +570,85 @@ CClientEntity* CPoolsSA::GetClientEntity(DWORD* pGameInterface)
return NULL;
}

CVehicle* CPoolsSA::AddTrain(CClientVehicle* pClientVehicle, CVector* vecPosition, DWORD dwModels[], int iSize, bool bDirection, uchar ucTrackId)
static void CreateMissionTrain(const CVector& vecPos, bool bDirection, std::uint32_t uiTrainType, CTrainSAInterface** ppTrainBeginning,
CTrainSAInterface** ppTrainEnd, int iNodeIndex, int iTrackId, bool bMissionTrain) noexcept
{
try
{
auto createMissionTrain = reinterpret_cast<void(__cdecl*)(CVector, bool, std::uint32_t, CTrainSAInterface**, CTrainSAInterface**,
int, int, bool)>(FUNC_CTrain_CreateMissionTrain);

createMissionTrain(vecPos, bDirection, uiTrainType, ppTrainBeginning, ppTrainEnd, iNodeIndex, iTrackId, bMissionTrain);
}
catch (...)
{
}
}

CVehicle* CPoolsSA::AddTrain(CClientVehicle* pClientVehicle, const CVector& vecPosition, std::vector<DWORD> Models, bool bDirection,
std::uint8_t ucTrackId) noexcept
{
// clean the existing array
MemSetFast((void*)VAR_TrainModelArray, 0, 32 * sizeof(DWORD));

// now load the models we're going to use and add them to the array
for (int i = 0; i < iSize; i++)
std::size_t count = 0;
for (const auto model : Models)
{
if (dwModels[i] == 449 || dwModels[i] == 537 || dwModels[i] == 538 || dwModels[i] == 569 || dwModels[i] == 590 || dwModels[i] == 570)
if (model == 449 || model == 537 || model == 538 || model == 569 || model == 590 || model == 570)
{
MemPutFast<DWORD>(VAR_TrainModelArray + i * 4, dwModels[i]);
MemPutFast<DWORD>(VAR_TrainModelArray + count * 4, model);
count += 1;
}
}

CTrainSAInterface* pTrainBeginning = nullptr;
CTrainSAInterface* pTrainEnd = nullptr;

float fX = vecPosition->fX;
float fY = vecPosition->fY;
float fZ = vecPosition->fZ;

// Disable GetVehicle because CreateMissionTrain calls it before our CVehicleSA instance is inited
m_bGetVehicleEnabled = false;

// Find closest track node
float fRailDistance;
int iNodeId = pGame->GetWorld()->FindClosestRailTrackNode(*vecPosition, ucTrackId, fRailDistance);
int iNodeId = pGame->GetWorld()->FindClosestRailTrackNode(vecPosition, ucTrackId, fRailDistance);
int iDesiredTrackId = ucTrackId;

DWORD dwFunc = FUNC_CTrain_CreateMissionTrain;
_asm
{
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
// 1 to 0)
push iDesiredTrackId // track ID
push iNodeId // node to start at (-1 for closest node)
lea ecx, pTrainEnd
push ecx // end of train
lea ecx, pTrainBeginning
push ecx // begining of train
push 0 // train type (always use 0 as thats where we're writing to)
push bDirection // direction
push fZ // z
push fY // y
push fX // x
call dwFunc
add esp, 0x28
}
CTrainSAInterface* pTrainBeginning = nullptr;
CTrainSAInterface* pTrainEnd = nullptr;

CreateMissionTrain(vecPosition, bDirection, 0, &pTrainBeginning, &pTrainEnd, iNodeId, iDesiredTrackId, false);

// Enable GetVehicle
m_bGetVehicleEnabled = true;

CVehicleSA* trainHead = NULL;
if (pTrainBeginning)
{
DWORD vehicleIndex = 0;
if (!pTrainBeginning || m_vehiclePool.ulCount >= MAX_VEHICLES)
return nullptr;

if (m_vehiclePool.ulCount < MAX_VEHICLES)
{
trainHead = new CTrainSA(pTrainBeginning);
if (!AddVehicleToPool(pClientVehicle, trainHead))
{
delete trainHead;
trainHead = NULL;
}
else
++vehicleIndex;
}
std::size_t vehicleIndex = 0;

std::unique_ptr<CVehicleSA> train = std::make_unique<CTrainSA>(pTrainBeginning);
if (!train || !AddVehicleToPool(pClientVehicle, train.get()))
return nullptr;

++vehicleIndex;

CVehicleSA* carriage = trainHead;
CVehicleSA* pCarriage = train.get();
while (m_vehiclePool.ulCount < MAX_VEHICLES && pCarriage && pCarriage->GetNextCarriageInTrain())
{
CTrainSAInterface* pVehCarriage = pCarriage->GetNextCarriageInTrain();
if (!pVehCarriage)
break;

while (carriage)
auto newCarriage = std::make_unique<CTrainSA>(pVehCarriage);
if (!newCarriage || !AddVehicleToPool(pClientVehicle, newCarriage.get()))
{
if (m_vehiclePool.ulCount < MAX_VEHICLES)
{
CTrainSAInterface* vehCarriage = carriage->GetNextCarriageInTrain();
if (vehCarriage)
{
carriage = new CTrainSA(vehCarriage);
if (!AddVehicleToPool(pClientVehicle, carriage))
{
delete carriage;
carriage = NULL;
}
else
++vehicleIndex;
}
else
carriage = NULL;
}
newCarriage.reset();
break;
}
}

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

return trainHead;
train->SetMoveSpeed(CVector());
return train.release();
}

DWORD CPoolsSA::GetPedPoolIndex(std::uint8_t* pInterface)
Expand Down
3 changes: 2 additions & 1 deletion Client/game_sa/CPoolsSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ class CPoolsSA : public CPools
uint GetModelIdFromClump(RpClump* pRpClump);

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

DWORD GetPedPoolIndex(std::uint8_t* pInterface);
DWORD GetVehiclePoolIndex(std::uint8_t* pInterfacee);
Expand Down
Loading
Loading