From dad7782ff0be00775f99ad54c656e58b39190b47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eray=20or=C3=A7unus?= Date: Mon, 2 Dec 2019 23:02:32 +0300 Subject: CPhone, CPlayerInfo, CFire, CWorld --- src/core/Explosion.cpp | 1 + src/core/Explosion.h | 1 + src/core/Fire.cpp | 21 ++++- src/core/Fire.h | 2 + src/core/Pad.h | 2 +- src/core/PlayerInfo.cpp | 245 ++++++++++++++++++++++++++++++++++++++++++++++-- src/core/PlayerInfo.h | 15 ++- src/core/Radar.cpp | 4 +- src/core/World.cpp | 48 ++++++++-- src/core/World.h | 2 + 10 files changed, 315 insertions(+), 26 deletions(-) (limited to 'src/core') diff --git a/src/core/Explosion.cpp b/src/core/Explosion.cpp index 9ccd6e81..30809dc9 100644 --- a/src/core/Explosion.cpp +++ b/src/core/Explosion.cpp @@ -3,6 +3,7 @@ #include "Explosion.h" WRAPPER void CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32) { EAXJMP(0x5591C0); } +WRAPPER void CExplosion::RemoveAllExplosionsInArea(CVector, float) { EAXJMP(0x55AD40); } WRAPPER int8 CExplosion::GetExplosionActiveCounter(uint8 id) diff --git a/src/core/Explosion.h b/src/core/Explosion.h index fde4ad7f..0768bbe4 100644 --- a/src/core/Explosion.h +++ b/src/core/Explosion.h @@ -27,4 +27,5 @@ public: static CVector *GetExplosionPosition(uint8 id); static uint8 GetExplosionType(uint8 id); static void ResetExplosionActiveCounter(uint8 id); + static void RemoveAllExplosionsInArea(CVector, float); }; diff --git a/src/core/Fire.cpp b/src/core/Fire.cpp index 0317ccbe..7657d8e9 100644 --- a/src/core/Fire.cpp +++ b/src/core/Fire.cpp @@ -5,6 +5,9 @@ CFireManager &gFireManager = *(CFireManager*)0x8F31D0; WRAPPER void CFire::Extinguish(void) { EAXJMP(0x479D40); } +WRAPPER void CFireManager::StartFire(CEntity* entityOnFire, CEntity* culprit, float, uint32) { EAXJMP(0x479590); } +WRAPPER void CFireManager::Update(void) { EAXJMP(0x479310); } +WRAPPER CFire* CFireManager::FindFurthestFire_NeverMindFireMen(CVector coors, float, float) { EAXJMP(0x479430); } CFire* CFireManager::FindNearestFire(CVector vecPos, float* pDistance) { @@ -31,6 +34,18 @@ CFire* CFireManager::FindNearestFire(CVector vecPos, float* pDistance) return nil; } -WRAPPER void CFireManager::StartFire(CEntity *entityOnFire, CEntity *culprit, float, uint32) { EAXJMP(0x479590); } -WRAPPER void CFireManager::Update(void) { EAXJMP(0x479310); } -WRAPPER CFire *CFireManager::FindFurthestFire_NeverMindFireMen(CVector coors, float, float) { EAXJMP(0x479430); } +void +CFireManager::ExtinguishPoint(CVector point, float range) +{ + for (int i = 0; i < NUM_FIRES; i++) { + if (m_aFires[i].m_bIsOngoing) { + if ((point - m_aFires[i].m_vecPos).MagnitudeSqr() < sq(range)) + m_aFires[i].Extinguish(); + } + } +} + +STARTPATCHES + InjectHook(0x479DB0, &CFireManager::ExtinguishPoint, PATCH_JUMP); + InjectHook(0x479340, &CFireManager::FindNearestFire, PATCH_JUMP); +ENDPATCHES \ No newline at end of file diff --git a/src/core/Fire.h b/src/core/Fire.h index c752b2a6..e0ad7cdf 100644 --- a/src/core/Fire.h +++ b/src/core/Fire.h @@ -34,6 +34,8 @@ public: void Update(void); CFire *FindFurthestFire_NeverMindFireMen(CVector coors, float, float); CFire *FindNearestFire(CVector, float*); + void ExtinguishPoint(CVector, float); + uint32 GetTotalActiveFires() const { return m_nTotalFires; } }; extern CFireManager &gFireManager; diff --git a/src/core/Pad.h b/src/core/Pad.h index eadbd299..03b734cb 100644 --- a/src/core/Pad.h +++ b/src/core/Pad.h @@ -7,7 +7,7 @@ enum { PLAYERCONTROL_DISABLED_4 = 4, PLAYERCONTROL_DISABLED_8 = 8, PLAYERCONTROL_DISABLED_10 = 16, - PLAYERCONTROL_DISABLED_20 = 32, + PLAYERCONTROL_DISABLED_20 = 32, // used on CPlayerInfo::MakePlayerSafe PLAYERCONTROL_DISABLED_40 = 64, // used on phone calls PLAYERCONTROL_DISABLED_80 = 128, }; diff --git a/src/core/PlayerInfo.cpp b/src/core/PlayerInfo.cpp index f0b7d444..85682ae3 100644 --- a/src/core/PlayerInfo.cpp +++ b/src/core/PlayerInfo.cpp @@ -3,15 +3,24 @@ #include "PlayerPed.h" #include "PlayerInfo.h" #include "Frontend.h" -#include "Vehicle.h" #include "PlayerSkin.h" #include "Darkel.h" #include "Messages.h" #include "Text.h" #include "Stats.h" +#include "Remote.h" +#include "World.h" +#include "Replay.h" +#include "Pad.h" +#include "ProjectileInfo.h" +#include "Explosion.h" +#include "Script.h" +#include "Vehicle.h" +#include "HandlingMgr.h" +#include "General.h" +#include "main.h" +#include "SpecialFX.h" -WRAPPER void CPlayerInfo::MakePlayerSafe(bool) { EAXJMP(0x4A1400); } -WRAPPER void CPlayerInfo::AwardMoneyForExplosion(CVehicle *vehicle) { EAXJMP(0x4A15F0); } WRAPPER void CPlayerInfo::Process(void) { EAXJMP(0x49FD30); } void @@ -24,7 +33,7 @@ CPlayerInfo::SetPlayerSkin(char *skin) CVector& CPlayerInfo::GetPos() { - if (m_pPed->bInVehicle && m_pPed->m_pMyVehicle) + if (m_pPed->InVehicle()) return m_pPed->m_pMyVehicle->GetPosition(); return m_pPed->GetPosition(); } @@ -44,7 +53,7 @@ CPlayerInfo::DeletePlayerSkin() { if (m_pSkinTexture) { RwTextureDestroy(m_pSkinTexture); - m_pSkinTexture = NULL; + m_pSkinTexture = nil; } } @@ -88,9 +97,227 @@ CPlayerInfo::PlayerFailedCriticalMission() CDarkel::ResetOnPlayerDeath(); } +void +CPlayerInfo::Clear(void) +{ + m_pPed = nil; + m_pRemoteVehicle = nil; + if (m_pVehicleEx) { + m_pVehicleEx->bUsingSpecialColModel = false; + m_pVehicleEx = nil; + } + m_nVisibleMoney = 0; + m_nMoney = m_nVisibleMoney; + m_WBState = WBSTATE_PLAYING; + m_nWBTime = 0; + m_nTrafficMultiplier = 0; + m_fRoadDensity = 1.0f; + m_bInRemoteMode = false; + m_bSwitchTaxi = false; + m_nSwitchTaxiTime = 0; + m_nCollectedPackages = 0; + m_nTotalPackages = 3; + m_nTimeLastHealthLoss = 0; + m_nTimeLastArmourLoss = 0; + m_nNextSexFrequencyUpdateTime = 0; + m_nNextSexMoneyUpdateTime = 0; + m_nSexFrequency = 0; + m_pHooker = nil; + m_nTimeTankShotGun = 0; + field_248 = 0; + m_nUpsideDownCounter = 0; + m_bInfiniteSprint = false; + m_bFastReload = false; + m_bGetOutOfJailFree = false; + m_bGetOutOfHospitalFree = false; + m_nPreviousTimeRewardedForExplosion = 0; + m_nExplosionsSinceLastReward = 0; +} + +void +CPlayerInfo::BlowUpRCBuggy(void) +{ + if (!m_pRemoteVehicle || m_pRemoteVehicle->bRemoveFromWorld) + return; + + CRemote::TakeRemoteControlledCarFromPlayer(); + m_pRemoteVehicle->BlowUpCar(FindPlayerPed()); +} + +void +CPlayerInfo::CancelPlayerEnteringCars(CVehicle *car) +{ + if (!car || car == m_pPed->m_pMyVehicle) { + if (m_pPed->m_nPedState == PED_CARJACK || m_pPed->m_nPedState == PED_ENTER_CAR) + m_pPed->QuitEnteringCar(); + } + if (m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER || m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) + m_pPed->ClearObjective(); +} + +void +CPlayerInfo::MakePlayerSafe(bool toggle) +{ + if (toggle) { + CTheScripts::CountdownToMakePlayerUnsafe = 0; + m_pPed->m_pWanted->m_bIgnoredByEveryone = true; + CWorld::StopAllLawEnforcersInTheirTracks(); + CPad::GetPad(0)->DisablePlayerControls |= PLAYERCONTROL_DISABLED_20; + CPad::StopPadsShaking(); + m_pPed->bBulletProof = true; + m_pPed->bFireProof = true; + m_pPed->bCollisionProof = true; + m_pPed->bMeleeProof = true; + m_pPed->bOnlyDamagedByPlayer = true; + m_pPed->bExplosionProof = true; + m_pPed->m_bCanBeDamaged = false; + ((CPlayerPed*)m_pPed)->ClearAdrenaline(); + CancelPlayerEnteringCars(false); + gFireManager.ExtinguishPoint(GetPos(), 4000.0f); + CExplosion::RemoveAllExplosionsInArea(GetPos(), 4000.0f); + CProjectileInfo::RemoveAllProjectiles(); + CWorld::SetAllCarsCanBeDamaged(false); + CWorld::ExtinguishAllCarFiresInArea(GetPos(), 4000.0f); + CReplay::DisableReplays(); + + } else if (!CGame::playingIntro && !CTheScripts::CountdownToMakePlayerUnsafe) { + m_pPed->m_pWanted->m_bIgnoredByEveryone = false; + CPad::GetPad(0)->DisablePlayerControls &= ~PLAYERCONTROL_DISABLED_20; + m_pPed->bBulletProof = false; + m_pPed->bFireProof = false; + m_pPed->bCollisionProof = false; + m_pPed->bMeleeProof = false; + m_pPed->bOnlyDamagedByPlayer = false; + m_pPed->bExplosionProof = false; + m_pPed->m_bCanBeDamaged = true; + CWorld::SetAllCarsCanBeDamaged(true); + CReplay::EnableReplays(); + } +} + +bool +CPlayerInfo::IsRestartingAfterDeath() +{ + return m_WBState == WBSTATE_WASTED; +} + +bool +CPlayerInfo::IsRestartingAfterArrest() +{ + return m_WBState == WBSTATE_BUSTED; +} + +// lastClosestness is passed to other calls of this function +void +CPlayerInfo::EvaluateCarPosition(CEntity *carToTest, CPed *player, float carBoundCentrePedDist, float *lastClosestness, CVehicle **closestCarOutput) +{ + // This dist used for determining the angle to face + CVector2D dist(carToTest->GetPosition() - player->GetPosition()); + float neededTurn = CGeneral::GetATanOfXY(player->GetForward().x, player->GetForward().y) - CGeneral::GetATanOfXY(dist.x, dist.y); + while (neededTurn >= PI) { + neededTurn -= 2 * PI; + } + + while (neededTurn < -PI) { + neededTurn += 2 * PI; + } + + // This dist used for evaluating cars' distances, weird... + // Accounts inverted needed turn (or needed turn in long way) and car dist. + float closestness = (1.0f - Abs(neededTurn) / TWOPI) * (10.0f - carBoundCentrePedDist); + if (closestness > *lastClosestness) { + *lastClosestness = closestness; + *closestCarOutput = (CVehicle*)carToTest; + } +} + +// There is something unfinished in here... Sadly all IDBs we have have it unfinished. +void +CPlayerInfo::AwardMoneyForExplosion(CVehicle *wreckedCar) +{ + if (CTimer::GetTimeInMilliseconds() - m_nPreviousTimeRewardedForExplosion < 6000) + ++m_nExplosionsSinceLastReward; + else + m_nExplosionsSinceLastReward = 1; + + m_nPreviousTimeRewardedForExplosion = CTimer::GetTimeInMilliseconds(); + int award = wreckedCar->pHandling->nMonetaryValue * 0.002f; + sprintf(gString, "$%d", award); +#ifdef MONEY_MESSAGES + // This line is a leftover from PS2, I don't know what it was meant to be. + // CVector sth(TheCamera.GetPosition() * 4.0f); + + CMoneyMessages::RegisterOne(wreckedCar->GetPosition() + CVector(0.0f, 0.0f, 2.0f), gString, 0, 255, 0, 2.0f, 0.5f); +#endif + CWorld::Players[CWorld::PlayerInFocus].m_nMoney += award; + + for (int i = m_nExplosionsSinceLastReward; i > 1; --i) { + CGeneral::GetRandomNumber(); + CWorld::Players[CWorld::PlayerInFocus].m_nMoney += award; + } +} + +void +CPlayerInfo::SavePlayerInfo(uint8 *buf, uint32 *size) +{ + // Interesting + *size = sizeof(CPlayerInfo); + +INITSAVEBUF + WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney); + WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState); + WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime); + WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier); + WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity); + WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney); + WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages); + WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages); + WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint); + WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bFastReload); + WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree); + WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree); + for (int i = 0; i < sizeof(CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName); i++) { + WriteSaveBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName[i]); + } +// Save struct is different +// VALIDATESAVEBUF(*size) +} + +void +CPlayerInfo::LoadPlayerInfo(uint8 *buf, uint32 size) +{ +INITSAVEBUF + CWorld::Players[CWorld::PlayerInFocus].m_nMoney = ReadSaveBuf(buf); + CWorld::Players[CWorld::PlayerInFocus].m_WBState = ReadSaveBuf(buf); + CWorld::Players[CWorld::PlayerInFocus].m_nWBTime = ReadSaveBuf(buf); + CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier = ReadSaveBuf(buf); + CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity = ReadSaveBuf(buf); + CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney = ReadSaveBuf(buf); + CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages = ReadSaveBuf(buf); + CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages = ReadSaveBuf(buf); + CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint = ReadSaveBuf(buf); + CWorld::Players[CWorld::PlayerInFocus].m_bFastReload = ReadSaveBuf(buf); + CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfJailFree = ReadSaveBuf(buf); + CWorld::Players[CWorld::PlayerInFocus].m_bGetOutOfHospitalFree = ReadSaveBuf(buf); + for (int i = 0; i < sizeof(CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName); i++) { + CWorld::Players[CWorld::PlayerInFocus].m_aPlayerName[i] = ReadSaveBuf(buf); + } +// Save struct is different +// VALIDATESAVEBUF(size) +} + STARTPATCHES -InjectHook(0x4A1700, &CPlayerInfo::LoadPlayerSkin, PATCH_JUMP); -InjectHook(0x4A1750, &CPlayerInfo::DeletePlayerSkin, PATCH_JUMP); -InjectHook(0x4A12E0, &CPlayerInfo::KillPlayer, PATCH_JUMP); -InjectHook(0x4A1330, &CPlayerInfo::ArrestPlayer, PATCH_JUMP); + InjectHook(0x4B5DC0, &CPlayerInfo::dtor, PATCH_JUMP); + InjectHook(0x4A1700, &CPlayerInfo::LoadPlayerSkin, PATCH_JUMP); + InjectHook(0x4A1750, &CPlayerInfo::DeletePlayerSkin, PATCH_JUMP); + InjectHook(0x4A12E0, &CPlayerInfo::KillPlayer, PATCH_JUMP); + InjectHook(0x4A1330, &CPlayerInfo::ArrestPlayer, PATCH_JUMP); + InjectHook(0x49FC10, &CPlayerInfo::Clear, PATCH_JUMP); + InjectHook(0x4A15C0, &CPlayerInfo::BlowUpRCBuggy, PATCH_JUMP); + InjectHook(0x4A13B0, &CPlayerInfo::CancelPlayerEnteringCars, PATCH_JUMP); + InjectHook(0x4A1400, &CPlayerInfo::MakePlayerSafe, PATCH_JUMP); + InjectHook(0x4A0EC0, &CPlayerInfo::EvaluateCarPosition, PATCH_JUMP); + InjectHook(0x4A15F0, &CPlayerInfo::AwardMoneyForExplosion, PATCH_JUMP); + InjectHook(0x4A0B20, &CPlayerInfo::LoadPlayerInfo, PATCH_JUMP); + InjectHook(0x4A0960, &CPlayerInfo::SavePlayerInfo, PATCH_JUMP); ENDPATCHES diff --git a/src/core/PlayerInfo.h b/src/core/PlayerInfo.h index 12c71766..28881796 100644 --- a/src/core/PlayerInfo.h +++ b/src/core/PlayerInfo.h @@ -10,6 +10,8 @@ enum eWastedBustedState WBSTATE_FAILED_CRITICAL_MISSION, }; +class CEntity; +class CPed; class CVehicle; class CPlayerPed; class CCivilianPed; @@ -40,7 +42,7 @@ public: int8 field_217; int8 field_218; int8 field_219; - int32 m_nWBTime; + uint32 m_nWBTime; bool m_bInRemoteMode; int8 field_225; int8 field_226; @@ -77,6 +79,17 @@ public: void ArrestPlayer(void); bool IsPlayerInRemoteMode(void); void PlayerFailedCriticalMission(void); + void Clear(void); + void BlowUpRCBuggy(void); + void CancelPlayerEnteringCars(CVehicle*); + bool IsRestartingAfterDeath(void); + bool IsRestartingAfterArrest(void); + void EvaluateCarPosition(CEntity*, CPed*, float, float*, CVehicle**); + void LoadPlayerInfo(uint8 *buf, uint32 size); + void SavePlayerInfo(uint8 *buf, uint32* size); + + ~CPlayerInfo() { }; + void dtor(void) { this->CPlayerInfo::~CPlayerInfo(); } }; static_assert(sizeof(CPlayerInfo) == 0x13C, "CPlayerInfo: error"); diff --git a/src/core/Radar.cpp b/src/core/Radar.cpp index f06e5317..ab7de13e 100644 --- a/src/core/Radar.cpp +++ b/src/core/Radar.cpp @@ -312,7 +312,7 @@ void CRadar::DrawBlips() break; case BLIP_CHAR: blipEntity = CPools::GetPedPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle); - if (blipEntity && ((CPed*)blipEntity)->bInVehicle && ((CPed*)blipEntity)->m_pMyVehicle) { + if (blipEntity && ((CPed*)blipEntity)->InVehicle()) { blipEntity = ((CPed*)blipEntity)->m_pMyVehicle; } break; @@ -415,7 +415,7 @@ void CRadar::DrawBlips() break; case BLIP_CHAR: blipEntity = CPools::GetPedPool()->GetAt(ms_RadarTrace[blipId].m_nEntityHandle); - if (blipEntity && ((CPed*)blipEntity)->bInVehicle && ((CPed*)blipEntity)->m_pMyVehicle) { + if (blipEntity && ((CPed*)blipEntity)->InVehicle()) { blipEntity = ((CPed*)blipEntity)->m_pMyVehicle; } break; diff --git a/src/core/World.cpp b/src/core/World.cpp index ae0d67cc..dac64970 100644 --- a/src/core/World.cpp +++ b/src/core/World.cpp @@ -859,8 +859,8 @@ FindPlayerPed(void) CVehicle* FindPlayerVehicle(void) { - CPlayerPed *ped = CWorld::Players[CWorld::PlayerInFocus].m_pPed; - if(ped->bInVehicle && ped->m_pMyVehicle) + CPlayerPed *ped = FindPlayerPed(); + if(ped->InVehicle()) return ped->m_pMyVehicle; else return nil; @@ -878,8 +878,8 @@ FindPlayerTrain(void) CEntity* FindPlayerEntity(void) { - CPlayerPed *ped = CWorld::Players[CWorld::PlayerInFocus].m_pPed; - if(ped->bInVehicle && ped->m_pMyVehicle) + CPlayerPed *ped = FindPlayerPed(); + if(ped->InVehicle()) return ped->m_pMyVehicle; else return ped; @@ -888,8 +888,8 @@ FindPlayerEntity(void) CVector FindPlayerCoors(void) { - CPlayerPed *ped = CWorld::Players[CWorld::PlayerInFocus].m_pPed; - if(ped->bInVehicle && ped->m_pMyVehicle) + CPlayerPed *ped = FindPlayerPed(); + if(ped->InVehicle()) return ped->m_pMyVehicle->GetPosition(); else return ped->GetPosition(); @@ -898,8 +898,8 @@ FindPlayerCoors(void) CVector& FindPlayerSpeed(void) { - CPlayerPed *ped = CWorld::Players[CWorld::PlayerInFocus].m_pPed; - if(ped->bInVehicle && ped->m_pMyVehicle) + CPlayerPed *ped = FindPlayerPed(); + if(ped->InVehicle()) return ped->m_pMyVehicle->m_vecMoveSpeed; else return ped->m_vecMoveSpeed; @@ -926,7 +926,7 @@ FindPlayerCentreOfWorld_NoSniperShift(void) return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetPosition(); if(FindPlayerVehicle()) return FindPlayerVehicle()->GetPosition(); - return CWorld::Players[CWorld::PlayerInFocus].m_pPed->GetPosition(); + return FindPlayerPed()->GetPosition(); } float @@ -936,7 +936,7 @@ FindPlayerHeading(void) return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetForward().Heading(); if(FindPlayerVehicle()) return FindPlayerVehicle()->GetForward().Heading(); - return CWorld::Players[CWorld::PlayerInFocus].m_pPed->GetForward().Heading(); + return FindPlayerPed()->GetForward().Heading(); } void @@ -1011,6 +1011,30 @@ CWorld::StopAllLawEnforcersInTheirTracks(void) } } +void +CWorld::SetAllCarsCanBeDamaged(bool toggle) +{ + int poolSize = CPools::GetVehiclePool()->GetSize(); + for (int poolIndex = 0; poolIndex < poolSize; poolIndex++) { + CVehicle *veh = CPools::GetVehiclePool()->GetSlot(poolIndex); + if (veh) + veh->bCanBeDamaged = toggle; + } +} + +void +CWorld::ExtinguishAllCarFiresInArea(CVector point, float range) +{ + int poolSize = CPools::GetVehiclePool()->GetSize(); + for (int poolIndex = 0; poolIndex < poolSize; poolIndex++) { + CVehicle* veh = CPools::GetVehiclePool()->GetSlot(poolIndex); + if (veh) { + if ((point - veh->GetPosition()).MagnitudeSqr() < sq(range)) + veh->ExtinguishCarFire(); + } + } +} + void CWorld::Process(void) { @@ -1212,5 +1236,9 @@ STARTPATCHES InjectHook(0x4B3AE0, CWorld::FindGroundZFor3DCoord, PATCH_JUMP); InjectHook(0x4B3B50, CWorld::FindRoofZFor3DCoord, PATCH_JUMP); + InjectHook(0x4B5BC0, CWorld::StopAllLawEnforcersInTheirTracks, PATCH_JUMP); + InjectHook(0x4B53F0, CWorld::SetAllCarsCanBeDamaged, PATCH_JUMP); + InjectHook(0x4B5460, CWorld::ExtinguishAllCarFiresInArea, PATCH_JUMP); + InjectHook(0x4B1A60, CWorld::Process, PATCH_JUMP); ENDPATCHES diff --git a/src/core/World.h b/src/core/World.h index 3b04403e..119c6324 100644 --- a/src/core/World.h +++ b/src/core/World.h @@ -121,6 +121,8 @@ public: static void RemoveFallenCars(); static void StopAllLawEnforcersInTheirTracks(); + static void SetAllCarsCanBeDamaged(bool); + static void ExtinguishAllCarFiresInArea(CVector, float); static void Initialise(); static void ShutDown(); -- cgit v1.2.3