work on CAutomobile
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user