diff options
Diffstat (limited to 'src/vehicles/Automobile.cpp')
-rw-r--r-- | src/vehicles/Automobile.cpp | 1044 |
1 files changed, 492 insertions, 552 deletions
diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index 96b78fa6..810c1661 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; @@ -103,6 +104,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; @@ -148,10 +151,10 @@ 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->Dimension.x*pHandling->Dimension.z/m_fMass; + m_fAirResistance = pHandling->fDragMult > 0.01f ? pHandling->fDragMult*0.0005f : pHandling->fDragMult; m_fElasticity = 0.05f; m_fBuoyancy = pHandling->fBuoyancy; @@ -192,12 +195,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); @@ -205,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; @@ -235,6 +236,7 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy) bExplosionProof = true; bBulletProof = true; } + m_vehLCS_2A3 = -1; } void @@ -246,6 +248,8 @@ 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); @@ -263,6 +267,23 @@ CAutomobile::ProcessControl(void) 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 @@ -312,7 +333,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: @@ -321,16 +342,18 @@ CAutomobile::ProcessControl(void) ScanForCrimes(); } + // TODO(LCS)? re-inline this and change where bDriverLastFrame is set + 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()){ @@ -353,7 +376,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; @@ -373,11 +396,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(); } @@ -396,7 +415,8 @@ CAutomobile::ProcessControl(void) // fall through case STATUS_PLAYER: if(playerRemote || - pDriver && pDriver->GetPedState() != PED_EXIT_CAR && pDriver->GetPedState() != PED_DRAG_FROM_CAR && pDriver->GetPedState() != PED_ARRESTED){ + // TODO(LCS): ped state 64 + 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); @@ -421,6 +441,34 @@ CAutomobile::ProcessControl(void) }else m_vecCentreOfMass.z = pHandling->CentreOfMass.z; + // 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(); @@ -456,8 +504,6 @@ CAutomobile::ProcessControl(void) m_fBrakePedal = 1.0f; m_fGasPedal = 0.0f; } - if(CPad::GetPad(0)->CarGunJustDown()) - ActivateBomb(); break; case STATUS_SIMPLE: @@ -532,8 +578,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: @@ -627,9 +675,7 @@ CAutomobile::ProcessControl(void) // special control switch(GetModelIndex()){ - case MI_FIRETRUCK: - FireTruckControl(); - break; + // FireTruckControl in PreRender now case MI_RHINO: TankControl(); BlowUpCarsInPath(); @@ -724,7 +770,7 @@ CAutomobile::ProcessControl(void) ApplyTurnSpeed(); } bIsInSafePosition = true; - bIsStuck = false; + bIsStuck = false; } CPhysical::ProcessControl(); @@ -743,6 +789,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 @@ -766,10 +813,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); } } @@ -782,7 +832,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 || @@ -794,8 +844,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); } } @@ -817,7 +867,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 @@ -830,42 +880,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; @@ -896,16 +910,37 @@ 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()) + // TODO(LCS)? re-inline this from CVehicle + ActivateBomb(); + if(FindPlayerVehicle() != this && (strongGrip1 || CVehicle::bCheat3)){ traction *= 1.2f; acceleration *= 1.4f; @@ -915,429 +950,67 @@ 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; + // 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; } - }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; - } - m_aWheelRotation[CARWHEEL_REAR_RIGHT] += m_aWheelSpeed[CARWHEEL_REAR_RIGHT]; - } + 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()); } - - // 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); +*/ + + static float magicValue = 4.0f; + float steerRange; + 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 - 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); - } + steerRange = Min(magic/DEGTORAD(pHandling->fSteeringLock), 1.0f); + + }else + steerRange = 1.0f; } - // Process front wheels off ground + m_fSteerAngle *= steerRange; - 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]; - } - } + brake = m_fBrakePedal * pHandling->fBrakeDeceleration * CTimer::GetTimeStep(); + + 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++){ @@ -1349,14 +1022,6 @@ CAutomobile::ProcessControl(void) 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 @@ -1367,7 +1032,7 @@ CAutomobile::ProcessControl(void) if(UsesSiren()){ if(Pads[0].bHornHistory[Pads[0].iCurrHornHistory]){ if(Pads[0].bHornHistory[(Pads[0].iCurrHornHistory+CPad::HORNHISTORY_SIZE-1) % CPad::HORNHISTORY_SIZE] && - Pads[0].bHornHistory[(Pads[0].iCurrHornHistory+CPad::HORNHISTORY_SIZE-2) % CPad::HORNHISTORY_SIZE]) + Pads[0].bHornHistory[(Pads[0].iCurrHornHistory+1) % CPad::HORNHISTORY_SIZE]) m_nCarHornTimer = 1; else m_nCarHornTimer = 0; @@ -1397,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) @@ -1470,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 @@ -1480,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(); } @@ -1492,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(); } @@ -1593,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 > SQR(0.2f)){ + 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 @@ -1620,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){ @@ -1651,13 +1338,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(); @@ -1710,17 +1397,262 @@ 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) 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) { CWorld::Remove(this); @@ -1741,6 +1673,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; @@ -2047,6 +1984,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)); @@ -2054,6 +1992,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)); + */ } } @@ -2203,8 +2142,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, @@ -2539,7 +2477,7 @@ CAutomobile::PreRender(void) else CShadows::StoreShadowForVehicle(this, VEH_SHD_TYPE_CAR); - DoSunGlare(); +// DoSunGlare(); // Heli dust if(IsRealHeli() && m_aWheelSpeed[1] > 0.1125f && GetPosition().z < 30.0f){ @@ -2560,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(); - 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; - } - - 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 @@ -2774,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])); @@ -2912,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) && @@ -2969,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()){ @@ -3094,6 +2996,9 @@ static float fMouseCentreMult = 0.975f; 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() || @@ -3104,6 +3009,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(); @@ -3116,7 +3022,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; @@ -3210,10 +3118,11 @@ CAutomobile::ProcessControlInputs(uint8 pad) // Brake if player isn't in control // BUG: game always uses pad 0 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; @@ -3908,7 +3817,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{ @@ -4340,6 +4249,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), @@ -4347,7 +4257,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, 40), 0, CGeneral::GetRandomNumberInRange(0, 4)); @@ -4582,7 +4492,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; @@ -4987,7 +4899,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) { @@ -5038,6 +4952,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++){ @@ -5077,6 +4999,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 @@ -5099,6 +5036,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()) @@ -5393,6 +5331,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); @@ -5402,6 +5341,7 @@ CAutomobile::Fix(void) RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LB]), 0); RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RB]), 0); } +*/ } void |