commit
7d1e1bf1dd
@ -81,7 +81,7 @@ public:
|
|||||||
uint32 m_nTimeTempAction;
|
uint32 m_nTimeTempAction;
|
||||||
float m_fMaxTrafficSpeed;
|
float m_fMaxTrafficSpeed;
|
||||||
uint8 m_nCruiseSpeed;
|
uint8 m_nCruiseSpeed;
|
||||||
uint8 m_flag1 : 1;
|
uint8 m_bSlowedDownBecauseOfCars : 1;
|
||||||
uint8 m_bSlowedDownBecauseOfPeds : 1;
|
uint8 m_bSlowedDownBecauseOfPeds : 1;
|
||||||
uint8 m_flag4 : 1;
|
uint8 m_flag4 : 1;
|
||||||
uint8 m_flag8 : 1;
|
uint8 m_flag8 : 1;
|
||||||
@ -109,7 +109,7 @@ public:
|
|||||||
m_nCruiseSpeed = 10;
|
m_nCruiseSpeed = 10;
|
||||||
m_fMaxTrafficSpeed = 10.0f;
|
m_fMaxTrafficSpeed = 10.0f;
|
||||||
m_bSlowedDownBecauseOfPeds = false;
|
m_bSlowedDownBecauseOfPeds = false;
|
||||||
m_flag1 = false;
|
m_bSlowedDownBecauseOfCars = false;
|
||||||
m_nPathFindNodesCount = 0;
|
m_nPathFindNodesCount = 0;
|
||||||
m_pTargetCar = 0;
|
m_pTargetCar = 0;
|
||||||
m_nTimeToStartMission = CTimer::GetTimeInMilliseconds();
|
m_nTimeToStartMission = CTimer::GetTimeInMilliseconds();
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include "Zones.h"
|
#include "Zones.h"
|
||||||
|
|
||||||
#define GAME_SPEED_TO_METERS_PER_SECOND 50.0f
|
#define GAME_SPEED_TO_METERS_PER_SECOND 50.0f
|
||||||
|
#define GAME_SPEED_TO_CARAI_SPEED 60.0f
|
||||||
|
|
||||||
#define DISTANCE_TO_SPAWN_ROADBLOCK_PEDS 51.0f
|
#define DISTANCE_TO_SPAWN_ROADBLOCK_PEDS 51.0f
|
||||||
#define DISTANCE_TO_SCAN_FOR_DANGER 11.0f
|
#define DISTANCE_TO_SCAN_FOR_DANGER 11.0f
|
||||||
@ -62,7 +63,6 @@ WRAPPER void CCarCtrl::RemoveFromInterestingVehicleList(CVehicle* v) { EAXJMP(0x
|
|||||||
WRAPPER void CCarCtrl::GenerateEmergencyServicesCar(void) { EAXJMP(0x41FC50); }
|
WRAPPER void CCarCtrl::GenerateEmergencyServicesCar(void) { EAXJMP(0x41FC50); }
|
||||||
WRAPPER void CCarCtrl::PickNextNodeAccordingStrategy(CVehicle*) { EAXJMP(0x41BA50); }
|
WRAPPER void CCarCtrl::PickNextNodeAccordingStrategy(CVehicle*) { EAXJMP(0x41BA50); }
|
||||||
WRAPPER void CCarCtrl::DragCarToPoint(CVehicle*, CVector*) { EAXJMP(0x41D450); }
|
WRAPPER void CCarCtrl::DragCarToPoint(CVehicle*, CVector*) { EAXJMP(0x41D450); }
|
||||||
WRAPPER void CCarCtrl::SlowCarDownForCarsSectorList(CPtrList&, CVehicle*, float, float, float, float, float*, float) { EAXJMP(0x419B40); }
|
|
||||||
WRAPPER void CCarCtrl::Init(void) { EAXJMP(0x41D280); }
|
WRAPPER void CCarCtrl::Init(void) { EAXJMP(0x41D280); }
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -440,7 +440,7 @@ CCarCtrl::GenerateOneRandomCar()
|
|||||||
}
|
}
|
||||||
finalPosition.z = groundZ + pCar->GetHeightAboveRoad();
|
finalPosition.z = groundZ + pCar->GetHeightAboveRoad();
|
||||||
pCar->GetPosition() = finalPosition;
|
pCar->GetPosition() = finalPosition;
|
||||||
pCar->SetMoveSpeed(directionIncludingCurve / 60.0f);
|
pCar->SetMoveSpeed(directionIncludingCurve / GAME_SPEED_TO_CARAI_SPEED);
|
||||||
CVector2D speedDifferenceWithTarget = (CVector2D)pCar->GetMoveSpeed() - vecPlayerSpeed;
|
CVector2D speedDifferenceWithTarget = (CVector2D)pCar->GetMoveSpeed() - vecPlayerSpeed;
|
||||||
CVector2D distanceToTarget = positionIncludingCurve - vecTargetPos;
|
CVector2D distanceToTarget = positionIncludingCurve - vecTargetPos;
|
||||||
switch (carClass) {
|
switch (carClass) {
|
||||||
@ -780,7 +780,7 @@ CCarCtrl::UpdateCarOnRails(CVehicle* pVehicle)
|
|||||||
);
|
);
|
||||||
positionIncludingCurve.z = 15.0f;
|
positionIncludingCurve.z = 15.0f;
|
||||||
DragCarToPoint(pVehicle, &positionIncludingCurve);
|
DragCarToPoint(pVehicle, &positionIncludingCurve);
|
||||||
pVehicle->SetMoveSpeed(directionIncludingCurve / 60.0f);
|
pVehicle->SetMoveSpeed(directionIncludingCurve / GAME_SPEED_TO_CARAI_SPEED);
|
||||||
}
|
}
|
||||||
|
|
||||||
float
|
float
|
||||||
@ -984,6 +984,194 @@ void CCarCtrl::SlowCarDownForPedsSectorList(CPtrList& lst, CVehicle* pVehicle, f
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void CCarCtrl::SlowCarDownForCarsSectorList(CPtrList& lst, CVehicle* pVehicle, float x_inf, float y_inf, float x_sup, float y_sup, float* pSpeed, float curSpeed)
|
||||||
|
{
|
||||||
|
for (CPtrNode* pNode = lst.first; pNode != nil; pNode = pNode->next){
|
||||||
|
CVehicle* pTestVehicle = (CVehicle*)pNode->item;
|
||||||
|
if (pVehicle == pTestVehicle)
|
||||||
|
continue;
|
||||||
|
if (pTestVehicle->m_scanCode == CWorld::GetCurrentScanCode())
|
||||||
|
continue;
|
||||||
|
if (!pTestVehicle->bUsesCollision)
|
||||||
|
continue;
|
||||||
|
pTestVehicle->m_scanCode = CWorld::GetCurrentScanCode();
|
||||||
|
CVector boundCenter = pTestVehicle->GetBoundCentre();
|
||||||
|
if (boundCenter.x < x_inf || boundCenter.x > x_sup)
|
||||||
|
continue;
|
||||||
|
if (boundCenter.y < y_inf || boundCenter.y > y_sup)
|
||||||
|
continue;
|
||||||
|
if (Abs(boundCenter.z - pVehicle->GetPosition().z) < 5.0f)
|
||||||
|
SlowCarDownForOtherCar(pTestVehicle, pVehicle, pSpeed, curSpeed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCarCtrl::SlowCarDownForOtherCar(CEntity* pOtherEntity, CVehicle* pVehicle, float* pSpeed, float curSpeed)
|
||||||
|
{
|
||||||
|
CVector forwardA = pVehicle->GetForward();
|
||||||
|
((CVector2D)forwardA).Normalise();
|
||||||
|
if (DotProduct2D(pOtherEntity->GetPosition() - pVehicle->GetPosition(), forwardA) < 0.0f)
|
||||||
|
return;
|
||||||
|
CVector forwardB = pOtherEntity->GetForward();
|
||||||
|
((CVector2D)forwardB).Normalise();
|
||||||
|
forwardA.z = forwardB.z = 0.0f;
|
||||||
|
CVehicle* pOtherVehicle = (CVehicle*)pOtherEntity;
|
||||||
|
/* why is the argument CEntity if it's always CVehicle anyway and is casted? */
|
||||||
|
float speedOtherX = GAME_SPEED_TO_CARAI_SPEED * pOtherVehicle->GetMoveSpeed().x;
|
||||||
|
float speedOtherY = GAME_SPEED_TO_CARAI_SPEED * pOtherVehicle->GetMoveSpeed().y;
|
||||||
|
float projectionX = speedOtherX - forwardA.x * curSpeed;
|
||||||
|
float projectionY = speedOtherY - forwardA.y * curSpeed;
|
||||||
|
float proximityA = TestCollisionBetween2MovingRects(pOtherVehicle, pVehicle, projectionX, projectionY, &forwardA, &forwardB, 0);
|
||||||
|
float proximityB = TestCollisionBetween2MovingRects(pVehicle, pOtherVehicle, -projectionX, -projectionY, &forwardB, &forwardA, 1);
|
||||||
|
float minProximity = min(proximityA, proximityB);
|
||||||
|
if (minProximity >= 0.0f && minProximity < 1.0f){
|
||||||
|
minProximity = max(0.0f, (minProximity - 0.2f) * 1.25f);
|
||||||
|
pVehicle->AutoPilot.m_bSlowedDownBecauseOfCars = true;
|
||||||
|
*pSpeed = min(*pSpeed, minProximity * curSpeed);
|
||||||
|
}
|
||||||
|
if (minProximity >= 0.0f && minProximity < 0.5f && pOtherEntity->IsVehicle() &&
|
||||||
|
CTimer::GetTimeInMilliseconds() - pVehicle->AutoPilot.m_nTimeToStartMission > 15000 &&
|
||||||
|
CTimer::GetTimeInMilliseconds() - pOtherVehicle->AutoPilot.m_nTimeToStartMission > 15000){
|
||||||
|
/* If cars are standing for 15 seconds, annoy one of them and make avoid cars. */
|
||||||
|
if (pOtherEntity != FindPlayerVehicle() &&
|
||||||
|
DotProduct2D(pVehicle->GetForward(), pOtherVehicle->GetForward()) < 0.5f &&
|
||||||
|
pVehicle < pOtherVehicle){ /* that comparasion though... */
|
||||||
|
*pSpeed = max(curSpeed / 5, *pSpeed);
|
||||||
|
if (pVehicle->m_status == STATUS_SIMPLE){
|
||||||
|
pVehicle->m_status = STATUS_PHYSICS;
|
||||||
|
SwitchVehicleToRealPhysics(pVehicle);
|
||||||
|
}
|
||||||
|
pVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
|
||||||
|
pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
WRAPPER float CCarCtrl::TestCollisionBetween2MovingRects(CVehicle* pVehicleA, CVehicle* pVehicleB, float projectionX, float projectionY, CVector* pForwardA, CVector* pForwardB, uint8 id) { EAXJMP(0x41A020); }
|
||||||
|
#else
|
||||||
|
float CCarCtrl::TestCollisionBetween2MovingRects(CVehicle* pVehicleA, CVehicle* pVehicleB, float projectionX, float projectionY, CVector* pForwardA, CVector* pForwardB, uint8 id)
|
||||||
|
{
|
||||||
|
CVector2D vecBToA = pVehicleA->GetPosition() - pVehicleB->GetPosition();
|
||||||
|
float lenB = pVehicleB->GetModelInfo()->GetColModel()->boundingBox.max.y;
|
||||||
|
float widthB = pVehicleB->GetModelInfo()->GetColModel()->boundingBox.max.x;
|
||||||
|
float backLenB = -pVehicleB->GetModelInfo()->GetColModel()->boundingBox.min.y;
|
||||||
|
float lenA = pVehicleA->GetModelInfo()->GetColModel()->boundingBox.max.y;
|
||||||
|
float widthA = pVehicleA->GetModelInfo()->GetColModel()->boundingBox.max.x;
|
||||||
|
float backLenA = -pVehicleA->GetModelInfo()->GetColModel()->boundingBox.min.y;
|
||||||
|
float proximity = 1.0f;
|
||||||
|
float fullWidthB = 2.0f * widthB;
|
||||||
|
float fullLenB = lenB + backLenB;
|
||||||
|
for (int i = 0; i < 4; i++){
|
||||||
|
float testedOffsetX;
|
||||||
|
float testedOffsetY;
|
||||||
|
switch (i) {
|
||||||
|
case 0: /* Front right corner */
|
||||||
|
testedOffsetX = vecBToA.x + widthA * pForwardB->y + lenA * pForwardB->x;
|
||||||
|
testedOffsetY = vecBToA.y + lenA * pForwardB->y - widthA * pForwardB->x;
|
||||||
|
break;
|
||||||
|
case 1: /* Front left corner */
|
||||||
|
testedOffsetX = vecBToA.x + -widthA * pForwardB->x + lenA * pForwardB->x;
|
||||||
|
testedOffsetY = vecBToA.y + lenA * pForwardB->y + widthA * pForwardB->x;
|
||||||
|
break;
|
||||||
|
case 2: /* Rear right corner */
|
||||||
|
testedOffsetX = vecBToA.x + widthA * pForwardB->y - backLenA * pForwardB->x;
|
||||||
|
testedOffsetY = vecBToA.y - backLenA * pForwardB->y - widthA * pForwardB->x;
|
||||||
|
break;
|
||||||
|
case 3: /* Rear left corner */
|
||||||
|
testedOffsetX = vecBToA.x - widthA * pForwardB->y - backLenA * pForwardB->x;
|
||||||
|
testedOffsetY = vecBToA.y - backLenA * pForwardB->y + widthA * pForwardB->x;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Testing width collision */
|
||||||
|
float baseWidthProximity = 0.0f;
|
||||||
|
float fullWidthProximity = 1.0f;
|
||||||
|
float widthDistance = testedOffsetX * pForwardA->y - testedOffsetY * pForwardA->x;
|
||||||
|
float widthProjection = projectionX * pForwardA->y - projectionY * pForwardA->x;
|
||||||
|
if (widthDistance > widthB){
|
||||||
|
if (widthProjection < 0.0f){
|
||||||
|
float proximityWidth = -(widthDistance - widthB) / widthProjection;
|
||||||
|
if (proximityWidth < 1.0f){
|
||||||
|
baseWidthProximity = proximityWidth;
|
||||||
|
fullWidthProximity = min(1.0f, proximityWidth - fullWidthB / widthProjection);
|
||||||
|
}else{
|
||||||
|
baseWidthProximity = 1.0f;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
baseWidthProximity = 1.0f;
|
||||||
|
fullWidthProximity = 1.0f;
|
||||||
|
}
|
||||||
|
}else if (widthDistance < -widthB){
|
||||||
|
if (widthProjection > 0.0f) {
|
||||||
|
float proximityWidth = -(widthDistance + widthB) / widthProjection;
|
||||||
|
if (proximityWidth < 1.0f) {
|
||||||
|
baseWidthProximity = proximityWidth;
|
||||||
|
fullWidthProximity = min(1.0f, proximityWidth + fullWidthB / widthProjection);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
baseWidthProximity = 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
baseWidthProximity = 1.0f;
|
||||||
|
fullWidthProximity = 1.0f;
|
||||||
|
}
|
||||||
|
}else if (widthProjection > 0.0f){
|
||||||
|
fullWidthProximity = (widthB - widthDistance) / widthProjection;
|
||||||
|
}else if (widthProjection < 0.0f){
|
||||||
|
fullWidthProximity = -(widthB + widthDistance) / widthProjection;
|
||||||
|
}
|
||||||
|
/* Testing length collision */
|
||||||
|
float baseLengthProximity = 0.0f;
|
||||||
|
float fullLengthProximity = 1.0f;
|
||||||
|
float lenDistance = testedOffsetX * pForwardA->x + testedOffsetY * pForwardA->y;
|
||||||
|
float lenProjection = projectionX * pForwardA->x + projectionY * pForwardA->y;
|
||||||
|
if (lenDistance > lenB) {
|
||||||
|
if (lenProjection < 0.0f) {
|
||||||
|
float proximityLength = -(lenDistance - lenB) / lenProjection;
|
||||||
|
if (proximityLength < 1.0f) {
|
||||||
|
baseLengthProximity = proximityLength;
|
||||||
|
fullLengthProximity = min(1.0f, proximityLength - fullLenB / lenProjection);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
baseLengthProximity = 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
baseLengthProximity = 1.0f;
|
||||||
|
fullLengthProximity = 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (lenDistance < -backLenB) {
|
||||||
|
if (lenProjection > 0.0f) {
|
||||||
|
float proximityLength = -(lenDistance + backLenB) / lenProjection;
|
||||||
|
if (proximityLength < 1.0f) {
|
||||||
|
baseLengthProximity = proximityLength;
|
||||||
|
fullLengthProximity = min(1.0f, proximityLength + fullLenB / lenProjection);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
baseLengthProximity = 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
baseLengthProximity = 1.0f;
|
||||||
|
fullLengthProximity = 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (lenProjection > 0.0f) {
|
||||||
|
fullLengthProximity = (lenB - lenDistance) / lenProjection;
|
||||||
|
}
|
||||||
|
else if (lenProjection < 0.0f) {
|
||||||
|
fullLengthProximity = -(backLenB + lenDistance) / lenProjection;
|
||||||
|
}
|
||||||
|
float baseProximity = max(baseWidthProximity, baseLengthProximity);
|
||||||
|
if (baseProximity < fullWidthProximity && baseProximity < fullLengthProximity)
|
||||||
|
proximity = min(proximity, baseProximity);
|
||||||
|
}
|
||||||
|
return proximity;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CCarCtrl::MapCouldMoveInThisArea(float x, float y)
|
CCarCtrl::MapCouldMoveInThisArea(float x, float y)
|
||||||
|
@ -62,6 +62,8 @@ public:
|
|||||||
static void SlowCarDownForCarsSectorList(CPtrList&, CVehicle*, float, float, float, float, float*, float);
|
static void SlowCarDownForCarsSectorList(CPtrList&, CVehicle*, float, float, float, float, float*, float);
|
||||||
static void SlowCarDownForPedsSectorList(CPtrList&, CVehicle*, float, float, float, float, float*, float);
|
static void SlowCarDownForPedsSectorList(CPtrList&, CVehicle*, float, float, float, float, float*, float);
|
||||||
static void Init(void);
|
static void Init(void);
|
||||||
|
static void SlowCarDownForOtherCar(CEntity*, CVehicle*, float*, float);
|
||||||
|
static float TestCollisionBetween2MovingRects(CVehicle*, CVehicle*, float, float, CVector*, CVector*, uint8);
|
||||||
|
|
||||||
static float GetOffsetOfLaneFromCenterOfRoad(int8 lane, CCarPathLink* pLink)
|
static float GetOffsetOfLaneFromCenterOfRoad(int8 lane, CCarPathLink* pLink)
|
||||||
{
|
{
|
||||||
|
@ -311,7 +311,7 @@ CAutomobile::ProcessControl(void)
|
|||||||
}
|
}
|
||||||
CVisibilityPlugins::SetClumpAlpha((RpClump*)m_rwObject, clumpAlpha);
|
CVisibilityPlugins::SetClumpAlpha((RpClump*)m_rwObject, clumpAlpha);
|
||||||
|
|
||||||
AutoPilot.m_flag1 = false;
|
AutoPilot.m_bSlowedDownBecauseOfCars = false;
|
||||||
AutoPilot.m_bSlowedDownBecauseOfPeds = false;
|
AutoPilot.m_bSlowedDownBecauseOfPeds = false;
|
||||||
|
|
||||||
// Set Center of Mass to make car more stable
|
// Set Center of Mass to make car more stable
|
||||||
@ -3931,7 +3931,7 @@ void
|
|||||||
CAutomobile::PlayHornIfNecessary(void)
|
CAutomobile::PlayHornIfNecessary(void)
|
||||||
{
|
{
|
||||||
if(AutoPilot.m_bSlowedDownBecauseOfPeds ||
|
if(AutoPilot.m_bSlowedDownBecauseOfPeds ||
|
||||||
AutoPilot.m_flag1)
|
AutoPilot.m_bSlowedDownBecauseOfCars)
|
||||||
if(!HasCarStoppedBecauseOfLight())
|
if(!HasCarStoppedBecauseOfLight())
|
||||||
PlayCarHorn();
|
PlayCarHorn();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user