Merge pull request #366 from Nick007J/master

Garage part 1
This commit is contained in:
aap 2020-03-29 19:12:53 +02:00 committed by GitHub
commit 8e3ee096e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 1483 additions and 152 deletions

View File

@ -3938,7 +3938,7 @@ cAudioManager::ProcessFrontEnd()
break; break;
case SOUND_GARAGE_NO_MONEY: case SOUND_GARAGE_NO_MONEY:
case SOUND_GARAGE_BAD_VEHICLE: case SOUND_GARAGE_BAD_VEHICLE:
case SOUND_3C: case SOUND_GARAGE_BOMB_ALREADY_SET:
m_sQueueSample.m_nSampleIndex = SFX_PICKUP_ERROR_LEFT; m_sQueueSample.m_nSampleIndex = SFX_PICKUP_ERROR_LEFT;
stereo = true; stereo = true;
break; break;
@ -4095,7 +4095,7 @@ cAudioManager::ProcessGarages()
CalculateDistance(distCalculated, distSquared); \ CalculateDistance(distCalculated, distSquared); \
m_sQueueSample.m_bVolume = ComputeVolume(60, 80.f, m_sQueueSample.m_fDistance); \ m_sQueueSample.m_bVolume = ComputeVolume(60, 80.f, m_sQueueSample.m_fDistance); \
if(m_sQueueSample.m_bVolume) { \ if(m_sQueueSample.m_bVolume) { \
if(CGarages::Garages[i].m_eGarageType == GARAGE_CRUSHER) { \ if(CGarages::aGarages[i].m_eGarageType == GARAGE_CRUSHER) { \
m_sQueueSample.m_nSampleIndex = SFX_COL_CAR_PANEL_2; \ m_sQueueSample.m_nSampleIndex = SFX_COL_CAR_PANEL_2; \
m_sQueueSample.m_nFrequency = 6735; \ m_sQueueSample.m_nFrequency = 6735; \
} else if(m_asAudioEntities[m_sQueueSample.m_nEntityIndex] \ } else if(m_asAudioEntities[m_sQueueSample.m_nEntityIndex] \
@ -4131,20 +4131,20 @@ cAudioManager::ProcessGarages()
} }
for(uint32 i = 0; i < CGarages::NumGarages; ++i) { for(uint32 i = 0; i < CGarages::NumGarages; ++i) {
if(CGarages::Garages[i].m_eGarageType == GARAGE_NONE) continue; if(CGarages::aGarages[i].m_eGarageType == GARAGE_NONE) continue;
entity = CGarages::Garages[i].m_pDoor1; entity = CGarages::aGarages[i].m_pDoor1;
if(!entity) continue; if(!entity) continue;
m_sQueueSample.m_vecPos = entity->GetPosition(); m_sQueueSample.m_vecPos = entity->GetPosition();
distCalculated = false; distCalculated = false;
distSquared = GetDistanceSquared(&m_sQueueSample.m_vecPos); distSquared = GetDistanceSquared(&m_sQueueSample.m_vecPos);
if(distSquared < 6400.f) { if(distSquared < 6400.f) {
state = CGarages::Garages[i].m_eGarageState; state = CGarages::aGarages[i].m_eGarageState;
if(state == GS_OPENING || state == GS_CLOSING || state == GS_AFTERDROPOFF) { if(state == GS_OPENING || state == GS_CLOSING || state == GS_AFTERDROPOFF) {
CalculateDistance(distCalculated, distSquared); CalculateDistance(distCalculated, distSquared);
m_sQueueSample.m_bVolume = ComputeVolume(90, 80.f, m_sQueueSample.m_fDistance); m_sQueueSample.m_bVolume = ComputeVolume(90, 80.f, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_bVolume) { if(m_sQueueSample.m_bVolume) {
if(CGarages::Garages[i].m_eGarageType == GARAGE_CRUSHER) { if(CGarages::aGarages[i].m_eGarageType == GARAGE_CRUSHER) {
if(CGarages::Garages[i].m_eGarageState == GS_AFTERDROPOFF) { if(CGarages::aGarages[i].m_eGarageState == GS_AFTERDROPOFF) {
if(!(m_FrameCounter & 1)) { if(!(m_FrameCounter & 1)) {
LOOP_HELPER LOOP_HELPER
continue; continue;

View File

@ -64,7 +64,7 @@ enum eSound : int16
SOUND_GARAGE_NO_MONEY = 57, SOUND_GARAGE_NO_MONEY = 57,
SOUND_GARAGE_BAD_VEHICLE = 58, SOUND_GARAGE_BAD_VEHICLE = 58,
SOUND_GARAGE_OPENING = 59, SOUND_GARAGE_OPENING = 59,
SOUND_3C = 60, SOUND_GARAGE_BOMB_ALREADY_SET = 60,
SOUND_GARAGE_BOMB1_SET = 61, SOUND_GARAGE_BOMB1_SET = 61,
SOUND_GARAGE_BOMB2_SET = 62, SOUND_GARAGE_BOMB2_SET = 62,
SOUND_GARAGE_BOMB3_SET = 63, SOUND_GARAGE_BOMB3_SET = 63,

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "Automobile.h" #include "Automobile.h"
#include "audio_enums.h" #include "audio_enums.h"
#include "Camera.h"
#include "config.h" #include "config.h"
class CVehicle; class CVehicle;
@ -63,34 +64,42 @@ class CStoredCar
int8 m_nVariationA; int8 m_nVariationA;
int8 m_nVariationB; int8 m_nVariationB;
int8 m_nCarBombType; int8 m_nCarBombType;
public:
void Init() { m_nModelIndex = 0; }
CStoredCar(const CStoredCar& other);
void StoreCar(CVehicle*);
CVehicle* RestoreCar();
}; };
static_assert(sizeof(CStoredCar) == 0x28, "CStoredCar"); static_assert(sizeof(CStoredCar) == 0x28, "CStoredCar");
#define SWITCH_GARAGE_DISTANCE_CLOSE 40.0f
class CGarage class CGarage
{ {
public: public:
eGarageType m_eGarageType; eGarageType m_eGarageType;
eGarageState m_eGarageState; eGarageState m_eGarageState;
char field_2; char field_2;
char m_bClosingWithoutTargetCar; bool m_bClosingWithoutTargetCar;
char m_bDeactivated; bool m_bDeactivated;
char m_bResprayHappened; bool m_bResprayHappened;
char field_6;
char field_7;
int m_nTargetModelIndex; int m_nTargetModelIndex;
CEntity *m_pDoor1; CEntity *m_pDoor1;
CEntity *m_pDoor2; CEntity *m_pDoor2;
char m_bDoor1PoolIndex; uint8 m_bDoor1PoolIndex;
char m_bDoor2PoolIndex; uint8 m_bDoor2PoolIndex;
char m_bIsDoor1Object; bool m_bDoor1IsDummy;
char m_bIsDoor2Object; bool m_bDoor2IsDummy;
char field_24; bool m_bRecreateDoorOnNextRefresh;
char m_bRotatedDoor; bool m_bRotatedDoor;
char m_bCameraFollowsPlayer; bool m_bCameraFollowsPlayer;
char field_27; float m_fX1;
CVector m_vecInf; float m_fX2;
CVector m_vecSup; float m_fY1;
float m_fY2;
float m_fZ1;
float m_fZ2;
float m_fDoorPos; float m_fDoorPos;
float m_fDoorHeight; float m_fDoorHeight;
float m_fDoor1X; float m_fDoor1X;
@ -99,7 +108,7 @@ public:
float m_fDoor2Y; float m_fDoor2Y;
float m_fDoor1Z; float m_fDoor1Z;
float m_fDoor2Z; float m_fDoor2Z;
int m_nDoorOpenTime; uint32 m_nTimeToStartAction;
char m_bCollectedCarsState; char m_bCollectedCarsState;
char field_89; char field_89;
char field_90; char field_90;
@ -112,6 +121,51 @@ public:
void CloseThisGarage(); void CloseThisGarage();
bool IsOpen() { return m_eGarageState == GS_OPENED || m_eGarageState == GS_OPENEDCONTAINSCAR; } bool IsOpen() { return m_eGarageState == GS_OPENED || m_eGarageState == GS_OPENEDCONTAINSCAR; }
bool IsClosed() { return m_eGarageState == GS_FULLYCLOSED; } bool IsClosed() { return m_eGarageState == GS_FULLYCLOSED; }
bool IsUsed() { return m_eGarageType != GARAGE_NONE; }
void Update();
float GetGarageCenterX() { return (m_fX1 + m_fX2) / 2; }
float GetGarageCenterY() { return (m_fY1 + m_fY2) / 2; }
bool IsClose()
{
#ifdef FIX_BUGS
return Abs(TheCamera.GetPosition().x - GetGarageCenterX()) > SWITCH_GARAGE_DISTANCE_CLOSE ||
Abs(TheCamera.GetPosition().y - GetGarageCenterY()) > SWITCH_GARAGE_DISTANCE_CLOSE;
#else
return Abs(TheCamera.GetPosition().x - m_fX1) > SWITCH_GARAGE_DISTANCE_CLOSE ||
Abs(TheCamera.GetPosition().y - m_fY1) > SWITCH_GARAGE_DISTANCE_CLOSE;
#endif
}
void TidyUpGarageClose();
void TidyUpGarage();
void RefreshDoorPointers(bool);
void UpdateCrusherAngle();
void UpdateDoorsHeight();
bool IsEntityEntirelyInside3D(CEntity*, float);
bool IsEntityEntirelyOutside(CEntity*, float);
bool IsEntityEntirelyInside(CEntity*);
float CalcDistToGarageRectangleSquared(float, float);
float CalcSmallestDistToGarageDoorSquared(float, float);
bool IsAnyOtherCarTouchingGarage(CVehicle* pException);
bool IsStaticPlayerCarEntirelyInside();
bool IsPlayerOutsideGarage();
bool IsAnyCarBlockingDoor();
void CenterCarInGarage(CVehicle*);
bool DoesCraigNeedThisCar(int32);
void MarkThisCarAsCollectedForCraig(int32);
bool HasCraigCollectedThisCar(int32);
bool IsGarageEmpty();
void UpdateCrusherShake(float, float);
int32 CountCarsWithCenterPointWithinGarage(CEntity* pException);
void RemoveCarsBlockingDoorNotInside();
void StoreAndRemoveCarsForThisHideout(CStoredCar*, int32);
bool RestoreCarsForThisHideout(CStoredCar*);
bool IsEntityTouching3D(CEntity*);
bool EntityHasASphereWayOutsideGarage(CEntity*, float);
bool IsAnyOtherPedTouchingGarage(CPed* pException);
void BuildRotatedDoorMatrix(CEntity*, float);
void FindDoorsEntities();
void FindDoorsEntitiesSectorList(CPtrList&, bool);
void PlayerArrestedOrDied();
}; };
static_assert(sizeof(CGarage) == 140, "CGarage"); static_assert(sizeof(CGarage) == 140, "CGarage");
@ -135,9 +189,19 @@ public:
static bool &PlayerInGarage; static bool &PlayerInGarage;
static int32 &PoliceCarsCollected; static int32 &PoliceCarsCollected;
static uint32 &GarageToBeTidied; static uint32 &GarageToBeTidied;
static CGarage(&Garages)[NUM_GARAGES]; static CGarage(&aGarages)[NUM_GARAGES];
static CStoredCar(&aCarsInSafeHouse1)[NUM_GARAGE_STORED_CARS];
static CStoredCar(&aCarsInSafeHouse2)[NUM_GARAGE_STORED_CARS];
static CStoredCar(&aCarsInSafeHouse3)[NUM_GARAGE_STORED_CARS];
static int32 &AudioEntity;
static bool &bCamShouldBeOutisde;
public: public:
static void Init(void);
#ifndef PS2
static void Shutdown(void);
#endif
static int16 AddOne(float X1, float Y1, float Z1, float X2, float Y2, float Z2, eGarageType type, int32 targetId);
static bool IsModelIndexADoor(uint32 id); static bool IsModelIndexADoor(uint32 id);
static void TriggerMessage(const char *text, int16, uint16 time, int16); static void TriggerMessage(const char *text, int16, uint16 time, int16);
static void PrintMessages(void); static void PrintMessages(void);
@ -145,12 +209,10 @@ public:
static bool IsPointWithinHideOutGarage(CVector&); static bool IsPointWithinHideOutGarage(CVector&);
static bool IsPointWithinAnyGarage(CVector&); static bool IsPointWithinAnyGarage(CVector&);
static void PlayerArrestedOrDied(); static void PlayerArrestedOrDied();
static void Init(void);
static void Shutdown(void);
static void Update(void); static void Update(void);
static void Load(uint8 *buf, uint32 size); static void Load(uint8 *buf, uint32 size);
static void Save(uint8 *buf, uint32 *size); static void Save(uint8 *buf, uint32 *size);
static int16 AddOne(float, float, float, float, float, float, uint8, uint32);
static void SetTargetCarForMissonGarage(int16, CVehicle*); static void SetTargetCarForMissonGarage(int16, CVehicle*);
static bool HasCarBeenDroppedOffYet(int16); static bool HasCarBeenDroppedOffYet(int16);
static void ActivateGarage(int16); static void ActivateGarage(int16);
@ -166,8 +228,17 @@ public:
static bool HasImportExportGarageCollectedThisCar(int16, int8); static bool HasImportExportGarageCollectedThisCar(int16, int8);
static void SetLeaveCameraForThisGarage(int16); static void SetLeaveCameraForThisGarage(int16);
static bool IsThisCarWithinGarageArea(int16, CEntity*); static bool IsThisCarWithinGarageArea(int16, CEntity*);
static bool IsCarSprayable(CVehicle*);
static int32 FindMaxNumStoredCarsForGarage(eGarageType);
static int32 CountCarsInHideoutGarage(eGarageType);
static bool IsPointInAGarageCameraZone(CVector);
static bool CameraShouldBeOutside();
static void CloseHideOutGaragesBeforeSave();
static void SetAllDoorsBackToOriginalHeight();
static int GetBombTypeForGarageType(eGarageType type) { return type - GARAGE_BOMBSHOP1 + 1; }
static int GetCarsCollectedIndexForGarageType(eGarageType type) { return type - GARAGE_COLLECTCARS_1; } static int GetCarsCollectedIndexForGarageType(eGarageType type) { return type - GARAGE_COLLECTCARS_1; }
static void SetAllDoorsBackToOriginalHeight(); private:
static float FindDoorHeightForMI(int32);
}; };

View File

@ -4622,7 +4622,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
infZ = *(float*)&ScriptParams[5]; infZ = *(float*)&ScriptParams[5];
supZ = *(float*)&ScriptParams[2]; supZ = *(float*)&ScriptParams[2];
} }
ScriptParams[0] = CGarages::AddOne(infX, infY, infZ, supX, supY, supZ, ScriptParams[6], 0); ScriptParams[0] = CGarages::AddOne(infX, infY, infZ, supX, supY, supZ, (eGarageType)ScriptParams[6], 0);
StoreParameters(&m_nIp, 1); StoreParameters(&m_nIp, 1);
return 0; return 0;
} }
@ -4647,7 +4647,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
infZ = *(float*)&ScriptParams[5]; infZ = *(float*)&ScriptParams[5];
supZ = *(float*)&ScriptParams[2]; supZ = *(float*)&ScriptParams[2];
} }
ScriptParams[0] = CGarages::AddOne(infX, infY, infZ, supX, supY, supZ, ScriptParams[6], ScriptParams[7]); ScriptParams[0] = CGarages::AddOne(infX, infY, infZ, supX, supY, supZ, (eGarageType)ScriptParams[6], ScriptParams[7]);
StoreParameters(&m_nIp, 1); StoreParameters(&m_nIp, 1);
return 0; return 0;
} }
@ -7110,13 +7110,13 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
case COMMAND_OPEN_GARAGE: case COMMAND_OPEN_GARAGE:
{ {
CollectParameters(&m_nIp, 1); CollectParameters(&m_nIp, 1);
CGarages::Garages[ScriptParams[0]].OpenThisGarage(); CGarages::aGarages[ScriptParams[0]].OpenThisGarage();
return 0; return 0;
} }
case COMMAND_CLOSE_GARAGE: case COMMAND_CLOSE_GARAGE:
{ {
CollectParameters(&m_nIp, 1); CollectParameters(&m_nIp, 1);
CGarages::Garages[ScriptParams[0]].CloseThisGarage(); CGarages::aGarages[ScriptParams[0]].CloseThisGarage();
return 0; return 0;
} }
case COMMAND_WARP_CHAR_FROM_CAR_TO_COORD: case COMMAND_WARP_CHAR_FROM_CAR_TO_COORD:

View File

@ -394,7 +394,9 @@ bool CGame::ShutDown(void)
CPlane::Shutdown(); CPlane::Shutdown();
CTrain::Shutdown(); CTrain::Shutdown();
CSpecialFX::Shutdown(); CSpecialFX::Shutdown();
#ifndef PS2
CGarages::Shutdown(); CGarages::Shutdown();
#endif
CMovingThings::Shutdown(); CMovingThings::Shutdown();
gPhoneInfo.Shutdown(); gPhoneInfo.Shutdown();
CWeapon::ShutdownWeapons(); CWeapon::ShutdownWeapons();

View File

@ -4,7 +4,7 @@ enum {
PLAYERCONTROL_ENABLED = 0, PLAYERCONTROL_ENABLED = 0,
PLAYERCONTROL_DISABLED_1 = 1, PLAYERCONTROL_DISABLED_1 = 1,
PLAYERCONTROL_DISABLED_2 = 2, PLAYERCONTROL_DISABLED_2 = 2,
PLAYERCONTROL_DISABLED_4 = 4, PLAYERCONTROL_GARAGE = 4,
PLAYERCONTROL_DISABLED_8 = 8, PLAYERCONTROL_DISABLED_8 = 8,
PLAYERCONTROL_DISABLED_10 = 16, PLAYERCONTROL_DISABLED_10 = 16,
PLAYERCONTROL_DISABLED_20 = 32, // used on CPlayerInfo::MakePlayerSafe PLAYERCONTROL_DISABLED_20 = 32, // used on CPlayerInfo::MakePlayerSafe
@ -434,6 +434,9 @@ public:
int16 GetRightStickY(void) { return NewState.RightStickY; } int16 GetRightStickY(void) { return NewState.RightStickY; }
bool ArePlayerControlsDisabled(void) { return DisablePlayerControls != PLAYERCONTROL_ENABLED; } bool ArePlayerControlsDisabled(void) { return DisablePlayerControls != PLAYERCONTROL_ENABLED; }
void SetDisablePlayerControls(uint8 who) { DisablePlayerControls |= who; }
void SetEnablePlayerControls(uint8 who) { DisablePlayerControls &= ~who; }
bool IsPlayerControlsDisabledBy(uint8 who) { return DisablePlayerControls & who; }
}; };
VALIDATE_SIZE(CPad, 0xFC); VALIDATE_SIZE(CPad, 0xFC);

View File

@ -48,6 +48,8 @@ int32& CStats::LongestFlightInDodo = *(int32*)0x8F5FE4;
int32& CStats::TimeTakenDefuseMission = *(int32*)0x880E24; int32& CStats::TimeTakenDefuseMission = *(int32*)0x880E24;
int32& CStats::TotalNumberKillFrenzies = *(int32*)0x8E2884; int32& CStats::TotalNumberKillFrenzies = *(int32*)0x8E2884;
int32& CStats::TotalNumberMissions = *(int32*)0x8E2820; int32& CStats::TotalNumberMissions = *(int32*)0x8E2820;
int32& CStats::KgOfExplosivesUsed = *(int32*)0x8F2510;
int32& CStats::CarsCrushed = *(int32*)0x943050;
int32(&CStats::FastestTimes)[CStats::TOTAL_FASTEST_TIMES] = *(int32(*)[CStats::TOTAL_FASTEST_TIMES])*(uintptr*)0x6E9128; int32(&CStats::FastestTimes)[CStats::TOTAL_FASTEST_TIMES] = *(int32(*)[CStats::TOTAL_FASTEST_TIMES])*(uintptr*)0x6E9128;
int32(&CStats::HighestScores)[CStats::TOTAL_HIGHEST_SCORES] = *(int32(*)[CStats::TOTAL_HIGHEST_SCORES]) * (uintptr*)0x8622B0; int32(&CStats::HighestScores)[CStats::TOTAL_HIGHEST_SCORES] = *(int32(*)[CStats::TOTAL_HIGHEST_SCORES]) * (uintptr*)0x8622B0;

View File

@ -53,6 +53,8 @@ public:
static int32 &TotalNumberMissions; static int32 &TotalNumberMissions;
static int32(&FastestTimes)[TOTAL_FASTEST_TIMES]; static int32(&FastestTimes)[TOTAL_FASTEST_TIMES];
static int32(&HighestScores)[TOTAL_HIGHEST_SCORES]; static int32(&HighestScores)[TOTAL_HIGHEST_SCORES];
static int32 &KgOfExplosivesUsed;
static int32 &CarsCrushed;
public: public:
static void RegisterFastestTime(int32, int32); static void RegisterFastestTime(int32, int32);

View File

@ -55,6 +55,7 @@ WRAPPER void CWorld::FindObjectsOfTypeInRangeSectorList(uint32, CPtrList&, CVect
WRAPPER void CWorld::FindMissionEntitiesIntersectingCube(const CVector&, const CVector&, int16*, int16, CEntity**, bool, bool, bool) { EAXJMP(0x4B3680); } WRAPPER void CWorld::FindMissionEntitiesIntersectingCube(const CVector&, const CVector&, int16*, int16, CEntity**, bool, bool, bool) { EAXJMP(0x4B3680); }
WRAPPER void CWorld::ClearCarsFromArea(float, float, float, float, float, float) { EAXJMP(0x4B50E0); } WRAPPER void CWorld::ClearCarsFromArea(float, float, float, float, float, float) { EAXJMP(0x4B50E0); }
WRAPPER void CWorld::ClearPedsFromArea(float, float, float, float, float, float) { EAXJMP(0x4B52B0); } WRAPPER void CWorld::ClearPedsFromArea(float, float, float, float, float, float) { EAXJMP(0x4B52B0); }
WRAPPER void CWorld::CallOffChaseForArea(float, float, float, float) { EAXJMP(0x4B5530); }
void void
CWorld::Initialise() CWorld::Initialise()

View File

@ -115,6 +115,7 @@ public:
static void FindMissionEntitiesIntersectingCube(const CVector&, const CVector&, int16*, int16, CEntity**, bool, bool, bool); static void FindMissionEntitiesIntersectingCube(const CVector&, const CVector&, int16*, int16, CEntity**, bool, bool, bool);
static void ClearCarsFromArea(float, float, float, float, float, float); static void ClearCarsFromArea(float, float, float, float, float, float);
static void ClearPedsFromArea(float, float, float, float, float, float); static void ClearPedsFromArea(float, float, float, float, float, float);
static void CallOffChaseForArea(float, float, float, float);
static float GetSectorX(float f) { return ((f - WORLD_MIN_X)/SECTOR_SIZE_X); } static float GetSectorX(float f) { return ((f - WORLD_MIN_X)/SECTOR_SIZE_X); }
static float GetSectorY(float f) { return ((f - WORLD_MIN_Y)/SECTOR_SIZE_Y); } static float GetSectorY(float f) { return ((f - WORLD_MIN_Y)/SECTOR_SIZE_Y); }

View File

@ -117,6 +117,8 @@ enum Config {
NUM_AUDIO_REFLECTIONS = 5, NUM_AUDIO_REFLECTIONS = 5,
NUM_SCRIPT_MAX_ENTITIES = 40, NUM_SCRIPT_MAX_ENTITIES = 40,
NUM_GARAGE_STORED_CARS = 6
}; };
// We'll use this once we're ready to become independent of the game // We'll use this once we're ready to become independent of the game

View File

@ -1113,6 +1113,8 @@ public:
}; };
STARTPATCHES STARTPATCHES
InjectHook(0x427820, &CVehicleModelInfo::SetComponentsToUse, PATCH_JUMP);
InjectHook(0x51FDC0, &CVehicleModelInfo_::DeleteRwObject_, PATCH_JUMP); InjectHook(0x51FDC0, &CVehicleModelInfo_::DeleteRwObject_, PATCH_JUMP);
InjectHook(0x51FCB0, &CVehicleModelInfo_::CreateInstance_, PATCH_JUMP); InjectHook(0x51FCB0, &CVehicleModelInfo_::CreateInstance_, PATCH_JUMP);
InjectHook(0x51FC60, &CVehicleModelInfo_::SetClump_, PATCH_JUMP); InjectHook(0x51FC60, &CVehicleModelInfo_::SetClump_, PATCH_JUMP);

View File

@ -132,5 +132,6 @@ public:
static void ShutdownEnvironmentMaps(void); static void ShutdownEnvironmentMaps(void);
static int GetMaximumNumberOfPassengersFromNumberOfDoors(int id); static int GetMaximumNumberOfPassengersFromNumberOfDoors(int id);
static void SetComponentsToUse(int8 c1, int8 c2) { ms_compsToUse[0] = c1; ms_compsToUse[1] = c2; }
}; };
static_assert(sizeof(CVehicleModelInfo) == 0x1F8, "CVehicleModelInfo: error"); static_assert(sizeof(CVehicleModelInfo) == 0x1F8, "CVehicleModelInfo: error");

