diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/control/CarCtrl.cpp | 4 | ||||
-rw-r--r-- | src/control/Darkel.cpp | 5 | ||||
-rw-r--r-- | src/control/Garages.cpp | 378 | ||||
-rw-r--r-- | src/control/Garages.h | 6 | ||||
-rw-r--r-- | src/control/PathFind.cpp | 2 | ||||
-rw-r--r-- | src/control/Record.cpp | 2 | ||||
-rw-r--r-- | src/control/Script.cpp | 3 | ||||
-rw-r--r-- | src/control/Script8.cpp | 2 | ||||
-rw-r--r-- | src/core/Cam.cpp | 14 | ||||
-rw-r--r-- | src/core/common.h | 8 | ||||
-rw-r--r-- | src/core/templates.h | 8 | ||||
-rw-r--r-- | src/entities/Building.cpp | 4 | ||||
-rw-r--r-- | src/entities/Dummy.cpp | 2 | ||||
-rw-r--r-- | src/objects/Object.cpp | 2 | ||||
-rw-r--r-- | src/peds/Ped.cpp | 2 | ||||
-rw-r--r-- | src/render/Fluff.cpp | 2 | ||||
-rw-r--r-- | src/skel/glfw/glfw.cpp | 33 | ||||
-rw-r--r-- | src/text/Text.cpp | 2 | ||||
-rw-r--r-- | src/vehicles/Automobile.h | 6 | ||||
-rw-r--r-- | src/vehicles/Vehicle.cpp | 2 | ||||
-rw-r--r-- | src/vehicles/Vehicle.h | 5 | ||||
-rw-r--r-- | src/weapons/Weapon.cpp | 4 |
22 files changed, 328 insertions, 168 deletions
diff --git a/src/control/CarCtrl.cpp b/src/control/CarCtrl.cpp index 3d52a0b0..d4691e2b 100644 --- a/src/control/CarCtrl.cpp +++ b/src/control/CarCtrl.cpp @@ -506,6 +506,10 @@ CCarCtrl::GenerateOneRandomCar() CCarPathLink* pCurrentLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo]; 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( pCurrentLink->GetX() + ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardY, pCurrentLink->GetY() - ((pVehicle->AutoPilot.m_nCurrentLane + pCurrentLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardX, diff --git a/src/control/Darkel.cpp b/src/control/Darkel.cpp index 0f68a989..722ebbcd 100644 --- a/src/control/Darkel.cpp +++ b/src/control/Darkel.cpp @@ -295,11 +295,16 @@ CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, uint16 kill, int32 mode CPlayerPed *player = FindPlayerPed(); if (fixedWeapon < WEAPONTYPE_TOTALWEAPONS) { InterruptedWeaponSelected = player->GetWeapon()->m_eWeaponType; +#if (defined FIX_BUGS || !defined GTA_PS2) player->RemoveWeaponAnims(InterruptedWeaponSelected, -1000.0f); +#endif InterruptedWeaponType = player->GetWeapon(player->GetWeaponSlot(fixedWeapon)).m_eWeaponType; AmmoInterruptedWeapon = player->GetWeapon(player->GetWeaponSlot(fixedWeapon)).m_nAmmoTotal; if (InterruptedWeaponType) CModelInfo::GetModelInfo(CWeaponInfo::GetWeaponInfo((eWeaponType)InterruptedWeaponType)->m_nModelId)->AddRef(); +#if (!defined FIX_BUGS && defined GTA_PS2) + player->RemoveWeaponAnims(InterruptedWeaponSelected, -1000.0f); +#endif player->GiveWeapon(fixedWeapon, 30000); player->SetCurrentWeapon(fixedWeapon); player->MakeChangesForNewWeapon(player->m_nSelectedWepSlot); diff --git a/src/control/Garages.cpp b/src/control/Garages.cpp index 29fc8db1..7d70fcc7 100644 --- a/src/control/Garages.cpp +++ b/src/control/Garages.cpp @@ -45,7 +45,7 @@ // Distances #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_KEEPCAR_GARAGE (17.0f) #define DISTANCE_TO_CLOSE_MISSION_GARAGE (30.0f) @@ -124,8 +124,8 @@ uint32 CGarages::MessageEndTime; uint32 CGarages::NumGarages; bool CGarages::PlayerInGarage; int32 CGarages::PoliceCarsCollected; -CStoredCar CGarages::aCarsInSafeHouses[TOTAL_HIDEOUT_GARAGES][CGarages::MAX_NUM_CARS_IN_HIDEOUT_GARAGE]; -int32 CGarages::AudioEntity = AEHANDLE_NONE; +CStoredCar CGarages::aCarsInSafeHouses[TOTAL_HIDEOUT_GARAGES][NUM_GARAGE_STORED_CARS]; +int32 hHandle = AEHANDLE_NONE; CGarage CGarages::aGarages[NUM_GARAGES]; bool CGarages::bCamShouldBeOutisde; @@ -146,27 +146,27 @@ void CGarages::Init(void) for (int i = 0; i < TOTAL_COLLECTCARS_GARAGES; i++) CarTypesCollected[i] = 0; LastTimeHelpMessage = 0; - for (int i = 0; i < TOTAL_HIDEOUT_GARAGES; i++) { - for (int j = 0; j < MAX_NUM_CARS_IN_HIDEOUT_GARAGE; j++) - aCarsInSafeHouses[i][j].Init(); + for (int i = 0; i < NUM_GARAGE_STORED_CARS; i++) { + for (int j = 0; j < TOTAL_HIDEOUT_GARAGES; j++) + aCarsInSafeHouses[j][i].Init(); } - AudioEntity = DMAudio.CreateEntity(AUDIOTYPE_GARAGE, (void*)1); - if (AudioEntity >= 0) - DMAudio.SetEntityStatus(AudioEntity, 1); + hHandle = DMAudio.CreateEntity(AUDIOTYPE_GARAGE, (void*)1); + if (hHandle >= 0) + DMAudio.SetEntityStatus(hHandle, 1); } void CGarages::Shutdown(void) { NumGarages = 0; - if (AudioEntity < 0) + if (hHandle < 0) return; - DMAudio.DestroyEntity(AudioEntity); - AudioEntity = AEHANDLE_NONE; + DMAudio.DestroyEntity(hHandle); + hHandle = AEHANDLE_NONE; } void CGarages::Update(void) { - static int GarageToBeTidied = 0; + static uint32 GarageToBeTidied = 0; #ifndef PS2 if (CReplay::IsPlayingBack()) return; @@ -174,13 +174,21 @@ void CGarages::Update(void) bCamShouldBeOutisde = false; TheCamera.pToGarageWeAreIn = nil; TheCamera.pToGarageWeAreInForHackAvoidFirstPerson = nil; +#ifdef FIX_BUGS + for (uint32 i = 0; i < NumGarages; i++) { +#else for (int i = 0; i < NUM_GARAGES; i++) { +#endif if (aGarages[i].IsUsed()) aGarages[i].Update(); } if ((CTimer::GetFrameCounter() & 0xF) != 0xC) return; +#ifdef FIX_BUGS + if (++GarageToBeTidied >= NumGarages) +#else if (++GarageToBeTidied >= NUM_GARAGES) +#endif GarageToBeTidied = 0; if (!aGarages[GarageToBeTidied].IsUsed()) return; @@ -337,6 +345,43 @@ void CGarage::Update() } if (m_bDeactivated && m_eGarageState == GS_FULLYCLOSED) 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) { case GARAGE_RESPRAY: switch (m_eGarageState) { @@ -376,7 +421,7 @@ void CGarage::Update() if (m_fDoorPos == 0.0f) { m_eGarageState = GS_FULLYCLOSED; 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(); } UpdateDoorsHeight(); @@ -480,7 +525,7 @@ void CGarage::Update() m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == m_fDoorHeight) { m_eGarageState = GS_OPENEDCONTAINSCAR; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); + DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_OPENED, 1.0f); } UpdateDoorsHeight(); break; @@ -524,7 +569,7 @@ void CGarage::Update() if (m_fDoorPos == 0.0f) { m_eGarageState = GS_FULLYCLOSED; 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(); if (m_eGarageType == GARAGE_BOMBSHOP3) @@ -537,14 +582,18 @@ void CGarage::Update() case GARAGE_BOMBSHOP1: DMAudio.PlayFrontEndSound(SOUND_GARAGE_BOMB1_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; - default: break; } m_eGarageState = GS_OPENING; if (!CGarages::BombsAreFree) CWorld::Players[CWorld::PlayerInFocus].m_nMoney = Max(0, CWorld::Players[CWorld::PlayerInFocus].m_nMoney - BOMB_PRICE); if (FindPlayerVehicle() && (FindPlayerVehicle()->IsCar() || FindPlayerVehicle()->IsBike())) { +#if (!defined GTA_PS2 || defined FIX_BUGS) FindPlayerVehicle()->m_bombType = CGarages::GetBombTypeForGarageType(m_eGarageType); 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) CGarages::GivePlayerDetonator(); CStats::KgsOfExplosivesUsed += KGS_OF_EXPLOSIVES_IN_BOMB; @@ -582,7 +631,6 @@ void CGarage::Update() case GARAGE_BOMBSHOP3: CHud::SetHelpMessage(TheText.Get("GA_8"), false); // Use the detonator to activate the bomb. break; - default: break; } CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_GARAGE); FindPlayerPed()->m_pWanted->m_bIgnoredByCops = false; @@ -596,7 +644,7 @@ void CGarage::Update() m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == m_fDoorHeight) { m_eGarageState = GS_OPENEDCONTAINSCAR; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); + DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_OPENED, 1.0f); } UpdateDoorsHeight(); break; @@ -614,13 +662,17 @@ void CGarage::Update() switch (m_eGarageState) { case GS_OPENED: 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_bClosingWithoutTargetCar = true; } } 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); FindPlayerPed()->m_pWanted->m_bIgnoredByCops = true; m_eGarageState = GS_CLOSING; @@ -632,7 +684,7 @@ void CGarage::Update() ThrowCarsNearDoorOutOfGarage(m_pTarget); m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); 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) m_eGarageState = GS_FULLYCLOSED; else { @@ -662,7 +714,7 @@ void CGarage::Update() m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == m_fDoorHeight) { m_eGarageState = GS_OPENED; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); + DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_OPENED, 1.0f); } UpdateDoorsHeight(); break; @@ -715,7 +767,7 @@ void CGarage::Update() m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == 0.0f) { 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) { MarkThisCarAsCollectedForCraig(m_pTarget->GetModelIndex()); DestroyVehicleAndDriverAndPassengers(m_pTarget); @@ -755,7 +807,7 @@ void CGarage::Update() m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == m_fDoorHeight) { m_eGarageState = GS_OPENED; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); + DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_OPENED, 1.0f); } UpdateDoorsHeight(); break; @@ -776,7 +828,7 @@ void CGarage::Update() m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == 0.0f) { 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()) m_eGarageState = GS_OPENING; @@ -787,7 +839,7 @@ void CGarage::Update() m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == m_fDoorHeight) { m_eGarageState = GS_OPENED; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); + DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_OPENED, 1.0f); } UpdateDoorsHeight(); break; @@ -821,7 +873,7 @@ void CGarage::Update() ThrowCarsNearDoorOutOfGarage(m_pTarget); m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); 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) m_eGarageState = GS_FULLYCLOSED; else { @@ -850,7 +902,7 @@ void CGarage::Update() m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == m_fDoorHeight) { m_eGarageState = GS_OPENED; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); + DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_OPENED, 1.0f); } UpdateDoorsHeight(); break; @@ -870,7 +922,7 @@ void CGarage::Update() m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == m_fDoorHeight) { m_eGarageState = GS_OPENED; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); + DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_OPENED, 1.0f); } UpdateDoorsHeight(); break; @@ -890,7 +942,7 @@ void CGarage::Update() m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == 0.0f) { m_eGarageState = GS_FULLYCLOSED; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f); + DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_CLOSED, 1.0f); } UpdateDoorsHeight(); break; @@ -898,7 +950,7 @@ void CGarage::Update() m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == m_fDoorHeight) { m_eGarageState = GS_OPENED; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); + DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_OPENED, 1.0f); } UpdateDoorsHeight(); break; @@ -930,8 +982,8 @@ void CGarage::Update() // 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 if ((distance > SQR(DISTANCE_TO_CLOSE_HIDEOUT_GARAGE_IN_CAR) || - !FindPlayerVehicle() && distance > SQR(DISTANCE_TO_CLOSE_HIDEOUT_GARAGE_ON_FOOT) && - !IsAnyCarBlockingDoor())) + !FindPlayerVehicle() && distance > SQR(DISTANCE_TO_CLOSE_HIDEOUT_GARAGE_ON_FOOT)) && + !IsAnyCarBlockingDoor()) m_eGarageState = GS_CLOSING; else if (FindPlayerVehicle() && CountCarsWithCenterPointWithinGarage(FindPlayerVehicle()) >= @@ -949,7 +1001,7 @@ void CGarage::Update() if (!IsPlayerOutsideGarage()) m_eGarageState = GS_OPENING; 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; StoreAndRemoveCarsForThisHideout(CGarages::aCarsInSafeHouses[CGarages::FindSafeHouseIndexForGarageType(m_eGarageType)], NUM_GARAGE_STORED_CARS); } @@ -980,7 +1032,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()); if (m_fDoorPos == m_fDoorHeight) { m_eGarageState = GS_OPENED; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); + DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_OPENED, 1.0f); } UpdateDoorsHeight(); break; @@ -1007,7 +1059,7 @@ void CGarage::Update() m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == 0.0f) { m_eGarageState = GS_FULLYCLOSED; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f); + DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_CLOSED, 1.0f); } UpdateDoorsHeight(); break; @@ -1023,7 +1075,7 @@ void CGarage::Update() m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == m_fDoorHeight) { m_eGarageState = GS_OPENED; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); + DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_OPENED, 1.0f); } UpdateDoorsHeight(); break; @@ -1034,8 +1086,8 @@ void CGarage::Update() break; } break; - //case GARAGE_COLLECTORSITEMS: - //case GARAGE_60SECONDS: + //case GARAGE_COLLECTORSITEMS: + //case GARAGE_60SECONDS: case GARAGE_FOR_SCRIPT_TO_OPEN_FOR_CAR: switch (m_eGarageState) { case GS_OPENED: @@ -1048,7 +1100,7 @@ void CGarage::Update() m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == 0.0f) { 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); } case GS_FULLYCLOSED: @@ -1057,7 +1109,7 @@ void CGarage::Update() m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep()); if (m_fDoorPos == m_fDoorHeight) { m_eGarageState = GS_OPENED; - DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f); + DMAudio.PlayOneShot(hHandle, SOUND_GARAGE_DOOR_OPENED, 1.0f); } UpdateDoorsHeight(); break; @@ -1072,28 +1124,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() { if (!FindPlayerVehicle()) @@ -1158,7 +1188,7 @@ bool CGarage::IsPointInsideGarage(CVector pos, float m_fMargin) 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 || pEntity->GetPosition().y < m_fInfY - fMargin || pEntity->GetPosition().y > m_fSupY + fMargin || @@ -1210,12 +1240,12 @@ bool CGarage::IsPlayerOutsideGarage() return IsEntityEntirelyOutside(FindPlayerPed(), 0.0f); } -bool CGarage::IsEntityTouching3D(CEntity * pEntity) +bool CGarage::IsEntityTouching3D(CEntity* pEntity) { float radius = pEntity->GetBoundRadius(); - if (pEntity->GetPosition().x - radius < m_fInfX || pEntity->GetPosition().x + radius > m_fSupX || - pEntity->GetPosition().y - radius < m_fInfY || pEntity->GetPosition().y + radius > m_fSupY || - pEntity->GetPosition().z - radius < m_fInfZ || pEntity->GetPosition().z + radius > m_fSupZ) + if (m_fInfX - radius > pEntity->GetPosition().x || m_fSupX + radius < pEntity->GetPosition().x || + m_fInfY - radius > pEntity->GetPosition().y || m_fSupY + radius < pEntity->GetPosition().y || + m_fInfZ - radius > pEntity->GetPosition().z || m_fSupZ + radius < pEntity->GetPosition().z) return false; CColModel* pColModel = pEntity->GetColModel(); for (int i = 0; i < pColModel->numSpheres; i++) { @@ -1259,6 +1289,28 @@ bool CGarage::IsAnyOtherCarTouchingGarage(CVehicle * pException) 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) { uint32 i = CPools::GetPedPool()->GetSize(); @@ -1326,7 +1378,9 @@ void CGarage::RemoveCarsBlockingDoorNotInside() if (!pVehicle->bIsLocked && pVehicle->CanBeDeleted()) { CWorld::Remove(pVehicle); delete pVehicle; - return; // WHY? +#ifndef FIX_BUGS + return; +#endif } } } @@ -1335,43 +1389,34 @@ void CGarage::RemoveCarsBlockingDoorNotInside() void CGarages::PrintMessages() { 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::SetJustifyOff(); CFont::SetBackgroundOff(); CFont::SetCentreSize(SCREEN_SCALE_X(590.0f)); CFont::SetCentreOn(); 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) - float y_offset = SCREEN_HEIGHT / 3; // THIS is PS2 calculation +#if defined(GTA_PS2) || defined (FIX_BUGS) + float y_offset = SCREEN_HEIGHT / 3 - SCREEN_SCALE_Y(40.0f); // THIS is PS2 calculation #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 #endif - 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); - } + if (MessageNumberInString2 >= 0) { + CMessages::InsertNumberInString(TheText.Get(MessageIDString), MessageNumberInString, MessageNumberInString2, -1, -1, -1, -1, gUString); + CFont::PrintString(SCREEN_WIDTH / 2, y_offset - SCREEN_SCALE_Y(30.0f), gUString); + } + else if (MessageNumberInString >= 0) { + 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 { - 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::SetColor(CRGBA(27, 89, 130, 255)); - CFont::PrintString(SCREEN_WIDTH / 2, y_offset - SCREEN_SCALE_Y(40.0f), gUString); + CFont::PrintString(SCREEN_WIDTH / 2, y_offset, TheText.Get(MessageIDString)); } } } @@ -1388,7 +1433,9 @@ bool CGarages::IsCarSprayable(CVehicle * pVehicle) case MI_BARRACKS: case MI_DODO: case MI_COACH: +#ifndef GTA_PS2 case MI_FBIRANCH: +#endif return false; default: break; @@ -1460,41 +1507,54 @@ void CGarage::UpdateCrusherShake(float X, float 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) +void CGarage::RefreshDoorPointers(bool bCreate) { - 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)) + bool bNeedToFindDoorEntities = bCreate || m_bRecreateDoorOnNextRefresh; + m_bRecreateDoorOnNextRefresh = false; + if (m_pDoor1) { + if (m_bDoor1IsDummy) { + if (CPools::GetDummyPool()->IsFreeSlot(CPools::GetDummyPool()->GetJustIndex_NoFreeAssert((CDummy*)m_pDoor1))) bNeedToFindDoorEntities = true; - if (!CGarages::IsModelIndexADoor(pDoor->GetModelIndex())) - return true; + else { + if (m_bDoor1PoolIndex != (CPools::GetDummyPool()->GetIndex((CDummy*)m_pDoor1) & 0x7F)) + bNeedToFindDoorEntities = true; + if (!CGarages::IsModelIndexADoor(m_pDoor1->GetModelIndex())) + bNeedToFindDoorEntities = true; + } } else { - if (CPools::GetObjectPool()->IsFreeSlot(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert((CObject*)pDoor))) - return true; - if (nIndex != (CPools::GetObjectPool()->GetIndex((CObject*)pDoor) & 0x7F)) + if (CPools::GetObjectPool()->IsFreeSlot(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert((CObject*)m_pDoor1))) bNeedToFindDoorEntities = true; - if (!CGarages::IsModelIndexADoor(pDoor->GetModelIndex())) - return 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; + } } } - return bNeedToFindDoorEntities; -} - -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)) - bNeedToFindDoorEntities = true; if (bNeedToFindDoorEntities) FindDoorsEntities(); } @@ -1518,7 +1578,7 @@ void CGarages::TriggerMessage(const char* text, int16 num1, uint16 time, int16 n MessageNumberInString2 = num2; } -void CGarages::SetTargetCarForMissonGarage(int16 garage, CVehicle * pVehicle) +void CGarages::SetTargetCarForMissonGarage(int16 garage, CVehicle* pVehicle) { assert(garage >= 0 && garage < NUM_GARAGES); if (pVehicle) { @@ -1661,9 +1721,9 @@ void CGarage::FindDoorsEntities() { m_pDoor1 = 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 ystart = Max(0, CWorld::GetSectorIndexY(m_fInfY)); + int ystart = Max(0, CWorld::GetSectorIndexY(GetGarageCenterY())); int yend = Min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(m_fSupY)); assert(xstart <= xend); assert(ystart <= yend); @@ -1777,8 +1837,8 @@ void CStoredCar::StoreCar(CVehicle* pVehicle) m_bExplosionproof = pVehicle->bExplosionProof; m_bCollisionproof = pVehicle->bCollisionProof; m_bMeleeproof = pVehicle->bMeleeProof; - if (pVehicle->IsCar()) - m_nCarBombType = ((CAutomobile*)pVehicle)->m_bombType; + if (pVehicle->IsCar() || pVehicle->IsBike()) + m_nCarBombType = ((CAutomobile*)pVehicle)->m_bombType; // NB: cast to CAutomobile is original behaviour } CVehicle* CStoredCar::RestoreCar() @@ -1815,9 +1875,7 @@ CVehicle* CStoredCar::RestoreCar() pVehicle->m_currentColour2 = m_nSecondaryColor; pVehicle->m_nRadioStation = m_nRadioStation; pVehicle->bFreebies = false; -#ifdef FIX_BUGS if (pVehicle->IsCar()) -#endif { ((CAutomobile*)pVehicle)->m_bombType = m_nCarBombType; #ifdef FIX_BUGS @@ -1880,7 +1938,11 @@ bool CGarage::RestoreCarsForThisHideout(CStoredCar* aCars) bool CGarages::IsPointInAGarageCameraZone(CVector point) { +#ifdef FIX_BUGS + for (uint32 i = 0; i < NumGarages; i++) { +#else for (int i = 0; i < NUM_GARAGES; i++) { +#endif switch (aGarages[i].m_eGarageType) { case GARAGE_NONE: break; @@ -1907,8 +1969,13 @@ bool CGarages::CameraShouldBeOutside() void CGarages::GivePlayerDetonator() { - FindPlayerPed()->GiveWeapon(WEAPONTYPE_DETONATOR, 1); - FindPlayerPed()->GetWeapon(FindPlayerPed()->GetWeaponSlot(WEAPONTYPE_DETONATOR)).m_eWeaponState = WEAPONSTATE_READY; + CPlayerPed* pPed = FindPlayerPed(); + 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) @@ -1921,12 +1988,12 @@ void CGarage::TidyUpGarage() uint32 i = CPools::GetVehiclePool()->GetSize(); while (i--) { CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i); - if (!pVehicle || !pVehicle->IsCar()) - continue; - if (IsPointInsideGarage(pVehicle->GetPosition())) { - if (pVehicle->GetStatus() == STATUS_WRECKED || pVehicle->GetUp().z < 0.5f) { - CWorld::Remove(pVehicle); - delete pVehicle; + if (pVehicle && (pVehicle->IsCar() || pVehicle->IsBike())) { + if (IsPointInsideGarage(pVehicle->GetPosition())) { + if (pVehicle->GetStatus() == STATUS_WRECKED || pVehicle->GetUp().z < 0.5f) { + CWorld::Remove(pVehicle); + delete pVehicle; + } } } } @@ -1937,9 +2004,9 @@ void CGarage::TidyUpGarageClose() uint32 i = CPools::GetVehiclePool()->GetSize(); while (i--) { CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i); - if (!pVehicle || !pVehicle->IsCar()) + if (!pVehicle) continue; - if (!pVehicle->IsCar() || pVehicle->GetStatus() != STATUS_WRECKED || !IsEntityTouching3D(pVehicle)) + if ((!pVehicle->IsCar() && !pVehicle->IsBike()) || pVehicle->GetStatus() != STATUS_WRECKED || !IsEntityTouching3D(pVehicle)) continue; bool bRemove = false; if (m_eGarageState != GS_FULLYCLOSED) { @@ -1964,7 +2031,11 @@ void CGarage::TidyUpGarageClose() void CGarages::PlayerArrestedOrDied() { static int GarageToBeTidied = 0; // lol +#ifdef FIX_BUGS + for (uint32 i = 0; i < NumGarages; i++) { +#else for (int i = 0; i < NUM_GARAGES; i++) { +#endif if (aGarages[i].m_eGarageType != GARAGE_NONE) aGarages[i].PlayerArrestedOrDied(); } @@ -2059,16 +2130,20 @@ void CGarage::CenterCarInGarage(CVehicle* pVehicle) void CGarages::CloseHideOutGaragesBeforeSave() { +#ifdef FIX_BUGS + for (uint32 i = 0; i < NumGarages; i++) { +#else for (int i = 0; i < NUM_GARAGES; i++) { +#endif if (!IsThisGarageTypeSafehouse(aGarages[i].m_eGarageType)) continue; if (aGarages[i].m_eGarageState != GS_FULLYCLOSED) { aGarages[i].m_eGarageState = GS_FULLYCLOSED; aGarages[i].StoreAndRemoveCarsForThisHideout(aCarsInSafeHouses[FindSafeHouseIndexForGarageType(aGarages[i].m_eGarageType)], NUM_GARAGE_STORED_CARS); aGarages[i].RemoveCarsBlockingDoorNotInside(); + aGarages[i].m_fDoorPos = 0.0f; + aGarages[i].UpdateDoorsHeight(); } - aGarages[i].m_fDoorPos = 0.0f; - aGarages[i].UpdateDoorsHeight(); } } @@ -2083,11 +2158,24 @@ int32 CGarages::CountCarsInHideoutGarage(uint8 type) bool CGarages::IsPointWithinHideOutGarage(Const CVector& point) { +#ifdef FIX_BUGS + for (uint32 i = 0; i < NumGarages; i++) { +#else for (int i = 0; i < NUM_GARAGES; i++) { +#endif switch (aGarages[i].m_eGarageType) { case GARAGE_HIDEOUT_ONE: case GARAGE_HIDEOUT_TWO: 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)) return true; default: break; @@ -2098,7 +2186,11 @@ bool CGarages::IsPointWithinHideOutGarage(Const CVector& point) bool CGarages::IsPointWithinAnyGarage(Const CVector& point) { +#ifdef FIX_BUGS + for (uint32 i = 0; i < NumGarages; i++) { +#else for (int i = 0; i < NUM_GARAGES; i++) { +#endif switch (aGarages[i].m_eGarageType) { case GARAGE_NONE: continue; @@ -2112,7 +2204,11 @@ bool CGarages::IsPointWithinAnyGarage(Const CVector& point) void CGarages::SetAllDoorsBackToOriginalHeight() { +#ifdef FIX_BUGS + for (uint32 i = 0; i < NumGarages; i++) { +#else for (int i = 0; i < NUM_GARAGES; i++) { +#endif switch (aGarages[i].m_eGarageType) { case GARAGE_NONE: continue; diff --git a/src/control/Garages.h b/src/control/Garages.h index 26a5ab41..46ae1542 100644 --- a/src/control/Garages.h +++ b/src/control/Garages.h @@ -187,7 +187,7 @@ class CGarage bool IsPointInsideGarage(CVector, float); 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 cAudioManager; @@ -198,7 +198,6 @@ class CGarages { enum { MESSAGE_LENGTH = 8, - MAX_NUM_CARS_IN_HIDEOUT_GARAGE = 4 }; static int32 BankVansCollected; static bool BombsAreFree; @@ -216,8 +215,7 @@ class CGarages static bool PlayerInGarage; static int32 PoliceCarsCollected; static CGarage aGarages[NUM_GARAGES]; - static CStoredCar aCarsInSafeHouses[TOTAL_HIDEOUT_GARAGES][MAX_NUM_CARS_IN_HIDEOUT_GARAGE]; - static int32 AudioEntity; + static CStoredCar aCarsInSafeHouses[TOTAL_HIDEOUT_GARAGES][NUM_GARAGE_STORED_CARS]; static bool bCamShouldBeOutisde; public: diff --git a/src/control/PathFind.cpp b/src/control/PathFind.cpp index e10693eb..aa453701 100644 --- a/src/control/PathFind.cpp +++ b/src/control/PathFind.cpp @@ -286,6 +286,8 @@ CPathFind::AllocatePathFindInfoMem(int16 numPathGroups) DetachedInfoForTilePeds = new CPathInfoForObject[12*NUMDETACHED_PEDS]; memset(DetachedInfoForTilePeds, 0, 12*NUMDETACHED_PEDS*sizeof(CPathInfoForObject)); + delete[] TempExternalNodes; + TempExternalNodes = nil; TempExternalNodes = new CTempNodeExternal[NUMTEMPEXTERNALNODES]; memset(TempExternalNodes, 0, NUMTEMPEXTERNALNODES*sizeof(CTempNodeExternal)); NumTempExternalNodes = 0; diff --git a/src/control/Record.cpp b/src/control/Record.cpp index 9b4a21fc..f10a6d00 100644 --- a/src/control/Record.cpp +++ b/src/control/Record.cpp @@ -69,10 +69,12 @@ void CRecordDataForChase::ProcessControlCars(void) { } +#if (defined(GTA_PS2) || defined(FIX_BUGS)) bool CRecordDataForChase::ShouldThisPadBeLeftAlone(uint8 pad) { return false; } +#endif void CRecordDataForChase::GiveUsACar(int32 mi, CVector pos, float angle, CAutomobile** ppCar, uint8 colour1, uint8 colour2) { diff --git a/src/control/Script.cpp b/src/control/Script.cpp index ff72d664..8638abe8 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -2332,6 +2332,7 @@ CRunningScript* CTheScripts::StartNewScript(uint32 ip) pNew->Init(); pNew->SetIP(ip); pNew->AddScriptToList(&pActiveScripts); + pNew->m_bIsActive = true; return pNew; } @@ -2416,6 +2417,8 @@ void CTheScripts::Process() script->UpdateTimers(timeStep); script->Process(); script = next; + if (script && !script->m_bIsActive) + script = nil; } DbgFlag = false; #ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT diff --git a/src/control/Script8.cpp b/src/control/Script8.cpp index ddeaf64b..08965e72 100644 --- a/src/control/Script8.cpp +++ b/src/control/Script8.cpp @@ -63,7 +63,7 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command) case COMMAND_SET_MAXIMUM_NUMBER_OF_CARS_IN_GARAGE: CollectParameters(&m_nIp, 2); CGarages::SetMaxNumStoredCarsForGarage(ScriptParams[0], ScriptParams[1]); - break; + return 0; case COMMAND_WANTED_STARS_ARE_FLASHING: { CWanted *pWanted = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted; diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp index bc01b58e..d1ff6ddb 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -5250,11 +5250,14 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, float timestepFactor = Pow(0.99f, CTimer::GetTimeStep()); dontCollideWithCars = (timestepFactor * dontCollideWithCars) + ((1.0f - timestepFactor) * car->m_vecMoveSpeed.Magnitude()); + // Our addition +#define IS_TRAFFIC_LIGHT(ent) (ent->IsObject() && IsLightObject(ent->GetModelIndex())) + // Move cam if on collision CColPoint foundCol; CEntity* foundEnt; CWorld::pIgnoreEntity = CamTargetEntity; - if (CWorld::ProcessLineOfSight(TargetCoors, Source, foundCol, foundEnt, true, dontCollideWithCars < 0.1f, false, false, false, true, false)) { + if (CWorld::ProcessLineOfSight(TargetCoors, Source, foundCol, foundEnt, true, dontCollideWithCars < 0.1f, false, true, false, true, false) && !IS_TRAFFIC_LIGHT(foundEnt)) { float obstacleTargetDist = (TargetCoors - foundCol.point).Magnitude(); float obstacleCamDist = newDistance - obstacleTargetDist; if (!foundEnt->IsPed() || obstacleCamDist <= 1.0f) { @@ -5263,7 +5266,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, RwCameraSetNearClipPlane(Scene.camera, Max(0.05f, obstacleTargetDist - 0.3f)); } } else { - if (!CWorld::ProcessLineOfSight(foundCol.point, Source, foundCol, foundEnt, true, dontCollideWithCars < 0.1f, false, false, false, true, false)) { + if (!CWorld::ProcessLineOfSight(foundCol.point, Source, foundCol, foundEnt, true, dontCollideWithCars < 0.1f, false, true, false, true, false) || IS_TRAFFIC_LIGHT(foundEnt)) { float lessClip = obstacleCamDist - 0.35f; if (lessClip <= DEFAULT_NEAR) RwCameraSetNearClipPlane(Scene.camera, lessClip); @@ -5282,6 +5285,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, } } } + CWorld::pIgnoreEntity = nil; float nearClip = RwCameraGetNearClipPlane(Scene.camera); float radius = Tan(DEGTORAD(FOV * 0.5f)) * CDraw::GetAspectRatio() * 1.1f; @@ -5289,9 +5293,12 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, // If we're seeing blue hell due to camera intersects some surface, fix it. // SA and LCS have this unrolled. for (int i = 0; - i <= 5 && CWorld::TestSphereAgainstWorld((nearClip * Front) + Source, radius * nearClip, nil, true, true, false, true, false, false); + i <= 5 && (foundEnt = CWorld::TestSphereAgainstWorld((nearClip * Front) + Source, radius * nearClip, nil, true, true, false, true, false, false)); i++) { + if (IS_TRAFFIC_LIGHT(foundEnt)) + break; + CVector surfaceCamDist = gaTempSphereColPoints->point - Source; CVector frontButInvertedIfTouchesSurface = DotProduct(surfaceCamDist, Front) * Front; float newNearClip = (surfaceCamDist - frontButInvertedIfTouchesSurface).Magnitude() / radius; @@ -5309,6 +5316,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation, nearClip = RwCameraGetNearClipPlane(Scene.camera); radius = Tan(DEGTORAD(FOV * 0.5f)) * CDraw::GetAspectRatio() * 1.1f; } +#undef IS_TRAFFIC_LIGHT } TheCamera.m_bCamDirectlyBehind = false; TheCamera.m_bCamDirectlyInFront = false; diff --git a/src/core/common.h b/src/core/common.h index 9c81cf3b..181389da 100644 --- a/src/core/common.h +++ b/src/core/common.h @@ -251,8 +251,14 @@ void re3_usererror(const char *format, ...); #define DEBUGBREAK() __debugbreak(); -#define debug(f, ...) re3_debug("[DBG]: " f, ## __VA_ARGS__) +// Switch to enable development messages. +#if 1 +#define DEV(f, ...) +#else #define DEV(f, ...) re3_debug("[DEV]: " f, ## __VA_ARGS__) +#endif + +#define debug(f, ...) re3_debug("[DBG]: " f, ## __VA_ARGS__) #define TRACE(f, ...) re3_trace(__FILE__, __LINE__, __FUNCTION__, f, ## __VA_ARGS__) #define Error(f, ...) re3_debug("[ERROR]: " f, ## __VA_ARGS__) #define USERERROR(f, ...) re3_usererror(f, ## __VA_ARGS__) diff --git a/src/core/templates.h b/src/core/templates.h index 704331c3..bb89814e 100644 --- a/src/core/templates.h +++ b/src/core/templates.h @@ -123,16 +123,16 @@ public: return m_flags[handle>>8].u == (handle & 0xFF) ? (T*)&m_entries[handle >> 8] : nil; } - int GetIndex(T *entry){ + int GetIndex(T* 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); assert(!IsFreeSlot(index)); return index; } - int GetJustIndex_NoFreeAssert(T* entry){ + int GetJustIndex_NoFreeAssert(T* entry) { int index = ((U*)entry - m_entries); assert((U*)entry == (U*)&m_entries[index]); // cast is unsafe - check required return index; diff --git a/src/entities/Building.cpp b/src/entities/Building.cpp index 921055ce..8035cf25 100644 --- a/src/entities/Building.cpp +++ b/src/entities/Building.cpp @@ -27,14 +27,14 @@ IsBuildingPointerValid(CBuilding* pBuilding) if (!pBuilding) return false; if (pBuilding->GetIsATreadable()) { - int index = CPools::GetTreadablePool()->GetJustIndex((CTreadable*)pBuilding); + int index = CPools::GetTreadablePool()->GetJustIndex_NoFreeAssert((CTreadable*)pBuilding); #ifdef FIX_BUGS return index >= 0 && index < CPools::GetTreadablePool()->GetSize(); #else return index >= 0 && index <= CPools::GetTreadablePool()->GetSize(); #endif } else { - int index = CPools::GetBuildingPool()->GetJustIndex(pBuilding); + int index = CPools::GetBuildingPool()->GetJustIndex_NoFreeAssert(pBuilding); #ifdef FIX_BUGS return index >= 0 && index < CPools::GetBuildingPool()->GetSize(); #else diff --git a/src/entities/Dummy.cpp b/src/entities/Dummy.cpp index 544e24a6..580245a8 100644 --- a/src/entities/Dummy.cpp +++ b/src/entities/Dummy.cpp @@ -58,7 +58,7 @@ IsDummyPointerValid(CDummy* pDummy) { if (!pDummy) return false; - int index = CPools::GetDummyPool()->GetJustIndex(pDummy); + int index = CPools::GetDummyPool()->GetJustIndex_NoFreeAssert(pDummy); #ifdef FIX_BUGS if (index < 0 || index >= CPools::GetDummyPool()->GetSize()) #else diff --git a/src/objects/Object.cpp b/src/objects/Object.cpp index 16483cca..0605f54f 100644 --- a/src/objects/Object.cpp +++ b/src/objects/Object.cpp @@ -825,7 +825,7 @@ IsObjectPointerValid(CObject *pObject) { if (!pObject) return false; - int index = CPools::GetObjectPool()->GetJustIndex(pObject); + int index = CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(pObject); #ifdef FIX_BUGS if (index < 0 || index >= CPools::GetObjectPool()->GetSize()) #else diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index e57671e3..3c1fc552 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -7817,7 +7817,7 @@ IsPedPointerValid_NotInWorld(CPed* pPed) { if (!pPed) return false; - int index = CPools::GetPedPool()->GetJustIndex(pPed); + int index = CPools::GetPedPool()->GetJustIndex_NoFreeAssert(pPed); #ifdef FIX_BUGS if (index < 0 || index >= NUMPEDS) #else diff --git a/src/render/Fluff.cpp b/src/render/Fluff.cpp index 3c0d3708..e220ce5a 100644 --- a/src/render/Fluff.cpp +++ b/src/render/Fluff.cpp @@ -1291,7 +1291,7 @@ INITSAVEBUF for (int32 j = 0; j < 6; j++) { 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++) { diff --git a/src/skel/glfw/glfw.cpp b/src/skel/glfw/glfw.cpp index c219e711..a73db217 100644 --- a/src/skel/glfw/glfw.cpp +++ b/src/skel/glfw/glfw.cpp @@ -70,9 +70,6 @@ static psGlobalType PsGlobal; #define PSGLOBAL(var) (((psGlobalType *)(RsGlobal.ps))->var) -#undef MAKEPOINTS -#define MAKEPOINTS(l) (*((POINTS /*FAR*/ *)&(l))) - size_t _dwMemAvailPhys; RwUInt32 gGameState; @@ -878,6 +875,36 @@ void _InputInitialiseJoys() PSGLOBAL(joy1id) = -1; PSGLOBAL(joy2id) = -1; + // Load our gamepad mappings. +#define SDL_GAMEPAD_DB_PATH "gamecontrollerdb.txt" + FILE *f = fopen(SDL_GAMEPAD_DB_PATH, "rb"); + if (f) { + fseek(f, 0, SEEK_END); + size_t fsize = ftell(f); + fseek(f, 0, SEEK_SET); + + char *db = (char*)malloc(fsize + 1); + if (fread(db, 1, fsize, f) == fsize) { + db[fsize] = '\0'; + + if (glfwUpdateGamepadMappings(db) == GLFW_FALSE) + Error("glfwUpdateGamepadMappings didn't succeed, check " SDL_GAMEPAD_DB_PATH ".\n"); + } else + Error("fread on " SDL_GAMEPAD_DB_PATH " wasn't successful.\n"); + + free(db); + fclose(f); + } else + printf("You don't seem to have copied " SDL_GAMEPAD_DB_PATH " file from re3/gamefiles to GTA3 directory. Some gamepads may not be recognized.\n"); + +#undef SDL_GAMEPAD_DB_PATH + + // But always overwrite it with the one in SDL_GAMECONTROLLERCONFIG. + char const* EnvControlConfig = getenv("SDL_GAMECONTROLLERCONFIG"); + if (EnvControlConfig != nil) { + glfwUpdateGamepadMappings(EnvControlConfig); + } + for (int i = 0; i <= GLFW_JOYSTICK_LAST; i++) { if (glfwJoystickPresent(i) && !IsThisJoystickBlacklisted(i)) { if (PSGLOBAL(joy1id) == -1) diff --git a/src/text/Text.cpp b/src/text/Text.cpp index 5adc576a..e23369fb 100644 --- a/src/text/Text.cpp +++ b/src/text/Text.cpp @@ -205,7 +205,7 @@ CText::GetNameOfLoadedMissionText(char *outName) void CText::ReadChunkHeader(ChunkHeader *buf, int32 file, size_t *offset) { -#if DUMB +#if THIS_IS_STUPID char *_buf = (char*)buf; for (int i = 0; i < sizeof(ChunkHeader); i++) { CFileMgr::Read(file, &_buf[i], 1); diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h index b2f0643c..1430e7ba 100644 --- a/src/vehicles/Automobile.h +++ b/src/vehicles/Automobile.h @@ -35,6 +35,9 @@ public: float m_aWheelPosition[4]; float m_aWheelSpeed[4]; uint8 m_auto_unused2; +#if (defined GTA_PS2 && !defined FIX_BUGS) + uint8 m_bombType : 3; +#endif uint8 bTaxiLight : 1; uint8 bFixedColour : 1; uint8 bBigWheels : 1; @@ -44,6 +47,9 @@ public: uint8 bTankDetonateCars : 1; uint8 bStuckInSand : 1; uint8 bHeliDestroyed : 1; +#if (defined GTA_PS2 && !defined FIX_BUGS) + CEntity* m_pBombRigger; +#endif int16 m_doingBurnout; uint16 m_hydraulicState; uint32 m_nBusDoorTimerEnd; diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp index f083e0f6..56de3562 100644 --- a/src/vehicles/Vehicle.cpp +++ b/src/vehicles/Vehicle.cpp @@ -2492,7 +2492,7 @@ IsVehiclePointerValid(CVehicle* pVehicle) { if (!pVehicle) return false; - int index = CPools::GetVehiclePool()->GetJustIndex(pVehicle); + int index = CPools::GetVehiclePool()->GetJustIndex_NoFreeAssert(pVehicle); #ifdef FIX_BUGS if (index < 0 || index >= NUMVEHICLES) #else diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h index 8f2686e1..9386880d 100644 --- a/src/vehicles/Vehicle.h +++ b/src/vehicles/Vehicle.h @@ -248,8 +248,9 @@ public: uint8 bRestingOnPhysical : 1; // Dont go static cause car is sitting on a physical object that might get removed uint8 bParking : 1; uint8 bCanPark : 1; - +#if (!defined GTA_PS2 || defined FIX_BUGS) uint8 m_bombType : 3; +#endif uint8 bDriverLastFrame : 1; int8 m_numPedsUseItAsCover; @@ -259,7 +260,9 @@ public: float m_fHealth; // 1000.0f = full health. 250.0f = fire. 0 -> explode uint8 m_nCurrentGear; float m_fChangeGearTime; +#if (!defined GTA_PS2 || defined FIX_BUGS) CEntity* m_pBombRigger; +#endif uint32 m_nSetPieceExtendedRangeTime; uint32 m_nGunFiringTime; // last time when gun on vehicle was fired (used on boats) uint32 m_nTimeOfDeath; diff --git a/src/weapons/Weapon.cpp b/src/weapons/Weapon.cpp index 26ed2037..52d95abb 100644 --- a/src/weapons/Weapon.cpp +++ b/src/weapons/Weapon.cpp @@ -1473,7 +1473,7 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim, } 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); for (int32 i = 0; i < 4; i++) @@ -1867,7 +1867,7 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource) { 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); for (int32 i = 0; i < 4; i++) |