From a65dd41da736a12866526abc1405cbaa154771a8 Mon Sep 17 00:00:00 2001 From: aap Date: Tue, 9 Jul 2019 18:50:35 +0200 Subject: yet more CAutomobile --- src/control/Darkel.cpp | 8 +-- src/control/Darkel.h | 7 ++- src/core/Camera.cpp | 1 + src/core/Camera.h | 2 + src/core/Explosion.cpp | 5 ++ src/core/Explosion.h | 15 ++++++ src/core/Fire.cpp | 6 ++- src/core/Fire.h | 21 +++++--- src/core/Wanted.cpp | 10 +++- src/core/Wanted.h | 1 + src/peds/Ped.cpp | 1 + src/peds/Ped.h | 1 + src/peds/PlayerPed.cpp | 13 +++++ src/peds/PlayerPed.h | 2 + src/vehicles/Automobile.cpp | 117 +++++++++++++++++++++++++++++++++++++++++++- src/vehicles/Automobile.h | 2 + src/vehicles/Vehicle.h | 12 ++--- 17 files changed, 201 insertions(+), 23 deletions(-) create mode 100644 src/core/Explosion.cpp create mode 100644 src/core/Explosion.h (limited to 'src') diff --git a/src/control/Darkel.cpp b/src/control/Darkel.cpp index f050a540..ab28f96e 100644 --- a/src/control/Darkel.cpp +++ b/src/control/Darkel.cpp @@ -123,18 +123,18 @@ eKillFrenzyStatus CDarkel::ReadStatus() } #if 1 -WRAPPER int32 CDarkel::RegisterCarBlownUpByPlayer(eKillFrenzyStatus status) { EAXJMP(0x421070); } +WRAPPER void CDarkel::RegisterCarBlownUpByPlayer(CVehicle *vehicle) { EAXJMP(0x421070); } #else -int32 CDarkel::RegisterCarBlownUpByPlayer(eKillFrenzyStatus status) +int32 CDarkel::RegisterCarBlownUpByPlayer(CVehicle *vehicle) { return 0; } #endif #if 1 -WRAPPER void CDarkel::RegisterKillByPlayer(int32 modelid, eWeaponType weapontype, bool flag) { EAXJMP(0x420F60); } +WRAPPER void CDarkel::RegisterKillByPlayer(CPed *victim, eWeaponType weapontype, bool headshot) { EAXJMP(0x420F60); } #else -void CDarkel::RegisterKillByPlayer(int32 modelid, eWeaponType weapontype, bool flag) +void CDarkel::RegisterKillByPlayer(CPed *victim, eWeaponType weapontype, bool headshot) { diff --git a/src/control/Darkel.h b/src/control/Darkel.h index da1df24a..35d849d2 100644 --- a/src/control/Darkel.h +++ b/src/control/Darkel.h @@ -1,6 +1,9 @@ #pragma once #include "Weapon.h" +class CVehicle; +class CPed; + enum eKillFrenzyStatus { KILLFRENZY_NONE, @@ -37,8 +40,8 @@ public: static void Init(); static int16 QueryModelsKilledByPlayer(int32 modelId); static eKillFrenzyStatus ReadStatus(); - static int32 RegisterCarBlownUpByPlayer(eKillFrenzyStatus status); - static void RegisterKillByPlayer(int32 modelid, eWeaponType weapontype, bool flag); + static void RegisterCarBlownUpByPlayer(CVehicle *vehicle); + static void RegisterKillByPlayer(CPed *victim, eWeaponType weapontype, bool headshot = false); static void RegisterKillNotByPlayer(); static void ResetModelsKilledByPlayer(); static void ResetOnPlayerDeath(); diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp index 832f9455..0f4503bb 100644 --- a/src/core/Camera.cpp +++ b/src/core/Camera.cpp @@ -18,6 +18,7 @@ const float DefaultFOV = 70.0f; // beta: 80.0f CCamera &TheCamera = *(CCamera*)0x6FACF8; bool &CCamera::m_bUseMouse3rdPerson = *(bool *)0x5F03D8; +WRAPPER void CCamera::CamShake(float strength, float x, float y, float z) { EAXJMP(0x46B200); } WRAPPER void CCamera::DrawBordersForWideScreen(void) { EAXJMP(0x46B430); } WRAPPER void CCamera::CalculateDerivedValues(void) { EAXJMP(0x46EEA0); } WRAPPER void CCamera::Restore(void) { EAXJMP(0x46F990); } diff --git a/src/core/Camera.h b/src/core/Camera.h index db5fff46..f00a213e 100644 --- a/src/core/Camera.h +++ b/src/core/Camera.h @@ -454,6 +454,8 @@ int m_iModeObbeCamIsInForCar; void ProcessMusicFade(void); void SetFadeColour(uint8 r, uint8 g, uint8 b); + void CamShake(float strength, float x, float y, float z); + void SetMotionBlur(int r, int g, int b, int a, int type); void SetMotionBlurAlpha(int a); void RenderMotionBlur(void); diff --git a/src/core/Explosion.cpp b/src/core/Explosion.cpp new file mode 100644 index 00000000..f55cbcd6 --- /dev/null +++ b/src/core/Explosion.cpp @@ -0,0 +1,5 @@ +#include "common.h" +#include "patcher.h" +#include "Explosion.h" + +WRAPPER void CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32) { EAXJMP(0x5591C0); } diff --git a/src/core/Explosion.h b/src/core/Explosion.h new file mode 100644 index 00000000..69508490 --- /dev/null +++ b/src/core/Explosion.h @@ -0,0 +1,15 @@ +#pragma once + +class CEntity; + +enum eExplosionType +{ + EXPLOSION_3 = 3, + EXPLOSION_4 +}; + +class CExplosion +{ +public: + static void AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32); +}; diff --git a/src/core/Fire.cpp b/src/core/Fire.cpp index 05d72199..bc59de2f 100644 --- a/src/core/Fire.cpp +++ b/src/core/Fire.cpp @@ -2,4 +2,8 @@ #include "patcher.h" #include "Fire.h" -WRAPPER void CFire::Extinguish(void) { EAXJMP(0x479D40); } \ No newline at end of file +CFireManager &gFireManager = *(CFireManager*)0x8F31D0; + +WRAPPER void CFire::Extinguish(void) { EAXJMP(0x479D40); } + +WRAPPER void CFireManager::StartFire(CEntity *entityOnFire, CEntity *culprit, float, uint32) { EAXJMP(0x479590); } diff --git a/src/core/Fire.h b/src/core/Fire.h index c7f83fd8..9c9e1dec 100644 --- a/src/core/Fire.h +++ b/src/core/Fire.h @@ -1,13 +1,13 @@ #pragma once -#include "common.h" -#include "Entity.h" + +class CEntity; class CFire { - char m_bIsOngoing; - char m_bExists; - char m_bPropogationFlag; - char m_bAudioSet; + bool m_bIsOngoing; + bool m_bExists; + bool m_bPropogationFlag; + bool m_bAudioSet; CVector m_vecPos; CEntity *m_pEntity; CEntity *m_pSource; @@ -20,4 +20,11 @@ class CFire public: void Extinguish(void); -}; \ No newline at end of file +}; + +class CFireManager +{ +public: + void StartFire(CEntity *entityOnFire, CEntity *culprit, float, uint32); +}; +extern CFireManager &gFireManager; diff --git a/src/core/Wanted.cpp b/src/core/Wanted.cpp index 21853308..4608bfef 100644 --- a/src/core/Wanted.cpp +++ b/src/core/Wanted.cpp @@ -34,7 +34,7 @@ int CWanted::NumOfHelisRequired() return 2; default: return 0; - }; + } } void CWanted::SetWantedLevel(int32 level) @@ -70,11 +70,17 @@ void CWanted::SetWantedLevel(int32 level) UpdateWantedLevel(); } +void CWanted::SetWantedLevelNoDrop(int32 level) +{ + if (level > m_nWantedLevel) + SetWantedLevel(level); +} + void CWanted::ClearQdCrimes() { for (int i = 0; i < 16; i++) { m_sCrimes[i].m_eCrimeType = CRIME_NONE; - }; + } } void CWanted::UpdateWantedLevel() diff --git a/src/core/Wanted.h b/src/core/Wanted.h index d14bb905..d3f6638b 100644 --- a/src/core/Wanted.h +++ b/src/core/Wanted.h @@ -42,6 +42,7 @@ public: bool AreArmyRequired(); int NumOfHelisRequired(); void SetWantedLevel(int32); + void SetWantedLevelNoDrop(int32 level); void ClearQdCrimes(); void UpdateWantedLevel(); }; diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index e0e0b913..28cb8823 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -28,6 +28,7 @@ WRAPPER void CPed::KillPedWithCar(CVehicle *veh, float impulse) { EAXJMP(0x4EC430); } WRAPPER void CPed::Say(uint16 audio) { EAXJMP(0x4E5A10); } WRAPPER void CPed::SetDie(AnimationId anim, float arg1, float arg2) { EAXJMP(0x4D37D0); } +WRAPPER void CPed::SetDead(void) { EAXJMP(0x4D3970); } WRAPPER void CPed::SpawnFlyingComponent(int, int8) { EAXJMP(0x4EB060); } WRAPPER void CPed::RestorePreviousState(void) { EAXJMP(0x4C5E30); } WRAPPER void CPed::ClearAttack(void) { EAXJMP(0x4E6790); } diff --git a/src/peds/Ped.h b/src/peds/Ped.h index 6aba79cf..f48c30ba 100644 --- a/src/peds/Ped.h +++ b/src/peds/Ped.h @@ -414,6 +414,7 @@ public: void SetLookFlag(float direction, bool unknown); void SetLookTimer(int time); void SetDie(AnimationId anim, float arg1, float arg2); + void SetDead(void); void ApplyHeadShot(eWeaponType weaponType, CVector pos, bool evenOnPlayer); void RemoveBodyPart(PedNode nodeId, int8 unknown); void SpawnFlyingComponent(int, int8 unknown); diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp index 07cb5541..43206e08 100644 --- a/src/peds/PlayerPed.cpp +++ b/src/peds/PlayerPed.cpp @@ -21,6 +21,19 @@ void CPlayerPed::ClearWeaponTarget() ClearPointGunAt(); } +void +CPlayerPed::SetWantedLevel(int32 level) +{ + m_pWanted->SetWantedLevel(level); +} + +void +CPlayerPed::SetWantedLevelNoDrop(int32 level) +{ + m_pWanted->SetWantedLevelNoDrop(level); +} + + class CPlayerPed_ : public CPlayerPed { public: diff --git a/src/peds/PlayerPed.h b/src/peds/PlayerPed.h index 1a106b38..8b617a43 100644 --- a/src/peds/PlayerPed.h +++ b/src/peds/PlayerPed.h @@ -43,6 +43,8 @@ public: void ReApplyMoveAnims(void); void ClearWeaponTarget(); + void SetWantedLevel(int32 level); + void SetWantedLevelNoDrop(int32 level); }; static_assert(sizeof(CPlayerPed) == 0x5F0, "CPlayerPed: error"); diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index 267e901a..54557dc2 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -4,15 +4,22 @@ #include "ModelIndices.h" #include "VisibilityPlugins.h" #include "DMAudio.h" +#include "Camera.h" +#include "Darkel.h" +#include "Fire.h" +#include "Explosion.h" #include "World.h" #include "SurfaceTable.h" #include "HandlingMgr.h" #include "CarCtrl.h" #include "PathFind.h" #include "Ped.h" +#include "PlayerPed.h" #include "Object.h" #include "Automobile.h" +RwObject *GetCurrentAtomicObjectCB(RwObject *object, void *data); + bool &CAutomobile::m_sAllTaxiLights = *(bool*)0x95CD21; WRAPPER CAutomobile* CAutomobile::ctor(int, uint8) { EAXJMP(0x52C6B0); } @@ -357,7 +364,88 @@ CAutomobile::RemoveRefsToVehicle(CEntity *ent) m_aGroundPhysical[i] = nil; } -WRAPPER void CAutomobile::BlowUpCar(CEntity *ent) { EAXJMP(0x53BC60); } +void +CAutomobile::BlowUpCar(CEntity *culprit) +{ + int i; + RpAtomic *atomic; + + if(!bCanBeDamaged) + return; + + // explosion pushes vehicle up + m_vecMoveSpeed.z += 0.13f; + m_status = STATUS_WRECKED; + bRenderScorched = true; + m_nTimeOfDeath = CTimer::GetTimeInMilliseconds(); + Damage.FuckCarCompletely(); + + if(GetModelIndex() != MI_RCBANDIT){ + SetBumperDamage(CAR_BUMP_FRONT, VEHBUMPER_FRONT); + SetBumperDamage(CAR_BUMP_REAR, VEHBUMPER_REAR); + SetDoorDamage(CAR_BONNET, DOOR_BONNET); + SetDoorDamage(CAR_BOOT, DOOR_BOOT); + SetDoorDamage(CAR_DOOR_LF, DOOR_FRONT_LEFT); + SetDoorDamage(CAR_DOOR_RF, DOOR_FRONT_RIGHT); + SetDoorDamage(CAR_DOOR_LR, DOOR_REAR_LEFT); + SetDoorDamage(CAR_DOOR_RR, DOOR_REAR_RIGHT); + SpawnFlyingComponent(CAR_WHEEL_LF, COMPGROUP_WHEEL); + RwFrameForAllObjects(m_aCarNodes[CAR_WHEEL_LF], GetCurrentAtomicObjectCB, &atomic); + if(atomic) + RpAtomicSetFlags(atomic, 0); + } + + m_fHealth = 0.0f; + m_nBombTimer = 0; + m_auto_flagA1 = false; + m_auto_flagA2 = false; + m_auto_flagA4 = false; + + TheCamera.CamShake(0.7f, GetPosition().x, GetPosition().y, GetPosition().z); + + // kill driver and passengers + if(pDriver){ + CDarkel::RegisterKillByPlayer(pDriver, WEAPONTYPE_EXPLOSION); + if(pDriver->GetPedState() == PED_DRIVING){ + pDriver->SetDead(); + if(!pDriver->IsPlayer()) + pDriver->FlagToDestroyWhenNextProcessed(); + }else + pDriver->SetDie(ANIM_KO_SHOT_FRONT1, 4.0f, 0.0f); + } + for(i = 0; i < m_nNumMaxPassengers; i++){ + if(pPassengers[i]){ + CDarkel::RegisterKillByPlayer(pPassengers[i], WEAPONTYPE_EXPLOSION); + if(pPassengers[i]->GetPedState() == PED_DRIVING){ + pPassengers[i]->SetDead(); + if(!pPassengers[i]->IsPlayer()) + pPassengers[i]->FlagToDestroyWhenNextProcessed(); + }else + pPassengers[i]->SetDie(ANIM_KO_SHOT_FRONT1, 4.0f, 0.0f); + } + } + + bEngineOn = false; + bLightsOn = false; + m_bSirenOrAlarm = false; + bTaxiLight = false; + if(bIsAmbulanceOnDuty){ + bIsAmbulanceOnDuty = false; + CCarCtrl::NumAmbulancesOnDuty--; + } + if(bIsFireTruckOnDuty){ + bIsFireTruckOnDuty = false; + CCarCtrl::NumFiretrucksOnDuty--; + } + ChangeLawEnforcerState(false); + + gFireManager.StartFire(this, culprit, 0.8f, 1); // TODO + CDarkel::RegisterCarBlownUpByPlayer(this); + if(GetModelIndex() == MI_RCBANDIT) + CExplosion::AddExplosion(this, culprit, EXPLOSION_4, GetPosition(), 0); // TODO + else + CExplosion::AddExplosion(this, culprit, EXPLOSION_3, GetPosition(), 0); // TODO +} bool CAutomobile::SetUpWheelColModel(CColModel *colModel) @@ -516,6 +604,31 @@ CAutomobile::SetupSuspensionLines(void) } } +// called on police cars +void +CAutomobile::ScanForCrimes(void) +{ + if(FindPlayerVehicle() && FindPlayerVehicle()->IsCar()) + if(FindPlayerVehicle()->m_nAlarmState != -1) + // if player's alarm is on, increase wanted level + if((FindPlayerVehicle()->GetPosition() - GetPosition()).MagnitudeSqr() < sq(20.0f)) + CWorld::Players[CWorld::PlayerInFocus].m_pPed->SetWantedLevelNoDrop(1); +} + +void +CAutomobile::BlowUpCarsInPath(void) +{ + int i; + + if(m_vecMoveSpeed.Magnitude() > 0.1f) + for(i = 0; i < m_nCollisionRecords; i++) + if(m_aCollisionRecords[i] && + m_aCollisionRecords[i]->IsVehicle() && + m_aCollisionRecords[i]->GetModelIndex() != MI_RHINO && + !m_aCollisionRecords[i]->bRenderScorched) + ((CVehicle*)m_aCollisionRecords[i])->BlowUpCar(this); +} + bool CAutomobile::HasCarStoppedBecauseOfLight(void) { @@ -1014,12 +1127,14 @@ STARTPATCHES InjectHook(0x52EFD0, &CAutomobile_::IsDoorClosed_, PATCH_JUMP); InjectHook(0x52F000, &CAutomobile_::IsDoorMissing_, PATCH_JUMP); InjectHook(0x53BF40, &CAutomobile_::RemoveRefsToVehicle_, PATCH_JUMP); + InjectHook(0x53BC60, &CAutomobile_::BlowUpCar_, PATCH_JUMP); InjectHook(0x53BF70, &CAutomobile_::SetUpWheelColModel_, PATCH_JUMP); InjectHook(0x53C0E0, &CAutomobile_::BurstTyre_, PATCH_JUMP); InjectHook(0x437690, &CAutomobile_::GetHeightAboveRoad_, PATCH_JUMP); InjectHook(0x53C450, &CAutomobile_::PlayCarHorn_, PATCH_JUMP); InjectHook(0x5353A0, &CAutomobile::ResetSuspension, PATCH_JUMP); InjectHook(0x52D210, &CAutomobile::SetupSuspensionLines, PATCH_JUMP); + InjectHook(0x53E000, &CAutomobile::BlowUpCarsInPath, PATCH_JUMP); InjectHook(0x42E220, &CAutomobile::HasCarStoppedBecauseOfLight, PATCH_JUMP); InjectHook(0x53D320, &CAutomobile::SetBusDoorTimer, PATCH_JUMP); InjectHook(0x53D370, &CAutomobile::ProcessAutoBusDoors, PATCH_JUMP); diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h index fc859f92..0e9bd945 100644 --- a/src/vehicles/Automobile.h +++ b/src/vehicles/Automobile.h @@ -91,6 +91,8 @@ public: void PlayHornIfNecessary(void); void ResetSuspension(void); void SetupSuspensionLines(void); + void ScanForCrimes(void); + void BlowUpCarsInPath(void); bool HasCarStoppedBecauseOfLight(void); void SetBusDoorTimer(uint32 timer, uint8 type); void ProcessAutoBusDoors(void); diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h index 5aa0a770..cd877da5 100644 --- a/src/vehicles/Vehicle.h +++ b/src/vehicles/Vehicle.h @@ -150,19 +150,19 @@ public: uint8 m_veh_flagB80 : 1; uint8 m_veh_flagC1 : 1; - uint8 bIsDamaged : 1; + uint8 bIsDamaged : 1; // This vehicle has been damaged and is displaying all its components uint8 m_veh_flagC4 : 1; uint8 m_veh_flagC8 : 1; uint8 m_veh_flagC10 : 1; uint8 m_veh_flagC20 : 1; - uint8 m_veh_flagC40 : 1; + uint8 bCanBeDamaged : 1; // Set to FALSE during cut scenes to avoid explosions uint8 m_veh_flagC80 : 1; uint8 m_veh_flagD1 : 1; uint8 m_veh_flagD2 : 1; - uint8 bVehicleColProcessed : 1; - uint8 bIsCarParkVehicle : 1; - uint8 bHasAlreadyBeenRecorded : 1; + uint8 bVehicleColProcessed : 1;// Has ProcessEntityCollision been processed for this car? + uint8 bIsCarParkVehicle : 1; // Car has been created using the special CAR_PARK script command + uint8 bHasAlreadyBeenRecorded : 1; // Used for replays uint8 m_veh_flagD20 : 1; uint8 m_veh_flagD40 : 1; uint8 m_veh_flagD80 : 1; @@ -189,7 +189,7 @@ public: int8 field_22B; uint8 m_nCarHornTimer; int8 field_22D; - uint8 m_nSirenOrAlarm; + bool m_bSirenOrAlarm; int8 field_22F; // TODO: this is an array CStoredCollPoly m_frontCollPoly; // poly which is under front part of car -- cgit v1.2.3