View File

@ -17,6 +17,7 @@
#include "DMAudio.h" #include "DMAudio.h"
#include "Radar.h" #include "Radar.h"
#include "Fire.h" #include "Fire.h"
#include "Darkel.h"
bool &CVehicle::bWheelsOnlyCheat = *(bool *)0x95CD78; bool &CVehicle::bWheelsOnlyCheat = *(bool *)0x95CD78;
bool &CVehicle::bAllDodosCheat = *(bool *)0x95CD75; bool &CVehicle::bAllDodosCheat = *(bool *)0x95CD75;
@ -765,6 +766,29 @@ CVehicle::IsSphereTouchingVehicle(float sx, float sy, float sz, float radius)
return true; return true;
} }
void
DestroyVehicleAndDriverAndPassengers(CVehicle* pVehicle)
{
if (pVehicle->pDriver) {
#ifndef FIX_BUGS
// this just isn't fair
CDarkel::RegisterKillByPlayer(pVehicle->pDriver, WEAPONTYPE_UNIDENTIFIED);
#endif
pVehicle->pDriver->FlagToDestroyWhenNextProcessed();
}
for (int i = 0; i < pVehicle->m_nNumMaxPassengers; i++) {
if (pVehicle->pPassengers[i]) {
#ifndef FIX_BUGS
// this just isn't fair
CDarkel::RegisterKillByPlayer(pVehicle->pPassengers[i], WEAPONTYPE_UNIDENTIFIED);
#endif
pVehicle->pPassengers[i]->FlagToDestroyWhenNextProcessed();
}
}
CWorld::Remove(pVehicle);
delete pVehicle;
}
class CVehicle_ : public CVehicle class CVehicle_ : public CVehicle
{ {

View File

@ -301,3 +301,5 @@ public:
}; };
static_assert(sizeof(cVehicleParams) == 0x18, "cVehicleParams: error"); static_assert(sizeof(cVehicleParams) == 0x18, "cVehicleParams: error");
void DestroyVehicleAndDriverAndPassengers(CVehicle* pVehicle);