From 2f92ccecb1b7200d5284986dd584f34493e005ec Mon Sep 17 00:00:00 2001 From: aap Date: Mon, 16 Aug 2021 00:19:09 +0200 Subject: work on CAutomobile --- src/vehicles/Automobile.cpp | 300 ++++++++++++++++++++++++++++---------------- 1 file changed, 195 insertions(+), 105 deletions(-) (limited to 'src/vehicles/Automobile.cpp') diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index 1625b1b2..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(); @@ -495,7 +543,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)); @@ -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); -- cgit v1.2.3