Merge pull request #869 from Nick007J/miami

garages revision + fixes
This commit is contained in:
aap 2020-12-09 09:55:50 +01:00 committed by GitHub
commit ccbbde549e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 240 additions and 161 deletions

View File

@ -506,6 +506,10 @@ CCarCtrl::GenerateOneRandomCar()
CCarPathLink* pCurrentLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo]; CCarPathLink* pCurrentLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo];
CCarPathLink* pNextLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo]; CCarPathLink* pNextLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo];
float currentPathLinkForwardX = pVehicle->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo].GetDirX();
float currentPathLinkForwardY = pVehicle->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo].GetDirY();
float nextPathLinkForwardX = pVehicle->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo].GetDirX();
float nextPathLinkForwardY = pVehicle->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo].GetDirY();
CVector positionOnCurrentLinkIncludingLane( CVector positionOnCurrentLinkIncludingLane(
pCurrentLink->GetX() + ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardY, pCurrentLink->GetX() + ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardY,
pCurrentLink->GetY() - ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardX, pCurrentLink->GetY() - ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardX,

View File

@ -45,7 +45,7 @@
// Distances // Distances
#define DISTANCE_TO_CALL_OFF_CHASE (10.0f) #define DISTANCE_TO_CALL_OFF_CHASE (10.0f)
#define DISTANCE_FOR_MRWHOOP_HACK (4.0f) #define DISTANCE_FOR_MRWHOOP_HACK (0.5f)
#define DISTANCE_TO_ACTIVATE_GARAGE (8.0f) #define DISTANCE_TO_ACTIVATE_GARAGE (8.0f)
#define DISTANCE_TO_ACTIVATE_KEEPCAR_GARAGE (17.0f) #define DISTANCE_TO_ACTIVATE_KEEPCAR_GARAGE (17.0f)
#define DISTANCE_TO_CLOSE_MISSION_GARAGE (30.0f) #define DISTANCE_TO_CLOSE_MISSION_GARAGE (30.0f)
@ -124,8 +124,8 @@ uint32 CGarages::MessageEndTime;
uint32 CGarages::NumGarages; uint32 CGarages::NumGarages;
bool CGarages::PlayerInGarage; bool CGarages::PlayerInGarage;
int32 CGarages::PoliceCarsCollected; int32 CGarages::PoliceCarsCollected;
CStoredCar CGarages::aCarsInSafeHouses[TOTAL_HIDEOUT_GARAGES][CGarages::MAX_NUM_CARS_IN_HIDEOUT_GARAGE]; CStoredCar CGarages::aCarsInSafeHouses[TOTAL_HIDEOUT_GARAGES][NUM_GARAGE_STORED_CARS];
int32 CGarages::AudioEntity = AEHANDLE_NONE; int32 hHandle = AEHANDLE_NONE;
CGarage CGarages::aGarages[NUM_GARAGES]; CGarage CGarages::aGarages[NUM_GARAGES];
bool CGarages::bCamShouldBeOutisde; bool CGarages::bCamShouldBeOutisde;
@ -146,22 +146,22 @@ void CGarages::Init(void)
for (int i = 0; i < TOTAL_COLLECTCARS_GARAGES; i++) for (int i = 0; i < TOTAL_COLLECTCARS_GARAGES; i++)
CarTypesCollected[i] = 0; CarTypesCollected[i] = 0;
LastTimeHelpMessage = 0; LastTimeHelpMessage = 0;
for (int i = 0; i < TOTAL_HIDEOUT_GARAGES; i++) { for (int i = 0; i < NUM_GARAGE_STORED_CARS; i++) {
for (int j = 0; j < MAX_NUM_CARS_IN_HIDEOUT_GARAGE; j++) for (int j = 0; j < TOTAL_HIDEOUT_GARAGES; j++)
aCarsInSafeHouses[i][j].Init(); aCarsInSafeHouses[j][i].Init();
} }
AudioEntity = DMAudio.CreateEntity(AUDIOTYPE_GARAGE, (void*)1); hHandle = DMAudio.CreateEntity(AUDIOTYPE_GARAGE, (void*)1);
if (AudioEntity >= 0) if (hHandle >= 0)
DMAudio.SetEntityStatus(AudioEntity, 1); DMAudio.SetEntityStatus(hHandle, 1);
} }
void CGarages::Shutdown(void) void CGarages::Shutdown(void)
{ {
NumGarages = 0; NumGarages = 0;
if (AudioEntity < 0) if (hHandle < 0)
return; return;
DMAudio.DestroyEntity(AudioEntity); DMAudio.DestroyEntity(hHandle);
AudioEntity = AEHANDLE_NONE; hHandle = AEHANDLE_NONE;
} }
void CGarages::Update(void) void CGarages::Update(void)
@ -337,6 +337,43 @@ void CGarage::Update()
} }
if (m_bDeactivated && m_eGarageState == GS_FULLYCLOSED) if (m_bDeactivated && m_eGarageState == GS_FULLYCLOSED)
return; return;
if (m_bRotatedDoor) {
#ifdef GTA_PS2
if (m_eGarageState == GS_OPENING) {
if (m_pDoor1) {
if (FindPlayerPed()->m_pCurrentPhysSurface == m_pDoor1)
m_pDoor1->bUsesCollision = false;
}
if (m_pDoor2) {
if (FindPlayerPed()->m_pCurrentPhysSurface == m_pDoor2)
m_pDoor2->bUsesCollision = false;
}
}
else if (m_eGarageState == GS_OPENED) {
if (m_pDoor1)
m_pDoor1->bUsesCollision = true;
if (m_pDoor2)
m_pDoor2->bUsesCollision = true;
}
#else
if (m_eGarageState == GS_OPENING || m_eGarageState == GS_OPENED) {
if (m_pDoor1) {
if (FindPlayerPed()->m_pCurrentPhysSurface == m_pDoor1 || FindPlayerPed()->GetPedState() == PED_JUMP || FindPlayerPed()->GetPedState() == PED_FALL || !FindPlayerPed()->bIsStanding)
m_pDoor1->bUsesCollision = false;
}
if (m_pDoor2) {
if (FindPlayerPed()->m_pCurrentPhysSurface == m_pDoor2 || FindPlayerPed()->GetPedState() == PED_JUMP || FindPlayerPed()->GetPedState() == PED_FALL || !FindPlayerPed()->bIsStanding)
m_pDoor2->bUsesCollision = false;
}
}
else {
if (m_pDoor1)
m_pDoor1->bUsesCollision = true;
if (m_pDoor2)
m_pDoor2->bUsesCollision = true;
}
#endif
}
switch (m_eGarageType) { switch (m_eGarageType) {
case GARAGE_RESPRAY: case GARAGE_RESPRAY:
switch (m_eGarageState) { switch (m_eGarageState) {
@ -376,7 +413,7 @@ void CGarage::Update()
if (m_fDoorPos == 0.0f) { if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED; m_eGarageState = GS_FULLYCLOSED;
m_nTimeToStartAction = CTimer::GetTimeInMilliseconds() + TIME_TO_RESPRAY; m_nTimeToStartAction = CTimer::GetTimeInMilliseconds() + TIME_TO_RESPRAY;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f); DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
CStats::CheckPointReachedSuccessfully(); CStats::CheckPointReachedSuccessfully();
} }
UpdateDoorsHeight(); UpdateDoorsHeight();
@ -480,7 +517,7 @@ void CGarage::Update()
m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) { if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENEDCONTAINSCAR; m_eGarageState = GS_OPENEDCONTAINSCAR;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_OPENED, 1.0f);
} }
UpdateDoorsHeight(); UpdateDoorsHeight();
break; break;
@ -524,7 +561,7 @@ void CGarage::Update()
if (m_fDoorPos == 0.0f) { if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED; m_eGarageState = GS_FULLYCLOSED;
m_nTimeToStartAction = CTimer::GetTimeInMilliseconds() + TIME_TO_SETUP_BOMB; m_nTimeToStartAction = CTimer::GetTimeInMilliseconds() + TIME_TO_SETUP_BOMB;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f); DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
} }
UpdateDoorsHeight(); UpdateDoorsHeight();
if (m_eGarageType == GARAGE_BOMBSHOP3) if (m_eGarageType == GARAGE_BOMBSHOP3)
@ -537,14 +574,18 @@ void CGarage::Update()
case GARAGE_BOMBSHOP1: DMAudio.PlayFrontEndSound(SOUND_GARAGE_BOMB1_SET, 1); break; case GARAGE_BOMBSHOP1: DMAudio.PlayFrontEndSound(SOUND_GARAGE_BOMB1_SET, 1); break;
case GARAGE_BOMBSHOP2: DMAudio.PlayFrontEndSound(SOUND_GARAGE_BOMB2_SET, 1); break; case GARAGE_BOMBSHOP2: DMAudio.PlayFrontEndSound(SOUND_GARAGE_BOMB2_SET, 1); break;
case GARAGE_BOMBSHOP3: DMAudio.PlayFrontEndSound(SOUND_GARAGE_BOMB3_SET, 1); break; case GARAGE_BOMBSHOP3: DMAudio.PlayFrontEndSound(SOUND_GARAGE_BOMB3_SET, 1); break;
default: break;
} }
m_eGarageState = GS_OPENING; m_eGarageState = GS_OPENING;
if (!CGarages::BombsAreFree) if (!CGarages::BombsAreFree)
CWorld::Players[CWorld::PlayerInFocus].m_nMoney = Max(0, CWorld::Players[CWorld::PlayerInFocus].m_nMoney - BOMB_PRICE); CWorld::Players[CWorld::PlayerInFocus].m_nMoney = Max(0, CWorld::Players[CWorld::PlayerInFocus].m_nMoney - BOMB_PRICE);
if (FindPlayerVehicle() && (FindPlayerVehicle()->IsCar() || FindPlayerVehicle()->IsBike())) { if (FindPlayerVehicle() && (FindPlayerVehicle()->IsCar() || FindPlayerVehicle()->IsBike())) {
#if (!defined GTA_PS2 || defined FIX_BUGS)
FindPlayerVehicle()->m_bombType = CGarages::GetBombTypeForGarageType(m_eGarageType); FindPlayerVehicle()->m_bombType = CGarages::GetBombTypeForGarageType(m_eGarageType);
FindPlayerVehicle()->m_pBombRigger = FindPlayerPed(); FindPlayerVehicle()->m_pBombRigger = FindPlayerPed();
#else // PS2 version contained a bug: CBike was casted to CAutomobile, but due to coincidence it didn't corrupt memory
((CAutomobile*)(FindPlayerVehicle()))->m_bombType = CGarages::GetBombTypeForGarageType(m_eGarageType);
((CAutomobile*)(FindPlayerVehicle()))->m_pBombRigger = FindPlayerPed();
#endif
if (m_eGarageType == GARAGE_BOMBSHOP3) if (m_eGarageType == GARAGE_BOMBSHOP3)
CGarages::GivePlayerDetonator(); CGarages::GivePlayerDetonator();
CStats::KgsOfExplosivesUsed += KGS_OF_EXPLOSIVES_IN_BOMB; CStats::KgsOfExplosivesUsed += KGS_OF_EXPLOSIVES_IN_BOMB;
@ -582,7 +623,6 @@ void CGarage::Update()
case GARAGE_BOMBSHOP3: case GARAGE_BOMBSHOP3:
CHud::SetHelpMessage(TheText.Get("GA_8"), false); // Use the detonator to activate the bomb. CHud::SetHelpMessage(TheText.Get("GA_8"), false); // Use the detonator to activate the bomb.
break; break;
default: break;
} }
CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_GARAGE); CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_GARAGE);
FindPlayerPed()->m_pWanted->m_bIgnoredByCops = false; FindPlayerPed()->m_pWanted->m_bIgnoredByCops = false;
@ -596,7 +636,7 @@ void CGarage::Update()
m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) { if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENEDCONTAINSCAR; m_eGarageState = GS_OPENEDCONTAINSCAR;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_OPENED, 1.0f);
} }
UpdateDoorsHeight(); UpdateDoorsHeight();
break; break;
@ -614,13 +654,17 @@ void CGarage::Update()
switch (m_eGarageState) { switch (m_eGarageState) {
case GS_OPENED: case GS_OPENED:
if (((CVector2D)FindPlayerCoors() - CVector2D(GetGarageCenterX(), GetGarageCenterY())).MagnitudeSqr() > SQR(DISTANCE_TO_CLOSE_MISSION_GARAGE)) { if (((CVector2D)FindPlayerCoors() - CVector2D(GetGarageCenterX(), GetGarageCenterY())).MagnitudeSqr() > SQR(DISTANCE_TO_CLOSE_MISSION_GARAGE)) {
if ((CTimer::GetFrameCounter() & 0x1F) == 0 && !IsAnyOtherCarTouchingGarage(nil)) { if ((CTimer::GetFrameCounter() & 0x1F) == 0
#ifndef GTA_PS2
&& (!m_pTarget || IsEntityTouching3D(m_pTarget))
#endif
) {
m_eGarageState = GS_CLOSING; m_eGarageState = GS_CLOSING;
m_bClosingWithoutTargetCar = true; m_bClosingWithoutTargetCar = true;
} }
} }
else if (!FindPlayerVehicle() && m_pTarget && IsEntityEntirelyInside3D(m_pTarget, 0.0f) && else if (!FindPlayerVehicle() && m_pTarget && IsEntityEntirelyInside3D(m_pTarget, 0.0f) &&
!IsAnyOtherCarTouchingGarage(m_pTarget) && IsEntityEntirelyOutside(FindPlayerPed(), 2.0f)) { IsEntityEntirelyOutside(FindPlayerVehicle() ? (CEntity*)FindPlayerVehicle() : (CEntity*)FindPlayerPed(), 2.0f)) {
CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_GARAGE); CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_GARAGE);
FindPlayerPed()->m_pWanted->m_bIgnoredByCops = true; FindPlayerPed()->m_pWanted->m_bIgnoredByCops = true;
m_eGarageState = GS_CLOSING; m_eGarageState = GS_CLOSING;
@ -632,7 +676,7 @@ void CGarage::Update()
ThrowCarsNearDoorOutOfGarage(m_pTarget); ThrowCarsNearDoorOutOfGarage(m_pTarget);
m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) { if (m_fDoorPos == 0.0f) {
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f); DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
if (m_bClosingWithoutTargetCar) if (m_bClosingWithoutTargetCar)
m_eGarageState = GS_FULLYCLOSED; m_eGarageState = GS_FULLYCLOSED;
else { else {
@ -662,7 +706,7 @@ void CGarage::Update()
m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) { if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED; m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_OPENED, 1.0f);
} }
UpdateDoorsHeight(); UpdateDoorsHeight();
break; break;
@ -715,7 +759,7 @@ void CGarage::Update()
m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) { if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED; m_eGarageState = GS_FULLYCLOSED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f); DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
if (m_pTarget) { if (m_pTarget) {
MarkThisCarAsCollectedForCraig(m_pTarget->GetModelIndex()); MarkThisCarAsCollectedForCraig(m_pTarget->GetModelIndex());
DestroyVehicleAndDriverAndPassengers(m_pTarget); DestroyVehicleAndDriverAndPassengers(m_pTarget);
@ -755,7 +799,7 @@ void CGarage::Update()
m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) { if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED; m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_OPENED, 1.0f);
} }
UpdateDoorsHeight(); UpdateDoorsHeight();
break; break;
@ -776,7 +820,7 @@ void CGarage::Update()
m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) { if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED; m_eGarageState = GS_FULLYCLOSED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f); DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
} }
if (!IsGarageEmpty()) if (!IsGarageEmpty())
m_eGarageState = GS_OPENING; m_eGarageState = GS_OPENING;
@ -787,7 +831,7 @@ void CGarage::Update()
m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) { if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED; m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_OPENED, 1.0f);
} }
UpdateDoorsHeight(); UpdateDoorsHeight();
break; break;
@ -821,7 +865,7 @@ void CGarage::Update()
ThrowCarsNearDoorOutOfGarage(m_pTarget); ThrowCarsNearDoorOutOfGarage(m_pTarget);
m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) { if (m_fDoorPos == 0.0f) {
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f); DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
if (m_bClosingWithoutTargetCar) if (m_bClosingWithoutTargetCar)
m_eGarageState = GS_FULLYCLOSED; m_eGarageState = GS_FULLYCLOSED;
else { else {
@ -850,7 +894,7 @@ void CGarage::Update()
m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) { if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED; m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_OPENED, 1.0f);
} }
UpdateDoorsHeight(); UpdateDoorsHeight();
break; break;
@ -870,7 +914,7 @@ void CGarage::Update()
m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) { if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED; m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_OPENED, 1.0f);
} }
UpdateDoorsHeight(); UpdateDoorsHeight();
break; break;
@ -890,7 +934,7 @@ void CGarage::Update()
m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) { if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED; m_eGarageState = GS_FULLYCLOSED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f); DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
} }
UpdateDoorsHeight(); UpdateDoorsHeight();
break; break;
@ -898,7 +942,7 @@ void CGarage::Update()
m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) { if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED; m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_OPENED, 1.0f);
} }
UpdateDoorsHeight(); UpdateDoorsHeight();
break; break;
@ -930,8 +974,8 @@ void CGarage::Update()
// Close car doors either if player is far, or if he is in vehicle and garage is full, // Close car doors either if player is far, or if he is in vehicle and garage is full,
// or if player is very very far so that we can remove whatever is blocking garage door without him noticing // or if player is very very far so that we can remove whatever is blocking garage door without him noticing
if ((distance > SQR(DISTANCE_TO_CLOSE_HIDEOUT_GARAGE_IN_CAR) || if ((distance > SQR(DISTANCE_TO_CLOSE_HIDEOUT_GARAGE_IN_CAR) ||
!FindPlayerVehicle() && distance > SQR(DISTANCE_TO_CLOSE_HIDEOUT_GARAGE_ON_FOOT) && !FindPlayerVehicle() && distance > SQR(DISTANCE_TO_CLOSE_HIDEOUT_GARAGE_ON_FOOT)) &&
!IsAnyCarBlockingDoor())) !IsAnyCarBlockingDoor())
m_eGarageState = GS_CLOSING; m_eGarageState = GS_CLOSING;
else if (FindPlayerVehicle() && else if (FindPlayerVehicle() &&
CountCarsWithCenterPointWithinGarage(FindPlayerVehicle()) >= CountCarsWithCenterPointWithinGarage(FindPlayerVehicle()) >=
@ -949,7 +993,7 @@ void CGarage::Update()
if (!IsPlayerOutsideGarage()) if (!IsPlayerOutsideGarage())
m_eGarageState = GS_OPENING; m_eGarageState = GS_OPENING;
else if (m_fDoorPos == 0.0f) { else if (m_fDoorPos == 0.0f) {
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f); DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
m_eGarageState = GS_FULLYCLOSED; m_eGarageState = GS_FULLYCLOSED;
StoreAndRemoveCarsForThisHideout(CGarages::aCarsInSafeHouses[CGarages::FindSafeHouseIndexForGarageType(m_eGarageType)], NUM_GARAGE_STORED_CARS); StoreAndRemoveCarsForThisHideout(CGarages::aCarsInSafeHouses[CGarages::FindSafeHouseIndexForGarageType(m_eGarageType)], NUM_GARAGE_STORED_CARS);
} }
@ -980,7 +1024,7 @@ void CGarage::Update()
m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + HIDEOUT_DOOR_SPEED_COEFFICIENT * (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + HIDEOUT_DOOR_SPEED_COEFFICIENT * (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) { if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED; m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_OPENED, 1.0f);
} }
UpdateDoorsHeight(); UpdateDoorsHeight();
break; break;
@ -1007,7 +1051,7 @@ void CGarage::Update()
m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) { if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED; m_eGarageState = GS_FULLYCLOSED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f); DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
} }
UpdateDoorsHeight(); UpdateDoorsHeight();
break; break;
@ -1023,7 +1067,7 @@ void CGarage::Update()
m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) { if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED; m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_OPENED, 1.0f);
} }
UpdateDoorsHeight(); UpdateDoorsHeight();
break; break;
@ -1048,7 +1092,7 @@ void CGarage::Update()
m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) { if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED; m_eGarageState = GS_FULLYCLOSED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f); DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_GARAGE); CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_GARAGE);
} }
case GS_FULLYCLOSED: case GS_FULLYCLOSED:
@ -1057,7 +1101,7 @@ void CGarage::Update()
m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) { if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED; m_eGarageState = GS_OPENED;
DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_OPENED, 1.0f);
} }
UpdateDoorsHeight(); UpdateDoorsHeight();
break; break;
@ -1072,28 +1116,6 @@ void CGarage::Update()
} }
} }
void CGarage::ThrowCarsNearDoorOutOfGarage(CVehicle* pException)
{
uint32 i = CPools::GetVehiclePool()->GetSize();
while (i--) {
CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
if (!pVehicle || pVehicle == pException)
continue;
if (!IsEntityTouching3D(pVehicle))
continue;
CColModel* pColModel = pVehicle->GetColModel();
for (int i = 0; i < pColModel->numSpheres; i++) {
CVector pos = pVehicle->GetMatrix() * pColModel->spheres[i].center;
float radius = pColModel->spheres[i].radius;
if (!IsPointInsideGarage(pos, 0.0f)) {
CVector vecDirectionAway(pVehicle->GetPosition().x - GetGarageCenterX(), pVehicle->GetPosition().y - GetGarageCenterY(), 0.0f);
vecDirectionAway.Normalise();
pVehicle->AddToMoveSpeed(vecDirectionAway * CTimer::GetTimeStepInSeconds());
}
}
}
}
bool CGarage::IsStaticPlayerCarEntirelyInside() bool CGarage::IsStaticPlayerCarEntirelyInside()
{ {
if (!FindPlayerVehicle()) if (!FindPlayerVehicle())
@ -1158,7 +1180,7 @@ bool CGarage::IsPointInsideGarage(CVector pos, float m_fMargin)
return true; return true;
} }
bool CGarage::IsEntityEntirelyInside3D(CEntity * pEntity, float fMargin) bool CGarage::IsEntityEntirelyInside3D(CEntity* pEntity, float fMargin)
{ {
if (pEntity->GetPosition().x < m_fInfX - fMargin || pEntity->GetPosition().x > m_fSupX + fMargin || if (pEntity->GetPosition().x < m_fInfX - fMargin || pEntity->GetPosition().x > m_fSupX + fMargin ||
pEntity->GetPosition().y < m_fInfY - fMargin || pEntity->GetPosition().y > m_fSupY + fMargin || pEntity->GetPosition().y < m_fInfY - fMargin || pEntity->GetPosition().y > m_fSupY + fMargin ||
@ -1210,12 +1232,12 @@ bool CGarage::IsPlayerOutsideGarage()
return IsEntityEntirelyOutside(FindPlayerPed(), 0.0f); return IsEntityEntirelyOutside(FindPlayerPed(), 0.0f);
} }
bool CGarage::IsEntityTouching3D(CEntity * pEntity) bool CGarage::IsEntityTouching3D(CEntity* pEntity)
{ {
float radius = pEntity->GetBoundRadius(); float radius = pEntity->GetBoundRadius();
if (pEntity->GetPosition().x - radius < m_fInfX || pEntity->GetPosition().x + radius > m_fSupX || if (m_fInfX - radius > pEntity->GetPosition().x || m_fSupX + radius < pEntity->GetPosition().x ||
pEntity->GetPosition().y - radius < m_fInfY || pEntity->GetPosition().y + radius > m_fSupY || m_fInfY - radius > pEntity->GetPosition().y || m_fSupY + radius < pEntity->GetPosition().y ||
pEntity->GetPosition().z - radius < m_fInfZ || pEntity->GetPosition().z + radius > m_fSupZ) m_fInfZ - radius > pEntity->GetPosition().z || m_fSupZ + radius < pEntity->GetPosition().z)
return false; return false;
CColModel* pColModel = pEntity->GetColModel(); CColModel* pColModel = pEntity->GetColModel();
for (int i = 0; i < pColModel->numSpheres; i++) { for (int i = 0; i < pColModel->numSpheres; i++) {
@ -1259,6 +1281,28 @@ bool CGarage::IsAnyOtherCarTouchingGarage(CVehicle * pException)
return false; return false;
} }
void CGarage::ThrowCarsNearDoorOutOfGarage(CVehicle* pException)
{
uint32 i = CPools::GetVehiclePool()->GetSize();
while (i--) {
CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
if (!pVehicle || pVehicle == pException)
continue;
if (!IsEntityTouching3D(pVehicle))
continue;
CColModel* pColModel = pVehicle->GetColModel();
for (int i = 0; i < pColModel->numSpheres; i++) {
CVector pos = pVehicle->GetMatrix() * pColModel->spheres[i].center;
float radius = pColModel->spheres[i].radius;
if (!IsPointInsideGarage(pos, 0.0f)) {
CVector vecDirectionAway(pVehicle->GetPosition().x - GetGarageCenterX(), pVehicle->GetPosition().y - GetGarageCenterY(), 0.0f);
vecDirectionAway.Normalise();
pVehicle->AddToMoveSpeed(vecDirectionAway * CTimer::GetTimeStepInSeconds());
}
}
}
}
bool CGarage::IsAnyOtherPedTouchingGarage(CPed * pException) bool CGarage::IsAnyOtherPedTouchingGarage(CPed * pException)
{ {
uint32 i = CPools::GetPedPool()->GetSize(); uint32 i = CPools::GetPedPool()->GetSize();
@ -1326,7 +1370,9 @@ void CGarage::RemoveCarsBlockingDoorNotInside()
if (!pVehicle->bIsLocked && pVehicle->CanBeDeleted()) { if (!pVehicle->bIsLocked && pVehicle->CanBeDeleted()) {
CWorld::Remove(pVehicle); CWorld::Remove(pVehicle);
delete pVehicle; delete pVehicle;
return; // WHY? #ifndef FIX_BUGS
return;
#endif
} }
} }
} }
@ -1335,43 +1381,34 @@ void CGarage::RemoveCarsBlockingDoorNotInside()
void CGarages::PrintMessages() void CGarages::PrintMessages()
{ {
if (CTimer::GetTimeInMilliseconds() > MessageStartTime && CTimer::GetTimeInMilliseconds() < MessageEndTime) { if (CTimer::GetTimeInMilliseconds() > MessageStartTime && CTimer::GetTimeInMilliseconds() < MessageEndTime) {
CFont::SetScale(SCREEN_SCALE_X(1.2f), SCREEN_SCALE_Y(1.5f)); // BUG: game doesn't use macro here. CFont::DrawFonts();
CFont::SetScale(SCREEN_SCALE_X(1.2f), SCREEN_SCALE_Y(1.5f));
CFont::SetPropOn(); CFont::SetPropOn();
CFont::SetJustifyOff(); CFont::SetJustifyOff();
CFont::SetBackgroundOff(); CFont::SetBackgroundOff();
CFont::SetCentreSize(SCREEN_SCALE_X(590.0f)); CFont::SetCentreSize(SCREEN_SCALE_X(590.0f));
CFont::SetCentreOn(); CFont::SetCentreOn();
CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
CFont::SetColor(CRGBA(0, 0, 0, 255)); CFont::SetColor(CRGBA(27, 89, 130, 255));
CFont::SetDropShadowPosition(2);
CFont::SetDropColor(CRGBA(0, 0, 0, 255));
#if defined(PS2) || defined (FIX_BUGS) #if defined(GTA_PS2) || defined (FIX_BUGS)
float y_offset = SCREEN_HEIGHT / 3; // THIS is PS2 calculation float y_offset = SCREEN_HEIGHT / 3 - SCREEN_SCALE_Y(40.0f); // THIS is PS2 calculation
#else #else
float y_offset = SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(84.0f); // This is PC and results in text being written over some HUD elements float y_offset = SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(84.0f); // This is PC and results in text being written over some HUD elements
#endif #endif
if (MessageNumberInString2 < 0) { if (MessageNumberInString2 >= 0) {
if (MessageNumberInString < 0) {
CFont::PrintString(SCREEN_WIDTH / 2 - SCREEN_SCALE_X(2.0f), y_offset - SCREEN_SCALE_Y(2.0f), TheText.Get(MessageIDString));
CFont::SetColor(CRGBA(27, 89, 130, 255));
CFont::PrintString(SCREEN_WIDTH / 2, y_offset, TheText.Get(MessageIDString));
}
else {
CMessages::InsertNumberInString(TheText.Get(MessageIDString), MessageNumberInString, -1, -1, -1, -1, -1, gUString);
CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(2.0f), y_offset - SCREEN_SCALE_Y(40.0f) + SCREEN_SCALE_Y(2.0f), gUString);
CFont::SetColor(CRGBA(27, 89, 130, 255));
CFont::PrintString(SCREEN_WIDTH / 2, y_offset - SCREEN_SCALE_Y(40.0f), gUString);
}
}
else {
CMessages::InsertNumberInString(TheText.Get(MessageIDString), MessageNumberInString, MessageNumberInString2, -1, -1, -1, -1, gUString); CMessages::InsertNumberInString(TheText.Get(MessageIDString), MessageNumberInString, MessageNumberInString2, -1, -1, -1, -1, gUString);
CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(2.0f), y_offset - SCREEN_SCALE_Y(40.0f) + SCREEN_SCALE_Y(2.0f), gUString); CFont::PrintString(SCREEN_WIDTH / 2, y_offset - SCREEN_SCALE_Y(30.0f), gUString);
}
CFont::SetColor(CRGBA(27, 89, 130, 255)); else if (MessageNumberInString >= 0) {
CFont::PrintString(SCREEN_WIDTH / 2, y_offset - SCREEN_SCALE_Y(40.0f), gUString); CMessages::InsertNumberInString(TheText.Get(MessageIDString), MessageNumberInString, -1, -1, -1, -1, -1, gUString);
CFont::PrintString(SCREEN_WIDTH / 2, y_offset - SCREEN_SCALE_Y(30.0f), gUString);
}
else {
CFont::PrintString(SCREEN_WIDTH / 2, y_offset, TheText.Get(MessageIDString));
} }
} }
} }
@ -1388,7 +1425,9 @@ bool CGarages::IsCarSprayable(CVehicle * pVehicle)
case MI_BARRACKS: case MI_BARRACKS:
case MI_DODO: case MI_DODO:
case MI_COACH: case MI_COACH:
#ifndef GTA_PS2
case MI_FBIRANCH: case MI_FBIRANCH:
#endif
return false; return false;
default: default:
break; break;
@ -1460,41 +1499,54 @@ void CGarage::UpdateCrusherShake(float X, float Y)
m_pDoor2->GetMatrix().GetPosition().y -= Y; m_pDoor2->GetMatrix().GetPosition().y -= Y;
} }
// This is dumb but there is no way to avoid goto. What was there originally even?
static bool DoINeedToRefreshPointer(CEntity * pDoor, bool bIsDummy, uint8 nIndex)
{
bool bNeedToFindDoorEntities = false;
if (pDoor) {
if (bIsDummy) {
if (CPools::GetDummyPool()->IsFreeSlot(CPools::GetDummyPool()->GetJustIndex_NoFreeAssert((CDummy*)pDoor)))
return true;
if (nIndex != (CPools::GetDummyPool()->GetIndex((CDummy*)pDoor) & 0x7F))
bNeedToFindDoorEntities = true;
if (!CGarages::IsModelIndexADoor(pDoor->GetModelIndex()))
return true;
}
else {
if (CPools::GetObjectPool()->IsFreeSlot(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert((CObject*)pDoor)))
return true;
if (nIndex != (CPools::GetObjectPool()->GetIndex((CObject*)pDoor) & 0x7F))
bNeedToFindDoorEntities = true;
if (!CGarages::IsModelIndexADoor(pDoor->GetModelIndex()))
return true;
}
}
return bNeedToFindDoorEntities;
}
void CGarage::RefreshDoorPointers(bool bCreate) void CGarage::RefreshDoorPointers(bool bCreate)
{ {
bool bNeedToFindDoorEntities = true; bool bNeedToFindDoorEntities = bCreate || m_bRecreateDoorOnNextRefresh;
if (!bCreate && !m_bRecreateDoorOnNextRefresh)
bNeedToFindDoorEntities = false;
m_bRecreateDoorOnNextRefresh = false; m_bRecreateDoorOnNextRefresh = false;
if (DoINeedToRefreshPointer(m_pDoor1, m_bDoor1IsDummy, m_bDoor1PoolIndex)) if (m_pDoor1) {
if (m_bDoor1IsDummy) {
if (CPools::GetDummyPool()->IsFreeSlot(CPools::GetDummyPool()->GetJustIndex_NoFreeAssert((CDummy*)m_pDoor1)))
bNeedToFindDoorEntities = true; bNeedToFindDoorEntities = true;
if (DoINeedToRefreshPointer(m_pDoor2, m_bDoor2IsDummy, m_bDoor2PoolIndex)) else {
if (m_bDoor1PoolIndex != (CPools::GetDummyPool()->GetIndex((CDummy*)m_pDoor1) & 0x7F))
bNeedToFindDoorEntities = true; bNeedToFindDoorEntities = true;
if (!CGarages::IsModelIndexADoor(m_pDoor1->GetModelIndex()))
bNeedToFindDoorEntities = true;
}
}
else {
if (CPools::GetObjectPool()->IsFreeSlot(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert((CObject*)m_pDoor1)))
bNeedToFindDoorEntities = true;
else {
if (m_bDoor1PoolIndex != (CPools::GetObjectPool()->GetIndex((CObject*)m_pDoor1) & 0x7F))
bNeedToFindDoorEntities = true;
if (!CGarages::IsModelIndexADoor(m_pDoor1->GetModelIndex()))
bNeedToFindDoorEntities = true;
}
}
}
if (m_pDoor2) {
if (m_bDoor2IsDummy) {
if (CPools::GetDummyPool()->IsFreeSlot(CPools::GetDummyPool()->GetJustIndex_NoFreeAssert((CDummy*)m_pDoor2)))
bNeedToFindDoorEntities = true;
else {
if (m_bDoor2PoolIndex != (CPools::GetDummyPool()->GetIndex((CDummy*)m_pDoor2) & 0x7F))
bNeedToFindDoorEntities = true;
if (!CGarages::IsModelIndexADoor(m_pDoor2->GetModelIndex()))
bNeedToFindDoorEntities = true;
}
}
else {
if (CPools::GetObjectPool()->IsFreeSlot(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert((CObject*)m_pDoor2)))
bNeedToFindDoorEntities = true;
else {
if (m_bDoor2PoolIndex != (CPools::GetObjectPool()->GetIndex((CObject*)m_pDoor2) & 0x7F))
bNeedToFindDoorEntities = true;
if (!CGarages::IsModelIndexADoor(m_pDoor2->GetModelIndex()))
bNeedToFindDoorEntities = true;
}
}
}
if (bNeedToFindDoorEntities) if (bNeedToFindDoorEntities)
FindDoorsEntities(); FindDoorsEntities();
} }
@ -1518,7 +1570,7 @@ void CGarages::TriggerMessage(const char* text, int16 num1, uint16 time, int16 n
MessageNumberInString2 = num2; MessageNumberInString2 = num2;
} }
void CGarages::SetTargetCarForMissonGarage(int16 garage, CVehicle * pVehicle) void CGarages::SetTargetCarForMissonGarage(int16 garage, CVehicle* pVehicle)
{ {
assert(garage >= 0 && garage < NUM_GARAGES); assert(garage >= 0 && garage < NUM_GARAGES);
if (pVehicle) { if (pVehicle) {
@ -1661,9 +1713,9 @@ void CGarage::FindDoorsEntities()
{ {
m_pDoor1 = nil; m_pDoor1 = nil;
m_pDoor2 = nil; m_pDoor2 = nil;
int xstart = Max(0, CWorld::GetSectorIndexX(m_fInfX)); int xstart = Max(0, CWorld::GetSectorIndexX(GetGarageCenterX()));
int xend = Min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(m_fSupX)); int xend = Min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(m_fSupX));
int ystart = Max(0, CWorld::GetSectorIndexY(m_fInfY)); int ystart = Max(0, CWorld::GetSectorIndexY(GetGarageCenterY()));
int yend = Min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(m_fSupY)); int yend = Min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(m_fSupY));
assert(xstart <= xend); assert(xstart <= xend);
assert(ystart <= yend); assert(ystart <= yend);
@ -1777,8 +1829,8 @@ void CStoredCar::StoreCar(CVehicle* pVehicle)
m_bExplosionproof = pVehicle->bExplosionProof; m_bExplosionproof = pVehicle->bExplosionProof;
m_bCollisionproof = pVehicle->bCollisionProof; m_bCollisionproof = pVehicle->bCollisionProof;
m_bMeleeproof = pVehicle->bMeleeProof; m_bMeleeproof = pVehicle->bMeleeProof;
if (pVehicle->IsCar()) if (pVehicle->IsCar() || pVehicle->IsBike())
m_nCarBombType = ((CAutomobile*)pVehicle)->m_bombType; m_nCarBombType = ((CAutomobile*)pVehicle)->m_bombType; // NB: cast to CAutomobile is original behaviour
} }
CVehicle* CStoredCar::RestoreCar() CVehicle* CStoredCar::RestoreCar()
@ -1815,9 +1867,7 @@ CVehicle* CStoredCar::RestoreCar()
pVehicle->m_currentColour2 = m_nSecondaryColor; pVehicle->m_currentColour2 = m_nSecondaryColor;
pVehicle->m_nRadioStation = m_nRadioStation; pVehicle->m_nRadioStation = m_nRadioStation;
pVehicle->bFreebies = false; pVehicle->bFreebies = false;
#ifdef FIX_BUGS
if (pVehicle->IsCar()) if (pVehicle->IsCar())
#endif
{ {
((CAutomobile*)pVehicle)->m_bombType = m_nCarBombType; ((CAutomobile*)pVehicle)->m_bombType = m_nCarBombType;
#ifdef FIX_BUGS #ifdef FIX_BUGS
@ -1907,8 +1957,13 @@ bool CGarages::CameraShouldBeOutside()
void CGarages::GivePlayerDetonator() void CGarages::GivePlayerDetonator()
{ {
FindPlayerPed()->GiveWeapon(WEAPONTYPE_DETONATOR, 1); CPlayerPed* pPed = FindPlayerPed();
FindPlayerPed()->GetWeapon(FindPlayerPed()->GetWeaponSlot(WEAPONTYPE_DETONATOR)).m_eWeaponState = WEAPONSTATE_READY; int slot = CWeaponInfo::GetWeaponInfo(WEAPONTYPE_DETONATOR)->m_nWeaponSlot;
pPed->GiveWeapon(WEAPONTYPE_DETONATOR, 1);
pPed->GetWeapon(pPed->GetWeaponSlot(WEAPONTYPE_DETONATOR)).m_eWeaponState = WEAPONSTATE_READY;
pPed->m_nSelectedWepSlot = slot;
if (pPed->m_storedWeapon != WEAPONTYPE_UNIDENTIFIED)
pPed->m_storedWeapon = WEAPONTYPE_DETONATOR;
} }
float CGarages::FindDoorHeightForMI(int32 mi) float CGarages::FindDoorHeightForMI(int32 mi)
@ -1921,8 +1976,7 @@ void CGarage::TidyUpGarage()
uint32 i = CPools::GetVehiclePool()->GetSize(); uint32 i = CPools::GetVehiclePool()->GetSize();
while (i--) { while (i--) {
CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i); CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
if (!pVehicle || !pVehicle->IsCar()) if (pVehicle && (pVehicle->IsCar() || pVehicle->IsBike())) {
continue;
if (IsPointInsideGarage(pVehicle->GetPosition())) { if (IsPointInsideGarage(pVehicle->GetPosition())) {
if (pVehicle->GetStatus() == STATUS_WRECKED || pVehicle->GetUp().z < 0.5f) { if (pVehicle->GetStatus() == STATUS_WRECKED || pVehicle->GetUp().z < 0.5f) {
CWorld::Remove(pVehicle); CWorld::Remove(pVehicle);
@ -1930,6 +1984,7 @@ void CGarage::TidyUpGarage()
} }
} }
} }
}
} }
void CGarage::TidyUpGarageClose() void CGarage::TidyUpGarageClose()
@ -1937,9 +1992,9 @@ void CGarage::TidyUpGarageClose()
uint32 i = CPools::GetVehiclePool()->GetSize(); uint32 i = CPools::GetVehiclePool()->GetSize();
while (i--) { while (i--) {
CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i); CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
if (!pVehicle || !pVehicle->IsCar()) if (!pVehicle)
continue; continue;
if (!pVehicle->IsCar() || pVehicle->GetStatus() != STATUS_WRECKED || !IsEntityTouching3D(pVehicle)) if ((!pVehicle->IsCar() && !pVehicle->IsBike()) || pVehicle->GetStatus() != STATUS_WRECKED || !IsEntityTouching3D(pVehicle))
continue; continue;
bool bRemove = false; bool bRemove = false;
if (m_eGarageState != GS_FULLYCLOSED) { if (m_eGarageState != GS_FULLYCLOSED) {
@ -2088,6 +2143,15 @@ bool CGarages::IsPointWithinHideOutGarage(Const CVector& point)
case GARAGE_HIDEOUT_ONE: case GARAGE_HIDEOUT_ONE:
case GARAGE_HIDEOUT_TWO: case GARAGE_HIDEOUT_TWO:
case GARAGE_HIDEOUT_THREE: case GARAGE_HIDEOUT_THREE:
case GARAGE_HIDEOUT_FOUR:
case GARAGE_HIDEOUT_FIVE:
case GARAGE_HIDEOUT_SIX:
case GARAGE_HIDEOUT_SEVEN:
case GARAGE_HIDEOUT_EIGHT:
case GARAGE_HIDEOUT_NINE:
case GARAGE_HIDEOUT_TEN:
case GARAGE_HIDEOUT_ELEVEN:
case GARAGE_HIDEOUT_TWELVE:
if (aGarages[i].IsPointInsideGarage(point)) if (aGarages[i].IsPointInsideGarage(point))
return true; return true;
default: break; default: break;

View File

@ -187,7 +187,7 @@ class CGarage
bool IsPointInsideGarage(CVector, float); bool IsPointInsideGarage(CVector, float);
void ThrowCarsNearDoorOutOfGarage(CVehicle*); void ThrowCarsNearDoorOutOfGarage(CVehicle*);
int32 FindMaxNumStoredCarsForGarage() { return Max(NUM_GARAGE_STORED_CARS, m_nMaxStoredCars); } int32 FindMaxNumStoredCarsForGarage() { return Min(NUM_GARAGE_STORED_CARS, m_nMaxStoredCars); }
friend class CGarages; friend class CGarages;
friend class cAudioManager; friend class cAudioManager;
@ -198,7 +198,6 @@ class CGarages
{ {
enum { enum {
MESSAGE_LENGTH = 8, MESSAGE_LENGTH = 8,
MAX_NUM_CARS_IN_HIDEOUT_GARAGE = 4
}; };
static int32 BankVansCollected; static int32 BankVansCollected;
static bool BombsAreFree; static bool BombsAreFree;
@ -216,8 +215,7 @@ class CGarages
static bool PlayerInGarage; static bool PlayerInGarage;
static int32 PoliceCarsCollected; static int32 PoliceCarsCollected;
static CGarage aGarages[NUM_GARAGES]; static CGarage aGarages[NUM_GARAGES];
static CStoredCar aCarsInSafeHouses[TOTAL_HIDEOUT_GARAGES][MAX_NUM_CARS_IN_HIDEOUT_GARAGE]; static CStoredCar aCarsInSafeHouses[TOTAL_HIDEOUT_GARAGES][NUM_GARAGE_STORED_CARS];
static int32 AudioEntity;
static bool bCamShouldBeOutisde; static bool bCamShouldBeOutisde;
public: public:

View File

@ -286,6 +286,8 @@ CPathFind::AllocatePathFindInfoMem(int16 numPathGroups)
DetachedInfoForTilePeds = new CPathInfoForObject[12*NUMDETACHED_PEDS]; DetachedInfoForTilePeds = new CPathInfoForObject[12*NUMDETACHED_PEDS];
memset(DetachedInfoForTilePeds, 0, 12*NUMDETACHED_PEDS*sizeof(CPathInfoForObject)); memset(DetachedInfoForTilePeds, 0, 12*NUMDETACHED_PEDS*sizeof(CPathInfoForObject));
delete[] TempExternalNodes;
TempExternalNodes = nil;
TempExternalNodes = new CTempNodeExternal[NUMTEMPEXTERNALNODES]; TempExternalNodes = new CTempNodeExternal[NUMTEMPEXTERNALNODES];
memset(TempExternalNodes, 0, NUMTEMPEXTERNALNODES*sizeof(CTempNodeExternal)); memset(TempExternalNodes, 0, NUMTEMPEXTERNALNODES*sizeof(CTempNodeExternal));
NumTempExternalNodes = 0; NumTempExternalNodes = 0;

View File

@ -69,10 +69,12 @@ void CRecordDataForChase::ProcessControlCars(void)
{ {
} }
#if (defined(GTA_PS2) || defined(FIX_BUGS))
bool CRecordDataForChase::ShouldThisPadBeLeftAlone(uint8 pad) bool CRecordDataForChase::ShouldThisPadBeLeftAlone(uint8 pad)
{ {
return false; return false;
} }
#endif
void CRecordDataForChase::GiveUsACar(int32 mi, CVector pos, float angle, CAutomobile** ppCar, uint8 colour1, uint8 colour2) void CRecordDataForChase::GiveUsACar(int32 mi, CVector pos, float angle, CAutomobile** ppCar, uint8 colour1, uint8 colour2)
{ {

View File

@ -123,16 +123,16 @@ public:
return m_flags[handle>>8].u == (handle & 0xFF) ? return m_flags[handle>>8].u == (handle & 0xFF) ?
(T*)&m_entries[handle >> 8] : nil; (T*)&m_entries[handle >> 8] : nil;
} }
int GetIndex(T *entry){ int GetIndex(T* entry) {
int i = GetJustIndex_NoFreeAssert(entry); int i = GetJustIndex_NoFreeAssert(entry);
return m_flags[i].u + (i<<8); return m_flags[i].u + (i << 8);
} }
int GetJustIndex(T *entry){ int GetJustIndex(T* entry) {
int index = GetJustIndex_NoFreeAssert(entry); int index = GetJustIndex_NoFreeAssert(entry);
assert(!IsFreeSlot(index)); assert(!IsFreeSlot(index));
return index; return index;
} }
int GetJustIndex_NoFreeAssert(T* entry){ int GetJustIndex_NoFreeAssert(T* entry) {
int index = ((U*)entry - m_entries); int index = ((U*)entry - m_entries);
assert((U*)entry == (U*)&m_entries[index]); // cast is unsafe - check required assert((U*)entry == (U*)&m_entries[index]); // cast is unsafe - check required
return index; return index;

View File

@ -27,14 +27,14 @@ IsBuildingPointerValid(CBuilding* pBuilding)
if (!pBuilding) if (!pBuilding)
return false; return false;
if (pBuilding->GetIsATreadable()) { if (pBuilding->GetIsATreadable()) {
int index = CPools::GetTreadablePool()->GetJustIndex((CTreadable*)pBuilding); int index = CPools::GetTreadablePool()->GetJustIndex_NoFreeAssert((CTreadable*)pBuilding);
#ifdef FIX_BUGS #ifdef FIX_BUGS
return index >= 0 && index < CPools::GetTreadablePool()->GetSize(); return index >= 0 && index < CPools::GetTreadablePool()->GetSize();
#else #else
return index >= 0 && index <= CPools::GetTreadablePool()->GetSize(); return index >= 0 && index <= CPools::GetTreadablePool()->GetSize();
#endif #endif
} else { } else {
int index = CPools::GetBuildingPool()->GetJustIndex(pBuilding); int index = CPools::GetBuildingPool()->GetJustIndex_NoFreeAssert(pBuilding);
#ifdef FIX_BUGS #ifdef FIX_BUGS
return index >= 0 && index < CPools::GetBuildingPool()->GetSize(); return index >= 0 && index < CPools::GetBuildingPool()->GetSize();
#else #else

View File

@ -58,7 +58,7 @@ IsDummyPointerValid(CDummy* pDummy)
{ {
if (!pDummy) if (!pDummy)
return false; return false;
int index = CPools::GetDummyPool()->GetJustIndex(pDummy); int index = CPools::GetDummyPool()->GetJustIndex_NoFreeAssert(pDummy);
#ifdef FIX_BUGS #ifdef FIX_BUGS
if (index < 0 || index >= CPools::GetDummyPool()->GetSize()) if (index < 0 || index >= CPools::GetDummyPool()->GetSize())
#else #else

View File

@ -825,7 +825,7 @@ IsObjectPointerValid(CObject *pObject)
{ {
if (!pObject) if (!pObject)
return false; return false;
int index = CPools::GetObjectPool()->GetJustIndex(pObject); int index = CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(pObject);
#ifdef FIX_BUGS #ifdef FIX_BUGS
if (index < 0 || index >= CPools::GetObjectPool()->GetSize()) if (index < 0 || index >= CPools::GetObjectPool()->GetSize())
#else #else

View File

@ -7846,7 +7846,7 @@ IsPedPointerValid_NotInWorld(CPed* pPed)
{ {
if (!pPed) if (!pPed)
return false; return false;
int index = CPools::GetPedPool()->GetJustIndex(pPed); int index = CPools::GetPedPool()->GetJustIndex_NoFreeAssert(pPed);
#ifdef FIX_BUGS #ifdef FIX_BUGS
if (index < 0 || index >= NUMPEDS) if (index < 0 || index >= NUMPEDS)
#else #else

View File

@ -1291,7 +1291,7 @@ INITSAVEBUF
for (int32 j = 0; j < 6; j++) { for (int32 j = 0; j < 6; j++) {
if (pPath->m_pObjects[j] != nil) if (pPath->m_pObjects[j] != nil)
pPath->m_pObjects[j] = (CObject*)(CPools::GetObjectPool()->GetJustIndex(pPath->m_pObjects[j]) + 1); pPath->m_pObjects[j] = (CObject*)(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(pPath->m_pObjects[j]) + 1);
} }
for (int32 j = 0; j < aArray[i].m_numNodes; j++) { for (int32 j = 0; j < aArray[i].m_numNodes; j++) {

View File

@ -205,7 +205,7 @@ CText::GetNameOfLoadedMissionText(char *outName)
void void
CText::ReadChunkHeader(ChunkHeader *buf, int32 file, size_t *offset) CText::ReadChunkHeader(ChunkHeader *buf, int32 file, size_t *offset)
{ {
#if DUMB #if THIS_IS_STUPID
char *_buf = (char*)buf; char *_buf = (char*)buf;
for (int i = 0; i < sizeof(ChunkHeader); i++) { for (int i = 0; i < sizeof(ChunkHeader); i++) {
CFileMgr::Read(file, &_buf[i], 1); CFileMgr::Read(file, &_buf[i], 1);

View File

@ -35,6 +35,9 @@ public:
float m_aWheelPosition[4]; float m_aWheelPosition[4];
float m_aWheelSpeed[4]; float m_aWheelSpeed[4];
uint8 m_auto_unused2; uint8 m_auto_unused2;
#if (defined GTA_PS2 && !defined FIX_BUGS)
uint8 m_bombType : 3;
#endif
uint8 bTaxiLight : 1; uint8 bTaxiLight : 1;
uint8 bFixedColour : 1; uint8 bFixedColour : 1;
uint8 bBigWheels : 1; uint8 bBigWheels : 1;
@ -44,6 +47,9 @@ public:
uint8 bTankDetonateCars : 1; uint8 bTankDetonateCars : 1;
uint8 bStuckInSand : 1; uint8 bStuckInSand : 1;
uint8 bHeliDestroyed : 1; uint8 bHeliDestroyed : 1;
#if (defined GTA_PS2 && !defined FIX_BUGS)
CEntity* m_pBombRigger;
#endif
int16 m_doingBurnout; int16 m_doingBurnout;
uint16 m_hydraulicState; uint16 m_hydraulicState;
uint32 m_nBusDoorTimerEnd; uint32 m_nBusDoorTimerEnd;

View File

@ -2492,7 +2492,7 @@ IsVehiclePointerValid(CVehicle* pVehicle)
{ {
if (!pVehicle) if (!pVehicle)
return false; return false;
int index = CPools::GetVehiclePool()->GetJustIndex(pVehicle); int index = CPools::GetVehiclePool()->GetJustIndex_NoFreeAssert(pVehicle);
#ifdef FIX_BUGS #ifdef FIX_BUGS
if (index < 0 || index >= NUMVEHICLES) if (index < 0 || index >= NUMVEHICLES)
#else #else

View File

@ -248,8 +248,9 @@ public:
uint8 bRestingOnPhysical : 1; // Dont go static cause car is sitting on a physical object that might get removed uint8 bRestingOnPhysical : 1; // Dont go static cause car is sitting on a physical object that might get removed
uint8 bParking : 1; uint8 bParking : 1;
uint8 bCanPark : 1; uint8 bCanPark : 1;
#if (!defined GTA_PS2 || defined FIX_BUGS)
uint8 m_bombType : 3; uint8 m_bombType : 3;
#endif
uint8 bDriverLastFrame : 1; uint8 bDriverLastFrame : 1;
int8 m_numPedsUseItAsCover; int8 m_numPedsUseItAsCover;
@ -259,7 +260,9 @@ public:
float m_fHealth; // 1000.0f = full health. 250.0f = fire. 0 -> explode float m_fHealth; // 1000.0f = full health. 250.0f = fire. 0 -> explode
uint8 m_nCurrentGear; uint8 m_nCurrentGear;
float m_fChangeGearTime; float m_fChangeGearTime;
#if (!defined GTA_PS2 || defined FIX_BUGS)
CEntity* m_pBombRigger; CEntity* m_pBombRigger;
#endif
uint32 m_nSetPieceExtendedRangeTime; uint32 m_nSetPieceExtendedRangeTime;
uint32 m_nGunFiringTime; // last time when gun on vehicle was fired (used on boats) uint32 m_nGunFiringTime; // last time when gun on vehicle was fired (used on boats)
uint32 m_nTimeOfDeath; uint32 m_nTimeOfDeath;

View File

@ -1473,7 +1473,7 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
} }
case ENTITY_TYPE_VEHICLE: case ENTITY_TYPE_VEHICLE:
{ {
if (point->pieceB >= SURFACE_LAMP_POST && point->pieceB <= SURFACE_METAL_CHAIN_FENCE) { if (point->pieceB >= CAR_PIECE_WHEEL_LF && point->pieceB <= CAR_PIECE_WHEEL_RR) {
((CVehicle*)victim)->BurstTyre(point->pieceB, true); ((CVehicle*)victim)->BurstTyre(point->pieceB, true);
for (int32 i = 0; i < 4; i++) for (int32 i = 0; i < 4; i++)
@ -1867,7 +1867,7 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
{ {
case ENTITY_TYPE_VEHICLE: case ENTITY_TYPE_VEHICLE:
{ {
if (point.pieceB >= SURFACE_LAMP_POST && point.pieceB <= SURFACE_METAL_CHAIN_FENCE) { if (point.pieceB >= CAR_PIECE_WHEEL_LF && point.pieceB <= CAR_PIECE_WHEEL_RR) {
((CVehicle*)victim)->BurstTyre(point.pieceB, true); ((CVehicle*)victim)->BurstTyre(point.pieceB, true);
for (int32 i = 0; i < 4; i++) for (int32 i = 0; i < 4; i++)