summaryrefslogtreecommitdiffstats
path: root/src/vehicles
diff options
context:
space:
mode:
Diffstat (limited to 'src/vehicles')
-rw-r--r--src/vehicles/Automobile.cpp856
-rw-r--r--src/vehicles/Automobile.h3
-rw-r--r--src/vehicles/Bike.cpp9
-rw-r--r--src/vehicles/Bike.h1
-rw-r--r--src/vehicles/Boat.cpp5
-rw-r--r--src/vehicles/Cranes.cpp10
-rw-r--r--src/vehicles/DamageManager.cpp5
-rw-r--r--src/vehicles/DamageManager.h1
-rw-r--r--src/vehicles/Door.cpp55
-rw-r--r--src/vehicles/Door.h19
-rw-r--r--src/vehicles/Ferry.h13
-rw-r--r--src/vehicles/HandlingMgr.cpp160
-rw-r--r--src/vehicles/HandlingMgr.h93
-rw-r--r--src/vehicles/Heli.cpp2
-rw-r--r--src/vehicles/Train.cpp58
-rw-r--r--src/vehicles/Transmission.cpp119
-rw-r--r--src/vehicles/Transmission.h2
-rw-r--r--src/vehicles/Vehicle.cpp44
-rw-r--r--src/vehicles/Vehicle.h10
19 files changed, 729 insertions, 736 deletions
diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp
index 041db625..2df57a10 100644
--- a/src/vehicles/Automobile.cpp
+++ b/src/vehicles/Automobile.cpp
@@ -102,6 +102,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;
@@ -150,7 +152,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;
@@ -191,12 +193,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);
@@ -256,6 +252,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;
@@ -310,7 +310,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:
@@ -319,16 +319,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()){
@@ -351,7 +353,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;
@@ -371,11 +373,7 @@ CAutomobile::ProcessControl(void)
bool playerRemote = false;
switch(GetStatus()){
case STATUS_PLAYER_REMOTE:
-#ifdef FIX_BUGS
if(CPad::GetPad(0)->CarGunJustDown() && !bDisableRemoteDetonation){
-#else
- if(CPad::GetPad(0)->WeaponJustDown() && !bDisableRemoteDetonation){
-#endif
BlowUpCar(FindPlayerPed());
CRemote::TakeRemoteControlledCarFromPlayer();
}
@@ -394,6 +392,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)
@@ -419,6 +418,8 @@ CAutomobile::ProcessControl(void)
}else
m_vecCentreOfMass.z = pHandling->CentreOfMass.z;
+ // TODO(LCS): some in air handling?
+
if(bHoverCheat)
DoHoverSuspensionRatios();
@@ -454,8 +455,6 @@ CAutomobile::ProcessControl(void)
m_fBrakePedal = 1.0f;
m_fGasPedal = 0.0f;
}
- if(CPad::GetPad(0)->CarGunJustDown())
- ActivateBomb();
break;
case STATUS_SIMPLE:
@@ -495,7 +494,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));
@@ -530,8 +529,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:
@@ -625,14 +626,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:
@@ -722,7 +722,7 @@ CAutomobile::ProcessControl(void)
ApplyTurnSpeed();
}
bIsInSafePosition = true;
- bIsStuck = false;
+ bIsStuck = false;
}
CPhysical::ProcessControl();
@@ -741,6 +741,7 @@ CAutomobile::ProcessControl(void)
CVector contactPoints[4]; // relative to model
CVector contactSpeeds[4]; // speed at contact points
CVector springDirections[4]; // normalized, in world space
+ float springForces[4];
for(i = 0; i < 4; i++){
// Set spring under certain circumstances
@@ -764,10 +765,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);
}
}
@@ -780,7 +784,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 ||
@@ -792,8 +796,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);
}
}
@@ -815,7 +819,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
@@ -828,42 +832,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;
@@ -894,16 +862,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;
@@ -913,448 +901,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.HasFrontWheelDrive(pHandling->nIdentifier))
- fThrust = acceleration;
- else
- fThrust = 0.0f;
-
- 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.HasFrontWheelDrive(pHandling->nIdentifier))
- fThrust = acceleration;
- else
- fThrust = 0.0f;
-
- 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.HasFrontWheelDrive(pHandling->nIdentifier) && acceleration != 0.0f){
- 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;
- }
- }else{
- m_aWheelSpeed[CARWHEEL_FRONT_LEFT] *= 0.95f;
- }
- m_aWheelRotation[CARWHEEL_FRONT_LEFT] += m_aWheelSpeed[CARWHEEL_FRONT_LEFT];
- }
- if(m_aWheelTimer[CARWHEEL_FRONT_RIGHT] <= 0.0f){
- if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier) && acceleration != 0.0f){
- 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;
- }
- }else{
- m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] *= 0.95f;
- }
- 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.HasRearWheelDrive(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.HasRearWheelDrive(pHandling->nIdentifier))
- fThrust = acceleration;
- else
- fThrust = 0.0f;
-
- 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.HasRearWheelDrive(pHandling->nIdentifier))
- fThrust = acceleration;
- else
- fThrust = 0.0f;
-
- 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.HasRearWheelDrive(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.HasRearWheelDrive(pHandling->nIdentifier) && acceleration != 0.0f){
- 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;
- }
- }else{
- m_aWheelSpeed[CARWHEEL_REAR_LEFT] *= 0.95f;
- }
- 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.HasRearWheelDrive(pHandling->nIdentifier) && acceleration != 0.0f){
- 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;
- }
- }else{
- m_aWheelSpeed[CARWHEEL_REAR_RIGHT] *= 0.95f;
+ // 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.HasFrontWheelDrive(pHandling->nIdentifier))
- fThrust = acceleration;
- else
- fThrust = 0.0f;
-
- 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.HasFrontWheelDrive(pHandling->nIdentifier))
- fThrust = acceleration;
- else
- fThrust = 0.0f;
-
- 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.HasFrontWheelDrive(pHandling->nIdentifier) && acceleration != 0.0f){
- 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;
- }
- }else{
- m_aWheelSpeed[CARWHEEL_FRONT_LEFT] *= 0.95f;
- }
- m_aWheelRotation[CARWHEEL_FRONT_LEFT] += m_aWheelSpeed[CARWHEEL_FRONT_LEFT];
- }
- if(m_aWheelTimer[CARWHEEL_FRONT_RIGHT] <= 0.0f){
- if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier) && acceleration != 0.0f){
- 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;
- }
- }else{
- m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] *= 0.95f;
- }
- 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
@@ -1649,13 +1262,13 @@ CAutomobile::ProcessControl(void)
// TODO: make the numbers defines
float heading;
- if(GetPosition().x > 1950.0f-400.0f){
+ if(GetPosition().x > 1950.0f){
if(m_vecMoveSpeed.x > 0.0f)
m_vecMoveSpeed.x *= -1.0f;
heading = GetForward().Heading();
if(heading > 0.0f) // going west
SetHeading(-heading);
- }else if(GetPosition().x < -1950.0f-400.0f){
+ }else if(GetPosition().x < -1950.0f){
if(m_vecMoveSpeed.x < 0.0f)
m_vecMoveSpeed.x *= -1.0f;
heading = GetForward().Heading();
@@ -1718,6 +1331,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.01f){
+#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)
{
@@ -1739,6 +1553,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;
@@ -2045,6 +1864,7 @@ CAutomobile::PreRender(void)
if(DotProduct(GetForward(), camDist) > 0.0f ||
TheCamera.GetLookDirection() == LOOKING_LEFT ||
TheCamera.GetLookDirection() == LOOKING_RIGHT){
+ /*
CParticle::AddParticle(PARTICLE_HEATHAZE, pos1, CVector(0.0f, 0.0f, 0.0f));
if(pHandling->Flags & HANDLING_DBL_EXHAUST)
CParticle::AddParticle(PARTICLE_HEATHAZE, pos2, CVector(0.0f, 0.0f, 0.0f));
@@ -2052,6 +1872,7 @@ CAutomobile::PreRender(void)
CParticle::AddParticle(PARTICLE_HEATHAZE, pos1, CVector(0.0f, 0.0f, 0.0f));
if(pHandling->Flags & HANDLING_DBL_EXHAUST)
CParticle::AddParticle(PARTICLE_HEATHAZE, pos2, CVector(0.0f, 0.0f, 0.0f));
+ */
}
}
@@ -2201,8 +2022,7 @@ CAutomobile::PreRender(void)
case MI_TAXI:
case MI_CABBIE:
- case MI_ZEBRA:
- case MI_KAUFMAN:
+ case MI_BORGNINE:
if(bTaxiLight){
CVector pos = GetPosition() + GetUp()*0.95f;
CCoronas::RegisterCorona((uintptr)this + 21,
@@ -3018,6 +2838,7 @@ CAutomobile::Render(void)
CEntity::Render();
}
+//--LCS: done
int32
CAutomobile::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints)
{
@@ -3089,9 +2910,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() ||
@@ -3102,6 +2927,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();
@@ -3114,7 +2940,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;
@@ -3207,6 +3035,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
@@ -3929,6 +3758,7 @@ CAutomobile::DoDriveByShootings(void)
}
}
+//--LCS: done
void
CAutomobile::DoHoverSuspensionRatios(void)
{
@@ -4344,7 +4174,7 @@ CAutomobile::dmgDrawCarCollidingParticles(const CVector &pos, float amount)
CGeneral::GetRandomNumberInRange(0.1f, 0.25f)),
nil,
CGeneral::GetRandomNumberInRange(0.02f, 0.08f),
- CVehicleModelInfo::ms_vehicleColourTable[m_currentColour1],
+ CVehicleModelInfo::mspInfo->ms_vehicleColourTable[m_currentColour1],
CGeneral::GetRandomNumberInRange(-40.0f, 40.0f),
0,
CGeneral::GetRandomNumberInRange(0.0f, 4.0f));
@@ -5025,6 +4855,7 @@ CAutomobile::ResetSuspension(void)
}
}
+//--LCS: done
void
CAutomobile::SetupSuspensionLines(void)
{
@@ -5033,6 +4864,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++){
@@ -5072,6 +4911,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 0b6d4e3a..ae567ae2 100644
--- a/src/vehicles/Bike.cpp
+++ b/src/vehicles/Bike.cpp
@@ -79,9 +79,10 @@ CBike::CBike(int32 id, uint8 CreatedBy)
m_bikeAnimType = ASSOCGRP_BIKE_STANDARD;
break;
case MI_SANCHEZ:
+ case MI_SANCHEZ2:
m_bikeAnimType = ASSOCGRP_BIKE_DIRT;
break;
- default: assert(0 && "invalid bike model ID");
+ default: m_bikeAnimType = ASSOCGRP_BIKE_STANDARD; //assert(0 && "invalid bike model ID"); // TODO
}
m_vehType = VEHICLE_TYPE_BIKE;
@@ -109,7 +110,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;
@@ -133,6 +134,8 @@ CBike::CBike(int32 id, uint8 CreatedBy)
bIsOnFire = false;
bWheelieCam = false;
+ bFixedColour = false; // <- figure out actual place (TODO)
+
m_fTireTemperature = 1.0f;
m_fBrakeDestabilization = 0.0f;
m_fVelocityChangeForAudio = 0;
@@ -1722,7 +1725,7 @@ CBike::PreRender(void)
TheCamera.GetLookDirection() == LOOKING_RIGHT)
pos1 -= 0.2f*GetForward();
- CParticle::AddParticle(PARTICLE_HEATHAZE, pos1, CVector(0.0f, 0.0f, 0.0f));
+ //CParticle::AddParticle(PARTICLE_HEATHAZE, pos1, CVector(0.0f, 0.0f, 0.0f));
}
}
}
diff --git a/src/vehicles/Bike.h b/src/vehicles/Bike.h
index 219d8872..611cd11d 100644
--- a/src/vehicles/Bike.h
+++ b/src/vehicles/Bike.h
@@ -75,6 +75,7 @@ public:
uint8 bExtraSpeed : 1; // leaning forward
uint8 bIsOnFire : 1;
uint8 bWheelieCam : 1;
+ uint8 bFixedColour : 1; // <- figure out its actual place (TODO)
int16 m_doingBurnout;
float m_fTireTemperature;
float m_fBrakeDestabilization;
diff --git a/src/vehicles/Boat.cpp b/src/vehicles/Boat.cpp
index 0bc653c6..3b9290ea 100644
--- a/src/vehicles/Boat.cpp
+++ b/src/vehicles/Boat.cpp
@@ -71,7 +71,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;
@@ -681,6 +681,7 @@ CBoat::ProcessControl(void)
}
// Spray waterdrops on screen
+ /*
if(TheCamera.GetLookingForwardFirstPerson() && FindPlayerVehicle() && FindPlayerVehicle()->IsBoat() &&
m_nDeltaVolumeUnderWater > 0 && numWaterDropOnScreen < 20){
CVector dropPos;
@@ -711,7 +712,7 @@ CBoat::ProcessControl(void)
if(CParticle::AddParticle(PARTICLE_WATERDROP, dropPos, dropDir, nil,
CGeneral::GetRandomNumberInRange(0.1f, 0.15f), dropColor, 0, 0, frm))
numWaterDropOnScreen++;
- }
+ }*/
if(m_fPrevVolumeUnderWater == 0.0f && m_fVolumeUnderWater > 0.0f && GetModelIndex() == MI_SKIMMER){
CVector splashDir(0.0f, 0.0f, 0.25f*speed);
diff --git a/src/vehicles/Cranes.cpp b/src/vehicles/Cranes.cpp
index b5926867..a675fe4e 100644
--- a/src/vehicles/Cranes.cpp
+++ b/src/vehicles/Cranes.cpp
@@ -12,7 +12,7 @@
#include "Object.h"
#include "World.h"
-#define MAX_DISTANCE_TO_FIND_CRANE (10.0f)
+#define MAX_DISTANCE_TO_FIND_CRANE (100.0f)
#define CRANE_UPDATE_RADIUS (300.0f)
#define CRANE_MOVEMENT_PROCESSING_RADIUS (150.0f)
#define CRUSHER_Z (-0.951f)
@@ -60,7 +60,8 @@ void CCranes::InitCranes(void)
}
}
}
- for (CPtrNode* pNode = CWorld::GetBigBuildingList(LEVEL_MAINLAND).first; pNode; pNode = pNode->next) {
+ // TODO(LCS)
+ for (CPtrNode* pNode = CWorld::GetBigBuildingList(LEVEL_INDUSTRIAL).first; pNode; pNode = pNode->next) {
CEntity* pEntity = (CEntity*)pNode->item;
if (MODELID_CRANE_1 == pEntity->GetModelIndex() ||
MODELID_CRANE_2 == pEntity->GetModelIndex() ||
@@ -70,6 +71,7 @@ void CCranes::InitCranes(void)
MODELID_CRANE_6 == pEntity->GetModelIndex())
AddThisOneCrane(pEntity);
}
+
}
void CCranes::AddThisOneCrane(CEntity* pEntity)
@@ -462,7 +464,7 @@ bool CCranes::DoesMilitaryCraneHaveThisOneAlready(uint32 mi)
case MI_FIRETRUCK: return (CarsCollectedMilitaryCrane & 1);
case MI_AMBULAN: return (CarsCollectedMilitaryCrane & 2);
case MI_ENFORCER: return (CarsCollectedMilitaryCrane & 4);
- case MI_FBIRANCH: return (CarsCollectedMilitaryCrane & 8);
+ case (uint32)MI_FBIRANCH: return (CarsCollectedMilitaryCrane & 8);
case MI_RHINO: return (CarsCollectedMilitaryCrane & 0x10);
case MI_BARRACKS: return (CarsCollectedMilitaryCrane & 0x20);
case MI_POLICE: return (CarsCollectedMilitaryCrane & 0x40);
@@ -477,7 +479,7 @@ void CCranes::RegisterCarForMilitaryCrane(uint32 mi)
case MI_FIRETRUCK: CarsCollectedMilitaryCrane |= 1; break;
case MI_AMBULAN: CarsCollectedMilitaryCrane |= 2; break;
case MI_ENFORCER: CarsCollectedMilitaryCrane |= 4; break;
- case MI_FBIRANCH: CarsCollectedMilitaryCrane |= 8; break;
+ case (uint32)MI_FBIRANCH: CarsCollectedMilitaryCrane |= 8; break;
case MI_RHINO: CarsCollectedMilitaryCrane |= 0x10; break;
case MI_BARRACKS: CarsCollectedMilitaryCrane |= 0x20; break;
case MI_POLICE: CarsCollectedMilitaryCrane |= 0x40; break;
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/Door.cpp b/src/vehicles/Door.cpp
index c80965aa..72a30339 100644
--- a/src/vehicles/Door.cpp
+++ b/src/vehicles/Door.cpp
@@ -168,3 +168,58 @@ CTrainDoor::IsClosed(void)
{
return m_fPosn == RetTranslationWhenClosed();
}
+
+bool
+CFerryDoor::IsInUse(void)
+{
+ float translationDifference = m_fPrevPosn - m_fPosn;
+ m_fPrevPosn = m_fPosn;
+ return Abs(translationDifference) > 0.002f;
+}
+
+float
+CFerryDoor::RetTranslationWhenClosed(void)
+{
+ if(Abs(m_fClosedPosn) < Abs(m_fOpenPosn))
+ return m_fClosedPosn;
+ else
+ return m_fOpenPosn;
+}
+
+bool
+CFerryDoor::IsClosed(void)
+{
+ return m_fPosn == RetTranslationWhenClosed();
+}
+
+float
+CFerryDoor::RetTranslationWhenOpen(void)
+{
+ if(Abs(m_fClosedPosn) < Abs(m_fOpenPosn))
+ return m_fOpenPosn;
+ else
+ return m_fClosedPosn;
+}
+
+bool
+CFerryDoor::IsFullyOpen(void)
+{
+ if(Abs(m_fPosn) < Abs(RetTranslationWhenOpen()) - 0.5f)
+ return false;
+ return true;
+}
+
+void
+CFerryDoor::Open(float ratio)
+{
+ float open;
+
+ m_fPrevPosn = m_fPosn;
+ open = RetTranslationWhenOpen();
+ if(ratio < 1.0f){
+ m_fPosn = open*ratio;
+ }else{
+ m_nDoorState = DOORST_OPEN;
+ m_fPosn = open;
+ }
+} \ No newline at end of file
diff --git a/src/vehicles/Door.h b/src/vehicles/Door.h
index 567d3263..da5a3de0 100644
--- a/src/vehicles/Door.h
+++ b/src/vehicles/Door.h
@@ -67,3 +67,22 @@ public:
float RetTranslationWhenOpen(void);
void Open(float ratio);
};
+
+
+class CFerryDoor {
+private:
+ float m_fClosedPosn;
+ float m_fOpenPosn;
+ int8 m_nDirn;
+ int8 m_nAxis;
+ int8 m_nDoorState;
+ float m_fPosn;
+ float m_fPrevPosn;
+public:
+ bool IsInUse(void);
+ float RetTranslationWhenClosed(void);
+ float RetTranslationWhenOpen(void);
+ bool IsClosed(void);
+ bool IsFullyOpen(void);
+ void Open(float ratio);
+}; \ No newline at end of file
diff --git a/src/vehicles/Ferry.h b/src/vehicles/Ferry.h
new file mode 100644
index 00000000..375dfce1
--- /dev/null
+++ b/src/vehicles/Ferry.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "Vehicle.h"
+#include "Door.h"
+
+enum eFerryNodes
+{
+ FERRY_DOOR_FRONT = 1,
+ FERRY_RAMP_FRONT,
+ FERRY_DOOR_BACK,
+ FERRY_RAMP_BACK,
+ NUM_FERRY_NODES
+};
diff --git a/src/vehicles/HandlingMgr.cpp b/src/vehicles/HandlingMgr.cpp
index 8438c5c9..b5dc7658 100644
--- a/src/vehicles/HandlingMgr.cpp
+++ b/src/vehicles/HandlingMgr.cpp
@@ -42,6 +42,7 @@ const char VehicleNames[NUMHANDLINGS][14] = {
"RHINO",
"BARRACKS",
"TRAIN",
+ "FERRY",
"HELI",
"DODO",
"COACH",
@@ -54,66 +55,40 @@ const char VehicleNames[NUMHANDLINGS][14] = {
"DEADDODO",
"FLATBED",
"YANKEE",
- "GOLFCART",
- "VOODOO",
- "WASHING",
- "CUBAN",
- "ROMERO",
- "PACKER",
- "ADMIRAL",
- "GANGBUR",
- "ZEBRA",
- "TOPFUN",
- "GLENDALE",
- "OCEANIC",
- "HERMES",
- "SABRE1",
- "SABRETUR",
- "PHEONIX",
- "WALTON",
- "REGINA",
- "COMET",
- "DELUXO",
- "BURRITO",
- "SPAND",
- "BAGGAGE",
- "KAUFMAN",
- "RANCHER",
- "FBIRANCH",
- "VIRGO",
- "GREENWOO",
- "HOTRING",
- "SANDKING",
- "BLISTAC",
- "BOXVILLE",
- "BENSON",
- "DESPERAD",
- "LOVEFIST",
- "BLOODRA",
- "BLOODRB",
+ "BLISTA",
+ "BELLYUP",
+ "MRWONGS",
+ "YARDIE",
+ "YAKUZA",
+ "DIABLOS",
+ "COLUMB",
+ "HOODS",
+ "PANLANT",
+ "BORGNINE",
+ "CAMPVAN",
+ "BALLOT",
+ "SPIDER",
+ "SHELBY",
+ "PONTIAC",
+ "ESPRIT",
+ "MINI",
+ "HOTROD",
+ "SINDACCO",
+ "FORELLI",
"BIKE",
"MOPED",
"DIRTBIKE",
"ANGEL",
+ "DIRTBIK2",
+ "ANGE2",
"FREEWAY",
"PREDATOR",
"SPEEDER",
"REEFER",
- "RIO",
- "SQUALO",
- "TROPIC",
- "COASTGRD",
- "DINGHY",
- "MARQUIS",
- "CUPBOAT",
- "SEAPLANE",
- "SPARROW",
- "SEASPAR",
"MAVERICK",
"COASTMAV",
"POLMAV",
"HUNTER",
- "RCBARON",
"RCGOBLIN",
"RCCOPTER"
};
@@ -138,18 +113,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;
@@ -158,21 +132,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
@@ -286,19 +257,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;
@@ -307,25 +278,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;
}
}
@@ -353,12 +327,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
@@ -371,10 +342,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){
@@ -420,15 +394,15 @@ cHandlingDataMgr::GetHandlingId(const char *name)
tFlyingHandlingData*
cHandlingDataMgr::GetFlyingPointer(uint8 id)
{
- if(id >= HANDLING_SEAPLANE && id <= HANDLING_RCCOPTER)
- return &FlyingHandlingData[id-HANDLING_SEAPLANE];
+ if(id >= HANDLING_MAVERICK && id <= HANDLING_RCCOPTER)
+ return &FlyingHandlingData[id-HANDLING_MAVERICK];
return &FlyingHandlingData[0];
}
tBoatHandlingData*
cHandlingDataMgr::GetBoatPointer(uint8 id)
{
- if(id >= HANDLING_PREDATOR && id <= HANDLING_SEAPLANE)
+ if(id >= HANDLING_PREDATOR && id <= HANDLING_MAVERICK)
return &BoatHandlingData[id-HANDLING_PREDATOR];
return &BoatHandlingData[0];
}
diff --git a/src/vehicles/HandlingMgr.h b/src/vehicles/HandlingMgr.h
index 8d290f7d..2d49761c 100644
--- a/src/vehicles/HandlingMgr.h
+++ b/src/vehicles/HandlingMgr.h
@@ -36,6 +36,7 @@ enum tVehicleType
HANDLING_RHINO,
HANDLING_BARRACKS,
HANDLING_TRAIN,
+ HANDLING_FERRY,
HANDLING_HELI,
HANDLING_DODO,
HANDLING_COACH,
@@ -48,76 +49,51 @@ enum tVehicleType
HANDLING_DEADDODO,
HANDLING_FLATBED,
HANDLING_YANKEE,
- HANDLING_GOLFCART,
- HANDLING_VOODOO,
- HANDLING_WASHING,
- HANDLING_CUBAN,
- HANDLING_ROMERO,
- HANDLING_PACKER,
- HANDLING_ADMIRAL,
- HANDLING_GANGBUR,
- HANDLING_ZEBRA,
- HANDLING_TOPFUN,
- HANDLING_GLENDALE,
- HANDLING_OCEANIC,
- HANDLING_HERMES,
- HANDLING_SABRE1,
- HANDLING_SABRETUR,
- HANDLING_PHEONIX,
- HANDLING_WALTON,
- HANDLING_REGINA,
- HANDLING_COMET,
- HANDLING_DELUXO,
- HANDLING_BURRITO,
- HANDLING_SPAND,
- HANDLING_BAGGAGE,
- HANDLING_KAUFMAN,
- HANDLING_RANCHER,
- HANDLING_FBIRANCH,
- HANDLING_VIRGO,
- HANDLING_GREENWOO,
- HANDLING_HOTRING,
- HANDLING_SANDKING,
- HANDLING_BLISTAC,
- HANDLING_BOXVILLE,
- HANDLING_BENSON,
- HANDLING_DESPERAD,
- HANDLING_LOVEFIST,
- HANDLING_BLOODRA,
- HANDLING_BLOODRB,
+ HANDLING_BLISTA,
+ HANDLING_BELLYUP,
+ HANDLING_MRWONGS,
+ HANDLING_YARDIE,
+ HANDLING_YAKUZA,
+ HANDLING_DIABLOS,
+ HANDLING_COLUMB,
+ HANDLING_HOODS,
+ HANDLING_PANLANT,
+ HANDLING_BORGNINE,
+ HANDLING_CAMPVAN,
+ HANDLING_BALLOT,
+ HANDLING_SPIDER,
+ HANDLING_SHELBY,
+ HANDLING_PONTIAC,
+ HANDLING_ESPRIT,
+ HANDLING_MINI,
+ HANDLING_HOTROD,
+ HANDLING_SINDACCO,
+ HANDLING_FORELLI,
HANDLING_BIKE,
HANDLING_MOPED,
HANDLING_DIRTBIKE,
HANDLING_ANGEL,
+ HANDLING_DIRTBIK2,
+ HANDLING_ANGE2,
HANDLING_FREEWAY,
HANDLING_PREDATOR,
HANDLING_SPEEDER,
HANDLING_REEFER,
- HANDLING_RIO,
- HANDLING_SQUALO,
- HANDLING_TROPIC,
- HANDLING_COASTGRD,
- HANDLING_DINGHY,
- HANDLING_MARQUIS,
- HANDLING_CUPBOAT,
- HANDLING_SEAPLANE, // both boat and plane!
- HANDLING_SPARROW,
- HANDLING_SEASPAR,
+
HANDLING_MAVERICK,
HANDLING_COASTMAV,
HANDLING_POLMAV,
HANDLING_HUNTER,
- HANDLING_RCBARON,
HANDLING_RCGOBLIN,
HANDLING_RCCOPTER,
NUMHANDLINGS,
NUMBIKEHANDLINGS = HANDLING_FREEWAY+1 - HANDLING_BIKE,
- NUMFLYINGHANDLINGS = HANDLING_RCCOPTER+1 - HANDLING_SEAPLANE,
- NUMBOATHANDLINGS = HANDLING_SEAPLANE+1 - HANDLING_PREDATOR,
+ NUMFLYINGHANDLINGS = HANDLING_RCCOPTER+1 - HANDLING_MAVERICK,
+ NUMBOATHANDLINGS = HANDLING_REEFER+1 - HANDLING_PREDATOR,
};
enum tField // most likely a handling field enum, never used so :shrug:
@@ -155,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;
@@ -182,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
diff --git a/src/vehicles/Heli.cpp b/src/vehicles/Heli.cpp
index bf14416c..3f01ff41 100644
--- a/src/vehicles/Heli.cpp
+++ b/src/vehicles/Heli.cpp
@@ -756,7 +756,7 @@ CHeli::InitHelis(void)
for(i = 0; i < NUM_HELIS; i++)
pHelis[i] = nil;
- ((CVehicleModelInfo*)CModelInfo::GetModelInfo(MI_CHOPPER))->SetColModel(&CTempColModels::ms_colModelPed1);
+ ((CVehicleModelInfo*)CModelInfo::GetModelInfo(MI_CHOPPER))->SetColModel(&gpTempColModels->ms_colModelPed1);
}
CHeli*
diff --git a/src/vehicles/Train.cpp b/src/vehicles/Train.cpp
index 5f0cf36a..55be4a20 100644
--- a/src/vehicles/Train.cpp
+++ b/src/vehicles/Train.cpp
@@ -459,11 +459,11 @@ CTrain::InitTrains(void)
CStreaming::LoadAllRequestedModels(false);
// El-Train wagons
- float wagonPositions[] = { 0.0f, 20.0f, 40.0f, 0.0f, 20.0f };
- int8 firstWagon[] = { 1, 0, 0, 1, 0 };
- int8 lastWagon[] = { 0, 0, 1, 0, 1 };
- int16 wagonGroup[] = { 0, 0, 0, 1, 1 };
- for(i = 0; i < 5; i++){
+ float wagonPositions[] = { 0.0f, 20.0f, 0.0f, 20.0f };
+ int8 firstWagon[] = { 1, 0, 1, 0 };
+ int8 lastWagon[] = { 0, 1, 0, 1 };
+ int16 wagonGroup[] = { 0, 0, 1, 1 };
+ for(i = 0; i < 4; i++){
train = new CTrain(MI_TRAIN, PERMANENT_VEHICLE);
train->GetMatrix().SetTranslate(0.0f, 0.0f, 0.0f);
train->SetStatus(STATUS_ABANDONED);
@@ -650,52 +650,6 @@ CTrain::ReadAndInterpretTrackFile(Const char *filename, CTrainNode **nodes, int1
}
void
-PlayAnnouncement(uint8 sound, uint8 station)
-{
- // this was gone in a PC version but inlined on PS2
- cAudioScriptObject *obj = new cAudioScriptObject;
- obj->AudioId = sound;
- obj->Posn = CTrain::aStationCoors[station];
- obj->AudioEntity = AEHANDLE_NONE;
- DMAudio.CreateOneShotScriptObject(obj);
-}
-
-void
-ProcessTrainAnnouncements(void)
-{
-#ifdef GTA_TRAIN
- for (int i = 0; i < ARRAY_SIZE(StationDist); i++) {
- for (int j = 0; j < ARRAY_SIZE(EngineTrackPosition); j++) {
- if (!bTrainArrivalAnnounced[i]) {
- float preDist = StationDist[i] - 100.0f;
- if (preDist < 0.0f)
- preDist += TotalLengthOfTrack;
- if (EngineTrackPosition[j] > preDist && EngineTrackPosition[j] < StationDist[i]) {
- bTrainArrivalAnnounced[i] = true;
- PlayAnnouncement(SCRIPT_SOUND_TRAIN_ANNOUNCEMENT_1, i);
- break;
- }
- } else {
- float postDist = StationDist[i] + 10.0f;
-#ifdef FIX_BUGS
- if (postDist > TotalLengthOfTrack)
- postDist -= TotalLengthOfTrack;
-#else
- if (postDist < 0.0f) // does this even make sense here?
- postDist += TotalLengthOfTrack;
-#endif
- if (EngineTrackPosition[j] > StationDist[i] && EngineTrackPosition[j] < postDist) {
- bTrainArrivalAnnounced[i] = false;
- PlayAnnouncement(SCRIPT_SOUND_TRAIN_ANNOUNCEMENT_2, i);
- break;
- }
- }
- }
- }
-#endif
-}
-
-void
CTrain::UpdateTrains(void)
{
#ifdef GTA_TRAIN
@@ -732,8 +686,6 @@ CTrain::UpdateTrains(void)
// time offset for each train
time += 0x20000/2;
}
-
- ProcessTrainAnnouncements();
}
// Update Subway
diff --git a/src/vehicles/Transmission.cpp b/src/vehicles/Transmission.cpp
index 1aeabfe0..f7851f47 100644
--- a/src/vehicles/Transmission.cpp
+++ b/src/vehicles/Transmission.cpp
@@ -4,6 +4,7 @@
#include "HandlingMgr.h"
#include "Transmission.h"
+//--LCS: file done
void
cTransmission::InitGearRatios(void)
{
@@ -14,11 +15,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;
@@ -45,9 +49,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
@@ -55,6 +62,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 9d90c616..239fc641 100644
--- a/src/vehicles/Vehicle.cpp
+++ b/src/vehicles/Vehicle.cpp
@@ -133,6 +133,7 @@ CVehicle::CVehicle(uint8 CreatedBy)
bCreatedAsPoliceVehicle = false;
bRestingOnPhysical = false;
bParking = false;
+ m_bGarageTurnedLightsOff = false;
bCanPark = CGeneral::GetRandomNumberInRange(0.0f, 1.0f) < 0.0f; // never true. probably doesn't work very well
bIsVan = false;
bIsBus = false;
@@ -217,8 +218,8 @@ void
CVehicle::SetModelIndex(uint32 id)
{
CEntity::SetModelIndex(id);
- m_aExtras[0] = CVehicleModelInfo::ms_compsUsed[0];
- m_aExtras[1] = CVehicleModelInfo::ms_compsUsed[1];
+ m_aExtras[0] = CVehicleModelInfo::mspInfo->ms_compsUsed[0];
+ m_aExtras[1] = CVehicleModelInfo::mspInfo->ms_compsUsed[1];
m_nNumMaxPassengers = CVehicleModelInfo::GetMaximumNumberOfPassengersFromNumberOfDoors(id);
}
@@ -771,7 +772,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
@@ -799,13 +802,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){
@@ -845,13 +850,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
@@ -875,7 +882,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;
@@ -883,6 +893,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;
}
@@ -891,7 +903,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;
@@ -928,6 +940,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)
@@ -1848,8 +1861,7 @@ CVehicle::SetDriver(CPed *driver)
case MI_TAXI:
case MI_CABBIE:
- case MI_ZEBRA:
- case MI_KAUFMAN:
+ case MI_BORGNINE:
CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 12;
break;
diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h
index 37b57944..d29c2dc0 100644
--- a/src/vehicles/Vehicle.h
+++ b/src/vehicles/Vehicle.h
@@ -240,16 +240,19 @@ public:
uint8 bRestingOnPhysical : 1; // Dont go static cause car is sitting on a physical object that might get removed
uint8 bParking : 1;
uint8 bCanPark : 1;
-#if (!defined GTA_PS2 || defined FIX_BUGS)
+#if (!defined GTA_PS2 || defined FIX_BUGS) // <- I think this can be moved back to CAutomobile?
uint8 m_bombType : 3;
#endif
uint8 bDriverLastFrame : 1;
+ uint8 bRewardVehicle : 1; // 25B_40
int8 m_numPedsUseItAsCover;
uint8 m_nAmmoInClip; // Used to make the guns on boat do a reload (20 by default)
int8 m_nPacManPickupsCarried;
uint8 m_nRoadblockType;
+ bool m_bGarageTurnedLightsOff;
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 +291,7 @@ public:
~CVehicle(void);
// from CEntity
void SetModelIndex(uint32 id);
+ void PreRender(void) {}
bool SetupLighting(void);
void RemoveLighting(bool);
void FlagToDestroyWhenNextProcessed(void) {}
@@ -384,8 +388,8 @@ public:
bool IsAlarmOn(void) { return m_nAlarmState != 0 && m_nAlarmState != -1 && GetStatus() != STATUS_WRECKED; }
CVehicleModelInfo* GetModelInfo() { return (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()); }
- bool IsTaxi(void) { return GetModelIndex() == MI_TAXI || GetModelIndex() == MI_CABBIE || GetModelIndex() == MI_ZEBRA || GetModelIndex() == MI_KAUFMAN; }
- bool IsLimo(void) { return GetModelIndex() == MI_STRETCH || GetModelIndex() == MI_LOVEFIST; }
+ bool IsTaxi(void) { return GetModelIndex() == MI_TAXI || GetModelIndex() == MI_CABBIE || GetModelIndex() == MI_BORGNINE; }
+ bool IsLimo(void) { return GetModelIndex() == MI_STRETCH; }
bool IsRealHeli(void) { return !!(pHandling->Flags & HANDLING_IS_HELI); }
bool IsRealPlane(void) { return !!(pHandling->Flags & HANDLING_IS_PLANE); }