mirror of
https://git.rip/DMCA_FUCKER/re3.git
synced 2024-12-23 19:10:01 +00:00
Merge pull request #230 from Nick007J/master
CCarAI, CCurves, CAutoPilot
This commit is contained in:
commit
f70c2ad54f
|
@ -2,5 +2,50 @@
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
#include "AutoPilot.h"
|
#include "AutoPilot.h"
|
||||||
|
|
||||||
WRAPPER void CAutoPilot::RemoveOnePathNode() { EAXJMP(0x413A00); }
|
#include "CarCtrl.h"
|
||||||
|
#include "Curves.h"
|
||||||
|
#include "PathFind.h"
|
||||||
|
|
||||||
|
#if 0
|
||||||
WRAPPER void CAutoPilot::ModifySpeed(float) { EAXJMP(0x4137B0); }
|
WRAPPER void CAutoPilot::ModifySpeed(float) { EAXJMP(0x4137B0); }
|
||||||
|
#else
|
||||||
|
void CAutoPilot::ModifySpeed(float speed)
|
||||||
|
{
|
||||||
|
m_fMaxTrafficSpeed = max(0.01f, speed);
|
||||||
|
float positionBetweenNodes = (float)(CTimer::GetTimeInMilliseconds() - m_nTimeEnteredCurve) / m_nTimeToSpendOnCurrentCurve;
|
||||||
|
CCarPathLink* pCurrentLink = &ThePaths.m_carPathLinks[m_nCurrentPathNodeInfo];
|
||||||
|
CCarPathLink* pNextLink = &ThePaths.m_carPathLinks[m_nNextPathNodeInfo];
|
||||||
|
float currentPathLinkForwardX = m_nCurrentDirection * ThePaths.m_carPathLinks[m_nCurrentPathNodeInfo].dirX;
|
||||||
|
float currentPathLinkForwardY = m_nCurrentDirection * ThePaths.m_carPathLinks[m_nCurrentPathNodeInfo].dirY;
|
||||||
|
float nextPathLinkForwardX = m_nNextDirection * ThePaths.m_carPathLinks[m_nNextPathNodeInfo].dirX;
|
||||||
|
float nextPathLinkForwardY = m_nNextDirection * ThePaths.m_carPathLinks[m_nNextPathNodeInfo].dirY;
|
||||||
|
CVector positionOnCurrentLinkIncludingLane(
|
||||||
|
pCurrentLink->posX + ((m_nCurrentLane + 0.5f) * LANE_WIDTH) * currentPathLinkForwardY,
|
||||||
|
pCurrentLink->posY - ((m_nCurrentLane + 0.5f) * LANE_WIDTH) * currentPathLinkForwardX,
|
||||||
|
0.0f);
|
||||||
|
CVector positionOnNextLinkIncludingLane(
|
||||||
|
pNextLink->posX + ((m_nNextLane + 0.5f) * LANE_WIDTH) * nextPathLinkForwardY,
|
||||||
|
pNextLink->posY - ((m_nNextLane + 0.5f) * LANE_WIDTH) * nextPathLinkForwardX,
|
||||||
|
0.0f);
|
||||||
|
m_nTimeToSpendOnCurrentCurve = CCurves::CalcSpeedScaleFactor(
|
||||||
|
&positionOnCurrentLinkIncludingLane,
|
||||||
|
&positionOnNextLinkIncludingLane,
|
||||||
|
currentPathLinkForwardX, currentPathLinkForwardY,
|
||||||
|
nextPathLinkForwardX, nextPathLinkForwardY
|
||||||
|
) * (1000.0f / m_fMaxTrafficSpeed);
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
/* Casting timer to float is very unwanted, and in this case even causes crashes. */
|
||||||
|
m_nTimeEnteredCurve = CTimer::GetTimeInMilliseconds() -
|
||||||
|
(uint32)(positionBetweenNodes * m_nTimeToSpendOnCurrentCurve);
|
||||||
|
#else
|
||||||
|
m_nTimeEnteredCurve = CTimer::GetTimeInMilliseconds() - positionBetweenNodes * m_nSpeedScaleFactor;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void CAutoPilot::RemoveOnePathNode()
|
||||||
|
{
|
||||||
|
--m_nPathFindNodesCount;
|
||||||
|
for (int i = 0; i < m_nPathFindNodesCount; i++)
|
||||||
|
m_aPathFindNodesInfo[i] = m_aPathFindNodesInfo[i + 1];
|
||||||
|
}
|
|
@ -86,7 +86,7 @@ public:
|
||||||
uint8 m_bSlowedDownBecauseOfPeds : 1;
|
uint8 m_bSlowedDownBecauseOfPeds : 1;
|
||||||
uint8 m_bStayInCurrentLevel : 1;
|
uint8 m_bStayInCurrentLevel : 1;
|
||||||
uint8 m_bStayInFastLane : 1;
|
uint8 m_bStayInFastLane : 1;
|
||||||
uint8 m_flag10 : 1;
|
uint8 m_bIgnorePathfinding : 1;
|
||||||
CVector m_vecDestinationCoors;
|
CVector m_vecDestinationCoors;
|
||||||
CPathNode *m_aPathFindNodesInfo[NUM_PATH_NODES_IN_AUTOPILOT];
|
CPathNode *m_aPathFindNodesInfo[NUM_PATH_NODES_IN_AUTOPILOT];
|
||||||
int16 m_nPathFindNodesCount;
|
int16 m_nPathFindNodesCount;
|
||||||
|
|
|
@ -2,25 +2,631 @@
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
#include "CarAI.h"
|
#include "CarAI.h"
|
||||||
|
|
||||||
|
#include "AccidentManager.h"
|
||||||
#include "AutoPilot.h"
|
#include "AutoPilot.h"
|
||||||
|
#include "CarCtrl.h"
|
||||||
|
#include "General.h"
|
||||||
|
#include "HandlingMgr.h"
|
||||||
|
#include "ModelIndices.h"
|
||||||
|
#include "PlayerPed.h"
|
||||||
|
#include "Pools.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
|
#include "TrafficLights.h"
|
||||||
#include "Vehicle.h"
|
#include "Vehicle.h"
|
||||||
|
#include "World.h"
|
||||||
|
#include "ZoneCull.h"
|
||||||
|
|
||||||
WRAPPER void CCarAI::UpdateCarAI(CVehicle*) { EAXJMP(0x413E50); }
|
#define DISTANCE_TO_SWITCH_DISTANCE_GOTO 20.0f
|
||||||
WRAPPER void CCarAI::MakeWayForCarWithSiren(CVehicle *veh) { EAXJMP(0x416280); }
|
|
||||||
WRAPPER eCarMission CCarAI::FindPoliceCarMissionForWantedLevel() { EAXJMP(0x415E30); }
|
float CCarAI::FindSwitchDistanceClose(CVehicle*)
|
||||||
WRAPPER int32 CCarAI::FindPoliceCarSpeedForWantedLevel(CVehicle*) { EAXJMP(0x415EB0); }
|
{
|
||||||
WRAPPER void CCarAI::AddPoliceOccupants(CVehicle*) { EAXJMP(0x415C60); }
|
return 30.0f;
|
||||||
WRAPPER void CCarAI::AddAmbulanceOccupants(CVehicle*) { EAXJMP(0x415CE0); }
|
}
|
||||||
WRAPPER void CCarAI::AddFiretruckOccupants(CVehicle*) { EAXJMP(0x415D00); }
|
|
||||||
WRAPPER void CCarAI::TellOccupantsToLeaveCar(CVehicle*) { EAXJMP(0x415D20); }
|
float CCarAI::FindSwitchDistanceFar(CVehicle* pVehicle)
|
||||||
WRAPPER float CCarAI::GetCarToGoToCoors(CVehicle*, CVector*) { EAXJMP(0x415B10); }
|
{
|
||||||
|
return pVehicle->bIsLawEnforcer ? 50.0f : 35.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCarAI::UpdateCarAI(CVehicle* pVehicle)
|
||||||
|
{
|
||||||
|
//((void(*)(CVehicle*))(0x413E50))(pVehicle);
|
||||||
|
//return;
|
||||||
|
if (pVehicle->bIsLawEnforcer){
|
||||||
|
if (pVehicle->AutoPilot.m_nCarMission == MISSION_BLOCKCAR_FARAWAY ||
|
||||||
|
pVehicle->AutoPilot.m_nCarMission == MISSION_RAMPLAYER_FARAWAY ||
|
||||||
|
pVehicle->AutoPilot.m_nCarMission == MISSION_BLOCKPLAYER_CLOSE ||
|
||||||
|
pVehicle->AutoPilot.m_nCarMission == MISSION_RAMPLAYER_CLOSE)
|
||||||
|
pVehicle->AutoPilot.m_nCruiseSpeed = FindPoliceCarSpeedForWantedLevel(pVehicle);
|
||||||
|
}
|
||||||
|
switch (pVehicle->m_status){
|
||||||
|
case STATUS_PLAYER:
|
||||||
|
case STATUS_PLAYER_PLAYBACKFROMBUFFER:
|
||||||
|
case STATUS_TRAIN_MOVING:
|
||||||
|
case STATUS_TRAIN_NOT_MOVING:
|
||||||
|
case STATUS_HELI:
|
||||||
|
case STATUS_PLANE:
|
||||||
|
case STATUS_PLAYER_REMOTE:
|
||||||
|
case STATUS_PLAYER_DISABLED:
|
||||||
|
break;
|
||||||
|
case STATUS_SIMPLE:
|
||||||
|
case STATUS_PHYSICS:
|
||||||
|
switch (pVehicle->AutoPilot.m_nCarMission) {
|
||||||
|
case MISSION_RAMPLAYER_FARAWAY:
|
||||||
|
if (FindSwitchDistanceClose(pVehicle) > (FindPlayerCoors() - pVehicle->GetPosition()).Magnitude2D() ||
|
||||||
|
pVehicle->AutoPilot.m_bIgnorePathfinding) {
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_RAMPLAYER_CLOSE;
|
||||||
|
if (pVehicle->UsesSiren(pVehicle->GetModelIndex()))
|
||||||
|
pVehicle->m_bSirenOrAlarm = true;
|
||||||
|
}
|
||||||
|
if (FindPlayerPed()->m_pWanted->m_bIgnoredByEveryone || pVehicle->bIsLawEnforcer &&
|
||||||
|
(FindPlayerPed()->m_pWanted->m_nWantedLevel == 0 || FindPlayerPed()->m_pWanted->m_bIgnoredByCops || CCullZones::NoPolice())) {
|
||||||
|
CCarCtrl::JoinCarWithRoadSystem(pVehicle);
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_CRUISE;
|
||||||
|
pVehicle->m_bSirenOrAlarm = false;
|
||||||
|
if (CCullZones::NoPolice())
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MISSION_RAMPLAYER_CLOSE:
|
||||||
|
if (FindSwitchDistanceFar(pVehicle) >= (FindPlayerCoors() - pVehicle->GetPosition()).Magnitude2D() ||
|
||||||
|
pVehicle->AutoPilot.m_bIgnorePathfinding) {
|
||||||
|
if (FindPlayerVehicle()) {
|
||||||
|
if (pVehicle->GetHasCollidedWith(FindPlayerVehicle())) {
|
||||||
|
if (pVehicle->AutoPilot.m_nTempAction != TEMPACT_TURNLEFT && pVehicle->AutoPilot.m_nTempAction != TEMPACT_TURNRIGHT) {
|
||||||
|
if (FindPlayerVehicle()->GetMoveSpeed().Magnitude() < 0.05f) {
|
||||||
|
pVehicle->AutoPilot.m_nTempAction = TEMPACT_REVERSE;
|
||||||
|
pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 800;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pVehicle->AutoPilot.m_nTempAction = TEMPACT_REVERSE;
|
||||||
|
pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 50;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (FindPlayerVehicle() && FindPlayerVehicle()->GetMoveSpeed().Magnitude() < 0.05f)
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
pVehicle->m_nTimeBlocked += CTimer::GetTimeStepInMilliseconds();
|
||||||
|
#else
|
||||||
|
pVehicle->m_nTimeBlocked += 1000.0f / 60.0f * CTimer::GetTimeStep();
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
pVehicle->m_nTimeBlocked = 0;
|
||||||
|
if (!FindPlayerVehicle() || FindPlayerVehicle()->IsUpsideDown() ||
|
||||||
|
FindPlayerVehicle()->GetMoveSpeed().Magnitude() < 0.05f && pVehicle->m_nTimeBlocked > TIME_COPS_WAIT_TO_EXIT_AFTER_STOPPING) {
|
||||||
|
if (pVehicle->bIsLawEnforcer &&
|
||||||
|
(pVehicle->GetModelIndex() != MI_RHINO || pVehicle->m_randomSeed > 10000) &&
|
||||||
|
(FindPlayerCoors() - pVehicle->GetPosition()).Magnitude2D() < 10.0f) {
|
||||||
|
TellOccupantsToLeaveCar(pVehicle);
|
||||||
|
pVehicle->AutoPilot.m_nCruiseSpeed = 0;
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
|
||||||
|
if (FindPlayerPed()->m_pWanted->m_nWantedLevel <= 1)
|
||||||
|
pVehicle->m_bSirenOrAlarm = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!CCarCtrl::JoinCarWithRoadSystemGotoCoors(pVehicle, FindPlayerCoors(), true)){
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_RAMPLAYER_FARAWAY;
|
||||||
|
pVehicle->m_bSirenOrAlarm = false;
|
||||||
|
pVehicle->m_nCarHornTimer = 0;
|
||||||
|
}
|
||||||
|
if (FindPlayerPed()->m_pWanted->m_bIgnoredByEveryone || pVehicle->bIsLawEnforcer &&
|
||||||
|
(FindPlayerPed()->m_pWanted->m_nWantedLevel == 0 || FindPlayerPed()->m_pWanted->m_bIgnoredByCops || CCullZones::NoPolice())){
|
||||||
|
CCarCtrl::JoinCarWithRoadSystem(pVehicle);
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_CRUISE;
|
||||||
|
pVehicle->m_bSirenOrAlarm = false;
|
||||||
|
if (CCullZones::NoPolice())
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
|
||||||
|
}
|
||||||
|
else if (pVehicle->bIsLawEnforcer)
|
||||||
|
MellowOutChaseSpeed(pVehicle);
|
||||||
|
break;
|
||||||
|
case MISSION_BLOCKPLAYER_FARAWAY:
|
||||||
|
if (FindSwitchDistanceClose(pVehicle) > (FindPlayerCoors() - pVehicle->GetPosition()).Magnitude2D() ||
|
||||||
|
pVehicle->AutoPilot.m_bIgnorePathfinding) {
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_BLOCKPLAYER_CLOSE;
|
||||||
|
if (pVehicle->UsesSiren(pVehicle->GetModelIndex()))
|
||||||
|
pVehicle->m_bSirenOrAlarm = true;
|
||||||
|
}
|
||||||
|
if (FindPlayerPed()->m_pWanted->m_bIgnoredByEveryone || pVehicle->bIsLawEnforcer &&
|
||||||
|
(FindPlayerPed()->m_pWanted->m_nWantedLevel == 0 || FindPlayerPed()->m_pWanted->m_bIgnoredByCops || CCullZones::NoPolice())) {
|
||||||
|
CCarCtrl::JoinCarWithRoadSystem(pVehicle);
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_CRUISE;
|
||||||
|
pVehicle->m_bSirenOrAlarm = false;
|
||||||
|
if (CCullZones::NoPolice())
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MISSION_BLOCKPLAYER_CLOSE:
|
||||||
|
if (FindSwitchDistanceFar(pVehicle) >= (FindPlayerCoors() - pVehicle->GetPosition()).Magnitude2D() ||
|
||||||
|
pVehicle->AutoPilot.m_bIgnorePathfinding) {
|
||||||
|
if (FindPlayerVehicle() && FindPlayerVehicle()->GetMoveSpeed().Magnitude() < 0.05f)
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
pVehicle->m_nTimeBlocked += CTimer::GetTimeStepInMilliseconds();
|
||||||
|
#else
|
||||||
|
pVehicle->m_nTimeBlocked += 1000.0f / 60.0f * CTimer::GetTimeStep();
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
pVehicle->m_nTimeBlocked = 0;
|
||||||
|
if (!FindPlayerVehicle() || FindPlayerVehicle()->IsUpsideDown() ||
|
||||||
|
FindPlayerVehicle()->GetMoveSpeed().Magnitude() < 0.05f && pVehicle->m_nTimeBlocked > TIME_COPS_WAIT_TO_EXIT_AFTER_STOPPING) {
|
||||||
|
if (pVehicle->bIsLawEnforcer &&
|
||||||
|
(pVehicle->GetModelIndex() != MI_RHINO || pVehicle->m_randomSeed > 10000) &&
|
||||||
|
(FindPlayerCoors() - pVehicle->GetPosition()).Magnitude2D() < 10.0f) {
|
||||||
|
TellOccupantsToLeaveCar(pVehicle);
|
||||||
|
pVehicle->AutoPilot.m_nCruiseSpeed = 0;
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
|
||||||
|
if (FindPlayerPed()->m_pWanted->m_nWantedLevel <= 1)
|
||||||
|
pVehicle->m_bSirenOrAlarm = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else if (!CCarCtrl::JoinCarWithRoadSystemGotoCoors(pVehicle, FindPlayerCoors(), true)) {
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_BLOCKPLAYER_FARAWAY;
|
||||||
|
pVehicle->m_bSirenOrAlarm = false;
|
||||||
|
pVehicle->m_nCarHornTimer = 0;
|
||||||
|
}
|
||||||
|
if (FindPlayerPed()->m_pWanted->m_bIgnoredByEveryone || pVehicle->bIsLawEnforcer &&
|
||||||
|
(FindPlayerPed()->m_pWanted->m_nWantedLevel == 0 || FindPlayerPed()->m_pWanted->m_bIgnoredByCops || CCullZones::NoPolice())) {
|
||||||
|
CCarCtrl::JoinCarWithRoadSystem(pVehicle);
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_CRUISE;
|
||||||
|
pVehicle->m_bSirenOrAlarm = false;
|
||||||
|
if (CCullZones::NoPolice())
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
|
||||||
|
}
|
||||||
|
else if (pVehicle->bIsLawEnforcer)
|
||||||
|
MellowOutChaseSpeed(pVehicle);
|
||||||
|
break;
|
||||||
|
case MISSION_GOTOCOORDS:
|
||||||
|
if ((pVehicle->AutoPilot.m_vecDestinationCoors - pVehicle->GetPosition()).Magnitude2D() < DISTANCE_TO_SWITCH_DISTANCE_GOTO ||
|
||||||
|
pVehicle->AutoPilot.m_bIgnorePathfinding)
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS_STRAIGHT;
|
||||||
|
break;
|
||||||
|
case MISSION_GOTOCOORDS_STRAIGHT:
|
||||||
|
{
|
||||||
|
float distance = (pVehicle->AutoPilot.m_vecDestinationCoors - pVehicle->GetPosition()).Magnitude2D();
|
||||||
|
if ((pVehicle->bIsAmbulanceOnDuty || pVehicle->bIsFireTruckOnDuty) && distance < 20.0f)
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_EMERGENCYVEHICLE_STOP;
|
||||||
|
if (distance < 5.0f){
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
|
||||||
|
pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
|
||||||
|
}
|
||||||
|
else if (distance > 35.0f && !pVehicle->AutoPilot.m_bIgnorePathfinding && (CTimer::GetFrameCounter() & 7) == 0){
|
||||||
|
pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = (CCarCtrl::JoinCarWithRoadSystemGotoCoors(pVehicle, pVehicle->AutoPilot.m_vecDestinationCoors, true)) ?
|
||||||
|
MISSION_GOTOCOORDS_STRAIGHT : MISSION_GOTOCOORDS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MISSION_EMERGENCYVEHICLE_STOP:
|
||||||
|
if (pVehicle->GetMoveSpeed().Magnitude2D() < 0.01f){
|
||||||
|
if (pVehicle->bIsAmbulanceOnDuty){
|
||||||
|
float distance = 30.0f;
|
||||||
|
if (gAccidentManager.FindNearestAccident(pVehicle->AutoPilot.m_vecDestinationCoors, &distance)){
|
||||||
|
TellOccupantsToLeaveCar(pVehicle);
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_STOP_FOREVER;
|
||||||
|
}else{
|
||||||
|
CCarCtrl::JoinCarWithRoadSystem(pVehicle);
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_CRUISE;
|
||||||
|
pVehicle->m_bSirenOrAlarm = false;
|
||||||
|
pVehicle->AutoPilot.m_nCruiseSpeed = 17;
|
||||||
|
if (pVehicle->bIsAmbulanceOnDuty){
|
||||||
|
pVehicle->bIsAmbulanceOnDuty = false;
|
||||||
|
--CCarCtrl::NumAmbulancesOnDuty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pVehicle->bIsFireTruckOnDuty) {
|
||||||
|
float distance = 30.0f;
|
||||||
|
if (gFireManager.FindNearestFire(pVehicle->AutoPilot.m_vecDestinationCoors, &distance)) {
|
||||||
|
TellOccupantsToLeaveCar(pVehicle);
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_STOP_FOREVER;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CCarCtrl::JoinCarWithRoadSystem(pVehicle);
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_CRUISE;
|
||||||
|
pVehicle->m_bSirenOrAlarm = false;
|
||||||
|
pVehicle->AutoPilot.m_nCruiseSpeed = 17;
|
||||||
|
if (pVehicle->bIsFireTruckOnDuty) {
|
||||||
|
pVehicle->bIsFireTruckOnDuty = false;
|
||||||
|
--CCarCtrl::NumFiretrucksOnDuty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MISSION_GOTOCOORDS_ACCURATE:
|
||||||
|
if ((pVehicle->AutoPilot.m_vecDestinationCoors - pVehicle->GetPosition()).Magnitude2D() < 20.0f ||
|
||||||
|
pVehicle->AutoPilot.m_bIgnorePathfinding)
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_GOTO_COORDS_STRAIGHT_ACCURATE;
|
||||||
|
break;
|
||||||
|
case MISSION_GOTO_COORDS_STRAIGHT_ACCURATE:
|
||||||
|
{
|
||||||
|
float distance = (pVehicle->AutoPilot.m_vecDestinationCoors - pVehicle->GetPosition()).Magnitude2D();
|
||||||
|
if (distance < 1.0f) {
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
|
||||||
|
pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
|
||||||
|
}
|
||||||
|
else if (distance > 35.0f && !pVehicle->AutoPilot.m_bIgnorePathfinding && (CTimer::GetFrameCounter() & 7) == 0) {
|
||||||
|
pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = (CCarCtrl::JoinCarWithRoadSystemGotoCoors(pVehicle, pVehicle->AutoPilot.m_vecDestinationCoors, true)) ?
|
||||||
|
MISSION_GOTOCOORDS_STRAIGHT : MISSION_GOTOCOORDS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MISSION_RAMCAR_FARAWAY:
|
||||||
|
if (pVehicle->AutoPilot.m_pTargetCar){
|
||||||
|
if ((pVehicle->GetPosition() - pVehicle->AutoPilot.m_pTargetCar->GetPosition()).Magnitude2D() < FindSwitchDistanceClose(pVehicle) ||
|
||||||
|
pVehicle->AutoPilot.m_bIgnorePathfinding)
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_RAMCAR_CLOSE;
|
||||||
|
}else{
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MISSION_RAMCAR_CLOSE:
|
||||||
|
if (pVehicle->AutoPilot.m_pTargetCar){
|
||||||
|
/* PlayerPed? */
|
||||||
|
if (FindPlayerPed()->m_pWanted->m_bIgnoredByEveryone || pVehicle->bIsLawEnforcer &&
|
||||||
|
(FindPlayerPed()->m_pWanted->m_nWantedLevel == 0 || FindPlayerPed()->m_pWanted->m_bIgnoredByCops || CCullZones::NoPolice())){
|
||||||
|
CCarCtrl::JoinCarWithRoadSystem(pVehicle);
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_CRUISE;
|
||||||
|
pVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS;
|
||||||
|
pVehicle->m_bSirenOrAlarm = false;
|
||||||
|
if (CCullZones::NoPolice())
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
|
||||||
|
}
|
||||||
|
if ((pVehicle->AutoPilot.m_pTargetCar->GetPosition() - pVehicle->GetPosition()).Magnitude2D() <= FindSwitchDistanceFar(pVehicle) ||
|
||||||
|
pVehicle->AutoPilot.m_bIgnorePathfinding){
|
||||||
|
if (pVehicle->GetHasCollidedWith(pVehicle->AutoPilot.m_pTargetCar)){
|
||||||
|
if (pVehicle->GetMoveSpeed().Magnitude() < 0.04f){
|
||||||
|
pVehicle->AutoPilot.m_nTempAction = TEMPACT_REVERSE;
|
||||||
|
pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 800;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_RAMCAR_FARAWAY;
|
||||||
|
CCarCtrl::JoinCarWithRoadSystem(pVehicle);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MISSION_BLOCKCAR_FARAWAY:
|
||||||
|
if (pVehicle->AutoPilot.m_pTargetCar){
|
||||||
|
if ((pVehicle->AutoPilot.m_pTargetCar->GetPosition() - pVehicle->GetPosition()).Magnitude2D() < FindSwitchDistanceClose(pVehicle) ||
|
||||||
|
pVehicle->AutoPilot.m_bIgnorePathfinding){
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_BLOCKCAR_CLOSE;
|
||||||
|
if (pVehicle->UsesSiren(pVehicle->GetModelIndex()))
|
||||||
|
pVehicle->m_bSirenOrAlarm = true;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MISSION_BLOCKCAR_CLOSE:
|
||||||
|
if (pVehicle->AutoPilot.m_pTargetCar){
|
||||||
|
if ((pVehicle->AutoPilot.m_pTargetCar->GetPosition() - pVehicle->GetPosition()).Magnitude2D() > FindSwitchDistanceFar(pVehicle) &&
|
||||||
|
!pVehicle->AutoPilot.m_bIgnorePathfinding){
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_BLOCKCAR_FARAWAY;
|
||||||
|
pVehicle->m_bSirenOrAlarm = false;
|
||||||
|
pVehicle->m_nCarHornTimer = 0;
|
||||||
|
CCarCtrl::JoinCarWithRoadSystem(pVehicle);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (pVehicle->bIsLawEnforcer && FindPlayerPed()->m_pWanted->m_nWantedLevel > 0 && !CCullZones::NoPolice()){
|
||||||
|
if (ABS(FindPlayerCoors().x - pVehicle->GetPosition().x) > 10.0f ||
|
||||||
|
ABS(FindPlayerCoors().y - pVehicle->GetPosition().y) > 10.0f){
|
||||||
|
pVehicle->AutoPilot.m_nCruiseSpeed = FindPoliceCarSpeedForWantedLevel(pVehicle);
|
||||||
|
pVehicle->m_status = STATUS_PHYSICS;
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = FindPoliceCarMissionForWantedLevel();
|
||||||
|
pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
|
||||||
|
pVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
|
||||||
|
}else if (pVehicle->AutoPilot.m_nCarMission == MISSION_CRUISE){
|
||||||
|
pVehicle->m_status = STATUS_PHYSICS;
|
||||||
|
TellOccupantsToLeaveCar(pVehicle);
|
||||||
|
pVehicle->AutoPilot.m_nCruiseSpeed = 0;
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
|
||||||
|
if (FindPlayerPed()->m_pWanted->m_nWantedLevel <= 1)
|
||||||
|
pVehicle->m_bSirenOrAlarm = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case STATUS_ABANDONED:
|
||||||
|
case STATUS_WRECKED:
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
|
||||||
|
pVehicle->AutoPilot.m_nCruiseSpeed = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
float flatSpeed = pVehicle->GetMoveSpeed().MagnitudeSqr2D();
|
||||||
|
if (flatSpeed > SQR(0.018f)){
|
||||||
|
pVehicle->AutoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds();
|
||||||
|
pVehicle->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
|
||||||
|
}
|
||||||
|
if (pVehicle->m_status == STATUS_PHYSICS && pVehicle->AutoPilot.m_nTempAction == TEMPACT_NONE){
|
||||||
|
if (pVehicle->AutoPilot.m_nCarMission != MISSION_NONE){
|
||||||
|
if (pVehicle->AutoPilot.m_nCarMission != MISSION_STOP_FOREVER &&
|
||||||
|
pVehicle->AutoPilot.m_nCruiseSpeed != 0 &&
|
||||||
|
(pVehicle->VehicleCreatedBy != RANDOM_VEHICLE || pVehicle->AutoPilot.m_nCarMission != MISSION_CRUISE)){
|
||||||
|
if (pVehicle->AutoPilot.m_nDrivingStyle != DRIVINGSTYLE_STOP_FOR_CARS){
|
||||||
|
if (CTimer::GetTimeInMilliseconds() - pVehicle->m_nLastTimeCollided > 500)
|
||||||
|
pVehicle->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
|
||||||
|
if (flatSpeed < SQR(0.018f) && CTimer::GetTimeInMilliseconds() - pVehicle->AutoPilot.m_nAntiReverseTimer > 2000){
|
||||||
|
pVehicle->AutoPilot.m_nTempAction = TEMPACT_REVERSE;
|
||||||
|
if (pVehicle->AutoPilot.m_nCarMission != MISSION_NONE &&
|
||||||
|
pVehicle->AutoPilot.m_nCarMission != MISSION_CRUISE || pVehicle->VehicleCreatedBy == RANDOM_VEHICLE)
|
||||||
|
pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 1500;
|
||||||
|
else
|
||||||
|
pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 750;
|
||||||
|
pVehicle->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
|
||||||
|
if (pVehicle->VehicleCreatedBy == RANDOM_VEHICLE)
|
||||||
|
pVehicle->AutoPilot.m_nDrivingStyle = max(DRIVINGSTYLE_AVOID_CARS, pVehicle->AutoPilot.m_nDrivingStyle);
|
||||||
|
pVehicle->PlayCarHorn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((pVehicle->m_randomSeed & 7) == 0){
|
||||||
|
if (CTimer::GetTimeInMilliseconds() - pVehicle->AutoPilot.m_nTimeToStartMission > 30000 &&
|
||||||
|
CTimer::GetPreviousTimeInMilliseconds() - pVehicle->AutoPilot.m_nTimeToStartMission <= 30000 &&
|
||||||
|
pVehicle->AutoPilot.m_nCarMission == MISSION_CRUISE &&
|
||||||
|
!CTrafficLights::ShouldCarStopForBridge(pVehicle)){
|
||||||
|
pVehicle->m_status = STATUS_PHYSICS;
|
||||||
|
CCarCtrl::SwitchVehicleToRealPhysics(pVehicle);
|
||||||
|
pVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
|
||||||
|
pVehicle->AutoPilot.m_nTempAction = TEMPACT_REVERSE;
|
||||||
|
pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 400;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pVehicle->GetUp().z < 0.7f){
|
||||||
|
pVehicle->AutoPilot.m_nTempAction = TEMPACT_WAIT;
|
||||||
|
pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 1000;
|
||||||
|
}
|
||||||
|
if (pVehicle->AutoPilot.m_nTempAction == TEMPACT_NONE){
|
||||||
|
switch (pVehicle->AutoPilot.m_nCarMission){
|
||||||
|
case MISSION_RAMPLAYER_FARAWAY:
|
||||||
|
case MISSION_RAMPLAYER_CLOSE:
|
||||||
|
case MISSION_BLOCKPLAYER_FARAWAY:
|
||||||
|
case MISSION_BLOCKPLAYER_CLOSE:
|
||||||
|
if (FindPlayerVehicle() && FindPlayerSpeed().Magnitude() > pVehicle->GetMoveSpeed().Magnitude()){
|
||||||
|
if (FindPlayerSpeed().Magnitude() > 0.1f){
|
||||||
|
if (DotProduct2D(FindPlayerVehicle()->GetForward(), pVehicle->GetForward()) > 0.0f){
|
||||||
|
CVector2D dist = pVehicle->GetPosition() - FindPlayerCoors();
|
||||||
|
CVector2D speed = FindPlayerSpeed();
|
||||||
|
if (0.5f * dist.Magnitude() * speed.Magnitude() < DotProduct2D(dist, speed)){
|
||||||
|
if ((FindPlayerCoors() - pVehicle->GetPosition()).Magnitude() > 12.0f){
|
||||||
|
pVehicle->AutoPilot.m_nTempAction = TEMPACT_WAIT;
|
||||||
|
pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pVehicle->pDriver && pVehicle->pDriver->m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS){
|
||||||
|
if ((pVehicle->GetPosition() - FindPlayerCoors()).Magnitude() < 15.0f){
|
||||||
|
if (!FindPlayerVehicle() || pVehicle->GetHasCollidedWith(FindPlayerVehicle())){
|
||||||
|
pVehicle->AutoPilot.m_nTempAction = TEMPACT_WAIT;
|
||||||
|
pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 3000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pVehicle->m_bSirenOrAlarm){
|
||||||
|
if ((uint8)(pVehicle->m_randomSeed ^ CGeneral::GetRandomNumber()) == 0xAD)
|
||||||
|
pVehicle->m_nCarHornTimer = 45;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CCarAI::CarHasReasonToStop(CVehicle* pVehicle)
|
void CCarAI::CarHasReasonToStop(CVehicle* pVehicle)
|
||||||
{
|
{
|
||||||
pVehicle->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
|
pVehicle->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float CCarAI::GetCarToGoToCoors(CVehicle* pVehicle, CVector* pTarget)
|
||||||
|
{
|
||||||
|
if (pVehicle->AutoPilot.m_nCarMission != MISSION_GOTOCOORDS && pVehicle->AutoPilot.m_nCarMission != MISSION_GOTOCOORDS_STRAIGHT){
|
||||||
|
pVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
|
||||||
|
pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
|
||||||
|
pVehicle->AutoPilot.m_nCruiseSpeed = 20;
|
||||||
|
pVehicle->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
|
||||||
|
pVehicle->m_status = STATUS_PHYSICS;
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = (CCarCtrl::JoinCarWithRoadSystemGotoCoors(pVehicle, *pTarget, false)) ?
|
||||||
|
MISSION_GOTOCOORDS_STRAIGHT : MISSION_GOTOCOORDS;
|
||||||
|
}else if (Abs(pTarget->x - pVehicle->AutoPilot.m_vecDestinationCoors.x) > 2.0f ||
|
||||||
|
Abs(pTarget->x - pVehicle->AutoPilot.m_vecDestinationCoors.x) > 2.0f){
|
||||||
|
pVehicle->AutoPilot.m_vecDestinationCoors = *pTarget;
|
||||||
|
}
|
||||||
|
return (pVehicle->GetPosition() - *pTarget).Magnitude2D();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCarAI::AddPoliceOccupants(CVehicle* pVehicle)
|
||||||
|
{
|
||||||
|
if (pVehicle->bOccupantsHaveBeenGenerated)
|
||||||
|
return;
|
||||||
|
switch (pVehicle->GetModelIndex()){
|
||||||
|
case MI_FBICAR:
|
||||||
|
case MI_ENFORCER:
|
||||||
|
pVehicle->SetUpDriver();
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
pVehicle->SetupPassenger(i);
|
||||||
|
return;
|
||||||
|
case MI_POLICE:
|
||||||
|
case MI_RHINO:
|
||||||
|
case MI_BARRACKS:
|
||||||
|
pVehicle->SetUpDriver();
|
||||||
|
if (FindPlayerPed()->m_pWanted->m_nWantedLevel > 1)
|
||||||
|
pVehicle->SetupPassenger(0);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCarAI::AddAmbulanceOccupants(CVehicle* pVehicle)
|
||||||
|
{
|
||||||
|
pVehicle->SetUpDriver();
|
||||||
|
pVehicle->SetupPassenger(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCarAI::AddFiretruckOccupants(CVehicle* pVehicle)
|
||||||
|
{
|
||||||
|
pVehicle->SetUpDriver();
|
||||||
|
pVehicle->SetupPassenger(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCarAI::TellOccupantsToLeaveCar(CVehicle* pVehicle)
|
||||||
|
{
|
||||||
|
if (pVehicle->pDriver){
|
||||||
|
pVehicle->pDriver->SetObjective(OBJECTIVE_LEAVE_VEHICLE, pVehicle);
|
||||||
|
if (pVehicle->GetModelIndex())
|
||||||
|
pVehicle->pDriver->Say(SOUND_PED_LEAVE_VEHICLE);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < pVehicle->m_nNumMaxPassengers; i++){
|
||||||
|
if (pVehicle->pPassengers[i])
|
||||||
|
pVehicle->pPassengers[i]->SetObjective(OBJECTIVE_LEAVE_VEHICLE, pVehicle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCarAI::TellCarToRamOtherCar(CVehicle* pVehicle, CVehicle* pTarget)
|
||||||
|
{
|
||||||
|
pVehicle->AutoPilot.m_pTargetCar = pTarget;
|
||||||
|
pTarget->RegisterReference((CEntity**)&pVehicle->AutoPilot.m_pTargetCar);
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_RAMCAR_FARAWAY;
|
||||||
|
pVehicle->bEngineOn = true;
|
||||||
|
pVehicle->AutoPilot.m_nCruiseSpeed = min(6, pVehicle->AutoPilot.m_nCruiseSpeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCarAI::TellCarToBlockOtherCar(CVehicle* pVehicle, CVehicle* pTarget)
|
||||||
|
{
|
||||||
|
pVehicle->AutoPilot.m_pTargetCar = pTarget;
|
||||||
|
pTarget->RegisterReference((CEntity**)&pVehicle->AutoPilot.m_pTargetCar);
|
||||||
|
pVehicle->AutoPilot.m_nCarMission = MISSION_BLOCKCAR_FARAWAY;
|
||||||
|
pVehicle->bEngineOn = true;
|
||||||
|
pVehicle->AutoPilot.m_nCruiseSpeed = min(6, pVehicle->AutoPilot.m_nCruiseSpeed);
|
||||||
|
}
|
||||||
|
eCarMission CCarAI::FindPoliceCarMissionForWantedLevel()
|
||||||
|
{
|
||||||
|
switch (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->m_nWantedLevel){
|
||||||
|
case 0:
|
||||||
|
case 1: return MISSION_BLOCKPLAYER_FARAWAY;
|
||||||
|
case 2: return (CGeneral::GetRandomNumber() & 3) >= 3 ? MISSION_RAMPLAYER_FARAWAY : MISSION_BLOCKPLAYER_FARAWAY;
|
||||||
|
case 3: return (CGeneral::GetRandomNumber() & 3) >= 2 ? MISSION_RAMPLAYER_FARAWAY : MISSION_BLOCKPLAYER_FARAWAY;
|
||||||
|
case 4:
|
||||||
|
case 5:
|
||||||
|
case 6: return (CGeneral::GetRandomNumber() & 3) >= 1 ? MISSION_RAMPLAYER_FARAWAY : MISSION_BLOCKPLAYER_FARAWAY;
|
||||||
|
default: return MISSION_BLOCKPLAYER_FARAWAY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 CCarAI::FindPoliceCarSpeedForWantedLevel(CVehicle* pVehicle)
|
||||||
|
{
|
||||||
|
switch (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->m_nWantedLevel) {
|
||||||
|
case 0: return CGeneral::GetRandomNumberInRange(12, 16);
|
||||||
|
case 1: return 25;
|
||||||
|
case 2: return 34;
|
||||||
|
case 3: return GAME_SPEED_TO_CARAI_SPEED * pVehicle->pHandling->Transmission.fMaxVelocity * 0.9f;
|
||||||
|
case 4: return GAME_SPEED_TO_CARAI_SPEED * pVehicle->pHandling->Transmission.fMaxVelocity * 1.2f;
|
||||||
|
case 5: return GAME_SPEED_TO_CARAI_SPEED * pVehicle->pHandling->Transmission.fMaxVelocity * 1.25f;
|
||||||
|
case 6: return GAME_SPEED_TO_CARAI_SPEED * pVehicle->pHandling->Transmission.fMaxVelocity * 1.3f;
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCarAI::MellowOutChaseSpeed(CVehicle* pVehicle)
|
||||||
|
{
|
||||||
|
if (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->m_nWantedLevel == 1){
|
||||||
|
float distanceToPlayer = (pVehicle->GetPosition() - FindPlayerCoors()).Magnitude();
|
||||||
|
if (FindPlayerVehicle()){
|
||||||
|
if (distanceToPlayer < 10.0f)
|
||||||
|
pVehicle->AutoPilot.m_nCruiseSpeed = 15;
|
||||||
|
else if (distanceToPlayer < 20.0f)
|
||||||
|
pVehicle->AutoPilot.m_nCruiseSpeed = 22;
|
||||||
|
else
|
||||||
|
pVehicle->AutoPilot.m_nCruiseSpeed = 25;
|
||||||
|
}else{
|
||||||
|
if (distanceToPlayer < 20.0f)
|
||||||
|
pVehicle->AutoPilot.m_nCruiseSpeed = 5;
|
||||||
|
else if (distanceToPlayer < 40.0f)
|
||||||
|
pVehicle->AutoPilot.m_nCruiseSpeed = 13;
|
||||||
|
else
|
||||||
|
pVehicle->AutoPilot.m_nCruiseSpeed = 25;
|
||||||
|
}
|
||||||
|
}else if (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->m_nWantedLevel == 2){
|
||||||
|
float distanceToPlayer = (pVehicle->GetPosition() - FindPlayerCoors()).Magnitude();
|
||||||
|
if (FindPlayerVehicle()) {
|
||||||
|
if (distanceToPlayer < 10.0f)
|
||||||
|
pVehicle->AutoPilot.m_nCruiseSpeed = 27;
|
||||||
|
else if (distanceToPlayer < 20.0f)
|
||||||
|
pVehicle->AutoPilot.m_nCruiseSpeed = 30;
|
||||||
|
else
|
||||||
|
pVehicle->AutoPilot.m_nCruiseSpeed = 34;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (distanceToPlayer < 20.0f)
|
||||||
|
pVehicle->AutoPilot.m_nCruiseSpeed = 5;
|
||||||
|
else if (distanceToPlayer < 40.0f)
|
||||||
|
pVehicle->AutoPilot.m_nCruiseSpeed = 18;
|
||||||
|
else
|
||||||
|
pVehicle->AutoPilot.m_nCruiseSpeed = 34;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCarAI::MakeWayForCarWithSiren(CVehicle *pVehicle)
|
||||||
|
{
|
||||||
|
float flatSpeed = pVehicle->GetMoveSpeed().Magnitude2D();
|
||||||
|
if (flatSpeed < 0.1f)
|
||||||
|
return;
|
||||||
|
CVector2D forward = pVehicle->GetMoveSpeed() / flatSpeed;
|
||||||
|
float projection = flatSpeed * 45 + 20;
|
||||||
|
int i = CPools::GetVehiclePool()->GetSize();
|
||||||
|
while (i--) {
|
||||||
|
CVehicle* vehicle = CPools::GetVehiclePool()->GetSlot(i);
|
||||||
|
if (!vehicle)
|
||||||
|
continue;
|
||||||
|
if (vehicle->m_vehType != VEHICLE_TYPE_CAR && vehicle->m_vehType != VEHICLE_TYPE_BIKE)
|
||||||
|
continue;
|
||||||
|
if (vehicle->m_status != STATUS_SIMPLE && vehicle->m_status != STATUS_PHYSICS)
|
||||||
|
continue;
|
||||||
|
if (vehicle->VehicleCreatedBy != RANDOM_VEHICLE)
|
||||||
|
continue;
|
||||||
|
if (vehicle->bIsLawEnforcer || vehicle->bIsAmbulanceOnDuty || vehicle->bIsFireTruckOnDuty)
|
||||||
|
continue;
|
||||||
|
if (vehicle == pVehicle)
|
||||||
|
continue;
|
||||||
|
if (Abs(pVehicle->GetPosition().z - vehicle->GetPosition().z) >= 5.0f)
|
||||||
|
continue;
|
||||||
|
CVector2D distance = vehicle->GetPosition() - pVehicle->GetPosition();
|
||||||
|
if (distance.Magnitude() >= projection)
|
||||||
|
continue;
|
||||||
|
if (vehicle->GetMoveSpeed().Magnitude2D() <= 0.05f)
|
||||||
|
continue;
|
||||||
|
float correlation = DotProduct2D(forward, distance) / distance.Magnitude();
|
||||||
|
if (correlation <= 0.0f)
|
||||||
|
continue;
|
||||||
|
if (correlation > 0.8f && DotProduct2D(forward, vehicle->GetForward()) > 0.7f){
|
||||||
|
if (vehicle->AutoPilot.m_nTempAction != TEMPACT_SWERVELEFT && vehicle->AutoPilot.m_nTempAction != TEMPACT_SWERVERIGHT){
|
||||||
|
vehicle->AutoPilot.m_nTempAction = (distance.x * forward.y - distance.y * forward.x > 0.0f) ?
|
||||||
|
TEMPACT_SWERVELEFT : TEMPACT_SWERVERIGHT;
|
||||||
|
vehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 2000;
|
||||||
|
}
|
||||||
|
vehicle->m_status = STATUS_PHYSICS;
|
||||||
|
}else{
|
||||||
|
if (DotProduct2D(vehicle->GetMoveSpeed(), distance) < 0.0f && vehicle->AutoPilot.m_nTempAction != TEMPACT_WAIT){
|
||||||
|
vehicle->AutoPilot.m_nTempAction = TEMPACT_WAIT;
|
||||||
|
vehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 2000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
STARTPATCHES
|
STARTPATCHES
|
||||||
InjectHook(0x415B00, &CCarAI::CarHasReasonToStop, PATCH_JUMP);
|
|
||||||
ENDPATCHES
|
ENDPATCHES
|
|
@ -7,14 +7,19 @@ class CVehicle;
|
||||||
class CCarAI
|
class CCarAI
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static float FindSwitchDistanceClose(CVehicle*);
|
||||||
|
static float FindSwitchDistanceFar(CVehicle*);
|
||||||
static void UpdateCarAI(CVehicle*);
|
static void UpdateCarAI(CVehicle*);
|
||||||
static void MakeWayForCarWithSiren(CVehicle *veh);
|
static void CarHasReasonToStop(CVehicle*);
|
||||||
static int32 FindPoliceCarSpeedForWantedLevel(CVehicle*);
|
static float GetCarToGoToCoors(CVehicle*, CVector*);
|
||||||
static eCarMission FindPoliceCarMissionForWantedLevel();
|
|
||||||
static void AddPoliceOccupants(CVehicle*);
|
static void AddPoliceOccupants(CVehicle*);
|
||||||
static void AddAmbulanceOccupants(CVehicle*);
|
static void AddAmbulanceOccupants(CVehicle*);
|
||||||
static void AddFiretruckOccupants(CVehicle*);
|
static void AddFiretruckOccupants(CVehicle*);
|
||||||
static void CarHasReasonToStop(CVehicle*);
|
|
||||||
static void TellOccupantsToLeaveCar(CVehicle*);
|
static void TellOccupantsToLeaveCar(CVehicle*);
|
||||||
static float GetCarToGoToCoors(CVehicle*, CVector*);
|
static void TellCarToRamOtherCar(CVehicle*, CVehicle*);
|
||||||
|
static void TellCarToBlockOtherCar(CVehicle*, CVehicle*);
|
||||||
|
static eCarMission FindPoliceCarMissionForWantedLevel();
|
||||||
|
static int32 FindPoliceCarSpeedForWantedLevel(CVehicle*);
|
||||||
|
static void MellowOutChaseSpeed(CVehicle*);
|
||||||
|
static void MakeWayForCarWithSiren(CVehicle *veh);
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,9 +31,6 @@
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
#include "Zones.h"
|
#include "Zones.h"
|
||||||
|
|
||||||
#define GAME_SPEED_TO_METERS_PER_SECOND 50.0f
|
|
||||||
#define GAME_SPEED_TO_CARAI_SPEED 60.0f
|
|
||||||
|
|
||||||
#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
|
||||||
|
@ -53,7 +50,6 @@
|
||||||
|
|
||||||
#define ATTEMPTS_TO_FIND_NEXT_NODE 15
|
#define ATTEMPTS_TO_FIND_NEXT_NODE 15
|
||||||
|
|
||||||
#define TIME_COPS_WAIT_TO_EXIT_AFTER_STOPPING 2500
|
|
||||||
#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
|
||||||
|
@ -428,7 +424,7 @@ CCarCtrl::GenerateOneRandomCar()
|
||||||
pCar->AutoPilot.m_nTimeEnteredCurve = CTimer::GetTimeInMilliseconds() -
|
pCar->AutoPilot.m_nTimeEnteredCurve = CTimer::GetTimeInMilliseconds() -
|
||||||
(uint32)((0.5f + positionBetweenNodes) * pCar->AutoPilot.m_nTimeToSpendOnCurrentCurve);
|
(uint32)((0.5f + positionBetweenNodes) * pCar->AutoPilot.m_nTimeToSpendOnCurrentCurve);
|
||||||
#else
|
#else
|
||||||
pCar->AutoPilot.m_nTotalSpeedScaleFactor = CTimer::GetTimeInMilliseconds() -
|
pCar->AutoPilot.m_nTimeEnteredCurve = CTimer::GetTimeInMilliseconds() -
|
||||||
(0.5f + positionBetweenNodes) * pCar->AutoPilot.m_nSpeedScaleFactor;
|
(0.5f + positionBetweenNodes) * pCar->AutoPilot.m_nSpeedScaleFactor;
|
||||||
#endif
|
#endif
|
||||||
CVector directionCurrentLink(directionCurrentLinkX, directionCurrentLinkY, 0.0f);
|
CVector directionCurrentLink(directionCurrentLinkX, directionCurrentLinkY, 0.0f);
|
||||||
|
@ -629,7 +625,7 @@ CCarCtrl::ChoosePoliceCarModel(void)
|
||||||
if (FindPlayerPed()->m_pWanted->AreArmyRequired() &&
|
if (FindPlayerPed()->m_pWanted->AreArmyRequired() &&
|
||||||
CStreaming::HasModelLoaded(MI_RHINO) &&
|
CStreaming::HasModelLoaded(MI_RHINO) &&
|
||||||
CStreaming::HasModelLoaded(MI_BARRACKS) &&
|
CStreaming::HasModelLoaded(MI_BARRACKS) &&
|
||||||
CStreaming::HasModelLoaded(MI_RHINO))
|
CStreaming::HasModelLoaded(MI_ARMY))
|
||||||
return CGeneral::GetRandomTrueFalse() ? MI_BARRACKS : MI_RHINO;
|
return CGeneral::GetRandomTrueFalse() ? MI_BARRACKS : MI_RHINO;
|
||||||
return MI_POLICE;
|
return MI_POLICE;
|
||||||
}
|
}
|
||||||
|
@ -1516,7 +1512,7 @@ void CCarCtrl::PickNextNodeRandomly(CVehicle* pVehicle)
|
||||||
if (pVehicle->AutoPilot.m_nNextRouteNode != prevNode) {
|
if (pVehicle->AutoPilot.m_nNextRouteNode != prevNode) {
|
||||||
pNextPathNode = &ThePaths.m_pathNodes[pVehicle->AutoPilot.m_nNextRouteNode];
|
pNextPathNode = &ThePaths.m_pathNodes[pVehicle->AutoPilot.m_nNextRouteNode];
|
||||||
if ((!pNextPathNode->bDisabled || pPrevPathNode->bDisabled) &&
|
if ((!pNextPathNode->bDisabled || pPrevPathNode->bDisabled) &&
|
||||||
(!pNextPathNode->bBetweenLevels || pNextPathNode->bBetweenLevels || !pVehicle->AutoPilot.m_bStayInCurrentLevel) &&
|
(!pNextPathNode->bBetweenLevels || pPrevPathNode->bBetweenLevels || !pVehicle->AutoPilot.m_bStayInCurrentLevel) &&
|
||||||
!goingAgainstOneWayRoad)
|
!goingAgainstOneWayRoad)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1536,7 +1532,7 @@ void CCarCtrl::PickNextNodeRandomly(CVehicle* pVehicle)
|
||||||
if (!goingAgainstOneWayRoad) {
|
if (!goingAgainstOneWayRoad) {
|
||||||
pNextPathNode = &ThePaths.m_pathNodes[pVehicle->AutoPilot.m_nNextRouteNode];
|
pNextPathNode = &ThePaths.m_pathNodes[pVehicle->AutoPilot.m_nNextRouteNode];
|
||||||
if ((!pNextPathNode->bDisabled || pPrevPathNode->bDisabled) &&
|
if ((!pNextPathNode->bDisabled || pPrevPathNode->bDisabled) &&
|
||||||
(!pNextPathNode->bBetweenLevels || pNextPathNode->bBetweenLevels || !pVehicle->AutoPilot.m_bStayInCurrentLevel))
|
(!pNextPathNode->bBetweenLevels || pPrevPathNode->bBetweenLevels || !pVehicle->AutoPilot.m_bStayInCurrentLevel))
|
||||||
/* Nice way to exit loop but this will fail because this is used for indexing! */
|
/* Nice way to exit loop but this will fail because this is used for indexing! */
|
||||||
nextLink = 1000;
|
nextLink = 1000;
|
||||||
}
|
}
|
||||||
|
@ -1559,7 +1555,7 @@ void CCarCtrl::PickNextNodeRandomly(CVehicle* pVehicle)
|
||||||
pVehicle->AutoPilot.m_nCurrentDirection = pVehicle->AutoPilot.m_nNextDirection;
|
pVehicle->AutoPilot.m_nCurrentDirection = pVehicle->AutoPilot.m_nNextDirection;
|
||||||
pVehicle->AutoPilot.m_nCurrentLane = pVehicle->AutoPilot.m_nNextLane;
|
pVehicle->AutoPilot.m_nCurrentLane = pVehicle->AutoPilot.m_nNextLane;
|
||||||
pVehicle->AutoPilot.m_nNextPathNodeInfo = ThePaths.m_carPathConnections[nextLink + pCurPathNode->firstLink];
|
pVehicle->AutoPilot.m_nNextPathNodeInfo = ThePaths.m_carPathConnections[nextLink + pCurPathNode->firstLink];
|
||||||
uint8 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->numLeftLanes;
|
||||||
|
@ -1729,7 +1725,7 @@ void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float t
|
||||||
pVehicle->AutoPilot.m_nCurrentDirection = pVehicle->AutoPilot.m_nNextDirection;
|
pVehicle->AutoPilot.m_nCurrentDirection = pVehicle->AutoPilot.m_nNextDirection;
|
||||||
pVehicle->AutoPilot.m_nCurrentLane = pVehicle->AutoPilot.m_nNextLane;
|
pVehicle->AutoPilot.m_nCurrentLane = pVehicle->AutoPilot.m_nNextLane;
|
||||||
pVehicle->AutoPilot.m_nNextPathNodeInfo = ThePaths.m_carPathConnections[nextLink + pCurNode->firstLink];
|
pVehicle->AutoPilot.m_nNextPathNodeInfo = ThePaths.m_carPathConnections[nextLink + pCurNode->firstLink];
|
||||||
uint8 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->numLeftLanes;
|
||||||
|
@ -1818,7 +1814,7 @@ bool CCarCtrl::PickNextNodeToFollowPath(CVehicle* pVehicle)
|
||||||
;
|
;
|
||||||
CCarPathLink* pNextLink = &ThePaths.m_carPathLinks[ThePaths.m_carPathConnections[nextLink + pCurNode->firstLink]];
|
CCarPathLink* pNextLink = &ThePaths.m_carPathLinks[ThePaths.m_carPathConnections[nextLink + pCurNode->firstLink]];
|
||||||
pVehicle->AutoPilot.m_nNextPathNodeInfo = ThePaths.m_carPathConnections[nextLink + pCurNode->firstLink];
|
pVehicle->AutoPilot.m_nNextPathNodeInfo = ThePaths.m_carPathConnections[nextLink + pCurNode->firstLink];
|
||||||
uint8 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->numLeftLanes;
|
||||||
|
@ -2103,10 +2099,8 @@ void CCarCtrl::SteerAICarWithPhysics_OnlyMission(CVehicle* pVehicle, float* pSwe
|
||||||
case MISSION_GOTOCOORDS_ACCURATE:
|
case MISSION_GOTOCOORDS_ACCURATE:
|
||||||
case MISSION_RAMCAR_FARAWAY:
|
case MISSION_RAMCAR_FARAWAY:
|
||||||
case MISSION_BLOCKCAR_FARAWAY:
|
case MISSION_BLOCKCAR_FARAWAY:
|
||||||
{
|
|
||||||
SteerAICarWithPhysicsFollowPath(pVehicle, pSwerve, pAccel, pBrake, pHandbrake);
|
SteerAICarWithPhysicsFollowPath(pVehicle, pSwerve, pAccel, pBrake, pHandbrake);
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
case MISSION_RAMPLAYER_CLOSE:
|
case MISSION_RAMPLAYER_CLOSE:
|
||||||
{
|
{
|
||||||
CVector2D targetPos = FindPlayerCoors();
|
CVector2D targetPos = FindPlayerCoors();
|
||||||
|
@ -2405,12 +2399,12 @@ void CCarCtrl::SteerAICarWithPhysicsTryingToBlockTarget_Stop(CVehicle* pVehicle,
|
||||||
#ifdef FIX_BUGS
|
#ifdef FIX_BUGS
|
||||||
pVehicle->m_nTimeBlocked += CTimer::GetTimeStepInMilliseconds();
|
pVehicle->m_nTimeBlocked += CTimer::GetTimeStepInMilliseconds();
|
||||||
#else
|
#else
|
||||||
pVehicle->m_nTimeBlocked += 16.66f * CTimer::GetTimeStep(); // very doubtful constant
|
pVehicle->m_nTimeBlocked += 1000.0f / 60.0f * CTimer::GetTimeStep(); // very doubtful constant
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
pVehicle->m_nTimeBlocked = 0;
|
pVehicle->m_nTimeBlocked = 0;
|
||||||
if ((FindPlayerVehicle() == nil || FindPlayerVehicle()->IsUpsideDown() ||
|
if (FindPlayerVehicle() == nil || FindPlayerVehicle()->IsUpsideDown() ||
|
||||||
FindPlayerVehicle()->GetMoveSpeed().Magnitude() < 0.05f) &&
|
FindPlayerVehicle()->GetMoveSpeed().Magnitude() < 0.05f &&
|
||||||
pVehicle->m_nTimeBlocked > TIME_COPS_WAIT_TO_EXIT_AFTER_STOPPING){
|
pVehicle->m_nTimeBlocked > TIME_COPS_WAIT_TO_EXIT_AFTER_STOPPING){
|
||||||
if (pVehicle->bIsLawEnforcer && distanceToTargetSqr < SQR(DISTANCE_TO_SWITCH_FROM_STOP_TO_BLOCK)){
|
if (pVehicle->bIsLawEnforcer && distanceToTargetSqr < SQR(DISTANCE_TO_SWITCH_FROM_STOP_TO_BLOCK)){
|
||||||
CCarAI::TellOccupantsToLeaveCar(pVehicle);
|
CCarAI::TellOccupantsToLeaveCar(pVehicle);
|
||||||
|
@ -2565,7 +2559,7 @@ void CCarCtrl::FindLinksToGoWithTheseNodes(CVehicle* pVehicle)
|
||||||
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++)
|
||||||
if (ThePaths.m_connections[nextLink + pCurNode->firstLink] != pVehicle->AutoPilot.m_nNextRouteNode)
|
if (ThePaths.m_connections[nextLink + pCurNode->firstLink] == pVehicle->AutoPilot.m_nNextRouteNode)
|
||||||
break;
|
break;
|
||||||
pVehicle->AutoPilot.m_nNextPathNodeInfo = ThePaths.m_carPathConnections[nextLink + pCurNode->firstLink];
|
pVehicle->AutoPilot.m_nNextPathNodeInfo = ThePaths.m_carPathConnections[nextLink + pCurNode->firstLink];
|
||||||
pVehicle->AutoPilot.m_nNextDirection = (pVehicle->AutoPilot.m_nCurrentRouteNode >= pVehicle->AutoPilot.m_nNextRouteNode) ? 1 : -1;
|
pVehicle->AutoPilot.m_nNextDirection = (pVehicle->AutoPilot.m_nCurrentRouteNode >= pVehicle->AutoPilot.m_nNextRouteNode) ? 1 : -1;
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
#include "Boat.h"
|
#include "Boat.h"
|
||||||
#include "Vehicle.h"
|
#include "Vehicle.h"
|
||||||
|
|
||||||
|
#define GAME_SPEED_TO_METERS_PER_SECOND 50.0f
|
||||||
|
#define GAME_SPEED_TO_CARAI_SPEED 60.0f
|
||||||
|
#define TIME_COPS_WAIT_TO_EXIT_AFTER_STOPPING 2500
|
||||||
|
|
||||||
class CZoneInfo;
|
class CZoneInfo;
|
||||||
|
|
||||||
enum{
|
enum{
|
||||||
|
|
|
@ -2,5 +2,38 @@
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
#include "Curves.h"
|
#include "Curves.h"
|
||||||
|
|
||||||
|
#if 0
|
||||||
WRAPPER float CCurves::CalcSpeedScaleFactor(CVector*, CVector*, float, float, float, float) { EAXJMP(0x420410); }
|
WRAPPER float CCurves::CalcSpeedScaleFactor(CVector*, CVector*, float, float, float, float) { EAXJMP(0x420410); }
|
||||||
|
#else
|
||||||
|
float CCurves::CalcSpeedScaleFactor(CVector* pPoint1, CVector* pPoint2, float dir1X, float dir1Y, float dir2X, float dir2Y)
|
||||||
|
{
|
||||||
|
CVector2D dir1(dir1X, dir1Y);
|
||||||
|
CVector2D dir2(dir2X, dir2Y);
|
||||||
|
float distance = (*pPoint1 - *pPoint2).Magnitude2D();
|
||||||
|
float dp = DotProduct2D(dir1, dir2);
|
||||||
|
if (dp > 0.9f)
|
||||||
|
return distance + Abs((pPoint1->x * dir1Y - pPoint1->y * dir1X) - (pPoint2->x * dir1Y - pPoint2->y * dir1X));
|
||||||
|
else
|
||||||
|
return ((1.0f - dp) * 0.2f + 1.0f) * distance;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
WRAPPER void CCurves::CalcCurvePoint(CVector*, CVector*, CVector*, CVector*, float, int32, CVector*, CVector*) { EAXJMP(0x4204D0); }
|
WRAPPER void CCurves::CalcCurvePoint(CVector*, CVector*, CVector*, CVector*, float, int32, CVector*, CVector*) { EAXJMP(0x4204D0); }
|
||||||
|
#else
|
||||||
|
void CCurves::CalcCurvePoint(CVector* pPos1, CVector* pPos2, CVector* pDir1, CVector* pDir2, float between, int32 timeOnCurve, CVector* pOutPos, CVector* pOutDir)
|
||||||
|
{
|
||||||
|
float actualFactor = CalcSpeedScaleFactor(pPos1, pPos2, pDir1->x, pDir1->y, pDir2->x, pDir2->y);
|
||||||
|
CVector2D dir1 = *pDir1 * actualFactor;
|
||||||
|
CVector2D dir2 = *pDir2 * actualFactor;
|
||||||
|
float curveCoef = 0.5f - 0.5f * cos(3.1415f * between);
|
||||||
|
*pOutPos = CVector(
|
||||||
|
(pPos1->x + between * dir1.x) * (1.0f - curveCoef) + (pPos2->x - (1 - between) * dir2.x) * curveCoef,
|
||||||
|
(pPos1->y + between * dir1.y) * (1.0f - curveCoef) + (pPos2->y - (1 - between) * dir2.y) * curveCoef,
|
||||||
|
0.0f);
|
||||||
|
*pOutDir = CVector(
|
||||||
|
(dir1.x * (1.0f - curveCoef) + dir2.x * curveCoef) / (timeOnCurve * 0.001f),
|
||||||
|
(dir1.y * (1.0f - curveCoef) + dir2.y * curveCoef) / (timeOnCurve * 0.001f),
|
||||||
|
0.0f);
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -2914,7 +2914,7 @@ CPed::QuitEnteringCar(void)
|
||||||
|
|
||||||
if (veh) {
|
if (veh) {
|
||||||
if (m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER || m_nPedState == PED_CARJACK)
|
if (m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER || m_nPedState == PED_CARJACK)
|
||||||
veh->m_veh_flagC10 = false;
|
veh->bIsBeingCarJacked = false;
|
||||||
|
|
||||||
if (veh->m_nNumGettingIn != 0)
|
if (veh->m_nNumGettingIn != 0)
|
||||||
veh->m_nNumGettingIn--;
|
veh->m_nNumGettingIn--;
|
||||||
|
@ -10517,7 +10517,7 @@ CPed::PedAnimDoorCloseCB(CAnimBlendAssociation *animAssoc, void *arg)
|
||||||
|| !veh->IsRoomForPedToLeaveCar(CAR_DOOR_LF, nil))))) {
|
|| !veh->IsRoomForPedToLeaveCar(CAR_DOOR_LF, nil))))) {
|
||||||
|
|
||||||
if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER)
|
if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER)
|
||||||
veh->m_veh_flagC10 = false;
|
veh->bIsBeingCarJacked = false;
|
||||||
|
|
||||||
ped->m_objective = OBJECTIVE_ENTER_CAR_AS_PASSENGER;
|
ped->m_objective = OBJECTIVE_ENTER_CAR_AS_PASSENGER;
|
||||||
PedSetInCarCB(nil, ped);
|
PedSetInCarCB(nil, ped);
|
||||||
|
@ -10881,7 +10881,7 @@ CPed::PedAnimGetInCB(CAnimBlendAssociation *animAssoc, void *arg)
|
||||||
veh->m_status = STATUS_PLAYER_DISABLED;
|
veh->m_status = STATUS_PLAYER_DISABLED;
|
||||||
}
|
}
|
||||||
driver->bBusJacked = true;
|
driver->bBusJacked = true;
|
||||||
veh->m_veh_flagC10 = false;
|
veh->bIsBeingCarJacked = false;
|
||||||
PedSetInCarCB(nil, ped);
|
PedSetInCarCB(nil, ped);
|
||||||
if (ped->m_nPedType == PEDTYPE_COP
|
if (ped->m_nPedType == PEDTYPE_COP
|
||||||
|| ped->m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT
|
|| ped->m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT
|
||||||
|
@ -11337,7 +11337,7 @@ CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER)
|
if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER)
|
||||||
veh->m_veh_flagC10 = false;
|
veh->bIsBeingCarJacked = false;
|
||||||
|
|
||||||
if (veh->m_nNumGettingIn)
|
if (veh->m_nNumGettingIn)
|
||||||
--veh->m_nNumGettingIn;
|
--veh->m_nNumGettingIn;
|
||||||
|
@ -12996,7 +12996,7 @@ CPed::ProcessObjective(void)
|
||||||
if (m_carInObjective->pDriver) {
|
if (m_carInObjective->pDriver) {
|
||||||
if (m_carInObjective->pDriver->m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS && m_carInObjective->pDriver != m_pedInObjective) {
|
if (m_carInObjective->pDriver->m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS && m_carInObjective->pDriver != m_pedInObjective) {
|
||||||
SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, m_carInObjective);
|
SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, m_carInObjective);
|
||||||
m_carInObjective->m_veh_flagC10 = false;
|
m_carInObjective->bIsBeingCarJacked = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13004,7 +13004,7 @@ CPed::ProcessObjective(void)
|
||||||
if (m_carInObjective->pDriver) {
|
if (m_carInObjective->pDriver) {
|
||||||
if (m_carInObjective->pDriver->m_nPedType == m_nPedType) {
|
if (m_carInObjective->pDriver->m_nPedType == m_nPedType) {
|
||||||
SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, m_carInObjective);
|
SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, m_carInObjective);
|
||||||
m_carInObjective->m_veh_flagC10 = false;
|
m_carInObjective->bIsBeingCarJacked = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14575,7 +14575,7 @@ CPed::SetEnterCar(CVehicle *car, uint32 unused)
|
||||||
}
|
}
|
||||||
if (!IsPedInControl() || m_fHealth <= 0.0f
|
if (!IsPedInControl() || m_fHealth <= 0.0f
|
||||||
|| doorFlag & car->m_nGettingInFlags || doorFlag & car->m_nGettingOutFlags
|
|| doorFlag & car->m_nGettingInFlags || doorFlag & car->m_nGettingOutFlags
|
||||||
|| car->m_veh_flagC10 || m_pVehicleAnim
|
|| car->bIsBeingCarJacked || m_pVehicleAnim
|
||||||
|| doorFlag && !car->IsDoorReady(door) && !car->IsDoorFullyOpen(door))
|
|| doorFlag && !car->IsDoorReady(door) && !car->IsDoorFullyOpen(door))
|
||||||
SetMoveState(PEDMOVE_STILL);
|
SetMoveState(PEDMOVE_STILL);
|
||||||
else
|
else
|
||||||
|
|
|
@ -68,15 +68,15 @@ CVehicle::CVehicle(uint8 CreatedBy)
|
||||||
bTakeLessDamage = false;
|
bTakeLessDamage = false;
|
||||||
bIsDamaged = false;
|
bIsDamaged = false;
|
||||||
bFadeOut = false;
|
bFadeOut = false;
|
||||||
m_veh_flagC10 = false;
|
bIsBeingCarJacked = false;
|
||||||
m_nTimeOfDeath = 0;
|
m_nTimeOfDeath = 0;
|
||||||
m_pCarFire = nil;
|
m_pCarFire = nil;
|
||||||
bHasBeenOwnedByPlayer = false;
|
bHasBeenOwnedByPlayer = false;
|
||||||
bCreateRoadBlockPeds = false;
|
bCreateRoadBlockPeds = false;
|
||||||
bCanBeDamaged = true;
|
bCanBeDamaged = true;
|
||||||
bUsingSpecialColModel = false;
|
bUsingSpecialColModel = false;
|
||||||
m_veh_flagD1 = false;
|
bOccupantsHaveBeenGenerated = false;
|
||||||
m_veh_flagD2 = false;
|
bGunSwitchedOff = false;
|
||||||
m_nGunFiringTime = 0;
|
m_nGunFiringTime = 0;
|
||||||
m_nTimeBlocked = 0;
|
m_nTimeBlocked = 0;
|
||||||
bLightsOn = false;
|
bLightsOn = false;
|
||||||
|
@ -105,7 +105,7 @@ CVehicle::CVehicle(uint8 CreatedBy)
|
||||||
AutoPilot.m_nTempAction = TEMPACT_NONE;
|
AutoPilot.m_nTempAction = TEMPACT_NONE;
|
||||||
AutoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds();
|
AutoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds();
|
||||||
AutoPilot.m_bStayInCurrentLevel = false;
|
AutoPilot.m_bStayInCurrentLevel = false;
|
||||||
AutoPilot.m_flag10 = false;
|
AutoPilot.m_bIgnorePathfinding = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CVehicle::~CVehicle()
|
CVehicle::~CVehicle()
|
||||||
|
|
|
@ -158,19 +158,16 @@ public:
|
||||||
uint8 bIsDamaged : 1; // This vehicle has been damaged and is displaying all its components
|
uint8 bIsDamaged : 1; // This vehicle has been damaged and is displaying all its components
|
||||||
uint8 bHasBeenOwnedByPlayer : 1;// To work out whether stealing it is a crime
|
uint8 bHasBeenOwnedByPlayer : 1;// To work out whether stealing it is a crime
|
||||||
uint8 bFadeOut : 1; // Fade vehicle out
|
uint8 bFadeOut : 1; // Fade vehicle out
|
||||||
uint8 m_veh_flagC10 : 1;
|
uint8 bIsBeingCarJacked : 1; // Fade vehicle out
|
||||||
uint8 bCreateRoadBlockPeds : 1; // If this vehicle gets close enough we will create peds (coppers or gang members) round it
|
uint8 bCreateRoadBlockPeds : 1; // If this vehicle gets close enough we will create peds (coppers or gang members) round it
|
||||||
uint8 bCanBeDamaged : 1; // Set to FALSE during cut scenes to avoid explosions
|
uint8 bCanBeDamaged : 1; // Set to FALSE during cut scenes to avoid explosions
|
||||||
uint8 bUsingSpecialColModel : 1;// Is player vehicle using special collision model, stored in player strucure
|
uint8 bUsingSpecialColModel : 1;// Is player vehicle using special collision model, stored in player strucure
|
||||||
|
|
||||||
uint8 m_veh_flagD1 : 1;
|
uint8 bOccupantsHaveBeenGenerated : 1; // Is true if the occupants have already been generated. (Shouldn't happen again)
|
||||||
uint8 m_veh_flagD2 : 1;
|
uint8 bGunSwitchedOff : 1; // Level designers can use this to switch off guns on boats
|
||||||
uint8 bVehicleColProcessed : 1;// Has ProcessEntityCollision been processed for this car?
|
uint8 bVehicleColProcessed : 1;// Has ProcessEntityCollision been processed for this car?
|
||||||
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 m_veh_flagD20 : 1;
|
|
||||||
uint8 m_veh_flagD40 : 1;
|
|
||||||
uint8 m_veh_flagD80 : 1;
|
|
||||||
|
|
||||||
int8 m_numPedsUseItAsCover;
|
int8 m_numPedsUseItAsCover;
|
||||||
uint8 m_nAmmoInClip; // Used to make the guns on boat do a reload (20 by default)
|
uint8 m_nAmmoInClip; // Used to make the guns on boat do a reload (20 by default)
|
||||||
|
|
Loading…
Reference in a new issue