work on CAutomobile

This commit is contained in:
aap 2021-08-16 00:19:09 +02:00
parent 39d2c427e5
commit 2f92ccecb1
11 changed files with 218 additions and 127 deletions

View File

@ -140,7 +140,7 @@ class CPad
public: public:
enum enum
{ {
HORNHISTORY_SIZE = 5, HORNHISTORY_SIZE = 8,
DRUNK_STEERING_BUFFER_SIZE = 10, DRUNK_STEERING_BUFFER_SIZE = 10,
}; };
CControllerState NewState; CControllerState NewState;

View File

@ -95,6 +95,7 @@ bool gUseModelResources;
bool gUseResources; bool gUseResources;
bool gNASTY_NASTY_MEM_SHUTDOWN_HACK; // rather unused bool gNASTY_NASTY_MEM_SHUTDOWN_HACK; // rather unused
bool gbPreviewCity; // don't do worldstream-style rendering but traditional method bool gbPreviewCity; // don't do worldstream-style rendering but traditional method
bool gMultiplayerSuperBrakeOnPause = true;
float FramesPerSecond = 30.0f; float FramesPerSecond = 30.0f;

View File

@ -43,6 +43,7 @@ extern bool gUseModelResources;
extern bool gUseResources; extern bool gUseResources;
extern bool gNASTY_NASTY_MEM_SHUTDOWN_HACK; extern bool gNASTY_NASTY_MEM_SHUTDOWN_HACK;
extern bool gbPreviewCity; extern bool gbPreviewCity;
extern bool gMultiplayerSuperBrakeOnPause;
class CSprite2d; class CSprite2d;

View File

@ -22,7 +22,7 @@ public:
z = v.z; z = v.z;
} }
// (0,1,0) means no rotation. So get right vector and its atan // (0,1,0) means no rotation. So get right vector and its atan
float Heading(void) const { return Atan2(-x, y); } float Heading(void) const { return x == 0.0f && y == 0.0f ? 0.0f : Atan2(-x, y); }
float Magnitude(void) const { return Sqrt(x*x + y*y + z*z); } float Magnitude(void) const { return Sqrt(x*x + y*y + z*z); }
float MagnitudeSqr(void) const { return x*x + y*y + z*z; } float MagnitudeSqr(void) const { return x*x + y*y + z*z; }
float Magnitude2D(void) const { return Sqrt(x*x + y*y); } float Magnitude2D(void) const { return Sqrt(x*x + y*y); }

View File

@ -1090,15 +1090,18 @@ enum
MI_LAST_VEHICLE = MI_VCNMAV, MI_LAST_VEHICLE = MI_VCNMAV,
// these indices are sort of original // these indices are sort of original
// with these three i don't know which is which: // with these two i don't know which is which:
MI_RCBARON = -999,
MI_CADDY = -963, MI_CADDY = -963,
MI_BAGGAGE = -955, MI_BAGGAGE = -999,
MI_RCBARON = -955,
MI_COMET = -972, // ps2 CAutomobile::IsOpenTopCar
MI_SANDKING = -981, // ps2 CAutomobile::ProcessControl
MI_VOODOO = -984, // ps2 hydraulics
MI_SEASPAR = -986,
MI_SPARROW = -985,
// HACK HACK, hopefully temporary // HACK HACK, hopefully temporary
MI_SEASPAR = -2000, MI_FBIRANCH = -2000,
MI_SPARROW,
MI_FBIRANCH,
MI_VICECHEE, MI_VICECHEE,
MI_RIO, MI_RIO,
MI_SQUALO, MI_SQUALO,
@ -1108,11 +1111,8 @@ enum
MI_MARQUIS, MI_MARQUIS,
MI_SKIMMER, MI_SKIMMER,
MI_TROPIC, MI_TROPIC,
MI_SANDKING,
MI_VOODOO,
MI_CUBAN, MI_CUBAN,
MI_PHEONIX, MI_PHEONIX,
MI_COMET,
MI_SABRE, MI_SABRE,
MI_VIRGO, MI_VIRGO,
MI_RANCHER, MI_RANCHER,

View File

