finished garages
This commit is contained in:
parent
23c6a28324
commit
50b43b680e
@ -3,6 +3,9 @@
|
||||
#include "Garages.h"
|
||||
#include "main.h"
|
||||
|
||||
#ifdef FIX_BUGS
|
||||
#include "Boat.h"
|
||||
#endif
|
||||
#include "DMAudio.h"
|
||||
#include "General.h"
|
||||
#include "Font.h"
|
||||
@ -15,6 +18,7 @@
|
||||
#include "PlayerPed.h"
|
||||
#include "Replay.h"
|
||||
#include "Stats.h"
|
||||
#include "Streaming.h"
|
||||
#include "Text.h"
|
||||
#include "Timer.h"
|
||||
#include "Vehicle.h"
|
||||
@ -53,6 +57,8 @@
|
||||
#define DISTANCE_TO_OPEN_HIDEOUT_GARAGE_IN_CAR (10.0f)
|
||||
#define DISTANCE_TO_SHOW_HIDEOUT_MESSAGE (5.0f)
|
||||
|
||||
#define DISTANCE_TO_CONSIDER_DOOR_FOR_GARAGE (20.0f)
|
||||
|
||||
// Time
|
||||
#define TIME_TO_RESPRAY (2000)
|
||||
#define TIME_TO_SETUP_BOMB (2000)
|
||||
@ -62,6 +68,7 @@
|
||||
// Respray stuff
|
||||
#define FREE_RESPRAY_HEALTH_THRESHOLD (970.0f)
|
||||
#define NUM_PARTICLES_IN_RESPRAY (200)
|
||||
#define RESPRAY_CENTERING_COEFFICIENT (0.75f)
|
||||
|
||||
// Bomb stuff
|
||||
#define KGS_OF_EXPLOSIVES_IN_BOMB (10)
|
||||
@ -87,9 +94,16 @@
|
||||
#define MAX_STORED_CARS_IN_INDUSTRIAL (1)
|
||||
#define MAX_STORED_CARS_IN_COMMERCIAL (NUM_GARAGE_STORED_CARS)
|
||||
#define MAX_STORED_CARS_IN_SUBURBAN (NUM_GARAGE_STORED_CARS)
|
||||
#define LIMIT_CARS_IN_INDUSTRIAL (1)
|
||||
#define LIMIT_CARS_IN_COMMERCIAL (2)
|
||||
#define LIMIT_CARS_IN_SUBURBAN (3)
|
||||
#define HIDEOUT_DOOR_SPEED_COEFFICIENT (1.7f)
|
||||
#define TIME_BETWEEN_HIDEOUT_MESSAGES (18000)
|
||||
|
||||
// Camera stuff
|
||||
#define MARGIN_FOR_CAMERA_COLLECTCARS (1.3f)
|
||||
#define MARGIN_FOR_CAMERA_DEFAULT (4.0f)
|
||||
|
||||
const int32 gaCarsToCollectInCraigsGarages[TOTAL_COLLECTCARS_GARAGES][TOTAL_COLLECTCARS_CARS] =
|
||||
{
|
||||
{ MI_SECURICA, MI_MOONBEAM, MI_COACH, MI_FLATBED, MI_LINERUN, MI_TRASH, MI_PATRIOT, MI_MRWHOOP, MI_BLISTA, MI_MULE, MI_YANKEE, MI_BOBCAT, MI_DODO, MI_BUS, MI_RUMPO, MI_PONY },
|
||||
@ -180,7 +194,7 @@ void CGarages::Update(void)
|
||||
GarageToBeTidied = 0;
|
||||
if (!aGarages[GarageToBeTidied].IsUsed())
|
||||
return;
|
||||
if (aGarages[GarageToBeTidied].IsClose())
|
||||
if (!aGarages[GarageToBeTidied].IsFar())
|
||||
aGarages[GarageToBeTidied].TidyUpGarageClose();
|
||||
else
|
||||
aGarages[GarageToBeTidied].TidyUpGarage();
|
||||
@ -222,9 +236,9 @@ int16 CGarages::AddOne(float X1, float Y1, float Z1, float X2, float Y2, float Z
|
||||
pGarage->m_fDoorPos = 0.0f;
|
||||
pGarage->m_eGarageState = GS_FULLYCLOSED;
|
||||
pGarage->m_nTimeToStartAction = 0;
|
||||
pGarage->field_2 = 0;
|
||||
pGarage->field_2 = false;
|
||||
pGarage->m_nTargetModelIndex = targetId;
|
||||
pGarage->field_96 = 0;
|
||||
pGarage->field_96 = nil;
|
||||
pGarage->m_bCollectedCarsState = 0;
|
||||
pGarage->m_bDeactivated = false;
|
||||
pGarage->m_bResprayHappened = false;
|
||||
@ -1405,18 +1419,13 @@ void CGarage::RemoveCarsBlockingDoorNotInside()
|
||||
continue;
|
||||
if (!IsEntityTouching3D(pVehicle))
|
||||
continue;
|
||||
CColModel* pColModel = CModelInfo::GetModelInfo(pVehicle->GetModelIndex())->GetColModel();
|
||||
for (int i = 0; i < pColModel->numSpheres; i++) {
|
||||
CVector pos = pVehicle->GetMatrix() * pColModel->spheres[i].center;
|
||||
float radius = pColModel->spheres[i].radius;
|
||||
if (pVehicle->GetPosition().x < m_fX1 || pVehicle->GetPosition().x > m_fX2 ||
|
||||
pVehicle->GetPosition().y < m_fY1 || pVehicle->GetPosition().y > m_fY2 ||
|
||||
pVehicle->GetPosition().z < m_fZ1 || pVehicle->GetPosition().z > m_fZ2) {
|
||||
if (pVehicle->bIsLocked && pVehicle->CanBeDeleted()) {
|
||||
CWorld::Remove(pVehicle);
|
||||
delete pVehicle;
|
||||
return; // WHY?
|
||||
}
|
||||
if (pVehicle->GetPosition().x < m_fX1 || pVehicle->GetPosition().x > m_fX2 ||
|
||||
pVehicle->GetPosition().y < m_fY1 || pVehicle->GetPosition().y > m_fY2 ||
|
||||
pVehicle->GetPosition().z < m_fZ1 || pVehicle->GetPosition().z > m_fZ2) {
|
||||
if (pVehicle->bIsLocked && pVehicle->CanBeDeleted()) {
|
||||
CWorld::Remove(pVehicle);
|
||||
delete pVehicle;
|
||||
return; // WHY?
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1566,6 +1575,7 @@ void CGarage::RefreshDoorPointers(bool bCreate)
|
||||
bool bNeedToFindDoorEntities = true;
|
||||
if (!bCreate && !m_bRecreateDoorOnNextRefresh)
|
||||
bNeedToFindDoorEntities = false;
|
||||
m_bRecreateDoorOnNextRefresh = false;
|
||||
if (DoINeedToRefreshPointer(m_pDoor1, m_bDoor1IsDummy, m_bDoor1PoolIndex))
|
||||
bNeedToFindDoorEntities = true;
|
||||
if (DoINeedToRefreshPointer(m_pDoor2, m_bDoor2IsDummy, m_bDoor2PoolIndex))
|
||||
@ -1775,7 +1785,58 @@ void CGarage::FindDoorsEntities()
|
||||
}
|
||||
}
|
||||
|
||||
WRAPPER void CGarage::FindDoorsEntitiesSectorList(CPtrList&, bool) { EAXJMP(0x427300); }
|
||||
void CGarage::FindDoorsEntitiesSectorList(CPtrList& list, bool dummy)
|
||||
{
|
||||
CPtrNode* node;
|
||||
for (node = list.first; node; node = node->next) {
|
||||
CEntity* pEntity = (CEntity*)node->item;
|
||||
if (pEntity->m_scanCode == CWorld::GetCurrentScanCode())
|
||||
continue;
|
||||
pEntity->m_scanCode = CWorld::GetCurrentScanCode();
|
||||
if (!pEntity || !CGarages::IsModelIndexADoor(pEntity->GetModelIndex()))
|
||||
continue;
|
||||
if (Abs(pEntity->GetPosition().x - GetGarageCenterX()) >= DISTANCE_TO_CONSIDER_DOOR_FOR_GARAGE)
|
||||
continue;
|
||||
if (Abs(pEntity->GetPosition().y - GetGarageCenterY()) >= DISTANCE_TO_CONSIDER_DOOR_FOR_GARAGE)
|
||||
continue;
|
||||
if (pEntity->GetModelIndex() == MI_CRUSHERBODY) {
|
||||
m_pDoor1 = pEntity;
|
||||
m_bDoor1IsDummy = dummy;
|
||||
// very odd pool operations, they could have used GetJustIndex
|
||||
if (dummy)
|
||||
m_bDoor1PoolIndex = (CPools::GetDummyPool()->GetIndex((CDummy*)pEntity)) & 0x7F;
|
||||
else
|
||||
m_bDoor1PoolIndex = (CPools::GetObjectPool()->GetIndex((CObject*)pEntity)) & 0x7F;
|
||||
continue;
|
||||
}
|
||||
if (pEntity->GetModelIndex() == MI_CRUSHERLID) {
|
||||
m_pDoor2 = pEntity;
|
||||
m_bDoor2IsDummy = dummy;
|
||||
if (dummy)
|
||||
m_bDoor2PoolIndex = (CPools::GetDummyPool()->GetIndex((CDummy*)pEntity)) & 0x7F;
|
||||
else
|
||||
m_bDoor2PoolIndex = (CPools::GetObjectPool()->GetIndex((CObject*)pEntity)) & 0x7F;
|
||||
continue;
|
||||
}
|
||||
if (!m_pDoor1) {
|
||||
m_pDoor1 = pEntity;
|
||||
m_bDoor1IsDummy = dummy;
|
||||
if (dummy)
|
||||
m_bDoor1PoolIndex = (CPools::GetDummyPool()->GetIndex((CDummy*)pEntity)) & 0x7F;
|
||||
else
|
||||
m_bDoor1PoolIndex = (CPools::GetObjectPool()->GetIndex((CObject*)pEntity)) & 0x7F;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
m_pDoor2 = pEntity;
|
||||
m_bDoor2IsDummy = dummy;
|
||||
if (dummy)
|
||||
m_bDoor2PoolIndex = (CPools::GetDummyPool()->GetIndex((CDummy*)pEntity)) & 0x7F;
|
||||
else
|
||||
m_bDoor2PoolIndex = (CPools::GetObjectPool()->GetIndex((CObject*)pEntity)) & 0x7F;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CGarages::HasResprayHappened(int16 garage)
|
||||
{
|
||||
@ -1805,12 +1866,139 @@ bool CGarages::HasCarBeenCrushed(int32 handle)
|
||||
return CrushedCarId == handle;
|
||||
}
|
||||
|
||||
WRAPPER void CStoredCar::StoreCar(CVehicle*) { EAXJMP(0x4275C0); }
|
||||
WRAPPER CVehicle* CStoredCar::RestoreCar() { EAXJMP(0x427690); }
|
||||
WRAPPER void CGarage::StoreAndRemoveCarsForThisHideout(CStoredCar*, int32) { EAXJMP(0x427840); }
|
||||
WRAPPER bool CGarage::RestoreCarsForThisHideout(CStoredCar*) { EAXJMP(0x427A40); }
|
||||
WRAPPER bool CGarages::IsPointInAGarageCameraZone(CVector) { EAXJMP(0x427AB0); }
|
||||
WRAPPER bool CGarages::CameraShouldBeOutside() { EAXJMP(0x427BC0); }
|
||||
void CStoredCar::StoreCar(CVehicle* pVehicle)
|
||||
{
|
||||
m_nModelIndex = pVehicle->GetModelIndex();
|
||||
m_vecPos = pVehicle->GetPosition();
|
||||
m_vecAngle = pVehicle->GetForward();
|
||||
m_nPrimaryColor = pVehicle->m_currentColour1;
|
||||
m_nSecondaryColor = pVehicle->m_currentColour2;
|
||||
m_nRadioStation = pVehicle->m_nRadioStation;
|
||||
m_nVariationA = pVehicle->m_aExtras[0];
|
||||
m_nVariationB = pVehicle->m_aExtras[1];
|
||||
m_bBulletproof = pVehicle->bBulletProof;
|
||||
m_bFireproof = pVehicle->bFireProof;
|
||||
m_bExplosionproof = pVehicle->bExplosionProof;
|
||||
m_bCollisionproof = pVehicle->bCollisionProof;
|
||||
m_bMeleeproof = pVehicle->bMeleeProof;
|
||||
if (pVehicle->IsCar())
|
||||
m_nCarBombType = ((CAutomobile*)pVehicle)->m_bombType;
|
||||
}
|
||||
|
||||
CVehicle* CStoredCar::RestoreCar()
|
||||
{
|
||||
CStreaming::RequestModel(m_nModelIndex, STREAMFLAGS_DEPENDENCY);
|
||||
if (!CStreaming::HasModelLoaded(m_nModelIndex))
|
||||
return nil;
|
||||
CVehicleModelInfo::SetComponentsToUse(m_nVariationA, m_nVariationB);
|
||||
#ifdef FIX_BUGS
|
||||
CVehicle* pVehicle;
|
||||
if (CModelInfo::IsBoatModel(m_nModelIndex))
|
||||
pVehicle = new CBoat(m_nModelIndex, RANDOM_VEHICLE);
|
||||
else
|
||||
pVehicle = new CAutomobile(m_nModelIndex, RANDOM_VEHICLE);
|
||||
#else
|
||||
CVehicle* pVehicle = new CAutomobile(m_nModelIndex, RANDOM_VEHICLE);
|
||||
#endif
|
||||
pVehicle->GetPosition() = m_vecPos;
|
||||
pVehicle->m_status = STATUS_ABANDONED;
|
||||
pVehicle->GetForward() = m_vecAngle;
|
||||
pVehicle->GetRight() = CVector(m_vecAngle.y, -m_vecAngle.x, 0.0f);
|
||||
pVehicle->GetUp() = CVector(0.0f, 0.0f, 1.0f);
|
||||
pVehicle->pDriver = nil;
|
||||
pVehicle->m_currentColour1 = m_nPrimaryColor;
|
||||
pVehicle->m_currentColour2 = m_nSecondaryColor;
|
||||
pVehicle->m_nRadioStation = m_nRadioStation;
|
||||
pVehicle->bFreebies = false;
|
||||
#ifdef FIX_BUGS
|
||||
((CAutomobile*)pVehicle)->m_bombType = m_nCarBombType;
|
||||
#endif
|
||||
pVehicle->bHasBeenOwnedByPlayer = true;
|
||||
pVehicle->m_nDoorLock = CARLOCK_UNLOCKED;
|
||||
pVehicle->bBulletProof = m_bBulletproof;
|
||||
pVehicle->bFireProof = m_bFireproof;
|
||||
pVehicle->bExplosionProof = m_bExplosionproof;
|
||||
pVehicle->bCollisionProof = m_bCollisionproof;
|
||||
pVehicle->bMeleeProof = m_bMeleeproof;
|
||||
return pVehicle;
|
||||
}
|
||||
|
||||
void CGarage::StoreAndRemoveCarsForThisHideout(CStoredCar* aCars, int32 nMax)
|
||||
{
|
||||
for (int i = 0; i < NUM_GARAGE_STORED_CARS; i++)
|
||||
aCars[i].Clear();
|
||||
int i = CPools::GetVehiclePool()->GetSize();
|
||||
int index = 0;
|
||||
while (i--) {
|
||||
CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
|
||||
if (!pVehicle)
|
||||
continue;
|
||||
if (pVehicle->GetPosition().x > m_fX1 && pVehicle->GetPosition().x < m_fX2 &&
|
||||
pVehicle->GetPosition().y > m_fY1 && pVehicle->GetPosition().y < m_fY2 &&
|
||||
pVehicle->GetPosition().z > m_fZ1 && pVehicle->GetPosition().z < m_fZ2) {
|
||||
if (pVehicle->VehicleCreatedBy != MISSION_VEHICLE) {
|
||||
if (index < max(NUM_GARAGE_STORED_CARS, nMax) && !EntityHasASphereWayOutsideGarage(pVehicle, 1.0f))
|
||||
aCars[index++].StoreCar(pVehicle);
|
||||
CWorld::Players[CWorld::PlayerInFocus].CancelPlayerEnteringCars(pVehicle);
|
||||
CWorld::Remove(pVehicle);
|
||||
delete pVehicle;
|
||||
}
|
||||
}
|
||||
}
|
||||
// why?
|
||||
for (i = index; i < NUM_GARAGE_STORED_CARS; i++)
|
||||
aCars[i].Clear();
|
||||
}
|
||||
|
||||
bool CGarage::RestoreCarsForThisHideout(CStoredCar* aCars)
|
||||
{
|
||||
for (int i = 0; i < NUM_GARAGE_STORED_CARS; i++) {
|
||||
if (aCars[i].HasCar()) {
|
||||
CVehicle* pVehicle = aCars[i].RestoreCar();
|
||||
if (pVehicle) {
|
||||
CWorld::Add(pVehicle);
|
||||
aCars[i].Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < NUM_GARAGE_STORED_CARS; i++) {
|
||||
if (aCars[i].HasCar())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGarages::IsPointInAGarageCameraZone(CVector point)
|
||||
{
|
||||
for (int i = 0; i < NUM_GARAGES; i++) {
|
||||
switch (aGarages[i].m_eGarageType) {
|
||||
case GARAGE_NONE:
|
||||
continue;
|
||||
case GARAGE_COLLECTCARS_1:
|
||||
case GARAGE_COLLECTCARS_2:
|
||||
case GARAGE_COLLECTCARS_3:
|
||||
if (aGarages[i].m_fX1 - MARGIN_FOR_CAMERA_COLLECTCARS < point.x ||
|
||||
aGarages[i].m_fX2 - MARGIN_FOR_CAMERA_COLLECTCARS > point.x ||
|
||||
aGarages[i].m_fY1 - MARGIN_FOR_CAMERA_COLLECTCARS < point.y ||
|
||||
aGarages[i].m_fY2 - MARGIN_FOR_CAMERA_COLLECTCARS > point.y)
|
||||
continue;
|
||||
return true;
|
||||
default:
|
||||
if (aGarages[i].m_fX1 - MARGIN_FOR_CAMERA_DEFAULT < point.x ||
|
||||
aGarages[i].m_fX2 - MARGIN_FOR_CAMERA_DEFAULT > point.x ||
|
||||
aGarages[i].m_fY1 - MARGIN_FOR_CAMERA_DEFAULT < point.y ||
|
||||
aGarages[i].m_fY2 - MARGIN_FOR_CAMERA_DEFAULT > point.y)
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CGarages::CameraShouldBeOutside()
|
||||
{
|
||||
return bCamShouldBeOutisde;
|
||||
}
|
||||
|
||||
void CGarages::GivePlayerDetonator()
|
||||
{
|
||||
@ -1818,19 +2006,299 @@ void CGarages::GivePlayerDetonator()
|
||||
FindPlayerPed()->GetWeapon(FindPlayerPed()->GetWeaponSlot(WEAPONTYPE_DETONATOR)).m_eWeaponState = WEAPONSTATE_READY;
|
||||
}
|
||||
|
||||
WRAPPER float CGarages::FindDoorHeightForMI(int32) { EAXJMP(0x427C10); }
|
||||
WRAPPER void CGarage::TidyUpGarage() { EAXJMP(0x427C30); }
|
||||
WRAPPER void CGarage::TidyUpGarageClose() { EAXJMP(0x427D90); }
|
||||
WRAPPER void CGarages::PlayerArrestedOrDied() { EAXJMP(0x427F60); }
|
||||
WRAPPER void CGarage::PlayerArrestedOrDied() { EAXJMP(0x427FC0); }
|
||||
WRAPPER void CGarage::CenterCarInGarage(CVehicle*) { EAXJMP(0x428000); }
|
||||
WRAPPER void CGarages::CloseHideOutGaragesBeforeSave() { EAXJMP(0x428130); }
|
||||
WRAPPER int32 CGarages::CountCarsInHideoutGarage(eGarageType) { EAXJMP(0x4281E0); }
|
||||
WRAPPER int32 CGarages::FindMaxNumStoredCarsForGarage(eGarageType) { EAXJMP(0x428230); }
|
||||
WRAPPER bool CGarages::IsPointWithinHideOutGarage(CVector&) { EAXJMP(0x428260); }
|
||||
WRAPPER bool CGarages::IsPointWithinAnyGarage(CVector&) { EAXJMP(0x428320); }
|
||||
WRAPPER void CGarages::SetAllDoorsBackToOriginalHeight() { EAXJMP(0x4283D0); }
|
||||
WRAPPER void CGarages::Save(uint8 * buf, uint32 * size) { EAXJMP(0x4284E0); }
|
||||
float CGarages::FindDoorHeightForMI(int32 mi)
|
||||
{
|
||||
return CModelInfo::GetModelInfo(mi)->GetColModel()->boundingBox.max.z - CModelInfo::GetModelInfo(mi)->GetColModel()->boundingBox.min.z - 0.1f;
|
||||
}
|
||||
|
||||
void CGarage::TidyUpGarage()
|
||||
{
|
||||
uint32 i = CPools::GetVehiclePool()->GetSize();
|
||||
while (i--) {
|
||||
CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
|
||||
if (!pVehicle || !pVehicle->IsCar())
|
||||
continue;
|
||||
if (pVehicle->GetPosition().x > m_fX1 && pVehicle->GetPosition().x < m_fX2 &&
|
||||
pVehicle->GetPosition().y > m_fY1 && pVehicle->GetPosition().y < m_fY2 &&
|
||||
pVehicle->GetPosition().z > m_fZ1 && pVehicle->GetPosition().z < m_fZ2) {
|
||||
if (pVehicle->m_status == STATUS_WRECKED || pVehicle->GetUp().z < 0.5f) {
|
||||
CWorld::Remove(pVehicle);
|
||||
delete pVehicle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGarage::TidyUpGarageClose()
|
||||
{
|
||||
uint32 i = CPools::GetVehiclePool()->GetSize();
|
||||
while (i--) {
|
||||
CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
|
||||
if (!pVehicle || !pVehicle->IsCar())
|
||||
continue;
|
||||
if (!pVehicle->IsCar() || pVehicle->m_status != STATUS_WRECKED || !IsEntityTouching3D(pVehicle))
|
||||
continue;
|
||||
bool bRemove = false;
|
||||
if (m_eGarageState != GS_FULLYCLOSED) {
|
||||
CColModel* pColModel = CModelInfo::GetModelInfo(pVehicle->GetModelIndex())->GetColModel();
|
||||
for (int i = 0; i < pColModel->numSpheres; i++) {
|
||||
CVector pos = pVehicle->GetMatrix() * pColModel->spheres[i].center;
|
||||
float radius = pColModel->spheres[i].radius;
|
||||
if (pos.x + radius < m_fX1 || pos.x - radius > m_fX2 ||
|
||||
pos.y + radius < m_fY1 || pos.y - radius > m_fY2 ||
|
||||
pos.z + radius < m_fZ1 || pos.z - radius > m_fZ2) {
|
||||
bRemove = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
bRemove = true;
|
||||
if (bRemove) {
|
||||
// no MISSION_VEHICLE check???
|
||||
CWorld::Remove(pVehicle);
|
||||
delete pVehicle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGarages::PlayerArrestedOrDied()
|
||||
{
|
||||
static int GarageToBeTidied = 0; // lol
|
||||
for (int i = 0; i < NUM_GARAGES; i++) {
|
||||
if (aGarages[i].m_eGarageType != GARAGE_NONE)
|
||||
aGarages[i].PlayerArrestedOrDied();
|
||||
}
|
||||
MessageEndTime = 0;
|
||||
MessageStartTime = 0;
|
||||
}
|
||||
|
||||
void CGarage::PlayerArrestedOrDied()
|
||||
{
|
||||
switch (m_eGarageType) {
|
||||
case GARAGE_MISSION:
|
||||
case GARAGE_COLLECTORSITEMS:
|
||||
case GARAGE_COLLECTSPECIFICCARS:
|
||||
case GARAGE_COLLECTCARS_1:
|
||||
case GARAGE_COLLECTCARS_2:
|
||||
case GARAGE_COLLECTCARS_3:
|
||||
case GARAGE_FORCARTOCOMEOUTOF:
|
||||
case GARAGE_60SECONDS:
|
||||
case GARAGE_MISSION_KEEPCAR:
|
||||
case GARAGE_FOR_SCRIPT_TO_OPEN:
|
||||
case GARAGE_HIDEOUT_ONE:
|
||||
case GARAGE_HIDEOUT_TWO:
|
||||
case GARAGE_HIDEOUT_THREE:
|
||||
case GARAGE_FOR_SCRIPT_TO_OPEN_AND_CLOSE:
|
||||
case GARAGE_KEEPS_OPENING_FOR_SPECIFIC_CAR:
|
||||
case GARAGE_MISSION_KEEPCAR_REMAINCLOSED:
|
||||
switch (m_eGarageState) {
|
||||
case GS_OPENED:
|
||||
case GS_CLOSING:
|
||||
case GS_OPENING:
|
||||
m_eGarageState = GS_CLOSING;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case GARAGE_BOMBSHOP1:
|
||||
case GARAGE_BOMBSHOP2:
|
||||
case GARAGE_BOMBSHOP3:
|
||||
case GARAGE_RESPRAY:
|
||||
case GARAGE_CRUSHER:
|
||||
switch (m_eGarageState) {
|
||||
case GS_FULLYCLOSED:
|
||||
case GS_CLOSING:
|
||||
case GS_OPENING:
|
||||
m_eGarageState = GS_OPENING;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CGarage::CenterCarInGarage(CVehicle* pVehicle)
|
||||
{
|
||||
if (IsAnyOtherCarTouchingGarage(FindPlayerVehicle()))
|
||||
return;
|
||||
if (IsAnyOtherPedTouchingGarage(FindPlayerPed()))
|
||||
return;
|
||||
float posX = pVehicle->GetPosition().x;
|
||||
float posY = pVehicle->GetPosition().y;
|
||||
float posZ = pVehicle->GetPosition().z;
|
||||
float garageX = GetGarageCenterX();
|
||||
float garageY = GetGarageCenterY();
|
||||
float offsetX = garageX - posX;
|
||||
float offsetY = garageY - posY;
|
||||
float offsetZ = posZ - posZ;
|
||||
float distance = CVector(offsetX, offsetY, offsetZ).Magnitude();
|
||||
if (distance < RESPRAY_CENTERING_COEFFICIENT) {
|
||||
pVehicle->GetPosition().x = GetGarageCenterX();
|
||||
pVehicle->GetPosition().y = GetGarageCenterY();
|
||||
}
|
||||
else {
|
||||
pVehicle->GetPosition().x += offsetX * RESPRAY_CENTERING_COEFFICIENT / distance;
|
||||
pVehicle->GetPosition().y += offsetY * RESPRAY_CENTERING_COEFFICIENT / distance;
|
||||
}
|
||||
if (!IsEntityEntirelyInside3D(pVehicle, 0.1f))
|
||||
pVehicle->GetPosition() = CVector(posX, posY, posZ);
|
||||
}
|
||||
|
||||
void CGarages::CloseHideOutGaragesBeforeSave()
|
||||
{
|
||||
for (int i = 0; i < NUM_GARAGES; i++) {
|
||||
if (aGarages[i].m_eGarageType != GARAGE_HIDEOUT_ONE &&
|
||||
aGarages[i].m_eGarageType != GARAGE_HIDEOUT_TWO &&
|
||||
aGarages[i].m_eGarageType != GARAGE_HIDEOUT_THREE)
|
||||
continue;
|
||||
if (aGarages[i].m_eGarageState != GS_FULLYCLOSED &&
|
||||
aGarages[i].m_eGarageType != GARAGE_HIDEOUT_ONE || !aGarages[i].IsAnyCarBlockingDoor()) {
|
||||
aGarages[i].m_eGarageState = GS_FULLYCLOSED;
|
||||
switch (aGarages[i].m_eGarageType) {
|
||||
case GARAGE_HIDEOUT_ONE:
|
||||
aGarages[i].StoreAndRemoveCarsForThisHideout(aCarsInSafeHouse1, NUM_GARAGE_STORED_CARS);
|
||||
aGarages[i].RemoveCarsBlockingDoorNotInside();
|
||||
break;
|
||||
case GARAGE_HIDEOUT_TWO:
|
||||
aGarages[i].StoreAndRemoveCarsForThisHideout(aCarsInSafeHouse2, NUM_GARAGE_STORED_CARS);
|
||||
aGarages[i].RemoveCarsBlockingDoorNotInside();
|
||||
break;
|
||||
case GARAGE_HIDEOUT_THREE:
|
||||
aGarages[i].StoreAndRemoveCarsForThisHideout(aCarsInSafeHouse3, NUM_GARAGE_STORED_CARS);
|
||||
aGarages[i].RemoveCarsBlockingDoorNotInside();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
aGarages[i].m_fDoorPos = 0.0f;
|
||||
aGarages[i].UpdateDoorsHeight();
|
||||
}
|
||||
}
|
||||
|
||||
int32 CGarages::CountCarsInHideoutGarage(eGarageType type)
|
||||
{
|
||||
int32 total = 0;
|
||||
for (int i = 0; i < NUM_GARAGE_STORED_CARS; i++) {
|
||||
switch (type) {
|
||||
case GARAGE_HIDEOUT_ONE:
|
||||
total += (aCarsInSafeHouse1[i].HasCar());
|
||||
break;
|
||||
case GARAGE_HIDEOUT_TWO:
|
||||
total += (aCarsInSafeHouse2[i].HasCar());
|
||||
break;
|
||||
case GARAGE_HIDEOUT_THREE:
|
||||
total += (aCarsInSafeHouse3[i].HasCar());
|
||||
break;
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
int32 CGarages::FindMaxNumStoredCarsForGarage(eGarageType type)
|
||||
{
|
||||
switch (type) {
|
||||
case GARAGE_HIDEOUT_ONE:
|
||||
return LIMIT_CARS_IN_INDUSTRIAL;
|
||||
case GARAGE_HIDEOUT_TWO:
|
||||
return LIMIT_CARS_IN_COMMERCIAL;
|
||||
case GARAGE_HIDEOUT_THREE:
|
||||
return LIMIT_CARS_IN_SUBURBAN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool CGarages::IsPointWithinHideOutGarage(CVector& point)
|
||||
{
|
||||
for (int i = 0; i < NUM_GARAGES; i++) {
|
||||
switch (aGarages[i].m_eGarageType) {
|
||||
case GARAGE_HIDEOUT_ONE:
|
||||
case GARAGE_HIDEOUT_TWO:
|
||||
case GARAGE_HIDEOUT_THREE:
|
||||
if (point.x > aGarages[i].m_fX1 && point.x < aGarages[i].m_fX2 &&
|
||||
point.y > aGarages[i].m_fY1 && point.y < aGarages[i].m_fY2 &&
|
||||
point.z > aGarages[i].m_fZ1 && point.z < aGarages[i].m_fZ2)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CGarages::IsPointWithinAnyGarage(CVector& point)
|
||||
{
|
||||
for (int i = 0; i < NUM_GARAGES; i++) {
|
||||
switch (aGarages[i].m_eGarageType) {
|
||||
case GARAGE_NONE:
|
||||
continue;
|
||||
default:
|
||||
if (point.x > aGarages[i].m_fX1 && point.x < aGarages[i].m_fX2 &&
|
||||
point.y > aGarages[i].m_fY1 && point.y < aGarages[i].m_fY2 &&
|
||||
point.z > aGarages[i].m_fZ1 && point.z < aGarages[i].m_fZ2)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CGarages::SetAllDoorsBackToOriginalHeight()
|
||||
{
|
||||
for (int i = 0; i < NUM_GARAGES; i++) {
|
||||
switch (aGarages[i].m_eGarageType) {
|
||||
case GARAGE_NONE:
|
||||
continue;
|
||||
default:
|
||||
aGarages[i].RefreshDoorPointers(true);
|
||||
if (aGarages[i].m_pDoor1) {
|
||||
aGarages[i].m_pDoor1->GetPosition().z = aGarages[i].m_fDoor1Z;
|
||||
if (aGarages[i].m_pDoor1->IsObject())
|
||||
((CObject*)aGarages[i].m_pDoor1)->m_objectMatrix.GetPosition().z = aGarages[i].m_fDoor1Z;
|
||||
if (aGarages[i].m_bRotatedDoor)
|
||||
aGarages[i].BuildRotatedDoorMatrix(aGarages[i].m_pDoor1, 0.0f);
|
||||
aGarages[i].m_pDoor1->GetMatrix().UpdateRW();
|
||||
aGarages[i].m_pDoor1->UpdateRwFrame();
|
||||
}
|
||||
if (aGarages[i].m_pDoor2) {
|
||||
aGarages[i].m_pDoor2->GetPosition().z = aGarages[i].m_fDoor2Z;
|
||||
if (aGarages[i].m_pDoor2->IsObject())
|
||||
((CObject*)aGarages[i].m_pDoor2)->m_objectMatrix.GetPosition().z = aGarages[i].m_fDoor2Z;
|
||||
if (aGarages[i].m_bRotatedDoor)
|
||||
aGarages[i].BuildRotatedDoorMatrix(aGarages[i].m_pDoor2, 0.0f);
|
||||
aGarages[i].m_pDoor2->GetMatrix().UpdateRW();
|
||||
aGarages[i].m_pDoor2->UpdateRwFrame();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGarages::Save(uint8 * buf, uint32 * size)
|
||||
{
|
||||
#ifdef FIX_GARAGE_SIZE
|
||||
*size = (6 * sizeof(uint32) + TOTAL_COLLECTCARS_GARAGES * sizeof(*CarTypesCollected) + sizeof(uint32) + 3 * NUM_GARAGE_STORED_CARS * sizeof(CStoredCar) + NUM_GARAGES * sizeof(CGarage));
|
||||
#else
|
||||
* size = 5484;
|
||||
#endif
|
||||
CloseHideOutGaragesBeforeSave();
|
||||
WriteSaveBuf(buf, NumGarages);
|
||||
WriteSaveBuf(buf, (uint32)BombsAreFree);
|
||||
WriteSaveBuf(buf, (uint32)RespraysAreFree);
|
||||
WriteSaveBuf(buf, CarsCollected);
|
||||
WriteSaveBuf(buf, BankVansCollected);
|
||||
WriteSaveBuf(buf, PoliceCarsCollected);
|
||||
for (int i = 0; i < TOTAL_COLLECTCARS_GARAGES; i++)
|
||||
WriteSaveBuf(buf, CarTypesCollected[i]);
|
||||
WriteSaveBuf(buf, LastTimeHelpMessage);
|
||||
for (int i = 0; i < NUM_GARAGE_STORED_CARS; i++) {
|
||||
WriteSaveBuf(buf, aCarsInSafeHouse1[i]);
|
||||
WriteSaveBuf(buf, aCarsInSafeHouse2[i]);
|
||||
WriteSaveBuf(buf, aCarsInSafeHouse3[i]);
|
||||
}
|
||||
for (int i = 0; i < NUM_GARAGES; i++)
|
||||
WriteSaveBuf(buf, aGarages[i]);
|
||||
}
|
||||
|
||||
CStoredCar::CStoredCar(const CStoredCar & other)
|
||||
{
|
||||
@ -1850,7 +2318,42 @@ CStoredCar::CStoredCar(const CStoredCar & other)
|
||||
m_nCarBombType = other.m_nCarBombType;
|
||||
}
|
||||
|
||||
WRAPPER void CGarages::Load(uint8 * buf, uint32 size) { EAXJMP(0x428940); }
|
||||
void CGarages::Load(uint8* buf, uint32 size)
|
||||
{
|
||||
#ifdef FIX_GARAGE_SIZE
|
||||
assert(size == (6 * sizeof(uint32) + TOTAL_COLLECTCARS_GARAGES * sizeof(*CarTypesCollected) + sizeof(uint32) + 3 * NUM_GARAGE_STORED_CARS * sizeof(CStoredCar) + NUM_GARAGES * sizeof(CGarage));
|
||||
#else
|
||||
assert(size == 5484);
|
||||
#endif
|
||||
CloseHideOutGaragesBeforeSave();
|
||||
NumGarages = ReadSaveBuf<uint32>(buf);
|
||||
BombsAreFree = ReadSaveBuf<uint32>(buf);
|
||||
RespraysAreFree = ReadSaveBuf<uint32>(buf);
|
||||
CarsCollected = ReadSaveBuf<int32>(buf);
|
||||
BankVansCollected = ReadSaveBuf<int32>(buf);
|
||||
PoliceCarsCollected = ReadSaveBuf<int32>(buf);
|
||||
for (int i = 0; i < TOTAL_COLLECTCARS_GARAGES; i++)
|
||||
CarTypesCollected[i] = ReadSaveBuf<uint32>(buf);
|
||||
LastTimeHelpMessage = ReadSaveBuf<uint32>(buf);
|
||||
for (int i = 0; i < NUM_GARAGE_STORED_CARS; i++) {
|
||||
aCarsInSafeHouse1[i] = ReadSaveBuf<CStoredCar>(buf);
|
||||
aCarsInSafeHouse2[i] = ReadSaveBuf<CStoredCar>(buf);
|
||||
aCarsInSafeHouse3[i] = ReadSaveBuf<CStoredCar>(buf);
|
||||
}
|
||||
for (int i = 0; i < NUM_GARAGES; i++) {
|
||||
aGarages[i] = ReadSaveBuf<CGarage>(buf);
|
||||
aGarages[i].m_pDoor1 = nil;
|
||||
aGarages[i].m_pDoor2 = nil;
|
||||
aGarages[i].m_pTarget = nil;
|
||||
aGarages[i].field_96 = nil;
|
||||
aGarages[i].m_bRecreateDoorOnNextRefresh = true;
|
||||
aGarages[i].RefreshDoorPointers(true);
|
||||
if (aGarages[i].m_eGarageType == GARAGE_CRUSHER)
|
||||
aGarages[i].UpdateCrusherAngle();
|
||||
else
|
||||
aGarages[i].UpdateDoorsHeight();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CGarages::IsModelIndexADoor(uint32 id)
|
||||
@ -1892,9 +2395,8 @@ CGarages::IsModelIndexADoor(uint32 id)
|
||||
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x421C60, CGarages::Init, PATCH_JUMP);
|
||||
#ifndef PS2
|
||||
InjectHook(0x421E10, CGarages::Shutdown, PATCH_JUMP);
|
||||
#endif
|
||||
InjectHook(0x421E40, CGarages::Update, PATCH_JUMP);
|
||||
InjectHook(0x426B20, CGarages::TriggerMessage, PATCH_JUMP); // CCrane::Update, CCrane::FindCarInSectorList
|
||||
InjectHook(0x427AB0, CGarages::IsPointInAGarageCameraZone, PATCH_JUMP); // CCamera::CamControl
|
||||
InjectHook(0x427BC0, CGarages::CameraShouldBeOutside, PATCH_JUMP); // CCamera::CamControl
|
||||
InjectHook(0x428940, CGarages::Load, PATCH_JUMP); // GenericLoad
|
||||
ENDPATCHES
|
@ -67,6 +67,8 @@ class CStoredCar
|
||||
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();
|
||||
@ -81,7 +83,7 @@ class CGarage
|
||||
public:
|
||||
eGarageType m_eGarageType;
|
||||
eGarageState m_eGarageState;
|
||||
char field_2;
|
||||
bool field_2;
|
||||
bool m_bClosingWithoutTargetCar;
|
||||
bool m_bDeactivated;
|
||||
bool m_bResprayHappened;
|
||||
@ -110,13 +112,10 @@ public:
|
||||
float m_fDoor1Z;
|
||||
float m_fDoor2Z;
|
||||
uint32 m_nTimeToStartAction;
|
||||
char m_bCollectedCarsState;
|
||||
char field_89;
|
||||
char field_90;
|
||||
char field_91;
|
||||
uint8 m_bCollectedCarsState;
|
||||
CVehicle *m_pTarget;
|
||||
int field_96;
|
||||
CStoredCar m_sStoredCar;
|
||||
void* field_96;
|
||||
CStoredCar m_sStoredCar; // not needed
|
||||
|
||||
void OpenThisGarage();
|
||||
void CloseThisGarage();
|
||||
@ -126,7 +125,7 @@ public:
|
||||
void Update();
|
||||
float GetGarageCenterX() { return (m_fX1 + m_fX2) / 2; }
|
||||
float GetGarageCenterY() { return (m_fY1 + m_fY2) / 2; }
|
||||
bool IsClose()
|
||||
bool IsFar()
|
||||
{
|
||||
#ifdef FIX_BUGS
|
||||
return Abs(TheCamera.GetPosition().x - GetGarageCenterX()) > SWITCH_GARAGE_DISTANCE_CLOSE ||
|
||||
|
Loading…
Reference in New Issue
Block a user