CCarCtrl::GenerateOneRandomCar

This commit is contained in:
Nikolay Korolev
2020-05-08 23:29:43 +03:00
parent f902136b6a
commit 7e753c2596
19 changed files with 275 additions and 41 deletions

View File

@@ -13,6 +13,7 @@
#include "DMAudio.h"
#include "Fire.h"
#include "Pools.h"
#include "Population.h"
#include "Timer.h"
#include "TrafficLights.h"
#include "Vehicle.h"
@@ -560,18 +561,15 @@ void CCarAI::AddPoliceCarOccupants(CVehicle* pVehicle)
case MI_PREDATOR:
pVehicle->SetUpDriver();
return;
//TODO(MIAMI) uncomment this when we have MI_VICECHEE
/*
case MI_VICECHEE:
{
pVehicle->SetUpDriver()->bIsMiamiViceCop = true;
pVehicle->SetUpPassenger(0)->bIsMiamiViceCop = true;
pVehicle->SetUpDriver()->bMiamiViceCop = true;
pVehicle->SetupPassenger(0)->bMiamiViceCop = true;
CPopulation::NumMiamiViceCops += 2;
CCarCtrl::MiamiViceCycle = (CCarCtrl::MiamiViceCycle + 1) % 4;
CCarCtrl::LastTimeMiamiViceGenerated = CTimer::GetTimeInMilliseconds();
return;
}
*/
default:
return;
}

View File

@@ -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];
@@ -292,8 +299,17 @@ CCarCtrl::GenerateOneRandomCar()
return;
}
else {
return;
// TODO: normal boats
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;
}
}
}
@@ -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))

View File

