ccarctrl
This commit is contained in:
parent
c86c9b3118
commit
05b01c5ff5
@ -2,4 +2,5 @@
|
|||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
#include "AutoPilot.h"
|
#include "AutoPilot.h"
|
||||||
|
|
||||||
|
WRAPPER void CAutoPilot::RemoveOnePathNode() { EAXJMP(0x413A00); }
|
||||||
WRAPPER void CAutoPilot::ModifySpeed(float) { EAXJMP(0x4137B0); }
|
WRAPPER void CAutoPilot::ModifySpeed(float) { EAXJMP(0x4137B0); }
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
|
|
||||||
class CVehicle;
|
class CVehicle;
|
||||||
|
struct CPathNode;
|
||||||
|
|
||||||
enum eCarMission : uint8
|
enum eCarMission : uint8
|
||||||
{
|
{
|
||||||
@ -87,8 +88,8 @@ public:
|
|||||||
uint8 m_bStayInFastLane : 1;
|
uint8 m_bStayInFastLane : 1;
|
||||||
uint8 m_flag10 : 1;
|
uint8 m_flag10 : 1;
|
||||||
CVector m_vecDestinationCoors;
|
CVector m_vecDestinationCoors;
|
||||||
void *m_aPathFindNodesInfo[8];
|
CPathNode *m_aPathFindNodesInfo[NUM_PATH_NODES_IN_AUTOPILOT];
|
||||||
uint16 m_nPathFindNodesCount;
|
int16 m_nPathFindNodesCount;
|
||||||
CVehicle *m_pTargetCar;
|
CVehicle *m_pTargetCar;
|
||||||
|
|
||||||
CAutoPilot(void) {
|
CAutoPilot(void) {
|
||||||
@ -118,5 +119,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ModifySpeed(float);
|
void ModifySpeed(float);
|
||||||
|
void RemoveOnePathNode();
|
||||||
};
|
};
|
||||||
static_assert(sizeof(CAutoPilot) == 0x70, "CAutoPilot: error");
|
static_assert(sizeof(CAutoPilot) == 0x70, "CAutoPilot: error");
|
||||||
|
@ -75,7 +75,6 @@ WRAPPER void CCarCtrl::RemoveFromInterestingVehicleList(CVehicle* v) { EAXJMP(0x
|
|||||||
WRAPPER void CCarCtrl::GenerateEmergencyServicesCar(void) { EAXJMP(0x41FC50); }
|
WRAPPER void CCarCtrl::GenerateEmergencyServicesCar(void) { EAXJMP(0x41FC50); }
|
||||||
WRAPPER void CCarCtrl::DragCarToPoint(CVehicle*, CVector*) { EAXJMP(0x41D450); }
|
WRAPPER void CCarCtrl::DragCarToPoint(CVehicle*, CVector*) { EAXJMP(0x41D450); }
|
||||||
WRAPPER void CCarCtrl::Init(void) { EAXJMP(0x41D280); }
|
WRAPPER void CCarCtrl::Init(void) { EAXJMP(0x41D280); }
|
||||||
WRAPPER bool CCarCtrl::PickNextNodeToFollowPath(CVehicle*) { EAXJMP(0x41CD50); }
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CCarCtrl::GenerateRandomCars()
|
CCarCtrl::GenerateRandomCars()
|
||||||
@ -1648,7 +1647,7 @@ void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float t
|
|||||||
CPathNode* pTargetNode;
|
CPathNode* pTargetNode;
|
||||||
int16 numNodes;
|
int16 numNodes;
|
||||||
float distanceToTargetNode;
|
float distanceToTargetNode;
|
||||||
#ifdef USE_TREADABLE_PATHFIND
|
#ifndef REMOVE_TREADABLE_PATHFIND
|
||||||
if (pTarget && pTarget->m_pCurGroundEntity->m_type == ENTITY_TYPE_BUILDING &&
|
if (pTarget && pTarget->m_pCurGroundEntity->m_type == ENTITY_TYPE_BUILDING &&
|
||||||
((CBuilding*)pTarget->m_pCurGroundEntity)->GetIsATreadable() &&
|
((CBuilding*)pTarget->m_pCurGroundEntity)->GetIsATreadable() &&
|
||||||
((CTreadable*)pTarget->m_pCurGroundEntity)->m_nodeIndices[0][0] >= 0){
|
((CTreadable*)pTarget->m_pCurGroundEntity)->m_nodeIndices[0][0] >= 0){
|
||||||
@ -1681,7 +1680,7 @@ void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float t
|
|||||||
CVector(targetX, targetY, 0.0f),
|
CVector(targetX, targetY, 0.0f),
|
||||||
#endif
|
#endif
|
||||||
&pTargetNode, &numNodes, 1, pVehicle, &distanceToTargetNode, 999999.9f, -1);
|
&pTargetNode, &numNodes, 1, pVehicle, &distanceToTargetNode, 999999.9f, -1);
|
||||||
#ifdef USE_TREADABLE_PATHFIND
|
#ifndef REMOVE_TREADABLE_PATHFIND
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
int newNextNode;
|
int newNextNode;
|
||||||
@ -1691,6 +1690,7 @@ void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float t
|
|||||||
nextLink = 0;
|
nextLink = 0;
|
||||||
float lowestAngleChange = 10.0f;
|
float lowestAngleChange = 10.0f;
|
||||||
int numLinks = pCurNode->numLinks;
|
int numLinks = pCurNode->numLinks;
|
||||||
|
newNextNode = 0;
|
||||||
for (int i = 0; i < numLinks; i++){
|
for (int i = 0; i < numLinks; i++){
|
||||||
int conNode = ThePaths.m_connections[i + pCurNode->firstLink];
|
int conNode = ThePaths.m_connections[i + pCurNode->firstLink];
|
||||||
if (conNode == prevNode && i > 1)
|
if (conNode == prevNode && i > 1)
|
||||||
@ -1707,8 +1707,8 @@ void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float t
|
|||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
nextLink = 0;
|
nextLink = 0;
|
||||||
int idOfTargetNode = pTargetNode - ThePaths.m_pathNodes;
|
newNextNode = pTargetNode - ThePaths.m_pathNodes;
|
||||||
for (int i = pCurNode->firstLink; ThePaths.m_connections[i] != idOfTargetNode; i++, nextLink++)
|
for (int i = pCurNode->firstLink; ThePaths.m_connections[i] != newNextNode; i++, nextLink++)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
CPathNode* pNextPathNode = &ThePaths.m_pathNodes[pVehicle->AutoPilot.m_nNextRouteNode];
|
CPathNode* pNextPathNode = &ThePaths.m_pathNodes[pVehicle->AutoPilot.m_nNextRouteNode];
|
||||||
@ -1716,6 +1716,7 @@ void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float t
|
|||||||
CCarPathLink* pCurLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo];
|
CCarPathLink* pCurLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo];
|
||||||
pVehicle->AutoPilot.m_nPrevRouteNode = pVehicle->AutoPilot.m_nCurrentRouteNode;
|
pVehicle->AutoPilot.m_nPrevRouteNode = pVehicle->AutoPilot.m_nCurrentRouteNode;
|
||||||
pVehicle->AutoPilot.m_nCurrentRouteNode = pVehicle->AutoPilot.m_nNextRouteNode;
|
pVehicle->AutoPilot.m_nCurrentRouteNode = pVehicle->AutoPilot.m_nNextRouteNode;
|
||||||
|
pVehicle->AutoPilot.m_nNextRouteNode = newNextNode;
|
||||||
pVehicle->AutoPilot.m_nTimeEnteredCurve += pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve;
|
pVehicle->AutoPilot.m_nTimeEnteredCurve += pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve;
|
||||||
pVehicle->AutoPilot.m_nPreviousPathNodeInfo = pVehicle->AutoPilot.m_nCurrentPathNodeInfo;
|
pVehicle->AutoPilot.m_nPreviousPathNodeInfo = pVehicle->AutoPilot.m_nCurrentPathNodeInfo;
|
||||||
pVehicle->AutoPilot.m_nCurrentPathNodeInfo = pVehicle->AutoPilot.m_nNextPathNodeInfo;
|
pVehicle->AutoPilot.m_nCurrentPathNodeInfo = pVehicle->AutoPilot.m_nNextPathNodeInfo;
|
||||||
@ -1783,6 +1784,90 @@ void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float t
|
|||||||
pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve = max(10, pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve);
|
pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve = max(10, pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CCarCtrl::PickNextNodeToFollowPath(CVehicle* pVehicle)
|
||||||
|
{
|
||||||
|
int curNode = pVehicle->AutoPilot.m_nNextRouteNode;
|
||||||
|
CPathNode* pCurNode = &ThePaths.m_pathNodes[curNode];
|
||||||
|
CPathNode* pTargetNode;
|
||||||
|
int16 numNodes;
|
||||||
|
float distanceToTargetNode;
|
||||||
|
if (pVehicle->AutoPilot.m_nPathFindNodesCount == 0){
|
||||||
|
ThePaths.DoPathSearch(0, pVehicle->GetPosition(), curNode,
|
||||||
|
pVehicle->AutoPilot.m_vecDestinationCoors, pVehicle->AutoPilot.m_aPathFindNodesInfo,
|
||||||
|
&pVehicle->AutoPilot.m_nPathFindNodesCount, NUM_PATH_NODES_IN_AUTOPILOT,
|
||||||
|
pVehicle, nil, 999999.9f, -1);
|
||||||
|
if (pVehicle->AutoPilot.m_nPathFindNodesCount < 1)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
CPathNode* pNextPathNode = &ThePaths.m_pathNodes[pVehicle->AutoPilot.m_nNextRouteNode];
|
||||||
|
CCarPathLink* pCurLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo];
|
||||||
|
pVehicle->AutoPilot.m_nPrevRouteNode = pVehicle->AutoPilot.m_nCurrentRouteNode;
|
||||||
|
pVehicle->AutoPilot.m_nCurrentRouteNode = pVehicle->AutoPilot.m_nNextRouteNode;
|
||||||
|
pVehicle->AutoPilot.m_nNextRouteNode = pVehicle->AutoPilot.m_aPathFindNodesInfo[0] - ThePaths.m_pathNodes;
|
||||||
|
pVehicle->AutoPilot.RemoveOnePathNode();
|
||||||
|
pVehicle->AutoPilot.m_nTimeEnteredCurve += pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve;
|
||||||
|
pVehicle->AutoPilot.m_nPreviousPathNodeInfo = pVehicle->AutoPilot.m_nCurrentPathNodeInfo;
|
||||||
|
pVehicle->AutoPilot.m_nCurrentPathNodeInfo = pVehicle->AutoPilot.m_nNextPathNodeInfo;
|
||||||
|
pVehicle->AutoPilot.m_nPreviousDirection = pVehicle->AutoPilot.m_nCurrentDirection;
|
||||||
|
pVehicle->AutoPilot.m_nCurrentDirection = pVehicle->AutoPilot.m_nNextDirection;
|
||||||
|
pVehicle->AutoPilot.m_nCurrentLane = pVehicle->AutoPilot.m_nNextLane;
|
||||||
|
int nextLink = 0;
|
||||||
|
for (int i = pCurNode->firstLink; ThePaths.m_connections[i] != pVehicle->AutoPilot.m_nNextRouteNode; i++, nextLink++)
|
||||||
|
;
|
||||||
|
CCarPathLink* pNextLink = &ThePaths.m_carPathLinks[ThePaths.m_carPathConnections[nextLink + pCurNode->firstLink]];
|
||||||
|
pVehicle->AutoPilot.m_nNextPathNodeInfo = ThePaths.m_carPathConnections[nextLink + pCurNode->firstLink];
|
||||||
|
uint8 lanesOnNextNode;
|
||||||
|
if (curNode >= pVehicle->AutoPilot.m_nNextRouteNode) {
|
||||||
|
pVehicle->AutoPilot.m_nNextDirection = 1;
|
||||||
|
lanesOnNextNode = pNextLink->numLeftLanes;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pVehicle->AutoPilot.m_nNextDirection = -1;
|
||||||
|
lanesOnNextNode = pNextLink->numRightLanes;
|
||||||
|
}
|
||||||
|
float currentPathLinkForwardX = pVehicle->AutoPilot.m_nCurrentDirection * pCurLink->dirX;
|
||||||
|
float currentPathLinkForwardY = pVehicle->AutoPilot.m_nCurrentDirection * pCurLink->dirY;
|
||||||
|
float nextPathLinkForwardX = pVehicle->AutoPilot.m_nNextDirection * pNextLink->dirX;
|
||||||
|
float nextPathLinkForwardY = pVehicle->AutoPilot.m_nNextDirection * pNextLink->dirY;
|
||||||
|
if (lanesOnNextNode >= 0) {
|
||||||
|
CVector2D dist = pNextPathNode->pos - pCurNode->pos;
|
||||||
|
if (dist.MagnitudeSqr() >= SQR(7.0f) && (CGeneral::GetRandomNumber() & 0x600) == 0) {
|
||||||
|
if (CGeneral::GetRandomTrueFalse())
|
||||||
|
pVehicle->AutoPilot.m_nNextLane += 1;
|
||||||
|
else
|
||||||
|
pVehicle->AutoPilot.m_nNextLane -= 1;
|
||||||
|
}
|
||||||
|
pVehicle->AutoPilot.m_nNextLane = min(lanesOnNextNode - 1, pVehicle->AutoPilot.m_nNextLane);
|
||||||
|
pVehicle->AutoPilot.m_nNextLane = max(0, pVehicle->AutoPilot.m_nNextLane);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pVehicle->AutoPilot.m_nNextLane = pVehicle->AutoPilot.m_nCurrentLane;
|
||||||
|
}
|
||||||
|
if (pVehicle->AutoPilot.m_bStayInFastLane)
|
||||||
|
pVehicle->AutoPilot.m_nNextLane = 0;
|
||||||
|
CVector positionOnCurrentLinkIncludingLane(
|
||||||
|
pCurLink->posX + GetOffsetOfLaneFromCenterOfRoad(pVehicle->AutoPilot.m_nCurrentLane, pCurLink) * currentPathLinkForwardY,
|
||||||
|
pCurLink->posY - GetOffsetOfLaneFromCenterOfRoad(pVehicle->AutoPilot.m_nCurrentLane, pCurLink) * currentPathLinkForwardX,
|
||||||
|
0.0f);
|
||||||
|
CVector positionOnNextLinkIncludingLane(
|
||||||
|
pNextLink->posX + GetOffsetOfLaneFromCenterOfRoad(pVehicle->AutoPilot.m_nNextLane, pNextLink) * nextPathLinkForwardY,
|
||||||
|
pNextLink->posY - GetOffsetOfLaneFromCenterOfRoad(pVehicle->AutoPilot.m_nNextLane, pNextLink) * nextPathLinkForwardX,
|
||||||
|
0.0f);
|
||||||
|
float directionCurrentLinkX = pCurLink->dirX * pVehicle->AutoPilot.m_nCurrentDirection;
|
||||||
|
float directionCurrentLinkY = pCurLink->dirY * pVehicle->AutoPilot.m_nCurrentDirection;
|
||||||
|
float directionNextLinkX = pNextLink->dirX * pVehicle->AutoPilot.m_nNextDirection;
|
||||||
|
float directionNextLinkY = pNextLink->dirY * pVehicle->AutoPilot.m_nNextDirection;
|
||||||
|
/* We want to make a path between two links that may not have the same forward directions a curve. */
|
||||||
|
pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve = CCurves::CalcSpeedScaleFactor(
|
||||||
|
&positionOnCurrentLinkIncludingLane,
|
||||||
|
&positionOnNextLinkIncludingLane,
|
||||||
|
directionCurrentLinkX, directionCurrentLinkY,
|
||||||
|
directionNextLinkX, directionNextLinkY
|
||||||
|
) * (1000.0f / pVehicle->AutoPilot.m_fMaxTrafficSpeed);
|
||||||
|
pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve = max(10, pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CCarCtrl::MapCouldMoveInThisArea(float x, float y)
|
CCarCtrl::MapCouldMoveInThisArea(float x, float y)
|
||||||
{
|
{
|
||||||
|
@ -15,8 +15,6 @@ enum{
|
|||||||
#define FIX_PATHFIND_BUG
|
#define FIX_PATHFIND_BUG
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define USE_TREADABLE_PATHFIND
|
|
||||||
|
|
||||||
class CCarCtrl
|
class CCarCtrl
|
||||||
{
|
{
|
||||||
enum eCarClass {
|
enum eCarClass {
|
||||||
|
@ -71,7 +71,9 @@ enum Config {
|
|||||||
NUMPICKUPS = 336,
|
NUMPICKUPS = 336,
|
||||||
NUMEVENTS = 64,
|
NUMEVENTS = 64,
|
||||||
|
|
||||||
NUM_CARGENS = 160
|
NUM_CARGENS = 160,
|
||||||
|
|
||||||
|
NUM_PATH_NODES_IN_AUTOPILOT = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
// We'll use this once we're ready to become independent of the game
|
// We'll use this once we're ready to become independent of the game
|
||||||
@ -132,3 +134,4 @@ enum Config {
|
|||||||
#define EXPLODING_AIRTRAIN // can blow up jumbo jet with rocket launcher
|
#define EXPLODING_AIRTRAIN // can blow up jumbo jet with rocket launcher
|
||||||
#define ANIMATE_PED_COL_MODEL
|
#define ANIMATE_PED_COL_MODEL
|
||||||
#define CANCELLABLE_CAR_ENTER
|
#define CANCELLABLE_CAR_ENTER
|
||||||
|
//#define REMOVE_TREADABLE_PATHFIND
|
||||||
|
@ -434,8 +434,9 @@ CVehicle::UsesSiren(uint32 id)
|
|||||||
bool
|
bool
|
||||||
CVehicle::IsVehicleNormal(void)
|
CVehicle::IsVehicleNormal(void)
|
||||||
{
|
{
|
||||||
if(pDriver && m_nNumPassengers == 0 && m_status != STATUS_WRECKED){
|
if (!pDriver || m_nNumPassengers != 0 || m_status == STATUS_WRECKED)
|
||||||
switch(GetModelIndex())
|
return false;
|
||||||
|
switch (GetModelIndex()){
|
||||||
case MI_FIRETRUCK:
|
case MI_FIRETRUCK:
|
||||||
case MI_AMBULAN:
|
case MI_AMBULAN:
|
||||||
case MI_TAXI:
|
case MI_TAXI:
|
||||||
@ -450,8 +451,9 @@ CVehicle::IsVehicleNormal(void)
|
|||||||
case MI_RCBANDIT:
|
case MI_RCBANDIT:
|
||||||
case MI_BORGNINE:
|
case MI_BORGNINE:
|
||||||
return false;
|
return false;
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
Loading…
Reference in New Issue
Block a user