summaryrefslogtreecommitdiff
path: root/src/control/Garages.h
blob: 3f471555923e20c0a30b7a54e637b582b2a786eb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
#pragma once
#include "Automobile.h"
#include "audio_enums.h"
#include "Camera.h"
#include "config.h"

class CVehicle;

enum eGarageState : int8
{
	GS_FULLYCLOSED,
	GS_OPENED,
	GS_CLOSING,
	GS_OPENING,
	GS_OPENEDCONTAINSCAR,
	GS_CLOSEDCONTAINSCAR,
	GS_AFTERDROPOFF,
};

enum eGarageType : int8
{
	GARAGE_NONE,
	GARAGE_MISSION,
	GARAGE_BOMBSHOP1,
	GARAGE_BOMBSHOP2,
	GARAGE_BOMBSHOP3,
	GARAGE_RESPRAY,
	GARAGE_COLLECTORSITEMS,
	GARAGE_COLLECTSPECIFICCARS,
	GARAGE_COLLECTCARS_1,
	GARAGE_COLLECTCARS_2,
	GARAGE_COLLECTCARS_3,
	GARAGE_FORCARTOCOMEOUTOF,
	GARAGE_60SECONDS,
	GARAGE_CRUSHER,
	GARAGE_MISSION_KEEPCAR,
	GARAGE_FOR_SCRIPT_TO_OPEN,
	GARAGE_HIDEOUT_ONE,
	GARAGE_HIDEOUT_TWO,
	GARAGE_HIDEOUT_THREE,
	GARAGE_FOR_SCRIPT_TO_OPEN_AND_CLOSE,
	GARAGE_KEEPS_OPENING_FOR_SPECIFIC_CAR,
	GARAGE_MISSION_KEEPCAR_REMAINCLOSED,
};

enum
{
	TOTAL_COLLECTCARS_GARAGES = GARAGE_COLLECTCARS_3 - GARAGE_COLLECTCARS_1 + 1,
	TOTAL_COLLECTCARS_CARS = 16
};

class CStoredCar
{
	int32 m_nModelIndex;
	CVector m_vecPos;
	CVector m_vecAngle;
	int32 m_bBulletproof : 1;
	int32 m_bFireproof : 1;
	int32 m_bExplosionproof : 1;
	int32 m_bCollisionproof : 1;
	int32 m_bMeleeproof : 1;
	int8 m_nPrimaryColor;
	int8 m_nSecondaryColor;
	int8 m_nRadioStation;
	int8 m_nVariationA;
	int8 m_nVariationB;
	int8 m_nCarBombType;
public:
	void Init() { m_nModelIndex = 0; }
	void Clear() { m_nModelIndex = 0; }
	bool HasCar() { return m_nModelIndex != 0; }
	CStoredCar(const CStoredCar& other);
	void StoreCar(CVehicle*);
	CVehicle* RestoreCar();
};

static_assert(sizeof(CStoredCar) == 0x28, "CStoredCar");

#define SWITCH_GARAGE_DISTANCE_CLOSE 40.0f

class CGarage
{
	eGarageType m_eGarageType;
	eGarageState m_eGarageState;
	bool field_2; // unused
	bool m_bClosingWithoutTargetCar;
	bool m_bDeactivated;
	bool m_bResprayHappened;
	int m_nTargetModelIndex;
	CEntity *m_pDoor1;
	CEntity *m_pDoor2;
	uint8 m_bDoor1PoolIndex;
	uint8 m_bDoor2PoolIndex;
	bool m_bDoor1IsDummy;
	bool m_bDoor2IsDummy;
	bool m_bRecreateDoorOnNextRefresh;
	bool m_bRotatedDoor;
	bool m_bCameraFollowsPlayer;
	float m_fX1;
	float m_fX2;
	float m_fY1;
	float m_fY2;
	float m_fZ1;
	float m_fZ2;
	float m_fDoorPos;
	float m_fDoorHeight;
	float m_fDoor1X;
	float m_fDoor1Y;
	float m_fDoor2X;
	float m_fDoor2Y;
	float m_fDoor1Z;
	float m_fDoor2Z;
	uint32 m_nTimeToStartAction;
	uint8 m_bCollectedCarsState;
	CVehicle *m_pTarget;
	void* field_96; // unused
	CStoredCar m_sStoredCar; // not needed

