diff options
Diffstat (limited to 'src/vehicles')
-rw-r--r-- | src/vehicles/Automobile.cpp | 36 | ||||
-rw-r--r-- | src/vehicles/Automobile.h | 6 | ||||
-rw-r--r-- | src/vehicles/Bike.h | 13 | ||||
-rw-r--r-- | src/vehicles/Boat.cpp | 24 | ||||
-rw-r--r-- | src/vehicles/Boat.h | 8 | ||||
-rw-r--r-- | src/vehicles/CarGen.cpp | 127 | ||||
-rw-r--r-- | src/vehicles/CarGen.h | 5 | ||||
-rw-r--r-- | src/vehicles/Cranes.cpp | 3 | ||||
-rw-r--r-- | src/vehicles/HandlingMgr.cpp | 86 | ||||
-rw-r--r-- | src/vehicles/HandlingMgr.h | 88 | ||||
-rw-r--r-- | src/vehicles/Heli.cpp | 18 | ||||
-rw-r--r-- | src/vehicles/Heli.h | 3 | ||||
-rw-r--r-- | src/vehicles/Plane.cpp | 2 | ||||
-rw-r--r-- | src/vehicles/Plane.h | 2 | ||||
-rw-r--r-- | src/vehicles/Train.cpp | 26 | ||||
-rw-r--r-- | src/vehicles/Train.h | 2 | ||||
-rw-r--r-- | src/vehicles/Vehicle.cpp | 156 | ||||
-rw-r--r-- | src/vehicles/Vehicle.h | 27 |
18 files changed, 405 insertions, 227 deletions
diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index 83fe44d5..6e88b997 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -195,7 +195,7 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy) CMatrix mat2(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_LF])); mat1.GetPosition() += CVector(mat2.GetPosition().x + 0.1f, 0.0f, mat2.GetPosition().z); mat1.UpdateRW(); - }else if(GetModelIndex() == MI_MIAMI_SPARROW || GetModelIndex() == MI_MIAMI_RCRAIDER){ + }else if(IsRealHeli()){ RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LF]), 0); RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_RF]), 0); RpAtomicSetFlags((RpAtomic*)GetFirstObject(m_aCarNodes[CAR_WHEEL_LB]), 0); @@ -229,10 +229,6 @@ CAutomobile::ProcessControl(void) 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; - // Improve grip of vehicles in certain cases bool strongGrip1 = false; bool strongGrip2 = false; @@ -496,8 +492,7 @@ CAutomobile::ProcessControl(void) TankControl(); BlowUpCarsInPath(); break; - case MI_YARDIE: - // beta also had esperanto here it seems + case MI_VOODOO: HydraulicControl(); break; default: @@ -679,9 +674,7 @@ CAutomobile::ProcessControl(void) acceleration /= m_fForceMultiplier; // unused - if(GetModelIndex() == MI_MIAMI_RCBARON || - GetModelIndex() == MI_MIAMI_RCRAIDER || - GetModelIndex() == MI_MIAMI_SPARROW) + if(GetModelIndex() == MI_RCBARON || IsRealHeli()) acceleration = 0.0f; brake = m_fBrakePedal * pHandling->fBrakeDeceleration * CTimer::GetTimeStep(); @@ -1007,7 +1000,7 @@ CAutomobile::ProcessControl(void) m_bSirenOrAlarm = !m_bSirenOrAlarm; }else m_nCarHornTimer = 0; - }else if(GetModelIndex() != MI_YARDIE && !CVehicle::bCheat3){ + }else if(GetModelIndex() != MI_VOODOO && !CVehicle::bCheat3){ if(Pads[0].GetHorn()) m_nCarHornTimer = 1; else @@ -1018,7 +1011,7 @@ CAutomobile::ProcessControl(void) // Flying if(GetStatus() != STATUS_PLAYER && GetStatus() != STATUS_PLAYER_REMOTE && GetStatus() != STATUS_PHYSICS){ - if(GetModelIndex() == MI_MIAMI_RCRAIDER || GetModelIndex() == MI_MIAMI_SPARROW) + if(GetModelIndex() == MI_RCRAIDER || GetModelIndex() == MI_SPARROW) m_aWheelSpeed[0] = Max(m_aWheelSpeed[0]-0.0005f, 0.0f); }else if((GetModelIndex() == MI_DODO || CVehicle::bAllDodosCheat) && m_vecMoveSpeed.Magnitude() > 0.0f && CTimer::GetTimeStep() > 0.0f){ @@ -1028,20 +1021,20 @@ CAutomobile::ProcessControl(void) else #endif FlyingControl(FLIGHT_MODEL_DODO); - }else if(GetModelIndex() == MI_MIAMI_RCBARON){ + }else if(GetModelIndex() == MI_RCBARON){ FlyingControl(FLIGHT_MODEL_RCPLANE); - }else if(GetModelIndex() == MI_MIAMI_RCRAIDER || GetModelIndex() == MI_MIAMI_SPARROW || bAllCarCheat){ + }else if(IsRealHeli() || bAllCarCheat){ #ifdef ALLCARSHELI_CHEAT if (bAllCarCheat) FlyingControl(FLIGHT_MODEL_HELI); else #endif { - if (CPad::GetPad(0)->GetCircleJustDown()) - m_aWheelSpeed[0] = Max(m_aWheelSpeed[0] - 0.03f, 0.0f); - if (m_aWheelSpeed[0] < 0.22f) - m_aWheelSpeed[0] += 0.0001f; - if (m_aWheelSpeed[0] > 0.15f) + // if (CPad::GetPad(0)->GetCircleJustDown()) + // m_aWheelSpeed[0] = Max(m_aWheelSpeed[0] - 0.03f, 0.0f); + // if (m_aWheelSpeed[0] < 0.22f) + // m_aWheelSpeed[0] += 0.0001f; + // if (m_aWheelSpeed[0] > 0.15f) FlyingControl(FLIGHT_MODEL_HELI); } } @@ -1600,7 +1593,8 @@ CAutomobile::PreRender(void) case MI_TAXI: case MI_CABBIE: - case MI_BORGNINE: + case MI_ZEBRA: + case MI_KAUFMAN: if(bTaxiLight){ CVector pos = GetPosition() + GetUp()*0.95f; CCoronas::RegisterCorona((uintptr)this + 21, @@ -3024,7 +3018,7 @@ CAutomobile::DoDriveByShootings(void) { CAnimBlendAssociation *anim; CWeapon *weapon = pDriver->GetWeapon(); - if(weapon->m_eWeaponType != WEAPONTYPE_UZI) + if(CWeaponInfo::GetWeaponInfo(weapon->m_eWeaponType)->m_nWeaponSlot != 5) return; weapon->Update(pDriver->m_audioEntityId); diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h index a3e8ac17..8c5c8f8e 100644 --- a/src/vehicles/Automobile.h +++ b/src/vehicles/Automobile.h @@ -36,7 +36,7 @@ enum eCarPositions CAR_POS_TAILLIGHTS, CAR_POS_FRONTSEAT, CAR_POS_BACKSEAT, - CAR_POS_EXHAUST = 9, + CAR_POS_EXHAUST }; // These are used for all the wheel arrays @@ -84,7 +84,6 @@ public: float m_aWheelPosition[4]; float m_aWheelSpeed[4]; uint8 field_4D8; - uint8 m_bombType : 3; uint8 bTaxiLight : 1; uint8 bHadDriver : 1; // for bombs uint8 bFixedColour : 1; @@ -92,7 +91,6 @@ public: uint8 bWaterTight : 1; // no damage for non-player peds uint8 bNotDamagedUpsideDown : 1; uint8 bMoreResistantToDamage : 1; - CEntity *m_pBombRigger; int16 field_4E0; uint16 m_hydraulicState; uint32 m_nBusDoorTimerEnd; @@ -197,8 +195,6 @@ public: static void SetAllTaxiLights(bool set); }; -VALIDATE_SIZE(CAutomobile, 0x5A8); - inline uint8 GetCarDoorFlag(int32 carnode) { switch (carnode) { case CAR_DOOR_LF: diff --git a/src/vehicles/Bike.h b/src/vehicles/Bike.h index 4e7e5a0e..85cd3213 100644 --- a/src/vehicles/Bike.h +++ b/src/vehicles/Bike.h @@ -1,7 +1,5 @@ #pragma once -// some miami bike leftovers - enum eBikeNodes { BIKE_NODE_NONE, BIKE_CHASSIS, @@ -12,4 +10,13 @@ enum eBikeNodes { BIKE_MUDGUARD, BIKE_HANDLEBARS, BIKE_NUM_NODES -};
\ No newline at end of file +}; + +enum eBikePositions +{ + BIKE_POS_HEADLIGHTS, + BIKE_POS_TAILLIGHTS, + BIKE_POS_FRONTSEAT, + BIKE_POS_BACKSEAT, + BIKE_POS_EXHAUST +}; diff --git a/src/vehicles/Boat.cpp b/src/vehicles/Boat.cpp index 72fca542..784d859f 100644 --- a/src/vehicles/Boat.cpp +++ b/src/vehicles/Boat.cpp @@ -3,6 +3,7 @@ #include "General.h" #include "Timecycle.h" #include "HandlingMgr.h" +#include "CarAI.h" #include "CarCtrl.h" #include "RwHelper.h" #include "ModelIndices.h" @@ -96,7 +97,7 @@ CBoat::CBoat(int mi, uint8 owner) : CVehicle(owner) void CBoat::SetModelIndex(uint32 id) { - CEntity::SetModelIndex(id); + CVehicle::SetModelIndex(id); SetupModelNodes(); } @@ -109,9 +110,6 @@ CBoat::GetComponentWorldPosition(int32 component, CVector &pos) void CBoat::ProcessControl(void) { - if(m_nZoneLevel > LEVEL_NONE && m_nZoneLevel != CCollision::ms_collisionInMemory) - return; - bool onLand = m_fDamageImpulse > 0.0f && m_vecDamageNormal.z > 0.1f; PruneWakeTrail(); @@ -155,6 +153,7 @@ CBoat::ProcessControl(void) case STATUS_SIMPLE: m_bIsAnchored = false; m_fOrientation = INVALID_ORIENTATION; + CCarAI::UpdateCarAI(this); CPhysical::ProcessControl(); bBoatInWater = true; bPropellerInWater = true; @@ -163,7 +162,8 @@ CBoat::ProcessControl(void) case STATUS_PHYSICS: m_bIsAnchored = false; m_fOrientation = INVALID_ORIENTATION; - CCarCtrl::SteerAIBoatWithPhysics(this); + CCarAI::UpdateCarAI(this); + CCarCtrl::SteerAICarWithPhysics(this); break; case STATUS_ABANDONED: case STATUS_WRECKED: @@ -295,8 +295,8 @@ CBoat::ProcessControl(void) AddWakePoint(GetPosition()); float steerFactor = 1.0f - DotProduct(m_vecMoveSpeed, GetForward()); - if (GetModelIndex() == MI_GHOST) - steerFactor = 1.0f - DotProduct(m_vecMoveSpeed, GetForward())*0.3f; +// if (GetModelIndex() == MI_GHOST) +// steerFactor = 1.0f - DotProduct(m_vecMoveSpeed, GetForward())*0.3f; if(steerFactor < 0.0f) steerFactor = 0.0f; CVector propeller(0.0f, -pHandling->Dimension.y*m_fPropellerY, -pHandling->Dimension.z*m_fPropellerZ); @@ -406,10 +406,10 @@ CBoat::ProcessControl(void) } // Slow down or push down boat as it approaches the world limits - m_vecMoveSpeed.x = Min(m_vecMoveSpeed.x, -(GetPosition().x - 1900.0f)*0.01f); // east - m_vecMoveSpeed.x = Max(m_vecMoveSpeed.x, -(GetPosition().x - -1515.0f)*0.01f); // west - m_vecMoveSpeed.y = Min(m_vecMoveSpeed.y, -(GetPosition().y - 600.0f)*0.01f); // north - m_vecMoveSpeed.y = Max(m_vecMoveSpeed.y, -(GetPosition().y - -1900.0f)*0.01f); // south + m_vecMoveSpeed.x = Min(m_vecMoveSpeed.x, -(GetPosition().x - (WORLD_MAX_X-100.0f))*0.01f); // east + m_vecMoveSpeed.x = Max(m_vecMoveSpeed.x, -(GetPosition().x - (WORLD_MIN_X+100.0f))*0.01f); // west + m_vecMoveSpeed.y = Min(m_vecMoveSpeed.y, -(GetPosition().y - (WORLD_MAX_Y-100.0f))*0.01f); // north + m_vecMoveSpeed.y = Max(m_vecMoveSpeed.y, -(GetPosition().y - (WORLD_MIN_Y+100.0f))*0.01f); // south if(!onLand && bBoatInWater) ApplyWaterResistance(); @@ -439,7 +439,7 @@ CBoat::ProcessControl(void) speedUp = pHandling->fBrakeDeceleration - m_vecMoveSpeed.z; if(speedUp < 0.0f) speedUp = 0.0f; float speedFwd = DotProduct(m_vecMoveSpeed, GetForward()); - speedFwd *= -m_nDeltaVolumeUnderWater * 0.01f * pHandling->fTractionLoss; + speedFwd *= -m_nDeltaVolumeUnderWater * 0.01f * pHandling->fBrakeBias; CVector speed = speedFwd*GetForward() + CVector(0.0f, 0.0f, speedUp); CVector splashImpulse = speed * m_fMass; ApplyMoveForce(splashImpulse); diff --git a/src/vehicles/Boat.h b/src/vehicles/Boat.h index 3cc3513d..7a0a9be4 100644 --- a/src/vehicles/Boat.h +++ b/src/vehicles/Boat.h @@ -5,8 +5,12 @@ enum eBoatNodes { BOAT_MOVING = 1, + BOAT_WINDSCREEN, BOAT_RUDDER, - BOAT_WINDSCREEN + BOAT_FLAP_LEFT, + BOAT_FLAP_RIGHT, + BOAT_REARFLAP_LEFT, + BOAT_REARFLAP_RIGHT }; class CBoat : public CVehicle @@ -72,8 +76,6 @@ public: }; -VALIDATE_SIZE(CBoat, 0x484); - extern float MAX_WAKE_LENGTH; extern float MIN_WAKE_INTERVAL; extern float WAKE_LIFETIME;
\ No newline at end of file diff --git a/src/vehicles/CarGen.cpp b/src/vehicles/CarGen.cpp index 72b6c30c..16401008 100644 --- a/src/vehicles/CarGen.cpp +++ b/src/vehicles/CarGen.cpp @@ -12,7 +12,9 @@ #include "Streaming.h" #include "Timer.h" #include "Vehicle.h" +#include "VisibilityPlugins.h" #include "World.h" +#include "Zones.h" uint8 CTheCarGenerators::ProcessCounter; uint32 CTheCarGenerators::NumOfCarGenerators; @@ -38,21 +40,43 @@ uint32 CCarGenerator::CalcNextGen() return CTimer::GetTimeInMilliseconds() + 4; } +//TODO(MIAMI): check for more changes - so far only -1 mi is accounted for void CCarGenerator::DoInternalProcessing() { - if (CheckForBlockage()) { - m_nTimer += 4; - if (m_nUsesRemaining == 0) - --CTheCarGenerators::CurrentActiveCount; - return; - } + int mi; if (CCarCtrl::NumParkedCars >= 10) return; - CStreaming::RequestModel(m_nModelIndex, STREAMFLAGS_DEPENDENCY); - if (!CStreaming::HasModelLoaded(m_nModelIndex)) + if (m_nModelIndex >= 0) { + if (CheckForBlockage(m_nModelIndex)) { + m_nTimer += 4; + return; + } + mi = m_nModelIndex; + } + else { + mi = -m_nModelIndex; + if (m_nModelIndex == -1 || !CStreaming::HasModelLoaded(mi)) { + CZoneInfo pZone; + CTheZones::GetZoneInfoForTimeOfDay(&FindPlayerCoors(), &pZone); + mi = CCarCtrl::ChooseCarModel(CCarCtrl::ChooseCarRating(&pZone)); + if (mi < 0) + return; + m_nModelIndex = -mi; + m_nColor1 = -1; + m_nColor2 = -1; + } + if (CheckForBlockage(mi)) { + m_nTimer += 4; + return; + } + } + CStreaming::RequestModel(mi, STREAMFLAGS_DEPENDENCY); + if (!CStreaming::HasModelLoaded(mi)) return; - if (CModelInfo::IsBoatModel(m_nModelIndex)){ - CBoat* pBoat = new CBoat(m_nModelIndex, PARKED_VEHICLE); + CVehicle* pVehicle; + if (CModelInfo::IsBoatModel(mi)){ + CBoat* pBoat = new CBoat(mi, PARKED_VEHICLE); + pVehicle = pBoat; pBoat->bIsStatic = false; pBoat->bEngineOn = false; CVector pos = m_vecPos; @@ -63,17 +87,7 @@ void CCarGenerator::DoInternalProcessing() pBoat->SetOrientation(0.0f, 0.0f, DEGTORAD(m_fAngle)); pBoat->SetStatus(STATUS_ABANDONED); pBoat->m_nDoorLock = CARLOCK_UNLOCKED; - CWorld::Add(pBoat); - if (CGeneral::GetRandomNumberInRange(0, 100) < m_nAlarm) - pBoat->m_nAlarmState = -1; - if (CGeneral::GetRandomNumberInRange(0, 100) < m_nDoorlock) - pBoat->m_nDoorLock = CARLOCK_LOCKED; - if (m_nColor1 != -1 && m_nColor2){ - pBoat->m_currentColour1 = m_nColor1; - pBoat->m_currentColour2 = m_nColor2; - } - m_nVehicleHandle = CPools::GetVehiclePool()->GetIndex(pBoat); - }else{ + }else{ // TODO(MIAMI): bikes bool groundFound = false; CVector pos = m_vecPos; if (pos.z > -100.0f){ @@ -88,28 +102,35 @@ void CCarGenerator::DoInternalProcessing() } if (!groundFound) { debug("CCarGenerator::DoInternalProcessing - can't find ground z for new car x = %f y = %f \n", m_vecPos.x, m_vecPos.y); - }else{ - CAutomobile* pCar = new CAutomobile(m_nModelIndex, PARKED_VEHICLE); - pCar->bIsStatic = false; - pCar->bEngineOn = false; - pos.z += pCar->GetDistanceFromCentreOfMassToBaseOfModel(); - pCar->SetPosition(pos); - pCar->SetOrientation(0.0f, 0.0f, DEGTORAD(m_fAngle)); - pCar->SetStatus(STATUS_ABANDONED); - pCar->bLightsOn = false; - pCar->m_nDoorLock = CARLOCK_UNLOCKED; - CWorld::Add(pCar); - if (CGeneral::GetRandomNumberInRange(0, 100) < m_nAlarm) - pCar->m_nAlarmState = -1; - if (CGeneral::GetRandomNumberInRange(0, 100) < m_nDoorlock) - pCar->m_nDoorLock = CARLOCK_LOCKED; - if (m_nColor1 != -1 && m_nColor2) { - pCar->m_currentColour1 = m_nColor1; - pCar->m_currentColour2 = m_nColor2; - } - m_nVehicleHandle = CPools::GetVehiclePool()->GetIndex(pCar); + return; } + CAutomobile* pCar = new CAutomobile(mi, PARKED_VEHICLE); + pVehicle = pCar; + pCar->bIsStatic = false; + pCar->bEngineOn = false; + pos.z += pCar->GetDistanceFromCentreOfMassToBaseOfModel(); + pCar->SetPosition(pos); + pCar->SetOrientation(0.0f, 0.0f, DEGTORAD(m_fAngle)); + pCar->SetStatus(STATUS_ABANDONED); + pCar->bLightsOn = false; + pCar->m_nDoorLock = CARLOCK_UNLOCKED; + + } + CWorld::Add(pVehicle); + if (CGeneral::GetRandomNumberInRange(0, 100) < m_nAlarm) + pVehicle->m_nAlarmState = -1; + if (CGeneral::GetRandomNumberInRange(0, 100) < m_nDoorlock) + pVehicle->m_nDoorLock = CARLOCK_LOCKED; + if (m_nColor1 != -1 && m_nColor2 != -1) { + pVehicle->m_currentColour1 = m_nColor1; + pVehicle->m_currentColour2 = m_nColor2; } + else if (m_nModelIndex < -1) { + m_nColor1 = pVehicle->m_currentColour1; + m_nColor2 = pVehicle->m_currentColour2; + } + CVisibilityPlugins::SetClumpAlpha(pVehicle->GetClump(), 0); + m_nVehicleHandle = CPools::GetVehiclePool()->GetIndex(pVehicle); if (m_nUsesRemaining < -1) /* I don't think this is a correct comparasion */ --m_nUsesRemaining; m_nTimer = CalcNextGen(); @@ -155,25 +176,33 @@ void CCarGenerator::Setup(float x, float y, float z, float angle, int32 mi, int1 m_nTimer = CTimer::GetTimeInMilliseconds() + 1; m_nUsesRemaining = 0; m_bIsBlocking = false; - m_vecInf = CModelInfo::GetModelInfo(m_nModelIndex)->GetColModel()->boundingBox.min; - m_vecSup = CModelInfo::GetModelInfo(m_nModelIndex)->GetColModel()->boundingBox.max; - m_fSize = Max(m_vecInf.Magnitude(), m_vecSup.Magnitude()); } -bool CCarGenerator::CheckForBlockage() +bool CCarGenerator::CheckForBlockage(int32 mi) { int16 entities; - CWorld::FindObjectsKindaColliding(CVector(m_vecPos), m_fSize, 1, &entities, 2, nil, false, true, true, false, false); - return entities > 0; + CEntity* pEntities[8]; + CColModel* pColModel = CModelInfo::GetModelInfo(mi)->GetColModel(); + CWorld::FindObjectsKindaColliding(CVector(m_vecPos), pColModel->boundingSphere.radius, 1, &entities, 8, pEntities, false, true, true, false, false); + for (int i = 0; i < entities; i++) { + if (m_vecPos.z + pColModel->boundingBox.min.z < pEntities[i]->GetPosition().z + pEntities[i]->GetColModel()->boundingBox.max.z + 1.0f && + m_vecPos.z + pColModel->boundingBox.max.z < pEntities[i]->GetPosition().z + pEntities[i]->GetColModel()->boundingBox.min.z - 1.0f) { + m_bIsBlocking = true; + return true; + } + } + return false; } bool CCarGenerator::CheckIfWithinRangeOfAnyPlayer() { CVector2D direction = FindPlayerCentreOfWorld(CWorld::PlayerInFocus) - m_vecPos; float distance = direction.Magnitude(); - float farclip = 120.0f * TheCamera.GenerationDistMultiplier; + float farclip = 110.0f * TheCamera.GenerationDistMultiplier; float nearclip = farclip - 20.0f; - if (distance >= farclip){ + bool canBeRemoved = (m_nModelIndex > 0 && CModelInfo::IsBoatModel(m_nModelIndex) && 165.0f * TheCamera.GenerationDistMultiplier > distance && + TheCamera.IsPointVisible(m_vecPos, &TheCamera.GetCameraMatrix())); // TODO(MIAMI) COcclision::IsPositionOccluded(m_vecPos, 0.0f) + if (distance >= farclip || canBeRemoved){ if (m_bIsBlocking) m_bIsBlocking = false; return false; diff --git a/src/vehicles/CarGen.h b/src/vehicles/CarGen.h index 9d645318..684f93ee 100644 --- a/src/vehicles/CarGen.h +++ b/src/vehicles/CarGen.h @@ -22,9 +22,6 @@ class CCarGenerator int32 m_nVehicleHandle; uint16 m_nUsesRemaining; bool m_bIsBlocking; - CVector m_vecInf; - CVector m_vecSup; - float m_fSize; public: void SwitchOff(); void SwitchOn(); @@ -32,7 +29,7 @@ public: void DoInternalProcessing(); void Process(); void Setup(float x, float y, float z, float angle, int32 mi, int16 color1, int16 color2, uint8 force, uint8 alarm, uint8 lock, uint16 min_delay, uint16 max_delay); - bool CheckForBlockage(); + bool CheckForBlockage(int32 mi); bool CheckIfWithinRangeOfAnyPlayer(); void SetUsesRemaining(uint16 uses) { m_nUsesRemaining = uses; } }; diff --git a/src/vehicles/Cranes.cpp b/src/vehicles/Cranes.cpp index 9c8f9fda..043f1c73 100644 --- a/src/vehicles/Cranes.cpp +++ b/src/vehicles/Cranes.cpp @@ -57,7 +57,8 @@ void CCranes::InitCranes(void) } } } - for (CPtrNode* pNode = CWorld::GetBigBuildingList(LEVEL_INDUSTRIAL).first; pNode; pNode = pNode->next) { + // TODO(MIAMI): LEVEL_MAINLAND just so it compiles + for (CPtrNode* pNode = CWorld::GetBigBuildingList(LEVEL_MAINLAND).first; pNode; pNode = pNode->next) { CEntity* pEntity = (CEntity*)pNode->item; if (MODELID_CRANE_1 == pEntity->GetModelIndex() || MODELID_CRANE_2 == pEntity->GetModelIndex() || diff --git a/src/vehicles/HandlingMgr.cpp b/src/vehicles/HandlingMgr.cpp index 3ac0da38..cc6428e1 100644 --- a/src/vehicles/HandlingMgr.cpp +++ b/src/vehicles/HandlingMgr.cpp @@ -21,7 +21,6 @@ const char VehicleNames[NUMHANDLINGS][14] = { "STRETCH", "MANANA", "INFERNUS", - "BLISTA", "PONY", "MULE", "CHEETAH", @@ -38,7 +37,6 @@ const char VehicleNames[NUMHANDLINGS][14] = { "ENFORCER", "SECURICA", "BANSHEE", - "PREDATOR", "BUS", "RHINO", "BARRACKS", @@ -50,22 +48,73 @@ const char VehicleNames[NUMHANDLINGS][14] = { "STALLION", "RUMPO", "RCBANDIT", - "BELLYUP", - "MRWONGS", "MAFIA", - "YARDIE", - "YAKUZA", - "DIABLOS", - "COLUMB", - "HOODS", "AIRTRAIN", "DEADDODO", - "SPEEDER", - "REEFER", - "PANLANT", "FLATBED", "YANKEE", - "BORGNINE" + "GOLFCART", + "VOODOO", + "WASHING", + "CUBAN", + "ROMERO", + "PACKER", + "ADMIRAL", + "GANGBUR", + "ZEBRA", + "TOPFUN", + "GLENDALE", + "OCEANIC", + "HERMES", + "SABRE1", + "SABRETUR", + "PHEONIX", + "WALTON", + "REGINA", + "COMET", + "DELUXO", + "BURRITO", + "SPAND", + "BAGGAGE", + "KAUFMAN", + "RANCHER", + "FBIRANCH", + "VIRGO", + "GREENWOO", + "HOTRING", + "SANDKING", + "BLISTAC", + "BOXVILLE", + "BENSON", + "DESPERAD", + "LOVEFIST", + "BLOODRA", + "BLOODRB", + "BIKE", + "MOPED", + "DIRTBIKE", + "ANGEL", + "FREEWAY", + "PREDATOR", + "SPEEDER", + "REEFER", + "RIO", + "SQUALO", + "TROPIC", + "COASTGRD", + "DINGHY", + "MARQUIS", + "CUPBOAT", + "SEAPLANE", + "SPARROW", + "SEASPAR", + "MAVERICK", + "COASTMAV", + "POLMAV", + "HUNTER", + "RCBARON", + "RCGOBLIN", + "RCCOPTER" }; cHandlingDataMgr::cHandlingDataMgr(void) @@ -117,7 +166,9 @@ cHandlingDataMgr::LoadHandlingData(void) // yeah, this is kinda crappy if(strncmp(line, ";the end", 9) == 0) keepGoing = 0; - else if(line[0] != ';'){ +// else if(line[0] != ';'){ +// TODO(MIAMI): read boat, bike, flying values + else if(line[0] != ';' && line[0] != '%' && line[0] != '!' && line[0] != '$'){ field = 0; strcpy(delim, " \t"); // FIX: game seems to use a do-while loop here @@ -158,11 +209,14 @@ cHandlingDataMgr::LoadHandlingData(void) case 27: handling->fSuspensionLowerLimit = strtod(word, nil); break; case 28: handling->fSuspensionBias = strtod(word, nil); break; case 29: + // TODO(MIAMI): suspension anti-dive multiplier + break; + case 30: sscanf(word, "%x", &handling->Flags); handling->Transmission.Flags = handling->Flags; break; - case 30: handling->FrontLights = atoi(word); break; - case 31: handling->RearLights = atoi(word); break; + case 31: handling->FrontLights = atoi(word); break; + case 32: handling->RearLights = atoi(word); break; } field++; } diff --git a/src/vehicles/HandlingMgr.h b/src/vehicles/HandlingMgr.h index 398a415f..e629d885 100644 --- a/src/vehicles/HandlingMgr.h +++ b/src/vehicles/HandlingMgr.h @@ -16,7 +16,6 @@ enum eHandlingId HANDLING_STRETCH, HANDLING_MANANA, HANDLING_INFERNUS, - HANDLING_BLISTA, HANDLING_PONY, HANDLING_MULE, HANDLING_CHEETAH, @@ -33,7 +32,6 @@ enum eHandlingId HANDLING_ENFORCER, HANDLING_SECURICA, HANDLING_BANSHEE, - HANDLING_PREDATOR, HANDLING_BUS, HANDLING_RHINO, HANDLING_BARRACKS, @@ -45,22 +43,73 @@ enum eHandlingId HANDLING_STALLION, HANDLING_RUMPO, HANDLING_RCBANDIT, - HANDLING_BELLYUP, - HANDLING_MRWONGS, HANDLING_MAFIA, - HANDLING_YARDIE, - HANDLING_YAKUZA, - HANDLING_DIABLOS, - HANDLING_COLUMB, - HANDLING_HOODS, HANDLING_AIRTRAIN, HANDLING_DEADDODO, - HANDLING_SPEEDER, - HANDLING_REEFER, - HANDLING_PANLANT, HANDLING_FLATBED, HANDLING_YANKEE, - HANDLING_BORGNINE + HANDLING_GOLFCART, + HANDLING_VOODOO, + HANDLING_WASHING, + HANDLING_CUBAN, + HANDLING_ROMERO, + HANDLING_PACKER, + HANDLING_ADMIRAL, + HANDLING_GANGBUR, + HANDLING_ZEBRA, + HANDLING_TOPFUN, + HANDLING_GLENDALE, + HANDLING_OCEANIC, + HANDLING_HERMES, + HANDLING_SABRE1, + HANDLING_SABRETUR, + HANDLING_PHEONIX, + HANDLING_WALTON, + HANDLING_REGINA, + HANDLING_COMET, + HANDLING_DELUXO, + HANDLING_BURRITO, + HANDLING_SPAND, + HANDLING_BAGGAGE, + HANDLING_KAUFMAN, + HANDLING_RANCHER, + HANDLING_FBIRANCH, + HANDLING_VIRGO, + HANDLING_GREENWOO, + HANDLING_HOTRING, + HANDLING_SANDKING, + HANDLING_BLISTAC, + HANDLING_BOXVILLE, + HANDLING_BENSON, + HANDLING_DESPERAD, + HANDLING_LOVEFIST, + HANDLING_BLOODRA, + HANDLING_BLOODRB, + HANDLING_BIKE, + HANDLING_MOPED, + HANDLING_DIRTBIKE, + HANDLING_ANGEL, + HANDLING_FREEWAY, + HANDLING_PREDATOR, + HANDLING_SPEEDER, + HANDLING_REEFER, + HANDLING_RIO, + HANDLING_SQUALO, + HANDLING_TROPIC, + HANDLING_COASTGRD, + HANDLING_DINGHY, + HANDLING_MARQUIS, + HANDLING_CUPBOAT, + HANDLING_SEAPLANE, + HANDLING_SPARROW, + HANDLING_SEASPAR, + HANDLING_MAVERICK, + HANDLING_COASTMAV, + HANDLING_POLMAV, + HANDLING_HUNTER, + HANDLING_RCBARON, + HANDLING_RCGOBLIN, + HANDLING_RCCOPTER }; enum @@ -81,6 +130,18 @@ enum HANDLING_HAS_NO_ROOF = 0x2000, HANDLING_IS_BIG = 0x4000, HANDLING_HALOGEN_LIGHTS = 0x8000, + HANDLING_IS_BIKE = 0x10000, + HANDLING_IS_HELI = 0x20000, + HANDLING_IS_PLANE = 0x40000, + HANDLING_IS_BOAT = 0x80000, + HANDLING_NO_EXHAUST = 0x100000, + HANDLING_REARWHEEL_1ST = 0x200000, + HANDLING_HANDBRAKE_TYRE = 0x400000, + HANDLING_SIT_IN_BOAT = 0x800000, + HANDLING_FAT_REARW = 0x1000000, + HANDLING_NARROW_FRONTW = 0x2000000, + HANDLING_GOOD_INSAND = 0x4000000, + HANDLING_UNKNOWN = 0x8000000, // something for helis and planes }; struct tHandlingData @@ -139,5 +200,4 @@ public: bool HasRearWheelDrive(eHandlingId id) { return HandlingData[id].Transmission.nDriveType == 'R'; } bool HasFrontWheelDrive(eHandlingId id) { return HandlingData[id].Transmission.nDriveType == 'F'; } }; -VALIDATE_SIZE(cHandlingDataMgr, 0x3030); extern cHandlingDataMgr mod_HandlingManager; diff --git a/src/vehicles/Heli.cpp b/src/vehicles/Heli.cpp index 7b62b461..5cd6488a 100644 --- a/src/vehicles/Heli.cpp +++ b/src/vehicles/Heli.cpp @@ -776,7 +776,6 @@ CHeli::InitHelis(void) for(i = 0; i < NUM_HELIS; i++) pHelis[i] = nil; - ((CVehicleModelInfo*)CModelInfo::GetModelInfo(MI_ESCAPE))->SetColModel(&CTempColModels::ms_colModelPed1); ((CVehicleModelInfo*)CModelInfo::GetModelInfo(MI_CHOPPER))->SetColModel(&CTempColModels::ms_colModelPed1); } @@ -787,10 +786,7 @@ GenerateHeli(bool catalina) CVector heliPos; int i; - if(catalina) - heli = new CHeli(MI_ESCAPE, PERMANENT_VEHICLE); - else - heli = new CHeli(MI_CHOPPER, PERMANENT_VEHICLE); + heli = new CHeli(MI_CHOPPER, PERMANENT_VEHICLE); if(catalina) heliPos = CVector(-224.0f, 201.0f, 83.0f); @@ -867,18 +863,6 @@ CHeli::UpdateHelis(void) pHelis[HELI_SCRIPT]->m_heliStatus = HELI_STATUS_FLY_AWAY; } - // Handle Catalina's heli - if(CatalinaHeliOn){ - if(CStreaming::HasModelLoaded(MI_ESCAPE) && pHelis[HELI_CATALINA] == nil){ - pHelis[HELI_CATALINA] = GenerateHeli(true); - pHelis[HELI_CATALINA]->m_heliType = HELI_TYPE_CATALINA; - }else - CStreaming::RequestModel(MI_ESCAPE, STREAMFLAGS_DONT_REMOVE); - }else{ - if(pHelis[HELI_CATALINA]) - pHelis[HELI_CATALINA]->m_heliStatus = HELI_STATUS_FLY_AWAY; - } - // Delete helis that we no longer need for(i = 0; i < NUM_HELIS; i++) if(pHelis[i] && pHelis[i]->m_heliStatus == HELI_STATUS_FLY_AWAY && pHelis[i]->GetPosition().z > 150.0f){ diff --git a/src/vehicles/Heli.h b/src/vehicles/Heli.h index cf3f791f..a8f604aa 100644 --- a/src/vehicles/Heli.h +++ b/src/vehicles/Heli.h @@ -95,6 +95,3 @@ public: static void ActivateHeli(bool activate); }; - -VALIDATE_SIZE(CHeli, 0x33C); - diff --git a/src/vehicles/Plane.cpp b/src/vehicles/Plane.cpp index 71189d84..39069364 100644 --- a/src/vehicles/Plane.cpp +++ b/src/vehicles/Plane.cpp @@ -806,7 +806,7 @@ CPlane::LoadPath(char const *filename, int32 &numNodes, float &totalLength, bool for(i = 0; i < numNodes; i++){ *gString = '\0'; - for(lp = 0; work_buff[bp] != '\n'; bp++, lp++) + for(lp = 0; work_buff[bp] != '\n' && work_buff[bp] != '\0'; bp++, lp++) gString[lp] = work_buff[bp]; bp++; // BUG: game doesn't terminate string diff --git a/src/vehicles/Plane.h b/src/vehicles/Plane.h index a6f6e1d9..a9afa4bc 100644 --- a/src/vehicles/Plane.h +++ b/src/vehicles/Plane.h @@ -71,8 +71,6 @@ public: static bool HasDropOffCesnaBeenShotDown(void); }; -VALIDATE_SIZE(CPlane, 0x29C); - extern float LandingPoint; extern float TakeOffPoint; extern float PlanePathPosition[3]; diff --git a/src/vehicles/Train.cpp b/src/vehicles/Train.cpp index 1d47ca3a..5dab70c5 100644 --- a/src/vehicles/Train.cpp +++ b/src/vehicles/Train.cpp @@ -38,6 +38,7 @@ CVector CTrain::aStationCoors_S[4]; CTrain::CTrain(int32 id, uint8 CreatedBy) : CVehicle(CreatedBy) { +#ifdef GTA_TRAIN CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(id); m_vehType = VEHICLE_TYPE_TRAIN; pHandling = mod_HandlingManager.GetHandlingData((eHandlingId)mi->m_handlingId); @@ -60,22 +61,28 @@ CTrain::CTrain(int32 id, uint8 CreatedBy) bUsesCollision = true; SetStatus(STATUS_TRAIN_MOVING); +#else + assert(0 && "No trains in this game"); +#endif } void CTrain::SetModelIndex(uint32 id) { +#ifdef GTA_TRAIN int i; CVehicle::SetModelIndex(id); for(i = 0; i < NUM_TRAIN_NODES; i++) m_aTrainNodes[i] = nil; CClumpModelInfo::FillFrameArray(GetClump(), m_aTrainNodes); +#endif } void CTrain::ProcessControl(void) { +#ifdef GTA_TRAIN if(gbModelViewer || m_isFarAway && (CTimer::GetFrameCounter() + m_nWagonId) & 0xF) return; @@ -278,11 +285,13 @@ CTrain::ProcessControl(void) TrainHitStuff(s->m_lists[ENTITYLIST_PEDS_OVERLAP]); } } +#endif GTA_TRAIN } void CTrain::PreRender(void) { +#ifdef GTA_TRAIN CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()); if(m_bIsFirstWagon){ @@ -342,17 +351,21 @@ CTrain::PreRender(void) CCoronas::TYPE_NORMAL, CCoronas::FLARE_NONE, CCoronas::REFLECTION_ON, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_ON, 0.0f); } +#endif } void CTrain::Render(void) { +#ifdef GTA_TRAIN CEntity::Render(); +#endif } void CTrain::TrainHitStuff(CPtrList &list) { +#ifdef GTA_TRAIN CPtrNode *node; CPhysical *phys; @@ -361,11 +374,13 @@ CTrain::TrainHitStuff(CPtrList &list) if(phys != this && Abs(this->GetPosition().z - phys->GetPosition().z) < 1.5f) phys->bHitByTrain = true; } +#endif } void CTrain::AddPassenger(CPed *ped) { +#ifdef GTA_TRAIN int i = ped->m_vehEnterType; if((i == TRAIN_POS_LEFT_ENTRY || i == TRAIN_POS_MID_ENTRY || i == TRAIN_POS_RIGHT_ENTRY) && pPassengers[i] == nil){ pPassengers[i] = ped; @@ -378,11 +393,13 @@ CTrain::AddPassenger(CPed *ped) return; } } +#endif } void CTrain::OpenTrainDoor(float ratio) { +#ifdef GTA_TRAIN if(m_rwObject == nil) return; @@ -407,6 +424,7 @@ CTrain::OpenTrainDoor(float ratio) doorL.UpdateRW(); doorR.UpdateRW(); +#endif } @@ -414,6 +432,7 @@ CTrain::OpenTrainDoor(float ratio) void CTrain::InitTrains(void) { +#ifdef GTA_TRAIN int i, j; CTrain *train; @@ -480,21 +499,25 @@ CTrain::InitTrains(void) for(j = 0; pTrackNodes_S[j].t < StationDist_S[i]; j++); aStationCoors_S[i] = pTrackNodes_S[j].p; } +#endif } void CTrain::Shutdown(void) { +#ifdef GTA_TRAIN delete[] pTrackNodes; delete[] pTrackNodes_S; pTrackNodes = nil; pTrackNodes_S = nil; +#endif } void CTrain::ReadAndInterpretTrackFile(Const char *filename, CTrainNode **nodes, int16 *numNodes, int32 numStations, float *stationDists, float *totalLength, float *totalDuration, CTrainInterpolationLine *interpLines, bool rightRail) { +#ifdef GTA_TRAIN bool readingFile = false; int bp, lp; int i, tmp; @@ -616,6 +639,7 @@ CTrain::ReadAndInterpretTrackFile(Const char *filename, CTrainNode **nodes, int1 // end interpLines[j].time = *totalDuration; +#endif } void @@ -627,6 +651,7 @@ ProcessTrainAnnouncements(void) void CTrain::UpdateTrains(void) { +#ifdef GTA_TRAIN int i, j; uint32 time; float t, deltaT; @@ -690,4 +715,5 @@ CTrain::UpdateTrains(void) // time offset for each train time += 0x40000/4; } +#endif } diff --git a/src/vehicles/Train.h b/src/vehicles/Train.h index c645ecaf..d8ee949d 100644 --- a/src/vehicles/Train.h +++ b/src/vehicles/Train.h @@ -91,5 +91,3 @@ public: float *totalLength, float *totalDuration, CTrainInterpolationLine *interpLines, bool rightRail); static void UpdateTrains(void); }; - -VALIDATE_SIZE(CTrain, 0x2E4); diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp index 5dc7bc72..4149fe6c 100644 --- a/src/vehicles/Vehicle.cpp +++ b/src/vehicles/Vehicle.cpp @@ -18,6 +18,7 @@ #include "Radar.h" #include "Fire.h" #include "Darkel.h" +#include "Streaming.h" bool CVehicle::bWheelsOnlyCheat; bool CVehicle::bAllDodosCheat; @@ -55,6 +56,7 @@ CVehicle::CVehicle(uint8 CreatedBy) m_fSteerRatio = 0.0f; m_type = ENTITY_TYPE_VEHICLE; VehicleCreatedBy = CreatedBy; + m_nRouteSeed = 0; bIsLocked = false; bIsLawEnforcer = false; bIsAmbulanceOnDuty = false; @@ -99,6 +101,9 @@ CVehicle::CVehicle(uint8 CreatedBy) m_bSirenOrAlarm = 0; m_nCarHornTimer = 0; m_nCarHornPattern = 0; + bPartOfConvoy = false; + bCreatedAsPoliceVehicle = false; + bParking = false; m_nAlarmState = 0; m_nDoorLock = CARLOCK_UNLOCKED; m_nLastWeaponDamage = -1; @@ -118,6 +123,7 @@ CVehicle::CVehicle(uint8 CreatedBy) AutoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds(); AutoPilot.m_bStayInCurrentLevel = false; AutoPilot.m_bIgnorePathfinding = false; + AutoPilot.m_nSwitchDistance = 20; } CVehicle::~CVehicle() @@ -383,7 +389,7 @@ CVehicle::FlyingControl(eFlightModel flightModel) case FLIGHT_MODEL_HELI: { CVector vecMoveResistance; - if (GetModelIndex() == MI_MIAMI_SPARROW) + if (GetModelIndex() == MI_SPARROW) vecMoveResistance = vecHeliMoveRes; else vecMoveResistance = vecRCHeliMoveRes; @@ -418,23 +424,22 @@ CVehicle::FlyingControl(eFlightModel flightModel) } else { fPitch = CPad::GetPad(0)->GetSteeringUpDown() / 128.0f; - fRoll = CPad::GetPad(0)->GetLookLeft(); - if (CPad::GetPad(0)->GetLookRight()) - fRoll = -1.0f; - fYaw = CPad::GetPad(0)->GetSteeringLeftRight() / 128.0f; + fYaw = CPad::GetPad(0)->GetLookRight(); + if (CPad::GetPad(0)->GetLookLeft()) + fYaw = -1.0f; + fRoll = -CPad::GetPad(0)->GetSteeringLeftRight() / 128.0f; } if (CPad::GetPad(0)->GetHorn()) { fYaw = 0.0f; fPitch = clamp(10.0f * DotProduct(m_vecMoveSpeed, GetUp()), -200.0f, 1.3f); fRoll = clamp(10.0f * DotProduct(m_vecMoveSpeed, GetRight()), -200.0f, 1.3f); } - debug("fPitch: %f\n", fPitch); ApplyTurnForce(fPitch * GetUp() * fPitchVar * m_fTurnMass * CTimer::GetTimeStep(), GetForward()); ApplyTurnForce(fRoll * GetUp() * fRollVar * m_fTurnMass * CTimer::GetTimeStep(), GetRight()); ApplyTurnForce(fYaw * GetForward() * fYawVar * m_fTurnMass * CTimer::GetTimeStep(), GetRight()); CVector vecResistance; - if (GetModelIndex() == MI_MIAMI_SPARROW) + if (GetModelIndex() == MI_SPARROW) vecResistance = vecHeliResistance; else vecResistance = vecRCHeliResistance; @@ -592,11 +597,14 @@ CVehicle::InflictDamage(CEntity* damagedBy, eWeaponType weaponType, float damage break; case WEAPONTYPE_COLT45: case WEAPONTYPE_UZI: + case WEAPONTYPE_TEC9: + case WEAPONTYPE_SILENCED_INGRAM: + case WEAPONTYPE_MP5: case WEAPONTYPE_SHOTGUN: case WEAPONTYPE_AK47: case WEAPONTYPE_M16: case WEAPONTYPE_SNIPERRIFLE: - case WEAPONTYPE_TOTAL_INVENTORY_WEAPONS: + case WEAPONTYPE_HELICANNON: case WEAPONTYPE_UZI_DRIVEBY: if (bBulletProof) return; @@ -693,45 +701,7 @@ void CVehicle::DoFixedMachineGuns(void) { if(CPad::GetPad(0)->GetCarGunFired() && !bGunSwitchedOff){ - if(CTimer::GetTimeInMilliseconds() > m_nGunFiringTime + 150){ - CVector source, target; - float dx, dy, len; - - dx = GetForward().x; - dy = GetForward().y; - len = Sqrt(SQR(dx) + SQR(dy)); - if(len < 0.1f) len = 0.1f; - dx /= len; - dy /= len; - - m_nGunFiringTime = CTimer::GetTimeInMilliseconds(); - - source = GetMatrix() * CVector(2.0f, 2.5f, 1.0f); - target = source + CVector(dx, dy, 0.0f)*60.0f; - target += CVector( - ((CGeneral::GetRandomNumber()&0xFF)-128) * 0.015f, - ((CGeneral::GetRandomNumber()&0xFF)-128) * 0.015f, - ((CGeneral::GetRandomNumber()&0xFF)-128) * 0.02f); - CWeapon::DoTankDoomAiming(this, pDriver, &source, &target); - FireOneInstantHitRound(&source, &target, 15); - - source = GetMatrix() * CVector(-2.0f, 2.5f, 1.0f); - target = source + CVector(dx, dy, 0.0f)*60.0f; - target += CVector( - ((CGeneral::GetRandomNumber()&0xFF)-128) * 0.015f, - ((CGeneral::GetRandomNumber()&0xFF)-128) * 0.015f, - ((CGeneral::GetRandomNumber()&0xFF)-128) * 0.02f); - CWeapon::DoTankDoomAiming(this, pDriver, &source, &target); - FireOneInstantHitRound(&source, &target, 15); - - DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f); - - m_nAmmoInClip--; - if(m_nAmmoInClip == 0){ - m_nAmmoInClip = 20; - m_nGunFiringTime = CTimer::GetTimeInMilliseconds() + 1400; - } - } + FireFixedMachineGuns(); }else{ if(CTimer::GetTimeInMilliseconds() > m_nGunFiringTime + 1400) m_nAmmoInClip = 20; @@ -739,6 +709,50 @@ CVehicle::DoFixedMachineGuns(void) } void +CVehicle::FireFixedMachineGuns(void) +{ + if (CTimer::GetTimeInMilliseconds() <= m_nGunFiringTime + 150) + return; + CVector source, target; + float dx, dy, len; + + dx = GetForward().x; + dy = GetForward().y; + len = Sqrt(SQR(dx) + SQR(dy)); + if (len < 0.1f) len = 0.1f; + dx /= len; + dy /= len; + + m_nGunFiringTime = CTimer::GetTimeInMilliseconds(); + + source = GetMatrix() * CVector(2.0f, 2.5f, 1.0f); + target = source + CVector(dx, dy, 0.0f) * 60.0f; + target += CVector( + ((CGeneral::GetRandomNumber() & 0xFF) - 128) * 0.015f, + ((CGeneral::GetRandomNumber() & 0xFF) - 128) * 0.015f, + ((CGeneral::GetRandomNumber() & 0xFF) - 128) * 0.02f); + CWeapon::DoTankDoomAiming(this, pDriver, &source, &target); + FireOneInstantHitRound(&source, &target, 15); + + source = GetMatrix() * CVector(-2.0f, 2.5f, 1.0f); + target = source + CVector(dx, dy, 0.0f) * 60.0f; + target += CVector( + ((CGeneral::GetRandomNumber() & 0xFF) - 128) * 0.015f, + ((CGeneral::GetRandomNumber() & 0xFF) - 128) * 0.015f, + ((CGeneral::GetRandomNumber() & 0xFF) - 128) * 0.02f); + CWeapon::DoTankDoomAiming(this, pDriver, &source, &target); + FireOneInstantHitRound(&source, &target, 15); + + DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_SHOT_FIRED, 0.0f); + + m_nAmmoInClip--; + if (m_nAmmoInClip == 0) { + m_nAmmoInClip = 20; + m_nGunFiringTime = CTimer::GetTimeInMilliseconds() + 1400; + } +} + +void CVehicle::ExtinguishCarFire(void) { m_fHealth = Max(m_fHealth, 300.0f); @@ -873,24 +887,7 @@ CVehicle::IsVehicleNormal(void) { if (!pDriver || m_nNumPassengers != 0 || GetStatus() == STATUS_WRECKED) return false; - switch (GetModelIndex()){ - case MI_FIRETRUCK: - case MI_AMBULAN: - case MI_TAXI: - case MI_POLICE: - case MI_ENFORCER: - case MI_BUS: - case MI_RHINO: - case MI_BARRACKS: - case MI_DODO: - case MI_COACH: - case MI_CABBIE: - case MI_RCBANDIT: - case MI_BORGNINE: - return false; - default: - return true; - } + return GetModelInfo()->m_vehicleClass != -1; } bool @@ -1047,7 +1044,7 @@ CVehicle::SetUpDriver(void) if(VehicleCreatedBy != RANDOM_VEHICLE) return nil; - pDriver = CPopulation::AddPedInCar(this); + pDriver = CPopulation::AddPedInCar(this, false); pDriver->m_pMyVehicle = this; pDriver->m_pMyVehicle->RegisterReference((CEntity**)&pDriver->m_pMyVehicle); pDriver->bInVehicle = true; @@ -1063,7 +1060,7 @@ CVehicle::SetupPassenger(int n) if(pPassengers[n]) return pPassengers[n]; - pPassengers[n] = CPopulation::AddPedInCar(this); + pPassengers[n] = CPopulation::AddPedInCar(this, true); pPassengers[n]->m_pMyVehicle = this; pPassengers[n]->m_pMyVehicle->RegisterReference((CEntity**)&pPassengers[n]->m_pMyVehicle); pPassengers[n]->bInVehicle = true; @@ -1085,11 +1082,12 @@ CVehicle::SetDriver(CPed *driver) FindPlayerPed()->m_fHealth = Min(FindPlayerPed()->m_fHealth + 20.0f, 100.0f); else if(GetModelIndex() == MI_TAXI) CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 25; - else if(GetModelIndex() == MI_POLICE) + else if (GetModelIndex() == MI_POLICE) { + CStreaming::RequestModel(WEAPONTYPE_SHOTGUN, STREAMFLAGS_DONT_REMOVE); driver->GiveWeapon(WEAPONTYPE_SHOTGUN, 5); - else if(GetModelIndex() == MI_ENFORCER) + } else if (GetModelIndex() == MI_ENFORCER) driver->m_fArmour = Max(driver->m_fArmour, 100.0f); - else if(GetModelIndex() == MI_CABBIE || GetModelIndex() == MI_BORGNINE) + else if(GetModelIndex() == MI_CABBIE || GetModelIndex() == MI_ZEBRA) // TODO(MIAMI): check zebra CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 25; bFreebies = false; } @@ -1347,3 +1345,21 @@ CVehicle::Load(uint8*& buf) SkipSaveBuf(buf, 99); } #endif + +eVehicleAppearance +//--MIAMI: TODO, implement VC version, appearance != type +// This would work for cars, boats and bikes but not for planes and helis +CVehicle::GetVehicleAppearance(void) +{ + if (IsCar()) + return VEHICLE_CAR; + if (IsBoat()) + return VEHICLE_BOAT; + if (IsBike()) + return VEHICLE_BIKE; + if (IsPlane()) + return VEHICLE_PLANE; + if (IsHeli()) + return VEHICLE_HELI; + return VEHICLE_NONE; +} diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h index f7205c7d..cdf0595a 100644 --- a/src/vehicles/Vehicle.h +++ b/src/vehicles/Vehicle.h @@ -5,6 +5,7 @@ #include "ModelIndices.h" #include "AnimManager.h" #include "Weapon.h" +#include "HandlingMgr.h" class CPed; class CFire; @@ -109,6 +110,16 @@ enum eFlightModel FLIGHT_MODEL_SEAPLANE }; +enum eVehicleAppearance +{ + VEHICLE_NONE, + VEHICLE_CAR, + VEHICLE_BIKE, + VEHICLE_HELI, + VEHICLE_BOAT, + VEHICLE_PLANE, +}; + // Or Weapon.h? void FireOneInstantHitRound(CVector *shotSource, CVector *shotTarget, int32 damage); @@ -122,7 +133,7 @@ public: uint8 m_currentColour2; uint8 m_aExtras[2]; int16 m_nAlarmState; - int16 m_nMissionValue; + int16 m_nRouteSeed; CPed *pDriver; CPed *pPassengers[8]; uint8 m_nNumPassengers; @@ -172,6 +183,12 @@ public: uint8 bIsCarParkVehicle : 1; // Car has been created using the special CAR_PARK script command uint8 bHasAlreadyBeenRecorded : 1; // Used for replays + uint8 bPartOfConvoy : 1; + uint8 bCreatedAsPoliceVehicle : 1;// True if this guy was created as a police vehicle (enforcer, policecar, miamivice car etc) + uint8 bParking : 1; + + uint8 m_bombType : 3; + int8 m_numPedsUseItAsCover; uint8 m_nAmmoInClip; // Used to make the guns on boat do a reload (20 by default) int8 m_nPacManPickupsCarried; @@ -180,6 +197,7 @@ public: float m_fHealth; // 1000.0f = full health. 250.0f = fire. 0 -> explode uint8 m_nCurrentGear; float m_fChangeGearTime; + CEntity* m_pBombRigger; uint32 m_nGunFiringTime; // last time when gun on vehicle was fired (used on boats) uint32 m_nTimeOfDeath; uint16 m_nTimeBlocked; @@ -236,6 +254,7 @@ public: virtual void Load(uint8*& buf); #endif + eVehicleAppearance GetVehicleAppearance(void); bool IsCar(void) { return m_vehType == VEHICLE_TYPE_CAR; } bool IsBoat(void) { return m_vehType == VEHICLE_TYPE_BOAT; } bool IsTrain(void) { return m_vehType == VEHICLE_TYPE_TRAIN; } @@ -273,11 +292,13 @@ public: bool ShufflePassengersToMakeSpace(void); void InflictDamage(CEntity *damagedBy, eWeaponType weaponType, float damage); void DoFixedMachineGuns(void); + void FireFixedMachineGuns(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; } + bool IsTaxi(void) { return GetModelIndex() == MI_TAXI || GetModelIndex() == MI_CABBIE || GetModelIndex() == MI_ZEBRA || GetModelIndex() == MI_KAUFMAN; } + bool IsRealHeli(void) { return !!(pHandling->Flags & HANDLING_IS_HELI); } AnimationId GetDriverAnim(void) { return IsCar() && bLowVehicle ? ANIM_CAR_LSIT : (IsBoat() && GetModelIndex() != MI_SPEEDER ? ANIM_DRIVE_BOAT : ANIM_CAR_SIT); } static bool bWheelsOnlyCheat; @@ -291,6 +312,4 @@ public: static bool m_bDisableMouseSteering; }; -VALIDATE_SIZE(CVehicle, 0x288); - void DestroyVehicleAndDriverAndPassengers(CVehicle* pVehicle); |