summaryrefslogtreecommitdiffstats
path: root/src/control
diff options
context:
space:
mode:
authoraap <aap@papnet.eu>2020-04-10 18:36:39 +0200
committeraap <aap@papnet.eu>2020-04-10 18:36:39 +0200
commitc5d61392ead394a3d6a1e2832c7d9f0ccf951ad3 (patch)
treedd8186d8f12e842649ba233274ad1916ed5b1343 /src/control
parentdisabling the code that freezes gang members (diff)
downloadre3-c5d61392ead394a3d6a1e2832c7d9f0ccf951ad3.tar
re3-c5d61392ead394a3d6a1e2832c7d9f0ccf951ad3.tar.gz
re3-c5d61392ead394a3d6a1e2832c7d9f0ccf951ad3.tar.bz2
re3-c5d61392ead394a3d6a1e2832c7d9f0ccf951ad3.tar.lz
re3-c5d61392ead394a3d6a1e2832c7d9f0ccf951ad3.tar.xz
re3-c5d61392ead394a3d6a1e2832c7d9f0ccf951ad3.tar.zst
re3-c5d61392ead394a3d6a1e2832c7d9f0ccf951ad3.zip
Diffstat (limited to 'src/control')
-rw-r--r--src/control/AutoPilot.cpp16
-rw-r--r--src/control/CarCtrl.cpp144
-rw-r--r--src/control/PathFind.cpp167
-rw-r--r--src/control/PathFind.h12
-rw-r--r--src/control/TrafficLights.cpp334
-rw-r--r--src/control/TrafficLights.h7
6 files changed, 567 insertions, 113 deletions
diff --git a/src/control/AutoPilot.cpp b/src/control/AutoPilot.cpp
index 70099291..b5bca21d 100644
--- a/src/control/AutoPilot.cpp
+++ b/src/control/AutoPilot.cpp
@@ -12,17 +12,17 @@ void CAutoPilot::ModifySpeed(float 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;
+ float currentPathLinkForwardX = m_nCurrentDirection * ThePaths.m_carPathLinks[m_nCurrentPathNodeInfo].dir.x;
+ float currentPathLinkForwardY = m_nCurrentDirection * ThePaths.m_carPathLinks[m_nCurrentPathNodeInfo].dir.y;
+ float nextPathLinkForwardX = m_nNextDirection * ThePaths.m_carPathLinks[m_nNextPathNodeInfo].dir.x;
+ float nextPathLinkForwardY = m_nNextDirection * ThePaths.m_carPathLinks[m_nNextPathNodeInfo].dir.y;
CVector positionOnCurrentLinkIncludingLane(
- pCurrentLink->posX + ((m_nCurrentLane + 0.5f) * LANE_WIDTH) * currentPathLinkForwardY,
- pCurrentLink->posY - ((m_nCurrentLane + 0.5f) * LANE_WIDTH) * currentPathLinkForwardX,
+ pCurrentLink->pos.x + ((m_nCurrentLane + 0.5f) * LANE_WIDTH) * currentPathLinkForwardY,
+ pCurrentLink->pos.y - ((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,
+ pNextLink->pos.x + ((m_nNextLane + 0.5f) * LANE_WIDTH) * nextPathLinkForwardY,
+ pNextLink->pos.y - ((m_nNextLane + 0.5f) * LANE_WIDTH) * nextPathLinkForwardX,
0.0f);
m_nTimeToSpendOnCurrentCurve = CCurves::CalcSpeedScaleFactor(
&positionOnCurrentLinkIncludingLane,
diff --git a/src/control/CarCtrl.cpp b/src/control/CarCtrl.cpp
index cdcfbba6..264f1f3f 100644
--- a/src/control/CarCtrl.cpp
+++ b/src/control/CarCtrl.cpp
@@ -393,25 +393,25 @@ CCarCtrl::GenerateOneRandomCar()
pCar->GetRight() = CVector(forwardY, -forwardX, 0.0f);
pCar->GetUp() = CVector(0.0f, 0.0f, 1.0f);
- float currentPathLinkForwardX = pCar->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pCar->AutoPilot.m_nCurrentPathNodeInfo].dirX;
- float currentPathLinkForwardY = pCar->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pCar->AutoPilot.m_nCurrentPathNodeInfo].dirY;
- float nextPathLinkForwardX = pCar->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pCar->AutoPilot.m_nNextPathNodeInfo].dirX;
- float nextPathLinkForwardY = pCar->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pCar->AutoPilot.m_nNextPathNodeInfo].dirY;
+ float currentPathLinkForwardX = pCar->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pCar->AutoPilot.m_nCurrentPathNodeInfo].dir.x;
+ float currentPathLinkForwardY = pCar->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pCar->AutoPilot.m_nCurrentPathNodeInfo].dir.y;
+ float nextPathLinkForwardX = pCar->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pCar->AutoPilot.m_nNextPathNodeInfo].dir.x;
+ float nextPathLinkForwardY = pCar->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pCar->AutoPilot.m_nNextPathNodeInfo].dir.y;
CCarPathLink* pCurrentLink = &ThePaths.m_carPathLinks[pCar->AutoPilot.m_nCurrentPathNodeInfo];
CCarPathLink* pNextLink = &ThePaths.m_carPathLinks[pCar->AutoPilot.m_nNextPathNodeInfo];
CVector positionOnCurrentLinkIncludingLane(
- pCurrentLink->posX + ((pCar->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardY,
- pCurrentLink->posY - ((pCar->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardX,
+ pCurrentLink->pos.x + ((pCar->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardY,
+ pCurrentLink->pos.y - ((pCar->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardX,
0.0f);
CVector positionOnNextLinkIncludingLane(
- pNextLink->posX + ((pCar->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardY,
- pNextLink->posY - ((pCar->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardX,
+ pNextLink->pos.x + ((pCar->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardY,
+ pNextLink->pos.y - ((pCar->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardX,
0.0f);
- float directionCurrentLinkX = pCurrentLink->dirX * pCar->AutoPilot.m_nCurrentDirection;
- float directionCurrentLinkY = pCurrentLink->dirY * pCar->AutoPilot.m_nCurrentDirection;
- float directionNextLinkX = pNextLink->dirX * pCar->AutoPilot.m_nNextDirection;
- float directionNextLinkY = pNextLink->dirY * pCar->AutoPilot.m_nNextDirection;
+ float directionCurrentLinkX = pCurrentLink->dir.x * pCar->AutoPilot.m_nCurrentDirection;
+ float directionCurrentLinkY = pCurrentLink->dir.y * pCar->AutoPilot.m_nCurrentDirection;
+ float directionNextLinkX = pNextLink->dir.x * pCar->AutoPilot.m_nNextDirection;
+ float directionNextLinkY = pNextLink->dir.y * pCar->AutoPilot.m_nNextDirection;
/* We want to make a path between two links that may not have the same forward directions a curve. */
pCar->AutoPilot.m_nTimeToSpendOnCurrentCurve = CCurves::CalcSpeedScaleFactor(
&positionOnCurrentLinkIncludingLane,
@@ -763,17 +763,17 @@ CCarCtrl::UpdateCarOnRails(CVehicle* pVehicle)
return;
CCarPathLink* pCurrentLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo];
CCarPathLink* pNextLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo];
- float currentPathLinkForwardX = pCurrentLink->dirX * pVehicle->AutoPilot.m_nCurrentDirection;
- float currentPathLinkForwardY = pCurrentLink->dirY * pVehicle->AutoPilot.m_nCurrentDirection;
- float nextPathLinkForwardX = pNextLink->dirX * pVehicle->AutoPilot.m_nNextDirection;
- float nextPathLinkForwardY = pNextLink->dirY * pVehicle->AutoPilot.m_nNextDirection;
+ float currentPathLinkForwardX = pCurrentLink->dir.x * pVehicle->AutoPilot.m_nCurrentDirection;
+ float currentPathLinkForwardY = pCurrentLink->dir.y * pVehicle->AutoPilot.m_nCurrentDirection;
+ float nextPathLinkForwardX = pNextLink->dir.x * pVehicle->AutoPilot.m_nNextDirection;
+ float nextPathLinkForwardY = pNextLink->dir.y * pVehicle->AutoPilot.m_nNextDirection;
CVector positionOnCurrentLinkIncludingLane(
- pCurrentLink->posX + ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardY,
- pCurrentLink->posY - ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardX,
+ pCurrentLink->pos.x + ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardY,
+ pCurrentLink->pos.y - ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardX,
0.0f);
CVector positionOnNextLinkIncludingLane(
- pNextLink->posX + ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardY,
- pNextLink->posY - ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardX,
+ pNextLink->pos.x + ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardY,
+ pNextLink->pos.y - ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardX,
0.0f);
CVector directionCurrentLink(currentPathLinkForwardX, currentPathLinkForwardY, 0.0f);
CVector directionNextLink(nextPathLinkForwardX, nextPathLinkForwardY, 0.0f);
@@ -1553,8 +1553,8 @@ void CCarCtrl::PickNextNodeRandomly(CVehicle* pVehicle)
pVehicle->AutoPilot.m_nNextDirection = -1;
lanesOnNextNode = pNextLink->numRightLanes;
}
- float currentPathLinkForwardX = pVehicle->AutoPilot.m_nCurrentDirection * pCurLink->dirX;
- float nextPathLinkForwardX = pVehicle->AutoPilot.m_nNextDirection * pNextLink->dirX;
+ float currentPathLinkForwardX = pVehicle->AutoPilot.m_nCurrentDirection * pCurLink->dir.x;
+ float nextPathLinkForwardX = pVehicle->AutoPilot.m_nNextDirection * pNextLink->dir.x;
if (lanesOnNextNode >= 0){
if ((CGeneral::GetRandomNumber() & 0x600) == 0){
/* 25% chance vehicle will try to switch lane */
@@ -1574,17 +1574,17 @@ void CCarCtrl::PickNextNodeRandomly(CVehicle* pVehicle)
if (pVehicle->AutoPilot.m_bStayInFastLane)
pVehicle->AutoPilot.m_nNextLane = 0;
CVector positionOnCurrentLinkIncludingLane(
- pCurLink->posX + ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH), /* ...what about Y? */
- pCurLink->posY - ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardX,
+ pCurLink->pos.x + ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH), /* ...what about Y? */
+ pCurLink->pos.y - ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardX,
0.0f);
CVector positionOnNextLinkIncludingLane(
- pNextLink->posX + ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH),
- pNextLink->posY - ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardX,
+ pNextLink->pos.x + ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH),
+ pNextLink->pos.y - ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * 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;
+ float directionCurrentLinkX = pCurLink->dir.x * pVehicle->AutoPilot.m_nCurrentDirection;
+ float directionCurrentLinkY = pCurLink->dir.y * pVehicle->AutoPilot.m_nCurrentDirection;
+ float directionNextLinkX = pNextLink->dir.x * pVehicle->AutoPilot.m_nNextDirection;
+ float directionNextLinkY = pNextLink->dir.y * 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,
@@ -1725,10 +1725,10 @@ void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float t
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;
+ float currentPathLinkForwardX = pVehicle->AutoPilot.m_nCurrentDirection * pCurLink->dir.x;
+ float currentPathLinkForwardY = pVehicle->AutoPilot.m_nCurrentDirection * pCurLink->dir.y;
+ float nextPathLinkForwardX = pVehicle->AutoPilot.m_nNextDirection * pNextLink->dir.x;
+ float nextPathLinkForwardY = pVehicle->AutoPilot.m_nNextDirection * pNextLink->dir.y;
if (lanesOnNextNode >= 0) {
CVector2D dist = pNextPathNode->pos - pCurNode->pos;
if (dist.MagnitudeSqr() >= SQR(7.0f)){
@@ -1755,17 +1755,17 @@ void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float t
if (pVehicle->AutoPilot.m_bStayInFastLane)
pVehicle->AutoPilot.m_nNextLane = 0;
CVector positionOnCurrentLinkIncludingLane(
- pCurLink->posX + ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardY,
- pCurLink->posY - ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardX,
+ pCurLink->pos.x + ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardY,
+ pCurLink->pos.y - ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardX,
0.0f);
CVector positionOnNextLinkIncludingLane(
- pNextLink->posX + ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardY,
- pNextLink->posY - ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardX,
+ pNextLink->pos.x + ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardY,
+ pNextLink->pos.y - ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * 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;
+ float directionCurrentLinkX = pCurLink->dir.x * pVehicle->AutoPilot.m_nCurrentDirection;
+ float directionCurrentLinkY = pCurLink->dir.y * pVehicle->AutoPilot.m_nCurrentDirection;
+ float directionNextLinkX = pNextLink->dir.x * pVehicle->AutoPilot.m_nNextDirection;
+ float directionNextLinkY = pNextLink->dir.y * 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,
@@ -1814,10 +1814,10 @@ bool CCarCtrl::PickNextNodeToFollowPath(CVehicle* pVehicle)
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;
+ float currentPathLinkForwardX = pVehicle->AutoPilot.m_nCurrentDirection * pCurLink->dir.x;
+ float currentPathLinkForwardY = pVehicle->AutoPilot.m_nCurrentDirection * pCurLink->dir.y;
+ float nextPathLinkForwardX = pVehicle->AutoPilot.m_nNextDirection * pNextLink->dir.x;
+ float nextPathLinkForwardY = pVehicle->AutoPilot.m_nNextDirection * pNextLink->dir.y;
if (lanesOnNextNode >= 0) {
CVector2D dist = pNextPathNode->pos - pCurNode->pos;
if (dist.MagnitudeSqr() >= SQR(7.0f) && (CGeneral::GetRandomNumber() & 0x600) == 0) {
@@ -1835,17 +1835,17 @@ bool CCarCtrl::PickNextNodeToFollowPath(CVehicle* pVehicle)
if (pVehicle->AutoPilot.m_bStayInFastLane)
pVehicle->AutoPilot.m_nNextLane = 0;
CVector positionOnCurrentLinkIncludingLane(
- pCurLink->posX + ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardY,
- pCurLink->posY - ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardX,
+ pCurLink->pos.x + ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardY,
+ pCurLink->pos.y - ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardX,
0.0f);
CVector positionOnNextLinkIncludingLane(
- pNextLink->posX + ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardY,
- pNextLink->posY - ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardX,
+ pNextLink->pos.x + ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardY,
+ pNextLink->pos.y - ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * 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;
+ float directionCurrentLinkX = pCurLink->dir.x * pVehicle->AutoPilot.m_nCurrentDirection;
+ float directionCurrentLinkY = pCurLink->dir.y * pVehicle->AutoPilot.m_nCurrentDirection;
+ float directionNextLinkX = pNextLink->dir.x * pVehicle->AutoPilot.m_nNextDirection;
+ float directionNextLinkY = pNextLink->dir.y * 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,
@@ -2192,16 +2192,16 @@ void CCarCtrl::SteerAICarWithPhysicsFollowPath(CVehicle* pVehicle, float* pSwerv
forward.Normalise();
CCarPathLink* pCurrentLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo];
CCarPathLink* pNextLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo];
- CVector2D currentPathLinkForward(pCurrentLink->dirX * pVehicle->AutoPilot.m_nCurrentDirection,
- pCurrentLink->dirY * pVehicle->AutoPilot.m_nCurrentDirection);
- float nextPathLinkForwardX = pNextLink->dirX * pVehicle->AutoPilot.m_nNextDirection;
- float nextPathLinkForwardY = pNextLink->dirY * pVehicle->AutoPilot.m_nNextDirection;
+ CVector2D currentPathLinkForward(pCurrentLink->dir.x * pVehicle->AutoPilot.m_nCurrentDirection,
+ pCurrentLink->dir.y * pVehicle->AutoPilot.m_nCurrentDirection);
+ float nextPathLinkForwardX = pNextLink->dir.x * pVehicle->AutoPilot.m_nNextDirection;
+ float nextPathLinkForwardY = pNextLink->dir.y * pVehicle->AutoPilot.m_nNextDirection;
CVector2D positionOnCurrentLinkIncludingLane(
- pCurrentLink->posX + ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.y,
- pCurrentLink->posY - ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.x);
+ pCurrentLink->pos.x + ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.y,
+ pCurrentLink->pos.y - ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.x);
CVector2D positionOnNextLinkIncludingLane(
- pNextLink->posX + ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardY,
- pNextLink->posY - ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardX);
+ pNextLink->pos.x + ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardY,
+ pNextLink->pos.y - ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardX);
CVector2D distanceToNextNode = (CVector2D)pVehicle->GetPosition() - positionOnCurrentLinkIncludingLane;
float scalarDistanceToNextNode = distanceToNextNode.Magnitude();
CVector2D distanceBetweenNodes = positionOnNextLinkIncludingLane - positionOnCurrentLinkIncludingLane;
@@ -2230,16 +2230,16 @@ void CCarCtrl::SteerAICarWithPhysicsFollowPath(CVehicle* pVehicle, float* pSwerv
}
pCurrentLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo];
scalarDistanceToNextNode = CVector2D(
- pCurrentLink->posX + ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.y - pVehicle->GetPosition().x,
- pCurrentLink->posY - ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.x - pVehicle->GetPosition().y).Magnitude();
+ pCurrentLink->pos.x + ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.y - pVehicle->GetPosition().x,
+ pCurrentLink->pos.y - ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.x - pVehicle->GetPosition().y).Magnitude();
pNextLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo];
- currentPathLinkForward.x = pCurrentLink->dirX * pVehicle->AutoPilot.m_nCurrentDirection;
- currentPathLinkForward.y = pCurrentLink->dirY * pVehicle->AutoPilot.m_nCurrentDirection;
- nextPathLinkForwardX = pNextLink->dirX * pVehicle->AutoPilot.m_nNextDirection;
- nextPathLinkForwardY = pNextLink->dirY * pVehicle->AutoPilot.m_nNextDirection;
+ currentPathLinkForward.x = pCurrentLink->dir.x * pVehicle->AutoPilot.m_nCurrentDirection;
+ currentPathLinkForward.y = pCurrentLink->dir.y * pVehicle->AutoPilot.m_nCurrentDirection;
+ nextPathLinkForwardX = pNextLink->dir.x * pVehicle->AutoPilot.m_nNextDirection;
+ nextPathLinkForwardY = pNextLink->dir.y * pVehicle->AutoPilot.m_nNextDirection;
}
- positionOnCurrentLinkIncludingLane.x = pCurrentLink->posX + ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.y;
- positionOnCurrentLinkIncludingLane.y = pCurrentLink->posY - ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.x;
+ positionOnCurrentLinkIncludingLane.x = pCurrentLink->pos.x + ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.y;
+ positionOnCurrentLinkIncludingLane.y = pCurrentLink->pos.y - ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.x;
CVector2D projectedPosition = positionOnCurrentLinkIncludingLane - currentPathLinkForward * scalarDistanceToNextNode * 0.4f;
if (scalarDistanceToNextNode > DISTANCE_TO_NEXT_NODE_TO_CONSIDER_SLOWING_DOWN){
projectedPosition.x = positionOnCurrentLinkIncludingLane.x;
@@ -2281,8 +2281,8 @@ void CCarCtrl::SteerAICarWithPhysicsFollowPath(CVehicle* pVehicle, float* pSwerv
CCarAI::CarHasReasonToStop(pVehicle);
speedStyleMultiplier = 0.0f;
}
- CVector2D trajectory(pCurrentLink->posX + ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.y,
- pCurrentLink->posY - ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.x);
+ CVector2D trajectory(pCurrentLink->pos.x + ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.y,
+ pCurrentLink->pos.y - ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForward.x);
trajectory -= pVehicle->GetPosition();
float speedAngleMultiplier = FindSpeedMultiplier(
CGeneral::GetATanOfXY(trajectory.x, trajectory.y) - angleForward,
diff --git a/src/control/PathFind.cpp b/src/control/PathFind.cpp
index 608a209a..61cd3d4e 100644
--- a/src/control/PathFind.cpp
+++ b/src/control/PathFind.cpp
@@ -5,8 +5,13 @@
#include "Camera.h"
#include "Vehicle.h"
#include "World.h"
+#include "Lines.h" // for debug
#include "PathFind.h"
+bool gbShowPedPaths;
+bool gbShowCarPaths;
+bool gbShowCarPathsLinks;
+
CPathFind &ThePaths = *(CPathFind*)0x8F6754;
WRAPPER bool CPedPath::CalcPedRoute(uint8, CVector, CVector, CVector*, int16*, int16) { EAXJMP(0x42E680); }
@@ -466,20 +471,20 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
// IMPROVE: use a goto here
// Find existing car path link
for(k = 0; k < m_numCarPathLinks; k++){
- if(m_carPathLinks[k].dirX == tempnodes[j].dirX &&
- m_carPathLinks[k].dirY == tempnodes[j].dirY &&
- m_carPathLinks[k].posX == tempnodes[j].pos.x &&
- m_carPathLinks[k].posY == tempnodes[j].pos.y){
+ if(m_carPathLinks[k].dir.x == tempnodes[j].dirX &&
+ m_carPathLinks[k].dir.y == tempnodes[j].dirY &&
+ m_carPathLinks[k].pos.x == tempnodes[j].pos.x &&
+ m_carPathLinks[k].pos.y == tempnodes[j].pos.y){
m_carPathConnections[m_numConnections] = k;
k = m_numCarPathLinks;
}
}
// k is m_numCarPathLinks+1 if we found one
if(k == m_numCarPathLinks){
- m_carPathLinks[m_numCarPathLinks].dirX = tempnodes[j].dirX;
- m_carPathLinks[m_numCarPathLinks].dirY = tempnodes[j].dirY;
- m_carPathLinks[m_numCarPathLinks].posX = tempnodes[j].pos.x;
- m_carPathLinks[m_numCarPathLinks].posY = tempnodes[j].pos.y;
+ m_carPathLinks[m_numCarPathLinks].dir.x = tempnodes[j].dirX;
+ m_carPathLinks[m_numCarPathLinks].dir.y = tempnodes[j].dirY;
+ m_carPathLinks[m_numCarPathLinks].pos.x = tempnodes[j].pos.x;
+ m_carPathLinks[m_numCarPathLinks].pos.y = tempnodes[j].pos.y;
m_carPathLinks[m_numCarPathLinks].pathNodeIndex = i;
m_carPathLinks[m_numCarPathLinks].numLeftLanes = tempnodes[j].numLeftLanes;
m_carPathLinks[m_numCarPathLinks].numRightLanes = tempnodes[j].numRightLanes;
@@ -529,20 +534,20 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
// IMPROVE: use a goto here
// Find existing car path link
for(k = 0; k < m_numCarPathLinks; k++){
- if(m_carPathLinks[k].dirX == dx &&
- m_carPathLinks[k].dirY == dy &&
- m_carPathLinks[k].posX == posx &&
- m_carPathLinks[k].posY == posy){
+ if(m_carPathLinks[k].dir.x == dx &&
+ m_carPathLinks[k].dir.y == dy &&
+ m_carPathLinks[k].pos.x == posx &&
+ m_carPathLinks[k].pos.y == posy){
m_carPathConnections[m_numConnections] = k;
k = m_numCarPathLinks;
}
}
// k is m_numCarPathLinks+1 if we found one
if(k == m_numCarPathLinks){
- m_carPathLinks[m_numCarPathLinks].dirX = dx;
- m_carPathLinks[m_numCarPathLinks].dirY = dy;
- m_carPathLinks[m_numCarPathLinks].posX = posx;
- m_carPathLinks[m_numCarPathLinks].posY = posy;
+ m_carPathLinks[m_numCarPathLinks].dir.x = dx;
+ m_carPathLinks[m_numCarPathLinks].dir.y = dy;
+ m_carPathLinks[m_numCarPathLinks].pos.x = posx;
+ m_carPathLinks[m_numCarPathLinks].pos.y = posy;
m_carPathLinks[m_numCarPathLinks].pathNodeIndex = i;
m_carPathLinks[m_numCarPathLinks].numLeftLanes = -1;
m_carPathLinks[m_numCarPathLinks].numRightLanes = -1;
@@ -760,8 +765,8 @@ CPathFind::SetLinksBridgeLights(float x1, float x2, float y1, float y2, bool ena
{
int i;
for(i = 0; i < m_numCarPathLinks; i++)
- if(x1 < m_carPathLinks[i].posX && m_carPathLinks[i].posX < x2 &&
- y1 < m_carPathLinks[i].posY && m_carPathLinks[i].posY < y2)
+ if(x1 < m_carPathLinks[i].pos.x && m_carPathLinks[i].pos.x < x2 &&
+ y1 < m_carPathLinks[i].pos.y && m_carPathLinks[i].pos.y < y2)
m_carPathLinks[i].bBridgeLights = enable;
}
@@ -1444,6 +1449,132 @@ CPathFind::Load(uint8 *buf, uint32 size)
m_pathNodes[i].bBetweenLevels = false;
}
+void
+CPathFind::DisplayPathData(void)
+{
+ // Not the function from mobm_carPathLinksile but my own!
+
+ int i, j, k;
+ // Draw 50 units around camera
+ CVector pos = TheCamera.GetPosition();
+ const float maxDist = 50.0f;
+
+ // Render car path nodes
+ if(gbShowCarPaths)
+ for(i = 0; i < m_numCarPathNodes; i++){
+ if((m_pathNodes[i].pos - pos).MagnitudeSqr() > SQR(maxDist))
+ continue;
+
+ CVector n1 = m_pathNodes[i].pos;
+ n1.z += 0.3f;
+
+ // Draw node itself
+ CLines::RenderLineWithClipping(n1.x, n1.y, n1.z,
+ n1.x, n1.y, n1.z + 1.0f,
+ 0xFFFFFFFF, 0xFFFFFFFF);
+
+ for(j = 0; j < m_pathNodes[i].numLinks; j++){
+ k = m_connections[m_pathNodes[i].firstLink + j];
+ CVector n2 = m_pathNodes[k].pos;
+ n2.z += 0.3f;
+ // Draw links to neighbours
+ CLines::RenderLineWithClipping(n1.x, n1.y, n1.z,
+ n2.x, n2.y, n2.z,
+ 0xFFFFFFFF, 0xFFFFFFFF);
+ }
+ }
+
+ // Render car path nodes
+ if(gbShowCarPathsLinks)
+ for(i = 0; i < m_numCarPathLinks; i++){
+ CVector2D n1_2d = m_carPathLinks[i].pos;
+ if((n1_2d - pos).MagnitudeSqr() > SQR(maxDist))
+ continue;
+
+ int ni = m_carPathLinks[i].pathNodeIndex;
+ CVector pn1 = m_pathNodes[ni].pos;
+ pn1.z += 0.3f;
+ CVector n1(n1_2d.x, n1_2d.y, pn1.z);
+ n1.z += 0.3f;
+
+ // Draw car node itself
+ CLines::RenderLineWithClipping(n1.x, n1.y, n1.z,
+ n1.x, n1.y, n1.z + 1.0f,
+ 0xFFFFFFFF, 0xFFFFFFFF);
+ CLines::RenderLineWithClipping(n1.x, n1.y, n1.z + 0.5f,
+ n1.x+m_carPathLinks[i].dir.x, n1.y+m_carPathLinks[i].dir.y, n1.z + 0.5f,
+ 0xFFFFFFFF, 0xFFFFFFFF);
+
+ // Draw connection to car path node
+ CLines::RenderLineWithClipping(n1.x, n1.y, n1.z,
+ pn1.x, pn1.y, pn1.z,
+ 0xFF0000FF, 0xFFFFFFFF);
+
+ // traffic light type
+ uint32 col = 0xFF;
+ if((m_carPathLinks[i].trafficLightType&0x7F) == 1)
+ col += 0xFF000000;
+ if((m_carPathLinks[i].trafficLightType&0x7F) == 2)
+ col += 0x00FF0000;
+ if(m_carPathLinks[i].trafficLightType & 0x80)
+ col += 0x0000FF00;
+ CLines::RenderLineWithClipping(n1.x+0.2f, n1.y, n1.z,
+ n1.x+0.2f, n1.y, n1.z + 1.0f,
+ col, col);
+
+ for(j = 0; j < m_pathNodes[ni].numLinks; j++){
+ k = m_carPathConnections[m_pathNodes[ni].firstLink + j];
+ CVector2D n2_2d = m_carPathLinks[k].pos;
+ int nk = m_carPathLinks[k].pathNodeIndex;
+ CVector pn2 = m_pathNodes[nk].pos;
+ pn2.z += 0.3f;
+ CVector n2(n2_2d.x, n2_2d.y, pn2.z);
+ n2.z += 0.3f;
+
+ // Draw links to neighbours
+ CLines::RenderLineWithClipping(n1.x, n1.y, n1.z,
+ n2.x, n2.y, n2.z,
+ 0xFF00FFFF, 0xFF00FFFF);
+ }
+ }
+
+ // Render ped path nodes
+ if(gbShowPedPaths)
+ for(i = m_numCarPathNodes; i < m_numPathNodes; i++){
+ if((m_pathNodes[i].pos - pos).MagnitudeSqr() > SQR(maxDist))
+ continue;
+
+ CVector n1 = m_pathNodes[i].pos;
+ n1.z += 0.3f;
+
+ // Draw node itself
+ CLines::RenderLineWithClipping(n1.x, n1.y, n1.z,
+ n1.x, n1.y, n1.z + 1.0f,
+ 0xFFFFFFFF, 0xFFFFFFFF);
+
+ for(j = 0; j < m_pathNodes[i].numLinks; j++){
+ k = m_connections[m_pathNodes[i].firstLink + j];
+ CVector n2 = m_pathNodes[k].pos;
+ n2.z += 0.3f;
+ // Draw links to neighbours
+ CLines::RenderLineWithClipping(n1.x, n1.y, n1.z,
+ n2.x, n2.y, n2.z,
+ 0xFFFFFFFF, 0xFFFFFFFF);
+
+ // Draw connection flags
+ CVector mid = (n1+n2)/2.0f;
+ uint32 col = 0xFF;
+ if(m_connectionFlags[m_pathNodes[i].firstLink + j].bCrossesRoad)
+ col += 0x00FF0000;
+ if(m_connectionFlags[m_pathNodes[i].firstLink + j].bTrafficLight)
+ col += 0xFF000000;
+ CLines::RenderLineWithClipping(mid.x, mid.y, mid.z,
+ mid.x, mid.y, mid.z + 1.0f,
+ col, col);
+ }
+ }
+}
+
STARTPATCHES
InjectHook(0x4294A0, &CPathFind::Init, PATCH_JUMP);
InjectHook(0x42D580, &CPathFind::AllocatePathFindInfoMem, PATCH_JUMP);
diff --git a/src/control/PathFind.h b/src/control/PathFind.h
index c51cb7c7..81467cdf 100644
--- a/src/control/PathFind.h
+++ b/src/control/PathFind.h
@@ -84,10 +84,8 @@ union CConnectionFlags
struct CCarPathLink
{
- float posX;
- float posY;
- float dirX;
- float dirY;
+ CVector2D pos;
+ CVector2D dir;
int16 pathNodeIndex;
int8 numLeftLanes;
int8 numRightLanes;
@@ -208,7 +206,13 @@ public:
bool TestCoorsCloseness(CVector target, uint8 type, CVector start);
void Save(uint8 *buf, uint32 *size);
void Load(uint8 *buf, uint32 size);
+
+ void DisplayPathData(void);
};
static_assert(sizeof(CPathFind) == 0x49bf4, "CPathFind: error");
extern CPathFind &ThePaths;
+
+extern bool gbShowPedPaths;
+extern bool gbShowCarPaths;
+extern bool gbShowCarPathsLinks;
diff --git a/src/control/TrafficLights.cpp b/src/control/TrafficLights.cpp
index 2cd09a03..e4416965 100644
--- a/src/control/TrafficLights.cpp
+++ b/src/control/TrafficLights.cpp
@@ -1,23 +1,335 @@
#include "common.h"
#include "patcher.h"
-#include "TrafficLights.h"
+#include "General.h"
+#include "Camera.h"
+#include "World.h"
+#include "PathFind.h"
#include "Timer.h"
+#include "Clock.h"
+#include "Weather.h"
+#include "Timecycle.h"
+#include "Pointlights.h"
+#include "Shadows.h"
+#include "Coronas.h"
+#include "SpecialFX.h"
#include "Vehicle.h"
+#include "TrafficLights.h"
+
+// TODO: figure out the meaning of this
+enum { SOME_FLAG = 0x80 };
+
+void
+CTrafficLights::DisplayActualLight(CEntity *ent)
+{
+ if(ent->GetUp().z < 0.96f || ent->bRenderDamaged)
+ return;
+
+ int phase;
+ if(FindTrafficLightType(ent) == 1)
+ phase = LightForCars1();
+ else
+ phase = LightForCars2();
+
+ int i;
+ CBaseModelInfo *mi = CModelInfo::GetModelInfo(ent->GetModelIndex());
+ float x = mi->Get2dEffect(0)->pos.x;
+ float yMin = mi->Get2dEffect(0)->pos.y;
+ float yMax = mi->Get2dEffect(0)->pos.y;
+ float zMin = mi->Get2dEffect(0)->pos.z;
+ float zMax = mi->Get2dEffect(0)->pos.z;
+ for(i = 1; i < 6; i++){
+ assert(mi->Get2dEffect(i));
+ yMin = min(yMin, mi->Get2dEffect(i)->pos.y);
+ yMax = min(yMax, mi->Get2dEffect(i)->pos.y);
+ zMin = min(zMin, mi->Get2dEffect(i)->pos.z);
+ zMax = min(zMax, mi->Get2dEffect(i)->pos.z);
+ }
+
+ CVector pos1, pos2;
+ uint8 r, g;
+ int id;
+ switch(phase){
+ case CAR_LIGHTS_GREEN:
+ r = 0;
+ g = 255;
+ pos1 = ent->GetMatrix() * CVector(x, yMax, zMin);
+ pos2 = ent->GetMatrix() * CVector(x, yMin, zMin);
+ id = 0;
+ break;
+ case CAR_LIGHTS_YELLOW:
+ r = 255;
+ g = 128;
+ pos1 = ent->GetMatrix() * CVector(x, yMax, (zMin+zMax)/2.0f);
+ pos2 = ent->GetMatrix() * CVector(x, yMin, (zMin+zMax)/2.0f);
+ id = 1;
+ break;
+ case CAR_LIGHTS_RED:
+ default:
+ r = 255;
+ g = 0;
+ pos1 = ent->GetMatrix() * CVector(x, yMax, zMax);
+ pos2 = ent->GetMatrix() * CVector(x, yMin, zMax);
+ id = 2;
+ break;
+ }
+
+ if(CClock::GetHours() > 19 || CClock::GetHours() < 6 || CWeather::Foggyness > 0.05f)
+ CPointLights::AddLight(CPointLights::LIGHT_POINT,
+ pos1, CVector(0.0f, 0.0f, 0.0f), 8.0f,
+ r/255.0f, g/255.0f, 0/255.0f, CPointLights::FOG_NORMAL, true);
+
+ CShadows::StoreStaticShadow((uintptr)ent,
+ SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos1,
+ 8.0f, 0.0f, 0.0f, -8.0f, 128,
+ r*CTimeCycle::GetLightOnGroundBrightness()/8.0f,
+ g*CTimeCycle::GetLightOnGroundBrightness()/8.0f,
+ 0*CTimeCycle::GetLightOnGroundBrightness()/8.0f,
+ 12.0f, 1.0f, 40.0f, false, 0.0f);
+
+ if(DotProduct(TheCamera.GetForward(), ent->GetForward()) < 0.0f)
+ CCoronas::RegisterCorona((uintptr)ent + id,
+ r*CTimeCycle::GetSpriteBrightness()*0.7f,
+ g*CTimeCycle::GetSpriteBrightness()*0.7f,
+ 0*CTimeCycle::GetSpriteBrightness()*0.7f,
+ 255,
+ pos1, 1.75f*CTimeCycle::GetSpriteSize(), 50.0f,
+ CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
+ CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
+ else
+ CCoronas::RegisterCorona((uintptr)ent + id + 3,
+ r*CTimeCycle::GetSpriteBrightness()*0.7f,
+ g*CTimeCycle::GetSpriteBrightness()*0.7f,
+ 0*CTimeCycle::GetSpriteBrightness()*0.7f,
+ 255,
+ pos2, 1.75f*CTimeCycle::GetSpriteSize(), 50.0f,
+ CCoronas::TYPE_STAR, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON,
+ CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f);
+
+ CBrightLights::RegisterOne(pos1, ent->GetUp(), ent->GetRight(), CVector(0.0f, 0.0f, 0.0f), id + BRIGHTLIGHT_TRAFFIC_GREEN);
+ CBrightLights::RegisterOne(pos2, ent->GetUp(), -ent->GetRight(), CVector(0.0f, 0.0f, 0.0f), id + BRIGHTLIGHT_TRAFFIC_GREEN);
+
+ static const float top = -0.127f;
+ static const float bot = -0.539f;
+ static const float mid = bot + (top-bot)/3.0f;
+ static const float left = 1.256f;
+ static const float right = 0.706f;
+ phase = CTrafficLights::LightForPeds();
+ if(phase == PED_LIGHTS_DONT_WALK){
+ CVector p0(2.7f, right, top);
+ CVector p1(2.7f, left, top);
+ CVector p2(2.7f, right, mid);
+ CVector p3(2.7f, left, mid);
+ CShinyTexts::RegisterOne(ent->GetMatrix()*p0, ent->GetMatrix()*p1, ent->GetMatrix()*p2, ent->GetMatrix()*p3,
+ 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
+ SHINYTEXT_WALK, 255, 0, 0, 60.0f);
+ }else if(phase == PED_LIGHTS_WALK || CTimer::GetTimeInMilliseconds() & 0x100){
+ CVector p0(2.7f, right, mid);
+ CVector p1(2.7f, left, mid);
+ CVector p2(2.7f, right, bot);
+ CVector p3(2.7f, left, bot);
+ CShinyTexts::RegisterOne(ent->GetMatrix()*p0, ent->GetMatrix()*p1, ent->GetMatrix()*p2, ent->GetMatrix()*p3,
+ 1.0f, 0.5f, 0.0f, 0.5f, 1.0f, 1.0f, 0.0f, 1.0f,
+ SHINYTEXT_WALK, 255, 255, 255, 60.0f);
+ }
+}
+
+void
+CTrafficLights::ScanForLightsOnMap(void)
+{
+ int x, y;
+ int i, j, l;
+ CPtrNode *node;
+
+ for(x = 0; x < NUMSECTORS_X; x++)
+ for(y = 0; y < NUMSECTORS_Y; y++){
+ CPtrList &list = CWorld::GetSector(x, y)->m_lists[ENTITYLIST_DUMMIES];
+ for(node = list.first; node; node = node->next){
+ CEntity *light = (CEntity*)node->item;
+ if(light->GetModelIndex() != MI_TRAFFICLIGHTS)
+ continue;
+
+ // Check cars
+ for(i = 0; i < ThePaths.m_numCarPathLinks; i++){
+ CVector2D dist = ThePaths.m_carPathLinks[i].pos - light->GetPosition();
+ float dotY = Abs(DotProduct2D(dist, light->GetForward())); // forward is direction of car light
+ float dotX = DotProduct2D(dist, light->GetRight()); // towards base of light
+ // it has to be on the correct side of the node and also not very far away
+ if(dotX < 0.0f && dotX > -15.0f && dotY < 3.0f){
+ float dz = ThePaths.m_pathNodes[ThePaths.m_carPathLinks[i].pathNodeIndex].pos.z -
+ light->GetPosition().z;
+ if(dz < 15.0f){
+ ThePaths.m_carPathLinks[i].trafficLightType = FindTrafficLightType(light);
+ // Find two neighbour nodes of this one
+ int n1 = -1;
+ int n2 = -1;
+ for(j = 0; j < ThePaths.m_numPathNodes; j++)
+ for(l = 0; l < ThePaths.m_pathNodes[j].numLinks; l++)
+ if(ThePaths.m_carPathConnections[ThePaths.m_pathNodes[j].firstLink + l] == i){
+ if(n1 == -1)
+ n1 = j;
+ else
+ n2 = j;
+ }
+ // What's going on here?
+ if(ThePaths.m_pathNodes[n1].numLinks <= ThePaths.m_pathNodes[n2].numLinks)
+ n1 = n2;
+ if(ThePaths.m_carPathLinks[i].pathNodeIndex != n1)
+ ThePaths.m_carPathLinks[i].trafficLightType |= SOME_FLAG;
+ }
+ }
+ }
+
+ // Check peds
+ for(i = ThePaths.m_numCarPathNodes; i < ThePaths.m_numPathNodes; i++){
+ float dist1, dist2;
+ dist1 = Abs(ThePaths.m_pathNodes[i].pos.x - light->GetPosition().x) +
+ Abs(ThePaths.m_pathNodes[i].pos.y - light->GetPosition().y);
+ if(dist1 < 50.0f){
+ for(l = 0; l < ThePaths.m_pathNodes[i].numLinks; l++){
+ j = ThePaths.m_pathNodes[i].firstLink + l;
+ if(ThePaths.m_connectionFlags[j].bCrossesRoad){
+ dist2 = Abs(ThePaths.m_pathNodes[j].pos.x - light->GetPosition().x) +
+ Abs(ThePaths.m_pathNodes[j].pos.y - light->GetPosition().y);
+ if(dist1 < 15.0f || dist2 < 15.0f)
+ ThePaths.m_connectionFlags[j].bTrafficLight = true;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+bool
+CTrafficLights::ShouldCarStopForLight(CVehicle *vehicle, bool alwaysStop)
+{
+ int node, type;
-WRAPPER void CTrafficLights::DisplayActualLight(CEntity *ent) { EAXJMP(0x455800); }
-WRAPPER void CTrafficLights::ScanForLightsOnMap(void) { EAXJMP(0x454F40); }
-WRAPPER bool CTrafficLights::ShouldCarStopForLight(CVehicle*, bool) { EAXJMP(0x455350); }
-WRAPPER bool CTrafficLights::ShouldCarStopForBridge(CVehicle*) { EAXJMP(0x456460); }
+ node = vehicle->AutoPilot.m_nNextPathNodeInfo;
+ type = ThePaths.m_carPathLinks[node].trafficLightType;
+ if(type){
+ if((type & SOME_FLAG || ThePaths.m_carPathLinks[node].pathNodeIndex == vehicle->AutoPilot.m_nNextRouteNode) &&
+ (!(type & SOME_FLAG) || ThePaths.m_carPathLinks[node].pathNodeIndex != vehicle->AutoPilot.m_nNextRouteNode))
+ if(alwaysStop ||
+ (type&~SOME_FLAG) == 1 && LightForCars1() != CAR_LIGHTS_GREEN ||
+ (type&~SOME_FLAG) == 2 && LightForCars2() != CAR_LIGHTS_GREEN){
+ float dist = DotProduct2D(CVector2D(vehicle->GetPosition()) - ThePaths.m_carPathLinks[node].pos,
+ ThePaths.m_carPathLinks[node].dir);
+ if(vehicle->AutoPilot.m_nNextDirection == -1){
+ if(dist > 0.0f && dist < 8.0f)
+ return true;
+ }else{
+ if(dist < 0.0f && dist > -8.0f)
+ return true;
+ }
+ }
+ }
+
+ node = vehicle->AutoPilot.m_nCurrentPathNodeInfo;
+ type = ThePaths.m_carPathLinks[node].trafficLightType;
+ if(type){
+ if((type & SOME_FLAG || ThePaths.m_carPathLinks[node].pathNodeIndex == vehicle->AutoPilot.m_nCurrentRouteNode) &&
+ (!(type & SOME_FLAG) || ThePaths.m_carPathLinks[node].pathNodeIndex != vehicle->AutoPilot.m_nCurrentRouteNode))
+ if(alwaysStop ||
+ (type&~SOME_FLAG) == 1 && LightForCars1() != CAR_LIGHTS_GREEN ||
+ (type&~SOME_FLAG) == 2 && LightForCars2() != CAR_LIGHTS_GREEN){
+ float dist = DotProduct2D(CVector2D(vehicle->GetPosition()) - ThePaths.m_carPathLinks[node].pos,
+ ThePaths.m_carPathLinks[node].dir);
+ if(vehicle->AutoPilot.m_nCurrentDirection == -1){
+ if(dist > 0.0f && dist < 8.0f)
+ return true;
+ }else{
+ if(dist < 0.0f && dist > -8.0f)
+ return true;
+ }
+ }
+ }
+
+ if(vehicle->m_status == STATUS_PHYSICS){
+ node = vehicle->AutoPilot.m_nPreviousPathNodeInfo;
+ type = ThePaths.m_carPathLinks[node].trafficLightType;
+ if(type){
+ if((type & SOME_FLAG || ThePaths.m_carPathLinks[node].pathNodeIndex == vehicle->AutoPilot.m_nPrevRouteNode) &&
+ (!(type & SOME_FLAG) || ThePaths.m_carPathLinks[node].pathNodeIndex != vehicle->AutoPilot.m_nPrevRouteNode))
+ if(alwaysStop ||
+ (type&~SOME_FLAG) == 1 && LightForCars1() != CAR_LIGHTS_GREEN ||
+ (type&~SOME_FLAG) == 2 && LightForCars2() != CAR_LIGHTS_GREEN){
+ float dist = DotProduct2D(CVector2D(vehicle->GetPosition()) - ThePaths.m_carPathLinks[node].pos,
+ ThePaths.m_carPathLinks[node].dir);
+ if(vehicle->AutoPilot.m_nPreviousDirection == -1){
+ if(dist > 0.0f && dist < 6.0f)
+ return true;
+ }else{
+ if(dist < 0.0f && dist > -6.0f)
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+bool
+CTrafficLights::ShouldCarStopForBridge(CVehicle *vehicle)
+{
+ return ThePaths.m_carPathLinks[vehicle->AutoPilot.m_nNextPathNodeInfo].bBridgeLights &&
+ !ThePaths.m_carPathLinks[vehicle->AutoPilot.m_nCurrentPathNodeInfo].bBridgeLights;
+}
+
+int
+CTrafficLights::FindTrafficLightType(CEntity *light)
+{
+ float orientation = RADTODEG(CGeneral::GetATanOfXY(light->GetForward().x, light->GetForward().y));
+ if((orientation > 60.0f && orientation < 60.0f + 90.0f) ||
+ (orientation > 240.0f && orientation < 240.0f + 90.0f))
+ return 1;
+ return 2;
+}
uint8
CTrafficLights::LightForPeds(void)
{
- uint32 period = CTimer::GetTimeInMilliseconds() & 0x3FFF; // Equals to % 16384
+ uint32 period = CTimer::GetTimeInMilliseconds() % 16384;
- if (period >= 15384)
- return PED_LIGHTS_WALK_BLINK;
- else if (period >= 12000)
+ if(period < 12000)
+ return PED_LIGHTS_DONT_WALK;
+ else if(period < 16384 - 1000)
return PED_LIGHTS_WALK;
else
- return PED_LIGHTS_DONT_WALK;
-} \ No newline at end of file
+ return PED_LIGHTS_WALK_BLINK;
+}
+
+uint8
+CTrafficLights::LightForCars1(void)
+{
+ uint32 period = CTimer::GetTimeInMilliseconds() % 16384;
+
+ if(period < 5000)
+ return CAR_LIGHTS_GREEN;
+ else if(period < 5000 + 1000)
+ return CAR_LIGHTS_YELLOW;
+ else
+ return CAR_LIGHTS_RED;
+}
+
+uint8
+CTrafficLights::LightForCars2(void)
+{
+ uint32 period = CTimer::GetTimeInMilliseconds() % 16384;
+
+ if(period < 6000)
+ return CAR_LIGHTS_RED;
+ else if(period < 12000 - 1000)
+ return CAR_LIGHTS_GREEN;
+ else if(period < 12000)
+ return CAR_LIGHTS_YELLOW;
+ else
+ return CAR_LIGHTS_RED;
+}
+
+STARTPATCHES
+ InjectHook(0x455760, &CTrafficLights::LightForCars1, PATCH_JUMP);
+ InjectHook(0x455790, &CTrafficLights::LightForCars2, PATCH_JUMP);
+ InjectHook(0x4557D0, &CTrafficLights::LightForPeds, PATCH_JUMP);
+ENDPATCHES
diff --git a/src/control/TrafficLights.h b/src/control/TrafficLights.h
index 06505ed6..f3df6cd5 100644
--- a/src/control/TrafficLights.h
+++ b/src/control/TrafficLights.h
@@ -7,6 +7,10 @@ enum {
PED_LIGHTS_WALK,
PED_LIGHTS_WALK_BLINK,
PED_LIGHTS_DONT_WALK,
+
+ CAR_LIGHTS_GREEN = 0,
+ CAR_LIGHTS_YELLOW,
+ CAR_LIGHTS_RED
};
class CTrafficLights
@@ -14,7 +18,10 @@ class CTrafficLights
public:
static void DisplayActualLight(CEntity *ent);
static void ScanForLightsOnMap(void);
+ static int FindTrafficLightType(CEntity *light);
static uint8 LightForPeds(void);
+ static uint8 LightForCars1(void);
+ static uint8 LightForCars2(void);
static bool ShouldCarStopForLight(CVehicle*, bool);
static bool ShouldCarStopForBridge(CVehicle*);
};