summaryrefslogtreecommitdiffstats
path: root/src/vehicles
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/vehicles/Automobile.cpp128
-rw-r--r--src/vehicles/Automobile.h8
-rw-r--r--src/vehicles/Boat.cpp41
-rw-r--r--src/vehicles/Boat.h9
-rw-r--r--src/vehicles/CarGen.cpp10
-rw-r--r--src/vehicles/Cranes.cpp10
-rw-r--r--src/vehicles/Cranes.h2
-rw-r--r--src/vehicles/Heli.cpp18
-rw-r--r--src/vehicles/Heli.h4
-rw-r--r--src/vehicles/Plane.cpp30
-rw-r--r--src/vehicles/Plane.h3
-rw-r--r--src/vehicles/Train.cpp14
-rw-r--r--src/vehicles/Train.h3
-rw-r--r--src/vehicles/Vehicle.cpp141
-rw-r--r--src/vehicles/Vehicle.h12
15 files changed, 314 insertions, 119 deletions
diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp
index bfb215d2..60f17204 100644
--- a/src/vehicles/Automobile.cpp
+++ b/src/vehicles/Automobile.cpp
@@ -51,6 +51,13 @@ RwObject *GetCurrentAtomicObjectCB(RwObject *object, void *data);
bool CAutomobile::m_sAllTaxiLights;
+const uint32 CAutomobile::nSaveStructSize =
+#ifdef COMPATIBLE_SAVES
+ 1448;
+#else
+ sizeof(CAutomobile);
+#endif
+
CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
: CVehicle(CreatedBy)
{
@@ -162,7 +169,7 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
SetupSuspensionLines();
- m_status = STATUS_SIMPLE;
+ SetStatus(STATUS_SIMPLE);
bUseCollisionRecords = true;
m_nNumPassengers = 0;
@@ -254,8 +261,8 @@ CAutomobile::ProcessControl(void)
ProcessCarAlarm();
// Scan if this car sees the player committing any crimes
- if(m_status != STATUS_ABANDONED && m_status != STATUS_WRECKED &&
- m_status != STATUS_PLAYER && m_status != STATUS_PLAYER_REMOTE && m_status != STATUS_PLAYER_DISABLED){
+ if(GetStatus() != STATUS_ABANDONED && GetStatus() != STATUS_WRECKED &&
+ GetStatus() != STATUS_PLAYER && GetStatus() != STATUS_PLAYER_REMOTE && GetStatus() != STATUS_PLAYER_DISABLED){
switch(GetModelIndex())
case MI_FBICAR:
case MI_POLICE:
@@ -318,7 +325,7 @@ CAutomobile::ProcessControl(void)
// Set Center of Mass to make car more stable
if(strongGrip1 || bCheat3)
m_vecCentreOfMass.z = 0.3f*m_aSuspensionSpringLength[0] + -1.0f*m_fHeightAboveRoad;
- else if(pHandling->Flags & HANDLING_NONPLAYER_STABILISER && m_status == STATUS_PHYSICS)
+ else if(pHandling->Flags & HANDLING_NONPLAYER_STABILISER && GetStatus() == STATUS_PHYSICS)
m_vecCentreOfMass.z = pHandling->CentreOfMass.z - 0.2f*pHandling->Dimension.z;
else
m_vecCentreOfMass.z = pHandling->CentreOfMass.z;
@@ -326,7 +333,7 @@ CAutomobile::ProcessControl(void)
// Process depending on status
bool playerRemote = false;
- switch(m_status){
+ switch(GetStatus()){
case STATUS_PLAYER_REMOTE:
if(CPad::GetPad(0)->WeaponJustDown()){
BlowUpCar(FindPlayerPed());
@@ -356,7 +363,7 @@ CAutomobile::ProcessControl(void)
PruneReferences();
- if(m_status == STATUS_PLAYER && !CRecordDataForChase::IsRecording())
+ if(GetStatus() == STATUS_PLAYER && !CRecordDataForChase::IsRecording())
DoDriveByShootings();
}
break;
@@ -426,7 +433,7 @@ CAutomobile::ProcessControl(void)
// Skip physics if object is found to have been static recently
bool skipPhysics = false;
- if(!bIsStuck && (m_status == STATUS_ABANDONED || m_status == STATUS_WRECKED)){
+ if(!bIsStuck && (GetStatus() == STATUS_ABANDONED || GetStatus() == STATUS_WRECKED)){
bool makeStatic = false;
float moveSpeedLimit, turnSpeedLimit, distanceLimit;
@@ -436,7 +443,7 @@ CAutomobile::ProcessControl(void)
m_aSuspensionSpringRatioPrev[3] != 1.0f)
makeStatic = true;
- if(m_status == STATUS_WRECKED){
+ if(GetStatus() == STATUS_WRECKED){
moveSpeedLimit = 0.006f;
turnSpeedLimit = 0.0015f;
distanceLimit = 0.015f;
@@ -494,7 +501,7 @@ CAutomobile::ProcessControl(void)
default:
if(CVehicle::bCheat3){
// Make vehicle jump when horn is sounded
- if(m_status == STATUS_PLAYER && m_vecMoveSpeed.MagnitudeSqr() > sq(0.2f) &&
+ if(GetStatus() == STATUS_PLAYER && m_vecMoveSpeed.MagnitudeSqr() > sq(0.2f) &&
// BUG: game checks [0] four times, instead of all wheels
m_aSuspensionSpringRatio[0] < 1.0f &&
CPad::GetPad(0)->HornJustDown()){
@@ -563,7 +570,7 @@ CAutomobile::ProcessControl(void)
bHasHitWall = false;
m_fDistanceTravelled = 0.0f;
m_bIsVehicleBeingShifted = false;
- m_phy_flagA80 = false;
+ bSkipLineCol = false;
ApplyMoveSpeed();
ApplyTurnSpeed();
for(i = 0; CheckCollision() && i < 5; i++){
@@ -713,7 +720,7 @@ CAutomobile::ProcessControl(void)
}
float traction;
- if(m_status == STATUS_PHYSICS)
+ if(GetStatus() == STATUS_PHYSICS)
traction = 0.004f * m_fTraction;
else
traction = 0.004f;
@@ -764,7 +771,7 @@ CAutomobile::ProcessControl(void)
m_aWheelColPoints[CARWHEEL_FRONT_LEFT].surfaceA = SURFACE_RUBBER29;
float adhesion = CSurfaceTable::GetAdhesiveLimit(m_aWheelColPoints[CARWHEEL_FRONT_LEFT])*traction;
- if(m_status == STATUS_PLAYER)
+ if(GetStatus() == STATUS_PLAYER)
adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_FRONT_LEFT].surfaceB);
WheelState[CARWHEEL_FRONT_LEFT] = m_aWheelState[CARWHEEL_FRONT_LEFT];
@@ -798,7 +805,7 @@ CAutomobile::ProcessControl(void)
m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].surfaceA = SURFACE_RUBBER29;
float adhesion = CSurfaceTable::GetAdhesiveLimit(m_aWheelColPoints[CARWHEEL_FRONT_RIGHT])*traction;
- if(m_status == STATUS_PLAYER)
+ if(GetStatus() == STATUS_PLAYER)
adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].surfaceB);
WheelState[CARWHEEL_FRONT_RIGHT] = m_aWheelState[CARWHEEL_FRONT_RIGHT];
@@ -873,7 +880,7 @@ CAutomobile::ProcessControl(void)
m_aWheelColPoints[CARWHEEL_REAR_LEFT].surfaceA = SURFACE_RUBBER29;
float adhesion = CSurfaceTable::GetAdhesiveLimit(m_aWheelColPoints[CARWHEEL_REAR_LEFT])*traction;
- if(m_status == STATUS_PLAYER)
+ if(GetStatus() == STATUS_PLAYER)
adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_REAR_LEFT].surfaceB);
WheelState[CARWHEEL_REAR_LEFT] = m_aWheelState[CARWHEEL_REAR_LEFT];
@@ -907,7 +914,7 @@ CAutomobile::ProcessControl(void)
m_aWheelColPoints[CARWHEEL_REAR_RIGHT].surfaceA = SURFACE_RUBBER29;
float adhesion = CSurfaceTable::GetAdhesiveLimit(m_aWheelColPoints[CARWHEEL_REAR_RIGHT])*traction;
- if(m_status == STATUS_PLAYER)
+ if(GetStatus() == STATUS_PLAYER)
adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_REAR_RIGHT].surfaceB);
WheelState[CARWHEEL_REAR_RIGHT] = m_aWheelState[CARWHEEL_REAR_RIGHT];
@@ -976,7 +983,7 @@ CAutomobile::ProcessControl(void)
// Process horn
- if(m_status != STATUS_PLAYER){
+ if(GetStatus() != STATUS_PLAYER){
ReduceHornCounter();
}else{
if(GetModelIndex() == MI_MRWHOOP){
@@ -1008,7 +1015,7 @@ CAutomobile::ProcessControl(void)
// Flying
- if(m_status != STATUS_PLAYER && m_status != STATUS_PLAYER_REMOTE && m_status != STATUS_PHYSICS){
+ if(GetStatus() != STATUS_PLAYER && GetStatus() != STATUS_PLAYER_REMOTE && GetStatus() != STATUS_PHYSICS){
if(GetModelIndex() == MI_MIAMI_RCRAIDER || GetModelIndex() == MI_MIAMI_SPARROW)
m_aWheelSpeed[0] = Max(m_aWheelSpeed[0]-0.0005f, 0.0f);
}else if((GetModelIndex() == MI_DODO || CVehicle::bAllDodosCheat) &&
@@ -1061,7 +1068,7 @@ CAutomobile::ProcessControl(void)
// move fire forward if in first person
if(this == FindPlayerVehicle() && TheCamera.GetLookingForwardFirstPerson())
- if(m_fHealth < 250.0f && m_status != STATUS_WRECKED){
+ if(m_fHealth < 250.0f && GetStatus() != STATUS_WRECKED){
if(GetModelIndex() == MI_FIRETRUCK)
damagePos += CVector(0.0f, 3.0f, -0.2f);
else
@@ -1071,7 +1078,7 @@ CAutomobile::ProcessControl(void)
damagePos = GetMatrix()*damagePos;
damagePos.z += 0.15f;
- if(m_fHealth < 250.0f && m_status != STATUS_WRECKED){
+ if(m_fHealth < 250.0f && GetStatus() != STATUS_WRECKED){
// Car is on fire
CParticle::AddParticle(PARTICLE_CARFLAME, damagePos,
@@ -1137,7 +1144,7 @@ CAutomobile::ProcessControl(void)
// Shake pad
- if((suspShake > 0.0f || surfShake > 0.0f) && m_status == STATUS_PLAYER){
+ if((suspShake > 0.0f || surfShake > 0.0f) && GetStatus() == STATUS_PLAYER){
float speed = m_vecMoveSpeed.MagnitudeSqr();
if(speed > sq(0.1f)){
speed = Sqrt(speed);
@@ -1198,7 +1205,7 @@ CAutomobile::ProcessControl(void)
m_vecMoveFriction = CVector(0.0f, 0.0f, 0.0f);
m_vecTurnFriction = CVector(0.0f, 0.0f, 0.0f);
}else if(!skipPhysics &&
- (m_fGasPedal == 0.0f && brake == 0.0f || m_status == STATUS_WRECKED)){
+ (m_fGasPedal == 0.0f && brake == 0.0f || GetStatus() == STATUS_WRECKED)){
if(Abs(m_vecMoveSpeed.x) < 0.005f &&
Abs(m_vecMoveSpeed.y) < 0.005f &&
Abs(m_vecMoveSpeed.z) < 0.005f){
@@ -1213,7 +1220,7 @@ CAutomobile::Teleport(CVector pos)
{
CWorld::Remove(this);
- GetPosition() = pos;
+ SetPosition(pos);
SetOrientation(0.0f, 0.0f, 0.0f);
SetMoveSpeed(0.0f, 0.0f, 0.0f);
SetTurnSpeed(0.0f, 0.0f, 0.0f);
@@ -1255,7 +1262,7 @@ CAutomobile::PreRender(void)
}
}
}else{
- if(m_status == STATUS_SIMPLE){
+ if(GetStatus() == STATUS_SIMPLE){
CMatrix mat;
CVector pos;
@@ -1285,8 +1292,8 @@ CAutomobile::PreRender(void)
}
int drawParticles = Abs(fwdSpeed) < 90.0f;
- if(m_status == STATUS_SIMPLE || m_status == STATUS_PHYSICS ||
- m_status == STATUS_PLAYER || m_status == STATUS_PLAYER_PLAYBACKFROMBUFFER){
+ if(GetStatus() == STATUS_SIMPLE || GetStatus() == STATUS_PHYSICS ||
+ GetStatus() == STATUS_PLAYER || GetStatus() == STATUS_PLAYER_PLAYBACKFROMBUFFER){
bool rearSkidding = false;
if(m_aWheelState[CARWHEEL_REAR_LEFT] == WHEEL_STATE_SKIDDING ||
m_aWheelState[CARWHEEL_REAR_RIGHT] == WHEEL_STATE_SKIDDING)
@@ -1618,8 +1625,8 @@ CAutomobile::PreRender(void)
CClock::GetHours() < 8 && CClock::GetMinutes() < (m_randomSeed & 0x3F) ||
m_randomSeed/50000.0f < CWeather::Foggyness ||
m_randomSeed/50000.0f < CWeather::WetRoads;
- if(shouldLightsBeOn != bLightsOn && m_status != STATUS_WRECKED){
- if(m_status == STATUS_ABANDONED){
+ if(shouldLightsBeOn != bLightsOn && GetStatus() != STATUS_WRECKED){
+ if(GetStatus() == STATUS_ABANDONED){
// Turn off lights on abandoned vehicles only when we they're far away
if(bLightsOn &&
Abs(TheCamera.GetPosition().x - GetPosition().x) + Abs(TheCamera.GetPosition().y - GetPosition().y) > 100.0f)
@@ -1857,7 +1864,7 @@ CAutomobile::PreRender(void)
}else{
// Lights off
- if(m_status == STATUS_ABANDONED || m_status == STATUS_WRECKED) {
+ if(GetStatus() == STATUS_ABANDONED || GetStatus() == STATUS_WRECKED) {
CShadows::StoreShadowForCar(this);
return;
}
@@ -2139,7 +2146,7 @@ CAutomobile::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints)
int i;
CColModel *colModel;
- if(m_status != STATUS_SIMPLE)
+ if(GetStatus() != STATUS_SIMPLE)
bVehicleColProcessed = true;
if(bUsingSpecialColModel)
@@ -2160,7 +2167,7 @@ CAutomobile::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints)
// m_aSuspensionSpringRatio are now set to the point where the tyre touches ground.
// In ProcessControl these will be re-normalized to ignore the tyre radius.
- if(m_bIsVehicleBeingShifted || m_phy_flagA80 ||
+ if(m_bIsVehicleBeingShifted || bSkipLineCol ||
GetModelIndex() == MI_DODO && (ent->IsPed() || ent->IsVehicle())){
// don't do line collision
for(i = 0; i < 4; i++)
@@ -2178,7 +2185,7 @@ CAutomobile::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints)
phys->RegisterReference((CEntity**)&m_aGroundPhysical[i]);
m_aGroundOffset[i] = m_aWheelColPoints[i].point - phys->GetPosition();
- if(phys->GetModelIndex() == MI_BODYCAST && m_status == STATUS_PLAYER){
+ if(phys->GetModelIndex() == MI_BODYCAST && GetStatus() == STATUS_PLAYER){
// damage body cast
float speed = m_vecMoveSpeed.MagnitudeSqr();
if(speed > 0.1f){
@@ -2187,7 +2194,7 @@ CAutomobile::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints)
}
// move body cast
- if(phys->bIsStatic){
+ if(phys->IsStatic()){
phys->bIsStatic = false;
phys->m_nStaticFrames = 0;
phys->ApplyMoveForce(m_vecMoveSpeed / Sqrt(speed));
@@ -2370,7 +2377,7 @@ CAutomobile::FireTruckControl(void)
cannonDir = Multiply3x3(GetMatrix(), cannonDir);
cannonDir.z += (CGeneral::GetRandomNumber()&0xF)/1000.0f;
CWaterCannons::UpdateOne((uintptr)this, &cannonPos, &cannonDir);
- }else if(m_status == STATUS_PHYSICS){
+ }else if(GetStatus() == STATUS_PHYSICS){
CFire *fire = gFireManager.FindFurthestFire_NeverMindFireMen(GetPosition(), 10.0f, 35.0f);
if(fire == nil)
return;
@@ -2531,7 +2538,7 @@ CAutomobile::HydraulicControl(void)
CPlayerInfo *playerInfo = &CWorld::Players[CWorld::PlayerInFocus];
CColModel *specialColModel = &playerInfo->m_ColModel;
- if(m_status != STATUS_PLAYER){
+ if(GetStatus() != STATUS_PLAYER){
// reset hydraulics for non-player cars
if(!bUsingSpecialColModel)
@@ -3123,7 +3130,7 @@ CAutomobile::RcbanditCheck1CarWheels(CPtrList &list)
mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(car->GetModelIndex());
for(i = 0; i < 4; i++){
- if(car->m_aSuspensionSpringRatioPrev[i] < 1.0f || car->m_status == STATUS_SIMPLE){
+ if(car->m_aSuspensionSpringRatioPrev[i] < 1.0f || car->GetStatus() == STATUS_SIMPLE){
CVector wheelPos;
CColSphere sph;
mi->GetWheelPosn(i, wheelPos);
@@ -3179,10 +3186,10 @@ CAutomobile::PlaceOnRoadProperly(void)
float c = Cos(angle);
float s = Sin(angle);
- GetRight() = CVector((front.y - rear.y)/len, -(front.x - rear.x)/len, 0.0f);
- GetForward() = CVector(-c*GetRight().y, c*GetRight().x, s);
- GetUp() = CrossProduct(GetRight(), GetForward());
- GetPosition() = CVector((front.x + rear.x)/2.0f, (front.y + rear.y)/2.0f, (frontZ + rearZ)/2.0f + GetHeightAboveRoad());
+ GetMatrix().GetRight() = CVector((front.y - rear.y) / len, -(front.x - rear.x) / len, 0.0f);
+ GetMatrix().GetForward() = CVector(-c * GetRight().y, c * GetRight().x, s);
+ GetMatrix().GetUp() = CrossProduct(GetRight(), GetForward());
+ GetMatrix().GetPosition() = CVector((front.x + rear.x) / 2.0f, (front.y + rear.y) / 2.0f, (frontZ + rearZ) / 2.0f + GetHeightAboveRoad());
}
void
@@ -3205,20 +3212,20 @@ CAutomobile::VehicleDamage(float impulse, uint16 damagedPiece)
// damage flipped over car
if(GetUp().z < 0.0f && this != FindPlayerVehicle()){
- if(bNotDamagedUpsideDown || m_status == STATUS_PLAYER_REMOTE || bIsInWater)
+ if(bNotDamagedUpsideDown || GetStatus() == STATUS_PLAYER_REMOTE || bIsInWater)
return;
m_fHealth -= 4.0f*CTimer::GetTimeStep();
}
- if(impulse > 25.0f && m_status != STATUS_WRECKED){
+ if(impulse > 25.0f && GetStatus() != STATUS_WRECKED){
if(bIsLawEnforcer &&
FindPlayerVehicle() && FindPlayerVehicle() == m_pDamageEntity &&
- m_status != STATUS_ABANDONED &&
+ GetStatus() != STATUS_ABANDONED &&
FindPlayerVehicle()->m_vecMoveSpeed.Magnitude() >= m_vecMoveSpeed.Magnitude() &&
FindPlayerVehicle()->m_vecMoveSpeed.Magnitude() > 0.1f)
FindPlayerPed()->SetWantedLevelNoDrop(1);
- if(m_status == STATUS_PLAYER && impulse > 50.0f){
+ if(GetStatus() == STATUS_PLAYER && impulse > 50.0f){
uint8 freq = Min(0.4f*impulse*2000.0f/m_fMass + 100.0f, 250.0f);
CPad::GetPad(0)->StartShake(40000/freq, freq);
}
@@ -3382,7 +3389,7 @@ CAutomobile::VehicleDamage(float impulse, uint16 damagedPiece)
float damage = (impulse-25.0f)*pHandling->fCollisionDamageMultiplier*0.6f*damageMultiplier;
- if(GetModelIndex() == MI_SECURICA && m_pDamageEntity && m_pDamageEntity->m_status == STATUS_PLAYER)
+ if(GetModelIndex() == MI_SECURICA && m_pDamageEntity && m_pDamageEntity->GetStatus() == STATUS_PLAYER)
damage *= 7.0f;
if(damage > 0.0f){
@@ -3816,7 +3823,7 @@ CAutomobile::BlowUpCar(CEntity *culprit)
// explosion pushes vehicle up
m_vecMoveSpeed.z += 0.13f;
- m_status = STATUS_WRECKED;
+ SetStatus(STATUS_WRECKED);
bRenderScorched = true;
m_nTimeOfDeath = CTimer::GetTimeInMilliseconds();
Damage.FuckCarCompletely();
@@ -3933,8 +3940,8 @@ CAutomobile::BurstTyre(uint8 wheel)
if(status == WHEEL_STATUS_OK){
Damage.SetWheelStatus(wheel, WHEEL_STATUS_BURST);
- if(m_status == STATUS_SIMPLE){
- m_status = STATUS_PHYSICS;
+ if(GetStatus() == STATUS_SIMPLE){
+ SetStatus(STATUS_PHYSICS);
CCarCtrl::SwitchVehicleToRealPhysics(this);
}
@@ -4133,13 +4140,13 @@ CAutomobile::HasCarStoppedBecauseOfLight(void)
{
int i;
- if(m_status != STATUS_SIMPLE && m_status != STATUS_PHYSICS)
+ if(GetStatus() != STATUS_SIMPLE && GetStatus() != STATUS_PHYSICS)
return false;
if(AutoPilot.m_nCurrentRouteNode && AutoPilot.m_nNextRouteNode){
CPathNode *curnode = &ThePaths.m_pathNodes[AutoPilot.m_nCurrentRouteNode];
for(i = 0; i < curnode->numLinks; i++)
- if(ThePaths.m_connections[curnode->firstLink + i] == AutoPilot.m_nNextRouteNode)
+ if(ThePaths.ConnectedNode(curnode->firstLink + i) == AutoPilot.m_nNextRouteNode)
break;
if(i < curnode->numLinks &&
ThePaths.m_carPathLinks[ThePaths.m_carPathConnections[curnode->firstLink + i]].trafficLightType & 3)
@@ -4149,7 +4156,7 @@ CAutomobile::HasCarStoppedBecauseOfLight(void)
if(AutoPilot.m_nCurrentRouteNode && AutoPilot.m_nPrevRouteNode){
CPathNode *curnode = &ThePaths.m_pathNodes[AutoPilot.m_nCurrentRouteNode];
for(i = 0; i < curnode->numLinks; i++)
- if(ThePaths.m_connections[curnode->firstLink + i] == AutoPilot.m_nPrevRouteNode)
+ if(ThePaths.ConnectedNode(curnode->firstLink + i) == AutoPilot.m_nPrevRouteNode)
break;
if(i < curnode->numLinks &&
ThePaths.m_carPathLinks[ThePaths.m_carPathConnections[curnode->firstLink + i]].trafficLightType & 3)
@@ -4401,7 +4408,7 @@ CAutomobile::SpawnFlyingComponent(int32 component, uint32 type)
if(GetUp().z > 0.0f){
// simulate fast upward movement if going fast
float speed = CVector2D(m_vecMoveSpeed).MagnitudeSqr();
- obj->GetPosition() += GetUp()*speed;
+ obj->GetMatrix().Translate(GetUp()*speed);
}
}
obj->ApplyMoveForce(dist);
@@ -4580,3 +4587,22 @@ CAutomobile::SetAllTaxiLights(bool set)
{
m_sAllTaxiLights = set;
}
+
+#ifdef COMPATIBLE_SAVES
+void
+CAutomobile::Save(uint8*& buf)
+{
+ CVehicle::Save(buf);
+ WriteSaveBuf<CDamageManager>(buf, Damage);
+ SkipSaveBuf(buf, 800 - sizeof(CDamageManager));
+}
+
+void
+CAutomobile::Load(uint8*& buf)
+{
+ CVehicle::Load(buf);
+ Damage = ReadSaveBuf<CDamageManager>(buf);
+ SkipSaveBuf(buf, 800 - sizeof(CDamageManager));
+ SetupDamageAfterLoad();
+}
+#endif
diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h
index 2de85a99..a3e8ac17 100644
--- a/src/vehicles/Automobile.h
+++ b/src/vehicles/Automobile.h
@@ -188,10 +188,16 @@ public:
void HideAllComps(void);
void ShowAllComps(void);
void ReduceHornCounter(void);
+#ifdef COMPATIBLE_SAVES
+ virtual void Save(uint8*& buf);
+ virtual void Load(uint8*& buf);
+#endif
+ static const uint32 nSaveStructSize;
static void SetAllTaxiLights(bool set);
};
-static_assert(sizeof(CAutomobile) == 0x5A8, "CAutomobile: error");
+
+VALIDATE_SIZE(CAutomobile, 0x5A8);
inline uint8 GetCarDoorFlag(int32 carnode) {
switch (carnode) {
diff --git a/src/vehicles/Boat.cpp b/src/vehicles/Boat.cpp
index 14eb2f05..348f2732 100644
--- a/src/vehicles/Boat.cpp
+++ b/src/vehicles/Boat.cpp
@@ -32,6 +32,13 @@ float WAKE_LIFETIME = 400.0f;
CBoat *CBoat::apFrameWakeGeneratingBoats[4];
+const uint32 CBoat::nSaveStructSize =
+#ifdef COMPATIBLE_SAVES
+ 1156;
+#else
+ sizeof(CBoat);
+#endif
+
CBoat::CBoat(int mi, uint8 owner) : CVehicle(owner)
{
CVehicleModelInfo *minfo = (CVehicleModelInfo*)CModelInfo::GetModelInfo(mi);
@@ -137,7 +144,7 @@ CBoat::ProcessControl(void)
ProcessCarAlarm();
- switch(m_status){
+ switch(GetStatus()){
case STATUS_PLAYER:
m_bIsAnchored = false;
m_fOrientation = INVALID_ORIENTATION;
@@ -176,7 +183,7 @@ CBoat::ProcessControl(void)
}
float collisionDamage = pHandling->fCollisionDamageMultiplier * m_fDamageImpulse;
- if(collisionDamage > 25.0f && m_status != STATUS_WRECKED && m_fHealth >= 150.0f){
+ if(collisionDamage > 25.0f && GetStatus() != STATUS_WRECKED && m_fHealth >= 150.0f){
float prevHealth = m_fHealth;
if(this == FindPlayerVehicle()){
if(bTakeLessDamage)
@@ -199,7 +206,7 @@ CBoat::ProcessControl(void)
}
// Damage particles
- if(m_fHealth <= 600.0f && m_status != STATUS_WRECKED &&
+ if(m_fHealth <= 600.0f && GetStatus() != STATUS_WRECKED &&
Abs(GetPosition().x - TheCamera.GetPosition().x) < 200.0f &&
Abs(GetPosition().y - TheCamera.GetPosition().y) < 200.0f){
float speedSq = m_vecMoveSpeed.MagnitudeSqr();
@@ -283,7 +290,7 @@ CBoat::ProcessControl(void)
AddWakePoint(GetPosition());
float steerFactor = 1.0f - DotProduct(m_vecMoveSpeed, GetForward());
- if(m_modelIndex == MI_GHOST)
+ if (GetModelIndex() == MI_GHOST)
steerFactor = 1.0f - DotProduct(m_vecMoveSpeed, GetForward())*0.3f;
if(steerFactor < 0.0f) steerFactor = 0.0f;
@@ -326,7 +333,7 @@ CBoat::ProcessControl(void)
// Spray some particles
CVector jetDir = -0.04f * force;
if(m_fGasPedal > 0.0f){
- if(m_status == STATUS_PLAYER){
+ if(GetStatus() == STATUS_PLAYER){
bool cameraHack = TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN ||
TheCamera.WhoIsInControlOfTheCamera == CAMCONTROL_OBBE;
CVector sternPos = GetColModel()->boundingBox.min;
@@ -513,7 +520,7 @@ CBoat::ProcessControl(void)
// is this some inlined CPlaceable method?
CVector pos = GetPosition();
GetMatrix().RotateZ(m_fOrientation - GetForward().Heading());
- GetPosition() = pos;
+ GetMatrix().GetPosition() = pos;
}
}
@@ -597,7 +604,7 @@ CBoat::BlowUpCar(CEntity *culprit)
// explosion pushes vehicle up
m_vecMoveSpeed.z += 0.13f;
- m_status = STATUS_WRECKED;
+ SetStatus(STATUS_WRECKED);
bRenderScorched = true;
m_fHealth = 0.0;
@@ -673,7 +680,7 @@ CBoat::BlowUpCar(CEntity *culprit)
dist.Normalise();
if(GetUp().z > 0.0f)
dist += GetUp();
- obj->GetPosition() += GetUp();
+ obj->GetMatrix().GetPosition() += GetUp();
CWorld::Add(obj);
@@ -764,7 +771,7 @@ void
CBoat::Teleport(CVector v)
{
CWorld::Remove(this);
- GetPosition() = v;
+ SetPosition(v);
SetOrientation(0.0f, 0.0f, 0.0f);
SetMoveSpeed(0.0f, 0.0f, 0.0f);
SetTurnSpeed(0.0f, 0.0f, 0.0f);
@@ -899,3 +906,19 @@ CBoat::AddWakePoint(CVector point)
m_nNumWakePoints = 1;
}
}
+
+#ifdef COMPATIBLE_SAVES
+void
+CBoat::Save(uint8*& buf)
+{
+ CVehicle::Save(buf);
+ SkipSaveBuf(buf, 1156 - 648);
+}
+
+void
+CBoat::Load(uint8*& buf)
+{
+ CVehicle::Load(buf);
+ SkipSaveBuf(buf, 1156 - 648);
+}
+#endif
diff --git a/src/vehicles/Boat.h b/src/vehicles/Boat.h
index ba56e355..3cc3513d 100644
--- a/src/vehicles/Boat.h
+++ b/src/vehicles/Boat.h
@@ -64,8 +64,15 @@ public:
static float IsVertexAffectedByWake(CVector vecVertex, CBoat *pBoat);
static void FillBoatList(void);
+#ifdef COMPATIBLE_SAVES
+ virtual void Save(uint8*& buf);
+ virtual void Load(uint8*& buf);
+#endif
+ static const uint32 nSaveStructSize;
+
};
-static_assert(sizeof(CBoat) == 0x484, "CBoat: error");
+
+VALIDATE_SIZE(CBoat, 0x484);
extern float MAX_WAKE_LENGTH;
extern float MIN_WAKE_INTERVAL;
diff --git a/src/vehicles/CarGen.cpp b/src/vehicles/CarGen.cpp
index 64743929..72b6c30c 100644
--- a/src/vehicles/CarGen.cpp
+++ b/src/vehicles/CarGen.cpp
@@ -59,9 +59,9 @@ void CCarGenerator::DoInternalProcessing()
if (pos.z <= -100.0f)
pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
pos.z += pBoat->GetDistanceFromCentreOfMassToBaseOfModel();
- pBoat->GetPosition() = pos;
+ pBoat->SetPosition(pos);
pBoat->SetOrientation(0.0f, 0.0f, DEGTORAD(m_fAngle));
- pBoat->m_status = STATUS_ABANDONED;
+ pBoat->SetStatus(STATUS_ABANDONED);
pBoat->m_nDoorLock = CARLOCK_UNLOCKED;
CWorld::Add(pBoat);
if (CGeneral::GetRandomNumberInRange(0, 100) < m_nAlarm)
@@ -93,9 +93,9 @@ void CCarGenerator::DoInternalProcessing()
pCar->bIsStatic = false;
pCar->bEngineOn = false;
pos.z += pCar->GetDistanceFromCentreOfMassToBaseOfModel();
- pCar->GetPosition() = pos;
+ pCar->SetPosition(pos);
pCar->SetOrientation(0.0f, 0.0f, DEGTORAD(m_fAngle));
- pCar->m_status = STATUS_ABANDONED;
+ pCar->SetStatus(STATUS_ABANDONED);
pCar->bLightsOn = false;
pCar->m_nDoorLock = CARLOCK_UNLOCKED;
CWorld::Add(pCar);
@@ -130,7 +130,7 @@ void CCarGenerator::Process()
m_nVehicleHandle = -1;
return;
}
- if (pVehicle->m_status != STATUS_PLAYER)
+ if (pVehicle->GetStatus() != STATUS_PLAYER)
return;
m_nTimer += 60000;
m_nVehicleHandle = -1;
diff --git a/src/vehicles/Cranes.cpp b/src/vehicles/Cranes.cpp
index 7d2160d9..3ef11302 100644
--- a/src/vehicles/Cranes.cpp
+++ b/src/vehicles/Cranes.cpp
@@ -340,7 +340,7 @@ void CCrane::Update(void)
case GOING_TOWARDS_TARGET_ONLY_HEIGHT:
case ROTATING_TARGET:
if (m_pVehiclePickedUp) {
- m_pVehiclePickedUp->GetPosition() = CVector(m_vecHookCurPos.x, m_vecHookCurPos.y, m_vecHookCurPos.z - m_pVehiclePickedUp->GetColModel()->boundingBox.max.z);
+ m_pVehiclePickedUp->SetPosition(m_vecHookCurPos.x, m_vecHookCurPos.y, m_vecHookCurPos.z - m_pVehiclePickedUp->GetColModel()->boundingBox.max.z);
m_pVehiclePickedUp->SetMoveSpeed(0.0f, 0.0f, 0.0f);
CVector up(vecHook.x - m_vecHookCurPos.x, vecHook.y - m_vecHookCurPos.y, 20.0f);
up.Normalise();
@@ -416,7 +416,7 @@ void CCrane::FindCarInSectorList(CPtrList* pList)
Abs(pVehicle->GetMoveSpeed().y) >= CAR_MOVING_SPEED_THRESHOLD ||
Abs(pVehicle->GetMoveSpeed().z) >= CAR_MOVING_SPEED_THRESHOLD)
continue;
- if (!pVehicle->IsCar() || pVehicle->m_status == STATUS_WRECKED || pVehicle->m_fHealth < 250.0f)
+ if (!pVehicle->IsCar() || pVehicle->GetStatus() == STATUS_WRECKED || pVehicle->m_fHealth < 250.0f)
continue;
if (!DoesCranePickUpThisCarType(pVehicle->GetModelIndex()) ||
m_bIsMilitaryCrane && CCranes::DoesMilitaryCraneHaveThisOneAlready(pVehicle->GetModelIndex())) {
@@ -443,7 +443,9 @@ bool CCrane::DoesCranePickUpThisCarType(uint32 mi)
if (m_bIsCrusher) {
return mi != MI_FIRETRUCK &&
mi != MI_TRASH &&
-#ifndef FIX_BUGS // why
+#ifdef FIX_BUGS
+ mi != MI_COACH &&
+#else
mi != MI_BLISTA &&
#endif
mi != MI_SECURICA &&
@@ -585,7 +587,7 @@ void CCrane::SetHookMatrix()
{
if (m_pHook == nil)
return;
- m_pHook->GetPosition() = m_vecHookCurPos;
+ m_pHook->SetPosition(m_vecHookCurPos);
CVector up(m_vecHookInitPos.x - m_vecHookCurPos.x, m_vecHookInitPos.y - m_vecHookCurPos.y, 20.0f);
up.Normalise();
m_pHook->GetRight() = CrossProduct(CVector(0.0f, 1.0f, 0.0f), up);
diff --git a/src/vehicles/Cranes.h b/src/vehicles/Cranes.h
index c0502638..6d877d82 100644
--- a/src/vehicles/Cranes.h
+++ b/src/vehicles/Cranes.h
@@ -72,7 +72,7 @@ public:
float GetHeightToDropoffHeight() { return m_fDropoffHeight + (m_bIsCrusher ? 7.0f : 2.0f); }
};
-static_assert(sizeof(CCrane) == 128, "CCrane: error");
+VALIDATE_SIZE(CCrane, 128);
class CCranes
{
diff --git a/src/vehicles/Heli.cpp b/src/vehicles/Heli.cpp
index 0073a5ad..e4cd5883 100644
--- a/src/vehicles/Heli.cpp
+++ b/src/vehicles/Heli.cpp
@@ -77,7 +77,7 @@ CHeli::CHeli(int32 id, uint8 CreatedBy)
m_fHeliDustZ[i] = -50.0f;
m_nPoliceShoutTimer = CTimer::GetTimeInMilliseconds();
- m_status = STATUS_HELI;
+ SetStatus(STATUS_HELI);
m_bTestRight = true;
m_fTargetOffset = 0.0f;
m_fSearchLightX = m_fSearchLightY = 0.0f;
@@ -144,11 +144,11 @@ CHeli::ProcessControl(void)
if(GetPosition().z > 31.55f)
break;
m_pathState = 7;
- GetPosition().z = 31.55f;
+ GetMatrix().GetPosition().z = 31.55f;
m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
break;
case 7:
- GetPosition().z = 31.55f;
+ GetMatrix().GetPosition().z = 31.55f;
target = GetPosition();
break;
@@ -214,8 +214,8 @@ CHeli::ProcessControl(void)
vTargetDist = target - GetPosition();
m_fTargetZ = target.z;
if(m_pathState == 6){
- GetPosition().x = GetPosition().x*0.99f + target.x*0.01f;
- GetPosition().y = GetPosition().y*0.99f + target.y*0.01f;
+ GetMatrix().GetPosition().x = GetMatrix().GetPosition().x*0.99f + target.x*0.01f;
+ GetMatrix().GetPosition().y = GetMatrix().GetPosition().y*0.99f + target.y*0.01f;
}
}else{
vTargetDist = FindPlayerCoors() - GetPosition();
@@ -367,8 +367,8 @@ CHeli::ProcessControl(void)
m_vecMoveSpeed.x += speedDir.x*speedInc;
m_vecMoveSpeed.y += speedDir.y*speedInc;
}
- GetPosition().x += m_vecMoveSpeed.x*CTimer::GetTimeStep();
- GetPosition().y += m_vecMoveSpeed.y*CTimer::GetTimeStep();
+ GetMatrix().GetPosition().x += m_vecMoveSpeed.x*CTimer::GetTimeStep();
+ GetMatrix().GetPosition().y += m_vecMoveSpeed.y*CTimer::GetTimeStep();
// Find z target
if(m_heliStatus == HELI_STATUS_FLY_AWAY)
@@ -389,7 +389,7 @@ CHeli::ProcessControl(void)
m_vecMoveSpeed.z -= speedIncZ;
else
m_vecMoveSpeed.z += speedIncZ*1.5f;
- GetPosition().z += m_vecMoveSpeed.z*CTimer::GetTimeStep();
+ GetMatrix().GetPosition().z += m_vecMoveSpeed.z*CTimer::GetTimeStep();
// Find angular speed
float targetAngularSpeed;
@@ -810,7 +810,7 @@ GenerateHeli(bool catalina)
if(catalina)
heli->GetMatrix().SetRotateZOnly(DEGTORAD(270.0f)); // game actually uses 3.14 here
- heli->m_status = STATUS_ABANDONED;
+ heli->SetStatus(STATUS_ABANDONED);
int id = -1;
bool found = false;
diff --git a/src/vehicles/Heli.h b/src/vehicles/Heli.h
index 39e4cbcf..cf3f791f 100644
--- a/src/vehicles/Heli.h
+++ b/src/vehicles/Heli.h
@@ -95,4 +95,6 @@ public:
static void ActivateHeli(bool activate);
};
-static_assert(sizeof(CHeli) == 0x33C, "CHeli: error");
+
+VALIDATE_SIZE(CHeli, 0x33C);
+
diff --git a/src/vehicles/Plane.cpp b/src/vehicles/Plane.cpp
index 273ac54a..71189d84 100644
--- a/src/vehicles/Plane.cpp
+++ b/src/vehicles/Plane.cpp
@@ -81,7 +81,7 @@ CPlane::CPlane(int32 id, uint8 CreatedBy)
m_bIsDrugRunCesna = false;
m_bIsDropOffCesna = false;
- m_status = STATUS_PLANE;
+ SetStatus(STATUS_PLANE);
bIsBIGBuilding = true;
m_level = LEVEL_NONE;
}
@@ -359,8 +359,8 @@ CPlane::ProcessControl(void)
CVector posFront2 = (1.0f - f)*pPathNodes[curPathNodeFront2].p + f*pPathNodes[nextPathNodeFront2].p;
// Now set matrix
- GetPosition() = (posRear + posFront)/2.0f;
- GetPosition().z += 4.3f;
+ GetMatrix().GetPosition() = (posRear + posFront) / 2.0f;
+ GetMatrix().GetPosition().z += 4.3f;
CVector fwd = posFront - posRear;
fwd.Normalise();
if(pitch != 0.0f){
@@ -375,9 +375,9 @@ CPlane::ProcessControl(void)
right.z += 3.0f*roll.z;
right.Normalise();
CVector up = CrossProduct(right, fwd);
- GetRight() = right;
- GetUp() = up;
- GetForward() = fwd;
+ GetMatrix().GetRight() = right;
+ GetMatrix().GetUp() = up;
+ GetMatrix().GetForward() = fwd;
// Set speed
m_vecMoveSpeed = fwd*PlanePathSpeed[m_nPlaneId]/60.0f;
@@ -511,8 +511,8 @@ CPlane::ProcessControl(void)
CVector posFront2 = (1.0f - f)*pathNodes[curPathNodeFront2].p + f*pathNodes[nextPathNodeFront2].p;
// Now set matrix
- GetPosition() = (posRear + posFront)/2.0f;
- GetPosition().z += 1.0f;
+ GetMatrix().GetPosition() = (posRear + posFront) / 2.0f;
+ GetMatrix().GetPosition().z += 1.0f;
CVector fwd = posFront - posRear;
fwd.Normalise();
CVector fwd2 = posFront2 - posRear;
@@ -522,9 +522,9 @@ CPlane::ProcessControl(void)
right.z += 3.0f*roll.z;
right.Normalise();
CVector up = CrossProduct(right, fwd);
- GetRight() = right;
- GetUp() = up;
- GetForward() = fwd;
+ GetMatrix().GetRight() = right;
+ GetMatrix().GetUp() = up;
+ GetMatrix().GetForward() = fwd;
// Set speed
m_vecMoveSpeed = fwd*planePathSpeed/60.0f;
@@ -754,7 +754,7 @@ CPlane::InitPlanes(void)
for(i = 0; i < 3; i++){
CPlane *plane = new CPlane(MI_AIRTRAIN, PERMANENT_VEHICLE);
plane->GetMatrix().SetTranslate(0.0f, 0.0f, 0.0f);
- plane->m_status = STATUS_ABANDONED;
+ plane->SetStatus(STATUS_ABANDONED);
plane->bIsLocked = true;
plane->m_nPlaneId = i;
plane->m_nCurPathNode = 0;
@@ -768,7 +768,7 @@ CPlane::InitPlanes(void)
for(i = 0; i < 3; i++){
CPlane *plane = new CPlane(MI_DEADDODO, PERMANENT_VEHICLE);
plane->GetMatrix().SetTranslate(0.0f, 0.0f, 0.0f);
- plane->m_status = STATUS_ABANDONED;
+ plane->SetStatus(STATUS_ABANDONED);
plane->bIsLocked = true;
plane->m_nPlaneId = i;
plane->m_nCurPathNode = 0;
@@ -926,7 +926,7 @@ CPlane::CreateIncomingCesna(void)
}
pDrugRunCesna = new CPlane(MI_DEADDODO, PERMANENT_VEHICLE);
pDrugRunCesna->GetMatrix().SetTranslate(0.0f, 0.0f, 0.0f);
- pDrugRunCesna->m_status = STATUS_ABANDONED;
+ pDrugRunCesna->SetStatus(STATUS_ABANDONED);
pDrugRunCesna->bIsLocked = true;
pDrugRunCesna->m_nPlaneId = 0;
pDrugRunCesna->m_nCurPathNode = 0;
@@ -948,7 +948,7 @@ CPlane::CreateDropOffCesna(void)
}
pDropOffCesna = new CPlane(MI_DEADDODO, PERMANENT_VEHICLE);
pDropOffCesna->GetMatrix().SetTranslate(0.0f, 0.0f, 0.0f);
- pDropOffCesna->m_status = STATUS_ABANDONED;
+ pDropOffCesna->SetStatus(STATUS_ABANDONED);
pDropOffCesna->bIsLocked = true;
pDropOffCesna->m_nPlaneId = 0;
pDropOffCesna->m_nCurPathNode = 0;
diff --git a/src/vehicles/Plane.h b/src/vehicles/Plane.h
index 79738858..7e822d64 100644
--- a/src/vehicles/Plane.h
+++ b/src/vehicles/Plane.h
@@ -63,7 +63,8 @@ public:
static bool HasCesnaBeenDestroyed(void);
static bool HasDropOffCesnaBeenShotDown(void);
};
-static_assert(sizeof(CPlane) == 0x29C, "CPlane: error");
+
+VALIDATE_SIZE(CPlane, 0x29C);
extern float LandingPoint;
extern float TakeOffPoint;
diff --git a/src/vehicles/Train.cpp b/src/vehicles/Train.cpp
index 0d1ff9b0..7831a0c8 100644
--- a/src/vehicles/Train.cpp
+++ b/src/vehicles/Train.cpp
@@ -59,7 +59,7 @@ CTrain::CTrain(int32 id, uint8 CreatedBy)
m_nDoorState = TRAIN_DOOR_CLOSED;
bUsesCollision = true;
- m_status = STATUS_TRAIN_MOVING;
+ SetStatus(STATUS_TRAIN_MOVING);
}
void
@@ -161,7 +161,7 @@ CTrain::ProcessControl(void)
CVector posFront = (1.0f - f)*trackNodes[curTrackNodeFront].p + f*trackNodes[nextTrackNodeFront].p;
// Now set matrix
- GetPosition() = (posRear + posFront)/2.0f;
+ SetPosition((posRear + posFront)/2.0f);
CVector fwd = posFront - posRear;
fwd.Normalise();
CVector right = CrossProduct(fwd, CVector(0.0f, 0.0f, 1.0f));
@@ -177,11 +177,11 @@ CTrain::ProcessControl(void)
m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f);
if(engineTrackSpeed[m_nWagonGroup] > 0.001f){
- m_status = STATUS_TRAIN_MOVING;
+ SetStatus(STATUS_TRAIN_MOVING);
m_bTrainStopping = false;
m_bProcessDoor = true;
}else{
- m_status = STATUS_TRAIN_NOT_MOVING;
+ SetStatus(STATUS_TRAIN_NOT_MOVING);
m_bTrainStopping = true;
}
@@ -252,7 +252,7 @@ CTrain::ProcessControl(void)
}
// Hit stuff
- if(m_bIsFirstWagon && m_status == STATUS_TRAIN_MOVING){
+ if(m_bIsFirstWagon && GetStatus()== STATUS_TRAIN_MOVING){
CVector front = GetPosition() + GetForward()*GetColModel()->boundingBox.max.y + m_vecMoveSpeed*CTimer::GetTimeStep();
int x, xmin, xmax;
@@ -440,7 +440,7 @@ CTrain::InitTrains(void)
for(i = 0; i < 5; i++){
train = new CTrain(MI_TRAIN, PERMANENT_VEHICLE);
train->GetMatrix().SetTranslate(0.0f, 0.0f, 0.0f);
- train->m_status = STATUS_ABANDONED;
+ train->SetStatus(STATUS_ABANDONED);
train->bIsLocked = true;
train->m_fWagonPosition = wagonPositions[i];
train->m_bIsFirstWagon = firstWagon[i];
@@ -459,7 +459,7 @@ CTrain::InitTrains(void)
for(i = 0; i < 8; i++){
train = new CTrain(MI_TRAIN, PERMANENT_VEHICLE);
train->GetMatrix().SetTranslate(0.0f, 0.0f, 0.0f);
- train->m_status = STATUS_ABANDONED;
+ train->SetStatus(STATUS_ABANDONED);
train->bIsLocked = true;
train->m_fWagonPosition = wagonPositions_S[i];
train->m_bIsFirstWagon = firstWagon_S[i];
diff --git a/src/vehicles/Train.h b/src/vehicles/Train.h
index bf541250..6aa76fa8 100644
--- a/src/vehicles/Train.h
+++ b/src/vehicles/Train.h
@@ -91,4 +91,5 @@ public:
float *totalLength, float *totalDuration, CTrainInterpolationLine *interpLines, bool rightRail);
static void UpdateTrains(void);
};
-static_assert(sizeof(CTrain) == 0x2E4, "CTrain: error");
+
+VALIDATE_SIZE(CTrain, 0x2E4);
diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp
index d0ccd31b..5dc7bc72 100644
--- a/src/vehicles/Vehicle.cpp
+++ b/src/vehicles/Vehicle.cpp
@@ -98,7 +98,7 @@ CVehicle::CVehicle(uint8 CreatedBy)
bHasAlreadyBeenRecorded = false;
m_bSirenOrAlarm = 0;
m_nCarHornTimer = 0;
- field_22D = 0;
+ m_nCarHornPattern = 0;
m_nAlarmState = 0;
m_nDoorLock = CARLOCK_UNLOCKED;
m_nLastWeaponDamage = -1;
@@ -393,7 +393,7 @@ CVehicle::FlyingControl(eFlightModel flightModel)
m_vecMoveSpeed.x *= rmX;
m_vecMoveSpeed.y *= rmY;
m_vecMoveSpeed.z *= rmZ;
- if (m_status != STATUS_PLAYER && m_status != STATUS_PLAYER_REMOTE)
+ if (GetStatus() != STATUS_PLAYER && GetStatus() != STATUS_PLAYER_REMOTE)
return;
float fThrust;
if (bCheat5)
@@ -623,13 +623,13 @@ CVehicle::InflictDamage(CEntity* damagedBy, eWeaponType weaponType, float damage
}
if (m_fHealth > 0.0f) {
if (VehicleCreatedBy == RANDOM_VEHICLE && pDriver &&
- (m_status == STATUS_SIMPLE || m_status == STATUS_PHYSICS) &&
+ (GetStatus() == STATUS_SIMPLE || GetStatus() == STATUS_PHYSICS) &&
AutoPilot.m_nCarMission == MISSION_CRUISE) {
if (m_randomSeed < DAMAGE_FLEE_IN_CAR_PROBABILITY_VALUE) {
CCarCtrl::SwitchVehicleToRealPhysics(this);
AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * pHandling->Transmission.fUnkMaxVelocity;
- m_status = STATUS_PHYSICS;
+ SetStatus(STATUS_PHYSICS);
}
}
m_nLastWeaponDamage = weaponType;
@@ -639,11 +639,11 @@ CVehicle::InflictDamage(CEntity* damagedBy, eWeaponType weaponType, float damage
if (VehicleCreatedBy == RANDOM_VEHICLE &&
(m_fHealth < DAMAGE_HEALTH_TO_FLEE_ALWAYS ||
bFrightensDriver && m_randomSeed > DAMAGE_FLEE_ON_FOOT_PROBABILITY_VALUE)) {
- switch (m_status) {
+ switch (GetStatus()) {
case STATUS_SIMPLE:
case STATUS_PHYSICS:
if (pDriver) {
- m_status = STATUS_ABANDONED;
+ SetStatus(STATUS_ABANDONED);
pDriver->bFleeAfterExitingCar = true;
pDriver->SetObjective(OBJECTIVE_LEAVE_VEHICLE, this);
}
@@ -871,7 +871,7 @@ CVehicle::UsesSiren(uint32 id)
bool
CVehicle::IsVehicleNormal(void)
{
- if (!pDriver || m_nNumPassengers != 0 || m_status == STATUS_WRECKED)
+ if (!pDriver || m_nNumPassengers != 0 || GetStatus() == STATUS_WRECKED)
return false;
switch (GetModelIndex()){
case MI_FIRETRUCK:
@@ -1141,7 +1141,7 @@ CVehicle::AddPassenger(CPed *passenger, uint8 n)
void
CVehicle::RemoveDriver(void)
{
- m_status = STATUS_ABANDONED;
+ SetStatus(STATUS_ABANDONED);
pDriver = nil;
}
@@ -1222,3 +1222,128 @@ DestroyVehicleAndDriverAndPassengers(CVehicle* pVehicle)
CWorld::Remove(pVehicle);
delete pVehicle;
}
+
+#ifdef COMPATIBLE_SAVES
+void
+CVehicle::Save(uint8*& buf)
+{
+ SkipSaveBuf(buf, 4);
+ WriteSaveBuf<float>(buf, GetRight().x);
+ WriteSaveBuf<float>(buf, GetRight().y);
+ WriteSaveBuf<float>(buf, GetRight().z);
+ SkipSaveBuf(buf, 4);
+ WriteSaveBuf<float>(buf, GetForward().x);
+ WriteSaveBuf<float>(buf, GetForward().y);
+ WriteSaveBuf<float>(buf, GetForward().z);
+ SkipSaveBuf(buf, 4);
+ WriteSaveBuf<float>(buf, GetUp().x);
+ WriteSaveBuf<float>(buf, GetUp().y);
+ WriteSaveBuf<float>(buf, GetUp().z);
+ SkipSaveBuf(buf, 4);
+ WriteSaveBuf<float>(buf, GetPosition().x);
+ WriteSaveBuf<float>(buf, GetPosition().y);
+ WriteSaveBuf<float>(buf, GetPosition().z);
+ SkipSaveBuf(buf, 16);
+ SaveEntityFlags(buf);
+ SkipSaveBuf(buf, 212);
+ AutoPilot.Save(buf);
+ WriteSaveBuf<int8>(buf, m_currentColour1);
+ WriteSaveBuf<int8>(buf, m_currentColour2);
+ SkipSaveBuf(buf, 2);
+ WriteSaveBuf<int16>(buf, m_nAlarmState);
+ SkipSaveBuf(buf, 43);
+ WriteSaveBuf<uint8>(buf, m_nNumMaxPassengers);
+ SkipSaveBuf(buf, 2);
+ WriteSaveBuf<float>(buf, field_1D0[0]);
+ WriteSaveBuf<float>(buf, field_1D0[1]);
+ WriteSaveBuf<float>(buf, field_1D0[2]);
+ WriteSaveBuf<float>(buf, field_1D0[3]);
+ SkipSaveBuf(buf, 8);
+ WriteSaveBuf<float>(buf, m_fSteerAngle);
+ WriteSaveBuf<float>(buf, m_fGasPedal);
+ WriteSaveBuf<float>(buf, m_fBrakePedal);
+ WriteSaveBuf<uint8>(buf, VehicleCreatedBy);
+ uint8 flags = 0;
+ if (bIsLawEnforcer) flags |= BIT(0);
+ if (bIsLocked) flags |= BIT(3);
+ if (bEngineOn) flags |= BIT(4);
+ if (bIsHandbrakeOn) flags |= BIT(5);
+ if (bLightsOn) flags |= BIT(6);
+ if (bFreebies) flags |= BIT(7);
+ WriteSaveBuf<uint8>(buf, flags);
+ SkipSaveBuf(buf, 10);
+ WriteSaveBuf<float>(buf, m_fHealth);
+ WriteSaveBuf<uint8>(buf, m_nCurrentGear);
+ SkipSaveBuf(buf, 3);
+ WriteSaveBuf<float>(buf, m_fChangeGearTime);
+ SkipSaveBuf(buf, 4);
+ WriteSaveBuf<uint32>(buf, m_nTimeOfDeath);
+ SkipSaveBuf(buf, 2);
+ WriteSaveBuf<int16>(buf, m_nBombTimer);
+ SkipSaveBuf(buf, 12);
+ WriteSaveBuf<int8>(buf, m_nDoorLock);
+ SkipSaveBuf(buf, 99);
+}
+
+void
+CVehicle::Load(uint8*& buf)
+{
+ CMatrix tmp;
+ SkipSaveBuf(buf, 4);
+ tmp.GetRight().x = ReadSaveBuf<float>(buf);
+ tmp.GetRight().y = ReadSaveBuf<float>(buf);
+ tmp.GetRight().z = ReadSaveBuf<float>(buf);
+ SkipSaveBuf(buf, 4);
+ tmp.GetForward().x = ReadSaveBuf<float>(buf);
+ tmp.GetForward().y = ReadSaveBuf<float>(buf);
+ tmp.GetForward().z = ReadSaveBuf<float>(buf);
+ SkipSaveBuf(buf, 4);
+ tmp.GetUp().x = ReadSaveBuf<float>(buf);
+ tmp.GetUp().y = ReadSaveBuf<float>(buf);
+ tmp.GetUp().z = ReadSaveBuf<float>(buf);
+ SkipSaveBuf(buf, 4);
+ tmp.GetPosition().x = ReadSaveBuf<float>(buf);
+ tmp.GetPosition().y = ReadSaveBuf<float>(buf);
+ tmp.GetPosition().z = ReadSaveBuf<float>(buf);
+ m_matrix = tmp;
+ SkipSaveBuf(buf, 16);
+ LoadEntityFlags(buf);
+ SkipSaveBuf(buf, 212);
+ AutoPilot.Load(buf);
+ m_currentColour1 = ReadSaveBuf<int8>(buf);
+ m_currentColour2 = ReadSaveBuf<int8>(buf);
+ SkipSaveBuf(buf, 2);
+ m_nAlarmState = ReadSaveBuf<int16>(buf);
+ SkipSaveBuf(buf, 43);
+ m_nNumMaxPassengers = ReadSaveBuf<int8>(buf);
+ SkipSaveBuf(buf, 2);
+ field_1D0[0] = ReadSaveBuf<float>(buf);
+ field_1D0[1] = ReadSaveBuf<float>(buf);
+ field_1D0[2] = ReadSaveBuf<float>(buf);
+ field_1D0[3] = ReadSaveBuf<float>(buf);
+ SkipSaveBuf(buf, 8);
+ m_fSteerAngle = ReadSaveBuf<float>(buf);
+ m_fGasPedal = ReadSaveBuf<float>(buf);
+ m_fBrakePedal = ReadSaveBuf<float>(buf);
+ VehicleCreatedBy = ReadSaveBuf<uint8>(buf);
+ uint8 flags = ReadSaveBuf<uint8>(buf);
+ bIsLawEnforcer = !!(flags & BIT(0));
+ bIsLocked = !!(flags & BIT(3));
+ bEngineOn = !!(flags & BIT(4));
+ bIsHandbrakeOn = !!(flags & BIT(5));
+ bLightsOn = !!(flags & BIT(6));
+ bFreebies = !!(flags & BIT(7));
+ SkipSaveBuf(buf, 10);
+ m_fHealth = ReadSaveBuf<float>(buf);
+ m_nCurrentGear = ReadSaveBuf<uint8>(buf);
+ SkipSaveBuf(buf, 3);
+ m_fChangeGearTime = ReadSaveBuf<float>(buf);
+ SkipSaveBuf(buf, 4);
+ m_nTimeOfDeath = ReadSaveBuf<uint32>(buf);
+ SkipSaveBuf(buf, 2);
+ m_nBombTimer = ReadSaveBuf<int16>(buf);
+ SkipSaveBuf(buf, 12);
+ m_nDoorLock = (eCarLock)ReadSaveBuf<int8>(buf);
+ SkipSaveBuf(buf, 99);
+}
+#endif
diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h
index cb4ac2cf..f7205c7d 100644
--- a/src/vehicles/Vehicle.h
+++ b/src/vehicles/Vehicle.h
@@ -193,7 +193,7 @@ public:
uint8 m_bRainAudioCounter;
uint8 m_bRainSamplesCounter;
uint8 m_nCarHornTimer;
- int8 field_22D; // last horn?
+ uint8 m_nCarHornPattern; // last horn?
bool m_bSirenOrAlarm;
int8 m_comedyControlState;
CStoredCollPoly m_aCollPolys[2]; // poly which is under front/rear part of car
@@ -231,6 +231,10 @@ public:
virtual bool IsRoomForPedToLeaveCar(uint32 component, CVector *forcedDoorPos) { return false;}
virtual float GetHeightAboveRoad(void);
virtual void PlayCarHorn(void) {}
+#ifdef COMPATIBLE_SAVES
+ virtual void Save(uint8*& buf);
+ virtual void Load(uint8*& buf);
+#endif
bool IsCar(void) { return m_vehType == VEHICLE_TYPE_CAR; }
bool IsBoat(void) { return m_vehType == VEHICLE_TYPE_BOAT; }
@@ -270,6 +274,7 @@ public:
void InflictDamage(CEntity *damagedBy, eWeaponType weaponType, float damage);
void DoFixedMachineGuns(void);
+
bool IsAlarmOn(void) { return m_nAlarmState != 0 && m_nAlarmState != -1; }
CVehicleModelInfo* GetModelInfo() { return (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()); }
bool IsTaxi(void) { return GetModelIndex() == MI_TAXI || GetModelIndex() == MI_CABBIE || GetModelIndex() == MI_BORGNINE; }
@@ -286,9 +291,6 @@ public:
static bool m_bDisableMouseSteering;
};
-static_assert(sizeof(CVehicle) == 0x288, "CVehicle: error");
-static_assert(offsetof(CVehicle, m_pCurGroundEntity) == 0x1E0, "CVehicle: error");
-static_assert(offsetof(CVehicle, m_nAlarmState) == 0x1A0, "CVehicle: error");
-static_assert(offsetof(CVehicle, m_nLastWeaponDamage) == 0x228, "CVehicle: error");
+VALIDATE_SIZE(CVehicle, 0x288);
void DestroyVehicleAndDriverAndPassengers(CVehicle* pVehicle);