mirror of
https://github.com/GTAmodding/re3.git
synced 2024-12-27 10:55:40 +00:00
more car control
This commit is contained in:
parent
e4683a3074
commit
2f7d2fa3ad
12 changed files with 370 additions and 187 deletions
|
@ -35,46 +35,50 @@
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
#include "Zones.h"
|
#include "Zones.h"
|
||||||
|
|
||||||
#define DISTANCE_TO_SPAWN_ROADBLOCK_PEDS 51.0f
|
#define DISTANCE_TO_SPAWN_ROADBLOCK_PEDS (51.0f)
|
||||||
#define DISTANCE_TO_SCAN_FOR_DANGER 11.0f
|
#define DISTANCE_TO_SCAN_FOR_DANGER (11.0f)
|
||||||
#define SAFE_DISTANCE_TO_PED 3.0f
|
#define SAFE_DISTANCE_TO_PED (3.0f)
|
||||||
#define INFINITE_Z 1000000000.0f
|
#define INFINITE_Z (1000000000.0f)
|
||||||
|
|
||||||
#define VEHICLE_HEIGHT_DIFF_TO_CONSIDER_WEAVING 4.0f
|
#define VEHICLE_HEIGHT_DIFF_TO_CONSIDER_WEAVING (4.0f)
|
||||||
#define PED_HEIGHT_DIFF_TO_CONSIDER_WEAVING 4.0f
|
#define PED_HEIGHT_DIFF_TO_CONSIDER_WEAVING (4.0f)
|
||||||
#define OBJECT_HEIGHT_DIFF_TO_CONSIDER_WEAVING 8.0f
|
#define OBJECT_HEIGHT_DIFF_TO_CONSIDER_WEAVING (8.0f)
|
||||||
#define WIDTH_COEF_TO_WEAVE_SAFELY 1.2f
|
#define WIDTH_COEF_TO_WEAVE_SAFELY (1.2f)
|
||||||
#define OBJECT_WIDTH_TO_WEAVE 0.3f
|
#define OBJECT_WIDTH_TO_WEAVE (0.3f)
|
||||||
#define PED_WIDTH_TO_WEAVE 0.8f
|
#define PED_WIDTH_TO_WEAVE (0.8f)
|
||||||
|
|
||||||
#define PATH_DIRECTION_NONE 0
|
#define PATH_DIRECTION_NONE (0)
|
||||||
#define PATH_DIRECTION_STRAIGHT 1
|
#define PATH_DIRECTION_STRAIGHT (1)
|
||||||
#define PATH_DIRECTION_RIGHT 2
|
#define PATH_DIRECTION_RIGHT (2)
|
||||||
#define PATH_DIRECTION_LEFT 4
|
#define PATH_DIRECTION_LEFT (4)
|
||||||
|
|
||||||
#define ATTEMPTS_TO_FIND_NEXT_NODE 15
|
#define ATTEMPTS_TO_FIND_NEXT_NODE (15)
|
||||||
|
|
||||||
#define DISTANCE_TO_SWITCH_FROM_BLOCK_TO_STOP 5.0f
|
#define DISTANCE_TO_SWITCH_FROM_BLOCK_TO_STOP (5.0f)
|
||||||
#define DISTANCE_TO_SWITCH_FROM_STOP_TO_BLOCK 10.0f
|
#define DISTANCE_TO_SWITCH_FROM_STOP_TO_BLOCK (10.0f)
|
||||||
#define MAX_SPEED_TO_ACCOUNT_IN_INTERCEPTING 0.13f
|
#define MAX_SPEED_TO_ACCOUNT_IN_INTERCEPTING (0.13f)
|
||||||
#define DISTANCE_TO_NEXT_NODE_TO_CONSIDER_SLOWING_DOWN 40.0f
|
#define DISTANCE_TO_NEXT_NODE_TO_CONSIDER_SLOWING_DOWN (40.0f)
|
||||||
#define MAX_ANGLE_TO_STEER_AT_HIGH_SPEED 0.2f
|
#define MAX_ANGLE_TO_STEER_AT_HIGH_SPEED (0.2f)
|
||||||
#define MIN_SPEED_TO_START_LIMITING_STEER 0.45f
|
#define MIN_SPEED_TO_START_LIMITING_STEER (0.45f)
|
||||||
#define DISTANCE_TO_NEXT_NODE_TO_SELECT_NEW 5.0f
|
#define DISTANCE_TO_NEXT_NODE_TO_SELECT_NEW (5.0f)
|
||||||
#define DISTANCE_TO_FACING_NEXT_NODE_TO_SELECT_NEW 8.0f
|
#define DISTANCE_TO_FACING_NEXT_NODE_TO_SELECT_NEW (8.0f)
|
||||||
#define DEFAULT_MAX_STEER_ANGLE 0.5f
|
#define DEFAULT_MAX_STEER_ANGLE (0.5f)
|
||||||
#define MIN_LOWERING_SPEED_COEFFICIENT 0.4f
|
#define MIN_LOWERING_SPEED_COEFFICIENT (0.4f)
|
||||||
#define MAX_ANGLE_FOR_SPEED_LIMITING 1.2f
|
#define MAX_ANGLE_FOR_SPEED_LIMITING (1.2f)
|
||||||
#define MIN_ANGLE_FOR_SPEED_LIMITING 0.4f
|
#define MIN_ANGLE_FOR_SPEED_LIMITING (0.4f)
|
||||||
#define MIN_ANGLE_FOR_SPEED_LIMITING_BETWEEN_NODES 0.1f
|
#define MIN_ANGLE_FOR_SPEED_LIMITING_BETWEEN_NODES (0.1f)
|
||||||
#define MIN_ANGLE_TO_APPLY_HANDBRAKE 0.7f
|
#define MIN_ANGLE_TO_APPLY_HANDBRAKE (0.7f)
|
||||||
#define MIN_SPEED_TO_APPLY_HANDBRAKE 0.3f
|
#define MIN_SPEED_TO_APPLY_HANDBRAKE (0.3f)
|
||||||
|
|
||||||
#define PROBABILITY_OF_DEAD_PED_ACCIDENT 0.005f
|
#define PROBABILITY_OF_DEAD_PED_ACCIDENT (0.005f)
|
||||||
#define DISTANCE_BETWEEN_CAR_AND_DEAD_PED 6.0f
|
#define DISTANCE_BETWEEN_CAR_AND_DEAD_PED (6.0f)
|
||||||
#define PROBABILITY_OF_PASSENGER_IN_VEHICLE 0.125f
|
#define PROBABILITY_OF_PASSENGER_IN_VEHICLE (0.125f)
|
||||||
|
|
||||||
#define FARAWAY_DISTANCE_REMOVAL 120.0f
|
#define ONSCREEN_DESPAWN_RANGE (120.0f)
|
||||||
|
#define MINIMAL_DISTANCE_TO_SPAWN_ONSCREEN (100.0f)
|
||||||
|
#define REQUEST_ONSCREEN_DISTANCE ((ONSCREEN_DESPAWN_RANGE + MINIMAL_DISTANCE_TO_SPAWN_ONSCREEN) / 2)
|
||||||
|
#define OFFSCREEN_DESPAWN_RANGE (40.0f)
|
||||||
|
#define EXTENDED_RANGE_DESPAWN_MULTIPLIER (1.5f)
|
||||||
|
|
||||||
int CCarCtrl::NumLawEnforcerCars;
|
int CCarCtrl::NumLawEnforcerCars;
|
||||||
int CCarCtrl::NumAmbulancesOnDuty;
|
int CCarCtrl::NumAmbulancesOnDuty;
|
||||||
|
@ -177,7 +181,7 @@ CCarCtrl::GenerateOneRandomCar()
|
||||||
angleLimit = -1.0f;
|
angleLimit = -1.0f;
|
||||||
bTopDownCamera = true;
|
bTopDownCamera = true;
|
||||||
invertAngleLimitTest = true;
|
invertAngleLimitTest = true;
|
||||||
preferredDistance = 55.0f;
|
preferredDistance = OFFSCREEN_DESPAWN_RANGE + 15.0f;
|
||||||
/* BUG: testForCollision not initialized in original game. */
|
/* BUG: testForCollision not initialized in original game. */
|
||||||
testForCollision = false;
|
testForCollision = false;
|
||||||
}else if (!pPlayerVehicle){
|
}else if (!pPlayerVehicle){
|
||||||
|
@ -191,14 +195,14 @@ CCarCtrl::GenerateOneRandomCar()
|
||||||
/* Forward to his current direction (camera direction). */
|
/* Forward to his current direction (camera direction). */
|
||||||
angleLimit = 0.707f; /* 45 degrees */
|
angleLimit = 0.707f; /* 45 degrees */
|
||||||
invertAngleLimitTest = true;
|
invertAngleLimitTest = true;
|
||||||
preferredDistance = 110.0f * TheCamera.GenerationDistMultiplier;
|
preferredDistance = REQUEST_ONSCREEN_DISTANCE * TheCamera.GenerationDistMultiplier;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
/* Spawn a vehicle close to player to his side. */
|
/* Spawn a vehicle close to player to his side. */
|
||||||
/* Kinda not within camera angle. */
|
/* Kinda not within camera angle. */
|
||||||
angleLimit = 0.707f; /* 45 degrees */
|
angleLimit = 0.707f; /* 45 degrees */
|
||||||
invertAngleLimitTest = false;
|
invertAngleLimitTest = false;
|
||||||
preferredDistance = 40.0f;
|
preferredDistance = OFFSCREEN_DESPAWN_RANGE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}else if (fPlayerVehicleSpeed > 0.4f){ /* 72 km/h */
|
}else if (fPlayerVehicleSpeed > 0.4f){ /* 72 km/h */
|
||||||
|
@ -213,21 +217,21 @@ CCarCtrl::GenerateOneRandomCar()
|
||||||
/* Spawn a vehicle in a very narrow gap in front of a player */
|
/* Spawn a vehicle in a very narrow gap in front of a player */
|
||||||
angleLimit = 0.85f; /* approx 30 degrees */
|
angleLimit = 0.85f; /* approx 30 degrees */
|
||||||
invertAngleLimitTest = true;
|
invertAngleLimitTest = true;
|
||||||
preferredDistance = 110.0f * TheCamera.GenerationDistMultiplier;
|
preferredDistance = REQUEST_ONSCREEN_DISTANCE * TheCamera.GenerationDistMultiplier;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
/* Spawn a vehicle relatively far away from player. */
|
/* Spawn a vehicle relatively far away from player. */
|
||||||
/* Forward to his current direction (camera direction). */
|
/* Forward to his current direction (camera direction). */
|
||||||
angleLimit = 0.707f; /* 45 degrees */
|
angleLimit = 0.707f; /* 45 degrees */
|
||||||
invertAngleLimitTest = true;
|
invertAngleLimitTest = true;
|
||||||
preferredDistance = 110.0f * TheCamera.GenerationDistMultiplier;
|
preferredDistance = REQUEST_ONSCREEN_DISTANCE * TheCamera.GenerationDistMultiplier;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
/* Spawn a vehicle close to player to his side. */
|
/* Spawn a vehicle close to player to his side. */
|
||||||
/* Kinda not within camera angle. */
|
/* Kinda not within camera angle. */
|
||||||
angleLimit = 0.707f; /* 45 degrees */
|
angleLimit = 0.707f; /* 45 degrees */
|
||||||
invertAngleLimitTest = false;
|
invertAngleLimitTest = false;
|
||||||
preferredDistance = 40.0f;
|
preferredDistance = OFFSCREEN_DESPAWN_RANGE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}else if (fPlayerVehicleSpeed > 0.1f){ /* 18 km/h */
|
}else if (fPlayerVehicleSpeed > 0.1f){ /* 18 km/h */
|
||||||
|
@ -241,14 +245,14 @@ CCarCtrl::GenerateOneRandomCar()
|
||||||
/* Spawn a vehicle in a very narrow gap in front of a player */
|
/* Spawn a vehicle in a very narrow gap in front of a player */
|
||||||
angleLimit = 0.85f; /* approx 30 degrees */
|
angleLimit = 0.85f; /* approx 30 degrees */
|
||||||
invertAngleLimitTest = true;
|
invertAngleLimitTest = true;
|
||||||
preferredDistance = 110.0f * TheCamera.GenerationDistMultiplier;
|
preferredDistance = REQUEST_ONSCREEN_DISTANCE * TheCamera.GenerationDistMultiplier;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
/* Spawn a vehicle relatively far away from player. */
|
/* Spawn a vehicle relatively far away from player. */
|
||||||
/* Forward to his current direction (camera direction). */
|
/* Forward to his current direction (camera direction). */
|
||||||
angleLimit = 0.707f; /* 45 degrees */
|
angleLimit = 0.707f; /* 45 degrees */
|
||||||
invertAngleLimitTest = true;
|
invertAngleLimitTest = true;
|
||||||
preferredDistance = 110.0f * TheCamera.GenerationDistMultiplier;
|
preferredDistance = REQUEST_ONSCREEN_DISTANCE * TheCamera.GenerationDistMultiplier;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
case 3:
|
case 3:
|
||||||
|
@ -256,7 +260,7 @@ CCarCtrl::GenerateOneRandomCar()
|
||||||
/* Kinda not within camera angle. */
|
/* Kinda not within camera angle. */
|
||||||
angleLimit = 0.707f; /* 45 degrees */
|
angleLimit = 0.707f; /* 45 degrees */
|
||||||
invertAngleLimitTest = false;
|
invertAngleLimitTest = false;
|
||||||
preferredDistance = 40.0f;
|
preferredDistance = OFFSCREEN_DESPAWN_RANGE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
|
@ -271,14 +275,14 @@ CCarCtrl::GenerateOneRandomCar()
|
||||||
/* Forward to his current direction (camera direction). */
|
/* Forward to his current direction (camera direction). */
|
||||||
angleLimit = 0.707f; /* 45 degrees */
|
angleLimit = 0.707f; /* 45 degrees */
|
||||||
invertAngleLimitTest = true;
|
invertAngleLimitTest = true;
|
||||||
preferredDistance = 110.0f * TheCamera.GenerationDistMultiplier;
|
preferredDistance = REQUEST_ONSCREEN_DISTANCE * TheCamera.GenerationDistMultiplier;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
/* Spawn a vehicle close to player to his side. */
|
/* Spawn a vehicle close to player to his side. */
|
||||||
/* Kinda not within camera angle. */
|
/* Kinda not within camera angle. */
|
||||||
angleLimit = 0.707f; /* 45 degrees */
|
angleLimit = 0.707f; /* 45 degrees */
|
||||||
invertAngleLimitTest = false;
|
invertAngleLimitTest = false;
|
||||||
preferredDistance = 40.0f;
|
preferredDistance = OFFSCREEN_DESPAWN_RANGE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -586,20 +590,21 @@ CCarCtrl::GenerateOneRandomCar()
|
||||||
case COPS_BOAT:
|
case COPS_BOAT:
|
||||||
pVehicle->ChangeLawEnforcerState(1);
|
pVehicle->ChangeLawEnforcerState(1);
|
||||||
pVehicle->SetStatus(STATUS_PHYSICS);
|
pVehicle->SetStatus(STATUS_PHYSICS);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
pVehicle->SetStatus(STATUS_SIMPLE);
|
bBoatGenerated ? pVehicle->SetStatus(STATUS_PHYSICS) : pVehicle->SetStatus(STATUS_SIMPLE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
CVisibilityPlugins::SetClumpAlpha(pVehicle->GetClump(), 0);
|
CVisibilityPlugins::SetClumpAlpha(pVehicle->GetClump(), 0);
|
||||||
if (!pVehicle->GetIsOnScreen()){
|
if (!pVehicle->GetIsOnScreen()){
|
||||||
if ((vecTargetPos - pVehicle->GetPosition()).Magnitude2D() > 40.0f * (pVehicle->bExtendedRange ? 1.5f : 1.0f)) {
|
if ((vecTargetPos - pVehicle->GetPosition()).Magnitude2D() > OFFSCREEN_DESPAWN_RANGE * (pVehicle->bExtendedRange ? EXTENDED_RANGE_DESPAWN_MULTIPLIER : 1.0f)) {
|
||||||
/* Too far away cars that are not visible aren't needed. */
|
/* Too far away cars that are not visible aren't needed. */
|
||||||
delete pVehicle;
|
delete pVehicle;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
if ((vecTargetPos - pVehicle->GetPosition()).Magnitude2D() > TheCamera.GenerationDistMultiplier * (pVehicle->bExtendedRange ? 1.5f : 1.0f) * FARAWAY_DISTANCE_REMOVAL ||
|
if ((vecTargetPos - pVehicle->GetPosition()).Magnitude2D() > TheCamera.GenerationDistMultiplier * (pVehicle->bExtendedRange ? EXTENDED_RANGE_DESPAWN_MULTIPLIER : 1.0f) * ONSCREEN_DESPAWN_RANGE ||
|
||||||
(vecTargetPos - pVehicle->GetPosition()).Magnitude2D() < TheCamera.GenerationDistMultiplier * 100.0f) {
|
(vecTargetPos - pVehicle->GetPosition()).Magnitude2D() < TheCamera.GenerationDistMultiplier * MINIMAL_DISTANCE_TO_SPAWN_ONSCREEN) {
|
||||||
delete pVehicle;
|
delete pVehicle;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -840,24 +845,27 @@ int32
|
||||||
CCarCtrl::ChoosePoliceCarModel(void)
|
CCarCtrl::ChoosePoliceCarModel(void)
|
||||||
{
|
{
|
||||||
if (FindPlayerPed()->m_pWanted->AreMiamiViceRequired() &&
|
if (FindPlayerPed()->m_pWanted->AreMiamiViceRequired() &&
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
(CTimer::GetTimeInMilliseconds() > LastTimeMiamiViceGenerated + 120000 || LastTimeMiamiViceGenerated == 0) &&
|
||||||
|
#else
|
||||||
CTimer::GetTimeInMilliseconds() > LastTimeMiamiViceGenerated + 120000 &&
|
CTimer::GetTimeInMilliseconds() > LastTimeMiamiViceGenerated + 120000 &&
|
||||||
|
#endif
|
||||||
CStreaming::HasModelLoaded(MI_VICECHEE)) {
|
CStreaming::HasModelLoaded(MI_VICECHEE)) {
|
||||||
// TODO(MIAMI): setup correct models!
|
|
||||||
switch (MiamiViceCycle) {
|
switch (MiamiViceCycle) {
|
||||||
case 0:
|
case 0:
|
||||||
if (CStreaming::HasModelLoaded(MI_COP) && CStreaming::HasModelLoaded(MI_COP))
|
if (CStreaming::HasModelLoaded(MI_VICE1) && CStreaming::HasModelLoaded(MI_VICE2))
|
||||||
return MI_VICECHEE;
|
return MI_VICECHEE;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
if (CStreaming::HasModelLoaded(MI_COP) && CStreaming::HasModelLoaded(MI_COP))
|
if (CStreaming::HasModelLoaded(MI_VICE3) && CStreaming::HasModelLoaded(MI_VICE4))
|
||||||
return MI_VICECHEE;
|
return MI_VICECHEE;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if (CStreaming::HasModelLoaded(MI_COP) && CStreaming::HasModelLoaded(MI_COP))
|
if (CStreaming::HasModelLoaded(MI_VICE5) && CStreaming::HasModelLoaded(MI_VICE6))
|
||||||
return MI_VICECHEE;
|
return MI_VICECHEE;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
if (CStreaming::HasModelLoaded(MI_COP) && CStreaming::HasModelLoaded(MI_COP))
|
if (CStreaming::HasModelLoaded(MI_VICE7) && CStreaming::HasModelLoaded(MI_VICE8))
|
||||||
return MI_VICECHEE;
|
return MI_VICECHEE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -956,7 +964,7 @@ CCarCtrl::PossiblyRemoveVehicle(CVehicle* pVehicle)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
float distanceToPlayer = (pVehicle->GetPosition() - vecPlayerPos).Magnitude2D();
|
float distanceToPlayer = (pVehicle->GetPosition() - vecPlayerPos).Magnitude2D();
|
||||||
float threshold = 40.0f;
|
float threshold = OFFSCREEN_DESPAWN_RANGE;
|
||||||
if (pVehicle->GetIsOnScreen() ||
|
if (pVehicle->GetIsOnScreen() ||
|
||||||
TheCamera.Cams[TheCamera.ActiveCam].LookingLeft ||
|
TheCamera.Cams[TheCamera.ActiveCam].LookingLeft ||
|
||||||
TheCamera.Cams[TheCamera.ActiveCam].LookingRight ||
|
TheCamera.Cams[TheCamera.ActiveCam].LookingRight ||
|
||||||
|
@ -968,12 +976,12 @@ CCarCtrl::PossiblyRemoveVehicle(CVehicle* pVehicle)
|
||||||
pVehicle->bIsLawEnforcer ||
|
pVehicle->bIsLawEnforcer ||
|
||||||
pVehicle->bIsCarParkVehicle
|
pVehicle->bIsCarParkVehicle
|
||||||
){
|
){
|
||||||
threshold = FARAWAY_DISTANCE_REMOVAL * TheCamera.GenerationDistMultiplier;
|
threshold = ONSCREEN_DESPAWN_RANGE * TheCamera.GenerationDistMultiplier;
|
||||||
}
|
}
|
||||||
if (TheCamera.GetForward().z < -0.9f)
|
if (TheCamera.GetForward().z < -0.9f)
|
||||||
threshold = 70.0f;
|
threshold = 70.0f;
|
||||||
if (pVehicle->bExtendedRange)
|
if (pVehicle->bExtendedRange)
|
||||||
threshold *= 1.5f;
|
threshold *= EXTENDED_RANGE_DESPAWN_MULTIPLIER;
|
||||||
if (distanceToPlayer > threshold && !CGarages::IsPointWithinHideOutGarage(pVehicle->GetPosition())){
|
if (distanceToPlayer > threshold && !CGarages::IsPointWithinHideOutGarage(pVehicle->GetPosition())){
|
||||||
if (pVehicle->GetIsOnScreen()){
|
if (pVehicle->GetIsOnScreen()){
|
||||||
pVehicle->bFadeOut = true;
|
pVehicle->bFadeOut = true;
|
||||||
|
@ -1553,12 +1561,13 @@ void CCarCtrl::WeaveThroughCarsSectorList(CPtrList& lst, CVehicle* pVehicle, CPh
|
||||||
|
|
||||||
void CCarCtrl::WeaveForOtherCar(CEntity* pOtherEntity, CVehicle* pVehicle, float* pAngleToWeaveLeft, float* pAngleToWeaveRight)
|
void CCarCtrl::WeaveForOtherCar(CEntity* pOtherEntity, CVehicle* pVehicle, float* pAngleToWeaveLeft, float* pAngleToWeaveRight)
|
||||||
{
|
{
|
||||||
// TODO(MIAMI):
|
CVehicle* pOtherCar = (CVehicle*)pOtherEntity;
|
||||||
|
if (pVehicle->bPartOfConvoy && pOtherCar->bPartOfConvoy)
|
||||||
|
return;
|
||||||
if (pVehicle->AutoPilot.m_nCarMission == MISSION_RAMPLAYER_CLOSE && pOtherEntity == FindPlayerVehicle())
|
if (pVehicle->AutoPilot.m_nCarMission == MISSION_RAMPLAYER_CLOSE && pOtherEntity == FindPlayerVehicle())
|
||||||
return;
|
return;
|
||||||
if (pVehicle->AutoPilot.m_nCarMission == MISSION_RAMCAR_CLOSE && pOtherEntity == pVehicle->AutoPilot.m_pTargetCar)
|
if (pVehicle->AutoPilot.m_nCarMission == MISSION_RAMCAR_CLOSE && pOtherEntity == pVehicle->AutoPilot.m_pTargetCar)
|
||||||
return;
|
return;
|
||||||
CVehicle* pOtherCar = (CVehicle*)pOtherEntity;
|
|
||||||
CVector2D vecDiff = pOtherCar->GetPosition() - pVehicle->GetPosition();
|
CVector2D vecDiff = pOtherCar->GetPosition() - pVehicle->GetPosition();
|
||||||
float angleBetweenVehicles = CGeneral::GetATanOfXY(vecDiff.x, vecDiff.y);
|
float angleBetweenVehicles = CGeneral::GetATanOfXY(vecDiff.x, vecDiff.y);
|
||||||
float distance = vecDiff.Magnitude();
|
float distance = vecDiff.Magnitude();
|
||||||
|
@ -1958,11 +1967,13 @@ void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float t
|
||||||
void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float targetY, CVehicle* pTarget)
|
void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float targetY, CVehicle* pTarget)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
if (pVehicle->m_nRouteSeed)
|
||||||
|
CGeneral::SetRandomSeed(pVehicle->m_nRouteSeed);
|
||||||
int prevNode = pVehicle->AutoPilot.m_nCurrentRouteNode;
|
int prevNode = pVehicle->AutoPilot.m_nCurrentRouteNode;
|
||||||
int curNode = pVehicle->AutoPilot.m_nNextRouteNode;
|
int curNode = pVehicle->AutoPilot.m_nNextRouteNode;
|
||||||
CPathNode* pPrevNode = &ThePaths.m_pathNodes[prevNode];
|
CPathNode* pPrevNode = &ThePaths.m_pathNodes[prevNode];
|
||||||
CPathNode* pCurNode = &ThePaths.m_pathNodes[curNode];
|
CPathNode* pCurNode = &ThePaths.m_pathNodes[curNode];
|
||||||
CPathNode* pTargetNode;
|
CPathNode* pTargetNode[2];
|
||||||
int16 numNodes;
|
int16 numNodes;
|
||||||
float distanceToTargetNode;
|
float distanceToTargetNode;
|
||||||
ThePaths.DoPathSearch(0, pCurNode->GetPosition(), curNode,
|
ThePaths.DoPathSearch(0, pCurNode->GetPosition(), curNode,
|
||||||
|
@ -1971,33 +1982,42 @@ void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float t
|
||||||
#else
|
#else
|
||||||
CVector(targetX, targetY, 0.0f),
|
CVector(targetX, targetY, 0.0f),
|
||||||
#endif
|
#endif
|
||||||
&pTargetNode, &numNodes, 1, pVehicle, &distanceToTargetNode, 999999.9f, -1);
|
pTargetNode, &numNodes, 2, pVehicle, &distanceToTargetNode, 999999.9f, -1);
|
||||||
|
|
||||||
int newNextNode;
|
int newNextNode;
|
||||||
int nextLink;
|
int nextLink;
|
||||||
if (numNodes != 1 || pTargetNode == pCurNode){
|
if (numNodes != 1 && numNodes != 2 || pTargetNode[0] == pCurNode){
|
||||||
float currentAngle = CGeneral::GetATanOfXY(targetX - pVehicle->GetPosition().x, targetY - pVehicle->GetPosition().y);
|
if (numNodes != 2 || pTargetNode[1] == pCurNode) {
|
||||||
nextLink = 0;
|
float currentAngle = CGeneral::GetATanOfXY(targetX - pVehicle->GetPosition().x, targetY - pVehicle->GetPosition().y);
|
||||||
float lowestAngleChange = 10.0f;
|
nextLink = 0;
|
||||||
int numLinks = pCurNode->numLinks;
|
float lowestAngleChange = 10.0f;
|
||||||
newNextNode = 0;
|
int numLinks = pCurNode->numLinks;
|
||||||
for (int i = 0; i < numLinks; i++){
|
newNextNode = 0;
|
||||||
int conNode = ThePaths.ConnectedNode(i + pCurNode->firstLink);
|
for (int i = 0; i < numLinks; i++) {
|
||||||
if (conNode == prevNode && i > 1)
|
int conNode = ThePaths.ConnectedNode(i + pCurNode->firstLink);
|
||||||
continue;
|
if (conNode == prevNode && i > 1)
|
||||||
CPathNode* pTestNode = &ThePaths.m_pathNodes[conNode];
|
continue;
|
||||||
float angle = CGeneral::GetATanOfXY(pTestNode->GetX() - pCurNode->GetX(), pTestNode->GetY() - pCurNode->GetY());
|
CPathNode* pTestNode = &ThePaths.m_pathNodes[conNode];
|
||||||
angle = LimitRadianAngle(angle - currentAngle);
|
float angle = CGeneral::GetATanOfXY(pTestNode->GetX() - pCurNode->GetX(), pTestNode->GetY() - pCurNode->GetY());
|
||||||
angle = ABS(angle);
|
angle = LimitRadianAngle(angle - currentAngle);
|
||||||
if (angle < lowestAngleChange){
|
angle = ABS(angle);
|
||||||
lowestAngleChange = angle;
|
if (angle < lowestAngleChange) {
|
||||||
newNextNode = conNode;
|
lowestAngleChange = angle;
|
||||||
nextLink = i;
|
newNextNode = conNode;
|
||||||
|
nextLink = i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
else {
|
||||||
|
nextLink = 0;
|
||||||
|
newNextNode = pTargetNode[1] - ThePaths.m_pathNodes;
|
||||||
|
for (int i = pCurNode->firstLink; ThePaths.ConnectedNode(i) != newNextNode; i++, nextLink++)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
nextLink = 0;
|
nextLink = 0;
|
||||||
newNextNode = pTargetNode - ThePaths.m_pathNodes;
|
newNextNode = pTargetNode[0] - ThePaths.m_pathNodes;
|
||||||
for (int i = pCurNode->firstLink; ThePaths.ConnectedNode(i) != newNextNode; i++, nextLink++)
|
for (int i = pCurNode->firstLink; ThePaths.ConnectedNode(i) != newNextNode; i++, nextLink++)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
@ -2017,11 +2037,11 @@ void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float t
|
||||||
int8 lanesOnNextNode;
|
int8 lanesOnNextNode;
|
||||||
if (curNode >= pVehicle->AutoPilot.m_nNextRouteNode) {
|
if (curNode >= pVehicle->AutoPilot.m_nNextRouteNode) {
|
||||||
pVehicle->AutoPilot.m_nNextDirection = 1;
|
pVehicle->AutoPilot.m_nNextDirection = 1;
|
||||||
lanesOnNextNode = pNextLink->numLeftLanes;
|
lanesOnNextNode = pNextLink->numRightLanes;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pVehicle->AutoPilot.m_nNextDirection = -1;
|
pVehicle->AutoPilot.m_nNextDirection = -1;
|
||||||
lanesOnNextNode = pNextLink->numRightLanes;
|
lanesOnNextNode = pNextLink->numLeftLanes;
|
||||||
}
|
}
|
||||||
float currentPathLinkForwardX = pVehicle->AutoPilot.m_nCurrentDirection * pCurLink->GetDirX();
|
float currentPathLinkForwardX = pVehicle->AutoPilot.m_nCurrentDirection * pCurLink->GetDirX();
|
||||||
float currentPathLinkForwardY = pVehicle->AutoPilot.m_nCurrentDirection * pCurLink->GetDirY();
|
float currentPathLinkForwardY = pVehicle->AutoPilot.m_nCurrentDirection * pCurLink->GetDirY();
|
||||||
|
@ -2076,6 +2096,8 @@ void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float t
|
||||||
|
|
||||||
bool CCarCtrl::PickNextNodeToFollowPath(CVehicle* pVehicle)
|
bool CCarCtrl::PickNextNodeToFollowPath(CVehicle* pVehicle)
|
||||||
{
|
{
|
||||||
|
if (pVehicle->m_nRouteSeed)
|
||||||
|
CGeneral::SetRandomSeed(pVehicle->m_nRouteSeed);
|
||||||
int curNode = pVehicle->AutoPilot.m_nNextRouteNode;
|
int curNode = pVehicle->AutoPilot.m_nNextRouteNode;
|
||||||
CPathNode* pCurNode = &ThePaths.m_pathNodes[curNode];
|
CPathNode* pCurNode = &ThePaths.m_pathNodes[curNode];
|
||||||
if (pVehicle->AutoPilot.m_nPathFindNodesCount == 0){
|
if (pVehicle->AutoPilot.m_nPathFindNodesCount == 0){
|
||||||
|
@ -2168,6 +2190,7 @@ void CCarCtrl::Init(void)
|
||||||
LastTimeAmbulanceCreated = 0;
|
LastTimeAmbulanceCreated = 0;
|
||||||
#ifdef FIX_BUGS
|
#ifdef FIX_BUGS
|
||||||
LastTimeLawEnforcerCreated = 0;
|
LastTimeLawEnforcerCreated = 0;
|
||||||
|
LastTimeMiamiViceGenerated = 0;
|
||||||
#endif
|
#endif
|
||||||
bCarsGeneratedAroundCamera = false;
|
bCarsGeneratedAroundCamera = false;
|
||||||
CountDownToCarsAtStart = 2;
|
CountDownToCarsAtStart = 2;
|
||||||
|
@ -2197,6 +2220,7 @@ void CCarCtrl::ReInit(void)
|
||||||
LastTimeFireTruckCreated = 0;
|
LastTimeFireTruckCreated = 0;
|
||||||
LastTimeAmbulanceCreated = 0;
|
LastTimeAmbulanceCreated = 0;
|
||||||
LastTimeLawEnforcerCreated = 0;
|
LastTimeLawEnforcerCreated = 0;
|
||||||
|
LastTimeMiamiViceGenerated = 0;
|
||||||
#endif
|
#endif
|
||||||
CountDownToCarsAtStart = 2;
|
CountDownToCarsAtStart = 2;
|
||||||
CarDensityMultiplier = 1.0f;
|
CarDensityMultiplier = 1.0f;
|
||||||
|
@ -2313,7 +2337,7 @@ void CCarCtrl::SteerAICarWithPhysics(CVehicle* pVehicle)
|
||||||
pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
|
pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
|
||||||
break;
|
break;
|
||||||
case TEMPACT_HANDBRAKETURNLEFT:
|
case TEMPACT_HANDBRAKETURNLEFT:
|
||||||
swerve = -1.0f; // It seems like this should be swerve = 1.0f (fixed in VC)
|
swerve = 1.0f;
|
||||||
accel = 0.0f;
|
accel = 0.0f;
|
||||||
brake = 0.0f;
|
brake = 0.0f;
|
||||||
handbrake = true;
|
handbrake = true;
|
||||||
|
@ -2321,7 +2345,7 @@ void CCarCtrl::SteerAICarWithPhysics(CVehicle* pVehicle)
|
||||||
pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
|
pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
|
||||||
break;
|
break;
|
||||||
case TEMPACT_HANDBRAKETURNRIGHT:
|
case TEMPACT_HANDBRAKETURNRIGHT:
|
||||||
swerve = 1.0f; // It seems like this should be swerve = -1.0f (fixed in VC)
|
swerve = -1.0f;
|
||||||
accel = 0.0f;
|
accel = 0.0f;
|
||||||
brake = 0.0f;
|
brake = 0.0f;
|
||||||
handbrake = true;
|
handbrake = true;
|
||||||
|
@ -2432,6 +2456,9 @@ void CCarCtrl::SteerAICarWithPhysics_OnlyMission(CVehicle* pVehicle, float* pSwe
|
||||||
SteerAICarWithPhysicsTryingToBlockTarget_Stop(pVehicle, FindPlayerCoors().x, FindPlayerCoors().y,
|
SteerAICarWithPhysicsTryingToBlockTarget_Stop(pVehicle, FindPlayerCoors().x, FindPlayerCoors().y,
|
||||||
FindPlayerSpeed().x, FindPlayerSpeed().y, pSwerve, pAccel, pBrake, pHandbrake);
|
FindPlayerSpeed().x, FindPlayerSpeed().y, pSwerve, pAccel, pBrake, pHandbrake);
|
||||||
return;
|
return;
|
||||||
|
case MISSION_WAITFORDELETION:
|
||||||
|
case MISSION_HELI_LAND:
|
||||||
|
return;
|
||||||
case MISSION_GOTOCOORDS_STRAIGHT:
|
case MISSION_GOTOCOORDS_STRAIGHT:
|
||||||
case MISSION_GOTO_COORDS_STRAIGHT_ACCURATE:
|
case MISSION_GOTO_COORDS_STRAIGHT_ACCURATE:
|
||||||
SteerAICarWithPhysicsHeadingForTarget(pVehicle, nil,
|
SteerAICarWithPhysicsHeadingForTarget(pVehicle, nil,
|
||||||
|
@ -2445,6 +2472,12 @@ void CCarCtrl::SteerAICarWithPhysics_OnlyMission(CVehicle* pVehicle, float* pSwe
|
||||||
*pHandbrake = true;
|
*pHandbrake = true;
|
||||||
*pBrake = 0.5f;
|
*pBrake = 0.5f;
|
||||||
return;
|
return;
|
||||||
|
case MISSION_GOTOCOORDS_ASTHECROWSWIMS:
|
||||||
|
SteerAIBoatWithPhysicsHeadingForTarget(pVehicle,
|
||||||
|
pVehicle->AutoPilot.m_vecDestinationCoors.x, pVehicle->AutoPilot.m_vecDestinationCoors.y,
|
||||||
|
pSwerve, pAccel, pBrake);
|
||||||
|
*pHandbrake = false;
|
||||||
|
return;
|
||||||
case MISSION_RAMCAR_CLOSE:
|
case MISSION_RAMCAR_CLOSE:
|
||||||
SteerAICarWithPhysicsHeadingForTarget(pVehicle, pVehicle->AutoPilot.m_pTargetCar,
|
SteerAICarWithPhysicsHeadingForTarget(pVehicle, pVehicle->AutoPilot.m_pTargetCar,
|
||||||
pVehicle->AutoPilot.m_pTargetCar->GetPosition().x, pVehicle->AutoPilot.m_pTargetCar->GetPosition().y,
|
pVehicle->AutoPilot.m_pTargetCar->GetPosition().x, pVehicle->AutoPilot.m_pTargetCar->GetPosition().y,
|
||||||
|
@ -2466,26 +2499,93 @@ void CCarCtrl::SteerAICarWithPhysics_OnlyMission(CVehicle* pVehicle, float* pSwe
|
||||||
pVehicle->AutoPilot.m_pTargetCar->GetMoveSpeed().y,
|
pVehicle->AutoPilot.m_pTargetCar->GetMoveSpeed().y,
|
||||||
pSwerve, pAccel, pBrake, pHandbrake);
|
pSwerve, pAccel, pBrake, pHandbrake);
|
||||||
return;
|
return;
|
||||||
|
case MISSION_HELI_FLYTOCOORS:
|
||||||
|
//SteerAIHeliTowardsTargetCoors((CAutomobile*)pVehicle);
|
||||||
|
return;
|
||||||
|
case MISSION_ATTACKPLAYER:
|
||||||
|
SteerAIBoatWithPhysicsAttackingPlayer(pVehicle, pSwerve, pAccel, pBrake, pHandbrake);
|
||||||
|
return;
|
||||||
|
case MISSION_PLANE_FLYTOCOORS:
|
||||||
|
//SteerAIPlaneTowardsTargetCoors((CAutomobile*)pVehicle);
|
||||||
|
return;
|
||||||
|
case MISSION_SLOWLY_DRIVE_TOWARDS_PLAYER_1:
|
||||||
|
SteerAICarWithPhysicsHeadingForTarget(pVehicle, nil,
|
||||||
|
pVehicle->AutoPilot.m_vecDestinationCoors.x, pVehicle->AutoPilot.m_vecDestinationCoors.y,
|
||||||
|
pSwerve, pAccel, pBrake, pHandbrake);
|
||||||
|
return;
|
||||||
|
case MISSION_SLOWLY_DRIVE_TOWARDS_PLAYER_2:
|
||||||
|
SteerAICarWithPhysicsHeadingForTarget(pVehicle, nil, FindPlayerCoors().x, FindPlayerCoors().y,
|
||||||
|
pSwerve, pAccel, pBrake, pHandbrake);
|
||||||
|
return;
|
||||||
|
case MISSION_BLOCKPLAYER_FORWARDANDBACK:
|
||||||
|
//SteerAICarBlockingPlayerForwardAndBack(pVehicle, pSwerve, pAccel, pBrake, pHandbrake);
|
||||||
|
return;
|
||||||
default:
|
default:
|
||||||
|
assert(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCarCtrl::SteerAIBoatWithPhysics(CBoat* pBoat)
|
void CCarCtrl::SteerAIBoatWithPhysicsHeadingForTarget(CVehicle* pVehicle, float targetX, float targetY, float* pSwerve, float* pAccel, float* pBrake)
|
||||||
{
|
{
|
||||||
if (pBoat->AutoPilot.m_nCarMission == MISSION_GOTOCOORDS_ASTHECROWSWIMS){
|
CVector2D forward = pVehicle->GetForward();
|
||||||
SteerAIBoatWithPhysicsHeadingForTarget(pBoat,
|
forward.Normalise();
|
||||||
pBoat->AutoPilot.m_vecDestinationCoors.x, pBoat->AutoPilot.m_vecDestinationCoors.y,
|
float angleToTarget = CGeneral::GetATanOfXY(targetX - pVehicle->GetPosition().x, targetY - pVehicle->GetPosition().y);
|
||||||
&pBoat->m_fSteeringLeftRight, &pBoat->m_fAccelerate, &pBoat->m_fBrake);
|
float angleForward = CGeneral::GetATanOfXY(forward.x, forward.y);
|
||||||
}else if (pBoat->AutoPilot.m_nCarMission == MISSION_NONE){
|
float steerAngle = LimitRadianAngle(angleToTarget - angleForward);
|
||||||
pBoat->m_fSteeringLeftRight = 0.0f;
|
steerAngle = clamp(steerAngle, -DEFAULT_MAX_STEER_ANGLE, DEFAULT_MAX_STEER_ANGLE);
|
||||||
pBoat->m_fAccelerate = 0.0f;
|
#ifdef FIX_BUGS
|
||||||
pBoat->m_fBrake = 0.0f;
|
float speedTarget = pVehicle->AutoPilot.GetCruiseSpeed();
|
||||||
|
#else
|
||||||
|
float speedTarget = pVehicle->AutoPilot.m_nCruiseSpeed;
|
||||||
|
#endif
|
||||||
|
float currentSpeed = pVehicle->GetMoveSpeed().Magnitude() * GAME_SPEED_TO_CARAI_SPEED;
|
||||||
|
float speedDiff = speedTarget - currentSpeed;
|
||||||
|
if (speedDiff <= 0.0f) {
|
||||||
|
speedDiff < -5.0f ? *pAccel = -0.2f : *pAccel = -0.1f;
|
||||||
|
steerAngle *= -1;
|
||||||
}
|
}
|
||||||
pBoat->m_fSteerAngle = pBoat->m_fSteeringLeftRight;
|
else if (speedDiff / currentSpeed > 0.25f) {
|
||||||
pBoat->m_fGasPedal = pBoat->m_fAccelerate;
|
*pAccel = 1.0f;
|
||||||
pBoat->m_fBrakePedal = pBoat->m_fBrake;
|
}
|
||||||
pBoat->bIsHandbrakeOn = false;
|
else {
|
||||||
|
*pAccel = 1.0f - (0.25f - speedDiff / currentSpeed) * 4.0f;
|
||||||
|
}
|
||||||
|
*pBrake = 0.0f;
|
||||||
|
*pSwerve = steerAngle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCarCtrl::SteerAIBoatWithPhysicsAttackingPlayer(CVehicle* pVehicle, float* pSwerve, float* pAccel, float* pBrake, bool* pHandbrake)
|
||||||
|
{
|
||||||
|
float distanceToPlayer = (FindPlayerCoors() - pVehicle->GetPosition()).Magnitude();
|
||||||
|
float projection = Min(distanceToPlayer * 0.05f, 2.0f);
|
||||||
|
CVector2D forward = pVehicle->GetForward();
|
||||||
|
forward.Normalise();
|
||||||
|
CVector2D vecToProjection = FindPlayerCoors() + FindPlayerSpeed() * projection * GAME_SPEED_TO_CARAI_SPEED;
|
||||||
|
float angleToTarget = CGeneral::GetATanOfXY(vecToProjection.x - pVehicle->GetPosition().x, vecToProjection.y - pVehicle->GetPosition().y);
|
||||||
|
float angleForward = CGeneral::GetATanOfXY(forward.x, forward.y);
|
||||||
|
float steerAngle = LimitRadianAngle(angleToTarget - angleForward);
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
float speedTarget = pVehicle->AutoPilot.GetCruiseSpeed();
|
||||||
|
#else
|
||||||
|
float speedTarget = pVehicle->AutoPilot.m_nCruiseSpeed;
|
||||||
|
#endif
|
||||||
|
float currentSpeed = pVehicle->GetMoveSpeed().Magnitude() * GAME_SPEED_TO_CARAI_SPEED;
|
||||||
|
float speedDiff = speedTarget - currentSpeed;
|
||||||
|
if (speedDiff <= 0.0f) {
|
||||||
|
speedDiff < -5.0f ? *pAccel = -0.2f : *pAccel = -0.1f;
|
||||||
|
}
|
||||||
|
else if (speedDiff / currentSpeed > 0.25f) {
|
||||||
|
*pAccel = 1.0f;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*pAccel = 1.0f - (0.25f - speedDiff / currentSpeed) * 4.0f;
|
||||||
|
}
|
||||||
|
*pBrake = 0.0f;
|
||||||
|
*pSwerve = steerAngle;
|
||||||
|
*pHandbrake = false;
|
||||||
|
if (pVehicle->GetModelIndex() == MI_PREDATOR && distanceToPlayer < 40.0f && steerAngle < 0.15f)
|
||||||
|
pVehicle->FireFixedMachineGuns();
|
||||||
}
|
}
|
||||||
|
|
||||||
float CCarCtrl::FindMaxSteerAngle(CVehicle* pVehicle)
|
float CCarCtrl::FindMaxSteerAngle(CVehicle* pVehicle)
|
||||||
|
@ -2672,6 +2772,7 @@ void CCarCtrl::SteerAICarWithPhysicsTryingToBlockTarget(CVehicle* pVehicle, floa
|
||||||
pVehicle->AutoPilot.m_nCarMission = (pVehicle->AutoPilot.m_nCarMission == MISSION_BLOCKCAR_CLOSE) ?
|
pVehicle->AutoPilot.m_nCarMission = (pVehicle->AutoPilot.m_nCarMission == MISSION_BLOCKCAR_CLOSE) ?
|
||||||
MISSION_BLOCKCAR_HANDBRAKESTOP : MISSION_BLOCKPLAYER_HANDBRAKESTOP;
|
MISSION_BLOCKCAR_HANDBRAKESTOP : MISSION_BLOCKPLAYER_HANDBRAKESTOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCarCtrl::SteerAICarWithPhysicsTryingToBlockTarget_Stop(CVehicle* pVehicle, float targetX, float targetY, float targetSpeedX, float targetSpeedY, float* pSwerve, float* pAccel, float* pBrake, bool* pHandbrake)
|
void CCarCtrl::SteerAICarWithPhysicsTryingToBlockTarget_Stop(CVehicle* pVehicle, float targetX, float targetY, float targetSpeedX, float targetSpeedY, float* pSwerve, float* pAccel, float* pBrake, bool* pHandbrake)
|
||||||
{
|
{
|
||||||
*pSwerve = 0.0f;
|
*pSwerve = 0.0f;
|
||||||
|
@ -2713,26 +2814,6 @@ void CCarCtrl::SteerAICarWithPhysicsTryingToBlockTarget_Stop(CVehicle* pVehicle,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCarCtrl::SteerAIBoatWithPhysicsHeadingForTarget(CBoat* pBoat, float targetX, float targetY, float* pSwerve, float* pAccel, float* pBrake)
|
|
||||||
{
|
|
||||||
CVector2D forward(pBoat->GetForward());
|
|
||||||
forward.Normalise();
|
|
||||||
CVector2D distanceToTarget = CVector2D(targetX, targetY) - pBoat->GetPosition();
|
|
||||||
float angleToTarget = CGeneral::GetATanOfXY(distanceToTarget.x, distanceToTarget.y);
|
|
||||||
float angleForward = CGeneral::GetATanOfXY(forward.x, forward.y);
|
|
||||||
float angleDiff = LimitRadianAngle(angleToTarget - angleForward);
|
|
||||||
angleDiff = Min(DEFAULT_MAX_STEER_ANGLE, Max(-DEFAULT_MAX_STEER_ANGLE, angleDiff));
|
|
||||||
float currentSpeed = pBoat->GetMoveSpeed().Magnitude2D(); // +0.0f for some reason
|
|
||||||
float speedDiff = pBoat->AutoPilot.m_nCruiseSpeed - currentSpeed * 60.0f;
|
|
||||||
if (speedDiff > 0.0f){
|
|
||||||
float accRemaining = speedDiff / pBoat->AutoPilot.m_nCruiseSpeed;
|
|
||||||
*pAccel = (accRemaining > 0.25f) ? 1.0f : 1.0f - (0.25f - accRemaining) * 4.0f;
|
|
||||||
}else
|
|
||||||
*pAccel = (speedDiff < -5.0f) ? -0.2f : -0.1f;
|
|
||||||
*pBrake = 0.0f;
|
|
||||||
*pSwerve = angleDiff;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CCarCtrl::RegisterVehicleOfInterest(CVehicle* pVehicle)
|
CCarCtrl::RegisterVehicleOfInterest(CVehicle* pVehicle)
|
||||||
{
|
{
|
||||||
|
@ -2852,8 +2933,12 @@ bool CCarCtrl::JoinCarWithRoadSystemGotoCoors(CVehicle* pVehicle, CVector vecTar
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//TODO
|
||||||
void CCarCtrl::FindLinksToGoWithTheseNodes(CVehicle* pVehicle)
|
void CCarCtrl::FindLinksToGoWithTheseNodes(CVehicle* pVehicle)
|
||||||
{
|
{
|
||||||
|
if (pVehicle->m_nRouteSeed)
|
||||||
|
CGeneral::SetRandomSeed(pVehicle->m_nRouteSeed);
|
||||||
int nextLink;
|
int nextLink;
|
||||||
CPathNode* pCurNode = &ThePaths.m_pathNodes[pVehicle->AutoPilot.m_nCurrentRouteNode];
|
CPathNode* pCurNode = &ThePaths.m_pathNodes[pVehicle->AutoPilot.m_nCurrentRouteNode];
|
||||||
for (nextLink = 0; nextLink < 12; nextLink++)
|
for (nextLink = 0; nextLink < 12; nextLink++)
|
||||||
|
@ -2881,6 +2966,8 @@ void CCarCtrl::GenerateEmergencyServicesCar(void)
|
||||||
{
|
{
|
||||||
if (FindPlayerPed()->m_pWanted->m_nWantedLevel > 3)
|
if (FindPlayerPed()->m_pWanted->m_nWantedLevel > 3)
|
||||||
return;
|
return;
|
||||||
|
if (CGame::IsInInterior())
|
||||||
|
return;
|
||||||
if (NumFiretrucksOnDuty + NumAmbulancesOnDuty + NumParkedCars + NumMissionCars +
|
if (NumFiretrucksOnDuty + NumAmbulancesOnDuty + NumParkedCars + NumMissionCars +
|
||||||
NumLawEnforcerCars + NumRandomCars > MaxNumberOfCarsInUse)
|
NumLawEnforcerCars + NumRandomCars > MaxNumberOfCarsInUse)
|
||||||
return;
|
return;
|
||||||
|
@ -2936,9 +3023,11 @@ bool CCarCtrl::GenerateOneEmergencyServicesCar(uint32 mi, CVector vecPos)
|
||||||
if (ThePaths.NewGenerateCarCreationCoors(pPlayerPos.x, pPlayerPos.y, 0.707f, 0.707f,
|
if (ThePaths.NewGenerateCarCreationCoors(pPlayerPos.x, pPlayerPos.y, 0.707f, 0.707f,
|
||||||
120.0f, -1.0f, true, &spawnPos, &curNode, &nextNode, &posBetweenNodes, false)){
|
120.0f, -1.0f, true, &spawnPos, &curNode, &nextNode, &posBetweenNodes, false)){
|
||||||
int16 colliding[2];
|
int16 colliding[2];
|
||||||
CWorld::FindObjectsKindaColliding(spawnPos, 10.0f, true, colliding, 2, nil, false, true, true, false, false);
|
if (!ThePaths.GetNode(curNode)->bWaterPath) {
|
||||||
if (colliding[0] == 0)
|
CWorld::FindObjectsKindaColliding(spawnPos, 10.0f, true, colliding, 2, nil, false, true, true, false, false);
|
||||||
created = true;
|
if (colliding[0] == 0)
|
||||||
|
created = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
attempts += 1;
|
attempts += 1;
|
||||||
}
|
}
|
||||||
|
@ -2997,18 +3086,24 @@ void CCarCtrl::UpdateCarCount(CVehicle* pVehicle, bool remove)
|
||||||
if (remove){
|
if (remove){
|
||||||
switch (pVehicle->VehicleCreatedBy){
|
switch (pVehicle->VehicleCreatedBy){
|
||||||
case RANDOM_VEHICLE:
|
case RANDOM_VEHICLE:
|
||||||
if (pVehicle->bIsLawEnforcer)
|
if (pVehicle->bIsLawEnforcer) {
|
||||||
--NumLawEnforcerCars;
|
if (--NumLawEnforcerCars < 0)
|
||||||
--NumRandomCars;
|
NumLawEnforcerCars = 0;
|
||||||
|
}
|
||||||
|
if (--NumRandomCars < 0)
|
||||||
|
NumRandomCars = 0;
|
||||||
return;
|
return;
|
||||||
case MISSION_VEHICLE:
|
case MISSION_VEHICLE:
|
||||||
--NumMissionCars;
|
if (--NumMissionCars < 0)
|
||||||
|
NumMissionCars = 0;
|
||||||
return;
|
return;
|
||||||
case PARKED_VEHICLE:
|
case PARKED_VEHICLE:
|
||||||
--NumParkedCars;
|
if (--NumParkedCars < 0)
|
||||||
|
NumParkedCars = 0;
|
||||||
return;
|
return;
|
||||||
case PERMANENT_VEHICLE:
|
case PERMANENT_VEHICLE:
|
||||||
--NumPermanentCars;;
|
if (--NumPermanentCars < 0)
|
||||||
|
NumPermanentCars = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3026,7 +3121,7 @@ void CCarCtrl::UpdateCarCount(CVehicle* pVehicle, bool remove)
|
||||||
++NumParkedCars;
|
++NumParkedCars;
|
||||||
return;
|
return;
|
||||||
case PERMANENT_VEHICLE:
|
case PERMANENT_VEHICLE:
|
||||||
++NumPermanentCars;;
|
++NumPermanentCars;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3034,7 +3129,11 @@ void CCarCtrl::UpdateCarCount(CVehicle* pVehicle, bool remove)
|
||||||
|
|
||||||
bool CCarCtrl::ThisRoadObjectCouldMove(int16 mi)
|
bool CCarCtrl::ThisRoadObjectCouldMove(int16 mi)
|
||||||
{
|
{
|
||||||
|
#ifdef GTA_BRIDGE
|
||||||
return mi == MI_BRIDGELIFT || mi == MI_BRIDGEROADSEGMENT;
|
return mi == MI_BRIDGELIFT || mi == MI_BRIDGEROADSEGMENT;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCarCtrl::MapCouldMoveInThisArea(float x, float y)
|
bool CCarCtrl::MapCouldMoveInThisArea(float x, float y)
|
||||||
|
|
|
@ -107,13 +107,11 @@ public:
|
||||||
static float FindSpeedMultiplier(float, float, float, float);
|
static float FindSpeedMultiplier(float, float, float, float);
|
||||||
static void SteerAICarWithPhysics(CVehicle*);
|
static void SteerAICarWithPhysics(CVehicle*);
|
||||||
static void SteerAICarWithPhysics_OnlyMission(CVehicle*, float*, float*, float*, bool*);
|
static void SteerAICarWithPhysics_OnlyMission(CVehicle*, float*, float*, float*, bool*);
|
||||||
static void SteerAIBoatWithPhysics(CBoat*);
|
|
||||||
static float FindMaxSteerAngle(CVehicle*);
|
static float FindMaxSteerAngle(CVehicle*);
|
||||||
static void SteerAICarWithPhysicsFollowPath(CVehicle*, float*, float*, float*, bool*);
|
static void SteerAICarWithPhysicsFollowPath(CVehicle*, float*, float*, float*, bool*);
|
||||||
static void SteerAICarWithPhysicsHeadingForTarget(CVehicle*, CPhysical*, float, float, float*, float*, float*, bool*);
|
static void SteerAICarWithPhysicsHeadingForTarget(CVehicle*, CPhysical*, float, float, float*, float*, float*, bool*);
|
||||||
static void SteerAICarWithPhysicsTryingToBlockTarget(CVehicle*, float, float, float, float, float*, float*, float*, bool*);
|
static void SteerAICarWithPhysicsTryingToBlockTarget(CVehicle*, float, float, float, float, float*, float*, float*, bool*);
|
||||||
static void SteerAICarWithPhysicsTryingToBlockTarget_Stop(CVehicle*, float, float, float, float, float*, float*, float*, bool*);
|
static void SteerAICarWithPhysicsTryingToBlockTarget_Stop(CVehicle*, float, float, float, float, float*, float*, float*, bool*);
|
||||||
static void SteerAIBoatWithPhysicsHeadingForTarget(CBoat*, float, float, float*, float*, float*);
|
|
||||||
static bool ThisRoadObjectCouldMove(int16);
|
static bool ThisRoadObjectCouldMove(int16);
|
||||||
static void ClearInterestingVehicleList();
|
static void ClearInterestingVehicleList();
|
||||||
static void FindLinksToGoWithTheseNodes(CVehicle*);
|
static void FindLinksToGoWithTheseNodes(CVehicle*);
|
||||||
|
@ -127,6 +125,11 @@ public:
|
||||||
static int32 ChooseCarModelToLoad(int32 rating);
|
static int32 ChooseCarModelToLoad(int32 rating);
|
||||||
static bool BoatWithTallMast(int32 mi);
|
static bool BoatWithTallMast(int32 mi);
|
||||||
static void RemoveCarsIfThePoolGetsFull(void);
|
static void RemoveCarsIfThePoolGetsFull(void);
|
||||||
|
static void SteerAIBoatWithPhysicsHeadingForTarget(CVehicle*, float, float, float*, float*, float*);
|
||||||
|
static void SteerAIHeliTowardsTargetCoors(CAutomobile*);
|
||||||
|
static void SteerAIPlaneTowardsTargetCoors(CAutomobile*);
|
||||||
|
static void SteerAIBoatWithPhysicsAttackingPlayer(CVehicle*, float*, float*, float*, bool*);
|
||||||
|
static void SteerAICarBlockingPlayerForwardAndBack(CVehicle*, float*, float*, float*, bool*);
|
||||||
|
|
||||||
static float GetPositionAlongCurrentCurve(CVehicle* pVehicle)
|
static float GetPositionAlongCurrentCurve(CVehicle* pVehicle)
|
||||||
{
|
{
|
||||||
|
|
|
@ -9784,7 +9784,15 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command)
|
||||||
case COMMAND_SET_CAR_FORWARD_SPEED:
|
case COMMAND_SET_CAR_FORWARD_SPEED:
|
||||||
case COMMAND_SET_AREA_VISIBLE:
|
case COMMAND_SET_AREA_VISIBLE:
|
||||||
case COMMAND_SET_CUTSCENE_ANIM_TO_LOOP:
|
case COMMAND_SET_CUTSCENE_ANIM_TO_LOOP:
|
||||||
|
assert(0);
|
||||||
case COMMAND_MARK_CAR_AS_CONVOY_CAR:
|
case COMMAND_MARK_CAR_AS_CONVOY_CAR:
|
||||||
|
{
|
||||||
|
CollectParameters(&m_nIp, 2);
|
||||||
|
CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
|
||||||
|
assert(pVehicle);
|
||||||
|
pVehicle->bPartOfConvoy = ScriptParams[1];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
case COMMAND_RESET_HAVOC_CAUSED_BY_PLAYER:
|
case COMMAND_RESET_HAVOC_CAUSED_BY_PLAYER:
|
||||||
case COMMAND_GET_HAVOC_CAUSED_BY_PLAYER:
|
case COMMAND_GET_HAVOC_CAUSED_BY_PLAYER:
|
||||||
case COMMAND_CREATE_SCRIPT_ROADBLOCK:
|
case COMMAND_CREATE_SCRIPT_ROADBLOCK:
|
||||||
|
|
|
@ -1397,12 +1397,44 @@ CStreaming::StreamVehiclesAndPeds(void)
|
||||||
SetModelIsDeletable(MI_CHOPPER);
|
SetModelIsDeletable(MI_CHOPPER);
|
||||||
|
|
||||||
if (FindPlayerPed()->m_pWanted->AreMiamiViceRequired()) {
|
if (FindPlayerPed()->m_pWanted->AreMiamiViceRequired()) {
|
||||||
//TODO(MIAMI): miami vice peds
|
SetModelIsDeletable(MI_VICE1);
|
||||||
|
SetModelIsDeletable(MI_VICE2);
|
||||||
|
SetModelIsDeletable(MI_VICE3);
|
||||||
|
SetModelIsDeletable(MI_VICE4);
|
||||||
|
SetModelIsDeletable(MI_VICE5);
|
||||||
|
SetModelIsDeletable(MI_VICE6);
|
||||||
|
SetModelIsDeletable(MI_VICE7);
|
||||||
|
SetModelIsDeletable(MI_VICE8);
|
||||||
|
switch (CCarCtrl::MiamiViceCycle) {
|
||||||
|
case 0:
|
||||||
|
RequestModel(MI_VICE1, STREAMFLAGS_DONT_REMOVE);
|
||||||
|
RequestModel(MI_VICE2, STREAMFLAGS_DONT_REMOVE);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
RequestModel(MI_VICE3, STREAMFLAGS_DONT_REMOVE);
|
||||||
|
RequestModel(MI_VICE4, STREAMFLAGS_DONT_REMOVE);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
RequestModel(MI_VICE5, STREAMFLAGS_DONT_REMOVE);
|
||||||
|
RequestModel(MI_VICE6, STREAMFLAGS_DONT_REMOVE);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
RequestModel(MI_VICE7, STREAMFLAGS_DONT_REMOVE);
|
||||||
|
RequestModel(MI_VICE8, STREAMFLAGS_DONT_REMOVE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
RequestModel(MI_VICECHEE, STREAMFLAGS_DONT_REMOVE);
|
RequestModel(MI_VICECHEE, STREAMFLAGS_DONT_REMOVE);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SetModelIsDeletable(MI_VICECHEE);
|
SetModelIsDeletable(MI_VICECHEE);
|
||||||
//TODO(MIAMI): miami vice peds
|
SetModelIsDeletable(MI_VICE1);
|
||||||
|
SetModelIsDeletable(MI_VICE2);
|
||||||
|
SetModelIsDeletable(MI_VICE3);
|
||||||
|
SetModelIsDeletable(MI_VICE4);
|
||||||
|
SetModelIsDeletable(MI_VICE5);
|
||||||
|
SetModelIsDeletable(MI_VICE6);
|
||||||
|
SetModelIsDeletable(MI_VICE7);
|
||||||
|
SetModelIsDeletable(MI_VICE8);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(timeBeforeNextLoad >= 0)
|
if(timeBeforeNextLoad >= 0)
|
||||||
|
|
|
@ -180,6 +180,13 @@ enum
|
||||||
MI_TAXI_D = 28, // HMOCA
|
MI_TAXI_D = 28, // HMOCA
|
||||||
MI_GANG01 = 83, // CBa
|
MI_GANG01 = 83, // CBa
|
||||||
MI_VICE1 = 97,
|
MI_VICE1 = 97,
|
||||||
|
MI_VICE2,
|
||||||
|
MI_VICE3,
|
||||||
|
MI_VICE4,
|
||||||
|
MI_VICE5,
|
||||||
|
MI_VICE6,
|
||||||
|
MI_VICE7,
|
||||||
|
MI_VICE8,
|
||||||
MI_WFYG2 = 106, // last regular ped
|
MI_WFYG2 = 106, // last regular ped
|
||||||
MI_SPECIAL01 = 109,
|
MI_SPECIAL01 = 109,
|
||||||
MI_SPECIAL21 = 129,
|
MI_SPECIAL21 = 129,
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include "Renderer.h"
|
#include "Renderer.h"
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
|
|
||||||
CCopPed::CCopPed(eCopType copType) : CPed(PEDTYPE_COP)
|
CCopPed::CCopPed(eCopType copType, int32 modifier) : CPed(PEDTYPE_COP)
|
||||||
{
|
{
|
||||||
m_nCopType = copType;
|
m_nCopType = copType;
|
||||||
switch (copType) {
|
switch (copType) {
|
||||||
|
@ -57,7 +57,23 @@ CCopPed::CCopPed(eCopType copType) : CPed(PEDTYPE_COP)
|
||||||
m_wepSkills = 32; /* TODO: what is this? seems unused */
|
m_wepSkills = 32; /* TODO: what is this? seems unused */
|
||||||
m_wepAccuracy = 84;
|
m_wepAccuracy = 84;
|
||||||
break;
|
break;
|
||||||
default:
|
case COP_MIAMIVICE:
|
||||||
|
switch (modifier) {
|
||||||
|
case 0: SetModelIndex(MI_VICE1); break;
|
||||||
|
case 1: SetModelIndex(MI_VICE2); break;
|
||||||
|
case 2: SetModelIndex(MI_VICE3); break;
|
||||||
|
case 3: SetModelIndex(MI_VICE4); break;
|
||||||
|
case 4: SetModelIndex(MI_VICE5); break;
|
||||||
|
case 5: SetModelIndex(MI_VICE6); break;
|
||||||
|
case 6: SetModelIndex(MI_VICE7); break;
|
||||||
|
case 7: SetModelIndex(MI_VICE8); break;
|
||||||
|
default: assert(0); break;
|
||||||
|
}
|
||||||
|
GiveWeapon(WEAPONTYPE_UZI, 1000);
|
||||||
|
SetCurrentWeapon(WEAPONTYPE_UZI);
|
||||||
|
m_fArmour = 100.0f;
|
||||||
|
m_wepSkills = 176;
|
||||||
|
m_wepAccuracy = 76;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
m_bIsInPursuit = false;
|
m_bIsInPursuit = false;
|
||||||
|
|
|
@ -7,6 +7,7 @@ enum eCopType
|
||||||
COP_FBI = 1,
|
COP_FBI = 1,
|
||||||
COP_SWAT = 2,
|
COP_SWAT = 2,
|
||||||
COP_ARMY = 3,
|
COP_ARMY = 3,
|
||||||
|
COP_MIAMIVICE = 5
|
||||||
};
|
};
|
||||||
|
|
||||||
class CCopPed : public CPed
|
class CCopPed : public CPed
|
||||||
|
@ -24,7 +25,7 @@ public:
|
||||||
eCopType m_nCopType;
|
eCopType m_nCopType;
|
||||||
int8 field_1364;
|
int8 field_1364;
|
||||||
|
|
||||||
CCopPed(eCopType);
|
CCopPed(eCopType, int32 modifier = 0);
|
||||||
~CCopPed();
|
~CCopPed();
|
||||||
|
|
||||||
void ClearPursuit(void);
|
void ClearPursuit(void);
|
||||||
|
|
|
@ -460,7 +460,7 @@ CPopulation::PedCreationDistMultiplier()
|
||||||
}
|
}
|
||||||
|
|
||||||
CPed*
|
CPed*
|
||||||
CPopulation::AddPed(ePedType pedType, uint32 miOrCopType, CVector const &coors)
|
CPopulation::AddPed(ePedType pedType, uint32 miOrCopType, CVector const &coors, int32 modifier)
|
||||||
{
|
{
|
||||||
switch (pedType) {
|
switch (pedType) {
|
||||||
case PEDTYPE_CIVMALE:
|
case PEDTYPE_CIVMALE:
|
||||||
|
@ -480,7 +480,7 @@ CPopulation::AddPed(ePedType pedType, uint32 miOrCopType, CVector const &coors)
|
||||||
}
|
}
|
||||||
case PEDTYPE_COP:
|
case PEDTYPE_COP:
|
||||||
{
|
{
|
||||||
CCopPed *ped = new CCopPed((eCopType)miOrCopType);
|
CCopPed *ped = new CCopPed((eCopType)miOrCopType, modifier);
|
||||||
ped->SetPosition(coors);
|
ped->SetPosition(coors);
|
||||||
ped->SetOrientation(0.0f, 0.0f, 0.0f);
|
ped->SetOrientation(0.0f, 0.0f, 0.0f);
|
||||||
CWorld::Add(ped);
|
CWorld::Add(ped);
|
||||||
|
@ -713,9 +713,10 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree
|
||||||
}
|
}
|
||||||
|
|
||||||
CPed*
|
CPed*
|
||||||
CPopulation::AddPedInCar(CVehicle* car)
|
CPopulation::AddPedInCar(CVehicle* car, bool isPassenger)
|
||||||
{
|
{
|
||||||
int defaultModel = MI_MALE01;
|
int defaultModel = MI_MALE01;
|
||||||
|
int miamiViceIndex = 0;
|
||||||
bool imSureThatModelIsLoaded = true;
|
bool imSureThatModelIsLoaded = true;
|
||||||
CVector coors = FindPlayerCoors();
|
CVector coors = FindPlayerCoors();
|
||||||
CZoneInfo zoneInfo;
|
CZoneInfo zoneInfo;
|
||||||
|
@ -740,7 +741,6 @@ CPopulation::AddPedInCar(CVehicle* car)
|
||||||
break;
|
break;
|
||||||
case MI_POLICE:
|
case MI_POLICE:
|
||||||
case MI_PREDATOR:
|
case MI_PREDATOR:
|
||||||
case MI_VICECHEE: // TODO(MIAMI): proper model
|
|
||||||
preferredModel = COP_STREET;
|
preferredModel = COP_STREET;
|
||||||
pedType = PEDTYPE_COP;
|
pedType = PEDTYPE_COP;
|
||||||
break;
|
break;
|
||||||
|
@ -753,6 +753,11 @@ CPopulation::AddPedInCar(CVehicle* car)
|
||||||
preferredModel = COP_ARMY;
|
preferredModel = COP_ARMY;
|
||||||
pedType = PEDTYPE_COP;
|
pedType = PEDTYPE_COP;
|
||||||
break;
|
break;
|
||||||
|
case MI_VICECHEE: // TODO(MIAMI): figure out new structure of the function
|
||||||
|
preferredModel = COP_MIAMIVICE;
|
||||||
|
pedType = PEDTYPE_COP;
|
||||||
|
miamiViceIndex = (isPassenger ? 2 * CCarCtrl::MiamiViceCycle : 2 * CCarCtrl::MiamiViceCycle + 1);
|
||||||
|
break;
|
||||||
case MI_TAXI:
|
case MI_TAXI:
|
||||||
case MI_CABBIE:
|
case MI_CABBIE:
|
||||||
case MI_ZEBRA:
|
case MI_ZEBRA:
|
||||||
|
@ -799,7 +804,7 @@ CPopulation::AddPedInCar(CVehicle* car)
|
||||||
pedType = ((CPedModelInfo*)CModelInfo::GetModelInfo(defaultModel))->m_pedType;
|
pedType = ((CPedModelInfo*)CModelInfo::GetModelInfo(defaultModel))->m_pedType;
|
||||||
}
|
}
|
||||||
|
|
||||||
CPed *newPed = CPopulation::AddPed((ePedType)pedType, preferredModel, car->GetPosition());
|
CPed *newPed = CPopulation::AddPed((ePedType)pedType, preferredModel, car->GetPosition(), miamiViceIndex);
|
||||||
newPed->bUsesCollision = false;
|
newPed->bUsesCollision = false;
|
||||||
|
|
||||||
// what??
|
// what??
|
||||||
|
|
|
@ -70,7 +70,7 @@ public:
|
||||||
static void LoadPedGroups();
|
static void LoadPedGroups();
|
||||||
static void UpdatePedCount(ePedType, bool);
|
static void UpdatePedCount(ePedType, bool);
|
||||||
static void DealWithZoneChange(eLevelName oldLevel, eLevelName newLevel, bool);
|
static void DealWithZoneChange(eLevelName oldLevel, eLevelName newLevel, bool);
|
||||||
static CPed *AddPedInCar(CVehicle *car);
|
static CPed *AddPedInCar(CVehicle *car, bool isPassenger);
|
||||||
static bool IsPointInSafeZone(CVector *coors);
|
static bool IsPointInSafeZone(CVector *coors);
|
||||||
static void RemovePed(CPed *ent);
|
static void RemovePed(CPed *ent);
|
||||||
static int32 ChooseCivilianOccupation(int32);
|
static int32 ChooseCivilianOccupation(int32);
|
||||||
|
@ -80,7 +80,7 @@ public:
|
||||||
static void FindClosestZoneForCoors(CVector*, int*, eLevelName, eLevelName);
|
static void FindClosestZoneForCoors(CVector*, int*, eLevelName, eLevelName);
|
||||||
static void GeneratePedsAtStartOfGame();
|
static void GeneratePedsAtStartOfGame();
|
||||||
static float PedCreationDistMultiplier();
|
static float PedCreationDistMultiplier();
|
||||||
static CPed *AddPed(ePedType pedType, uint32 mi, CVector const &coors);
|
static CPed *AddPed(ePedType pedType, uint32 mi, CVector const &coors, int32 modifier = 0);
|
||||||
static void AddToPopulation(float, float, float, float);
|
static void AddToPopulation(float, float, float, float);
|
||||||
static void ManagePopulation(void);
|
static void ManagePopulation(void);
|
||||||
static void MoveCarsAndPedsOutOfAbandonedZones(void);
|
static void MoveCarsAndPedsOutOfAbandonedZones(void);
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "General.h"
|
#include "General.h"
|
||||||
#include "Timecycle.h"
|
#include "Timecycle.h"
|
||||||
#include "HandlingMgr.h"
|
#include "HandlingMgr.h"
|
||||||
|
#include "CarAI.h"
|
||||||
#include "CarCtrl.h"
|
#include "CarCtrl.h"
|
||||||
#include "RwHelper.h"
|
#include "RwHelper.h"
|
||||||
#include "ModelIndices.h"
|
#include "ModelIndices.h"
|
||||||
|
@ -152,6 +153,7 @@ CBoat::ProcessControl(void)
|
||||||
case STATUS_SIMPLE:
|
case STATUS_SIMPLE:
|
||||||
m_bIsAnchored = false;
|
m_bIsAnchored = false;
|
||||||
m_fOrientation = INVALID_ORIENTATION;
|
m_fOrientation = INVALID_ORIENTATION;
|
||||||
|
CCarAI::UpdateCarAI(this);
|
||||||
CPhysical::ProcessControl();
|
CPhysical::ProcessControl();
|
||||||
bBoatInWater = true;
|
bBoatInWater = true;
|
||||||
bPropellerInWater = true;
|
bPropellerInWater = true;
|
||||||
|
@ -160,7 +162,8 @@ CBoat::ProcessControl(void)
|
||||||
case STATUS_PHYSICS:
|
case STATUS_PHYSICS:
|
||||||
m_bIsAnchored = false;
|
m_bIsAnchored = false;
|
||||||
m_fOrientation = INVALID_ORIENTATION;
|
m_fOrientation = INVALID_ORIENTATION;
|
||||||
CCarCtrl::SteerAIBoatWithPhysics(this);
|
CCarAI::UpdateCarAI(this);
|
||||||
|
CCarCtrl::SteerAICarWithPhysics(this);
|
||||||
break;
|
break;
|
||||||
case STATUS_ABANDONED:
|
case STATUS_ABANDONED:
|
||||||
case STATUS_WRECKED:
|
case STATUS_WRECKED:
|
||||||
|
@ -398,9 +401,9 @@ CBoat::ProcessControl(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Slow down or push down boat as it approaches the world limits
|
// Slow down or push down boat as it approaches the world limits
|
||||||
m_vecMoveSpeed.x = Min(m_vecMoveSpeed.x, -(GetPosition().x - 1900.0f)*0.01f); // east
|
m_vecMoveSpeed.x = Min(m_vecMoveSpeed.x, -(GetPosition().x - 1500.0f)*0.01f); // east
|
||||||
m_vecMoveSpeed.x = Max(m_vecMoveSpeed.x, -(GetPosition().x - -1515.0f)*0.01f); // west
|
m_vecMoveSpeed.x = Max(m_vecMoveSpeed.x, -(GetPosition().x - -2300.0f)*0.01f); // west
|
||||||
m_vecMoveSpeed.y = Min(m_vecMoveSpeed.y, -(GetPosition().y - 600.0f)*0.01f); // north
|
m_vecMoveSpeed.y = Min(m_vecMoveSpeed.y, -(GetPosition().y - 1900.0f)*0.01f); // north
|
||||||
m_vecMoveSpeed.y = Max(m_vecMoveSpeed.y, -(GetPosition().y - -1900.0f)*0.01f); // south
|
m_vecMoveSpeed.y = Max(m_vecMoveSpeed.y, -(GetPosition().y - -1900.0f)*0.01f); // south
|
||||||
|
|
||||||
if(!onLand && bBoatInWater)
|
if(!onLand && bBoatInWater)
|
||||||
|
|
|
@ -100,6 +100,7 @@ CVehicle::CVehicle(uint8 CreatedBy)
|
||||||
m_bSirenOrAlarm = 0;
|
m_bSirenOrAlarm = 0;
|
||||||
m_nCarHornTimer = 0;
|
m_nCarHornTimer = 0;
|
||||||
m_nCarHornPattern = 0;
|
m_nCarHornPattern = 0;
|
||||||
|
bPartOfConvoy = false;
|
||||||
bCreatedAsPoliceVehicle = false;
|
bCreatedAsPoliceVehicle = false;
|
||||||
bParking = false;
|
bParking = false;
|
||||||
m_nAlarmState = 0;
|
m_nAlarmState = 0;
|
||||||
|
@ -697,51 +698,57 @@ void
|
||||||
CVehicle::DoFixedMachineGuns(void)
|
CVehicle::DoFixedMachineGuns(void)
|
||||||
{
|
{
|
||||||
if(CPad::GetPad(0)->GetCarGunFired() && !bGunSwitchedOff){
|
if(CPad::GetPad(0)->GetCarGunFired() && !bGunSwitchedOff){
|
||||||
if(CTimer::GetTimeInMilliseconds() > m_nGunFiringTime + 150){
|
FireFixedMachineGuns();
|
||||||
CVector source, target;
|
|
||||||
float dx, dy, len;
|
|
||||||
|
|
||||||
dx = GetForward().x;
|
|
||||||
dy = GetForward().y;
|
|
||||||
len = Sqrt(SQR(dx) + SQR(dy));
|
|
||||||
if(len < 0.1f) len = 0.1f;
|
|
||||||
dx /= len;
|
|
||||||
dy /= len;
|
|
||||||
|
|
||||||
m_nGunFiringTime = CTimer::GetTimeInMilliseconds();
|
|
||||||
|
|
||||||
source = GetMatrix() * CVector(2.0f, 2.5f, 1.0f);
|
|
||||||
target = source + CVector(dx, dy, 0.0f)*60.0f;
|
|
||||||
target += CVector(
|
|
||||||
((CGeneral::GetRandomNumber()&0xFF)-128) * 0.015f,
|
|
||||||
((CGeneral::GetRandomNumber()&0xFF)-128) * 0.015f,
|
|
||||||
((CGeneral::GetRandomNumber()&0xFF)-128) * 0.02f);
|
|
||||||
CWeapon::DoTankDoomAiming(this, pDriver, &source, &target);
|
|
||||||
FireOneInstantHitRound(&source, &target, 15);
|
|
||||||
|
|
||||||
source = GetMatrix() * CVector(-2.0f, 2.5f, 1.0f);
|
|
||||||
target = source + CVector(dx, dy, 0.0f)*60.0f;
|
|
||||||
target += CVector(
|
|
||||||
((CGeneral::GetRandomNumber()&0xFF)-128) * 0.015f,
|
|
||||||
((CGeneral::GetRandomNumber()&0xFF)-128) * 0.015f,
|
|
||||||
((CGeneral::GetRandomNumber()&0xFF)-128) * 0.02f);
|
|
||||||
CWeapon::DoTankDoomAiming(this, pDriver, &source, &target);
|
|
||||||
FireOneInstantHitRound(&source, &target, 15);
|
|
||||||
|
|
||||||
DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f);
|
|
||||||
|
|
||||||
m_nAmmoInClip--;
|
|
||||||
if(m_nAmmoInClip == 0){
|
|
||||||
m_nAmmoInClip = 20;
|
|
||||||
m_nGunFiringTime = CTimer::GetTimeInMilliseconds() + 1400;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}else{
|
}else{
|
||||||
if(CTimer::GetTimeInMilliseconds() > m_nGunFiringTime + 1400)
|
if(CTimer::GetTimeInMilliseconds() > m_nGunFiringTime + 1400)
|
||||||
m_nAmmoInClip = 20;
|
m_nAmmoInClip = 20;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CVehicle::FireFixedMachineGuns(void)
|
||||||
|
{
|
||||||
|
if (CTimer::GetTimeInMilliseconds() <= m_nGunFiringTime + 150)
|
||||||
|
return;
|
||||||
|
CVector source, target;
|
||||||
|
float dx, dy, len;
|
||||||
|
|
||||||
|
dx = GetForward().x;
|
||||||
|
dy = GetForward().y;
|
||||||
|
len = Sqrt(SQR(dx) + SQR(dy));
|
||||||
|
if (len < 0.1f) len = 0.1f;
|
||||||
|
dx /= len;
|
||||||
|
dy /= len;
|
||||||
|
|
||||||
|
m_nGunFiringTime = CTimer::GetTimeInMilliseconds();
|
||||||
|
|
||||||
|
source = GetMatrix() * CVector(2.0f, 2.5f, 1.0f);
|
||||||
|
target = source + CVector(dx, dy, 0.0f) * 60.0f;
|
||||||
|
target += CVector(
|
||||||
|
((CGeneral::GetRandomNumber() & 0xFF) - 128) * 0.015f,
|
||||||
|
((CGeneral::GetRandomNumber() & 0xFF) - 128) * 0.015f,
|
||||||
|
((CGeneral::GetRandomNumber() & 0xFF) - 128) * 0.02f);
|
||||||
|
CWeapon::DoTankDoomAiming(this, pDriver, &source, &target);
|
||||||
|
FireOneInstantHitRound(&source, &target, 15);
|
||||||
|
|
||||||
|
source = GetMatrix() * CVector(-2.0f, 2.5f, 1.0f);
|
||||||
|
target = source + CVector(dx, dy, 0.0f) * 60.0f;
|
||||||
|
target += CVector(
|
||||||
|
((CGeneral::GetRandomNumber() & 0xFF) - 128) * 0.015f,
|
||||||
|
((CGeneral::GetRandomNumber() & 0xFF) - 128) * 0.015f,
|
||||||
|
((CGeneral::GetRandomNumber() & 0xFF) - 128) * 0.02f);
|
||||||
|
CWeapon::DoTankDoomAiming(this, pDriver, &source, &target);
|
||||||
|
FireOneInstantHitRound(&source, &target, 15);
|
||||||
|
|
||||||
|
DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f);
|
||||||
|
|
||||||
|
m_nAmmoInClip--;
|
||||||
|
if (m_nAmmoInClip == 0) {
|
||||||
|
m_nAmmoInClip = 20;
|
||||||
|
m_nGunFiringTime = CTimer::GetTimeInMilliseconds() + 1400;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CVehicle::ExtinguishCarFire(void)
|
CVehicle::ExtinguishCarFire(void)
|
||||||
{
|
{
|
||||||
|
@ -1034,7 +1041,7 @@ CVehicle::SetUpDriver(void)
|
||||||
if(VehicleCreatedBy != RANDOM_VEHICLE)
|
if(VehicleCreatedBy != RANDOM_VEHICLE)
|
||||||
return nil;
|
return nil;
|
||||||
|
|
||||||
pDriver = CPopulation::AddPedInCar(this);
|
pDriver = CPopulation::AddPedInCar(this, false);
|
||||||
pDriver->m_pMyVehicle = this;
|
pDriver->m_pMyVehicle = this;
|
||||||
pDriver->m_pMyVehicle->RegisterReference((CEntity**)&pDriver->m_pMyVehicle);
|
pDriver->m_pMyVehicle->RegisterReference((CEntity**)&pDriver->m_pMyVehicle);
|
||||||
pDriver->bInVehicle = true;
|
pDriver->bInVehicle = true;
|
||||||
|
@ -1050,7 +1057,7 @@ CVehicle::SetupPassenger(int n)
|
||||||
if(pPassengers[n])
|
if(pPassengers[n])
|
||||||
return pPassengers[n];
|
return pPassengers[n];
|
||||||
|
|
||||||
pPassengers[n] = CPopulation::AddPedInCar(this);
|
pPassengers[n] = CPopulation::AddPedInCar(this, true);
|
||||||
pPassengers[n]->m_pMyVehicle = this;
|
pPassengers[n]->m_pMyVehicle = this;
|
||||||
pPassengers[n]->m_pMyVehicle->RegisterReference((CEntity**)&pPassengers[n]->m_pMyVehicle);
|
pPassengers[n]->m_pMyVehicle->RegisterReference((CEntity**)&pPassengers[n]->m_pMyVehicle);
|
||||||
pPassengers[n]->bInVehicle = true;
|
pPassengers[n]->bInVehicle = true;
|
||||||
|
|
|
@ -182,6 +182,7 @@ public:
|
||||||
uint8 bIsCarParkVehicle : 1; // Car has been created using the special CAR_PARK script command
|
uint8 bIsCarParkVehicle : 1; // Car has been created using the special CAR_PARK script command
|
||||||
uint8 bHasAlreadyBeenRecorded : 1; // Used for replays
|
uint8 bHasAlreadyBeenRecorded : 1; // Used for replays
|
||||||
|
|
||||||
|
uint8 bPartOfConvoy : 1;
|
||||||
uint8 bCreatedAsPoliceVehicle : 1;// True if this guy was created as a police vehicle (enforcer, policecar, miamivice car etc)
|
uint8 bCreatedAsPoliceVehicle : 1;// True if this guy was created as a police vehicle (enforcer, policecar, miamivice car etc)
|
||||||
uint8 bParking : 1;
|
uint8 bParking : 1;
|
||||||
|
|
||||||
|
@ -287,6 +288,7 @@ public:
|
||||||
bool ShufflePassengersToMakeSpace(void);
|
bool ShufflePassengersToMakeSpace(void);
|
||||||
void InflictDamage(CEntity *damagedBy, eWeaponType weaponType, float damage);
|
void InflictDamage(CEntity *damagedBy, eWeaponType weaponType, float damage);
|
||||||
void DoFixedMachineGuns(void);
|
void DoFixedMachineGuns(void);
|
||||||
|
void FireFixedMachineGuns(void);
|
||||||
|
|
||||||
|
|
||||||
bool IsAlarmOn(void) { return m_nAlarmState != 0 && m_nAlarmState != -1; }
|
bool IsAlarmOn(void) { return m_nAlarmState != 0 && m_nAlarmState != -1; }
|
||||||
|
|
Loading…
Reference in a new issue