From 59145cea83da6d0ade8221dbe8c1469be8084ea0 Mon Sep 17 00:00:00 2001 From: aap Date: Fri, 19 Jul 2019 11:57:12 +0200 Subject: [PATCH] CAutomobile ctor, car spawner, fixes --- src/core/re3.cpp | 93 ++++++++++++-------- src/entities/Entity.cpp | 2 +- src/entities/Entity.h | 2 +- src/objects/ObjectData.cpp | 2 +- src/peds/Ped.cpp | 4 +- src/vehicles/Automobile.cpp | 150 ++++++++++++++++++++++++++++++++- src/vehicles/Automobile.h | 10 ++- src/vehicles/DamageManager.cpp | 7 ++ src/vehicles/DamageManager.h | 2 + src/vehicles/Door.h | 6 ++ 10 files changed, 230 insertions(+), 48 deletions(-) diff --git a/src/core/re3.cpp b/src/core/re3.cpp index 4876c555..2c44986f 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -10,6 +10,7 @@ #include "Clock.h" #include "World.h" #include "Vehicle.h" +#include "ModelIndices.h" #include "Streaming.h" #include "PathFind.h" #include "Boat.h" @@ -101,58 +102,41 @@ void ChittyChittyBangBangCheat(); void StrongGripCheat(); void NastyLimbsCheat(); -// needs too much stuff for now -#if 0 +DebugMenuEntry *carCol1; +DebugMenuEntry *carCol2; + void -spawnCar(int id) +SpawnCar(int id) { CVector playerpos; CStreaming::RequestModel(id, 0); CStreaming::LoadAllRequestedModels(false); if(CStreaming::HasModelLoaded(id)){ - FindPlayerCoors(playerpos); + playerpos = FindPlayerCoors(); int node = ThePaths.FindNodeClosestToCoors(playerpos, 0, 100.0f, false, false); if(node < 0) return; CVehicle *v; - if(CModelInfo::IsBoatModel(id)){ -// CBoat* boat = (CBoat*)CVehicle__new(0x484); -// boat = boat->ctor(id, 1); -// v = (CVehicle*)(boat); - }else{ -// CAutomobile *au = (CAutomobile*)CVehicle__new(0x5A8); -// au = au->ctor(id, 1); -// v = (CVehicle*)au; - } -/* - // unlock doors - FIELD(int, v, 0x224) = 1; - // set player owned - FIELD(uint8, v, 0x1F7) |= 4; + if(CModelInfo::IsBoatModel(id)) + return; + else + v = new CAutomobile(id, RANDOM_VEHICLE); - DebugMenuEntrySetAddress(carCol1, &FIELD(uchar, v, 0x19C)); - DebugMenuEntrySetAddress(carCol2, &FIELD(uchar, v, 0x19D)); - //if(id == MODELID_ESPERANTO) - // FIELD(uchar, v, 0x19C) = 54; + v->bHasBeenOwnedByPlayer = true; + if(carCol1) + DebugMenuEntrySetAddress(carCol1, &v->m_currentColour1); + if(carCol2) + DebugMenuEntrySetAddress(carCol2, &v->m_currentColour2); - v->matrix.matrix.pos.x = ThePaths.nodes[node].x; - v->matrix.matrix.pos.y = ThePaths.nodes[node].y; - v->matrix.matrix.pos.z = ThePaths.nodes[node].z + 4.0f; - float x = v->matrix.matrix.pos.x; - float y = v->matrix.matrix.pos.y; - float z = v->matrix.matrix.pos.z; - v->matrix.SetRotate(0.0f, 0.0f, 3.49f); - v->matrix.matrix.pos.x += x; - v->matrix.matrix.pos.y += y; - v->matrix.matrix.pos.z += z; - v->bfTypeStatus = v->bfTypeStatus & 7 | 0x20; - FIELD(int, v, 0x224) = 1; -*/ + v->GetPosition() = ThePaths.m_pathNodes[node].pos; + v->GetPosition().z += 4.0f; + v->SetOrientation(0.0f, 0.0f, 3.49f); + v->m_status = STATUS_ABANDONED; + v->m_nDoorLock = CARLOCK_UNLOCKED; CWorld::Add(v); } } -#endif static void FixCar(void) @@ -176,6 +160,14 @@ ToggleComedy(void) veh->bComedyControls = !veh->bComedyControls; } +static const char *carnames[] = { + "landstal", "idaho", "stinger", "linerun", "peren", "sentinel", "patriot", "firetruk", "trash", "stretch", "manana", "infernus", "blista", "pony", + "mule", "cheetah", "ambulan", "fbicar", "moonbeam", "esperant", "taxi", "kuruma", "bobcat", "mrwhoop", "bfinject", "corpse", "police", "enforcer", + "securica", "banshee", "predator", "bus", "rhino", "barracks", "train", "chopper", "dodo", "coach", "cabbie", "stallion", "rumpo", "rcbandit", + "bellyup", "mrwongs", "mafia", "yardie", "yakuza", "diablos", "columb", "hoods", "airtrain", "deaddodo", "speeder", "reefer", "panlant", "flatbed", + "yankee", "escape", "borgnine", "toyz", "ghost", +}; + void DebugMenuPopulate(void) { @@ -220,6 +212,35 @@ DebugMenuPopulate(void) DebugMenuAddCmd("Cheats", "Strong grip", StrongGripCheat); DebugMenuAddCmd("Cheats", "Nasty limbs", NastyLimbsCheat); + static int spawnCarId = MI_LANDSTAL; + e = DebugMenuAddVar("Spawn", "Spawn Car ID", &spawnCarId, nil, 1, MI_LANDSTAL, MI_GHOST, carnames); + DebugMenuEntrySetWrap(e, true); + DebugMenuAddCmd("Spawn", "Spawn Car", [](){ + if(spawnCarId == MI_TRAIN || + spawnCarId == MI_CHOPPER || + spawnCarId == MI_AIRTRAIN || + spawnCarId == MI_DEADDODO || + spawnCarId == MI_ESCAPE) + return; + SpawnCar(spawnCarId); + }); + static uint8 dummy; + carCol1 = DebugMenuAddVar("Spawn", "First colour", &dummy, nil, 1, 0, 255, nil); + carCol2 = DebugMenuAddVar("Spawn", "Second colour", &dummy, nil, 1, 0, 255, nil); + DebugMenuAddCmd("Spawn", "Spawn Stinger", [](){ SpawnCar(MI_STINGER); }); + DebugMenuAddCmd("Spawn", "Spawn Infernus", [](){ SpawnCar(MI_INFERNUS); }); + DebugMenuAddCmd("Spawn", "Spawn Cheetah", [](){ SpawnCar(MI_CHEETAH); }); + DebugMenuAddCmd("Spawn", "Spawn Esperanto", [](){ SpawnCar(MI_ESPERANT); }); + DebugMenuAddCmd("Spawn", "Spawn Stallion", [](){ SpawnCar(MI_STALLION); }); + DebugMenuAddCmd("Spawn", "Spawn Kuruma", [](){ SpawnCar(MI_KURUMA); }); + DebugMenuAddCmd("Spawn", "Spawn Taxi", [](){ SpawnCar(MI_TAXI); }); + DebugMenuAddCmd("Spawn", "Spawn Police", [](){ SpawnCar(MI_POLICE); }); + DebugMenuAddCmd("Spawn", "Spawn Enforcer", [](){ SpawnCar(MI_ENFORCER); }); + DebugMenuAddCmd("Spawn", "Spawn Banshee", [](){ SpawnCar(MI_BANSHEE); }); + DebugMenuAddCmd("Spawn", "Spawn Yakuza", [](){ SpawnCar(MI_YAKUZA); }); + DebugMenuAddCmd("Spawn", "Spawn Dodo", [](){ SpawnCar(MI_DODO); }); + + DebugMenuAddCmd("Debug", "Fix Car", FixCar); DebugMenuAddCmd("Debug", "Toggle Comedy Controls", ToggleComedy); diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp index 10677bdf..1882c3b5 100644 --- a/src/entities/Entity.cpp +++ b/src/entities/Entity.cpp @@ -42,7 +42,7 @@ CEntity::CEntity(void) bUseCollisionRecords = false; bWasPostponed = false; - m_flagB2 = false; + bExplosionProof = false; bIsVisible = true; bHasCollided = false; bRenderScorched = false; diff --git a/src/entities/Entity.h b/src/entities/Entity.h index 69fd6eea..ff43903f 100644 --- a/src/entities/Entity.h +++ b/src/entities/Entity.h @@ -50,7 +50,7 @@ public: // flagsB uint32 bWasPostponed : 1; - uint32 m_flagB2 : 1; // explosion proof? + uint32 bExplosionProof : 1; uint32 bIsVisible : 1; uint32 bHasCollided : 1; // uint32 bRenderScorched : 1; diff --git a/src/objects/ObjectData.cpp b/src/objects/ObjectData.cpp index ef5bcc5e..775a87a1 100644 --- a/src/objects/ObjectData.cpp +++ b/src/objects/ObjectData.cpp @@ -93,7 +93,7 @@ CObjectData::SetObjectData(int32 modelId, CObject &object) if(object.m_fMass >= 99998.0){ object.bInfiniteMass = true; object.bAffectedByGravity = false; - object.m_flagB2 = true; + object.bExplosionProof = true; } } diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index 924098bc..80b4b5db 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -3461,7 +3461,7 @@ CPed::InflictDamage(CEntity* damagedBy, eWeaponType method, float damage, ePedPi case WEAPONTYPE_ROCKETLAUNCHER: case WEAPONTYPE_GRENADE: case WEAPONTYPE_EXPLOSION: - if (bCanPointGunAtTarget) + if (bExplosionProof) return false; if (CGame::nastyGame && !IsPlayer() && !bInVehicle && @@ -3483,7 +3483,7 @@ CPed::InflictDamage(CEntity* damagedBy, eWeaponType method, float damage, ePedPi } // fall through case WEAPONTYPE_MOLOTOV: - if (m_flagB2) + if (bExplosionProof) return false; switch (direction) { diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index 6890eeb9..33f099b3 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -2,6 +2,7 @@ #include "main.h" #include "patcher.h" #include "General.h" +#include "RwHelper.h" #include "Pad.h" #include "ModelIndices.h" #include "VisibilityPlugins.h" @@ -35,9 +36,152 @@ bool &CAutomobile::m_sAllTaxiLights = *(bool*)0x95CD21; WRAPPER CAutomobile* CAutomobile::ctor(int, uint8) { EAXJMP(0x52C6B0); } -CAutomobile::CAutomobile(int mi, uint8 CreatedBy) +CAutomobile::CAutomobile(int32 id, uint8 CreatedBy) + : CVehicle(CreatedBy) { - ctor(mi, CreatedBy); + int i; + + m_vehType = VEHICLE_TYPE_CAR; + + CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(id); + m_fFireBlowUpTimer = 0.0f; + field_4E0 = 0; + bTaxiLight = m_sAllTaxiLights; + m_auto_flagA20 = false; + m_auto_flagA40 = false; + m_auto_flagA80 = false; + + SetModelIndex(id); + + pHandling = mod_HandlingManager.GetHandlingData((eHandlingId)mi->m_handlingId); + + field_49C = 20.0f; + field_4D8 = 0; + + mi->ChooseVehicleColour(m_currentColour1, m_currentColour2); + + bIsVan = !!(pHandling->Flags & HANDLING_IS_VAN); + bIsBig = !!(pHandling->Flags & HANDLING_IS_BIG); + bIsBus = !!(pHandling->Flags & HANDLING_IS_BUS); + bLowVehicle = !!(pHandling->Flags & HANDLING_IS_LOW); + + // Doors + if(bIsBus){ + Doors[DOOR_FRONT_LEFT].Init(-HALFPI, 0.0f, 0, 2); + Doors[DOOR_FRONT_RIGHT].Init(0.0f, HALFPI, 1, 2); + }else{ + Doors[DOOR_FRONT_LEFT].Init(-PI*0.4f, 0.0f, 0, 2); + Doors[DOOR_FRONT_RIGHT].Init(0.0f, PI*0.4f, 1, 2); + } + if(bIsVan){ + Doors[DOOR_REAR_LEFT].Init(-HALFPI, 0.0f, 1, 2); + Doors[DOOR_REAR_RIGHT].Init(0.0f, HALFPI, 0, 2); + }else{ + Doors[DOOR_REAR_LEFT].Init(-PI*0.4f, 0.0f, 0, 2); + Doors[DOOR_REAR_RIGHT].Init(0.0f, PI*0.4f, 1, 2); + } + if(pHandling->Flags & HANDLING_REV_BONNET) + Doors[DOOR_BONNET].Init(-PI*0.3f, 0.0f, 1, 0); + else + Doors[DOOR_BONNET].Init(0.0f, PI*0.3f, 1, 0); + if(pHandling->Flags & HANDLING_HANGING_BOOT) + Doors[DOOR_BOOT].Init(PI*0.4f, 0.0f, 0, 0); + else if(pHandling->Flags & HANDLING_TAILGATE_BOOT) + Doors[DOOR_BOOT].Init(0.0, HALFPI, 1, 0); + else + Doors[DOOR_BOOT].Init(-PI*0.3f, 0.0f, 1, 0); + if(pHandling->Flags & HANDLING_NO_DOORS){ + Damage.SetDoorStatus(DOOR_FRONT_LEFT, DOOR_STATUS_MISSING); + Damage.SetDoorStatus(DOOR_FRONT_RIGHT, DOOR_STATUS_MISSING); + Damage.SetDoorStatus(DOOR_REAR_LEFT, DOOR_STATUS_MISSING); + Damage.SetDoorStatus(DOOR_REAR_RIGHT, DOOR_STATUS_MISSING); + } + + for(i = 0; i < 6; i++) + m_randomValues[i] = CGeneral::GetRandomNumberInRange(-0.15f, 0.15f); + + m_fMass = pHandling->fMass; + m_fTurnMass = pHandling->fTurnMass; + m_vecCentreOfMass = pHandling->CentreOfMass; + m_fAirResistance = pHandling->Dimension.x*pHandling->Dimension.z/m_fMass; + m_fElasticity = 0.05f; + m_fBuoyancy = pHandling->fBuoyancy; + + m_nBusDoorTimerEnd = 0; + m_nBusDoorTimerStart = 0; + + m_fSteerAngle = 0.0f; + m_fGasPedal = 0.0f; + m_fBrakePedal = 0.0f; + m_pSetOnFireEntity = nil; + field_594 = 0; + bNotDamagedUpsideDown = false; + bMoreResistantToDamage = false; + field_514 = 0; + field_4E2 = 0; + + for(i = 0; i < 4; i++){ + m_aGroundPhysical[i] = nil; + m_aGroundOffset[i] = CVector(0.0f, 0.0f, 0.0f); + m_aSuspensionSpringRatio[i] = 1.0f; + m_aSuspensionSpringRatioPrev[i] = m_aSuspensionSpringRatio[i]; + m_aWheelTimer[i] = 0.0f; + m_aWheelRotation[i] = 0.0f; + m_aWheelSpeed[i] = 0.0f; + m_aWheelState[i] = WHEEL_STATE_0; + m_aWheelSkidmarkMuddy[i] = false; + m_aWheelSkidmarkBloody[i] = false; + } + + m_nWheelsOnGround = 0; + m_nDriveWheelsOnGround = 0; + m_nDriveWheelsOnGroundPrev = 0; + m_fHeightAboveRoad = 0.0f; + m_fTraction = 1.0f; + + CColModel *colModel = mi->GetColModel(); + if(colModel->lines == nil){ + colModel->lines = (CColLine*)RwMalloc(4*sizeof(CColLine)); + colModel->numLines = 4; + } + + SetupSuspensionLines(); + + m_status = STATUS_SIMPLE; + bUseCollisionRecords = true; + + m_nNumPassengers = 0; + + m_bombType = CARBOMB_NONE; + bHadDriver = false; + field_4DC = nil; + + if(m_nDoorLock == CARLOCK_UNLOCKED && + (id == MI_POLICE || id == MI_ENFORCER || id == MI_RHINO)) + m_nDoorLock = CARLOCK_LOCKED_INITIALLY; + + m_fCarGunLR = 0.0f; + m_fCarGunUD = 0.05f; + m_fWindScreenRotation = 0.0f; + m_weaponThingA = 0.0f; + m_weaponThingB = m_weaponThingA; + + if(GetModelIndex() == MI_DODO){ + RpAtomicSetFlags(GetFirstObject(m_aCarNodes[CAR_WHEEL_LF]), 0); + CMatrix mat1; + mat1.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WHEEL_RF])); + 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){ + RpAtomicSetFlags(GetFirstObject(m_aCarNodes[CAR_WHEEL_LF]), 0); + RpAtomicSetFlags(GetFirstObject(m_aCarNodes[CAR_WHEEL_RF]), 0); + RpAtomicSetFlags(GetFirstObject(m_aCarNodes[CAR_WHEEL_LB]), 0); + RpAtomicSetFlags(GetFirstObject(m_aCarNodes[CAR_WHEEL_RB]), 0); + }else if(GetModelIndex() == MI_RHINO){ + bExplosionProof = true; + bBulletProof = true; + } } @@ -572,7 +716,7 @@ CAutomobile::ProcessControl(void) m_pBlowUpEntity = FindPlayerPed(); CGarages::TriggerMessage("GA_12", -1, 3000, -1); DMAudio.PlayOneShot(m_audioEntityId, SOUND_BOMB_TIMED_ACTIVATED, 1.0f); - }else{ + }else if(m_bombType == CARBOMB_ONIGNITION){ m_bombType = CARBOMB_ONIGNITIONACTIVE; CGarages::TriggerMessage("GA_12", -1, 3000, -1); DMAudio.PlayOneShot(m_audioEntityId, SOUND_BOMB_ONIGNITION_ACTIVATED, 1.0f); diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h index 6caf5dde..0182dd99 100644 --- a/src/vehicles/Automobile.h +++ b/src/vehicles/Automobile.h @@ -53,14 +53,16 @@ public: uint8 bMoreResistantToDamage : 1; uint8 field_4DB; CEntity *field_4DC; // blow up entity - uint8 field_4E0[4]; + int16 field_4E0; + int16 field_4E2; uint32 m_nBusDoorTimerEnd; uint32 m_nBusDoorTimerStart; float m_aSuspensionSpringLength[4]; float m_aSuspensionLineLength[4]; float m_fHeightAboveRoad; float m_fTraction; - uint8 stuff6[28]; + int32 field_514; + float m_randomValues[6]; // used for what? float m_fFireBlowUpTimer; CPhysical *m_aGroundPhysical[4]; // physicals touching wheels CVector m_aGroundOffset[4]; // from ground object to colpoint @@ -74,12 +76,12 @@ public: uint8 m_nWheelsOnGround; uint8 m_nDriveWheelsOnGround; uint8 m_nDriveWheelsOnGroundPrev; - uint8 stuff5[5]; + int32 field_594; tWheelState m_aWheelState[4]; static bool &m_sAllTaxiLights; - CAutomobile(int, uint8); + CAutomobile(int32, uint8); // from CEntity void SetModelIndex(uint32 id); diff --git a/src/vehicles/DamageManager.cpp b/src/vehicles/DamageManager.cpp index c4d16207..3a7bd9e9 100644 --- a/src/vehicles/DamageManager.cpp +++ b/src/vehicles/DamageManager.cpp @@ -7,6 +7,13 @@ float G_aComponentDamage[] = { 2.5f, 1.25f, 3.2f, 1.4f, 2.5f, 2.8f, 0.5f }; +CDamageManager::CDamageManager(void) +{ + ResetDamageStatus(); + m_fWheelDamageEffect = 0.75f; + field_24 = 1; +} + void CDamageManager::ResetDamageStatus(void) { diff --git a/src/vehicles/DamageManager.h b/src/vehicles/DamageManager.h index 37fd90f5..adcd7430 100644 --- a/src/vehicles/DamageManager.h +++ b/src/vehicles/DamageManager.h @@ -79,6 +79,8 @@ public: uint32 m_panelStatus; uint32 field_24; + CDamageManager(void); + void ResetDamageStatus(void); void FuckCarCompletely(void); bool ApplyDamage(tComponent component, float damage, float unused); diff --git a/src/vehicles/Door.h b/src/vehicles/Door.h index fc771a40..7bb7bba3 100644 --- a/src/vehicles/Door.h +++ b/src/vehicles/Door.h @@ -26,6 +26,12 @@ struct CDoor CVector m_vecSpeed; CDoor(void); + void Init(float minAngle, float maxAngle, int8 dir, int8 axis) { + m_fMinAngle = minAngle; + m_fMaxAngle = maxAngle; + m_nDirn = dir; + m_nAxis = axis; + } void Open(float ratio); void Process(CVehicle *veh); float RetAngleWhenClosed(void);