mirror of
https://github.com/GTAmodding/re3.git
synced 2021-02-19 17:49:54 +01:00
implemented CTrafficLights
This commit is contained in:
parent
3a4442eca4
commit
c5d61392ea
@ -43,7 +43,6 @@ CPools - save/loading
|
||||
CRecordDataForChase
|
||||
CRecordDataForGame
|
||||
CRoadBlocks
|
||||
CTrafficLights
|
||||
CWeapon
|
||||
CWorld
|
||||
GenericLoad
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
||||
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); }
|
||||
// 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;
|
||||
|
||||
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;
|
||||
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
|
||||
|
@ -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*);
|
||||
};
|
||||
|
@ -1,8 +1,7 @@
|
||||
#include "common.h"
|
||||
#include "rpmatfx.h"
|
||||
#include "rpskin.h"
|
||||
#include "rphanim.h"
|
||||
#include "rtbmp.h"
|
||||
#include "rpskin.h"
|
||||
#include "patcher.h"
|
||||
#include "main.h"
|
||||
#include "CdStream.h"
|
||||
@ -54,6 +53,7 @@
|
||||
#include "Frontend.h"
|
||||
#include "AnimViewer.h"
|
||||
#include "Script.h"
|
||||
#include "PathFind.h"
|
||||
#include "Debug.h"
|
||||
#include "Console.h"
|
||||
#include "timebars.h"
|
||||
@ -788,8 +788,11 @@ void
|
||||
RenderDebugShit(void)
|
||||
{
|
||||
CTheScripts::RenderTheScriptDebugLines();
|
||||
#ifndef FINAL
|
||||
if(gbShowCollisionLines)
|
||||
CRenderer::RenderCollisionLines();
|
||||
ThePaths.DisplayPathData();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -350,6 +350,9 @@ DebugMenuPopulate(void)
|
||||
DebugMenuAddCmd("Debug", "Catalina Fly Away", CHeli::MakeCatalinaHeliFlyAway);
|
||||
DebugMenuAddVarBool8("Debug", "Script Heli On", (int8*)0x95CD43, nil);
|
||||
|
||||
DebugMenuAddVarBool8("Debug", "Show Ped Paths", (int8*)&gbShowPedPaths, nil);
|
||||
DebugMenuAddVarBool8("Debug", "Show Car Paths", (int8*)&gbShowCarPaths, nil);
|
||||
DebugMenuAddVarBool8("Debug", "Show Car Path Links", (int8*)&gbShowCarPathsLinks, nil);
|
||||
DebugMenuAddVarBool8("Debug", "Show Ped Road Groups", (int8*)&gbShowPedRoadGroups, nil);
|
||||
DebugMenuAddVarBool8("Debug", "Show Car Road Groups", (int8*)&gbShowCarRoadGroups, nil);
|
||||
DebugMenuAddVarBool8("Debug", "Show Collision Lines", (int8*)&gbShowCollisionLines, nil);
|
||||
|
@ -119,8 +119,10 @@ public:
|
||||
static int GetSunCoronaBlue(void) { return m_nCurrentSunCoronaBlue; }
|
||||
static float GetSunSize(void) { return m_fCurrentSunSize; }
|
||||
static float GetSpriteBrightness(void) { return m_fCurrentSpriteBrightness; }
|
||||
static float GetSpriteSize(void) { return m_fCurrentSpriteSize; }
|
||||
static int GetShadowStrength(void) { return m_nCurrentShadowStrength; }
|
||||
static int GetLightShadowStrength(void) { return m_nCurrentLightShadowStrength; }
|
||||
static int GetLightOnGroundBrightness(void) { return m_fCurrentLightsOnGroundBrightness; }
|
||||
static float GetFarClip(void) { return m_fCurrentFarClip; }
|
||||
static float GetFogStart(void) { return m_fCurrentFogStart; }
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user