summaryrefslogtreecommitdiffstats
path: root/src/vehicles
diff options
context:
space:
mode:
Diffstat (limited to 'src/vehicles')
-rw-r--r--src/vehicles/Automobile.cpp847
-rw-r--r--src/vehicles/Automobile.h3
-rw-r--r--src/vehicles/Bike.cpp2
-rw-r--r--src/vehicles/Boat.cpp2
-rw-r--r--src/vehicles/DamageManager.cpp5
-rw-r--r--src/vehicles/DamageManager.h1
-rw-r--r--src/vehicles/HandlingMgr.cpp83
-rw-r--r--src/vehicles/HandlingMgr.h23
-rw-r--r--src/vehicles/Transmission.cpp120
-rw-r--r--src/vehicles/Transmission.h2
-rw-r--r--src/vehicles/Vehicle.cpp38
-rw-r--r--src/vehicles/Vehicle.h2
12 files changed, 560 insertions, 568 deletions
diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp
index d54c2291..c915f7e2 100644
--- a/src/vehicles/Automobile.cpp
+++ b/src/vehicles/Automobile.cpp
@@ -50,8 +50,6 @@
#include "Automobile.h"
#include "Bike.h"
-//--MIAMI: file done
-
bool bAllCarCheat;
RwObject *GetCurrentAtomicObjectCB(RwObject *object, void *data);
@@ -103,6 +101,8 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
pHandling = mod_HandlingManager.GetHandlingData((tVehicleType)mi->m_handlingId);
pFlyingHandling = mod_HandlingManager.GetFlyingPointer((tVehicleType)mi->m_handlingId);
+ m_fEngineInertiaVar1 = 0.0f;
+ m_fEngineInertiaVar2 = 0.0f;
m_auto_unused1 = 20.0f;
m_auto_unused2 = 0;
@@ -151,7 +151,7 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
m_fMass = pHandling->fMass;
m_fTurnMass = pHandling->fTurnMass;
m_vecCentreOfMass = pHandling->CentreOfMass;
- m_fAirResistance = pHandling->Dimension.x*pHandling->Dimension.z/m_fMass;
+ m_fAirResistance = pHandling->fDragMult > 0.01f ? pHandling->fDragMult*0.0005f : pHandling->fDragMult;
m_fElasticity = 0.05f;
m_fBuoyancy = pHandling->fBuoyancy;
@@ -192,12 +192,6 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
m_fTraction = 1.0f;
m_fTireTemperature = 1.0f;
- CColModel *colModel = mi->GetColModel();
- if(colModel->lines == nil){
- colModel->lines = (CColLine*)RwMalloc(4*sizeof(CColLine));
- colModel->numLines = 4;
- }
-
SetupSuspensionLines();
SetStatus(STATUS_SIMPLE);
@@ -257,6 +251,10 @@ CVector vecDAMAGE_ENGINE_POS_BIG(-0.5f, -0.3f, 0.0f);
void
CAutomobile::ProcessControl(void)
{
+ // TODO(LCS):
+ // TheCamera can remove service vehicles
+ // some audio (?) stuff
+
int i;
float wheelRot;
CColModel *colModel;
@@ -311,7 +309,7 @@ CAutomobile::ProcessControl(void)
if(GetStatus() != STATUS_ABANDONED && GetStatus() != STATUS_WRECKED &&
GetStatus() != STATUS_PLAYER && GetStatus() != STATUS_PLAYER_REMOTE && GetStatus() != STATUS_PLAYER_DISABLED){
switch(GetModelIndex())
- case MI_FBIRANCH:
+ case MI_FBICAR:
case MI_POLICE:
case MI_ENFORCER:
case MI_SECURICA:
@@ -320,16 +318,18 @@ CAutomobile::ProcessControl(void)
ScanForCrimes();
}
+ // TODO(LCS): the fields used by this function are weird
+ ActivateBombWhenEntered();
+
// Process driver
- if(pDriver)
+ if(pDriver){
if(IsUpsideDown() && CanPedEnterCar()){
if(!pDriver->IsPlayer() &&
!(pDriver->m_leader && pDriver->m_leader->bInVehicle) &&
pDriver->CharCreatedBy != MISSION_CHAR)
pDriver->SetObjective(OBJECTIVE_LEAVE_CAR, this);
}
-
- ActivateBombWhenEntered();
+ }
// Process passengers
if(m_nNumPassengers != 0 && IsUpsideDown() && CanPedEnterCar()){
@@ -352,7 +352,7 @@ CAutomobile::ProcessControl(void)
if(strongGrip1 || bCheat3)
m_vecCentreOfMass.z = 0.3f*m_aSuspensionSpringLength[0] + -1.0f*m_fHeightAboveRoad;
else if(pHandling->Flags & HANDLING_NONPLAYER_STABILISER && GetStatus() == STATUS_PHYSICS)
- m_vecCentreOfMass.z = pHandling->CentreOfMass.z - 0.2f*pHandling->Dimension.z;
+ m_vecCentreOfMass.z = pHandling->CentreOfMass.z + (colModel->boundingBox.min.z - pHandling->CentreOfMass.z)*0.4f;
else
m_vecCentreOfMass = pHandling->CentreOfMass;
@@ -372,7 +372,7 @@ CAutomobile::ProcessControl(void)
bool playerRemote = false;
switch(GetStatus()){
case STATUS_PLAYER_REMOTE:
- if(CPad::GetPad(0)->WeaponJustDown() && !bDisableRemoteDetonation){
+ if(CPad::GetPad(0)->CarGunJustDown() && !bDisableRemoteDetonation){
BlowUpCar(FindPlayerPed());
CRemote::TakeRemoteControlledCarFromPlayer();
}
@@ -391,6 +391,7 @@ CAutomobile::ProcessControl(void)
// fall through
case STATUS_PLAYER:
if(playerRemote ||
+ // TODO(LCS): ped state 64
pDriver && pDriver->GetPedState() != PED_EXIT_CAR && pDriver->GetPedState() != PED_DRAG_FROM_CAR && pDriver->GetPedState() != PED_ARRESTED){
// process control input if controlled by player
if(playerRemote || pDriver->m_nPedType == PEDTYPE_PLAYER1)
@@ -416,6 +417,8 @@ CAutomobile::ProcessControl(void)
}else
m_vecCentreOfMass.z = pHandling->CentreOfMass.z;
+ // TODO(LCS): some in air handling?
+
if(bHoverCheat)
DoHoverSuspensionRatios();
@@ -451,8 +454,6 @@ CAutomobile::ProcessControl(void)
m_fBrakePedal = 1.0f;
m_fGasPedal = 0.0f;
}
- if(CPad::GetPad(0)->CarGunJustDown())
- ActivateBomb();
break;
case STATUS_SIMPLE:
@@ -492,7 +493,7 @@ CAutomobile::ProcessControl(void)
m_aSuspensionSpringRatio[1] < 1.0f && CSurfaceTable::GetAdhesionGroup(m_aWheelColPoints[1].surfaceB) == ADHESIVE_SAND ||
m_aSuspensionSpringRatio[2] < 1.0f && CSurfaceTable::GetAdhesionGroup(m_aWheelColPoints[2].surfaceB) == ADHESIVE_SAND ||
m_aSuspensionSpringRatio[3] < 1.0f && CSurfaceTable::GetAdhesionGroup(m_aWheelColPoints[3].surfaceB) == ADHESIVE_SAND){
- if(GetModelIndex() != MI_RCBANDIT && GetModelIndex() != MI_SANDKING && GetModelIndex() != MI_BFINJECT){
+ if(GetModelIndex() != MI_RCBANDIT /*&& GetModelIndex() != MI_SANDKING*/ && GetModelIndex() != MI_BFINJECT){
bStuckInSand = true;
if(CWeather::WetRoads > 0.0f)
ApplyMoveForce(m_vecMoveSpeed * -CTimer::GetTimeStep()*SAND_SLOWDOWN*m_fMass * (1.0f-CWeather::WetRoads));
@@ -527,8 +528,10 @@ CAutomobile::ProcessControl(void)
m_fSteerAngle = 0.0f;
m_fGasPedal = 0.0f;
- if(!IsAlarmOn())
- m_nCarHornTimer = 0;
+ m_nCarHornTimer = 0;
+ // TODO(LCS):
+ // CWeapon::::RemovePlayersRemoteDetonatorForThisVehicle
+ m_pBombRigger = nil;
break;
case STATUS_PLAYER_DISABLED:
@@ -622,14 +625,13 @@ CAutomobile::ProcessControl(void)
// special control
switch(GetModelIndex()){
- case MI_FIRETRUCK:
- FireTruckControl();
- break;
+ // FireTruckControl in PreRender now
case MI_RHINO:
TankControl();
BlowUpCarsInPath();
break;
- case MI_VOODOO:
+ // LCS: this is gone but i'm keeping it!
+ case MI_YARDIE:
HydraulicControl();
break;
default:
@@ -719,7 +721,7 @@ CAutomobile::ProcessControl(void)
ApplyTurnSpeed();
}
bIsInSafePosition = true;
- bIsStuck = false;
+ bIsStuck = false;
}
CPhysical::ProcessControl();
@@ -737,7 +739,8 @@ CAutomobile::ProcessControl(void)
float fwdSpeed = Abs(DotProduct(m_vecMoveSpeed, GetForward()));
CVector contactPoints[4]; // relative to model
CVector contactSpeeds[4]; // speed at contact points
- CVector springDirections[4]; // normalized, in model space
+ CVector springDirections[4]; // normalized, in world space
+ float springForces[4];
for(i = 0; i < 4; i++){
// Set spring under certain circumstances
@@ -761,10 +764,13 @@ CAutomobile::ProcessControl(void)
}
// get points and directions if spring is compressed
+ springDirections[i] = -GetUp(); // springs are always pointing down anyway
if(m_aSuspensionSpringRatio[i] < 1.0f){
contactPoints[i] = m_aWheelColPoints[i].point - GetPosition();
- springDirections[i] = Multiply3x3(GetMatrix(), colModel->lines[i].p1 - colModel->lines[i].p0);
- springDirections[i].Normalise();
+// springDirections[i] = Multiply3x3(GetMatrix(), colModel->lines[i].p1 - colModel->lines[i].p0);
+// springDirections[i].Normalise();
+ }else{
+ contactPoints[i] = CVector(0.0f, 0.0f, 0.0f);
}
}
@@ -777,7 +783,7 @@ CAutomobile::ProcessControl(void)
ApplySpringCollisionAlt(pHandling->fSuspensionForceLevel,
springDirections[i], contactPoints[i],
- m_aSuspensionSpringRatio[i], bias, m_aWheelColPoints[i].normal);
+ m_aSuspensionSpringRatio[i], bias, m_aWheelColPoints[i].normal, springForces[i]);
m_aWheelSkidmarkUnk[i] = false;
if(m_aWheelColPoints[i].surfaceB == SURFACE_GRASS ||
@@ -789,8 +795,8 @@ CAutomobile::ProcessControl(void)
m_aWheelSkidmarkUnk[i] = true;
}else
m_aWheelSkidmarkType[i] = SKIDMARK_NORMAL;
- }else{
- contactPoints[i] = Multiply3x3(GetMatrix(), colModel->lines[i].p1);
+// }else{
+// contactPoints[i] = Multiply3x3(GetMatrix(), colModel->lines[i].p1);
}
}
@@ -812,7 +818,7 @@ CAutomobile::ProcessControl(void)
// dampen springs
for(i = 0; i < 4; i++)
if(m_aSuspensionSpringRatio[i] < 0.99999f)
- ApplySpringDampening(pHandling->fSuspensionDampingLevel,
+ ApplySpringDampening(pHandling->fSuspensionDampingLevel, springForces[i],
springDirections[i], contactPoints[i], contactSpeeds[i]);
// Get speed at contact points again
@@ -825,42 +831,6 @@ CAutomobile::ProcessControl(void)
}
}
- bool gripCheat = true;
- fwdSpeed = DotProduct(m_vecMoveSpeed, GetForward());
- if(!strongGrip1 && !CVehicle::bCheat3)
- gripCheat = false;
- float acceleration = pHandling->Transmission.CalculateDriveAcceleration(m_fGasPedal, m_nCurrentGear, m_fChangeGearTime, fwdSpeed, gripCheat);
- acceleration /= m_fForceMultiplier;
-
- if(IsRealHeli() || IsRealPlane())
- acceleration = 0.0f;
-
- if(bAudioChangingGear && m_fGasPedal > 0.4f && m_fBrakePedal < 0.1f && fwdSpeed > 0.15f &&
- this == FindPlayerVehicle() && TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::MODE_1STPERSON){
- if(GetStatus() == STATUS_PLAYER && !(pHandling->Flags & HANDLING_IS_BUS)){
- if(m_nBusDoorTimerEnd == 0)
- m_nBusDoorTimerEnd = 1000;
- else {
- uint32 timeStepInMs = CTimer::GetTimeStepInMilliseconds();
- if(m_nBusDoorTimerEnd > timeStepInMs)
- m_nBusDoorTimerEnd -= timeStepInMs;
- else
- m_nBusDoorTimerEnd = 0;
- }
- }
-
- if((m_aSuspensionSpringRatio[0] < 1.0f || m_aSuspensionSpringRatio[2] < 1.0f) &&
- (m_aSuspensionSpringRatio[1] < 1.0f || m_aSuspensionSpringRatio[3] < 1.0f))
- ApplyTurnForce(-GRAVITY*Min(m_fTurnMass, 2500.0f)*GetUp(), -1.0f*GetForward());
- }
-
- brake = m_fBrakePedal * pHandling->fBrakeDeceleration * CTimer::GetTimeStep();
- bool neutralHandling = GetStatus() != STATUS_PLAYER && GetStatus() != STATUS_PLAYER_REMOTE && (pHandling->Flags & HANDLING_NEUTRALHANDLING);
- float brakeBiasFront = neutralHandling ? 1.0f : 2.0f*pHandling->fBrakeBias;
- float brakeBiasRear = neutralHandling ? 1.0f : 2.0f-pHandling->fBrakeBias; // looks like a bug, but it was correct in III...
- float tractionBiasFront = neutralHandling ? 1.0f : 2.0f*pHandling->fTractionBias;
- float tractionBiasRear = neutralHandling ? 1.0f : 2.0f-tractionBiasFront;
-
// Count how many wheels are touching the ground
m_nWheelsOnGround = 0;
@@ -891,16 +861,36 @@ CAutomobile::ProcessControl(void)
}
}
+ bool gripCheat = true;
+ fwdSpeed = DotProduct(m_vecMoveSpeed, GetForward());
+ if(!strongGrip1 && !CVehicle::bCheat3)
+ gripCheat = false;
+ float acceleration = pHandling->Transmission.CalculateDriveAcceleration(m_fGasPedal, m_nCurrentGear, m_fChangeGearTime, fwdSpeed,
+ &m_fEngineInertiaVar1, &m_fEngineInertiaVar2, m_nDriveWheelsOnGround, gripCheat);
+ acceleration /= m_fForceMultiplier;
+
+ if(IsRealHeli() || IsRealPlane())
+ acceleration = 0.0f;
+
+ if(Abs(acceleration) > 0.0f)
+ m_fEngineEnergy += Abs(acceleration);
+ else
+ m_fEngineEnergy = 0.0f;
+
float traction;
if(GetStatus() == STATUS_PHYSICS)
traction = 0.004f * m_fTraction;
else
traction = 0.004f;
- traction *= pHandling->fTractionMultiplier / 4.0f;
+ traction *= pHandling->GetTractionMultiplier() / 4.0f;
traction /= m_fForceMultiplier;
if(CVehicle::bCheat3)
traction *= 4.0f;
+ if(FindPlayerVehicle() && FindPlayerVehicle() == this)
+ if(CPad::GetPad(0)->CarGunJustDown())
+ ActivateBomb();
+
if(FindPlayerVehicle() != this && (strongGrip1 || CVehicle::bCheat3)){
traction *= 1.2f;
acceleration *= 1.4f;
@@ -910,448 +900,73 @@ CAutomobile::ProcessControl(void)
}
}
- static float fThrust;
- static tWheelState WheelState[4];
-
- bool rearWheelsFirst = !!(pHandling->Flags & HANDLING_REARWHEEL_1ST);
-
- // Process front wheels on ground - first try
-
- if(!rearWheelsFirst){
- if(m_aWheelTimer[CARWHEEL_FRONT_LEFT] > 0.0f || m_aWheelTimer[CARWHEEL_FRONT_RIGHT] > 0.0f){
- float s = Sin(m_fSteerAngle);
- float c = Cos(m_fSteerAngle);
-
- CVector wheelFwd, wheelRight, tmp;
-
- if(m_aWheelTimer[CARWHEEL_FRONT_LEFT] > 0.0f){
- if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier))
- fThrust = 0.0f;
- else
- fThrust = acceleration;
-
- wheelFwd = GetForward();
- wheelFwd -= DotProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_FRONT_LEFT].normal)*m_aWheelColPoints[CARWHEEL_FRONT_LEFT].normal;
- wheelFwd.Normalise();
- wheelRight = CrossProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_FRONT_LEFT].normal);
- wheelRight.Normalise();
- tmp = c*wheelFwd - s*wheelRight;
- wheelRight = s*wheelFwd + c*wheelRight;
- wheelFwd = tmp;
-
- m_aWheelColPoints[CARWHEEL_FRONT_LEFT].surfaceA = SURFACE_WHEELBASE;
- float adhesion = CSurfaceTable::GetAdhesiveLimit(m_aWheelColPoints[CARWHEEL_FRONT_LEFT])*traction;
- if(GetStatus() == STATUS_PLAYER)
- adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_FRONT_LEFT].surfaceB);
- WheelState[CARWHEEL_FRONT_LEFT] = m_aWheelState[CARWHEEL_FRONT_LEFT];
-
- if(Damage.GetWheelStatus(CARWHEEL_FRONT_LEFT) == WHEEL_STATUS_BURST)
- ProcessWheel(wheelFwd, wheelRight,
- contactSpeeds[CARWHEEL_FRONT_LEFT], contactPoints[CARWHEEL_FRONT_LEFT],
- m_nWheelsOnGround, fThrust,
- brake*brakeBiasFront,
- adhesion*tractionBiasFront*Damage.m_fWheelDamageEffect,
- CARWHEEL_FRONT_LEFT,
- &m_aWheelSpeed[CARWHEEL_FRONT_LEFT],
- &WheelState[CARWHEEL_FRONT_LEFT],
- WHEEL_STATUS_BURST);
- else
- ProcessWheel(wheelFwd, wheelRight,
- contactSpeeds[CARWHEEL_FRONT_LEFT], contactPoints[CARWHEEL_FRONT_LEFT],
- m_nWheelsOnGround, fThrust,
- brake*brakeBiasFront,
- adhesion*tractionBiasFront,
- CARWHEEL_FRONT_LEFT,
- &m_aWheelSpeed[CARWHEEL_FRONT_LEFT],
- &WheelState[CARWHEEL_FRONT_LEFT],
- WHEEL_STATUS_OK);
- }
-
- if(m_aWheelTimer[CARWHEEL_FRONT_RIGHT] > 0.0f){
- if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier))
- fThrust = 0.0f;
- else
- fThrust = acceleration;
-
- wheelFwd = GetForward();
- wheelFwd -= DotProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].normal)*m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].normal;
- wheelFwd.Normalise();
- wheelRight = CrossProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].normal);
- wheelRight.Normalise();
- tmp = c*wheelFwd - s*wheelRight;
- wheelRight = s*wheelFwd + c*wheelRight;
- wheelFwd = tmp;
-
- m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].surfaceA = SURFACE_WHEELBASE;
- float adhesion = CSurfaceTable::GetAdhesiveLimit(m_aWheelColPoints[CARWHEEL_FRONT_RIGHT])*traction;
- if(GetStatus() == STATUS_PLAYER)
- adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].surfaceB);
- WheelState[CARWHEEL_FRONT_RIGHT] = m_aWheelState[CARWHEEL_FRONT_RIGHT];
-
- if(Damage.GetWheelStatus(CARWHEEL_FRONT_RIGHT) == WHEEL_STATUS_BURST)
- ProcessWheel(wheelFwd, wheelRight,
- contactSpeeds[CARWHEEL_FRONT_RIGHT], contactPoints[CARWHEEL_FRONT_RIGHT],
- m_nWheelsOnGround, fThrust,
- brake*brakeBiasFront,
- adhesion*tractionBiasFront*Damage.m_fWheelDamageEffect,
- CARWHEEL_FRONT_RIGHT,
- &m_aWheelSpeed[CARWHEEL_FRONT_RIGHT],
- &WheelState[CARWHEEL_FRONT_RIGHT],
- WHEEL_STATUS_BURST);
- else
- ProcessWheel(wheelFwd, wheelRight,
- contactSpeeds[CARWHEEL_FRONT_RIGHT], contactPoints[CARWHEEL_FRONT_RIGHT],
- m_nWheelsOnGround, fThrust,
- brake*brakeBiasFront,
- adhesion*tractionBiasFront,
- CARWHEEL_FRONT_RIGHT,
- &m_aWheelSpeed[CARWHEEL_FRONT_RIGHT],
- &WheelState[CARWHEEL_FRONT_RIGHT],
- WHEEL_STATUS_OK);
- }
- }
-
- // Process front wheels off ground
-
- if(!IsRealHeli()){
- if(m_aWheelTimer[CARWHEEL_FRONT_LEFT] <= 0.0f){
- if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier) || acceleration == 0.0f)
- m_aWheelSpeed[CARWHEEL_FRONT_LEFT] *= 0.95f;
- else{
- if(acceleration > 0.0f){
- if(m_aWheelSpeed[CARWHEEL_FRONT_LEFT] < 2.0f)
- m_aWheelSpeed[CARWHEEL_FRONT_LEFT] -= 0.2f;
- }else{
- if(m_aWheelSpeed[CARWHEEL_FRONT_LEFT] > -2.0f)
- m_aWheelSpeed[CARWHEEL_FRONT_LEFT] += 0.1f;
- }
- }
- m_aWheelRotation[CARWHEEL_FRONT_LEFT] += m_aWheelSpeed[CARWHEEL_FRONT_LEFT];
- }
- if(m_aWheelTimer[CARWHEEL_FRONT_RIGHT] <= 0.0f){
- if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier) || acceleration == 0.0f)
- m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] *= 0.95f;
- else{
- if(acceleration > 0.0f){
- if(m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] < 2.0f)
- m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] -= 0.2f;
- }else{
- if(m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] > -2.0f)
- m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] += 0.1f;
- }
- }
- m_aWheelRotation[CARWHEEL_FRONT_RIGHT] += m_aWheelSpeed[CARWHEEL_FRONT_RIGHT];
- }
- }
- }
-
- // Process rear wheels
-
- if(m_aWheelTimer[CARWHEEL_REAR_LEFT] > 0.0f || m_aWheelTimer[CARWHEEL_REAR_RIGHT] > 0.0f){
- CVector wheelFwd = GetForward();
- CVector wheelRight = GetRight(); // overwritten for resp. wheel
-
- float rearBrake = brake;
- float rearTraction = traction;
- if(bIsHandbrakeOn){
-#ifdef FIX_BUGS
- // Not sure if this is needed, but brake usually has timestep as a factor
- rearBrake = 20000.0f * CTimer::GetTimeStepFix();
-#else
- rearBrake = 20000.0f;
-#endif
- if(fwdSpeed > 0.1f && pHandling->Flags & HANDLING_HANDBRAKE_TYRE){
- m_fTireTemperature += 0.005*CTimer::GetTimeStep();
- if(m_fTireTemperature > 2.0f)
- m_fTireTemperature = 2.0f;
- }
- }else if(m_doingBurnout && !mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier)){
- rearBrake = 0.0f;
- rearTraction = 0.0f;
- // BUG: missing timestep
- ApplyTurnForce(contactPoints[CARWHEEL_REAR_LEFT], -0.001f*m_fTurnMass*m_fSteerAngle*GetRight());
- }else if(m_fTireTemperature > 1.0f){
- rearTraction *= m_fTireTemperature;
- }
-
- if(m_aWheelTimer[CARWHEEL_REAR_LEFT] > 0.0f){
- if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier))
- fThrust = 0.0f;
- else
- fThrust = acceleration;
-
- wheelFwd -= DotProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_REAR_LEFT].normal)*m_aWheelColPoints[CARWHEEL_REAR_LEFT].normal;
- wheelFwd.Normalise();
- wheelRight = CrossProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_REAR_LEFT].normal);
- wheelRight.Normalise();
-
- m_aWheelColPoints[CARWHEEL_REAR_LEFT].surfaceA = SURFACE_WHEELBASE;
- float adhesion = CSurfaceTable::GetAdhesiveLimit(m_aWheelColPoints[CARWHEEL_REAR_LEFT])*rearTraction;
- if(GetStatus() == STATUS_PLAYER)
- adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_REAR_LEFT].surfaceB);
- WheelState[CARWHEEL_REAR_LEFT] = m_aWheelState[CARWHEEL_REAR_LEFT];
-
- if(Damage.GetWheelStatus(CARWHEEL_REAR_LEFT) == WHEEL_STATUS_BURST)
- ProcessWheel(wheelFwd, wheelRight,
- contactSpeeds[CARWHEEL_REAR_LEFT], contactPoints[CARWHEEL_REAR_LEFT],
- m_nWheelsOnGround, fThrust,
- rearBrake*brakeBiasRear,
- adhesion*tractionBiasRear*Damage.m_fWheelDamageEffect,
- CARWHEEL_REAR_LEFT,
- &m_aWheelSpeed[CARWHEEL_REAR_LEFT],
- &WheelState[CARWHEEL_REAR_LEFT],
- WHEEL_STATUS_BURST);
- else
- ProcessWheel(wheelFwd, wheelRight,
- contactSpeeds[CARWHEEL_REAR_LEFT], contactPoints[CARWHEEL_REAR_LEFT],
- m_nWheelsOnGround, fThrust,
- rearBrake*brakeBiasRear,
- adhesion*tractionBiasRear,
- CARWHEEL_REAR_LEFT,
- &m_aWheelSpeed[CARWHEEL_REAR_LEFT],
- &WheelState[CARWHEEL_REAR_LEFT],
- WHEEL_STATUS_OK);
- }
-
-#ifdef FIX_BUGS
- // Shouldn't we reset these after the left wheel?
- wheelFwd = GetForward();
- wheelRight = GetRight(); // actually useless
-#endif
-
- if(m_aWheelTimer[CARWHEEL_REAR_RIGHT] > 0.0f){
- if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier))
- fThrust = 0.0f;
- else
- fThrust = acceleration;
-
- wheelFwd -= DotProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_REAR_RIGHT].normal)*m_aWheelColPoints[CARWHEEL_REAR_RIGHT].normal;
- wheelFwd.Normalise();
- wheelRight = CrossProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_REAR_RIGHT].normal);
- wheelRight.Normalise();
-
- m_aWheelColPoints[CARWHEEL_REAR_RIGHT].surfaceA = SURFACE_WHEELBASE;
- float adhesion = CSurfaceTable::GetAdhesiveLimit(m_aWheelColPoints[CARWHEEL_REAR_RIGHT])*rearTraction;
- if(GetStatus() == STATUS_PLAYER)
- adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_REAR_RIGHT].surfaceB);
- WheelState[CARWHEEL_REAR_RIGHT] = m_aWheelState[CARWHEEL_REAR_RIGHT];
-
- if(Damage.GetWheelStatus(CARWHEEL_REAR_RIGHT) == WHEEL_STATUS_BURST)
- ProcessWheel(wheelFwd, wheelRight,
- contactSpeeds[CARWHEEL_REAR_RIGHT], contactPoints[CARWHEEL_REAR_RIGHT],
- m_nWheelsOnGround, fThrust,
- rearBrake*brakeBiasRear,
- adhesion*tractionBiasRear*Damage.m_fWheelDamageEffect,
- CARWHEEL_REAR_RIGHT,
- &m_aWheelSpeed[CARWHEEL_REAR_RIGHT],
- &WheelState[CARWHEEL_REAR_RIGHT],
- WHEEL_STATUS_BURST);
- else
- ProcessWheel(wheelFwd, wheelRight,
- contactSpeeds[CARWHEEL_REAR_RIGHT], contactPoints[CARWHEEL_REAR_RIGHT],
- m_nWheelsOnGround, fThrust,
- rearBrake*brakeBiasRear,
- adhesion*tractionBiasRear,
- CARWHEEL_REAR_RIGHT,
- &m_aWheelSpeed[CARWHEEL_REAR_RIGHT],
- &WheelState[CARWHEEL_REAR_RIGHT],
- WHEEL_STATUS_OK);
- }
- }
-
- if(m_doingBurnout && !mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier) &&
- (m_aWheelState[CARWHEEL_REAR_LEFT] == WHEEL_STATE_SPINNING || m_aWheelState[CARWHEEL_REAR_RIGHT] == WHEEL_STATE_SPINNING)){
- m_fTireTemperature += 0.001f*CTimer::GetTimeStep();
- if(m_fTireTemperature > 3.0f)
- m_fTireTemperature = 3.0f;
- }else if(m_fTireTemperature > 1.0f){
- m_fTireTemperature = (m_fTireTemperature - 1.0f)*Pow(0.995f, CTimer::GetTimeStep()) + 1.0f;
- }
-
- // Process rear wheels off ground
-
- if(!IsRealHeli()){
- if(m_aWheelTimer[CARWHEEL_REAR_LEFT] <= 0.0f){
- if(bIsHandbrakeOn)
- m_aWheelSpeed[CARWHEEL_REAR_LEFT] = 0.0f;
- else if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier) || acceleration == 0.0f)
- m_aWheelSpeed[CARWHEEL_REAR_LEFT] *= 0.95f;
- else{
- if(acceleration > 0.0f){
- if(m_aWheelSpeed[CARWHEEL_REAR_LEFT] < 2.0f)
- m_aWheelSpeed[CARWHEEL_REAR_LEFT] -= 0.2f;
- }else{
- if(m_aWheelSpeed[CARWHEEL_REAR_LEFT] > -2.0f)
- m_aWheelSpeed[CARWHEEL_REAR_LEFT] += 0.1f;
- }
- }
- m_aWheelRotation[CARWHEEL_REAR_LEFT] += m_aWheelSpeed[CARWHEEL_REAR_LEFT];
- }
- if(m_aWheelTimer[CARWHEEL_REAR_RIGHT] <= 0.0f){
- if(bIsHandbrakeOn)
- m_aWheelSpeed[CARWHEEL_REAR_RIGHT] = 0.0f;
- else if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier) || acceleration == 0.0f)
- m_aWheelSpeed[CARWHEEL_REAR_RIGHT] *= 0.95f;
- else{
- if(acceleration > 0.0f){
- if(m_aWheelSpeed[CARWHEEL_REAR_RIGHT] < 2.0f)
- m_aWheelSpeed[CARWHEEL_REAR_RIGHT] -= 0.2f;
- }else{
- if(m_aWheelSpeed[CARWHEEL_REAR_RIGHT] > -2.0f)
- m_aWheelSpeed[CARWHEEL_REAR_RIGHT] += 0.1f;
- }
+ // TODO(LCS): where did this go?
+/*
+ if(bAudioChangingGear && m_fGasPedal > 0.4f && m_fBrakePedal < 0.1f && fwdSpeed > 0.15f &&
+ this == FindPlayerVehicle() && TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::MODE_1STPERSON){
+ if(GetStatus() == STATUS_PLAYER && !(pHandling->Flags & HANDLING_IS_BUS)){
+ if(m_nBusDoorTimerEnd == 0)
+ m_nBusDoorTimerEnd = 1000;
+ else {
+ uint32 timeStepInMs = CTimer::GetTimeStepInMilliseconds();
+ if(m_nBusDoorTimerEnd > timeStepInMs)
+ m_nBusDoorTimerEnd -= timeStepInMs;
+ else
+ m_nBusDoorTimerEnd = 0;
}
- m_aWheelRotation[CARWHEEL_REAR_RIGHT] += m_aWheelSpeed[CARWHEEL_REAR_RIGHT];
- }
- }
-
- // Process front wheels on ground - second try
-
- if(rearWheelsFirst){
- if(m_aWheelTimer[CARWHEEL_FRONT_LEFT] > 0.0f || m_aWheelTimer[CARWHEEL_FRONT_RIGHT] > 0.0f){
- float s = Sin(m_fSteerAngle);
- float c = Cos(m_fSteerAngle);
-
- CVector wheelFwd, wheelRight, tmp;
-
- if(m_aWheelTimer[CARWHEEL_FRONT_LEFT] > 0.0f){
- if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier))
- fThrust = 0.0f;
- else
- fThrust = acceleration;
-
- wheelFwd = GetForward();
- wheelFwd -= DotProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_FRONT_LEFT].normal)*m_aWheelColPoints[CARWHEEL_FRONT_LEFT].normal;
- wheelFwd.Normalise();
- wheelRight = CrossProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_FRONT_LEFT].normal);
- wheelRight.Normalise();
- tmp = c*wheelFwd - s*wheelRight;
- wheelRight = s*wheelFwd + c*wheelRight;
- wheelFwd = tmp;
-
- m_aWheelColPoints[CARWHEEL_FRONT_LEFT].surfaceA = SURFACE_WHEELBASE;
- float adhesion = CSurfaceTable::GetAdhesiveLimit(m_aWheelColPoints[CARWHEEL_FRONT_LEFT])*traction;
- if(GetStatus() == STATUS_PLAYER)
- adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_FRONT_LEFT].surfaceB);
- WheelState[CARWHEEL_FRONT_LEFT] = m_aWheelState[CARWHEEL_FRONT_LEFT];
-
- if(Damage.GetWheelStatus(CARWHEEL_FRONT_LEFT) == WHEEL_STATUS_BURST)
- ProcessWheel(wheelFwd, wheelRight,
- contactSpeeds[CARWHEEL_FRONT_LEFT], contactPoints[CARWHEEL_FRONT_LEFT],
- m_nWheelsOnGround, fThrust,
- brake*brakeBiasFront,
- adhesion*tractionBiasFront*Damage.m_fWheelDamageEffect,
- CARWHEEL_FRONT_LEFT,
- &m_aWheelSpeed[CARWHEEL_FRONT_LEFT],
- &WheelState[CARWHEEL_FRONT_LEFT],
- WHEEL_STATUS_BURST);
- else
- ProcessWheel(wheelFwd, wheelRight,
- contactSpeeds[CARWHEEL_FRONT_LEFT], contactPoints[CARWHEEL_FRONT_LEFT],
- m_nWheelsOnGround, fThrust,
- brake*brakeBiasFront,
- adhesion*tractionBiasFront,
- CARWHEEL_FRONT_LEFT,
- &m_aWheelSpeed[CARWHEEL_FRONT_LEFT],
- &WheelState[CARWHEEL_FRONT_LEFT],
- WHEEL_STATUS_OK);
}
- if(m_aWheelTimer[CARWHEEL_FRONT_RIGHT] > 0.0f){
- if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier))
- fThrust = 0.0f;
- else
- fThrust = acceleration;
-
- wheelFwd = GetForward();
- wheelFwd -= DotProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].normal)*m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].normal;
- wheelFwd.Normalise();
- wheelRight = CrossProduct(wheelFwd, m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].normal);
- wheelRight.Normalise();
- tmp = c*wheelFwd - s*wheelRight;
- wheelRight = s*wheelFwd + c*wheelRight;
- wheelFwd = tmp;
-
- m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].surfaceA = SURFACE_WHEELBASE;
- float adhesion = CSurfaceTable::GetAdhesiveLimit(m_aWheelColPoints[CARWHEEL_FRONT_RIGHT])*traction;
- if(GetStatus() == STATUS_PLAYER)
- adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].surfaceB);
- WheelState[CARWHEEL_FRONT_RIGHT] = m_aWheelState[CARWHEEL_FRONT_RIGHT];
-
- if(Damage.GetWheelStatus(CARWHEEL_FRONT_RIGHT) == WHEEL_STATUS_BURST)
- ProcessWheel(wheelFwd, wheelRight,
- contactSpeeds[CARWHEEL_FRONT_RIGHT], contactPoints[CARWHEEL_FRONT_RIGHT],
- m_nWheelsOnGround, fThrust,
- brake*brakeBiasFront,
- adhesion*tractionBiasFront*Damage.m_fWheelDamageEffect,
- CARWHEEL_FRONT_RIGHT,
- &m_aWheelSpeed[CARWHEEL_FRONT_RIGHT],
- &WheelState[CARWHEEL_FRONT_RIGHT],
- WHEEL_STATUS_BURST);
- else
- ProcessWheel(wheelFwd, wheelRight,
- contactSpeeds[CARWHEEL_FRONT_RIGHT], contactPoints[CARWHEEL_FRONT_RIGHT],
- m_nWheelsOnGround, fThrust,
- brake*brakeBiasFront,
- adhesion*tractionBiasFront,
- CARWHEEL_FRONT_RIGHT,
- &m_aWheelSpeed[CARWHEEL_FRONT_RIGHT],
- &WheelState[CARWHEEL_FRONT_RIGHT],
- WHEEL_STATUS_OK);
- }
+ if((m_aSuspensionSpringRatio[0] < 1.0f || m_aSuspensionSpringRatio[2] < 1.0f) &&
+ (m_aSuspensionSpringRatio[1] < 1.0f || m_aSuspensionSpringRatio[3] < 1.0f))
+ ApplyTurnForce(-GRAVITY*Min(m_fTurnMass, 2500.0f)*GetUp(), -1.0f*GetForward());
}
+*/
+
+ float steerRange;
+ if(fwdSpeed > 0.01f && m_aWheelTimer[CARWHEEL_FRONT_LEFT] > 0.0f && m_aWheelTimer[CARWHEEL_FRONT_RIGHT] > 0.0f && GetStatus() == STATUS_PLAYER){
+ CColPoint point;
+ point.surfaceA = SURFACE_WHEELBASE;
+ point.surfaceB = SURFACE_TARMAC;
+ float rightSpeed = DotProduct(m_vecMoveSpeed, GetRight());
+ float adhesion = CSurfaceTable::GetAdhesiveLimit(point);
+ // i have no idea what's going on here
+ float magic = traction * adhesion * 16.0f / SQR(fwdSpeed);
+ magic = clamp(magic, -1.0f, 1.0f);
+ magic = Asin(magic);
+ if(m_fSteerAngle < 0.0f && rightSpeed > 0.05f ||
+ m_fSteerAngle > 0.0f && rightSpeed < -0.05f ||
+ bIsHandbrakeOn)
+ steerRange = 1.0f;
+ else
+ steerRange = Min(magic/DEGTORAD(pHandling->fSteeringLock), 1.0f);
+
+ }else
+ steerRange = 1.0f;
+ m_fSteerAngle *= steerRange;
- // Process front wheels off ground
+ brake = m_fBrakePedal * pHandling->fBrakeDeceleration * CTimer::GetTimeStep();
- if (!IsRealHeli()) {
- if(m_aWheelTimer[CARWHEEL_FRONT_LEFT] <= 0.0f){
- if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier) || acceleration == 0.0f)
- m_aWheelSpeed[CARWHEEL_FRONT_LEFT] *= 0.95f;
- else{
- if(acceleration > 0.0f){
- if(m_aWheelSpeed[CARWHEEL_FRONT_LEFT] < 2.0f)
- m_aWheelSpeed[CARWHEEL_FRONT_LEFT] -= 0.2f;
- }else{
- if(m_aWheelSpeed[CARWHEEL_FRONT_LEFT] > -2.0f)
- m_aWheelSpeed[CARWHEEL_FRONT_LEFT] += 0.1f;
- }
- }
- m_aWheelRotation[CARWHEEL_FRONT_LEFT] += m_aWheelSpeed[CARWHEEL_FRONT_LEFT];
- }
- if(m_aWheelTimer[CARWHEEL_FRONT_RIGHT] <= 0.0f){
- if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier) || acceleration == 0.0f)
- m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] *= 0.95f;
- else{
- if(acceleration > 0.0f){
- if(m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] < 2.0f)
- m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] -= 0.2f;
- }else{
- if(m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] > -2.0f)
- m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] += 0.1f;
- }
- }
- m_aWheelRotation[CARWHEEL_FRONT_RIGHT] += m_aWheelSpeed[CARWHEEL_FRONT_RIGHT];
- }
- }
+ if(pHandling->Flags & HANDLING_REARWHEEL_1ST){
+ ProcessCarWheelPair(CARWHEEL_REAR_LEFT, CARWHEEL_REAR_RIGHT, -999.0f, contactSpeeds, contactPoints,
+ traction, acceleration, brake, false);
+ ProcessCarWheelPair(CARWHEEL_FRONT_LEFT, CARWHEEL_FRONT_RIGHT, m_fSteerAngle, contactSpeeds, contactPoints,
+ traction, acceleration, brake, true);
+ }else{
+ ProcessCarWheelPair(CARWHEEL_FRONT_LEFT, CARWHEEL_FRONT_RIGHT, m_fSteerAngle, contactSpeeds, contactPoints,
+ traction, acceleration, brake, true);
+ ProcessCarWheelPair(CARWHEEL_REAR_LEFT, CARWHEEL_REAR_RIGHT, -999.0f, contactSpeeds, contactPoints,
+ traction, acceleration, brake, false);
}
for(i = 0; i < 4; i++){
float wheelPos = colModel->lines[i].p0.z;
if(m_aSuspensionSpringRatio[i] > 0.0f)
wheelPos -= m_aSuspensionSpringRatio[i]*m_aSuspensionSpringLength[i];
- if(GetModelIndex() == MI_VOODOO && bUsingSpecialColModel)
+ if(GetModelIndex() == MI_YARDIE && bUsingSpecialColModel) // not original LCS
m_aWheelPosition[i] = wheelPos;
else
m_aWheelPosition[i] += (wheelPos - m_aWheelPosition[i])*0.75f;
}
- for(i = 0; i < 4; i++)
- m_aWheelState[i] = WheelState[i];
- if(m_fGasPedal < 0.0f){
- if(m_aWheelState[CARWHEEL_REAR_LEFT] == WHEEL_STATE_SPINNING)
- m_aWheelState[CARWHEEL_REAR_LEFT] = WHEEL_STATE_NORMAL;
- if(m_aWheelState[CARWHEEL_REAR_RIGHT] == WHEEL_STATE_SPINNING)
- m_aWheelState[CARWHEEL_REAR_RIGHT] = WHEEL_STATE_NORMAL;
- }
// Process horn
@@ -1710,6 +1325,207 @@ CAutomobile::ProcessControl(void)
#pragma optimize("", on)
+//--LCS: done
+void
+CAutomobile::ProcessCarWheelPair(int leftWheel, int rightWheel, float steerAngle, CVector *contactSpeeds, CVector *contactPoints, float traction, float acceleration, float brake, bool bFront)
+{
+ bool driveWheels;
+ float suspensionBias;
+
+ if(bFront){
+ driveWheels = mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier);
+ suspensionBias = 2.0f*pHandling->fSuspensionBias;
+ }else{
+ driveWheels = mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier);
+ suspensionBias = 2.0f*(1.0f-pHandling->fSuspensionBias);
+
+ float fwdSpeed = DotProduct(m_vecMoveSpeed, GetForward());
+ if(bIsHandbrakeOn && Abs(fwdSpeed) > 0.1f){
+#ifdef FIX_BUGS
+ // Not sure if this is needed, but brake usually has timestep as a factor
+ brake = 20000.0f * CTimer::GetTimeStepFix();
+#else
+ brake = 20000.0f;
+#endif
+/*
+ if(fwdSpeed > 0.1f && pHandling->Flags & HANDLING_HANDBRAKE_TYRE){
+ m_fTireTemperature += 0.005*CTimer::GetTimeStep();
+ if(m_fTireTemperature > 2.0f)
+ m_fTireTemperature = 2.0f;
+ }
+*/
+ }else if(driveWheels && m_doingBurnout){
+ brake = 0.0f;
+ traction = 0.0f;
+ // BUG: missing timestep
+ ApplyTurnForce(contactPoints[leftWheel], -0.003f*m_fTurnMass*Min(3000.0f/m_fTurnMass, 1.0f)*m_fSteerAngle*GetRight());
+ }else if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier)){
+ traction *= m_fTireTemperature;
+ }
+ }
+
+ // Wheels on ground
+ if(m_aWheelTimer[leftWheel] > 0.0f || m_aWheelTimer[rightWheel] > 0.0f){
+ CVector wheelFwd, wheelRight;
+ float s, c;
+ bool canSteer = steerAngle > -100.0f;
+ if(canSteer){
+ s = Sin(steerAngle);
+ c = Cos(steerAngle);
+ }
+
+ bool neutralHandling = GetStatus() != STATUS_PLAYER && GetStatus() != STATUS_PLAYER_REMOTE && (pHandling->Flags & HANDLING_NEUTRALHANDLING);
+ float brakeBias, tractionBias;
+ if(bFront){
+ brakeBias = neutralHandling ? 1.0f : 2.0f*pHandling->fBrakeBias;
+ tractionBias = neutralHandling ? 1.0f : 2.0f*pHandling->fTractionBias;
+ }else{
+ brakeBias = neutralHandling ? 1.0f : 2.0f*(1.0f-pHandling->fBrakeBias);
+ tractionBias = neutralHandling ? 1.0f : 2.0f*(1.0f-pHandling->fTractionBias);
+ }
+
+ if(m_aWheelTimer[leftWheel] > 0.0f){
+ float fThrust = driveWheels ? acceleration : 0.0f;
+
+ wheelFwd = GetForward();
+ wheelFwd -= DotProduct(wheelFwd, m_aWheelColPoints[leftWheel].normal)*m_aWheelColPoints[leftWheel].normal;
+ wheelFwd.Normalise();
+ wheelRight = CrossProduct(wheelFwd, m_aWheelColPoints[leftWheel].normal);
+ wheelRight.Normalise();
+ if(canSteer){
+ CVector tmp = c*wheelFwd - s*wheelRight;
+ wheelRight = s*wheelFwd + c*wheelRight;
+ wheelFwd = tmp;
+ }
+
+ m_aWheelColPoints[leftWheel].surfaceA = SURFACE_WHEELBASE;
+ float adhesion = CSurfaceTable::GetAdhesiveLimit(m_aWheelColPoints[leftWheel])*traction;
+ if(GetStatus() == STATUS_PLAYER){
+ adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[leftWheel].surfaceB);
+ adhesion *= Min(suspensionBias*pHandling->fSuspensionForceLevel*4.0f*(1.0f-m_aSuspensionSpringRatio[leftWheel]), 2.0f);
+ }
+ tWheelState WheelState = m_aWheelState[leftWheel];
+ if(Damage.GetWheelStatus(leftWheel) == WHEEL_STATUS_BURST)
+ ProcessWheel(wheelFwd, wheelRight,
+ contactSpeeds[leftWheel], contactPoints[leftWheel],
+ m_nWheelsOnGround, fThrust,
+ brake*brakeBias,
+ adhesion*tractionBias*Damage.m_fWheelDamageEffect,
+ leftWheel,
+ &m_aWheelRotation[leftWheel],
+ &WheelState,
+ WHEEL_STATUS_BURST);
+ else
+ ProcessWheel(wheelFwd, wheelRight,
+ contactSpeeds[leftWheel], contactPoints[leftWheel],
+ m_nWheelsOnGround, fThrust,
+ brake*brakeBias,
+ adhesion*tractionBias,
+ leftWheel,
+ &m_aWheelRotation[leftWheel],
+ &WheelState,
+ WHEEL_STATUS_OK);
+
+ if(driveWheels && m_fGasPedal < 0.0f && WheelState == WHEEL_STATE_SPINNING)
+ m_aWheelState[leftWheel] = WHEEL_STATE_NORMAL;
+ else
+ m_aWheelState[leftWheel] = WheelState;
+ }
+
+ if(m_aWheelTimer[rightWheel] > 0.0f){
+ float fThrust = driveWheels ? acceleration : 0.0f;
+
+ wheelFwd = GetForward();
+ wheelFwd -= DotProduct(wheelFwd, m_aWheelColPoints[rightWheel].normal)*m_aWheelColPoints[rightWheel].normal;
+ wheelFwd.Normalise();
+ wheelRight = CrossProduct(wheelFwd, m_aWheelColPoints[rightWheel].normal);
+ wheelRight.Normalise();
+ if(canSteer){
+ CVector tmp = c*wheelFwd - s*wheelRight;
+ wheelRight = s*wheelFwd + c*wheelRight;
+ wheelFwd = tmp;
+ }
+
+ m_aWheelColPoints[rightWheel].surfaceA = SURFACE_WHEELBASE;
+ float adhesion = CSurfaceTable::GetAdhesiveLimit(m_aWheelColPoints[rightWheel])*traction;
+ if(GetStatus() == STATUS_PLAYER){
+ adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[rightWheel].surfaceB);
+ adhesion *= Min(suspensionBias*pHandling->fSuspensionForceLevel*4.0f*(1.0f-m_aSuspensionSpringRatio[rightWheel]), 2.0f);
+ }
+ tWheelState WheelState = m_aWheelState[rightWheel];
+ if(Damage.GetWheelStatus(rightWheel) == WHEEL_STATUS_BURST)
+ ProcessWheel(wheelFwd, wheelRight,
+ contactSpeeds[rightWheel], contactPoints[rightWheel],
+ m_nWheelsOnGround, fThrust,
+ brake*brakeBias,
+ adhesion*tractionBias*Damage.m_fWheelDamageEffect,
+ rightWheel,
+ &m_aWheelRotation[rightWheel],
+ &WheelState,
+ WHEEL_STATUS_BURST);
+ else
+ ProcessWheel(wheelFwd, wheelRight,
+ contactSpeeds[rightWheel], contactPoints[rightWheel],
+ m_nWheelsOnGround, fThrust,
+ brake*brakeBias,
+ adhesion*tractionBias,
+ rightWheel,
+ &m_aWheelRotation[rightWheel],
+ &WheelState,
+ WHEEL_STATUS_OK);
+
+ if(driveWheels && m_fGasPedal < 0.0f && WheelState == WHEEL_STATE_SPINNING)
+ m_aWheelState[rightWheel] = WHEEL_STATE_NORMAL;
+ else
+ m_aWheelState[rightWheel] = WheelState;
+ }
+ }
+
+ if(!bFront){
+ if(m_doingBurnout && driveWheels &&
+ (m_aWheelState[CARWHEEL_REAR_LEFT] == WHEEL_STATE_SPINNING || m_aWheelState[CARWHEEL_REAR_RIGHT] == WHEEL_STATE_SPINNING)){
+ m_fTireTemperature += 0.001f*CTimer::GetTimeStep();
+ if(m_fTireTemperature > 3.0f)
+ m_fTireTemperature = 3.0f;
+ }else if(m_fTireTemperature > 1.0f){
+ m_fTireTemperature = (m_fTireTemperature - 1.0f)*Pow(0.995f, CTimer::GetTimeStep()) + 1.0f;
+ }
+ }
+
+ // Process wheels off ground
+
+ if(!IsRealHeli()){
+ if(m_aWheelTimer[leftWheel] <= 0.0f){
+ if(driveWheels && acceleration != 0.0f){
+ if(acceleration > 0.0f){
+ if(m_aWheelSpeed[leftWheel] < 1.0f)
+ m_aWheelSpeed[leftWheel] -= 0.1f;
+ }else{
+ if(m_aWheelSpeed[leftWheel] > -1.0f)
+ m_aWheelSpeed[leftWheel] += 0.05f;
+ }
+ }else{
+ m_aWheelSpeed[leftWheel] *= 0.95f;
+ }
+ m_aWheelRotation[leftWheel] += m_aWheelSpeed[leftWheel]*CTimer::GetTimeStep();
+ }
+ if(m_aWheelTimer[rightWheel] <= 0.0f){
+ if(driveWheels && acceleration != 0.0f){
+ if(acceleration > 0.0f){
+ if(m_aWheelSpeed[rightWheel] < 1.0f)
+ m_aWheelSpeed[rightWheel] -= 0.1f;
+ }else{
+ if(m_aWheelSpeed[rightWheel] > -1.0f)
+ m_aWheelSpeed[rightWheel] += 0.05f;
+ }
+ }else{
+ m_aWheelSpeed[rightWheel] *= 0.95f;
+ }
+ m_aWheelRotation[rightWheel] += m_aWheelSpeed[rightWheel]*CTimer::GetTimeStep();
+ }
+ }
+}
+
void
CAutomobile::Teleport(CVector pos)
{
@@ -1731,6 +1547,11 @@ CAutomobile::PreRender(void)
int i, j, n;
CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
+ if(GetModelIndex() == MI_FIRETRUCK)
+ FireTruckControl();
+
+ CVehicle::PreRender();
+
if(GetModelIndex() == MI_RHINO && m_aCarNodes[CAR_WINDSCREEN]){
// Rotate Rhino turret
CMatrix m;
@@ -3011,6 +2832,7 @@ CAutomobile::Render(void)
CEntity::Render();
}
+//--LCS: done
int32
CAutomobile::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints)
{
@@ -3082,9 +2904,13 @@ static float fMouseCentreRange = 0.35f;
static float fMouseSteerSens = -0.0035f;
static float fMouseCentreMult = 0.975f;
+//--LCS: done except TODO
void
CAutomobile::ProcessControlInputs(uint8 pad)
{
+ if(this == FindPlayerVehicle() && CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle)
+ return;
+
float speed = DotProduct(m_vecMoveSpeed, GetForward());
if(!CPad::GetPad(pad)->GetExitVehicle() ||
@@ -3095,6 +2921,7 @@ CAutomobile::ProcessControlInputs(uint8 pad)
bIsHandbrakeOn = true;
// Steer left/right
+#if 0 // LCS: removed, need mouse for free cam
if(CCamera::m_bUseMouse3rdPerson && !CVehicle::m_bDisableMouseSteering){
if(CPad::GetPad(pad)->GetMouseX() != 0.0f){
m_fSteerInput += fMouseSteerSens*CPad::GetPad(pad)->GetMouseX();
@@ -3107,7 +2934,9 @@ CAutomobile::ProcessControlInputs(uint8 pad)
0.2f*CTimer::GetTimeStep();
nLastControlInput = 0;
}
- }else{
+ }else
+#endif
+ {
m_fSteerInput += (-CPad::GetPad(pad)->GetSteeringLeftRight()/128.0f - m_fSteerInput)*
0.2f*CTimer::GetTimeStep();
nLastControlInput = 0;
@@ -3200,6 +3029,7 @@ CAutomobile::ProcessControlInputs(uint8 pad)
// Brake if player isn't in control
// BUG: game always uses pad 0 here
+ // TODO(LCS): more conditions here
#ifdef FIX_BUGS
if(CPad::GetPad(pad)->ArePlayerControlsDisabled()){
#else
@@ -3922,6 +3752,7 @@ CAutomobile::DoDriveByShootings(void)
}
}
+//--LCS: done
void
CAutomobile::DoHoverSuspensionRatios(void)
{
@@ -5018,6 +4849,7 @@ CAutomobile::ResetSuspension(void)
}
}
+//--LCS: done
void
CAutomobile::SetupSuspensionLines(void)
{
@@ -5026,6 +4858,14 @@ CAutomobile::SetupSuspensionLines(void)
CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
CColModel *colModel = mi->GetColModel();
+ bool adjustColModel;
+ if(colModel->lines == nil){
+ adjustColModel = true;
+ colModel->lines = new CColLine[4];
+ colModel->numLines = 4;
+ }else
+ adjustColModel = false;
+
// Each suspension line starts at the uppermost wheel position
// and extends down to the lowermost point on the tyre
for(i = 0; i < 4; i++){
@@ -5065,6 +4905,21 @@ CAutomobile::SetupSuspensionLines(void)
for(i = 0; i < colModel->numSpheres; i++)
colModel->spheres[i].radius = 0.3f;
}
+
+ if(pHandling->Flags & HANDLING_FORCE_GRND_CLR && adjustColModel){
+ // 0.25 is the min distance between ground and col spheres, everything above it is safe
+ float safePos = 0.25f - m_fHeightAboveRoad;
+ for(i = 0; i < colModel->numSpheres; i++){
+ CColSphere *sph = &colModel->spheres[i];
+ if(sph->center.z - sph->radius < safePos){
+ // sphere extends too far down, so move it up
+ // or decrease the radius for bigger spheres
+ if(radius > 0.4f)
+ sph->radius = Max(sph->center.z - safePos, 0.4f);
+ sph->center.z = safePos + sph->radius;
+ }
+ }
+ }
}
// called on police cars
diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h
index 16d86917..4f4ab500 100644
--- a/src/vehicles/Automobile.h
+++ b/src/vehicles/Automobile.h
@@ -26,6 +26,8 @@ public:
float m_aSuspensionSpringRatioPrev[4];
float m_aWheelTimer[4]; // set to 4.0 when wheel is touching ground, then decremented
float m_auto_unused1;
+ float m_fEngineInertiaVar1;
+ float m_fEngineInertiaVar2;
eSkidmarkType m_aWheelSkidmarkType[4];
bool m_aWheelSkidmarkBloody[4];
bool m_aWheelSkidmarkUnk[4];
@@ -114,6 +116,7 @@ public:
float GetHeightAboveRoad(void);
void PlayCarHorn(void);
+ void ProcessCarWheelPair(int leftWheel, int rightWheel, float steerAngle, CVector *contactSpeeds, CVector *contactPoints, float traction, float acceleration, float brake, bool bFront);
void FireTruckControl(void);
void TankControl(void);
void HydraulicControl(void);
diff --git a/src/vehicles/Bike.cpp b/src/vehicles/Bike.cpp
index 293cf58e..6d70c22a 100644
--- a/src/vehicles/Bike.cpp
+++ b/src/vehicles/Bike.cpp
@@ -111,7 +111,7 @@ CBike::CBike(int32 id, uint8 CreatedBy)
m_fTurnMass = pHandling->fTurnMass;
m_vecCentreOfMass = pHandling->CentreOfMass;
m_vecCentreOfMass.z = 0.1f;
- m_fAirResistance = pHandling->Dimension.x*pHandling->Dimension.z/m_fMass;
+ m_fAirResistance = pHandling->fDragMult > 0.01f ? pHandling->fDragMult*0.0005f : pHandling->fDragMult;
m_fElasticity = 0.05f;
m_fBuoyancy = pHandling->fBuoyancy;
diff --git a/src/vehicles/Boat.cpp b/src/vehicles/Boat.cpp
index e3bcf096..e97bfa0d 100644
--- a/src/vehicles/Boat.cpp
+++ b/src/vehicles/Boat.cpp
@@ -72,7 +72,7 @@ CBoat::CBoat(int mi, uint8 owner) : CVehicle(owner)
m_fMass = pHandling->fMass;
m_fTurnMass = pHandling->fTurnMass / 2.0f;
m_vecCentreOfMass = pHandling->CentreOfMass;
- m_fAirResistance = pHandling->Dimension.x * pHandling->Dimension.z / m_fMass;
+ m_fAirResistance = pHandling->fDragMult > 0.01f ? pHandling->fDragMult*0.0005f : pHandling->fDragMult;
m_fElasticity = 0.1f;
m_fBuoyancy = pHandling->fBuoyancy;
m_fSteerAngle = 0.0f;
diff --git a/src/vehicles/DamageManager.cpp b/src/vehicles/DamageManager.cpp
index 8ba235b7..b74e7086 100644
--- a/src/vehicles/DamageManager.cpp
+++ b/src/vehicles/DamageManager.cpp
@@ -10,7 +10,8 @@ float G_aComponentDamage[] = { 2.5f, 1.25f, 3.2f, 1.4f, 2.5f, 2.8f, 0.5f };
CDamageManager::CDamageManager(void)
{
ResetDamageStatus();
- m_fWheelDamageEffect = 0.5f;
+ m_fWheelDamageEffect = 0.65f;
+ m_bSmashedDoorDoesntClose = false;
field_18 = 1;
}
@@ -136,6 +137,8 @@ void
CDamageManager::SetDoorStatus(int32 door, uint32 status)
{
m_doorStatus[door] = status;
+ if(m_bSmashedDoorDoesntClose && door != DOOR_BONNET && status == DOOR_STATUS_SMASHED)
+ m_doorStatus[door] = DOOR_STATUS_SWINGING;
}
int32
diff --git a/src/vehicles/DamageManager.h b/src/vehicles/DamageManager.h
index 312006e3..1f836429 100644
--- a/src/vehicles/DamageManager.h
+++ b/src/vehicles/DamageManager.h
@@ -81,6 +81,7 @@ class CDamageManager
public:
float m_fWheelDamageEffect;
+ bool m_bSmashedDoorDoesntClose;
uint8 m_engineStatus;
uint8 m_wheelStatus[4];
uint8 m_doorStatus[6];
diff --git a/src/vehicles/HandlingMgr.cpp b/src/vehicles/HandlingMgr.cpp
index 040b6972..1a8d059c 100644
--- a/src/vehicles/HandlingMgr.cpp
+++ b/src/vehicles/HandlingMgr.cpp
@@ -115,18 +115,17 @@ void
cHandlingDataMgr::LoadHandlingData(void)
{
char *start, *end;
- char line[201]; // weird value
+ char line[300];
char delim[4]; // not sure
char *word;
int field, handlingId;
- int keepGoing;
tHandlingData *handling;
tFlyingHandlingData *flyingHandling;
tBoatHandlingData *boatHandling;
tBikeHandlingData *bikeHandling;
CFileMgr::SetDir("DATA");
- CFileMgr::LoadFile(HandlingFilename, work_buff, sizeof(work_buff), "r");
+ ssize_t filesz = CFileMgr::LoadFile(HandlingFilename, work_buff, sizeof(work_buff), "r");
CFileMgr::SetDir("");
start = (char*)work_buff;
@@ -135,21 +134,18 @@ cHandlingDataMgr::LoadHandlingData(void)
flyingHandling = nil;
boatHandling = nil;
bikeHandling = nil;
- keepGoing = 1;
- while(keepGoing){
+ while(start < (char*)&work_buff[filesz]){
// find end of line
while(*end != '\n') end++;
// get line
strncpy(line, start, end - start);
line[end - start] = '\0';
- start = end+1;
- end = start+1;
// yeah, this is kinda crappy
if(strcmp(line, ";the end") == 0)
- keepGoing = 0;
+ break;
else if(line[0] != ';'){
if(line[0] == '!'){
// Bike data
@@ -263,19 +259,19 @@ cHandlingDataMgr::LoadHandlingData(void)
handling->nIdentifier = (tVehicleType)handlingId;
break;
case 1: handling->fMass = atof(word); break;
- case 2: handling->Dimension.x = atof(word); break;
- case 3: handling->Dimension.y = atof(word); break;
- case 4: handling->Dimension.z = atof(word); break;
- case 5: handling->CentreOfMass.x = atof(word); break;
- case 6: handling->CentreOfMass.y = atof(word); break;
- case 7: handling->CentreOfMass.z = atof(word); break;
- case 8: handling->nPercentSubmerged = atoi(word); break;
- case 9: handling->fTractionMultiplier = atof(word); break;
- case 10: handling->fTractionLoss = atof(word); break;
- case 11: handling->fTractionBias = atof(word); break;
- case 12: handling->Transmission.nNumberOfGears = atoi(word); break;
- case 13: handling->Transmission.fMaxVelocity = atof(word); break;
- case 14: handling->Transmission.fEngineAcceleration = atof(word) * 0.4; break;
+ case 2: handling->fTurnMass = atof(word); break;
+ case 3: handling->fDragMult = atof(word); break;
+ case 4: handling->CentreOfMass.x = atof(word); break;
+ case 5: handling->CentreOfMass.y = atof(word); break;
+ case 6: handling->CentreOfMass.z = atof(word); break;
+ case 7: handling->nPercentSubmerged = atoi(word); break;
+ case 8: handling->fTractionMultiplier = atof(word); break;
+ case 9: handling->fTractionLoss = atof(word); break;
+ case 10: handling->fTractionBias = atof(word); break;
+ case 11: handling->Transmission.nNumberOfGears = atoi(word); break;
+ case 12: handling->Transmission.fMaxVelocity = atof(word); break;
+ case 13: handling->Transmission.fEngineAcceleration = atof(word) * 0.4; break;
+ case 14: handling->Transmission.fEngineInertia = atof(word); break;
case 15: handling->Transmission.nDriveType = word[0]; break;
case 16: handling->Transmission.nEngineType = word[0]; break;
case 17: handling->fBrakeDeceleration = atof(word); break;
@@ -284,25 +280,28 @@ cHandlingDataMgr::LoadHandlingData(void)
case 20: handling->fSteeringLock = atof(word); break;
case 21: handling->fSuspensionForceLevel = atof(word); break;
case 22: handling->fSuspensionDampingLevel = atof(word); break;
- case 23: handling->fSeatOffsetDistance = atof(word); break;
- case 24: handling->fCollisionDamageMultiplier = atof(word); break;
- case 25: handling->nMonetaryValue = atoi(word); break;
- case 26: handling->fSuspensionUpperLimit = atof(word); break;
- case 27: handling->fSuspensionLowerLimit = atof(word); break;
- case 28: handling->fSuspensionBias = atof(word); break;
- case 29: handling->fSuspensionAntidiveMultiplier = atof(word); break;
- case 30:
+ // case 23: // fSuspensionHighSpdComDamp unused
+ case 24: handling->fSuspensionUpperLimit = atof(word); break;
+ case 25: handling->fSuspensionLowerLimit = atof(word); break;
+ case 26: handling->fSuspensionBias = atof(word); break;
+ case 27: handling->fSuspensionAntidiveMultiplier = atof(word); break;
+ case 28: handling->fSeatOffsetDistance = atof(word); break;
+ case 29: handling->fCollisionDamageMultiplier = atof(word); break;
+ case 30: handling->nMonetaryValue = atoi(word); break;
+ case 31:
sscanf(word, "%x", &handling->Flags);
- handling->Transmission.Flags = handling->Flags;
+ // handling->Transmission.Flags = handling->Flags;
break;
- case 31: handling->FrontLights = atoi(word); break;
- case 32: handling->RearLights = atoi(word); break;
+ case 32: handling->FrontLights = atoi(word); break;
+ case 33: handling->RearLights = atoi(word); break;
}
field++;
}
ConvertDataToGameUnits(handling);
}
}
+ start = end+1;
+ end = start+1;
}
}
@@ -330,12 +329,9 @@ cHandlingDataMgr::ConvertDataToGameUnits(tHandlingData *handling)
handling->Transmission.fEngineAcceleration *= 1.0f/(50.0f*50.0f);
handling->Transmission.fMaxVelocity *= 1000.0f/(60.0f*60.0f * 50.0f);
handling->fBrakeDeceleration *= 1.0f/(50.0f*50.0f);
- handling->fTurnMass = (sq(handling->Dimension.x) + sq(handling->Dimension.y)) * handling->fMass / 12.0f;
- if(handling->fTurnMass < 10.0f)
- handling->fTurnMass *= 5.0f;
- handling->fInvMass = 1.0f/handling->fMass;
- handling->fCollisionDamageMultiplier *= 2000.0f/handling->fMass;
- handling->fBuoyancy = 100.0f/handling->nPercentSubmerged * GRAVITY*handling->fMass;
+ handling->fInvMass = 1.0f/handling->GetMass();
+ handling->fCollisionDamageMultiplier = handling->GetCollisionDamageMultiplier() * 2000.0f/handling->GetMass();
+ handling->fBuoyancy = 100.0f/handling->nPercentSubmerged * GRAVITY*handling->GetMass();
// Don't quite understand this. What seems to be going on is that
// we calculate a drag (air resistance) deceleration for a given velocity and
@@ -348,10 +344,13 @@ cHandlingDataMgr::ConvertDataToGameUnits(tHandlingData *handling)
velocity -= 0.01f;
// what's the 1/6?
a = handling->Transmission.fEngineAcceleration/6.0f;
- // no density or drag coefficient here...
- float a_drag = 0.5f*SQR(velocity) * handling->Dimension.x*handling->Dimension.z / handling->fMass;
- // can't make sense of this... maybe v - v/(drag + 1) ? but that doesn't make so much sense either
- b = -velocity * (1.0f/(a_drag + 1.0f) - 1.0f);
+ // no idea what's happening here
+ float drag;
+ if(handling->fDragMult < 0.01f)
+ drag = 1.0f - 1.0f/(SQR(velocity)*handling->fDragMult + 1.0f);
+ else
+ drag = 0.0005f*handling->fDragMult * velocity;
+ b = velocity * drag;
}
if(handling->nIdentifier == HANDLING_RCBANDIT){
diff --git a/src/vehicles/HandlingMgr.h b/src/vehicles/HandlingMgr.h
index e6b5236f..2d49761c 100644
--- a/src/vehicles/HandlingMgr.h
+++ b/src/vehicles/HandlingMgr.h
@@ -93,7 +93,7 @@ enum tVehicleType
NUMBIKEHANDLINGS = HANDLING_FREEWAY+1 - HANDLING_BIKE,
NUMFLYINGHANDLINGS = HANDLING_RCCOPTER+1 - HANDLING_MAVERICK,
- NUMBOATHANDLINGS = HANDLING_COASTMAV+1 - HANDLING_PREDATOR,
+ NUMBOATHANDLINGS = HANDLING_REEFER+1 - HANDLING_PREDATOR,
};
enum tField // most likely a handling field enum, never used so :shrug:
@@ -131,19 +131,21 @@ enum
HANDLING_NARROW_FRONTW = 0x2000000,
HANDLING_GOOD_INSAND = 0x4000000,
HANDLING_UNKNOWN = 0x8000000, // something for helis and planes
+ HANDLING_FORCE_GRND_CLR = 0x10000000
};
struct tHandlingData
{
- tVehicleType nIdentifier;
float fMass;
- float fInvMass;
float fTurnMass;
- CVector Dimension;
+ float fTractionMultiplier;
+ float fCollisionDamageMultiplier;
+ tVehicleType nIdentifier;
+ float fInvMass;
+ float fDragMult;
CVector CentreOfMass;
int8 nPercentSubmerged;
float fBuoyancy;
- float fTractionMultiplier;
cTransmission Transmission;
float fBrakeDeceleration;
float fBrakeBias;
@@ -158,12 +160,17 @@ struct tHandlingData
float fSuspensionLowerLimit;
float fSuspensionBias;
float fSuspensionAntidiveMultiplier;
- float fCollisionDamageMultiplier;
uint32 Flags;
float fSeatOffsetDistance;
int32 nMonetaryValue;
int8 FrontLights;
int8 RearLights;
+ int unk[4];
+
+ float GetMass(void) const { return fMass; }
+ float GetTurnMass(void) const { return fTurnMass; }
+ float GetTractionMultiplier(void) const { return fTractionMultiplier; }
+ float GetCollisionDamageMultiplier(void) const { return fCollisionDamageMultiplier; }
};
struct tBikeHandlingData
@@ -249,7 +256,7 @@ public:
tBikeHandlingData *GetBikePointer(uint8 id) { return &BikeHandlingData[id-HANDLING_BIKE]; }
tFlyingHandlingData *GetFlyingPointer(uint8 id);
tBoatHandlingData *GetBoatPointer(uint8 id);
- bool HasRearWheelDrive(tVehicleType id) { return HandlingData[id].Transmission.nDriveType == 'R'; }
- bool HasFrontWheelDrive(tVehicleType id) { return HandlingData[id].Transmission.nDriveType == 'F'; }
+ bool HasRearWheelDrive(tVehicleType id) { return HandlingData[id].Transmission.nDriveType != 'F'; }
+ bool HasFrontWheelDrive(tVehicleType id) { return HandlingData[id].Transmission.nDriveType != 'R'; }
};
extern cHandlingDataMgr mod_HandlingManager;
diff --git a/src/vehicles/Transmission.cpp b/src/vehicles/Transmission.cpp
index b3e1af7d..ce4b97f4 100644
--- a/src/vehicles/Transmission.cpp
+++ b/src/vehicles/Transmission.cpp
@@ -4,7 +4,7 @@
#include "HandlingMgr.h"
#include "Transmission.h"
-//--MIAMI: done
+//--LCS: file done
void
cTransmission::InitGearRatios(void)
@@ -16,11 +16,14 @@ cTransmission::InitGearRatios(void)
memset(Gears, 0, sizeof(Gears));
+ float baseVelocity = 0.5f*fMaxVelocity / nNumberOfGears;
+ float step = (fMaxVelocity - baseVelocity) / nNumberOfGears;
+
for(i = 1; i <= nNumberOfGears; i++){
pGearRatio0 = &Gears[i-1];
pGearRatio1 = &Gears[i];
- pGearRatio1->fMaxVelocity = (float)i / nNumberOfGears * fMaxVelocity;
+ pGearRatio1->fMaxVelocity = baseVelocity + i*step;
velocityDiff = pGearRatio1->fMaxVelocity - pGearRatio0->fMaxVelocity;
@@ -47,9 +50,12 @@ cTransmission::CalculateGearForSimpleCar(float speed, uint8 &gear)
pGearRatio = &Gears[gear];
fCurVelocity = speed;
- if(speed > pGearRatio->fShiftUpVelocity)
- gear++;
- else if(speed < pGearRatio->fShiftDownVelocity){
+ if(speed > pGearRatio->fShiftUpVelocity){
+ if(gear + 1 > nNumberOfGears)
+ gear = nNumberOfGears;
+ else
+ gear++;
+ }else if(speed < pGearRatio->fShiftDownVelocity){
if(gear - 1 < 0)
gear = 0;
else
@@ -57,6 +63,110 @@ cTransmission::CalculateGearForSimpleCar(float speed, uint8 &gear)
}
}
+float TRANSMISSION_NITROS_INERTIA_MULT = 0.5f;
+float TRANSMISSION_AI_CHEAT_INERTIA_MULT = 0.75f;
+float TRANSMISSION_NITROS_MULT = 2.0f;
+float TRANSMISSION_AI_CHEAT_MULT = 1.2f;
+float TRANSMISSION_SMOOTHER_FRAC = 0.85f;
+float TRANSMISSION_FREE_ACCELERATION = 0.1f;
+
+//--LCS: done
+float
+cTransmission::CalculateDriveAcceleration(const float &gasPedal, uint8 &gear, float &time, const float &velocity, float *inertiaVar1, float *inertiaVar2, uint8 nDriveWheels, uint8 cheat)
+{
+ static float fAcceleration = 0.0f;
+ static float fVelocity;
+ static float fCheat;
+ static tGear *pGearRatio;
+
+ fVelocity = velocity;
+ if(fVelocity < fMaxReverseVelocity)
+ return 0.0f;
+ if(fVelocity > fMaxVelocity)
+ return 0.0f;
+ fCurVelocity = fVelocity;
+
+ assert(gear <= nNumberOfGears);
+
+ pGearRatio = &Gears[gear];
+ if(fVelocity > pGearRatio->fShiftUpVelocity){
+ if(gear != 0 || gasPedal > 0.0f){
+ gear++;
+ return CalculateDriveAcceleration(gasPedal, gear, time, fVelocity, nil, nil, 0, false);
+ }
+ }else if(fVelocity < pGearRatio->fShiftDownVelocity && gear != 0){
+ if(gear != 1 || gasPedal < 0.0f){
+ gear--;
+ return CalculateDriveAcceleration(gasPedal, gear, time, fVelocity, nil, nil, 0, false);
+ }
+ }
+
+ float accelMul;
+
+ if(nNumberOfGears == 1){
+ accelMul = 1.0f;
+ }else if(gear == 0){
+ accelMul = 4.5f;
+ }else{
+ float f = 1.0f - (gear-1.0f)/(nNumberOfGears-1.0f);
+ if(Flags & HANDLING_1G_BOOST)
+ accelMul = SQR(f)*5.0f + 1.0f;
+ else if(Flags & HANDLING_2G_BOOST)
+ accelMul = SQR(f)*4.0f + 1.0f;
+ else
+ accelMul = SQR(f)*3.0f + 1.0f;
+ }
+
+ fCheat = 1.0f;
+ float nitroMult = 1.0f;
+ if(cheat == 1)
+ fCheat = TRANSMISSION_AI_CHEAT_MULT;
+ else if(cheat == 2)
+ nitroMult = TRANSMISSION_NITROS_MULT;
+
+ fAcceleration = fEngineAcceleration*CTimer::GetTimeStep()*0.4f*accelMul*gasPedal*fCheat*nitroMult;
+
+ if(inertiaVar1 != nil && inertiaVar2 != nil){
+ if(nDriveWheels == 0){
+ float f = TRANSMISSION_FREE_ACCELERATION*CTimer::GetTimeStep()*Abs(gasPedal)/fEngineInertia;
+ *inertiaVar1 = Min(*inertiaVar1 + f, 1.0f);
+ *inertiaVar2 = 0.1f;
+ }else{
+ float var1;
+ // What is being calculated here?
+ // TODO: find better names for the inertia vars
+ if(gear == 0){
+ var1 = ((fMaxVelocity/nNumberOfGears)*(1.0f-0.6667f) - fVelocity) /
+ ((fMaxVelocity/nNumberOfGears)*(1.0f-0.6667f) - Gears[gear].fShiftDownVelocity);
+ }else if(gear == 1){
+ var1 = ((fMaxVelocity/nNumberOfGears)*(1.0f-0.6667f) + fVelocity) /
+ ((fMaxVelocity/nNumberOfGears)*(1.0f-0.6667f) + Gears[gear].fShiftUpVelocity);
+ }else{
+ var1 = (fVelocity - Gears[gear].fShiftDownVelocity) /
+ (Gears[gear].fShiftUpVelocity - Gears[gear].fShiftDownVelocity);
+ }
+ float inertiaMult = var1 - *inertiaVar1;
+ if(cheat == 1)
+ inertiaMult *= TRANSMISSION_AI_CHEAT_INERTIA_MULT;
+ else if(cheat == 2)
+ inertiaMult *= TRANSMISSION_NITROS_INERTIA_MULT;
+ float var2target = 1.0f - inertiaMult*fEngineInertia;
+ var2target = clamp(var2target, 0.1f, 1.0f);
+ *inertiaVar2 = (1.0f-TRANSMISSION_SMOOTHER_FRAC)*var2target + TRANSMISSION_SMOOTHER_FRAC*(*inertiaVar2);
+ *inertiaVar1 = var1;
+ fAcceleration *= *inertiaVar2;
+ }
+ }
+
+ float targetVelocity = Gears[gear].fMaxVelocity*fCheat;
+ if(Gears[gear].fMaxVelocity < 0.0f && targetVelocity > fVelocity)
+ fAcceleration *= 1.0f - Min((targetVelocity - fVelocity)/0.05f, 1.0f);
+ else if(Gears[gear].fMaxVelocity > 0.0f && targetVelocity < fVelocity)
+ fAcceleration *= 1.0f - Min((fVelocity - targetVelocity)/0.05f, 1.0f);
+ return fAcceleration;
+}
+
+// TEMP old VC code until we have bikes
float
cTransmission::CalculateDriveAcceleration(const float &gasPedal, uint8 &gear, float &time, const float &velocity, bool cheat)
{
diff --git a/src/vehicles/Transmission.h b/src/vehicles/Transmission.h
index a3d15513..8aea7b02 100644
--- a/src/vehicles/Transmission.h
+++ b/src/vehicles/Transmission.h
@@ -17,6 +17,7 @@ public:
int8 nNumberOfGears;
uint8 Flags;
float fEngineAcceleration;
+ float fEngineInertia;
float fMaxVelocity;
float fMaxCruiseVelocity;
float fMaxReverseVelocity;
@@ -24,5 +25,6 @@ public:
void InitGearRatios(void);
void CalculateGearForSimpleCar(float speed, uint8 &gear);
+ float CalculateDriveAcceleration(const float &gasPedal, uint8 &gear, float &time, const float &velocity, float *inertiaVar1, float *inertiaVar2, uint8 nDriveWheels, uint8 cheat);
float CalculateDriveAcceleration(const float &gasPedal, uint8 &gear, float &time, const float &velocity, bool cheat);
};
diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp
index 145611b1..2625ab78 100644
--- a/src/vehicles/Vehicle.cpp
+++ b/src/vehicles/Vehicle.cpp
@@ -33,8 +33,6 @@
#include "Weather.h"
#include "Coronas.h"
-//--MIAMI: done
-
bool CVehicle::bWheelsOnlyCheat;
bool CVehicle::bAllDodosCheat;
bool CVehicle::bCheat3;
@@ -764,7 +762,9 @@ CVehicle::BladeColSectorList(CPtrList &list, CColModel &rotorColModel, CMatrix &
}
-float fBurstSpeedMax = 0.3f;
+float WS_ALREADY_SPINNING_LOSS = 0.2f;
+float WS_TRAC_FRAC_LIMIT = 0.3f;
+float fBurstSpeedMax = 0.2f;
float fBurstTyreMod = 0.13f;
void
@@ -792,13 +792,15 @@ CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelCon
float contactSpeedFwd = DotProduct(wheelContactSpeed, wheelFwd);
float contactSpeedRight = DotProduct(wheelContactSpeed, wheelRight);
- if(*wheelState != WHEEL_STATE_NORMAL)
+ adhesion *= CTimer::GetTimeStep();
+ if(*wheelState != WHEEL_STATE_NORMAL){
bAlreadySkidding = true;
+ adhesion *= pHandling->fTractionLoss;
+ if(*wheelState == WHEEL_STATE_SPINNING && (GetStatus() == STATUS_PLAYER || GetStatus() == STATUS_PLAYER_REMOTE))
+ adhesion *= 1.0f - Abs(m_fGasPedal) * WS_ALREADY_SPINNING_LOSS;
+ }
*wheelState = WHEEL_STATE_NORMAL;
- adhesion *= CTimer::GetTimeStep();
- if(bAlreadySkidding)
- adhesion *= pHandling->fTractionLoss;
// moving sideways
if(contactSpeedRight != 0.0f){
@@ -838,13 +840,15 @@ CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelCon
if(!bBraking){
if(m_fGasPedal < 0.01f){
if(IsBike())
- brake = 0.6f * mod_HandlingManager.fWheelFriction / (pHandling->fMass + 200.0f);
- else if(pHandling->fMass < 500.0f)
- brake = 0.2f * mod_HandlingManager.fWheelFriction / pHandling->fMass;
+ brake = 0.6f * mod_HandlingManager.fWheelFriction / (pHandling->GetMass() + 200.0f);
+ else if(IsPlane())
+ brake = 0.0f;
+ else if(pHandling->GetMass() < 500.0f)
+ brake = 0.1f * mod_HandlingManager.fWheelFriction / pHandling->GetMass();
else if(GetModelIndex() == MI_RCBANDIT)
- brake = 0.2f * mod_HandlingManager.fWheelFriction / pHandling->fMass;
+ brake = 0.2f * mod_HandlingManager.fWheelFriction / pHandling->GetMass();
else
- brake = mod_HandlingManager.fWheelFriction / pHandling->fMass;
+ brake = mod_HandlingManager.fWheelFriction / pHandling->GetMass();
#ifdef FIX_BUGS
brake *= CTimer::GetTimeStepFix();
#endif
@@ -868,7 +872,10 @@ CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelCon
float speedSq = sq(right) + sq(fwd);
if(sq(adhesion) < speedSq){
if(*wheelState != WHEEL_STATE_FIXED){
- if(bDriving && contactSpeedFwd < 0.2f)
+ float tractionLimit = WS_TRAC_FRAC_LIMIT;
+ if(contactSpeedFwd > 0.15f && (wheelId == CARWHEEL_FRONT_LEFT || wheelId == CARWHEEL_FRONT_RIGHT))
+ tractionLimit *= 2.0f;
+ if(bDriving && tractionLimit*adhesion < Abs(fwd))
*wheelState = WHEEL_STATE_SPINNING;
else
*wheelState = WHEEL_STATE_SKIDDING;
@@ -876,6 +883,8 @@ CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelCon
float l = Sqrt(speedSq);
float tractionLoss = bAlreadySkidding ? 1.0f : pHandling->fTractionLoss;
+ if(*wheelState == WHEEL_STATE_SPINNING && (GetStatus() == STATUS_PLAYER || GetStatus() == STATUS_PLAYER_REMOTE))
+ tractionLoss *= 1.0f - Abs(m_fGasPedal) * WS_ALREADY_SPINNING_LOSS;
right *= adhesion * tractionLoss / l;
fwd *= adhesion * tractionLoss / l;
}
@@ -884,7 +893,7 @@ CVehicle::ProcessWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelCon
CVector totalSpeed = fwd*wheelFwd + right*wheelRight;
CVector turnDirection = totalSpeed;
- bool separateTurnForce = false; // BUG: not initialized on PC
+ bool separateTurnForce = false;
if(pHandling->fSuspensionAntidiveMultiplier > 0.0f){
if(bBraking){
separateTurnForce = true;
@@ -921,6 +930,7 @@ float fBurstBikeSpeedMax = 0.12f;
float fBurstBikeTyreMod = 0.05f;
float fTweakBikeWheelTurnForce = 2.0f;
+//--LCS: done
void
CVehicle::ProcessBikeWheel(CVector &wheelFwd, CVector &wheelRight, CVector &wheelContactSpeed, CVector &wheelContactPoint,
int32 wheelsOnGround, float thrust, float brake, float adhesion, float destabTraction, int8 wheelId, float *wheelSpeed, tWheelState *wheelState, eBikeWheelSpecial special, uint16 wheelStatus)
diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h
index 795161bf..29a4eea1 100644
--- a/src/vehicles/Vehicle.h
+++ b/src/vehicles/Vehicle.h
@@ -250,6 +250,7 @@ public:
int8 m_nPacManPickupsCarried;
uint8 m_nRoadblockType;
float m_fHealth; // 1000.0f = full health. 250.0f = fire. 0 -> explode
+ float m_fEngineEnergy; // TODO(LCS): better name. it adds up acceleration force, so possibly kinetic energy??
uint8 m_nCurrentGear;
float m_fChangeGearTime;
#if (!defined GTA_PS2 || defined FIX_BUGS)
@@ -288,6 +289,7 @@ public:
~CVehicle(void);
// from CEntity
void SetModelIndex(uint32 id);
+ void PreRender(void) {}
bool SetupLighting(void);
void RemoveLighting(bool);
void FlagToDestroyWhenNextProcessed(void) {}