diff options
Diffstat (limited to 'src/control/CarCtrl.cpp')
-rw-r--r-- | src/control/CarCtrl.cpp | 165 |
1 files changed, 145 insertions, 20 deletions
diff --git a/src/control/CarCtrl.cpp b/src/control/CarCtrl.cpp index 66e29b6c..8be39a86 100644 --- a/src/control/CarCtrl.cpp +++ b/src/control/CarCtrl.cpp @@ -20,6 +20,7 @@ #include "Ped.h" #include "PlayerInfo.h" #include "PlayerPed.h" +#include "Population.h" #include "Wanted.h" #include "Pools.h" #include "Renderer.h" @@ -69,6 +70,10 @@ #define MIN_ANGLE_TO_APPLY_HANDBRAKE 0.7f #define MIN_SPEED_TO_APPLY_HANDBRAKE 0.3f +#define PROBABILITY_OF_DEAD_PED_ACCIDENT 0.005f +#define DISTANCE_BETWEEN_CAR_AND_DEAD_PED 6.0f +#define PROBABILITY_OF_PASSENGER_IN_VEHICLE 0.125f + int CCarCtrl::NumLawEnforcerCars; int CCarCtrl::NumAmbulancesOnDuty; int CCarCtrl::NumFiretrucksOnDuty; @@ -83,6 +88,8 @@ int32 CCarCtrl::MaxNumberOfCarsInUse = 12; uint32 CCarCtrl::LastTimeLawEnforcerCreated; uint32 CCarCtrl::LastTimeFireTruckCreated; uint32 CCarCtrl::LastTimeAmbulanceCreated; +int32 CCarCtrl::MiamiViceCycle; +uint32 CCarCtrl::LastTimeMiamiViceGenerated; int32 CCarCtrl::TotalNumOfCarsOfRating[TOTAL_CUSTOM_CLASSES]; int32 CCarCtrl::CarArrays[TOTAL_CUSTOM_CLASSES][MAX_CAR_MODELS_IN_ARRAY]; int32 CCarCtrl::NumRequestsOfCarRating[TOTAL_CUSTOM_CLASSES]; @@ -291,10 +298,19 @@ CCarCtrl::GenerateOneRandomCar() CStreaming::RequestModel(MI_PREDATOR, STREAMFLAGS_DEPENDENCY); return; } - else { - return; - // TODO: normal boats + } + else { + int i; + carModel = -1; + for (i = 10; i > 0 && (carModel == -1 || !CStreaming::HasModelLoaded(carModel)); i--) { + carModel = ChooseBoatModel(ChooseBoatRating(&zone)); } + if (i == 0) + return; + } + if (pCurNode->bOnlySmallBoats || pNextNode->bOnlySmallBoats) { + if (BoatWithTallMast(carModel)) + return; } } int16 colliding; @@ -320,8 +336,8 @@ CCarCtrl::GenerateOneRandomCar() CVehicle* pVehicle; if (CModelInfo::IsBoatModel(carModel)) pVehicle = new CBoat(carModel, RANDOM_VEHICLE); - //else if (CModelInfo::IsBikeModel(carModel)) - // pVehicle = new CBike(carModel, RANDOM_VEHICLE); + else if (CModelInfo::IsBikeModel(carModel)) + return; // TODO(MIAMI): spawn bikes else pVehicle = new CAutomobile(carModel, RANDOM_VEHICLE); pVehicle->AutoPilot.m_nPrevRouteNode = 0; @@ -344,15 +360,15 @@ CCarCtrl::GenerateOneRandomCar() if (carModel == MI_FBICAR){ pVehicle->m_currentColour1 = 0; pVehicle->m_currentColour2 = 0; - /* FBI cars are gray in carcols, but we want them black if they going after player. */ } - // TODO(MIAMI): check the flag + pVehicle->bCreatedAsPoliceVehicle = true; break; case COPS_BOAT: pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE; pVehicle->AutoPilot.m_nCruiseSpeed = CGeneral::GetRandomNumberInRange(4.0f, 16.0f); pVehicle->AutoPilot.m_fMaxTrafficSpeed = pVehicle->AutoPilot.m_nCruiseSpeed; pVehicle->AutoPilot.m_nCarMission = CCarAI::FindPoliceBoatMissionForWantedLevel(); + pVehicle->bCreatedAsPoliceVehicle = true; break; default: pVehicle->AutoPilot.m_nCruiseSpeed = CGeneral::GetRandomNumberInRange(9, 14); @@ -445,6 +461,8 @@ CCarCtrl::GenerateOneRandomCar() /* Second fix: adding 0.5f is a mistake. It should be between 0 and 1. It was fixed in SA.*/ /* It is also correct in CAutoPilot::ModifySpeed. */ + + /* It seems like design decisions in VC were made based on this 0.5f addition. Can't remove it anymore. */ pVehicle->AutoPilot.m_nTimeEnteredCurve = CTimer::GetTimeInMilliseconds() - (uint32)((0.5f + positionBetweenNodes) * pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve); #else @@ -520,15 +538,21 @@ CCarCtrl::GenerateOneRandomCar() delete pVehicle; return; } - }else if((vecTargetPos - pVehicle->GetPosition()).Magnitude2D() > TheCamera.GenerationDistMultiplier * (pVehicle->bExtendedRange ? 1.5f : 1.0f) * 120.0f || - (vecTargetPos - pVehicle->GetPosition()).Magnitude2D() < TheCamera.GenerationDistMultiplier * 100.0f){ - delete pVehicle; - return; - }else if((TheCamera.GetPosition() - pVehicle->GetPosition()).Magnitude2D() < 82.5f * TheCamera.GenerationDistMultiplier || bTopDownCamera ){ - delete pVehicle; - return; + }else{ + if ((vecTargetPos - pVehicle->GetPosition()).Magnitude2D() > TheCamera.GenerationDistMultiplier * (pVehicle->bExtendedRange ? 1.5f : 1.0f) * 120.0f || + (vecTargetPos - pVehicle->GetPosition()).Magnitude2D() < TheCamera.GenerationDistMultiplier * 100.0f) { + delete pVehicle; + return; + } + if ((TheCamera.GetPosition() - pVehicle->GetPosition()).Magnitude2D() < 82.5f * TheCamera.GenerationDistMultiplier || bTopDownCamera) { + delete pVehicle; + return; + } + if (pVehicle->GetModelIndex() == MI_MARQUIS) { // so marquis can only spawn if player doesn't see it? + delete pVehicle; + return; + } } - // TODO(MIAMI): if MARQUIS then delete CVehicleModelInfo* pVehicleModel = pVehicle->GetModelInfo(); float radiusToTest = pVehicleModel->GetColModel()->boundingSphere.radius; if (testForCollision){ @@ -552,17 +576,93 @@ CCarCtrl::GenerateOneRandomCar() CWorld::Add(pVehicle); if (carClass == COPS || carClass == COPS_BOAT) CCarAI::AddPoliceCarOccupants(pVehicle); - else - pVehicle->SetUpDriver(); //TODO(MIAMI): FIX! - if ((CGeneral::GetRandomNumber() & 0x3F) == 0){ /* 1/64 probability */ /* TODO(MIAMI): FIX!*/ + else { + pVehicle->SetUpDriver(); + int32 passengers = 0; + for (int i = 0; i < pVehicle->m_nNumMaxPassengers; i++) + passengers += (CGeneral::GetRandomNumberInRange(0.0f, 1.0f) < PROBABILITY_OF_PASSENGER_IN_VEHICLE) ? 1 : 0; + if (CModelInfo::IsCarModel(carModel) && (CModelInfo::GetModelInfo(carModel)->GetAnimFileIndex() == CAnimManager::GetAnimationBlockIndex("van") && passengers >= 1)) + passengers = 1; + for (int i = 0; i < passengers; i++) { + CPed* pPassenger = pVehicle->SetupPassenger(i); + if (pPassenger) { + ++CPopulation::ms_nTotalCarPassengerPeds; + pPassenger->bCarPassenger = true; + } + } + } + int nMadDrivers; + switch (pVehicle->GetVehicleAppearance()) { + case VEHICLE_BIKE: + nMadDrivers = 30; + break; + case VEHICLE_BOAT: + nMadDrivers = 40; + break; + default: + nMadDrivers = 6; + break; + } + if ((CGeneral::GetRandomNumber() & 0x7F) < nMadDrivers /* TODO(MIAMI): || mad drivers cheat */) { pVehicle->SetStatus(STATUS_PHYSICS); pVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS; pVehicle->AutoPilot.m_nCruiseSpeed += 10; } if (carClass == COPS) LastTimeLawEnforcerCreated = CTimer::GetTimeInMilliseconds(); - /* TODO(MIAMI): CADDY, VICECHEE, dead ped code*/ - return; + if (pVehicle->GetModelIndex() == MI_CADDY) { + pVehicle->SetStatus(STATUS_PHYSICS); + pVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS; + } + if (carClass == COPS && pVehicle->GetModelIndex() == MI_VICECHEE) { + CVehicleModelInfo* pVehicleModel = (CVehicleModelInfo*)CModelInfo::GetModelInfo(MI_VICECHEE); + switch (MiamiViceCycle) { + case 0: + pVehicleModel->SetVehicleColour(53, 77); + break; + case 1: + pVehicleModel->SetVehicleColour(15, 77); + break; + case 2: + pVehicleModel->SetVehicleColour(41, 77); + break; + case 3: + pVehicleModel->SetVehicleColour(61, 77); + break; + default: + break; + } + } + if (CGeneral::GetRandomNumberInRange(0.0f, 1.0f) >= (1 - PROBABILITY_OF_DEAD_PED_ACCIDENT)) { + if (CModelInfo::IsCarModel(pVehicle->GetModelIndex()) && !pVehicle->bIsLawEnforcer) { + if (CPopulation::AddDeadPedInFrontOfCar(pVehicle->GetPosition() + pVehicle->GetForward() * DISTANCE_BETWEEN_CAR_AND_DEAD_PED, pVehicle)) { + pVehicle->AutoPilot.m_nCruiseSpeed = 0; + pVehicle->SetMoveSpeed(0.0f, 0.0f, 0.0f); + for (int i = 0; i < pVehicle->m_nNumPassengers; i++) { + if (pVehicle->pPassengers[i]) { + pVehicle->pPassengers[i]->SetObjective(OBJECTIVE_LEAVE_VEHICLE, pVehicle); + pVehicle->pPassengers[i]->m_nLastPedState = PED_WANDER_PATH; + pVehicle->pPassengers[i]->m_vehicleInAccident = pVehicle; + pVehicle->pPassengers[i]->bDeadPedInFrontOfCar = true; + pVehicle->RegisterReference((CEntity**)&pVehicle->pPassengers[i]->m_vehicleInAccident); + } + } + if (pVehicle->pDriver) { + pVehicle->pDriver->SetObjective(OBJECTIVE_LEAVE_VEHICLE, pVehicle); + pVehicle->pDriver->m_nLastPedState = PED_WANDER_PATH; + pVehicle->pDriver->m_vehicleInAccident = pVehicle; + pVehicle->pDriver->bDeadPedInFrontOfCar = true; + pVehicle->RegisterReference((CEntity**)&pVehicle->pDriver->m_vehicleInAccident); + } + } + } + } +} + +bool +CCarCtrl::BoatWithTallMast(int32 mi) +{ + return mi == MI_RIO || mi == MI_TROPIC || mi == MI_MARQUIS; } int32 @@ -680,6 +780,31 @@ CCarCtrl::ChooseCarModelToLoad(int rating) int32 CCarCtrl::ChoosePoliceCarModel(void) { + if (FindPlayerPed()->m_pWanted->AreMiamiViceRequired() && + CTimer::GetTimeInMilliseconds() > LastTimeMiamiViceGenerated + 120000 && + CStreaming::HasModelLoaded(MI_VICECHEE)) { + // TODO(MIAMI): setup correct models! + switch (MiamiViceCycle) { + case 0: + if (CStreaming::HasModelLoaded(MI_COP) && CStreaming::HasModelLoaded(MI_COP)) + return MI_VICECHEE; + break; + case 1: + if (CStreaming::HasModelLoaded(MI_COP) && CStreaming::HasModelLoaded(MI_COP)) + return MI_VICECHEE; + break; + case 2: + if (CStreaming::HasModelLoaded(MI_COP) && CStreaming::HasModelLoaded(MI_COP)) + return MI_VICECHEE; + break; + case 3: + if (CStreaming::HasModelLoaded(MI_COP) && CStreaming::HasModelLoaded(MI_COP)) + return MI_VICECHEE; + break; + default: + break; + } + } if (FindPlayerPed()->m_pWanted->AreSwatRequired() && CStreaming::HasModelLoaded(MI_ENFORCER) && CStreaming::HasModelLoaded(MI_POLICE)) |