	void OpenThisGarage();
	void CloseThisGarage();
	bool IsOpen() { return m_eGarageState == GS_OPENED || m_eGarageState == GS_OPENEDCONTAINSCAR; }
	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 IsFar()
	{ 
#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);
	bool 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();

	friend class CGarages;
	friend class cAudioManager;
};

static_assert(sizeof(CGarage) == 140, "CGarage");

class CGarages
{
	enum {
		MESSAGE_LENGTH = 8
	};
	static int32 &BankVansCollected;
	static bool &BombsAreFree;
	static bool &RespraysAreFree;
	static int32 &CarsCollected;
	static int32 (&CarTypesCollected)[TOTAL_COLLECTCARS_GARAGES];
	static int32 &CrushedCarId;
	static uint32 &LastTimeHelpMessage;
	static int32 &MessageNumberInString;
	static char(&MessageIDString)[MESSAGE_LENGTH];
	static int32 &MessageNumberInString2;
	static uint32 &MessageStartTime;
	static uint32 &MessageEndTime;
	static uint32 &NumGarages;
	static bool &PlayerInGarage;
	static int32 &PoliceCarsCollected;
	static uint32 &GarageToBeTidied;
	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:
	static void Init(void);
#ifndef PS2
	static void Shutdown(void);
#endif
	static void Update(void);

	static int16 AddOne(float X1, float Y1, float Z1, float X2, float Y2, float Z2, eGarageType type, int32 targetId);
	static void ChangeGarageType(int16, eGarageType, int32);
	static void PrintMessages(void);
	static void TriggerMessage(const char* text, int16, uint16 time, int16);
	static void SetTargetCarForMissonGarage(int16, CVehicle*);
	static bool HasCarBeenDroppedOffYet(int16);
	static void DeActivateGarage(int16);
	static void ActivateGarage(int16);
	static int32 QueryCarsCollected(int16);
	static bool HasImportExportGarageCollectedThisCar(int16, int8);
	static bool IsGarageOpen(int16);
	static bool IsGarageClosed(int16);
	static bool HasThisCarBeenCollected(int16, uint8);
	static void OpenGarage(int16 garage) { aGarages[garage].OpenThisGarage(); }
	static void CloseGarage(int16 garage) { aGarages[garage].CloseThisGarage(); }
	static bool HasResprayHappened(int16);
	static void SetGarageDoorToRotate(int16);
	static void SetLeaveCameraForThisGarage(int16);
	static bool IsThisCarWithinGarageArea(int16, CEntity*);
	static bool HasCarBeenCrushed(int32);
	static bool IsPointInAGarageCameraZone(CVector);
	static bool CameraShouldBeOutside(void);
	static void GivePlayerDetonator(void);
	static void PlayerArrestedOrDied(void);
	static bool IsPointWithinHideOutGarage(CVector&);
	static bool IsPointWithinAnyGarage(CVector&);
	static void SetAllDoorsBackToOriginalHeight(void);
	static void Save(uint8* buf, uint32* size);
	static void Load(uint8* buf, uint32 size);
	static bool IsModelIndexADoor(uint32 id);
	static void SetFreeBombs(bool bValue) { BombsAreFree = bValue; }
	static void SetFreeResprays(bool bValue) { RespraysAreFree = bValue; }

private:
	static bool IsCarSprayable(CVehicle*);
	static float FindDoorHeightForMI(int32);
	static void CloseHideOutGaragesBeforeSave(void);
	static int32 CountCarsInHideoutGarage(eGarageType);
	static int32 FindMaxNumStoredCarsForGarage(eGarageType);
	static int32 GetBombTypeForGarageType(eGarageType type) { return type - GARAGE_BOMBSHOP1 + 1; }
	static int32 GetCarsCollectedIndexForGarageType(eGarageType type) { return type - GARAGE_COLLECTCARS_1; }

	friend class cAudioManager;
	friend class CGarage;
};