diff options
Diffstat (limited to '')
-rw-r--r-- | src/vehicles/Automobile.cpp | 128 | ||||
-rw-r--r-- | src/vehicles/Automobile.h | 8 | ||||
-rw-r--r-- | src/vehicles/Boat.cpp | 41 | ||||
-rw-r--r-- | src/vehicles/Boat.h | 9 | ||||
-rw-r--r-- | src/vehicles/CarGen.cpp | 10 | ||||
-rw-r--r-- | src/vehicles/Cranes.cpp | 10 | ||||
-rw-r--r-- | src/vehicles/Cranes.h | 2 | ||||
-rw-r--r-- | src/vehicles/Heli.cpp | 18 | ||||
-rw-r--r-- | src/vehicles/Heli.h | 4 | ||||
-rw-r--r-- | src/vehicles/Plane.cpp | 30 | ||||
-rw-r--r-- | src/vehicles/Plane.h | 3 | ||||
-rw-r--r-- | src/vehicles/Train.cpp | 14 | ||||
-rw-r--r-- | src/vehicles/Train.h | 3 | ||||
-rw-r--r-- | src/vehicles/Vehicle.cpp | 141 | ||||
-rw-r--r-- | src/vehicles/Vehicle.h | 12 |
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); |