From 36f3a517f9664415b07a4aa537db22159b67a8f2 Mon Sep 17 00:00:00 2001 From: aap Date: Tue, 16 Jul 2019 19:48:50 +0200 Subject: more fixes; started CAutomobile::ProcessControl --- src/control/Script.cpp | 48 ++++---- src/core/World.cpp | 16 +-- src/entities/Entity.h | 7 +- src/peds/Ped.cpp | 4 +- src/vehicles/Automobile.cpp | 288 +++++++++++++++++++++++++++++++++++++++++-- src/vehicles/Automobile.h | 17 ++- src/vehicles/DamageManager.h | 3 +- src/vehicles/Vehicle.cpp | 36 +++--- src/vehicles/Vehicle.h | 10 +- 9 files changed, 350 insertions(+), 79 deletions(-) (limited to 'src') diff --git a/src/control/Script.cpp b/src/control/Script.cpp index a363cc41..88537da8 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -1891,9 +1891,9 @@ int8 CRunningScript::ProcessCommandsFrom100To199(int32 command) CTheScripts::ClearSpaceForMissionEntity(pos, boat); boat->m_status = STATUS_ABANDONED; boat->bIsLocked = true; - boat->m_autoPilot.m_nCarMission = MISSION_NONE; - boat->m_autoPilot.m_nAnimationId = TEMPACT_NONE; /* Animation ID? */ - boat->m_autoPilot.m_nCruiseSpeed = boat->m_autoPilot.m_fMaxTrafficSpeed = 20.0f; + boat->AutoPilot.m_nCarMission = MISSION_NONE; + boat->AutoPilot.m_nAnimationId = TEMPACT_NONE; /* Animation ID? */ + boat->AutoPilot.m_nCruiseSpeed = boat->AutoPilot.m_fMaxTrafficSpeed = 20.0f; CWorld::Add(boat); handle = CPools::GetVehiclePool()->GetIndex(boat); } @@ -1909,11 +1909,11 @@ int8 CRunningScript::ProcessCommandsFrom100To199(int32 command) CTheScripts::ClearSpaceForMissionEntity(pos, car); car->m_status = STATUS_ABANDONED; car->bIsLocked = true; - car->m_autoPilot.m_nCarMission = MISSION_NONE; - car->m_autoPilot.m_nAnimationId = TEMPACT_NONE; /* Animation ID? */ - car->m_autoPilot.m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS; - car->m_autoPilot.m_nCruiseSpeed = car->m_autoPilot.m_fMaxTrafficSpeed = 9.0f; - car->m_autoPilot.m_nPreviousLane = car->m_autoPilot.m_nCurrentLane = 0; + car->AutoPilot.m_nCarMission = MISSION_NONE; + car->AutoPilot.m_nAnimationId = TEMPACT_NONE; /* Animation ID? */ + car->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS; + car->AutoPilot.m_nCruiseSpeed = car->AutoPilot.m_fMaxTrafficSpeed = 9.0f; + car->AutoPilot.m_nPreviousLane = car->AutoPilot.m_nCurrentLane = 0; car->bEngineOn = false; car->m_level = CTheZones::GetLevelFromPosition(pos); car->bHasBeenOwnedByPlayer = true; @@ -1949,13 +1949,13 @@ int8 CRunningScript::ProcessCommandsFrom100To199(int32 command) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); pos.z += car->GetDistanceFromCentreOfMassToBaseOfModel(); if (CCarCtrl::JoinCarWithRoadSystemGotoCoors(car, pos, false)) - car->m_autoPilot.m_nCarMission = MISSION_GOTOCOORDS_STRAIGHT; + car->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS_STRAIGHT; else - car->m_autoPilot.m_nCarMission = MISSION_GOTOCOORDS; + car->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS; car->m_status = STATUS_PHYSICS; car->bEngineOn = true; - car->m_autoPilot.m_nCruiseSpeed = max(car->m_autoPilot.m_nCruiseSpeed, 6); - car->m_autoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds(); + car->AutoPilot.m_nCruiseSpeed = max(car->AutoPilot.m_nCruiseSpeed, 6); + car->AutoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds(); return 0; } case COMMAND_CAR_WANDER_RANDOMLY: @@ -1964,10 +1964,10 @@ int8 CRunningScript::ProcessCommandsFrom100To199(int32 command) CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); assert(car); CCarCtrl::JoinCarWithRoadSystem(car); - car->m_autoPilot.m_nCarMission = MISSION_CRUISE; + car->AutoPilot.m_nCarMission = MISSION_CRUISE; car->bEngineOn = true; - car->m_autoPilot.m_nCruiseSpeed = max(car->m_autoPilot.m_nCruiseSpeed, 6); - car->m_autoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds(); + car->AutoPilot.m_nCruiseSpeed = max(car->AutoPilot.m_nCruiseSpeed, 6); + car->AutoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds(); return 0; } case COMMAND_CAR_SET_IDLE: @@ -1975,7 +1975,7 @@ int8 CRunningScript::ProcessCommandsFrom100To199(int32 command) CollectParameters(&m_nIp, 1); CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); assert(car); - car->m_autoPilot.m_nCarMission = MISSION_NONE; + car->AutoPilot.m_nCarMission = MISSION_NONE; return 0; } case COMMAND_GET_CAR_COORDINATES: @@ -2006,7 +2006,7 @@ int8 CRunningScript::ProcessCommandsFrom100To199(int32 command) car->Teleport(pos); CTheScripts::ClearSpaceForMissionEntity(pos, car); /* May the following be inlined CCarCtrl function? */ - switch (car->m_autoPilot.m_nCarMission) { + switch (car->AutoPilot.m_nCarMission) { case MISSION_CRUISE: CCarCtrl::JoinCarWithRoadSystem(car); break; @@ -2019,18 +2019,18 @@ int8 CRunningScript::ProcessCommandsFrom100To199(int32 command) break; case MISSION_GOTOCOORDS: case MISSION_GOTOCOORDS_STRAIGHT: - CCarCtrl::JoinCarWithRoadSystemGotoCoors(car, car->m_autoPilot.m_vecDestinationCoors, false); + CCarCtrl::JoinCarWithRoadSystemGotoCoors(car, car->AutoPilot.m_vecDestinationCoors, false); break; case MISSION_GOTOCOORDS_ACCURATE: case MISSION_GOTO_COORDS_STRAIGHT_ACCURATE: - CCarCtrl::JoinCarWithRoadSystemGotoCoors(car, car->m_autoPilot.m_vecDestinationCoors, false); + CCarCtrl::JoinCarWithRoadSystemGotoCoors(car, car->AutoPilot.m_vecDestinationCoors, false); break; case MISSION_RAMCAR_FARAWAY: case MISSION_RAMCAR_CLOSE: case MISSION_BLOCKCAR_FARAWAY: case MISSION_BLOCKCAR_CLOSE: case MISSION_BLOCKCAR_HANDBRAKESTOP: - CCarCtrl::JoinCarWithRoadSystemGotoCoors(car, car->m_autoPilot.m_pTargetCar->GetPosition(), false); + CCarCtrl::JoinCarWithRoadSystemGotoCoors(car, car->AutoPilot.m_pTargetCar->GetPosition(), false); break; default: break; @@ -2050,7 +2050,7 @@ int8 CRunningScript::ProcessCommandsFrom100To199(int32 command) CollectParameters(&m_nIp, 2); CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); assert(car); - car->m_autoPilot.m_nCruiseSpeed = min(*(float*)&ScriptParams[1], 60.0f * car->m_handling->TransmissionData.fUnkMaxVelocity); + car->AutoPilot.m_nCruiseSpeed = min(*(float*)&ScriptParams[1], 60.0f * car->m_handling->TransmissionData.fUnkMaxVelocity); return 0; } case COMMAND_SET_CAR_DRIVING_STYLE: @@ -2058,7 +2058,7 @@ int8 CRunningScript::ProcessCommandsFrom100To199(int32 command) CollectParameters(&m_nIp, 2); CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); assert(car); - car->m_autoPilot.m_nDrivingStyle = (eCarDrivingStyle)ScriptParams[1]; + car->AutoPilot.m_nDrivingStyle = (eCarDrivingStyle)ScriptParams[1]; return 0; } case COMMAND_SET_CAR_MISSION: @@ -2066,8 +2066,8 @@ int8 CRunningScript::ProcessCommandsFrom100To199(int32 command) CollectParameters(&m_nIp, 2); CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); assert(car); - car->m_autoPilot.m_nCarMission = (eCarMission)ScriptParams[1]; - car->m_autoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds(); + car->AutoPilot.m_nCarMission = (eCarMission)ScriptParams[1]; + car->AutoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds(); car->bEngineOn = true; return 0; } diff --git a/src/core/World.cpp b/src/core/World.cpp index e8fc54a2..829a64d4 100644 --- a/src/core/World.cpp +++ b/src/core/World.cpp @@ -607,12 +607,12 @@ CWorld::FindObjectsInRange(CVector ¢re, float distance, bool ignoreZ, short minY = 0; int maxX = GetSectorIndexX(centre.x + distance); - if (maxX >= 100) - maxX = 100; + if (maxX >= NUMSECTORS_X) + maxX = NUMSECTORS_X; int maxY = GetSectorIndexY(centre.y + distance); - if (maxY >= 100) - maxY = 100; + if (maxY >= NUMSECTORS_Y) + maxY = NUMSECTORS_Y; AdvanceCurrentScanCode(); @@ -658,12 +658,12 @@ CWorld::TestSphereAgainstWorld(CVector centre, float distance, CEntity* entityTo minY = 0; int maxX = GetSectorIndexX(centre.x + distance); - if (maxX >= 100) - maxX = 100; + if (maxX >= NUMSECTORS_X) + maxX = NUMSECTORS_X; int maxY = GetSectorIndexY(centre.y + distance); - if (maxY >= 100) - maxY = 100; + if (maxY >= NUMSECTORS_Y) + maxY = NUMSECTORS_Y; AdvanceCurrentScanCode(); diff --git a/src/entities/Entity.h b/src/entities/Entity.h index 12a631d2..69fd6eea 100644 --- a/src/entities/Entity.h +++ b/src/entities/Entity.h @@ -13,14 +13,11 @@ enum eEntityType ENTITY_TYPE_PED, ENTITY_TYPE_OBJECT, ENTITY_TYPE_DUMMY, - ENTITY_TYPE_6, - ENTITY_TYPE_7, }; enum eEntityStatus { - // from SA MTA! let's hope they didn't change from III - STATUS_PLAYER = 0, + STATUS_PLAYER, STATUS_PLAYER_PLAYBACKFROMBUFFER, STATUS_SIMPLE, STATUS_PHYSICS, @@ -32,8 +29,6 @@ enum eEntityStatus STATUS_PLANE, STATUS_PLAYER_REMOTE, STATUS_PLAYER_DISABLED, - //STATUS_TRAILER, - //STATUS_SIMPLE_TRAILER }; class CEntity : public CPlaceable diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index e81dfa51..dc645003 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -2733,8 +2733,8 @@ CPed::QuitEnteringCar(void) m_pVehicleAnim = nil; if (veh) { - if (veh->m_autoPilot.m_nCruiseSpeed == 0) - veh->m_autoPilot.m_nCruiseSpeed = 17; + if (veh->AutoPilot.m_nCruiseSpeed == 0) + veh->AutoPilot.m_nCruiseSpeed = 17; } } diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index 1f64228b..ba8388d6 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -38,7 +38,270 @@ CAutomobile::SetModelIndex(uint32 id) SetupModelNodes(); } -WRAPPER void CAutomobile::ProcessControl(void) { EAXJMP(0x531470); } +//WRAPPER void CAutomobile::ProcessControl(void) { EAXJMP(0x531470); } +void +CAutomobile::ProcessControl(void) +{ + int i; + CColModel *colModel; + + if(m_veh_flagC80) + colModel = &CWorld::Players[CWorld::PlayerInFocus].m_ColModel; + else + colModel = GetColModel(); + bWarnedPeds = false; + + // skip if the collision isn't for the current level + if(colModel->level > LEVEL_NONE && colModel->level != CCollision::ms_collisionInMemory) + return; + + bool strongGrip = false; + + assert(0 && "some player stuff"); + + if(bIsBus) + ProcessAutoBusDoors(); + + ProcessCarAlarm(); + + // Scan if this car is committing a crime that the police can see + if(m_status != STATUS_ABANDONED && m_status != STATUS_WRECKED && + m_status != STATUS_PLAYER && m_status != STATUS_PLAYER_REMOTE && m_status != STATUS_PLAYER_DISABLED){ + switch(GetModelIndex()) + case MI_FBICAR: + case MI_POLICE: + case MI_ENFORCER: + case MI_SECURICA: + case MI_RHINO: + case MI_BARRACKS: + ScanForCrimes(); + } + + // Process driver + if(pDriver){ + if(!bHadDriver && m_bombType == 5){ + // If someone enters the car and there is a bomb, detonate + m_nBombTimer = 1000; + m_pBlowUpEntity = field_4DC; + if(m_pBlowUpEntity) + m_pBlowUpEntity->RegisterReference((CEntity**)&m_pBlowUpEntity); + DMAudio.PlayOneShot(m_audioEntityId, SOUND_BOMB_TICK, 1.0f); + } + bHadDriver = true; + + if(IsUpsideDown() && CanPedEnterCar()){ + if(!pDriver->IsPlayer() && + !(pDriver->m_leader && pDriver->m_leader->bInVehicle) && + pDriver->CharCreatedBy != MISSION_CHAR) + pDriver->SetObjective(OBJECTIVE_LEAVE_VEHICLE, this); + } + }else + bHadDriver = false; + + // Process passengers + if(m_nNumPassengers != 0 && IsUpsideDown() && CanPedEnterCar()){ + for(i = 0; i < m_nNumMaxPassengers; i++) + if(pPassengers[i]) + if(!pPassengers[i]->IsPlayer() && + !(pPassengers[i]->m_leader && pPassengers[i]->m_leader->bInVehicle) && + pPassengers[i]->CharCreatedBy != MISSION_CHAR) + pPassengers[i]->SetObjective(OBJECTIVE_LEAVE_VEHICLE, this); + } + + // CRubbish::StirUp + + // blend in clump + int clumpAlpha = CVisibilityPlugins::GetClumpAlpha((RpClump*)m_rwObject); + if(bFadeOut){ + clumpAlpha -= 8; + if(clumpAlpha < 0) + clumpAlpha = 0; + }else if(clumpAlpha < 255){ + clumpAlpha += 16; + if(clumpAlpha > 255) + clumpAlpha = 255; + } + CVisibilityPlugins::SetClumpAlpha((RpClump*)m_rwObject, clumpAlpha); + + AutoPilot.m_flag1 = false; + AutoPilot.m_flag2 = false; + + // Set Center of Mass to make car more stable + if(strongGrip || bCheat3) + m_vecCentreOfMass.z = 0.3f*m_aSuspensionSpringLength[0] + -1.0*m_fHeightAboveRoad; + else if(m_handling->Flags & HANDLING_NONPLAYER_STABILISER && m_status == STATUS_PHYSICS) + m_vecCentreOfMass.z = m_handling->CentreOfMass.z - 0.2f*m_handling->Dimension.z; + else + m_vecCentreOfMass.z = m_handling->CentreOfMass.z; + + // Process depending on status + + switch(m_status){ + case STATUS_PLAYER: + case STATUS_SIMPLE: + case STATUS_PHYSICS: + case STATUS_ABANDONED: + case STATUS_WRECKED: + case STATUS_PLAYER_REMOTE: + case STATUS_PLAYER_DISABLED: + assert(0); + } + + if(GetPosition().z < -0.6f){ + assert(0); + } + + bool skipPhysics = false; + if(!bIsStuck){ + assert(0); + } + + // Postpone + for(i = 0; i < 4; i++) + if(m_aGroundPhysical[i] && !CWorld::bForceProcessControl && m_aGroundPhysical[i]->bIsInSafePosition){ + bWasPostponed = true; + return; + } + + // VehicleDamage + + // special control + switch(GetModelIndex()){ + case MI_FIRETRUCK: + case MI_RHINO: + case MI_YARDIE: + default: + assert(0); + } + + if(skipPhysics){ + bHasContacted = false; + bIsInSafePosition = false; + bWasPostponed = false; + bHasHitWall = false; + m_nCollisionRecords = 0; + bHasCollided = false; + bVehicleColProcessed = false; + m_nDamagePieceType = 0; + m_fDamageImpulse = 0.0f; + m_pDamageEntity = nil; + m_vecTurnFriction = CVector(0.0f, 0.0f, 0.0f); + m_vecMoveFriction = CVector(0.0f, 0.0f, 0.0f); + }else{ + + // This has to be done if ProcessEntityCollision wasn't called + if(!bVehicleColProcessed){ + CMatrix mat(GetMatrix()); + bIsStuck = false; + bHasContacted = false; + bIsInSafePosition = false; + bWasPostponed = false; + bHasHitWall = false; + m_fDistanceTravelled = 0.0f; + field_EF = false; + m_phy_flagA80 = false; + ApplyMoveSpeed(); + ApplyTurnSpeed(); + for(i = 0; CheckCollision() && i < 5; i++){ + GetMatrix() = mat; + ApplyMoveSpeed(); + ApplyTurnSpeed(); + } + bIsInSafePosition = true; + bIsStuck = false; + } + + CPhysical::ProcessControl(); + + ProcessBuoyancy(); + + // Rescale spring ratios, i.e. subtract wheel radius + for(i = 0; i < 4; i++){ + // wheel radius in relation to suspension line + float wheelRadius = 1.0f - m_aSuspensionSpringLength[i]/m_aSuspensionLineLength[i]; + // rescale such that 0.0 is fully compressed and 1.0 is fully extended + m_aSuspensionSpringRatio[i] = (m_aSuspensionSpringRatio[i]-wheelRadius)/(1.0f-wheelRadius); + } + + float fwdSpeed = DotProduct(m_vecMoveSpeed, GetForward()); + CVector contactPoints[4]; // relative to model + CVector contactSpeeds[4]; // speed at contact points + CVector springDirections[4]; // normalized, in model space + + for(i = 0; i < 4; i++){ + // Set spring under certain circumstances + if(Damage.GetWheelStatus(i) == WHEEL_STATUS_MISSING) + m_aSuspensionSpringRatio[i] = 1.0f; + else if(Damage.GetWheelStatus(i) == WHEEL_STATUS_BURST){ + // wheel more bumpy the faster we are + if(CGeneral::GetRandomNumberInRange(0, (uint16)(40*fwdSpeed) + 98) < 100){ + m_aSuspensionSpringRatio[i] += 0.3f*(m_aSuspensionLineLength[i]-m_aSuspensionSpringLength[i])/m_aSuspensionSpringLength[i]; + if(m_aSuspensionSpringRatio[i] > 1.0f) + m_aSuspensionSpringRatio[i] = 1.0f; + } + } + + // get points and directions if spring is compressed + if(m_aSuspensionSpringRatio[i] < 1.0f){ + contactPoints[i] = m_aWheelColPoints[i].point - GetPosition(); + springDirections[i] = Multiply3x3(GetMatrix(), colModel->lines[i].p1 - colModel->lines[i].p0); + springDirections[i].Normalise(); + } + } + + // Make springs push up vehicle + for(i = 0; i < 4; i++){ + if(m_aSuspensionSpringRatio[i] < 1.0f){ + float bias = m_handling->fSuspensionBias; + if(i == 1 || i == 3) // rear + bias = 1.0f - bias; + + ApplySpringCollision(m_handling->fSuspensionForceLevel, + springDirections[i], contactPoints[i], + m_aSuspensionSpringRatio[i], bias); + m_aWheelSkidmarkMuddy[i] = + m_aWheelColPoints[i].surfaceB == SURFACE_GRASS || + m_aWheelColPoints[i].surfaceB == SURFACE_DIRTTRACK || + m_aWheelColPoints[i].surfaceB == SURFACE_SAND; + }else{ + contactPoints[i] = Multiply3x3(GetMatrix(), colModel->lines[i].p1); + } + } + + // Get speed at contact points + for(i = 0; i < 4; i++){ + contactSpeeds[i] = GetSpeed(contactPoints[i]); + if(m_aGroundPhysical[i]){ + // subtract movement of physical we're standing on + contactSpeeds[i] -= m_aGroundPhysical[i]->GetSpeed(m_aGroundOffset[i]); +#ifndef FIX_BUGS + // this shouldn't be reset because we still need it below + m_aGroundPhysical[i] = nil; +#endif + } + } + + // dampen springs + for(i = 0; i < 4; i++) + if(m_aSuspensionSpringRatio[i] < 1.0f) + ApplySpringDampening(m_handling->fSuspensionDampingLevel, + springDirections[i], contactPoints[i], contactSpeeds[i]); + + // Get speed at contact points again + for(i = 0; i < 4; i++){ + contactSpeeds[i] = GetSpeed(contactPoints[i]); + if(m_aGroundPhysical[i]){ + // subtract movement of physical we're standing on + contactSpeeds[i] -= m_aGroundPhysical[i]->GetSpeed(m_aGroundOffset[i]); + m_aGroundPhysical[i] = nil; + } + } + + assert(0); + } + + assert(0 && "misc stuff"); +} void CAutomobile::Teleport(CVector pos) @@ -271,6 +534,11 @@ CAutomobile::ProcessControlInputs(uint8 pad) } } +WRAPPER void +CAutomobile::ProcessBuoyancy(void) +{ EAXJMP(0x5308D0); +} + void CAutomobile::GetComponentWorldPosition(int32 component, CVector &pos) { @@ -524,7 +792,7 @@ CAutomobile::BlowUpCar(CEntity *culprit) m_fHealth = 0.0f; m_nBombTimer = 0; - m_auto_flagA7 = 0; + m_bombType = 0; TheCamera.CamShake(0.7f, GetPosition().x, GetPosition().y, GetPosition().z); @@ -660,8 +928,8 @@ CAutomobile::PlayCarHorn(void) void CAutomobile::PlayHornIfNecessary(void) { - if(m_autoPilot.m_flag2 || - m_autoPilot.m_flag1) + if(AutoPilot.m_flag2 || + AutoPilot.m_flag1) if(!HasCarStoppedBecauseOfLight()) PlayCarHorn(); } @@ -761,20 +1029,20 @@ CAutomobile::HasCarStoppedBecauseOfLight(void) if(m_status != STATUS_SIMPLE && m_status != STATUS_PHYSICS) return false; - if(m_autoPilot.m_nCurrentRouteNode && m_autoPilot.m_nNextRouteNode){ - CPathNode *curnode = &ThePaths.m_pathNodes[m_autoPilot.m_nCurrentRouteNode]; + 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] == m_autoPilot.m_nNextRouteNode) + if(ThePaths.m_connections[curnode->firstLink + i] == AutoPilot.m_nNextRouteNode) break; if(i < curnode->numLinks && ThePaths.m_carPathLinks[ThePaths.m_carPathConnections[curnode->firstLink + i]].trafficLightType & 3) // TODO return true; } - if(m_autoPilot.m_nCurrentRouteNode && m_autoPilot.m_nPrevRouteNode){ - CPathNode *curnode = &ThePaths.m_pathNodes[m_autoPilot.m_nCurrentRouteNode]; + 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] == m_autoPilot.m_nPrevRouteNode) + if(ThePaths.m_connections[curnode->firstLink + i] == AutoPilot.m_nPrevRouteNode) break; if(i < curnode->numLinks && ThePaths.m_carPathLinks[ThePaths.m_carPathConnections[curnode->firstLink + i]].trafficLightType & 3) // TODO diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h index 60e08d0a..31042415 100644 --- a/src/vehicles/Automobile.h +++ b/src/vehicles/Automobile.h @@ -6,6 +6,12 @@ class CObject; +// Wheels are in order: +// FRONT LEFT +// REAR LEFT +// FRONT RIGHT +// REAR RIGHT + class CAutomobile : public CVehicle { public: @@ -24,13 +30,15 @@ public: float m_aWheelPosition[4]; float m_aWheelSpeed[4]; uint8 field_4D8; - uint8 m_auto_flagA7 : 1; + uint8 m_bombType : 3; uint8 bTaxiLight : 1; - uint8 m_auto_flagA10 : 1; + uint8 bHadDriver : 1; // for bombs uint8 m_auto_flagA20 : 1; uint8 m_auto_flagA40 : 1; uint8 m_auto_flagA80 : 1; - uint8 field_4DA[10]; + uint8 field_4DA[2]; + CEntity *field_4DC; // blow up entity + uint8 field_4E0[4]; uint32 m_nBusDoorTimerEnd; uint32 m_nBusDoorTimerStart; float m_aSuspensionSpringLength[4]; @@ -41,7 +49,7 @@ public: float field_530; CPhysical *m_aGroundPhysical[4]; // physicals touching wheels CVector m_aGroundOffset[4]; // from ground object to colpoint - CEntity *m_pBlowUpEntity; + CEntity *m_pSetOnFireEntity; float m_weaponThingA; // TODO float m_weaponThingB; // TODO float m_fCarGunLR; @@ -87,6 +95,7 @@ public: float GetHeightAboveRoad(void); void PlayCarHorn(void); + void ProcessBuoyancy(void); void PlayHornIfNecessary(void); void ResetSuspension(void); void SetupSuspensionLines(void); diff --git a/src/vehicles/DamageManager.h b/src/vehicles/DamageManager.h index b815f724..f2044ec2 100644 --- a/src/vehicles/DamageManager.h +++ b/src/vehicles/DamageManager.h @@ -23,7 +23,8 @@ enum ePanelStatus enum eWheelStatus { WHEEL_STATUS_OK, - WHEEL_STATUS_BURST + WHEEL_STATUS_BURST, + WHEEL_STATUS_MISSING }; enum tComponent diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp index 0abdffd2..2781f9f5 100644 --- a/src/vehicles/Vehicle.cpp +++ b/src/vehicles/Vehicle.cpp @@ -56,14 +56,14 @@ CVehicle::CVehicle(uint8 CreatedBy) for(i = 0; i < m_nNumMaxPassengers; i++) pPassengers[i] = nil; m_nBombTimer = 0; - m_pWhoSetMeOnFire = nil; + m_pBlowUpEntity = nil; field_1FB = 0; bComedyControls = false; m_veh_flagB40 = false; m_veh_flagB80 = false; m_veh_flagC1 = false; bIsDamaged = false; - m_veh_flagC8 = false; + bFadeOut = false; m_veh_flagC10 = false; bHasBeenOwnedByPlayer = false; m_veh_flagC20 = false; @@ -96,11 +96,11 @@ CVehicle::CVehicle(uint8 CreatedBy) m_comedyControlState = 0; m_aCollPolys[0].valid = false; m_aCollPolys[1].valid = false; - m_autoPilot.m_nCarMission = MISSION_NONE; - m_autoPilot.m_nAnimationId = TEMPACT_NONE; - m_autoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds(); - m_autoPilot.m_flag4 = false; - m_autoPilot.m_flag10 = false; + AutoPilot.m_nCarMission = MISSION_NONE; + AutoPilot.m_nAnimationId = TEMPACT_NONE; + AutoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds(); + AutoPilot.m_flag4 = false; + AutoPilot.m_flag10 = false; } CVehicle::~CVehicle() @@ -374,20 +374,18 @@ CVehicle::ProcessDelayedExplosion(void) if(m_nBombTimer == 0) return; - if(m_nBombTimer == 0){ - int tick = CTimer::GetTimeStep()/60.0f*1000.0f; - if(tick > m_nBombTimer) - m_nBombTimer = 0; - else - m_nBombTimer -= tick; + int tick = CTimer::GetTimeStep()/60.0f*1000.0f; + if(tick > m_nBombTimer) + m_nBombTimer = 0; + else + m_nBombTimer -= tick; - if(IsCar() && ((CAutomobile*)this)->m_auto_flagA7 == 4 && (m_nBombTimer & 0xFE00) != 0xFE00) - DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_BOMB_TICK, 0.0f); + if(IsCar() && ((CAutomobile*)this)->m_bombType == 4 && (m_nBombTimer & 0xFE00) != 0xFE00) + DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_BOMB_TICK, 0.0f); - if(FindPlayerVehicle() != this && m_pWhoSetMeOnFire == FindPlayerPed()) - CWorld::Players[CWorld::PlayerInFocus].AwardMoneyForExplosion(this); - BlowUpCar(m_pWhoSetMeOnFire); - } + if(FindPlayerVehicle() != this && m_pBlowUpEntity == FindPlayerPed()) + CWorld::Players[CWorld::PlayerInFocus].AwardMoneyForExplosion(this); + BlowUpCar(m_pBlowUpEntity); } bool diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h index 03bdad69..1f848dc8 100644 --- a/src/vehicles/Vehicle.h +++ b/src/vehicles/Vehicle.h @@ -126,7 +126,7 @@ class CVehicle : public CPhysical public: // 0x128 tHandlingData *m_handling; - CAutoPilot m_autoPilot; + CAutoPilot AutoPilot; uint8 m_currentColour1; uint8 m_currentColour2; uint8 m_aExtras[2]; @@ -162,14 +162,14 @@ public: uint8 bIsBig: 1; // Is this vehicle a bus uint8 bLowVehicle: 1; // Need this for sporty type cars to use low getting-in/out anims uint8 bComedyControls : 1; // Will make the car hard to control (hopefully in a funny way) - uint8 m_veh_flagB20 : 1; + uint8 bWarnedPeds : 1; // Has scan and warn peds of danger been processed? uint8 m_veh_flagB40 : 1; uint8 m_veh_flagB80 : 1; uint8 m_veh_flagC1 : 1; uint8 bIsDamaged : 1; // This vehicle has been damaged and is displaying all its components - uint8 bHasBeenOwnedByPlayer : 1; - uint8 m_veh_flagC8 : 1; + uint8 bHasBeenOwnedByPlayer : 1;// To work out whether stealing it is a crime + uint8 bFadeOut : 1; // Fade vehicle out uint8 m_veh_flagC10 : 1; uint8 m_veh_flagC20 : 1; uint8 bCanBeDamaged : 1; // Set to FALSE during cut scenes to avoid explosions @@ -196,7 +196,7 @@ public: uint32 m_nTimeOfDeath; int16 field_214; int16 m_nBombTimer; // goes down with each frame - CPed *m_pWhoSetMeOnFire; + CEntity *m_pBlowUpEntity; float field_21C; float field_220; eCarLock m_nDoorLock; -- cgit v1.2.3