@ -428,7 +428,8 @@ enum PedState
PED_EXIT_CAR, PED_EXIT_CAR,
PED_HANDS_UP, PED_HANDS_UP,
PED_ARRESTED, PED_ARRESTED,
PED_DEPLOY_STINGER PED_DEPLOY_STINGER,
PED_STATE64
}; };
enum eMoveState { enum eMoveState {

View File

@ -86,6 +86,7 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
switch(GetModelIndex()){ switch(GetModelIndex()){
case MI_HUNTER: case MI_HUNTER:
case MI_ANGEL: case MI_ANGEL:
case MI_ANGEL2:
case MI_FREEWAY: case MI_FREEWAY:
m_nRadioStation = V_ROCK; m_nRadioStation = V_ROCK;
break; break;
@ -150,8 +151,8 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
for(i = 0; i < 6; i++) for(i = 0; i < 6; i++)
m_randomValues[i] = CGeneral::GetRandomNumberInRange(-0.15f, 0.15f); m_randomValues[i] = CGeneral::GetRandomNumberInRange(-0.15f, 0.15f);
m_fMass = pHandling->fMass; m_fMass = pHandling->GetMass();
m_fTurnMass = pHandling->fTurnMass; m_fTurnMass = pHandling->GetTurnMass();
m_vecCentreOfMass = pHandling->CentreOfMass; m_vecCentreOfMass = pHandling->CentreOfMass;
m_fAirResistance = pHandling->fDragMult > 0.01f ? pHandling->fDragMult*0.0005f : pHandling->fDragMult; m_fAirResistance = pHandling->fDragMult > 0.01f ? pHandling->fDragMult*0.0005f : pHandling->fDragMult;
m_fElasticity = 0.05f; m_fElasticity = 0.05f;
@ -201,6 +202,10 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
m_nNumPassengers = 0; m_nNumPassengers = 0;
m_pBombRigger = nil;
m_bombType = CARBOMB_NONE;
bUnknownFlag = false;
if(m_nDoorLock == CARLOCK_UNLOCKED && if(m_nDoorLock == CARLOCK_UNLOCKED &&
(id == MI_POLICE || id == MI_ENFORCER || id == MI_RHINO)) (id == MI_POLICE || id == MI_ENFORCER || id == MI_RHINO))
m_nDoorLock = CARLOCK_LOCKED_INITIALLY; m_nDoorLock = CARLOCK_LOCKED_INITIALLY;
@ -231,6 +236,7 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
bExplosionProof = true; bExplosionProof = true;
bBulletProof = true; bBulletProof = true;
} }
m_vehLCS_2A3 = -1;
} }
void void
@ -242,6 +248,9 @@ CAutomobile::SetModelIndex(uint32 id)
#define SAND_SLOWDOWN (0.01f) #define SAND_SLOWDOWN (0.01f)
float CAR_BALANCE_MULT = 0.3f; 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 vecSeaSparrowGunPos(-0.5f, 2.4f, -0.785f);
CVector vecHunterGunPos(0.0f, 4.8f, -1.3f); CVector vecHunterGunPos(0.0f, 4.8f, -1.3f);
CVector vecHunterRocketPos(2.5f, 1.0f, -0.5f); CVector vecHunterRocketPos(2.5f, 1.0f, -0.5f);
@ -253,15 +262,28 @@ CVector vecDAMAGE_ENGINE_POS_BIG(-0.5f, -0.3f, 0.0f);
void void
CAutomobile::ProcessControl(void) CAutomobile::ProcessControl(void)
{ {
// TODO(LCS):
// TheCamera can remove service vehicles
// some audio (?) stuff
int i; int i;
float wheelRot; float wheelRot;
CColModel *colModel; CColModel *colModel;
float brake = 0.0f; 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) if(bUsingSpecialColModel)
colModel = &CWorld::Players[CWorld::PlayerInFocus].m_ColModel; colModel = &CWorld::Players[CWorld::PlayerInFocus].m_ColModel;
else else
@ -320,7 +342,7 @@ CAutomobile::ProcessControl(void)
ScanForCrimes(); ScanForCrimes();
} }
// TODO(LCS): the fields used by this function are weird // TODO(LCS)? re-inline this and change where bDriverLastFrame is set
ActivateBombWhenEntered(); ActivateBombWhenEntered();
// Process driver // Process driver
@ -394,7 +416,7 @@ CAutomobile::ProcessControl(void)
case STATUS_PLAYER: case STATUS_PLAYER:
if(playerRemote || if(playerRemote ||
// TODO(LCS): ped state 64 // 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 // process control input if controlled by player
if(playerRemote || pDriver->m_nPedType == PEDTYPE_PLAYER1) if(playerRemote || pDriver->m_nPedType == PEDTYPE_PLAYER1)
ProcessControlInputs(0); ProcessControlInputs(0);
@ -419,7 +441,33 @@ CAutomobile::ProcessControl(void)
}else }else
m_vecCentreOfMass.z = pHandling->CentreOfMass.z; 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) if(bHoverCheat)
DoHoverSuspensionRatios(); DoHoverSuspensionRatios();
@ -495,7 +543,7 @@ CAutomobile::ProcessControl(void)
m_aSuspensionSpringRatio[1] < 1.0f && CSurfaceTable::GetAdhesionGroup(m_aWheelColPoints[1].surfaceB) == ADHESIVE_SAND || 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[2] < 1.0f && CSurfaceTable::GetAdhesionGroup(m_aWheelColPoints[2].surfaceB) == ADHESIVE_SAND ||
m_aSuspensionSpringRatio[3] < 1.0f && CSurfaceTable::GetAdhesionGroup(m_aWheelColPoints[3].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; bStuckInSand = true;
if(CWeather::WetRoads > 0.0f) if(CWeather::WetRoads > 0.0f)
ApplyMoveForce(m_vecMoveSpeed * -CTimer::GetTimeStep()*SAND_SLOWDOWN*m_fMass * (1.0f-CWeather::WetRoads)); ApplyMoveForce(m_vecMoveSpeed * -CTimer::GetTimeStep()*SAND_SLOWDOWN*m_fMass * (1.0f-CWeather::WetRoads));
@ -632,8 +680,7 @@ CAutomobile::ProcessControl(void)
TankControl(); TankControl();
BlowUpCarsInPath(); BlowUpCarsInPath();
break; break;
// LCS: this is gone but i'm keeping it! case MI_VOODOO:
case MI_YARDIE:
HydraulicControl(); HydraulicControl();
break; break;
default: default:
@ -891,6 +938,7 @@ CAutomobile::ProcessControl(void)
if(FindPlayerVehicle() && FindPlayerVehicle() == this) if(FindPlayerVehicle() && FindPlayerVehicle() == this)
if(CPad::GetPad(0)->CarGunJustDown()) if(CPad::GetPad(0)->CarGunJustDown())
// TODO(LCS)? re-inline this from CVehicle
ActivateBomb(); ActivateBomb();
if(FindPlayerVehicle() != this && (strongGrip1 || CVehicle::bCheat3)){ if(FindPlayerVehicle() != this && (strongGrip1 || CVehicle::bCheat3)){
@ -924,15 +972,18 @@ CAutomobile::ProcessControl(void)
} }
*/ */
static float magicValue = 4.0f;
float steerRange; float steerRange;
if(fwdSpeed > 0.01f && m_aWheelTimer[CARWHEEL_FRONT_LEFT] > 0.0f && m_aWheelTimer[CARWHEEL_FRONT_RIGHT] > 0.0f && GetStatus() == STATUS_PLAYER){ 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; CColPoint point;
point.surfaceA = SURFACE_WHEELBASE; point.surfaceA = SURFACE_WHEELBASE;
point.surfaceB = SURFACE_TARMAC; point.surfaceB = SURFACE_TARMAC;
float rightSpeed = DotProduct(m_vecMoveSpeed, GetRight()); float rightSpeed = DotProduct(m_vecMoveSpeed, GetRight());
float adhesion = CSurfaceTable::GetAdhesiveLimit(point); float adhesion = CSurfaceTable::GetAdhesiveLimit(point);
// i have no idea what's going on here // i have no idea what's going on here
float magic = traction * adhesion * 16.0f / SQR(fwdSpeed); float magic = magicValue * traction * adhesion * 4.0f / SQR(fwdSpeed);
magic = Clamp(magic, -1.0f, 1.0f); magic = Clamp(magic, -1.0f, 1.0f);
magic = Asin(magic); magic = Asin(magic);
if(m_fSteerAngle < 0.0f && rightSpeed > 0.05f || if(m_fSteerAngle < 0.0f && rightSpeed > 0.05f ||
@ -944,6 +995,8 @@ CAutomobile::ProcessControl(void)
}else }else
steerRange = 1.0f; steerRange = 1.0f;
}
m_fSteerAngle *= steerRange; m_fSteerAngle *= steerRange;
brake = m_fBrakePedal * pHandling->fBrakeDeceleration * CTimer::GetTimeStep(); brake = m_fBrakePedal * pHandling->fBrakeDeceleration * CTimer::GetTimeStep();
@ -964,7 +1017,7 @@ CAutomobile::ProcessControl(void)
float wheelPos = colModel->lines[i].p0.z; float wheelPos = colModel->lines[i].p0.z;
if(m_aSuspensionSpringRatio[i] > 0.0f) if(m_aSuspensionSpringRatio[i] > 0.0f)
wheelPos -= m_aSuspensionSpringRatio[i]*m_aSuspensionSpringLength[i]; wheelPos -= m_aSuspensionSpringRatio[i]*m_aSuspensionSpringLength[i];
if(GetModelIndex() == MI_YARDIE && bUsingSpecialColModel) // not original LCS if(GetModelIndex() == MI_VOODOO && bUsingSpecialColModel)
m_aWheelPosition[i] = wheelPos; m_aWheelPosition[i] = wheelPos;
else else
m_aWheelPosition[i] += (wheelPos - m_aWheelPosition[i])*0.75f; m_aWheelPosition[i] += (wheelPos - m_aWheelPosition[i])*0.75f;
@ -978,13 +1031,13 @@ CAutomobile::ProcessControl(void)
}else{ }else{
if(UsesSiren()){ if(UsesSiren()){
if(Pads[0].bHornHistory[Pads[0].iCurrHornHistory]){ if(Pads[0].bHornHistory[Pads[0].iCurrHornHistory]){
if(Pads[0].bHornHistory[(Pads[0].iCurrHornHistory+4) % 5] && if(Pads[0].bHornHistory[(Pads[0].iCurrHornHistory+CPad::HORNHISTORY_SIZE-1) % CPad::HORNHISTORY_SIZE] &&
Pads[0].bHornHistory[(Pads[0].iCurrHornHistory+3) % 5]) Pads[0].bHornHistory[(Pads[0].iCurrHornHistory+1) % CPad::HORNHISTORY_SIZE])
m_nCarHornTimer = 1; m_nCarHornTimer = 1;
else else
m_nCarHornTimer = 0; m_nCarHornTimer = 0;
}else if(Pads[0].bHornHistory[(Pads[0].iCurrHornHistory+4) % 5] && }else if(Pads[0].bHornHistory[(Pads[0].iCurrHornHistory+CPad::HORNHISTORY_SIZE-1) % CPad::HORNHISTORY_SIZE] &&
!Pads[0].bHornHistory[(Pads[0].iCurrHornHistory+1) % 5]){ !Pads[0].bHornHistory[(Pads[0].iCurrHornHistory+1) % CPad::HORNHISTORY_SIZE]){
m_nCarHornTimer = 0; m_nCarHornTimer = 0;
m_bSirenOrAlarm = !m_bSirenOrAlarm; m_bSirenOrAlarm = !m_bSirenOrAlarm;
}else }else
@ -1009,11 +1062,15 @@ CAutomobile::ProcessControl(void)
if(GetStatus() != STATUS_PLAYER && GetStatus() != STATUS_PLAYER_REMOTE && GetStatus() != STATUS_PHYSICS){ if(GetStatus() != STATUS_PLAYER && GetStatus() != STATUS_PLAYER_REMOTE && GetStatus() != STATUS_PHYSICS){
if(IsRealHeli()){ if(IsRealHeli()){
bEngineOn = false; bEngineOn = false;
if(GetStatus() == STATUS_WRECKED)
m_aWheelSpeed[1] = 0.0f;
else{
m_aWheelSpeed[1] = Max(m_aWheelSpeed[1]-0.0005f, 0.0f); m_aWheelSpeed[1] = Max(m_aWheelSpeed[1]-0.0005f, 0.0f);
if(GetModelIndex() != MI_RCRAIDER && GetModelIndex() != MI_RCGOBLIN) if(GetModelIndex() != MI_RCRAIDER && GetModelIndex() != MI_RCGOBLIN)
if(m_aWheelSpeed[1] < 0.154f && m_aWheelSpeed[1] > 0.0044f) if(m_aWheelSpeed[1] < 0.154f && m_aWheelSpeed[1] > 0.0044f)
playRotorSound = true; playRotorSound = true;
} }
}
}else if(isPlane && m_vecMoveSpeed.Magnitude() > 0.0f && CTimer::GetTimeStep() > 0.0f){ }else if(isPlane && m_vecMoveSpeed.Magnitude() > 0.0f && CTimer::GetTimeStep() > 0.0f){
if(GetModelIndex() == MI_DODO) if(GetModelIndex() == MI_DODO)
FlyingControl(FLIGHT_MODEL_DODO); FlyingControl(FLIGHT_MODEL_DODO);
@ -1082,7 +1139,7 @@ CAutomobile::ProcessControl(void)
source = GetMatrix()*source + Max(DotProduct(m_vecMoveSpeed, GetForward()), 0.0f)*GetForward()*CTimer::GetTimeStep(); source = GetMatrix()*source + Max(DotProduct(m_vecMoveSpeed, GetForward()), 0.0f)*GetForward()*CTimer::GetTimeStep();
gun.FireProjectile(this, &source, 0.0f); gun.FireProjectile(this, &source, 0.0f);
CStats::RoundsFiredByPlayer++; // CStats::RoundsFiredByPlayer++;
DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f); DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f);
m_nGunFiringTime = CTimer::GetTimeInMilliseconds(); m_nGunFiringTime = CTimer::GetTimeInMilliseconds();
// Hunter gun // Hunter gun
@ -1092,7 +1149,7 @@ CAutomobile::ProcessControl(void)
source = GetMatrix()*source + m_vecMoveSpeed*CTimer::GetTimeStep(); source = GetMatrix()*source + m_vecMoveSpeed*CTimer::GetTimeStep();
gun.FireInstantHit(this, &source); gun.FireInstantHit(this, &source);
gun.AddGunshell(this, source, CVector2D(0.0f, 0.1f), 0.025f); 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); DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f);
m_nGunFiringTime = CTimer::GetTimeInMilliseconds(); m_nGunFiringTime = CTimer::GetTimeInMilliseconds();
} }
@ -1104,7 +1161,7 @@ CAutomobile::ProcessControl(void)
source = GetMatrix()*source + m_vecMoveSpeed*CTimer::GetTimeStep(); source = GetMatrix()*source + m_vecMoveSpeed*CTimer::GetTimeStep();
gun.FireInstantHit(this, &source); gun.FireInstantHit(this, &source);
gun.AddGunshell(this, source, CVector2D(0.0f, 0.1f), 0.025f); 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); DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f);
m_nGunFiringTime = CTimer::GetTimeInMilliseconds(); m_nGunFiringTime = CTimer::GetTimeInMilliseconds();
} }
@ -1123,9 +1180,9 @@ CAutomobile::ProcessControl(void)
CMatrix mat; CMatrix mat;
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_BONNET])); mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_BONNET]));
CVector blade = mat.GetRight(); CVector blade = mat.GetRight();
blade = Multiply3x3(blade, GetMatrix()); blade = Multiply3x3(GetMatrix(), blade);
camDist /= Max(Sqrt(distSq), 0.01f); 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); DMAudio.PlayOneShot(m_audioEntityId, SOUND_HELI_BLADE, 0.0f);
m_fPropellerRotation = m_aWheelRotation[1]; m_fPropellerRotation = m_aWheelRotation[1];
} }
@ -1205,9 +1262,10 @@ CAutomobile::ProcessControl(void)
float suspShake = 0.0f; float suspShake = 0.0f;
float surfShake = 0.0f; float surfShake = 0.0f;
float speedsq = m_vecMoveSpeed.MagnitudeSqr(); float speedsq = m_vecMoveSpeed.MagnitudeSqr();
float wheelSpin = 0.0f;
for(i = 0; i < 4; i++){ for(i = 0; i < 4; i++){
float suspChange = m_aSuspensionSpringRatioPrev[i] - m_aSuspensionSpringRatio[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) if(Damage.GetWheelStatus(i) == WHEEL_STATUS_BURST)
DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_JUMP_2, suspChange); DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_JUMP_2, suspChange);
else else
@ -1232,10 +1290,27 @@ CAutomobile::ProcessControl(void)
// BUG: this only observes one of the wheels // BUG: this only observes one of the wheels
TheCamera.m_bVehicleSuspenHigh = Abs(suspChange) > 0.05f; 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_aSuspensionSpringRatioPrev[i] = m_aSuspensionSpringRatio[i];
m_aSuspensionSpringRatio[i] = 1.0f; 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 // Shake pad
if(!drivingInSand && (suspShake > 0.0f || surfShake > 0.0f) && GetStatus() == STATUS_PLAYER){ 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); 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) || 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... if(!bRenderScorched){ // we already know this is true...
CExplosion::AddExplosion(this, nil, EXPLOSION_CAR, GetPosition(), 0); CExplosion::AddExplosion(this, nil, EXPLOSION_CAR, GetPosition(), 0);
bRenderScorched = true; 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) #pragma optimize("", on)
//--LCS: done
void void
CAutomobile::ProcessCarWheelPair(int leftWheel, int rightWheel, float steerAngle, CVector *contactSpeeds, CVector *contactPoints, float traction, float acceleration, float brake, bool bFront) 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; CMatrix mat;
CVector pos; 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 }; RwRGBA hoverParticleCol = { 255, 255, 255, 32 };
// Rear right wheel // Rear right wheel
@ -2593,9 +2685,6 @@ CAutomobile::PreRender(void)
mat.Translate(pos); mat.Translate(pos);
mat.UpdateRW(); mat.UpdateRW();
} }
ProcessSwingingDoor(CAR_DOOR_LF, DOOR_FRONT_LEFT);
ProcessSwingingDoor(CAR_DOOR_RF, DOOR_FRONT_RIGHT);
}else if(GetModelIndex() == MI_RHINO){ }else if(GetModelIndex() == MI_RHINO){
// Front right wheel // Front right wheel
mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_RF])); mat.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_RF]));
@ -2731,13 +2820,6 @@ CAutomobile::PreRender(void)
mat.Scale(mi->m_wheelScale); mat.Scale(mi->m_wheelScale);
mat.Translate(pos); mat.Translate(pos);
mat.UpdateRW(); 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) && if((GetModelIndex() == MI_PHEONIX || GetModelIndex() == MI_BFINJECT) &&
@ -2788,6 +2870,7 @@ CAutomobile::Render(void)
{ {
CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()); CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
m_nSetPieceExtendedRangeTime = CTimer::GetTimeInMilliseconds() + 3000;
mi->SetVehicleColour(m_currentColour1, m_currentColour2); mi->SetVehicleColour(m_currentColour1, m_currentColour2);
if(IsRealHeli()){ if(IsRealHeli()){
@ -2839,7 +2922,6 @@ CAutomobile::Render(void)
CEntity::Render(); CEntity::Render();
} }
//--LCS: done
int32 int32
CAutomobile::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints) CAutomobile::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints)
{ {
@ -2911,7 +2993,6 @@ static float fMouseCentreRange = 0.35f;
static float fMouseSteerSens = -0.0035f; static float fMouseSteerSens = -0.0035f;
static float fMouseCentreMult = 0.975f; static float fMouseCentreMult = 0.975f;
//--LCS: done except TODO
void void
CAutomobile::ProcessControlInputs(uint8 pad) CAutomobile::ProcessControlInputs(uint8 pad)
{ {
@ -3036,12 +3117,12 @@ CAutomobile::ProcessControlInputs(uint8 pad)
// Brake if player isn't in control // Brake if player isn't in control
// BUG: game always uses pad 0 here // BUG: game always uses pad 0 here
// TODO(LCS): more conditions here
#ifdef FIX_BUGS #ifdef FIX_BUGS
if(CPad::GetPad(pad)->ArePlayerControlsDisabled()){ if((CPad::GetPad(pad)->ArePlayerControlsDisabled() || CPad::GetPad(pad)->bApplyBrakes || m_bSuperBrake) &&
#else #else
if(CPad::GetPad(0)->ArePlayerControlsDisabled()){ if((CPad::GetPad(0)->ArePlayerControlsDisabled() || CPad::GetPad(0)->bApplyBrakes || m_bSuperBrake) &&
#endif #endif
(gMultiplayerSuperBrakeOnPause || m_bSuperBrake)){
m_fBrakePedal = 1.0f; m_fBrakePedal = 1.0f;
bIsHandbrakeOn = true; bIsHandbrakeOn = true;
m_fGasPedal = 0.0f; m_fGasPedal = 0.0f;
@ -3735,7 +3816,7 @@ CAutomobile::DoDriveByShootings(void)
if (!anim || !anim->IsRunning()) { if (!anim || !anim->IsRunning()) {
if (CPad::GetPad(0)->GetCarGunFired() && CTimer::GetTimeInMilliseconds() > weapon->m_nTimer) { if (CPad::GetPad(0)->GetCarGunFired() && CTimer::GetTimeInMilliseconds() > weapon->m_nTimer) {
weapon->FireFromCar(this, lookingLeft, true); weapon->FireFromCar(this, lookingLeft, true);
weapon->m_nTimer = CTimer::GetTimeInMilliseconds() + 70; weapon->m_nTimer = CTimer::GetTimeInMilliseconds() + weapon->GetInfo()->m_nFiringRate;
} }
} }
}else{ }else{
@ -3759,7 +3840,6 @@ CAutomobile::DoDriveByShootings(void)
} }
} }
//--LCS: done
void void
CAutomobile::DoHoverSuspensionRatios(void) CAutomobile::DoHoverSuspensionRatios(void)
{ {
@ -3789,10 +3869,10 @@ CAutomobile::DoHoverSuspensionRatios(void)
}else }else
m_aSuspensionSpringRatio[i] = 0.99999f; m_aSuspensionSpringRatio[i] = 0.99999f;
m_aWheelColPoints[i].point.x = (lower.x - upper.x)*m_aSuspensionSpringRatio[i] + upper.x; m_aWheelColPoints[i].point = CVector((lower.x - upper.x)*m_aSuspensionSpringRatio[i] + upper.x,
m_aWheelColPoints[i].point.y = (lower.y - upper.y)*m_aSuspensionSpringRatio[i] + upper.y; (lower.y - upper.y)*m_aSuspensionSpringRatio[i] + upper.y,
m_aWheelColPoints[i].point.z = waterZ; waterZ);
m_aWheelColPoints[i].normal = CVector(0.01f, 0.0f, 1.0f); m_aWheelColPoints[i].normal = CVector(0.0f, 0.0f, 1.0f);
m_aWheelColPoints[i].surfaceB = SURFACE_WATER; 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); CVector(0.0f, 0.0f, 0.0f), nil, 0.5f);
n = (int)amount/50 + 1; n = (int)amount/50 + 1;
n = Min(n, 10);
for(i = 0; i < n; i++) for(i = 0; i < n; i++)
CParticle::AddParticle(PARTICLE_CAR_DEBRIS, pos, CParticle::AddParticle(PARTICLE_CAR_DEBRIS, pos,
CVector(CGeneral::GetRandomNumberInRange(-0.25f, 0.25f), CVector(CGeneral::GetRandomNumberInRange(-0.25f, 0.25f),
@ -4176,9 +4257,9 @@ CAutomobile::dmgDrawCarCollidingParticles(const CVector &pos, float amount)
nil, nil,
CGeneral::GetRandomNumberInRange(0.02f, 0.08f), CGeneral::GetRandomNumberInRange(0.02f, 0.08f),
CVehicleModelInfo::mspInfo->ms_vehicleColourTable[m_currentColour1], CVehicleModelInfo::mspInfo->ms_vehicleColourTable[m_currentColour1],
CGeneral::GetRandomNumberInRange(-40.0f, 40.0f), CGeneral::GetRandomNumberInRange(-40, 40),
0, 0,
CGeneral::GetRandomNumberInRange(0.0f, 4.0f)); CGeneral::GetRandomNumberInRange(0, 4));
} }
void void
@ -4410,6 +4491,8 @@ CAutomobile::OpenDoor(int32 component, eDoors door, float openRatio)
if(Damage.GetDoorStatus(door) == DOOR_STATUS_SWINGING) if(Damage.GetDoorStatus(door) == DOOR_STATUS_SWINGING)
Damage.SetDoorStatus(door, DOOR_STATUS_OK); // huh? Damage.SetDoorStatus(door, DOOR_STATUS_OK); // huh?
ShowAllComps(); ShowAllComps();
// 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); DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_DOOR_CLOSE_BONNET + door, 0.0f);
} }
@ -4709,6 +4792,8 @@ CAutomobile::SetUpWheelColModel(CColModel *colModel)
return true; return true;
} }
float fBurstForceMult = 0.03f;
void void
CAutomobile::BurstTyre(uint8 wheel, bool applyForces) CAutomobile::BurstTyre(uint8 wheel, bool applyForces)
{ {
@ -4734,8 +4819,8 @@ CAutomobile::BurstTyre(uint8 wheel, bool applyForces)
} }
if(applyForces){ if(applyForces){
ApplyMoveForce(GetRight() * m_fMass * CGeneral::GetRandomNumberInRange(-0.03f, 0.03f)); ApplyMoveForce(GetRight() * m_fMass * CGeneral::GetRandomNumberInRange(-fBurstForceMult, fBurstForceMult));
ApplyTurnForce(GetRight() * m_fTurnMass * CGeneral::GetRandomNumberInRange(-0.03f, 0.03f), GetForward()); ApplyTurnForce(GetRight() * m_fTurnMass * CGeneral::GetRandomNumberInRange(-fBurstForceMult, fBurstForceMult), GetForward());
} }
} }
} }
@ -4782,7 +4867,7 @@ CAutomobile::IsRoomForPedToLeaveCar(uint32 component, CVector *doorOffset)
CVector dist = doorPos - seatPos; 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; doorPos.z += 0.5f;
float length = dist.Magnitude(); float length = dist.Magnitude();
CVector pedPos = seatPos + dist*((length+0.6f)/length); CVector pedPos = seatPos + dist*((length+0.6f)/length);
@ -4813,7 +4898,9 @@ CAutomobile::PlayCarHorn(void)
{ {
uint32 r; uint32 r;
if (IsAlarmOn() || m_nCarHornTimer != 0) if (IsAlarmOn() ||
this == FindPlayerVehicle() && CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle ||
m_nCarHornTimer != 0)
return; return;
if (m_nCarHornDelay) { if (m_nCarHornDelay) {
@ -4856,7 +4943,6 @@ CAutomobile::ResetSuspension(void)
} }
} }
//--LCS: done
void void
CAutomobile::SetupSuspensionLines(void) CAutomobile::SetupSuspensionLines(void)
{ {
@ -4949,6 +5035,7 @@ CAutomobile::BlowUpCarsInPath(void)
for(i = 0; i < m_nCollisionRecords; i++) for(i = 0; i < m_nCollisionRecords; i++)
if(m_aCollisionRecords[i] && if(m_aCollisionRecords[i] &&
m_aCollisionRecords[i]->IsVehicle() && m_aCollisionRecords[i]->IsVehicle() &&
IsVehiclePointerValid((CVehicle*)m_aCollisionRecords[i]) &&
m_aCollisionRecords[i]->GetModelIndex() != MI_RHINO && m_aCollisionRecords[i]->GetModelIndex() != MI_RHINO &&
!m_aCollisionRecords[i]->bRenderScorched){ !m_aCollisionRecords[i]->bRenderScorched){
if(this == FindPlayerVehicle()) if(this == FindPlayerVehicle())
@ -5243,6 +5330,7 @@ CAutomobile::Fix(void)
for(component = 0; component < 4; component++) for(component = 0; component < 4; component++)
Damage.SetWheelStatus(component, WHEEL_STATUS_OK); Damage.SetWheelStatus(component, WHEEL_STATUS_OK);
/*
if(GetModelIndex() == MI_HUNTER){ if(GetModelIndex() == MI_HUNTER){
RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LB]), 0); RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LB]), 0);
RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RB]), 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_LB]), 0);
RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RB]), 0); RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RB]), 0);
} }
*/
} }
void void
@ -5458,13 +5547,14 @@ CAutomobile::SetPanelDamage(int32 component, ePanels panel, bool noFlyingCompone
if(m_aCarNodes[component] == nil) if(m_aCarNodes[component] == nil)
return; return;
if(status == PANEL_STATUS_SMASHED1){ if(status == PANEL_STATUS_SMASHED1){
if(panel == VEHPANEL_WINDSCREEN)
DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_WINDSHIELD_CRACK, 0.0f); DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_WINDSHIELD_CRACK, 0.0f);
// show damaged part // show damaged part
SetComponentVisibility(m_aCarNodes[component], ATOMIC_FLAG_DAM); SetComponentVisibility(m_aCarNodes[component], ATOMIC_FLAG_DAM);
}else if(status == PANEL_STATUS_MISSING){ }else if(status == PANEL_STATUS_MISSING){
if(!noFlyingComponents) if(!noFlyingComponents)
SpawnFlyingComponent(component, COMPGROUP_PANEL); SpawnFlyingComponent(component, COMPGROUP_PANEL);
else else if(panel == VEHPANEL_WINDSCREEN)
CGlass::CarWindscreenShatters(this, false); CGlass::CarWindscreenShatters(this, false);
// hide both // hide both
SetComponentVisibility(m_aCarNodes[component], ATOMIC_FLAG_NONE); SetComponentVisibility(m_aCarNodes[component], ATOMIC_FLAG_NONE);

View File

@ -39,6 +39,7 @@ public:
uint8 m_bombType : 3; uint8 m_bombType : 3;
#endif #endif
uint8 bTaxiLight : 1; uint8 bTaxiLight : 1;
uint8 bUnknownFlag : 1; // new in LCS
uint8 bFixedColour : 1; uint8 bFixedColour : 1;
uint8 bBigWheels : 1; uint8 bBigWheels : 1;
uint8 bWaterTight : 1; // no damage for non-player peds uint8 bWaterTight : 1; // no damage for non-player peds

View File

@ -69,7 +69,6 @@ float TRANSMISSION_AI_CHEAT_MULT = 1.2f;
float TRANSMISSION_SMOOTHER_FRAC = 0.85f; float TRANSMISSION_SMOOTHER_FRAC = 0.85f;
float TRANSMISSION_FREE_ACCELERATION = 0.1f; float TRANSMISSION_FREE_ACCELERATION = 0.1f;
//--LCS: done
float float
cTransmission::CalculateDriveAcceleration(const float &gasPedal, uint8 &gear, float &time, const float &velocity, float *inertiaVar1, float *inertiaVar2, uint8 nDriveWheels, uint8 cheat) cTransmission::CalculateDriveAcceleration(const float &gasPedal, uint8 &gear, float &time, const float &velocity, float *inertiaVar1, float *inertiaVar2, uint8 nDriveWheels, uint8 cheat)
{ {

View File

@ -53,7 +53,6 @@ bool CVehicle::bDisableRemoteDetonationOnContact;
bool CVehicle::m_bDisplayHandlingInfo; bool CVehicle::m_bDisplayHandlingInfo;
#endif #endif
float CVehicle::rcHeliHeightLimit = 60.0f; float CVehicle::rcHeliHeightLimit = 60.0f;
// unused from SA:
float CVehicle::WHEELSPIN_FALL_RATE = 0.7f; float CVehicle::WHEELSPIN_FALL_RATE = 0.7f;
float CVehicle::WHEELSPIN_RISE_RATE = 0.95f; float CVehicle::WHEELSPIN_RISE_RATE = 0.95f;
float CVehicle::WHEELSPIN_INAIR_TARGET_RATE = 10.0f; float CVehicle::WHEELSPIN_INAIR_TARGET_RATE = 10.0f;
@ -82,12 +81,12 @@ CVehicle::CVehicle(uint8 CreatedBy)
int i; int i;
m_fGasPedal = 0.0f; m_fGasPedal = 0.0f;
m_fBrakePedal = 0.0; m_fBrakePedal = 0.0f;
m_vehLCS_264 = 0; m_fWheelSpin = 0.0f;
m_vehLCS_29E = 0; m_vehLCS_29E = 0;
m_vehLCS_29C = 0; m_vehLCS_29C = 0;
m_vehLCS_2A3 = -1; m_vehLCS_2A3 = -1;
m_vehLCS_348 = false; m_bSuperBrake = false; // probably for multiplayer
m_nCurrentGear = 1; m_nCurrentGear = 1;
m_fChangeGearTime = 0.0f; m_fChangeGearTime = 0.0f;

View File

@ -256,7 +256,7 @@ public:
int8 m_nPacManPickupsCarried; int8 m_nPacManPickupsCarried;
uint8 m_nRoadblockType; uint8 m_nRoadblockType;
uint8 m_bGarageTurnedLightsOff; uint8 m_bGarageTurnedLightsOff;
int32 m_vehLCS_264; float m_fWheelSpin;
float m_fHealth; // 1000.0f = full health. 250.0f = fire. 0 -> explode float m_fHealth; // 1000.0f = full health. 250.0f = fire. 0 -> explode
float m_fEngineEnergy; // TODO(LCS): better name. it adds up acceleration force, so possibly kinetic energy?? float m_fEngineEnergy; // TODO(LCS): better name. it adds up acceleration force, so possibly kinetic energy??
uint8 m_nCurrentGear; uint8 m_nCurrentGear;
@ -280,8 +280,8 @@ public:
uint8 m_nRadioStation; uint8 m_nRadioStation;
uint8 m_bRainAudioCounter; uint8 m_bRainAudioCounter;
uint8 m_bRainSamplesCounter; uint8 m_bRainSamplesCounter;
int8 m_vehLCS_2A3; int8 m_vehLCS_2A3; // enables 2A4
int32 m_vehLCS_2A4; // haven't seen this used yet uint8 m_vehLCS_2A4; // some timer
uint32 m_nCarHornTimer; uint32 m_nCarHornTimer;
uint8 m_nCarHornPattern; uint8 m_nCarHornPattern;
uint8 m_bSirenOrAlarm; uint8 m_bSirenOrAlarm;
@ -292,7 +292,7 @@ public:
CStoredCollPoly m_aCollPolys[2]; // poly which is under front/rear part of car CStoredCollPoly m_aCollPolys[2]; // poly which is under front/rear part of car
float m_fSteerInput; float m_fSteerInput;
eVehicleType m_vehType; eVehicleType m_vehType;
bool m_vehLCS_348; bool m_bSuperBrake;
static void *operator new(size_t) throw(); static void *operator new(size_t) throw();
static void *operator new(size_t sz, int slot) throw(); static void *operator new(size_t sz, int slot) throw();
@ -429,7 +429,6 @@ public:
static bool m_bDisplayHandlingInfo; static bool m_bDisplayHandlingInfo;
#endif #endif
static float rcHeliHeightLimit; static float rcHeliHeightLimit;
// unused from SA:
static float WHEELSPIN_FALL_RATE; static float WHEELSPIN_FALL_RATE;
static float WHEELSPIN_RISE_RATE; static float WHEELSPIN_RISE_RATE;
static float WHEELSPIN_INAIR_TARGET_RATE; static float WHEELSPIN_INAIR_TARGET_RATE;