@@ -124,7 +124,8 @@ public:
static int32 ChooseCarRating(CZoneInfo* pZoneInfo);
static void AddToLoadedVehicleArray(int32 mi, int32 rating, int32 freq);
static void RemoveFromLoadedVehicleArray(int32 mi, int32 rating);
static int32 ChooseCarModelToLoad(int rating);
static int32 ChooseCarModelToLoad(int32 rating);
static bool BoatWithTallMast(int32 mi);
static float GetPositionAlongCurrentCurve(CVehicle* pVehicle)
{
@@ -158,6 +159,8 @@ public:
static int32 TotalNumOfCarsOfRating[TOTAL_CUSTOM_CLASSES];
static int32 CarArrays[TOTAL_CUSTOM_CLASSES][MAX_CAR_MODELS_IN_ARRAY];
static int32 MiamiViceCycle;
static uint32 LastTimeMiamiViceGenerated;
static int32 NumRequestsOfCarRating[TOTAL_CUSTOM_CLASSES];
static int32 NumOfLoadedCarsOfRating[TOTAL_CUSTOM_CLASSES];
static int32 CarFreqArrays[TOTAL_CUSTOM_CLASSES][MAX_CAR_MODELS_IN_ARRAY];

View File

@@ -322,7 +322,7 @@ CPathFind::StoreNodeInfoPed(int16 id, int16 node, int8 type, int8 next, int16 x,
InfoForTilePeds[i].roadBlock = false;
InfoForTilePeds[i].disabled = false;
InfoForTilePeds[i].waterPath = false;
InfoForTilePeds[i].flag02 = false;
InfoForTilePeds[i].onlySmallBoats = false;
InfoForTilePeds[i].betweenLevels = false;
InfoForTilePeds[i].spawnRate = Min(spawnRate, 15);
@@ -351,7 +351,7 @@ CPathFind::StoreNodeInfoCar(int16 id, int16 node, int8 type, int8 next, int16 x,
InfoForTilePeds[i].roadBlock = false;
InfoForTilePeds[i].disabled = false;
InfoForTilePeds[i].waterPath = false;
InfoForTilePeds[i].flag02 = false;
InfoForTilePeds[i].onlySmallBoats = false;
InfoForTilePeds[i].betweenLevels = false;
InfoForTilePeds[i].spawnRate = Min(spawnRate, 15);
@@ -383,7 +383,7 @@ CPathFind::StoreDetachedNodeInfoPed(int32 node, int8 type, int32 next, float x,
DetachedInfoForTilePeds[i].roadBlock = false;
DetachedInfoForTilePeds[i].disabled = disabled;
DetachedInfoForTilePeds[i].waterPath = false;
DetachedInfoForTilePeds[i].flag02 = false;
DetachedInfoForTilePeds[i].onlySmallBoats = false;
DetachedInfoForTilePeds[i].betweenLevels = betweenLevels;
DetachedInfoForTilePeds[i].spawnRate = Min(spawnRate, 15);
@@ -396,7 +396,7 @@ CPathFind::StoreDetachedNodeInfoPed(int32 node, int8 type, int32 next, float x,
//--MIAMI: done
void
CPathFind::StoreDetachedNodeInfoCar(int32 node, int8 type, int32 next, float x, float y, float z, float width, int8 numLeft, int8 numRight,
bool disabled, bool betweenLevels, uint8 speedLimit, bool roadBlock, bool waterPath, uint8 spawnRate, bool unk)
bool disabled, bool betweenLevels, uint8 speedLimit, bool roadBlock, bool waterPath, uint8 spawnRate, bool onlySmallBoats)
{
int i;
@@ -417,7 +417,7 @@ CPathFind::StoreDetachedNodeInfoCar(int32 node, int8 type, int32 next, float x,
DetachedInfoForTileCars[i].roadBlock = roadBlock;
DetachedInfoForTileCars[i].disabled = disabled;
DetachedInfoForTileCars[i].waterPath = waterPath;
DetachedInfoForTileCars[i].flag02 = unk;
DetachedInfoForTileCars[i].onlySmallBoats = onlySmallBoats;
DetachedInfoForTileCars[i].betweenLevels = betweenLevels;
DetachedInfoForTileCars[i].spawnRate = Min(spawnRate, 15);
@@ -655,7 +655,7 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
m_pathNodes[m_numPathNodes].bUseInRoadBlock = objectpathinfo[start + j].roadBlock;
m_pathNodes[m_numPathNodes].bDisabled = objectpathinfo[start + j].disabled;
m_pathNodes[m_numPathNodes].bWaterPath = objectpathinfo[start + j].waterPath;
m_pathNodes[m_numPathNodes].flagB2 = objectpathinfo[start + j].flag02;
m_pathNodes[m_numPathNodes].bOnlySmallBoats = objectpathinfo[start + j].onlySmallBoats;
m_pathNodes[m_numPathNodes].bBetweenLevels = objectpathinfo[start + j].betweenLevels;
m_numPathNodes++;
}
@@ -696,7 +696,7 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
m_pathNodes[m_numPathNodes].bUseInRoadBlock = detachednodes[start + j].roadBlock;
m_pathNodes[m_numPathNodes].bDisabled = detachednodes[start + j].disabled;
m_pathNodes[m_numPathNodes].bWaterPath = detachednodes[start + j].waterPath;
m_pathNodes[m_numPathNodes].flagB2 = detachednodes[start + j].flag02;
m_pathNodes[m_numPathNodes].bOnlySmallBoats = detachednodes[start + j].onlySmallBoats;
m_pathNodes[m_numPathNodes].bBetweenLevels = detachednodes[start + j].betweenLevels;
m_numPathNodes++;
}else if(detachednodes[start + j].type == NodeTypeExtern){

View File

@@ -69,7 +69,7 @@ struct CPathNode
uint8 bUseInRoadBlock : 1;
uint8 bWaterPath : 1;
uint8 flagB2 : 1; // flag 2 in node info, always zero
uint8 bOnlySmallBoats : 1;
uint8 flagB4 : 1; // where is this set?
uint8 speedLimit : 2;
//uint8 flagB20 : 1;
@@ -145,7 +145,7 @@ struct CPathInfoForObject
int8 width;
uint8 crossing : 1;
uint8 flag02 : 1; // always zero
uint8 onlySmallBoats : 1;
uint8 roadBlock : 1;
uint8 disabled : 1;
uint8 waterPath : 1;

View File

@@ -3089,7 +3089,7 @@ int8 CRunningScript::ProcessCommands300To399(int32 command)
case COMMAND_SET_ZONE_CAR_INFO:
{
char label[12];
int16 gangDensities[NUM_GANGS];
int16 gangDensities[NUM_GANGS] = { 0 };
int i;
CTheScripts::ReadTextLabelFromScript(&m_nIp, label);
@@ -9849,8 +9849,8 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
case COMMAND_SET_ZONE_CIVILIAN_CAR_INFO:
{
char label[12];
int16 carDensities[CCarCtrl::NUM_CAR_CLASSES];
int16 boatDensities[CCarCtrl::NUM_BOAT_CLASSES];
int16 carDensities[CCarCtrl::NUM_CAR_CLASSES] = { 0 };
int16 boatDensities[CCarCtrl::NUM_BOAT_CLASSES] = { 0 };
int i;
CTheScripts::ReadTextLabelFromScript(&m_nIp, label);