summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/Pad.h2
-rw-r--r--src/core/main.cpp1
-rw-r--r--src/core/main.h1
-rw-r--r--src/math/Vector.h2
-rw-r--r--src/modelinfo/ModelIndices.h23
-rw-r--r--src/peds/Ped.h3
-rw-r--r--src/vehicles/Automobile.cpp298
-rw-r--r--src/vehicles/Automobile.h1
-rw-r--r--src/vehicles/Transmission.cpp1
-rw-r--r--src/vehicles/Vehicle.cpp7
-rw-r--r--src/vehicles/Vehicle.h9
11 files changed, 218 insertions, 130 deletions
diff --git a/src/core/Pad.h b/src/core/Pad.h
index 748482e7..cc0fa9d1 100644
--- a/src/core/Pad.h
+++ b/src/core/Pad.h
@@ -140,7 +140,7 @@ class CPad
public:
enum
{
- HORNHISTORY_SIZE = 5,
+ HORNHISTORY_SIZE = 8,
DRUNK_STEERING_BUFFER_SIZE = 10,
};
CControllerState NewState;
diff --git a/src/core/main.cpp b/src/core/main.cpp
index 2a130684..562d3f1d 100644
--- a/src/core/main.cpp
+++ b/src/core/main.cpp
@@ -95,6 +95,7 @@ bool gUseModelResources;
bool gUseResources;
bool gNASTY_NASTY_MEM_SHUTDOWN_HACK; // rather unused
bool gbPreviewCity; // don't do worldstream-style rendering but traditional method
+bool gMultiplayerSuperBrakeOnPause = true;
float FramesPerSecond = 30.0f;
diff --git a/src/core/main.h b/src/core/main.h
index 400730a0..0c43d7f4 100644
--- a/src/core/main.h
+++ b/src/core/main.h
@@ -43,6 +43,7 @@ extern bool gUseModelResources;
extern bool gUseResources;
extern bool gNASTY_NASTY_MEM_SHUTDOWN_HACK;
extern bool gbPreviewCity;
+extern bool gMultiplayerSuperBrakeOnPause;
class CSprite2d;
diff --git a/src/math/Vector.h b/src/math/Vector.h
index 87895806..a86e4e72 100644
--- a/src/math/Vector.h
+++ b/src/math/Vector.h
@@ -22,7 +22,7 @@ public:
z = v.z;
}
// (0,1,0) means no rotation. So get right vector and its atan
- float Heading(void) const { return Atan2(-x, y); }
+ float Heading(void) const { return x == 0.0f && y == 0.0f ? 0.0f : Atan2(-x, y); }
float Magnitude(void) const { return Sqrt(x*x + y*y + z*z); }
float MagnitudeSqr(void) const { return x*x + y*y + z*z; }
float Magnitude2D(void) const { return Sqrt(x*x + y*y); }
diff --git a/src/modelinfo/ModelIndices.h b/src/modelinfo/ModelIndices.h
index 173b50ff..8cb83d5d 100644
--- a/src/modelinfo/ModelIndices.h
+++ b/src/modelinfo/ModelIndices.h
@@ -1090,34 +1090,31 @@ enum
MI_LAST_VEHICLE = MI_VCNMAV,
- // these indices are sort of original
+ // these indices are original
MI_CADDY = -999,
-
- // with these two i don't know which is which:
- MI_RCBARON = -963,
- MI_BAGGAGE = -955,
-
+ MI_MARQUIS = -990,
+ MI_SEASPAR = -986,
+ MI_SPARROW = -985,
+ MI_VOODOO = -984,
MI_SANDKING = -981,
+ MI_COMET = -972,
+ MI_BAGGAGE = -963,
MI_VICECHEE = -954,
- MI_MARQUIS = -990,
+ MI_RCBARON = -955,
- // these two also unknown
+ // these two are unknown
MI_RIO = -992,
MI_TROPIC = -988,
// HACK HACK, hopefully temporary
- MI_SEASPAR = -2000,
- MI_SPARROW,
- MI_FBIRANCH,
+ MI_FBIRANCH = -2000,
MI_SQUALO,
MI_JETMAX,
MI_COASTG,
MI_DINGHY,
MI_SKIMMER,
- MI_VOODOO,
MI_CUBAN,
MI_PHEONIX,
- MI_COMET,
MI_SABRE,
MI_VIRGO,
MI_RANCHER,
diff --git a/src/peds/Ped.h b/src/peds/Ped.h
index 63feeef5..7984b0f8 100644
--- a/src/peds/Ped.h
+++ b/src/peds/Ped.h
@@ -428,7 +428,8 @@ enum PedState
PED_EXIT_CAR,
PED_HANDS_UP,
PED_ARRESTED,
- PED_DEPLOY_STINGER
+ PED_DEPLOY_STINGER,
+ PED_STATE64
};
enum eMoveState {
diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp
index 0b6f4422..a249ee7f 100644
--- a/src/vehicles/Automobile.cpp
+++ b/src/vehicles/Automobile.cpp
@@ -86,6 +86,7 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
switch(GetModelIndex()){
case MI_HUNTER:
case MI_ANGEL:
+ case MI_ANGEL2:
case MI_FREEWAY:
m_nRadioStation = V_ROCK;
break;
@@ -150,8 +151,8 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
for(i = 0; i < 6; i++)
m_randomValues[i] = CGeneral::GetRandomNumberInRange(-0.15f, 0.15f);
- m_fMass = pHandling->fMass;
- m_fTurnMass = pHandling->fTurnMass;
+ m_fMass = pHandling->GetMass();
+ m_fTurnMass = pHandling->GetTurnMass();
m_vecCentreOfMass = pHandling->CentreOfMass;
m_fAirResistance = pHandling->fDragMult > 0.01f ? pHandling->fDragMult*0.0005f : pHandling->fDragMult;
m_fElasticity = 0.05f;
@@ -201,6 +202,10 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
m_nNumPassengers = 0;
+ m_pBombRigger = nil;
+ m_bombType = CARBOMB_NONE;
+ bUnknownFlag = false;
+
if(m_nDoorLock == CARLOCK_UNLOCKED &&
(id == MI_POLICE || id == MI_ENFORCER || id == MI_RHINO))
m_nDoorLock = CARLOCK_LOCKED_INITIALLY;
@@ -231,6 +236,7 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
bExplosionProof = true;
bBulletProof = true;
}
+ m_vehLCS_2A3 = -1;
}
void
@@ -242,6 +248,9 @@ CAutomobile::SetModelIndex(uint32 id)
#define SAND_SLOWDOWN (0.01f)
float CAR_BALANCE_MULT = 0.3f;
+float CAR_INAIR_ROTF = 0.0007f;
+float CAR_INAIR_ROTLIM = 0.02f;
+float HELI_ROTOR_DOTPROD_LIMIT = 0.95f;
CVector vecSeaSparrowGunPos(-0.5f, 2.4f, -0.785f);
CVector vecHunterGunPos(0.0f, 4.8f, -1.3f);
CVector vecHunterRocketPos(2.5f, 1.0f, -0.5f);
@@ -253,15 +262,28 @@ 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;
float brake = 0.0f;
+ if(TheCamera.WorldViewerBeingUsed){
+ if(bIsAmbulanceOnDuty){
+ bIsAmbulanceOnDuty = false;
+ CCarCtrl::NumAmbulancesOnDuty--;
+ }
+ if(bIsFireTruckOnDuty){
+ bIsFireTruckOnDuty = false;
+ CCarCtrl::NumFiretrucksOnDuty--;
+ }
+ }
+
+ if(m_vehLCS_2A3 >= 0){
+ m_vehLCS_2A4--;
+ if(m_vehLCS_2A4 == 0)
+ m_vehLCS_2A3 = -1;
+ }
+
if(bUsingSpecialColModel)
colModel = &CWorld::Players[CWorld::PlayerInFocus].m_ColModel;
else
@@ -320,7 +342,7 @@ CAutomobile::ProcessControl(void)
ScanForCrimes();
}
- // TODO(LCS): the fields used by this function are weird
+ // TODO(LCS)? re-inline this and change where bDriverLastFrame is set
ActivateBombWhenEntered();
// Process driver
@@ -394,7 +416,7 @@ CAutomobile::ProcessControl(void)
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){
+ pDriver && pDriver->GetPedState() != PED_EXIT_CAR && pDriver->GetPedState() != PED_DRAG_FROM_CAR && pDriver->GetPedState() != PED_ARRESTED && pDriver->GetPedState() != PED_STATE64){
// process control input if controlled by player
if(playerRemote || pDriver->m_nPedType == PEDTYPE_PLAYER1)
ProcessControlInputs(0);
@@ -419,7 +441,33 @@ CAutomobile::ProcessControl(void)
}else
m_vecCentreOfMass.z = pHandling->CentreOfMass.z;
- // TODO(LCS): some in air handling?
+ // in air handling
+ if(m_nWheelsOnGround == 0 &&
+ GetVehicleAppearance() != VEHICLE_APPEARANCE_PLANE && GetVehicleAppearance() != VEHICLE_APPEARANCE_HELI){
+ float turnForce = m_fTurnMass * CAR_INAIR_ROTF;
+ turnForce *= Min(3000.0f/m_fTurnMass, 1.0f);
+ if(CPad::GetPad(0)->GetHandBrake()){
+ float upRot = DotProduct(m_vecTurnSpeed, GetUp());
+ if(upRot < CAR_INAIR_ROTLIM && CPad::GetPad(0)->GetSteeringLeftRight() < 0.0f ||
+ upRot > -CAR_INAIR_ROTLIM && CPad::GetPad(0)->GetSteeringLeftRight() > 0.0f)
+ ApplyTurnForce(GetRight() * turnForce * (CPad::GetPad(0)->GetSteeringLeftRight()/128.0f) * CTimer::GetTimeStep(),
+ m_vecCentreOfMass + GetForward());
+ }else if(!CPad::GetPad(0)->GetAccelerate()){
+ float fwdRot = DotProduct(m_vecTurnSpeed, GetForward());
+ if(fwdRot < CAR_INAIR_ROTLIM && CPad::GetPad(0)->GetSteeringLeftRight() < 0.0f ||
+ fwdRot > -CAR_INAIR_ROTLIM && CPad::GetPad(0)->GetSteeringLeftRight() > 0.0f)
+ ApplyTurnForce(GetRight() * turnForce * (CPad::GetPad(0)->GetSteeringLeftRight()/128.0f) * CTimer::GetTimeStep(),
+ m_vecCentreOfMass + GetUp());
+ }
+
+ if(!CPad::GetPad(0)->GetAccelerate()){
+ float rightRot = DotProduct(m_vecTurnSpeed, GetRight());
+ if(rightRot < CAR_INAIR_ROTLIM && CPad::GetPad(0)->GetSteeringUpDown() < 0.0f ||
+ rightRot > -CAR_INAIR_ROTLIM && CPad::GetPad(0)->GetSteeringUpDown() > 0.0f)
+ ApplyTurnForce(GetUp() * turnForce * (CPad::GetPad(0)->GetSteeringUpDown()/128.0f) * CTimer::GetTimeStep(),
+ m_vecCentreOfMass + GetForward());
+ }
+ }
if(bHoverCheat)
DoHoverSuspensionRatios();
@@ -632,8 +680,7 @@ CAutomobile::ProcessControl(void)
TankControl();
BlowUpCarsInPath();
break;
- // LCS: this is gone but i'm keeping it!
- case MI_YARDIE:
+ case MI_VOODOO:
HydraulicControl();
break;
default:
@@ -891,6 +938,7 @@ CAutomobile::ProcessControl(void)
if(FindPlayerVehicle() && FindPlayerVehicle() == this)
if(CPad::GetPad(0)->CarGunJustDown())
+ // TODO(LCS)? re-inline this from CVehicle
ActivateBomb();
if(FindPlayerVehicle() != this && (strongGrip1 || CVehicle::bCheat3)){
@@ -924,26 +972,31 @@ CAutomobile::ProcessControl(void)
}
*/
+ static float magicValue = 4.0f;
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);
+ if(magicValue > 0.0f){
+ // looks like a bug with the wheel ids here, why only left wheels?
+ if(fwdSpeed > 0.01f && (m_aWheelTimer[CARWHEEL_FRONT_LEFT] > 0.0f || m_aWheelTimer[CARWHEEL_REAR_LEFT] > 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 = magicValue * traction * adhesion * 4.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;
+ }else
+ steerRange = 1.0f;
+ }
+
m_fSteerAngle *= steerRange;
brake = m_fBrakePedal * pHandling->fBrakeDeceleration * CTimer::GetTimeStep();
@@ -964,7 +1017,7 @@ CAutomobile::ProcessControl(void)
float wheelPos = colModel->lines[i].p0.z;
if(m_aSuspensionSpringRatio[i] > 0.0f)
wheelPos -= m_aSuspensionSpringRatio[i]*m_aSuspensionSpringLength[i];
- if(GetModelIndex() == MI_YARDIE && bUsingSpecialColModel) // not original LCS
+ if(GetModelIndex() == MI_VOODOO && bUsingSpecialColModel)
m_aWheelPosition[i] = wheelPos;
else
m_aWheelPosition[i] += (wheelPos - m_aWheelPosition[i])*0.75f;
@@ -978,13 +1031,13 @@ CAutomobile::ProcessControl(void)
}else{
if(UsesSiren()){
if(Pads[0].bHornHistory[Pads[0].iCurrHornHistory]){
- if(Pads[0].bHornHistory[(Pads[0].iCurrHornHistory+4) % 5] &&
- Pads[0].bHornHistory[(Pads[0].iCurrHornHistory+3) % 5])
+ if(Pads[0].bHornHistory[(Pads[0].iCurrHornHistory+CPad::HORNHISTORY_SIZE-1) % CPad::HORNHISTORY_SIZE] &&
+ Pads[0].bHornHistory[(Pads[0].iCurrHornHistory+1) % CPad::HORNHISTORY_SIZE])
m_nCarHornTimer = 1;
else
m_nCarHornTimer = 0;
- }else if(Pads[0].bHornHistory[(Pads[0].iCurrHornHistory+4) % 5] &&
- !Pads[0].bHornHistory[(Pads[0].iCurrHornHistory+1) % 5]){
+ }else if(Pads[0].bHornHistory[(Pads[0].iCurrHornHistory+CPad::HORNHISTORY_SIZE-1) % CPad::HORNHISTORY_SIZE] &&
+ !Pads[0].bHornHistory[(Pads[0].iCurrHornHistory+1) % CPad::HORNHISTORY_SIZE]){
m_nCarHornTimer = 0;
m_bSirenOrAlarm = !m_bSirenOrAlarm;
}else
@@ -1009,10 +1062,14 @@ CAutomobile::ProcessControl(void)
if(GetStatus() != STATUS_PLAYER && GetStatus() != STATUS_PLAYER_REMOTE && GetStatus() != STATUS_PHYSICS){
if(IsRealHeli()){
bEngineOn = false;
- m_aWheelSpeed[1] = Max(m_aWheelSpeed[1]-0.0005f, 0.0f);
- if(GetModelIndex() != MI_RCRAIDER && GetModelIndex() != MI_RCGOBLIN)
- if(m_aWheelSpeed[1] < 0.154f && m_aWheelSpeed[1] > 0.0044f)
- playRotorSound = true;
+ if(GetStatus() == STATUS_WRECKED)
+ m_aWheelSpeed[1] = 0.0f;
+ else{
+ m_aWheelSpeed[1] = Max(m_aWheelSpeed[1]-0.0005f, 0.0f);
+ if(GetModelIndex() != MI_RCRAIDER && GetModelIndex() != MI_RCGOBLIN)
+ if(m_aWheelSpeed[1] < 0.154f && m_aWheelSpeed[1] > 0.0044f)
+ playRotorSound = true;
+ }
}
}else if(isPlane && m_vecMoveSpeed.Magnitude() > 0.0f && CTimer::GetTimeStep() > 0.0f){
if(GetModelIndex() == MI_DODO)
@@ -1082,7 +1139,7 @@ CAutomobile::ProcessControl(void)
source = GetMatrix()*source + Max(DotProduct(m_vecMoveSpeed, GetForward()), 0.0f)*GetForward()*CTimer::GetTimeStep();
gun.FireProjectile(this, &source, 0.0f);
- CStats::RoundsFiredByPlayer++;
+// CStats::RoundsFiredByPlayer++;
DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f);
m_nGunFiringTime = CTimer::GetTimeInMilliseconds();
// Hunter gun
@@ -1092,7 +1149,7 @@ CAutomobile::ProcessControl(void)
source = GetMatrix()*source + m_vecMoveSpeed*CTimer::GetTimeStep();
gun.FireInstantHit(this, &source);
gun.AddGunshell(this, source, CVector2D(0.0f, 0.1f), 0.025f);
- CStats::RoundsFiredByPlayer++;
+// CStats::RoundsFiredByPlayer++;
DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f);
m_nGunFiringTime = CTimer::GetTimeInMilliseconds();
}
@@ -1104,7 +1161,7 @@ CAutomobile::ProcessControl(void)
source = GetMatrix()*source + m_vecMoveSpeed*CTimer::GetTimeStep();
gun.FireInstantHit(this, &source);
gun.AddGunshell(this, source, CVector2D(0.0f, 0.1f), 0.025f);
- CStats::RoundsFiredByPlayer++;
+// CStats::RoundsFiredByPlayer++;
DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f);
m_nGunFiringTime = CTimer::GetTimeInMilliseconds();
}
@@ -1123,9 +1180,9 @@ CAutomobile::ProcessControl(void)
CMatrix mat;
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_BONNET]));
CVector blade = mat.GetRight();
- blade = Multiply3x3(blade, GetMatrix());
+ blade = Multiply3x3(GetMatrix(), blade);
camDist /= Max(Sqrt(distSq), 0.01f);
- if(Abs(DotProduct(camDist, blade)) > 0.95f){
+ if(Abs(DotProduct(camDist, blade)) > HELI_ROTOR_DOTPROD_LIMIT){
DMAudio.PlayOneShot(m_audioEntityId, SOUND_HELI_BLADE, 0.0f);
m_fPropellerRotation = m_aWheelRotation[1];
}
@@ -1205,9 +1262,10 @@ CAutomobile::ProcessControl(void)
float suspShake = 0.0f;
float surfShake = 0.0f;
float speedsq = m_vecMoveSpeed.MagnitudeSqr();
+ float wheelSpin = 0.0f;
for(i = 0; i < 4; i++){
float suspChange = m_aSuspensionSpringRatioPrev[i] - m_aSuspensionSpringRatio[i];
- if(suspChange > 0.3f && !drivingInSand && speedsq > 0.04f){
+ if(suspChange > 0.1f && !drivingInSand && speedsq > SQR(0.2f)){
if(Damage.GetWheelStatus(i) == WHEEL_STATUS_BURST)
DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_JUMP_2, suspChange);
else
@@ -1232,10 +1290,27 @@ CAutomobile::ProcessControl(void)
// BUG: this only observes one of the wheels
TheCamera.m_bVehicleSuspenHigh = Abs(suspChange) > 0.05f;
+ if((i == CARWHEEL_FRONT_LEFT || i == CARWHEEL_FRONT_RIGHT) && mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier) ||
+ (i == CARWHEEL_REAR_LEFT || i == CARWHEEL_REAR_RIGHT) && mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier))
+ wheelSpin += WHEELSPIN_TARGET_RATE;
+ else if(m_aWheelState[i] == WHEEL_STATE_SPINNING)
+ wheelSpin += WHEELSPIN_INAIR_TARGET_RATE;
+
m_aSuspensionSpringRatioPrev[i] = m_aSuspensionSpringRatio[i];
m_aSuspensionSpringRatio[i] = 1.0f;
}
+ if(pHandling->Transmission.nDriveType == '4')
+ wheelSpin /= 4.0f;
+ else
+ wheelSpin /= 2.0f;
+ float spinChange;
+ if(wheelSpin < m_fWheelSpin)
+ spinChange = Pow(WHEELSPIN_FALL_RATE, CTimer::GetTimeStep());
+ else
+ spinChange = Pow(WHEELSPIN_RISE_RATE, CTimer::GetTimeStep());
+ m_fWheelSpin = m_fWheelSpin*spinChange + wheelSpin*(1.0f-spinChange);
+
// Shake pad
if(!drivingInSand && (suspShake > 0.0f || surfShake > 0.0f) && GetStatus() == STATUS_PLAYER){
@@ -1322,17 +1397,61 @@ CAutomobile::ProcessControl(void)
CVector(0.0f, 0.0f, 0.0f), nil, 0.7f, col, 0, 0, 0, 3000);
if(CWorld::TestSphereAgainstWorld(GetPosition(), 10.0f, this, true, false, false, false, false, false) ||
- GetPosition().z < 6.0f)
+ GetPosition().z < 0.0f)
if(!bRenderScorched){ // we already know this is true...
CExplosion::AddExplosion(this, nil, EXPLOSION_CAR, GetPosition(), 0);
bRenderScorched = true;
}
}
+
+ // The rest was in PreRender
+
+ bool onlyFrontWheels = false;
+ if(IsRealHeli()){
+ // Looks like LCS actually uses fmodf for the angles but VC has a loop...
+ // top rotor
+ m_aWheelRotation[1] += m_aWheelSpeed[1]*CTimer::GetTimeStep();
+ while(m_aWheelRotation[1] > TWOPI) m_aWheelRotation[1] -= TWOPI;
+ // rear rotor
+ m_aWheelRotation[3] += m_aWheelSpeed[1]*CTimer::GetTimeStep();
+ while(m_aWheelRotation[3] > TWOPI) m_aWheelRotation[3] -= TWOPI;
+ onlyFrontWheels = true;
+ }
+
+ CVehicleModelInfo *mi = GetModelInfo();
+ CVector contactPoints[4]; // relative to model
+ CVector contactSpeeds[4]; // speed at contact points
+ CVector frontWheelFwd = Multiply3x3(GetMatrix(), CVector(-Sin(m_fSteerAngle), Cos(m_fSteerAngle), 0.0f));
+ CVector rearWheelFwd = GetForward();
+ for(i = 0; i < 4; i++){
+ if (m_aWheelTimer[i] > 0.0f && (!onlyFrontWheels || i == CARWHEEL_FRONT_LEFT || i == CARWHEEL_FRONT_RIGHT)) {
+ contactPoints[i] = m_aWheelColPoints[i].point - GetPosition();
+ contactSpeeds[i] = GetSpeed(contactPoints[i]);
+ if (i == CARWHEEL_FRONT_LEFT || i == CARWHEEL_FRONT_RIGHT)
+ m_aWheelSpeed[i] = ProcessWheelRotation(m_aWheelState[i], frontWheelFwd, contactSpeeds[i], 0.5f*mi->m_wheelScale);
+ else
+ m_aWheelSpeed[i] = ProcessWheelRotation(m_aWheelState[i], rearWheelFwd, contactSpeeds[i], 0.5f*mi->m_wheelScale);
+ m_aWheelRotation[i] += m_aWheelSpeed[i];
+ }
+ }
+
+ if(GetModelIndex() == MI_DODO){
+ ProcessSwingingDoor(CAR_DOOR_LF, DOOR_FRONT_LEFT);
+ ProcessSwingingDoor(CAR_DOOR_RF, DOOR_FRONT_RIGHT);
+ }else if(GetModelIndex() == MI_RHINO){
+ }else if(IsRealHeli()){
+ }else{
+ ProcessSwingingDoor(CAR_DOOR_LF, DOOR_FRONT_LEFT);
+ ProcessSwingingDoor(CAR_DOOR_RF, DOOR_FRONT_RIGHT);
+ ProcessSwingingDoor(CAR_DOOR_LR, DOOR_REAR_LEFT);
+ ProcessSwingingDoor(CAR_DOOR_RR, DOOR_REAR_RIGHT);
+ ProcessSwingingDoor(CAR_BONNET, DOOR_BONNET);
+ ProcessSwingingDoor(CAR_BOOT, DOOR_BOOT);
+ }
}
#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)
{
@@ -2379,33 +2498,6 @@ CAutomobile::PreRender(void)
CMatrix mat;
CVector pos;
- bool onlyFrontWheels = false;
- if(IsRealHeli()){
- // top rotor
- m_aWheelRotation[1] += m_aWheelSpeed[1]*CTimer::GetTimeStep();
- if(m_aWheelRotation[1] > TWOPI) m_aWheelRotation[1] -= TWOPI;
- // rear rotor
- m_aWheelRotation[3] += m_aWheelSpeed[1]*CTimer::GetTimeStep();
- if(m_aWheelRotation[3] > TWOPI) m_aWheelRotation[3] -= TWOPI;
- onlyFrontWheels = true;
- }
-
- CVector contactPoints[4]; // relative to model
- CVector contactSpeeds[4]; // speed at contact points
- CVector frontWheelFwd = Multiply3x3(GetMatrix(), CVector(-Sin(m_fSteerAngle), Cos(m_fSteerAngle), 0.0f));
- CVector rearWheelFwd = GetForward();
- for(i = 0; i < 4; i++){
- if (m_aWheelTimer[i] > 0.0f && (!onlyFrontWheels || i == CARWHEEL_FRONT_LEFT || i == CARWHEEL_FRONT_RIGHT)) {
- contactPoints[i] = m_aWheelColPoints[i].point - GetPosition();
- contactSpeeds[i] = GetSpeed(contactPoints[i]);
- if (i == CARWHEEL_FRONT_LEFT || i == CARWHEEL_FRONT_RIGHT)
- m_aWheelSpeed[i] = ProcessWheelRotation(m_aWheelState[i], frontWheelFwd, contactSpeeds[i], 0.5f*mi->m_wheelScale);
- else
- m_aWheelSpeed[i] = ProcessWheelRotation(m_aWheelState[i], rearWheelFwd, contactSpeeds[i], 0.5f*mi->m_wheelScale);
- m_aWheelRotation[i] += m_aWheelSpeed[i];
- }
- }
-
RwRGBA hoverParticleCol = { 255, 255, 255, 32 };
// Rear right wheel
@@ -2593,9 +2685,6 @@ CAutomobile::PreRender(void)
mat.Translate(pos);
mat.UpdateRW();
}
-
- ProcessSwingingDoor(CAR_DOOR_LF, DOOR_FRONT_LEFT);
- ProcessSwingingDoor(CAR_DOOR_RF, DOOR_FRONT_RIGHT);
}else if(GetModelIndex() == MI_RHINO){
// Front right wheel
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_RF]));
@@ -2731,13 +2820,6 @@ CAutomobile::PreRender(void)
mat.Scale(mi->m_wheelScale);
mat.Translate(pos);
mat.UpdateRW();
-
- ProcessSwingingDoor(CAR_DOOR_LF, DOOR_FRONT_LEFT);
- ProcessSwingingDoor(CAR_DOOR_RF, DOOR_FRONT_RIGHT);
- ProcessSwingingDoor(CAR_DOOR_LR, DOOR_REAR_LEFT);
- ProcessSwingingDoor(CAR_DOOR_RR, DOOR_REAR_RIGHT);
- ProcessSwingingDoor(CAR_BONNET, DOOR_BONNET);
- ProcessSwingingDoor(CAR_BOOT, DOOR_BOOT);
}
if((GetModelIndex() == MI_PHEONIX || GetModelIndex() == MI_BFINJECT) &&
@@ -2788,6 +2870,7 @@ CAutomobile::Render(void)
{
CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
+ m_nSetPieceExtendedRangeTime = CTimer::GetTimeInMilliseconds() + 3000;
mi->SetVehicleColour(m_currentColour1, m_currentColour2);
if(IsRealHeli()){
@@ -2839,7 +2922,6 @@ CAutomobile::Render(void)
CEntity::Render();
}
-//--LCS: done
int32
CAutomobile::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints)
{
@@ -2911,7 +2993,6 @@ static float fMouseCentreRange = 0.35f;
static float fMouseSteerSens = -0.0035f;
static float fMouseCentreMult = 0.975f;
-//--LCS: done except TODO
void
CAutomobile::ProcessControlInputs(uint8 pad)
{
@@ -3036,12 +3117,12 @@ 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()){
+ if((CPad::GetPad(pad)->ArePlayerControlsDisabled() || CPad::GetPad(pad)->bApplyBrakes || m_bSuperBrake) &&
#else
- if(CPad::GetPad(0)->ArePlayerControlsDisabled()){
+ if((CPad::GetPad(0)->ArePlayerControlsDisabled() || CPad::GetPad(0)->bApplyBrakes || m_bSuperBrake) &&
#endif
+ (gMultiplayerSuperBrakeOnPause || m_bSuperBrake)){
m_fBrakePedal = 1.0f;
bIsHandbrakeOn = true;
m_fGasPedal = 0.0f;
@@ -3735,7 +3816,7 @@ CAutomobile::DoDriveByShootings(void)
if (!anim || !anim->IsRunning()) {
if (CPad::GetPad(0)->GetCarGunFired() && CTimer::GetTimeInMilliseconds() > weapon->m_nTimer) {
weapon->FireFromCar(this, lookingLeft, true);
- weapon->m_nTimer = CTimer::GetTimeInMilliseconds() + 70;
+ weapon->m_nTimer = CTimer::GetTimeInMilliseconds() + weapon->GetInfo()->m_nFiringRate;
}
}
}else{
@@ -3759,7 +3840,6 @@ CAutomobile::DoDriveByShootings(void)
}
}
-//--LCS: done
void
CAutomobile::DoHoverSuspensionRatios(void)
{
@@ -3789,10 +3869,10 @@ CAutomobile::DoHoverSuspensionRatios(void)
}else
m_aSuspensionSpringRatio[i] = 0.99999f;
- m_aWheelColPoints[i].point.x = (lower.x - upper.x)*m_aSuspensionSpringRatio[i] + upper.x;
- m_aWheelColPoints[i].point.y = (lower.y - upper.y)*m_aSuspensionSpringRatio[i] + upper.y;
- m_aWheelColPoints[i].point.z = waterZ;
- m_aWheelColPoints[i].normal = CVector(0.01f, 0.0f, 1.0f);
+ m_aWheelColPoints[i].point = CVector((lower.x - upper.x)*m_aSuspensionSpringRatio[i] + upper.x,
+ (lower.y - upper.y)*m_aSuspensionSpringRatio[i] + upper.y,
+ waterZ);
+ m_aWheelColPoints[i].normal = CVector(0.0f, 0.0f, 1.0f);
m_aWheelColPoints[i].surfaceB = SURFACE_WATER;
}
}
@@ -4168,6 +4248,7 @@ CAutomobile::dmgDrawCarCollidingParticles(const CVector &pos, float amount)
CVector(0.0f, 0.0f, 0.0f), nil, 0.5f);
n = (int)amount/50 + 1;
+ n = Min(n, 10);
for(i = 0; i < n; i++)
CParticle::AddParticle(PARTICLE_CAR_DEBRIS, pos,
CVector(CGeneral::GetRandomNumberInRange(-0.25f, 0.25f),
@@ -4176,9 +4257,9 @@ CAutomobile::dmgDrawCarCollidingParticles(const CVector &pos, float amount)
nil,
CGeneral::GetRandomNumberInRange(0.02f, 0.08f),
CVehicleModelInfo::mspInfo->ms_vehicleColourTable[m_currentColour1],
- CGeneral::GetRandomNumberInRange(-40.0f, 40.0f),
+ CGeneral::GetRandomNumberInRange(-40, 40),
0,
- CGeneral::GetRandomNumberInRange(0.0f, 4.0f));
+ CGeneral::GetRandomNumberInRange(0, 4));
}
void
@@ -4410,7 +4491,9 @@ CAutomobile::OpenDoor(int32 component, eDoors door, float openRatio)
if(Damage.GetDoorStatus(door) == DOOR_STATUS_SWINGING)
Damage.SetDoorStatus(door, DOOR_STATUS_OK); // huh?
ShowAllComps();
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_DOOR_CLOSE_BONNET + door, 0.0f);
+ // TODO(LCS): this makes no sense at all to me
+ if(component != CAR_DOOR_LR || IsDoorReady(DOOR_REAR_RIGHT))
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_DOOR_CLOSE_BONNET + door, 0.0f);
}
axes[Doors[door].m_nAxis] = Doors[door].m_fAngle;
@@ -4709,6 +4792,8 @@ CAutomobile::SetUpWheelColModel(CColModel *colModel)
return true;
}
+float fBurstForceMult = 0.03f;
+
void
CAutomobile::BurstTyre(uint8 wheel, bool applyForces)
{
@@ -4734,8 +4819,8 @@ CAutomobile::BurstTyre(uint8 wheel, bool applyForces)
}
if(applyForces){
- ApplyMoveForce(GetRight() * m_fMass * CGeneral::GetRandomNumberInRange(-0.03f, 0.03f));
- ApplyTurnForce(GetRight() * m_fTurnMass * CGeneral::GetRandomNumberInRange(-0.03f, 0.03f), GetForward());
+ ApplyMoveForce(GetRight() * m_fMass * CGeneral::GetRandomNumberInRange(-fBurstForceMult, fBurstForceMult));
+ ApplyTurnForce(GetRight() * m_fTurnMass * CGeneral::GetRandomNumberInRange(-fBurstForceMult, fBurstForceMult), GetForward());
}
}
}
@@ -4782,7 +4867,7 @@ CAutomobile::IsRoomForPedToLeaveCar(uint32 component, CVector *doorOffset)
CVector dist = doorPos - seatPos;
- // Removing that makes thiProcessEntityCollisions func. return false for van doors.
+ // Removing that makes this func. return false for van doors.
doorPos.z += 0.5f;
float length = dist.Magnitude();
CVector pedPos = seatPos + dist*((length+0.6f)/length);
@@ -4813,7 +4898,9 @@ CAutomobile::PlayCarHorn(void)
{
uint32 r;
- if (IsAlarmOn() || m_nCarHornTimer != 0)
+ if (IsAlarmOn() ||
+ this == FindPlayerVehicle() && CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle ||
+ m_nCarHornTimer != 0)
return;
if (m_nCarHornDelay) {
@@ -4856,7 +4943,6 @@ CAutomobile::ResetSuspension(void)
}
}
-//--LCS: done
void
CAutomobile::SetupSuspensionLines(void)
{
@@ -4949,6 +5035,7 @@ CAutomobile::BlowUpCarsInPath(void)
for(i = 0; i < m_nCollisionRecords; i++)
if(m_aCollisionRecords[i] &&
m_aCollisionRecords[i]->IsVehicle() &&
+ IsVehiclePointerValid((CVehicle*)m_aCollisionRecords[i]) &&
m_aCollisionRecords[i]->GetModelIndex() != MI_RHINO &&
!m_aCollisionRecords[i]->bRenderScorched){
if(this == FindPlayerVehicle())
@@ -5243,6 +5330,7 @@ CAutomobile::Fix(void)
for(component = 0; component < 4; component++)
Damage.SetWheelStatus(component, WHEEL_STATUS_OK);
+/*
if(GetModelIndex() == MI_HUNTER){
RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LB]), 0);
RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RB]), 0);
@@ -5252,6 +5340,7 @@ CAutomobile::Fix(void)
RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LB]), 0);
RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RB]), 0);
}
+*/
}
void
@@ -5458,13 +5547,14 @@ CAutomobile::SetPanelDamage(int32 component, ePanels panel, bool noFlyingCompone
if(m_aCarNodes[component] == nil)
return;
if(status == PANEL_STATUS_SMASHED1){
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_WINDSHIELD_CRACK, 0.0f);
+ if(panel == VEHPANEL_WINDSCREEN)
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_WINDSHIELD_CRACK, 0.0f);
// show damaged part
SetComponentVisibility(m_aCarNodes[component], ATOMIC_FLAG_DAM);
}else if(status == PANEL_STATUS_MISSING){
if(!noFlyingComponents)
SpawnFlyingComponent(component, COMPGROUP_PANEL);
- else
+ else if(panel == VEHPANEL_WINDSCREEN)
CGlass::CarWindscreenShatters(this, false);
// hide both
SetComponentVisibility(m_aCarNodes[component], ATOMIC_FLAG_NONE);
diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h
index 4f4ab500..a6f380c9 100644
--- a/src/vehicles/Automobile.h
+++ b/src/vehicles/Automobile.h
@@ -39,6 +39,7 @@ public:
uint8 m_bombType : 3;
#endif
uint8 bTaxiLight : 1;
+ uint8 bUnknownFlag : 1; // new in LCS
uint8 bFixedColour : 1;
uint8 bBigWheels : 1;
uint8 bWaterTight : 1; // no damage for non-player peds
diff --git a/src/vehicles/Transmission.cpp b/src/vehicles/Transmission.cpp
index efc32079..18e5fa98 100644
--- a/src/vehicles/Transmission.cpp
+++ b/src/vehicles/Transmission.cpp
@@ -69,7 +69,6 @@ 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)
{
diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp
index 281311e8..7784bc07 100644
--- a/src/vehicles/Vehicle.cpp
+++ b/src/vehicles/Vehicle.cpp
@@ -53,7 +53,6 @@ bool CVehicle::bDisableRemoteDetonationOnContact;
bool CVehicle::m_bDisplayHandlingInfo;
#endif
float CVehicle::rcHeliHeightLimit = 60.0f;
-// unused from SA:
float CVehicle::WHEELSPIN_FALL_RATE = 0.7f;
float CVehicle::WHEELSPIN_RISE_RATE = 0.95f;
float CVehicle::WHEELSPIN_INAIR_TARGET_RATE = 10.0f;
@@ -82,15 +81,15 @@ CVehicle::CVehicle(uint8 CreatedBy)
int i;
m_fGasPedal = 0.0f;
- m_fBrakePedal = 0.0;
- m_vehLCS_264 = 0;
+ m_fBrakePedal = 0.0f;
+ m_fWheelSpin = 0.0f;
#if defined FIX_BUGS || !defined GTA_PSP
bRewardVehicle = false;
#endif
m_vehLCS_29E = 0;
m_vehLCS_29C = 0;
m_vehLCS_2A3 = -1;
- m_vehLCS_348 = false;
+ m_bSuperBrake = false; // probably for multiplayer
m_nCurrentGear = 1;
m_fChangeGearTime = 0.0f;
diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h
index dc044b53..fa2f988c 100644
--- a/src/vehicles/Vehicle.h
+++ b/src/vehicles/Vehicle.h
@@ -256,7 +256,7 @@ public:
int8 m_nPacManPickupsCarried;
uint8 m_nRoadblockType;
uint8 m_bGarageTurnedLightsOff;
- int32 m_vehLCS_264;
+ float m_fWheelSpin;
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;
@@ -280,8 +280,8 @@ public:
uint8 m_nRadioStation;
uint8 m_bRainAudioCounter;
uint8 m_bRainSamplesCounter;
- int8 m_vehLCS_2A3;
- int32 m_vehLCS_2A4; // haven't seen this used yet
+ int8 m_vehLCS_2A3; // enables 2A4
+ uint8 m_vehLCS_2A4; // some timer
uint32 m_nCarHornTimer;
uint8 m_nCarHornPattern;
uint8 m_bSirenOrAlarm;
@@ -292,7 +292,7 @@ public:
CStoredCollPoly m_aCollPolys[2]; // poly which is under front/rear part of car
float m_fSteerInput;
eVehicleType m_vehType;
- bool m_vehLCS_348;
+ bool m_bSuperBrake;
static void *operator new(size_t) throw();
static void *operator new(size_t sz, int slot) throw();
@@ -429,7 +429,6 @@ public:
static bool m_bDisplayHandlingInfo;
#endif
static float rcHeliHeightLimit;
- // unused from SA:
static float WHEELSPIN_FALL_RATE;
static float WHEELSPIN_RISE_RATE;
static float WHEELSPIN_INAIR_TARGET_RATE;