From 590ff324691a8dd60c7e05170544cff8b9bcb0ab Mon Sep 17 00:00:00 2001 From: Fire-Head Date: Thu, 9 Apr 2020 06:20:44 +0300 Subject: PS2 Cheats, restored R*names --- src/control/Replay.cpp | 6 +++--- src/control/Script.cpp | 8 ++++---- src/control/Script.h | 29 +++++++++++++++++++---------- 3 files changed, 26 insertions(+), 17 deletions(-) (limited to 'src/control') diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp index b8e2318d..0da32dd2 100644 --- a/src/control/Replay.cpp +++ b/src/control/Replay.cpp @@ -1129,8 +1129,8 @@ void CReplay::StoreStuffInMem(void) pEmptyReferences = CReferences::pEmptyList; pStoredCam = new uint8[sizeof(CCamera)]; memcpy(pStoredCam, &TheCamera, sizeof(CCamera)); - pRadarBlips = new uint8[sizeof(CBlip) * NUMRADARBLIPS]; - memcpy(pRadarBlips, CRadar::ms_RadarTrace, NUMRADARBLIPS * sizeof(CBlip)); + pRadarBlips = new uint8[sizeof(sRadarTrace) * NUMRADARBLIPS]; + memcpy(pRadarBlips, CRadar::ms_RadarTrace, NUMRADARBLIPS * sizeof(sRadarTrace)); PlayerWanted = *FindPlayerPed()->m_pWanted; PlayerInfo = CWorld::Players[0]; Time1 = CTimer::GetTimeInMilliseconds(); @@ -1179,7 +1179,7 @@ void CReplay::RestoreStuffFromMem(void) memcpy(&TheCamera, pStoredCam, sizeof(CCamera)); delete[] pStoredCam; pStoredCam = nil; - memcpy(CRadar::ms_RadarTrace, pRadarBlips, sizeof(CBlip) * NUMRADARBLIPS); + memcpy(CRadar::ms_RadarTrace, pRadarBlips, sizeof(sRadarTrace) * NUMRADARBLIPS); delete[] pRadarBlips; pRadarBlips = nil; FindPlayerPed()->m_pWanted = new CWanted(PlayerWanted); diff --git a/src/control/Script.cpp b/src/control/Script.cpp index 18572573..75fd32a0 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -91,10 +91,10 @@ uint8 (&CTheScripts::ScriptSpace)[SIZE_SCRIPT_SPACE] = *(uint8(*)[SIZE_SCRIPT_SP CRunningScript(&CTheScripts::ScriptsArray)[MAX_NUM_SCRIPTS] = *(CRunningScript(*)[MAX_NUM_SCRIPTS])*(uintptr*)0x6F5C08; int32(&CTheScripts::BaseBriefIdForContact)[MAX_NUM_CONTACTS] = *(int32(*)[MAX_NUM_CONTACTS])*(uintptr*)0x880200; int32(&CTheScripts::OnAMissionForContactFlag)[MAX_NUM_CONTACTS] = *(int32(*)[MAX_NUM_CONTACTS])*(uintptr*)0x8622F0; -CTextLine (&CTheScripts::IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES] = *(CTextLine (*)[MAX_NUM_INTRO_TEXT_LINES])*(uintptr*)0x70EA68; -CScriptRectangle (&CTheScripts::IntroRectangles)[MAX_NUM_INTRO_RECTANGLES] = *(CScriptRectangle (*)[MAX_NUM_INTRO_RECTANGLES])*(uintptr*)0x72D108; +intro_text_line (&CTheScripts::IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES] = *(intro_text_line (*)[MAX_NUM_INTRO_TEXT_LINES])*(uintptr*)0x70EA68; +intro_script_rectangle (&CTheScripts::IntroRectangles)[MAX_NUM_INTRO_RECTANGLES] = *(intro_script_rectangle (*)[MAX_NUM_INTRO_RECTANGLES])*(uintptr*)0x72D108; CSprite2d (&CTheScripts::ScriptSprites)[MAX_NUM_SCRIPT_SRPITES] = *(CSprite2d(*)[MAX_NUM_SCRIPT_SRPITES])*(uintptr*)0x72B090; -CScriptSphere(&CTheScripts::ScriptSphereArray)[MAX_NUM_SCRIPT_SPHERES] = *(CScriptSphere(*)[MAX_NUM_SCRIPT_SPHERES])*(uintptr*)0x727D60; +script_sphere_struct(&CTheScripts::ScriptSphereArray)[MAX_NUM_SCRIPT_SPHERES] = *(script_sphere_struct(*)[MAX_NUM_SCRIPT_SPHERES])*(uintptr*)0x727D60; tCollectiveData(&CTheScripts::CollectiveArray)[MAX_NUM_COLLECTIVES] = *(tCollectiveData(*)[MAX_NUM_COLLECTIVES])*(uintptr*)0x6FA008; tUsedObject(&CTheScripts::UsedObjectArray)[MAX_NUM_USED_OBJECTS] = *(tUsedObject(*)[MAX_NUM_USED_OBJECTS])*(uintptr*)0x6E69C8; int32(&CTheScripts::MultiScriptArray)[MAX_NUM_MISSION_SCRIPTS] = *(int32(*)[MAX_NUM_MISSION_SCRIPTS])*(uintptr*)0x6F0558; @@ -313,7 +313,7 @@ bool CUpsideDownCarCheck::HasCarBeenUpsideDownForAWhile(int32 id) return false; } -void CStuckCarCheckEntry::Reset() +void stuck_car_data::Reset() { m_nVehicleIndex = -1; m_vecPos = CVector(-5000.0f, -5000.0f, -5000.0f); diff --git a/src/control/Script.h b/src/control/Script.h index 8143bd43..4338bd18 100644 --- a/src/control/Script.h +++ b/src/control/Script.h @@ -15,22 +15,25 @@ class CRunningScript; #define KEY_LENGTH_IN_SCRIPT 8 -struct CScriptRectangle +struct intro_script_rectangle { bool m_bIsUsed; bool m_bBeforeFade; int16 m_nTextureId; CRect m_sRect; CRGBA m_sColor; + + intro_script_rectangle() { } + ~intro_script_rectangle() { } }; -static_assert(sizeof(CScriptRectangle) == 0x18, "Script.h: error"); +static_assert(sizeof(intro_script_rectangle) == 0x18, "Script.h: error"); enum { SCRIPT_TEXT_MAX_LENGTH = 500 }; -struct CTextLine +struct intro_text_line { float m_fScaleX; float m_fScaleY; @@ -50,6 +53,9 @@ struct CTextLine float m_fAtY; wchar m_Text[SCRIPT_TEXT_MAX_LENGTH]; + intro_text_line() { } + ~intro_text_line() { } + void Reset() { m_fScaleX = 0.48f; @@ -72,15 +78,17 @@ struct CTextLine } }; -static_assert(sizeof(CTextLine) == 0x414, "Script.h: error"); +static_assert(sizeof(intro_text_line) == 0x414, "Script.h: error"); -struct CScriptSphere +struct script_sphere_struct { bool m_bInUse; uint16 m_Index; uint32 m_Id; CVector m_vecCenter; float m_fRadius; + + script_sphere_struct() { } }; struct CStoredLine @@ -145,7 +153,7 @@ public: bool HasCarBeenUpsideDownForAWhile(int32); }; -struct CStuckCarCheckEntry +struct stuck_car_data { int32 m_nVehicleIndex; CVector m_vecPos; @@ -154,12 +162,13 @@ struct CStuckCarCheckEntry uint32 m_nStuckTime; bool m_bStuck; + stuck_car_data() { } inline void Reset(); }; class CStuckCarCheck { - CStuckCarCheckEntry m_sCars[MAX_STUCK_CAR_CHECKS]; + stuck_car_data m_sCars[MAX_STUCK_CAR_CHECKS]; public: void Init(); @@ -235,10 +244,10 @@ class CTheScripts static CRunningScript(&ScriptsArray)[MAX_NUM_SCRIPTS]; static int32(&BaseBriefIdForContact)[MAX_NUM_CONTACTS]; static int32(&OnAMissionForContactFlag)[MAX_NUM_CONTACTS]; - static CTextLine(&IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES]; - static CScriptRectangle(&IntroRectangles)[MAX_NUM_INTRO_RECTANGLES]; + static intro_text_line(&IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES]; + static intro_script_rectangle(&IntroRectangles)[MAX_NUM_INTRO_RECTANGLES]; static CSprite2d(&ScriptSprites)[MAX_NUM_SCRIPT_SRPITES]; - static CScriptSphere(&ScriptSphereArray)[MAX_NUM_SCRIPT_SPHERES]; + static script_sphere_struct(&ScriptSphereArray)[MAX_NUM_SCRIPT_SPHERES]; static tCollectiveData(&CollectiveArray)[MAX_NUM_COLLECTIVES]; static tUsedObject(&UsedObjectArray)[MAX_NUM_USED_OBJECTS]; static int32(&MultiScriptArray)[MAX_NUM_MISSION_SCRIPTS]; -- cgit v1.2.3 From 34349c4df2683fca35be37ec626aaa8eef2ddaee Mon Sep 17 00:00:00 2001 From: aap Date: Thu, 9 Apr 2020 20:50:24 +0200 Subject: normalized line endings to LF --- src/control/GameLogic.cpp | 572 ++++++------ src/control/GameLogic.h | 24 +- src/control/Gangs.cpp | 18 +- src/control/OnscreenTimer.h | 96 +- src/control/Pickups.cpp | 2098 +++++++++++++++++++++---------------------- src/control/Pickups.h | 248 ++--- src/control/PowerPoints.cpp | 42 +- src/control/PowerPoints.h | 50 +- src/control/Restart.cpp | 434 ++++----- 9 files changed, 1791 insertions(+), 1791 deletions(-) (limited to 'src/control') diff --git a/src/control/GameLogic.cpp b/src/control/GameLogic.cpp index 0abae7d6..8e0ea02d 100644 --- a/src/control/GameLogic.cpp +++ b/src/control/GameLogic.cpp @@ -1,294 +1,294 @@ #include "common.h" #include "patcher.h" -#include "GameLogic.h" -#include "Clock.h" -#include "Stats.h" -#include "Pickups.h" -#include "Timer.h" -#include "Streaming.h" -#include "CutsceneMgr.h" -#include "World.h" -#include "PlayerPed.h" -#include "Wanted.h" -#include "Camera.h" -#include "Messages.h" -#include "CarCtrl.h" -#include "Restart.h" -#include "Pad.h" -#include "References.h" -#include "Fire.h" -#include "Script.h" -#include "Garages.h" - -uint8 CGameLogic::ActivePlayers; // 0x95CD5E - -void -CGameLogic::InitAtStartOfGame() -{ - ActivePlayers = 1; -} - -void -CGameLogic::PassTime(uint32 time) -{ - int32 minutes, hours, days; - - minutes = time + CClock::GetMinutes(); - hours = CClock::GetHours(); - - for (; minutes >= 60; minutes -= 60) - hours++; - - if (hours > 23) { - days = CStats::DaysPassed; - for (; hours >= 24; hours -= 24) - days++; - CStats::DaysPassed = days; - } - - CClock::SetGameClock(hours, minutes); - CPickups::PassTime(time * 1000); -} - -void -CGameLogic::SortOutStreamingAndMemory(const CVector &pos) -{ - CTimer::Stop(); - CStreaming::FlushRequestList(); - CStreaming::DeleteRwObjectsAfterDeath(pos); - CStreaming::RemoveUnusedModelsInLoadedList(); - CGame::DrasticTidyUpMemory(true); - CStreaming::LoadScene(pos); - CTimer::Update(); -} - -void -CGameLogic::Update() -{ - CVector vecRestartPos; - float fRestartFloat; - - if (CCutsceneMgr::IsCutsceneProcessing()) return; - - CPlayerInfo &pPlayerInfo = CWorld::Players[CWorld::PlayerInFocus]; - switch (pPlayerInfo.m_WBState) { - case WBSTATE_PLAYING: - if (pPlayerInfo.m_pPed->m_nPedState == PED_DEAD) { - pPlayerInfo.m_pPed->ClearAdrenaline(); - pPlayerInfo.KillPlayer(); - } - if (pPlayerInfo.m_pPed->m_nPedState == PED_ARRESTED) { - pPlayerInfo.m_pPed->ClearAdrenaline(); - pPlayerInfo.ArrestPlayer(); - } - break; - case WBSTATE_WASTED: - if ((CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 0x800) && (CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= 0x800)) { - TheCamera.SetFadeColour(200, 200, 200); - TheCamera.Fade(2.0f, FADE_OUT); - } - - if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= 0x1000) { - pPlayerInfo.m_WBState = WBSTATE_PLAYING; - if (pPlayerInfo.m_bGetOutOfHospitalFree) { - pPlayerInfo.m_bGetOutOfHospitalFree = false; - } else { - pPlayerInfo.m_nMoney = max(0, pPlayerInfo.m_nMoney - 1000); - pPlayerInfo.m_pPed->ClearWeapons(); - } - - if (pPlayerInfo.m_pPed->bInVehicle) { - CVehicle *pVehicle = pPlayerInfo.m_pPed->m_pMyVehicle; - if (pVehicle != nil) { - if (pVehicle->pDriver == pPlayerInfo.m_pPed) { - pVehicle->pDriver = nil; - if (pVehicle->m_status != STATUS_WRECKED) - pVehicle->m_status = STATUS_ABANDONED; - } else - pVehicle->RemovePassenger(pPlayerInfo.m_pPed); - } - } - CEventList::Initialise(); - CMessages::ClearMessages(); - CCarCtrl::ClearInterestingVehicleList(); - CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1); - CRestart::FindClosestHospitalRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat); - CRestart::OverrideHospitalLevel = LEVEL_NONE; - CRestart::OverridePoliceStationLevel = LEVEL_NONE; - PassTime(720); - RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat); - SortOutStreamingAndMemory(pPlayerInfo.GetPos()); - TheCamera.m_fCamShakeForce = 0.0f; - TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE); - CPad::GetPad(0)->StopShaking(0); - CReferences::RemoveReferencesToPlayer(); - CCarCtrl::CountDownToCarsAtStart = 2; - CPad::GetPad(CWorld::PlayerInFocus)->DisablePlayerControls = PLAYERCONTROL_ENABLED; - if (CRestart::bFadeInAfterNextDeath) { - TheCamera.SetFadeColour(200, 200, 200); - TheCamera.Fade(4.0f, FADE_IN); - } else CRestart::bFadeInAfterNextDeath = true; - } - break; - case WBSTATE_BUSTED: - if ((CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 0x800) && (CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= 0x800)) { - TheCamera.SetFadeColour(0, 0, 0); - TheCamera.Fade(2.0f, FADE_OUT); - } - if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= 0x1000) { - pPlayerInfo.m_WBState = WBSTATE_PLAYING; - int takeMoney; - - switch (pPlayerInfo.m_pPed->m_pWanted->m_nWantedLevel) { - case 0: - case 1: - takeMoney = 100; - break; - case 2: - takeMoney = 200; - break; - case 3: - takeMoney = 400; - break; - case 4: - takeMoney = 600; - break; - case 5: - takeMoney = 900; - break; - case 6: - takeMoney = 1500; - break; - } - if (pPlayerInfo.m_bGetOutOfJailFree) { - pPlayerInfo.m_bGetOutOfJailFree = false; - } else { - pPlayerInfo.m_nMoney = max(0, pPlayerInfo.m_nMoney - takeMoney); - pPlayerInfo.m_pPed->ClearWeapons(); - } - - if (pPlayerInfo.m_pPed->bInVehicle) { - CVehicle *pVehicle = pPlayerInfo.m_pPed->m_pMyVehicle; - if (pVehicle != nil) { - if (pVehicle->pDriver == pPlayerInfo.m_pPed) { - pVehicle->pDriver = nil; - if (pVehicle->m_status != STATUS_WRECKED) - pVehicle->m_status = STATUS_ABANDONED; - } - else - pVehicle->RemovePassenger(pPlayerInfo.m_pPed); - } - } - CEventList::Initialise(); - CMessages::ClearMessages(); - CCarCtrl::ClearInterestingVehicleList(); - CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1); - CRestart::FindClosestPoliceRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat); - CRestart::OverrideHospitalLevel = LEVEL_NONE; - CRestart::OverridePoliceStationLevel = LEVEL_NONE; - PassTime(720); - RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat); - pPlayerInfo.m_pPed->ClearWeapons(); - SortOutStreamingAndMemory(pPlayerInfo.GetPos()); - TheCamera.m_fCamShakeForce = 0.0f; - TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE); - CPad::GetPad(0)->StopShaking(0); - CReferences::RemoveReferencesToPlayer(); - CCarCtrl::CountDownToCarsAtStart = 2; - CPad::GetPad(CWorld::PlayerInFocus)->DisablePlayerControls = PLAYERCONTROL_ENABLED; - if (CRestart::bFadeInAfterNextArrest) { - TheCamera.SetFadeColour(0, 0, 0); - TheCamera.Fade(4.0f, FADE_IN); - } else CRestart::bFadeInAfterNextArrest = true; - } - break; - case WBSTATE_FAILED_CRITICAL_MISSION: - if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 0x800 && CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= 0x800) { - TheCamera.SetFadeColour(0, 0, 0); - TheCamera.Fade(2.0f, FADE_OUT); - } - if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= 0x1000) { - pPlayerInfo.m_WBState = WBSTATE_PLAYING; - if (pPlayerInfo.m_pPed->bInVehicle) { - CVehicle *pVehicle = pPlayerInfo.m_pPed->m_pMyVehicle; - if (pVehicle != nil) { - if (pVehicle->pDriver == pPlayerInfo.m_pPed) { - pVehicle->pDriver = nil; - if (pVehicle->m_status != STATUS_WRECKED) - pVehicle->m_status = STATUS_ABANDONED; - } else - pVehicle->RemovePassenger(pPlayerInfo.m_pPed); - } - } - CEventList::Initialise(); - CMessages::ClearMessages(); - CCarCtrl::ClearInterestingVehicleList(); - CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1); - CRestart::FindClosestPoliceRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat); - CRestart::OverridePoliceStationLevel = LEVEL_NONE; - CRestart::OverrideHospitalLevel = LEVEL_NONE; - RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat); - SortOutStreamingAndMemory(pPlayerInfo.GetPos()); - TheCamera.m_fCamShakeForce = 0.0f; - TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE); - CPad::GetPad(0)->StopShaking(0); - CReferences::RemoveReferencesToPlayer(); - CCarCtrl::CountDownToCarsAtStart = 2; - CPad::GetPad(CWorld::PlayerInFocus)->DisablePlayerControls = PLAYERCONTROL_ENABLED; - TheCamera.SetFadeColour(0, 0, 0); - TheCamera.Fade(4.0f, FADE_IN); - } - break; - case 4: - return; - } -} - -void -CGameLogic::RestorePlayerStuffDuringResurrection(CPlayerPed *pPlayerPed, CVector pos, float angle) -{ - pPlayerPed->m_fHealth = 100.0f; - pPlayerPed->m_fArmour = 0.0f; - pPlayerPed->bIsVisible = true; - pPlayerPed->m_bloodyFootprintCountOrDeathTime = 0; - pPlayerPed->bDoBloodyFootprints = false; - pPlayerPed->ClearAdrenaline(); - pPlayerPed->m_fCurrentStamina = pPlayerPed->m_fMaxStamina; - if (pPlayerPed->m_pFire) - pPlayerPed->m_pFire->Extinguish(); - pPlayerPed->bInVehicle = false; - pPlayerPed->m_pMyVehicle = nil; - pPlayerPed->m_pVehicleAnim = nil; - pPlayerPed->m_pWanted->Reset(); - pPlayerPed->RestartNonPartialAnims(); - pPlayerPed->GetPlayerInfoForThisPlayerPed()->MakePlayerSafe(false); - pPlayerPed->bRemoveFromWorld = false; - pPlayerPed->ClearWeaponTarget(); - pPlayerPed->SetInitialState(); - CCarCtrl::ClearInterestingVehicleList(); - - pos.z += 1.0f; - pPlayerPed->Teleport(pos); - pPlayerPed->SetMoveSpeed(CVector(0.0f, 0.0f, 0.0f)); - - pPlayerPed->m_fRotationCur = DEGTORAD(angle); - pPlayerPed->m_fRotationDest = pPlayerPed->m_fRotationCur; - pPlayerPed->SetHeading(pPlayerPed->m_fRotationCur); - CTheScripts::ClearSpaceForMissionEntity(pos, pPlayerPed); - CWorld::ClearExcitingStuffFromArea(pos, 4000.0, 1); - pPlayerPed->RestoreHeadingRate(); - TheCamera.SetCameraDirectlyInFrontForFollowPed_CamOnAString(); - CReferences::RemoveReferencesToPlayer(); - CGarages::PlayerArrestedOrDied(); - CStats::CheckPointReachedUnsuccessfully(); - CWorld::Remove(pPlayerPed); - CWorld::Add(pPlayerPed); -} - +#include "GameLogic.h" +#include "Clock.h" +#include "Stats.h" +#include "Pickups.h" +#include "Timer.h" +#include "Streaming.h" +#include "CutsceneMgr.h" +#include "World.h" +#include "PlayerPed.h" +#include "Wanted.h" +#include "Camera.h" +#include "Messages.h" +#include "CarCtrl.h" +#include "Restart.h" +#include "Pad.h" +#include "References.h" +#include "Fire.h" +#include "Script.h" +#include "Garages.h" + +uint8 CGameLogic::ActivePlayers; // 0x95CD5E + +void +CGameLogic::InitAtStartOfGame() +{ + ActivePlayers = 1; +} + +void +CGameLogic::PassTime(uint32 time) +{ + int32 minutes, hours, days; + + minutes = time + CClock::GetMinutes(); + hours = CClock::GetHours(); + + for (; minutes >= 60; minutes -= 60) + hours++; + + if (hours > 23) { + days = CStats::DaysPassed; + for (; hours >= 24; hours -= 24) + days++; + CStats::DaysPassed = days; + } + + CClock::SetGameClock(hours, minutes); + CPickups::PassTime(time * 1000); +} + +void +CGameLogic::SortOutStreamingAndMemory(const CVector &pos) +{ + CTimer::Stop(); + CStreaming::FlushRequestList(); + CStreaming::DeleteRwObjectsAfterDeath(pos); + CStreaming::RemoveUnusedModelsInLoadedList(); + CGame::DrasticTidyUpMemory(true); + CStreaming::LoadScene(pos); + CTimer::Update(); +} + +void +CGameLogic::Update() +{ + CVector vecRestartPos; + float fRestartFloat; + + if (CCutsceneMgr::IsCutsceneProcessing()) return; + + CPlayerInfo &pPlayerInfo = CWorld::Players[CWorld::PlayerInFocus]; + switch (pPlayerInfo.m_WBState) { + case WBSTATE_PLAYING: + if (pPlayerInfo.m_pPed->m_nPedState == PED_DEAD) { + pPlayerInfo.m_pPed->ClearAdrenaline(); + pPlayerInfo.KillPlayer(); + } + if (pPlayerInfo.m_pPed->m_nPedState == PED_ARRESTED) { + pPlayerInfo.m_pPed->ClearAdrenaline(); + pPlayerInfo.ArrestPlayer(); + } + break; + case WBSTATE_WASTED: + if ((CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 0x800) && (CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= 0x800)) { + TheCamera.SetFadeColour(200, 200, 200); + TheCamera.Fade(2.0f, FADE_OUT); + } + + if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= 0x1000) { + pPlayerInfo.m_WBState = WBSTATE_PLAYING; + if (pPlayerInfo.m_bGetOutOfHospitalFree) { + pPlayerInfo.m_bGetOutOfHospitalFree = false; + } else { + pPlayerInfo.m_nMoney = max(0, pPlayerInfo.m_nMoney - 1000); + pPlayerInfo.m_pPed->ClearWeapons(); + } + + if (pPlayerInfo.m_pPed->bInVehicle) { + CVehicle *pVehicle = pPlayerInfo.m_pPed->m_pMyVehicle; + if (pVehicle != nil) { + if (pVehicle->pDriver == pPlayerInfo.m_pPed) { + pVehicle->pDriver = nil; + if (pVehicle->m_status != STATUS_WRECKED) + pVehicle->m_status = STATUS_ABANDONED; + } else + pVehicle->RemovePassenger(pPlayerInfo.m_pPed); + } + } + CEventList::Initialise(); + CMessages::ClearMessages(); + CCarCtrl::ClearInterestingVehicleList(); + CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1); + CRestart::FindClosestHospitalRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat); + CRestart::OverrideHospitalLevel = LEVEL_NONE; + CRestart::OverridePoliceStationLevel = LEVEL_NONE; + PassTime(720); + RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat); + SortOutStreamingAndMemory(pPlayerInfo.GetPos()); + TheCamera.m_fCamShakeForce = 0.0f; + TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE); + CPad::GetPad(0)->StopShaking(0); + CReferences::RemoveReferencesToPlayer(); + CCarCtrl::CountDownToCarsAtStart = 2; + CPad::GetPad(CWorld::PlayerInFocus)->DisablePlayerControls = PLAYERCONTROL_ENABLED; + if (CRestart::bFadeInAfterNextDeath) { + TheCamera.SetFadeColour(200, 200, 200); + TheCamera.Fade(4.0f, FADE_IN); + } else CRestart::bFadeInAfterNextDeath = true; + } + break; + case WBSTATE_BUSTED: + if ((CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 0x800) && (CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= 0x800)) { + TheCamera.SetFadeColour(0, 0, 0); + TheCamera.Fade(2.0f, FADE_OUT); + } + if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= 0x1000) { + pPlayerInfo.m_WBState = WBSTATE_PLAYING; + int takeMoney; + + switch (pPlayerInfo.m_pPed->m_pWanted->m_nWantedLevel) { + case 0: + case 1: + takeMoney = 100; + break; + case 2: + takeMoney = 200; + break; + case 3: + takeMoney = 400; + break; + case 4: + takeMoney = 600; + break; + case 5: + takeMoney = 900; + break; + case 6: + takeMoney = 1500; + break; + } + if (pPlayerInfo.m_bGetOutOfJailFree) { + pPlayerInfo.m_bGetOutOfJailFree = false; + } else { + pPlayerInfo.m_nMoney = max(0, pPlayerInfo.m_nMoney - takeMoney); + pPlayerInfo.m_pPed->ClearWeapons(); + } + + if (pPlayerInfo.m_pPed->bInVehicle) { + CVehicle *pVehicle = pPlayerInfo.m_pPed->m_pMyVehicle; + if (pVehicle != nil) { + if (pVehicle->pDriver == pPlayerInfo.m_pPed) { + pVehicle->pDriver = nil; + if (pVehicle->m_status != STATUS_WRECKED) + pVehicle->m_status = STATUS_ABANDONED; + } + else + pVehicle->RemovePassenger(pPlayerInfo.m_pPed); + } + } + CEventList::Initialise(); + CMessages::ClearMessages(); + CCarCtrl::ClearInterestingVehicleList(); + CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1); + CRestart::FindClosestPoliceRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat); + CRestart::OverrideHospitalLevel = LEVEL_NONE; + CRestart::OverridePoliceStationLevel = LEVEL_NONE; + PassTime(720); + RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat); + pPlayerInfo.m_pPed->ClearWeapons(); + SortOutStreamingAndMemory(pPlayerInfo.GetPos()); + TheCamera.m_fCamShakeForce = 0.0f; + TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE); + CPad::GetPad(0)->StopShaking(0); + CReferences::RemoveReferencesToPlayer(); + CCarCtrl::CountDownToCarsAtStart = 2; + CPad::GetPad(CWorld::PlayerInFocus)->DisablePlayerControls = PLAYERCONTROL_ENABLED; + if (CRestart::bFadeInAfterNextArrest) { + TheCamera.SetFadeColour(0, 0, 0); + TheCamera.Fade(4.0f, FADE_IN); + } else CRestart::bFadeInAfterNextArrest = true; + } + break; + case WBSTATE_FAILED_CRITICAL_MISSION: + if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 0x800 && CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= 0x800) { + TheCamera.SetFadeColour(0, 0, 0); + TheCamera.Fade(2.0f, FADE_OUT); + } + if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= 0x1000) { + pPlayerInfo.m_WBState = WBSTATE_PLAYING; + if (pPlayerInfo.m_pPed->bInVehicle) { + CVehicle *pVehicle = pPlayerInfo.m_pPed->m_pMyVehicle; + if (pVehicle != nil) { + if (pVehicle->pDriver == pPlayerInfo.m_pPed) { + pVehicle->pDriver = nil; + if (pVehicle->m_status != STATUS_WRECKED) + pVehicle->m_status = STATUS_ABANDONED; + } else + pVehicle->RemovePassenger(pPlayerInfo.m_pPed); + } + } + CEventList::Initialise(); + CMessages::ClearMessages(); + CCarCtrl::ClearInterestingVehicleList(); + CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1); + CRestart::FindClosestPoliceRestartPoint(pPlayerInfo.GetPos(), &vecRestartPos, &fRestartFloat); + CRestart::OverridePoliceStationLevel = LEVEL_NONE; + CRestart::OverrideHospitalLevel = LEVEL_NONE; + RestorePlayerStuffDuringResurrection(pPlayerInfo.m_pPed, vecRestartPos, fRestartFloat); + SortOutStreamingAndMemory(pPlayerInfo.GetPos()); + TheCamera.m_fCamShakeForce = 0.0f; + TheCamera.SetMotionBlur(0, 0, 0, 0, MBLUR_NONE); + CPad::GetPad(0)->StopShaking(0); + CReferences::RemoveReferencesToPlayer(); + CCarCtrl::CountDownToCarsAtStart = 2; + CPad::GetPad(CWorld::PlayerInFocus)->DisablePlayerControls = PLAYERCONTROL_ENABLED; + TheCamera.SetFadeColour(0, 0, 0); + TheCamera.Fade(4.0f, FADE_IN); + } + break; + case 4: + return; + } +} + +void +CGameLogic::RestorePlayerStuffDuringResurrection(CPlayerPed *pPlayerPed, CVector pos, float angle) +{ + pPlayerPed->m_fHealth = 100.0f; + pPlayerPed->m_fArmour = 0.0f; + pPlayerPed->bIsVisible = true; + pPlayerPed->m_bloodyFootprintCountOrDeathTime = 0; + pPlayerPed->bDoBloodyFootprints = false; + pPlayerPed->ClearAdrenaline(); + pPlayerPed->m_fCurrentStamina = pPlayerPed->m_fMaxStamina; + if (pPlayerPed->m_pFire) + pPlayerPed->m_pFire->Extinguish(); + pPlayerPed->bInVehicle = false; + pPlayerPed->m_pMyVehicle = nil; + pPlayerPed->m_pVehicleAnim = nil; + pPlayerPed->m_pWanted->Reset(); + pPlayerPed->RestartNonPartialAnims(); + pPlayerPed->GetPlayerInfoForThisPlayerPed()->MakePlayerSafe(false); + pPlayerPed->bRemoveFromWorld = false; + pPlayerPed->ClearWeaponTarget(); + pPlayerPed->SetInitialState(); + CCarCtrl::ClearInterestingVehicleList(); + + pos.z += 1.0f; + pPlayerPed->Teleport(pos); + pPlayerPed->SetMoveSpeed(CVector(0.0f, 0.0f, 0.0f)); + + pPlayerPed->m_fRotationCur = DEGTORAD(angle); + pPlayerPed->m_fRotationDest = pPlayerPed->m_fRotationCur; + pPlayerPed->SetHeading(pPlayerPed->m_fRotationCur); + CTheScripts::ClearSpaceForMissionEntity(pos, pPlayerPed); + CWorld::ClearExcitingStuffFromArea(pos, 4000.0, 1); + pPlayerPed->RestoreHeadingRate(); + TheCamera.SetCameraDirectlyInFrontForFollowPed_CamOnAString(); + CReferences::RemoveReferencesToPlayer(); + CGarages::PlayerArrestedOrDied(); + CStats::CheckPointReachedUnsuccessfully(); + CWorld::Remove(pPlayerPed); + CWorld::Add(pPlayerPed); +} + STARTPATCHES InjectHook(0x4213F0, &CGameLogic::InitAtStartOfGame, PATCH_JUMP); InjectHook(0x421C00, &CGameLogic::PassTime, PATCH_JUMP); InjectHook(0x421A20, &CGameLogic::SortOutStreamingAndMemory, PATCH_JUMP); InjectHook(0x421400, &CGameLogic::Update, PATCH_JUMP); - InjectHook(0x421A60, &CGameLogic::RestorePlayerStuffDuringResurrection, PATCH_JUMP); + InjectHook(0x421A60, &CGameLogic::RestorePlayerStuffDuringResurrection, PATCH_JUMP); ENDPATCHES \ No newline at end of file diff --git a/src/control/GameLogic.h b/src/control/GameLogic.h index db626558..43e244a3 100644 --- a/src/control/GameLogic.h +++ b/src/control/GameLogic.h @@ -1,13 +1,13 @@ -#pragma once - -class CGameLogic -{ -public: - static void InitAtStartOfGame(); - static void PassTime(uint32 time); - static void SortOutStreamingAndMemory(const CVector &pos); - static void Update(); - static void RestorePlayerStuffDuringResurrection(class CPlayerPed *pPlayerPed, CVector pos, float angle); - - static uint8 ActivePlayers; +#pragma once + +class CGameLogic +{ +public: + static void InitAtStartOfGame(); + static void PassTime(uint32 time); + static void SortOutStreamingAndMemory(const CVector &pos); + static void Update(); + static void RestorePlayerStuffDuringResurrection(class CPlayerPed *pPlayerPed, CVector pos, float angle); + + static uint8 ActivePlayers; }; \ No newline at end of file diff --git a/src/control/Gangs.cpp b/src/control/Gangs.cpp index ac32ad98..57d9c67e 100644 --- a/src/control/Gangs.cpp +++ b/src/control/Gangs.cpp @@ -1,7 +1,7 @@ #include "common.h" #include "patcher.h" #include "ModelIndices.h" -#include "Gangs.h" +#include "Gangs.h" #include "Weapon.h" //CGangInfo(&CGangs::Gang)[NUM_GANGS] = *(CGangInfo(*)[NUM_GANGS])*(uintptr*)0x6EDF78; @@ -57,20 +57,20 @@ void CGangs::SaveAllGangData(uint8 *buf, uint32 *size) { INITSAVEBUF - *size = SAVE_HEADER_SIZE + sizeof(Gang); + *size = SAVE_HEADER_SIZE + sizeof(Gang); WriteSaveHeader(buf, 'G','N','G','\0', *size - SAVE_HEADER_SIZE); - for (int i = 0; i < NUM_GANGS; i++) - WriteSaveBuf(buf, Gang[i]); - + for (int i = 0; i < NUM_GANGS; i++) + WriteSaveBuf(buf, Gang[i]); + VALIDATESAVEBUF(*size); } void CGangs::LoadAllGangData(uint8 *buf, uint32 size) { - Initialise(); - -INITSAVEBUF - // original: SkipSaveBuf(buf, SAVE_HEADER_SIZE); + Initialise(); + +INITSAVEBUF + // original: SkipSaveBuf(buf, SAVE_HEADER_SIZE); CheckSaveHeader(buf, 'G','N','G','\0', size - SAVE_HEADER_SIZE); for (int i = 0; i < NUM_GANGS; i++) diff --git a/src/control/OnscreenTimer.h b/src/control/OnscreenTimer.h index b1e0e622..fb139266 100644 --- a/src/control/OnscreenTimer.h +++ b/src/control/OnscreenTimer.h @@ -1,49 +1,49 @@ -#pragma once - -enum -{ - COUNTER_DISPLAY_NUMBER, - COUNTER_DISPLAY_BAR, -}; - -class COnscreenTimerEntry -{ -public: - uint32 m_nTimerOffset; - uint32 m_nCounterOffset; - char m_aTimerText[10]; - char m_aCounterText[10]; - uint16 m_nType; - char m_bCounterBuffer[42]; - char m_bTimerBuffer[42]; - bool m_bTimerProcessed; - bool m_bCounterProcessed; - - void Process(); - bool ProcessForDisplay(); - - void ProcessForDisplayClock(); - void ProcessForDisplayCounter(); -}; - -static_assert(sizeof(COnscreenTimerEntry) == 0x74, "COnscreenTimerEntry: error"); - -class COnscreenTimer -{ -public: - COnscreenTimerEntry m_sEntries[NUMONSCREENTIMERENTRIES]; - bool m_bProcessed; - bool m_bDisabled; - - void Init(); - void Process(); - void ProcessForDisplay(); - - void ClearCounter(uint32 offset); - void ClearClock(uint32 offset); - - void AddCounter(uint32 offset, uint16 type, char* text); - void AddClock(uint32 offset, char* text); -}; - +#pragma once + +enum +{ + COUNTER_DISPLAY_NUMBER, + COUNTER_DISPLAY_BAR, +}; + +class COnscreenTimerEntry +{ +public: + uint32 m_nTimerOffset; + uint32 m_nCounterOffset; + char m_aTimerText[10]; + char m_aCounterText[10]; + uint16 m_nType; + char m_bCounterBuffer[42]; + char m_bTimerBuffer[42]; + bool m_bTimerProcessed; + bool m_bCounterProcessed; + + void Process(); + bool ProcessForDisplay(); + + void ProcessForDisplayClock(); + void ProcessForDisplayCounter(); +}; + +static_assert(sizeof(COnscreenTimerEntry) == 0x74, "COnscreenTimerEntry: error"); + +class COnscreenTimer +{ +public: + COnscreenTimerEntry m_sEntries[NUMONSCREENTIMERENTRIES]; + bool m_bProcessed; + bool m_bDisabled; + + void Init(); + void Process(); + void ProcessForDisplay(); + + void ClearCounter(uint32 offset); + void ClearClock(uint32 offset); + + void AddCounter(uint32 offset, uint16 type, char* text); + void AddClock(uint32 offset, char* text); +}; + static_assert(sizeof(COnscreenTimer) == 0x78, "COnscreenTimer: error"); \ No newline at end of file diff --git a/src/control/Pickups.cpp b/src/control/Pickups.cpp index 3e3c2a48..774abd8c 100644 --- a/src/control/Pickups.cpp +++ b/src/control/Pickups.cpp @@ -1,1049 +1,1049 @@ -#include "common.h" -#include "patcher.h" -#include "main.h" - -#include "Camera.h" -#include "Coronas.h" -#include "Darkel.h" -#include "Entity.h" -#include "Explosion.h" -#include "Font.h" -#include "Garages.h" -#include "General.h" -#include "ModelIndices.h" -#include "Object.h" -#include "Pad.h" -#include "Pickups.h" -#include "PlayerPed.h" -#include "Wanted.h" -#include "DMAudio.h" -#include "Fire.h" -#include "PointLights.h" -#include "Pools.h" -#ifdef FIX_BUGS -#include "Replay.h" -#endif -#include "Script.h" -#include "Shadows.h" -#include "SpecialFX.h" -#include "Sprite.h" -#include "Timer.h" -#include "WaterLevel.h" -#include "World.h" - -CPickup(&CPickups::aPickUps)[NUMPICKUPS] = *(CPickup(*)[NUMPICKUPS])*(uintptr*)0x878C98; -int16 CPickups::NumMessages;// = *(int16*)0x95CC98; -int32 CPickups::aPickUpsCollected[NUMCOLLECTEDPICKUPS];// = *(int32(*)[NUMCOLLECTEDPICKUPS])*(uintptr*)0x87C538; -int16 CPickups::CollectedPickUpIndex;// = *(int16*)0x95CC8A; - -// unused -bool &CPickups::bPickUpcamActivated = *(bool*)0x95CD71; -CVehicle *&CPickups::pPlayerVehicle = *(CVehicle**)0x8F29E8; -CVector &CPickups::StaticCamCoors = *(CVector*)0x9404C8; -uint32 &CPickups::StaticCamStartTime = *(uint32*)0x8E289C; - -tPickupMessage CPickups::aMessages[NUMPICKUPMESSAGES]; - -// 20 ?! Some Miami leftover? (Originally at 0x5ED8D4) -uint16 AmmoForWeapon[20] = { 0, 1, 45, 125, 25, 150, 300, 25, 5, 250, 5, 5, 0, 500, 0, 100, 0, 0, 0, 0 }; -uint16 AmmoForWeapon_OnStreet[20] = { 0, 1, 9, 25, 5, 30, 60, 5, 1, 50, 1, 1, 0, 200, 0, 100, 0, 0, 0, 0 }; -uint16 CostOfWeapon[20] = { 0, 10, 250, 800, 1500, 3000, 5000, 10000, 25000, 25000, 2000, 2000, 0, 50000, 0, 3000, 0, 0, 0, 0 }; - -uint8 aWeaponReds[] = { 255, 0, 128, 255, 255, 0, 255, 0, 128, 128, 255, 255, 128, 0, 255, 0 }; -uint8 aWeaponGreens[] = { 0, 255, 128, 255, 0, 255, 128, 255, 0, 255, 255, 0, 255, 0, 255, 0 }; -uint8 aWeaponBlues[] = { 0, 0, 255, 0, 255, 255, 0, 128, 255, 0, 255, 0, 128, 255, 0, 0 }; -float aWeaponScale[] = { 1.0f, 2.0f, 1.5f, 1.0f, 1.0f, 1.5f, 1.0f, 2.0f, 1.0f, 2.0f, 2.5f, 1.0f, 1.0f, 1.0f, 1.0f }; - -WRAPPER void CPacManPickups::Init(void) { EAXJMP(0x432760); } -WRAPPER void CPacManPickups::Update(void) { EAXJMP(0x432800); } -WRAPPER void CPacManPickups::GeneratePMPickUps(CVector, float, int16, uint8) { EAXJMP(0x432AE0); } -WRAPPER void CPacManPickups::GeneratePMPickUpsForRace(int32) { EAXJMP(0x432D50); } -WRAPPER void CPacManPickups::GenerateOnePMPickUp(CVector) { EAXJMP(0x432F20); } -WRAPPER void CPacManPickups::Render(void) { EAXJMP(0x432F60); } -WRAPPER void CPacManPickups::DoCleanUpPacManStuff(void) { EAXJMP(0x433150); } -WRAPPER void CPacManPickups::StartPacManRace(int32) { EAXJMP(0x433340); } -WRAPPER void CPacManPickups::StartPacManRecord(void) { EAXJMP(0x433360); } -WRAPPER uint32 CPacManPickups::QueryPowerPillsEatenInRace(void) { EAXJMP(0x4333A0); } -WRAPPER void CPacManPickups::ResetPowerPillsEatenInRace(void) { EAXJMP(0x4333B0); } -WRAPPER void CPacManPickups::CleanUpPacManStuff(void) { EAXJMP(0x4333C0); } -WRAPPER void CPacManPickups::StartPacManScramble(CVector, float, int16) { EAXJMP(0x4333D0); } -WRAPPER uint32 CPacManPickups::QueryPowerPillsCarriedByPlayer(void) { EAXJMP(0x4333F0); } -WRAPPER void CPacManPickups::ResetPowerPillsCarriedByPlayer(void) { EAXJMP(0x433410); } - - -void -CPickup::RemoveKeepType() -{ - CWorld::Remove(m_pObject); - delete m_pObject; - - m_bRemoved = true; - m_pObject = nil; -} - -void -CPickup::Remove() -{ - RemoveKeepType(); - m_eType = PICKUP_NONE; -} - -CObject * -CPickup::GiveUsAPickUpObject(int32 handle) -{ - CObject *object; - - if (handle <= 0) object = new CObject(m_eModelIndex, false); - else { - CPools::MakeSureSlotInObjectPoolIsEmpty(handle); - object = new(handle) CObject(m_eModelIndex, false); - } - - if (object == nil) return nil; - object->ObjectCreatedBy = MISSION_OBJECT; - object->GetPosition() = m_vecPos; - object->SetOrientation(0.0f, 0.0f, -HALFPI); - object->GetMatrix().UpdateRW(); - object->UpdateRwFrame(); - - object->bAffectedByGravity = false; - object->bExplosionProof = true; - object->bUsesCollision = false; - object->bIsPickup = true; - - object->field_172 = m_eModelIndex == MI_PICKUP_BONUS ? m_nQuantity : 0; - - switch (m_eType) - { - case PICKUP_IN_SHOP: - object->m_obj_flag2 = true; - object->bOutOfStock = false; - break; - case PICKUP_ON_STREET: - case PICKUP_ONCE: - case PICKUP_ONCE_TIMEOUT: - case PICKUP_COLLECTABLE1: - case PICKUP_MONEY: - case PICKUP_MINE_INACTIVE: - case PICKUP_MINE_ARMED: - case PICKUP_NAUTICAL_MINE_INACTIVE: - case PICKUP_NAUTICAL_MINE_ARMED: - case PICKUP_FLOATINGPACKAGE: - case PICKUP_ON_STREET_SLOW: - object->m_obj_flag2 = false; - object->bOutOfStock = false; - break; - case PICKUP_IN_SHOP_OUT_OF_STOCK: - object->m_obj_flag2 = false; - object->bOutOfStock = true; - object->bRenderScorched = true; - break; - case PICKUP_FLOATINGPACKAGE_FLOATING: - default: - break; - } - return object; -} - -bool -CPickup::CanBePickedUp(CPlayerPed *player) -{ - assert(m_pObject != nil); - bool cannotBePickedUp = - (m_pObject->GetModelIndex() == MI_PICKUP_BODYARMOUR && player->m_fArmour > 99.5f) - || (m_pObject->GetModelIndex() == MI_PICKUP_HEALTH && player->m_fHealth > 99.5f) - || (m_pObject->GetModelIndex() == MI_PICKUP_BRIBE && player->m_pWanted->m_nWantedLevel == 0) - || (m_pObject->GetModelIndex() == MI_PICKUP_KILLFRENZY && (CTheScripts::IsPlayerOnAMission() || CDarkel::FrenzyOnGoing() || !CGame::nastyGame)); - return !cannotBePickedUp; -} - -bool -CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId) -{ - float waterLevel; - - if (m_bRemoved) { - if (CTimer::GetTimeInMilliseconds() > m_nTimer) { - // respawn pickup if we're far enough - float dist = (FindPlayerCoors().x - m_vecPos.x) * (FindPlayerCoors().x - m_vecPos.x) + (FindPlayerCoors().y - m_vecPos.y) * (FindPlayerCoors().y - m_vecPos.y); - if (dist > 100.0f || m_eType == PICKUP_IN_SHOP && dist > 2.4f) { - m_pObject = GiveUsAPickUpObject(-1); - if (m_pObject) { - CWorld::Add(m_pObject); - m_bRemoved = false; - } - } - } - return false; - } - - if (!m_pObject) return false; - - if (!IsMine()) { - // let's check if we touched the pickup - bool isPickupTouched = false; - if (m_pObject->GetModelIndex() == MI_PICKUP_BRIBE) { - if (vehicle != nil) { - if (vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 2.0f)) - isPickupTouched = true; - } - else { - if (Abs(player->GetPosition().z - m_pObject->GetPosition().z) < 2.0f) { - if ((player->GetPosition().x - m_pObject->GetPosition().x) * (player->GetPosition().x - m_pObject->GetPosition().x) + - (player->GetPosition().y - m_pObject->GetPosition().y) * (player->GetPosition().y - m_pObject->GetPosition().y) < 1.8f) - isPickupTouched = true; - } - } - } else if (m_pObject->GetModelIndex() == MI_PICKUP_CAMERA) { - if (vehicle != nil && vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 2.0f)) { - isPickupTouched = true; - } - } else if (vehicle == nil) { - if (Abs(player->GetPosition().z - m_pObject->GetPosition().z) < 2.0f) { - if ((player->GetPosition().x - m_pObject->GetPosition().x) * (player->GetPosition().x - m_pObject->GetPosition().x) + - (player->GetPosition().y - m_pObject->GetPosition().y) * (player->GetPosition().y - m_pObject->GetPosition().y) < 1.8f) - isPickupTouched = true; - } - } - - // if we didn't then we've got nothing to do - if (isPickupTouched && CanBePickedUp(player)) { - CPad::GetPad(0)->StartShake(120, 100); - switch (m_eType) - { - case PICKUP_IN_SHOP: - if (CWorld::Players[playerId].m_nMoney < CostOfWeapon[CPickups::WeaponForModel(m_pObject->GetModelIndex())]) { - CGarages::TriggerMessage("PU_MONY", -1, 6000, -1); - } else { - CWorld::Players[playerId].m_nMoney -= CostOfWeapon[CPickups::WeaponForModel(m_pObject->GetModelIndex())]; - if (!CPickups::GivePlayerGoodiesWithPickUpMI(m_pObject->GetModelIndex(), playerId)) { - player->GiveWeapon(CPickups::WeaponForModel(m_pObject->GetModelIndex()), AmmoForWeapon[CPickups::WeaponForModel(m_pObject->GetModelIndex())]); - player->m_nSelectedWepSlot = player->GetWeaponSlot(CPickups::WeaponForModel(m_pObject->GetModelIndex())); - DMAudio.PlayFrontEndSound(SOUND_PICKUP_WEAPON_BOUGHT, m_pObject->GetModelIndex() - MI_GRENADE); - } - RemoveKeepType(); - m_nTimer = CTimer::GetTimeInMilliseconds() + 5000; - return true; - } - break; - case PICKUP_ON_STREET: - case PICKUP_ON_STREET_SLOW: - if (!CPickups::GivePlayerGoodiesWithPickUpMI(m_pObject->GetModelIndex(), playerId)) { - if (CPickups::WeaponForModel(m_pObject->GetModelIndex())) { - player->GiveWeapon(CPickups::WeaponForModel(m_pObject->GetModelIndex()), m_nQuantity != 0 ? m_nQuantity : AmmoForWeapon_OnStreet[CPickups::WeaponForModel(m_pObject->GetModelIndex())]); - if (player->m_nSelectedWepSlot == player->GetWeaponSlot(WEAPONTYPE_UNARMED)) { - player->m_nSelectedWepSlot = player->GetWeaponSlot(CPickups::WeaponForModel(m_pObject->GetModelIndex())); - } - DMAudio.PlayFrontEndSound(SOUND_PICKUP_WEAPON, m_pObject->GetModelIndex() - MI_GRENADE); - } else if (m_pObject->GetModelIndex() == MI_PICKUP_CAMERA && vehicle != nil) { - DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0); - CPickups::bPickUpcamActivated = true; - CPickups::pPlayerVehicle = FindPlayerVehicle(); - CPickups::StaticCamCoors = m_pObject->GetPosition(); - CPickups::StaticCamStartTime = CTimer::GetTimeInMilliseconds(); - } - } - if (m_eType == PICKUP_ON_STREET) { - m_nTimer = CTimer::GetTimeInMilliseconds() + 30000; - } else if (m_eType == PICKUP_ON_STREET_SLOW) { - if (MI_PICKUP_BRIBE == m_pObject->m_modelIndex) - m_nTimer = CTimer::GetTimeInMilliseconds() + 300000; - else - m_nTimer = CTimer::GetTimeInMilliseconds() + 720000; - } - - RemoveKeepType(); - return true; - case PICKUP_ONCE: - case PICKUP_ONCE_TIMEOUT: - if (!CPickups::GivePlayerGoodiesWithPickUpMI(m_pObject->GetModelIndex(), playerId)) { - if (CPickups::WeaponForModel(m_pObject->GetModelIndex())) { - player->GiveWeapon(CPickups::WeaponForModel(m_pObject->GetModelIndex()), m_nQuantity != 0 ? m_nQuantity : AmmoForWeapon[CPickups::WeaponForModel(m_pObject->GetModelIndex())]); - if (player->m_nSelectedWepSlot == player->GetWeaponSlot(WEAPONTYPE_UNARMED)) - player->m_nSelectedWepSlot = player->GetWeaponSlot(CPickups::WeaponForModel(m_pObject->GetModelIndex())); - } - DMAudio.PlayFrontEndSound(SOUND_PICKUP_WEAPON, m_pObject->GetModelIndex() - MI_GRENADE); - } - Remove(); - return true; - case PICKUP_COLLECTABLE1: - CWorld::Players[playerId].m_nCollectedPackages++; - CWorld::Players[playerId].m_nMoney += 1000; - - if (CWorld::Players[playerId].m_nCollectedPackages == CWorld::Players[playerId].m_nTotalPackages) { - printf("All collectables have been picked up\n"); - CGarages::TriggerMessage("CO_ALL", -1, 5000, -1); - CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 1000000; - } else - CGarages::TriggerMessage("CO_ONE", CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages, 5000, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages); - - Remove(); - DMAudio.PlayFrontEndSound(SOUND_PICKUP_HIDDEN_PACKAGE, 0); - return true; - case PICKUP_MONEY: - CWorld::Players[playerId].m_nMoney += m_nQuantity; - sprintf(gString, "$%d", m_nQuantity); -#ifdef MONEY_MESSAGES - CMoneyMessages::RegisterOne(m_vecPos + CVector(0.0f, 0.0f, 1.0f), gString, 0, 255, 0, 0.5f, 0.5f); -#endif - Remove(); - DMAudio.PlayFrontEndSound(SOUND_PICKUP_MONEY, 0); - return true; - //case PICKUP_IN_SHOP_OUT_OF_STOCK: - //case PICKUP_MINE_INACTIVE: - //case PICKUP_MINE_ARMED: - //case PICKUP_NAUTICAL_MINE_INACTIVE: - //case PICKUP_NAUTICAL_MINE_ARMED: - //case PICKUP_FLOATINGPACKAGE: - //case PICKUP_FLOATINGPACKAGE_FLOATING: - default: - break; - } - } - } else { - switch (m_eType) - { - case PICKUP_MINE_INACTIVE: - if (vehicle != nil && !vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 2.0f)) { - m_eType = PICKUP_MINE_ARMED; - m_nTimer = CTimer::GetTimeInMilliseconds() + 10000; - } - break; - case PICKUP_NAUTICAL_MINE_INACTIVE: - { - if (CWaterLevel::GetWaterLevel(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z + 5.0f, &waterLevel, false)) - m_pObject->GetPosition().z = waterLevel + 0.6f; - - m_pObject->GetMatrix().UpdateRW(); - m_pObject->UpdateRwFrame(); - - bool touched = false; - for (int32 i = CPools::GetVehiclePool()->GetSize()-1; i >= 0; i--) { - CVehicle *vehicle = CPools::GetVehiclePool()->GetSlot(i); - if (vehicle != nil && vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 1.5f)) { - touched = true; - break; // added break here - } - } - - if (!touched) { - m_eType = PICKUP_NAUTICAL_MINE_ARMED; - m_nTimer = CTimer::GetTimeInMilliseconds() + 10000; - } - break; - } - case PICKUP_NAUTICAL_MINE_ARMED: - if (CWaterLevel::GetWaterLevel(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z + 5.0f, &waterLevel, false)) - m_pObject->GetPosition().z = waterLevel + 0.6f; - - m_pObject->GetMatrix().UpdateRW(); - m_pObject->UpdateRwFrame(); - // no break here - case PICKUP_MINE_ARMED: - { - bool explode = false; - if (CTimer::GetTimeInMilliseconds() > m_nTimer) - explode = true; - else {// added else here since vehicle lookup is useless - for (int32 i = CPools::GetVehiclePool()->GetSize()-1; i >= 0; i--) { - CVehicle *vehicle = CPools::GetVehiclePool()->GetSlot(i); - if (vehicle != nil && vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 1.5f)) { - explode = true; - break; // added break here - } - } - } - if (explode) { - CExplosion::AddExplosion(nil, nil, EXPLOSION_MINE, m_pObject->GetPosition(), 0); - Remove(); - } - break; - } - case PICKUP_FLOATINGPACKAGE: - m_pObject->m_vecMoveSpeed.z -= 0.01f * CTimer::GetTimeStep(); - m_pObject->GetPosition() += m_pObject->GetMoveSpeed() * CTimer::GetTimeStep(); - - m_pObject->GetMatrix().UpdateRW(); - m_pObject->UpdateRwFrame(); - if (CWaterLevel::GetWaterLevel(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z + 5.0f, &waterLevel, 0) && waterLevel >= m_pObject->GetPosition().z) - m_eType = PICKUP_FLOATINGPACKAGE_FLOATING; - break; - case PICKUP_FLOATINGPACKAGE_FLOATING: - if (CWaterLevel::GetWaterLevel(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z + 5.0f, &waterLevel, 0)) - m_pObject->GetPosition().z = waterLevel; - - m_pObject->GetMatrix().UpdateRW(); - m_pObject->UpdateRwFrame(); - if (vehicle != nil && vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 2.0f)) { - Remove(); - DMAudio.PlayFrontEndSound(SOUND_PICKUP_FLOAT_PACKAGE, 0); - return true; - } - break; - } - } - if (!m_bRemoved && (m_eType == PICKUP_ONCE_TIMEOUT || m_eType == PICKUP_MONEY) && CTimer::GetTimeInMilliseconds() > m_nTimer) - Remove(); - return false; -} - -void -CPickups::Init(void) -{ - NumMessages = 0; - for (int i = 0; i < NUMPICKUPS; i++) { - aPickUps[i].m_eType = PICKUP_NONE; - aPickUps[i].m_nIndex = 1; - aPickUps[i].m_pObject = nil; - } - - for (int i = 0; i < NUMCOLLECTEDPICKUPS; i++) - aPickUpsCollected[i] = 0; - - CollectedPickUpIndex = 0; -} - -bool -CPickups::IsPickUpPickedUp(int32 pickupId) -{ - for (int i = 0; i < NUMCOLLECTEDPICKUPS; i++) { - if (pickupId == aPickUpsCollected[i]) { - aPickUpsCollected[i] = 0; - return true; - } - } - return false; -} - -void -CPickups::PassTime(uint32 time) -{ - for (int i = 0; i < NUMPICKUPS; i++) { - if (aPickUps[i].m_eType != PICKUP_NONE) { - if (aPickUps[i].m_nTimer <= time) - aPickUps[i].m_nTimer = 0; - else - aPickUps[i].m_nTimer -= time; - } - } -} - -int32 -CPickups::GetActualPickupIndex(int32 index) -{ - if (index == -1) return -1; - - // doesn't look nice - if ((uint16)((index & 0xFFFF0000) >> 16) != aPickUps[(uint16)index].m_nIndex) return -1; - return (uint16)index; -} - -bool -CPickups::GivePlayerGoodiesWithPickUpMI(int16 modelIndex, int playerIndex) -{ - CPlayerPed *player; - - if (playerIndex <= 0) player = CWorld::Players[CWorld::PlayerInFocus].m_pPed; - else player = CWorld::Players[playerIndex].m_pPed; - - if (modelIndex == MI_PICKUP_ADRENALINE) { - player->m_bAdrenalineActive = true; - player->m_nAdrenalineTime = CTimer::GetTimeInMilliseconds() + 20000; - player->m_fCurrentStamina = player->m_fMaxStamina; - DMAudio.PlayFrontEndSound(SOUND_PICKUP_ADRENALINE, 0); - return true; - } else if (modelIndex == MI_PICKUP_BODYARMOUR) { - player->m_fArmour = 100.0f; - DMAudio.PlayFrontEndSound(SOUND_PICKUP_ARMOUR, 0); - return true; - } else if (modelIndex == MI_PICKUP_INFO) { - DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0); - return true; - } else if (modelIndex == MI_PICKUP_HEALTH) { - player->m_fHealth = 100.0f; - DMAudio.PlayFrontEndSound(SOUND_PICKUP_HEALTH, 0); - return true; - } else if (modelIndex == MI_PICKUP_BONUS) { - DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0); - return true; - } else if (modelIndex == MI_PICKUP_BRIBE) { - int32 level = FindPlayerPed()->m_pWanted->m_nWantedLevel - 1; - if (level < 0) level = 0; - player->SetWantedLevel(level); - DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0); - return true; - } else if (modelIndex == MI_PICKUP_KILLFRENZY) { - DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0); - return true; - } - return false; -} - -void -CPickups::RemoveAllFloatingPickups() -{ - for (int i = 0; i < NUMPICKUPS; i++) { - if (aPickUps[i].m_eType == PICKUP_FLOATINGPACKAGE || aPickUps[i].m_eType == PICKUP_FLOATINGPACKAGE_FLOATING) { - if (aPickUps[i].m_pObject) { - CWorld::Remove(aPickUps[i].m_pObject); - delete aPickUps[i].m_pObject; - aPickUps[i].m_pObject = nil; - } - } - } -} - -void -CPickups::RemovePickUp(int32 pickupIndex) -{ - int32 index = CPickups::GetActualPickupIndex(pickupIndex); - if (index == -1) return; - - if (aPickUps[index].m_pObject) { - CWorld::Remove(aPickUps[index].m_pObject); - delete aPickUps[index].m_pObject; - aPickUps[index].m_pObject = nil; - } - aPickUps[index].m_eType = PICKUP_NONE; - aPickUps[index].m_bRemoved = true; -} - -int32 -CPickups::GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quantity) -{ - bool bFreeFound = false; - int32 slot = 0; - - if (type == PICKUP_FLOATINGPACKAGE || type == PICKUP_NAUTICAL_MINE_INACTIVE) { - for (slot = NUMPICKUPS; slot >= 0; slot--) { - if (aPickUps[slot].m_eType == PICKUP_NONE) { - bFreeFound = true; - break; - } - } - } else { - for (slot = 0; slot < NUMGENERALPICKUPS; slot++) { - if (aPickUps[slot].m_eType == PICKUP_NONE) { - bFreeFound = true; - break; - } - } - } - - if (!bFreeFound) - { - for (slot = 0; slot < NUMGENERALPICKUPS; slot++) { - if (aPickUps[slot].m_eType == PICKUP_MONEY) break; - } - - if (slot >= NUMGENERALPICKUPS) - { - for (slot = 0; slot < NUMGENERALPICKUPS; slot++) { - if (aPickUps[slot].m_eType == PICKUP_ONCE_TIMEOUT) break; - } - - if (slot >= NUMGENERALPICKUPS) return -1; - } - } - - if (slot >= NUMPICKUPS) return -1; - - aPickUps[slot].m_eType = (ePickupType)type; - aPickUps[slot].m_bRemoved = false; - aPickUps[slot].m_nQuantity = quantity; - if (type == PICKUP_ONCE_TIMEOUT) - aPickUps[slot].m_nTimer = CTimer::GetTimeInMilliseconds() + 20000; - else if (type == PICKUP_MONEY) - aPickUps[slot].m_nTimer = CTimer::GetTimeInMilliseconds() + 30000; - else if (type == PICKUP_MINE_INACTIVE || type == PICKUP_MINE_ARMED) { - aPickUps[slot].m_eType = PICKUP_MINE_INACTIVE; - aPickUps[slot].m_nTimer = CTimer::GetTimeInMilliseconds() + 1500; - } else if (type == PICKUP_NAUTICAL_MINE_INACTIVE || type == PICKUP_NAUTICAL_MINE_ARMED) { - aPickUps[slot].m_eType = PICKUP_NAUTICAL_MINE_INACTIVE; - aPickUps[slot].m_nTimer = CTimer::GetTimeInMilliseconds() + 1500; - } - aPickUps[slot].m_eModelIndex = modelIndex; - aPickUps[slot].m_vecPos = pos; - aPickUps[slot].m_pObject = aPickUps[slot].GiveUsAPickUpObject(-1); - if (aPickUps[slot].m_pObject) - CWorld::Add(aPickUps[slot].m_pObject); - return GetNewUniquePickupIndex(slot); -} - -int32 -CPickups::GenerateNewOne_WeaponType(CVector pos, eWeaponType weaponType, uint8 type, uint32 quantity) -{ - return GenerateNewOne(pos, ModelForWeapon(weaponType), type, quantity); -} - -int32 -CPickups::GetNewUniquePickupIndex(int32 slot) -{ - if (aPickUps[slot].m_nIndex >= 0xFFFE) - aPickUps[slot].m_nIndex = 1; - else - aPickUps[slot].m_nIndex++; - return slot | (aPickUps[slot].m_nIndex << 16); -} - -int32 -CPickups::ModelForWeapon(eWeaponType weaponType) -{ - switch (weaponType) - { - case WEAPONTYPE_BASEBALLBAT: return MI_BASEBALL_BAT; - case WEAPONTYPE_COLT45: return MI_COLT; - case WEAPONTYPE_UZI: return MI_UZI; - case WEAPONTYPE_SHOTGUN: return MI_SHOTGUN; - case WEAPONTYPE_AK47: return MI_AK47; - case WEAPONTYPE_M16: return MI_M16; - case WEAPONTYPE_SNIPERRIFLE: return MI_SNIPER; - case WEAPONTYPE_ROCKETLAUNCHER: return MI_ROCKETLAUNCHER; - case WEAPONTYPE_FLAMETHROWER: return MI_FLAMETHROWER; - case WEAPONTYPE_MOLOTOV: return MI_MOLOTOV; - case WEAPONTYPE_GRENADE: return MI_GRENADE; - } - return 0; -} - -eWeaponType -CPickups::WeaponForModel(int32 model) -{ - if (model == MI_PICKUP_BODYARMOUR) return WEAPONTYPE_ARMOUR; - switch (model) - { - case MI_GRENADE: return WEAPONTYPE_GRENADE; - case MI_AK47: return WEAPONTYPE_AK47; - case MI_BASEBALL_BAT: return WEAPONTYPE_BASEBALLBAT; - case MI_COLT: return WEAPONTYPE_COLT45; - case MI_MOLOTOV: return WEAPONTYPE_MOLOTOV; - case MI_ROCKETLAUNCHER: return WEAPONTYPE_ROCKETLAUNCHER; - case MI_SHOTGUN: return WEAPONTYPE_SHOTGUN; - case MI_SNIPER: return WEAPONTYPE_SNIPERRIFLE; - case MI_UZI: return WEAPONTYPE_UZI; - case MI_MISSILE: return WEAPONTYPE_UNARMED; - case MI_M16: return WEAPONTYPE_M16; - case MI_FLAMETHROWER: return WEAPONTYPE_FLAMETHROWER; - } - return WEAPONTYPE_UNARMED; -} - -int32 -CPickups::FindColourIndexForWeaponMI(int32 model) -{ - return WeaponForModel(model) - 1; -} - -void -CPickups::AddToCollectedPickupsArray(int32 index) -{ - aPickUpsCollected[CollectedPickUpIndex++] = index | (aPickUps[index].m_nIndex << 16); - if (CollectedPickUpIndex >= NUMCOLLECTEDPICKUPS) - CollectedPickUpIndex = 0; -} - -void -CPickups::Update() -{ -#ifdef FIX_BUGS // RIP speedrunning (solution from SA) - if (CReplay::IsPlayingBack()) - return; -#endif -#define PICKUPS_FRAME_SPAN (6) -#ifdef FIX_BUGS - for (uint32 i = NUMGENERALPICKUPS * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN) / PICKUPS_FRAME_SPAN; i < NUMGENERALPICKUPS * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN + 1) / PICKUPS_FRAME_SPAN; i++) { -#else // BUG: this code can only reach 318 out of 320 pickups - for (uint32 i = NUMGENERALPICKUPS / PICKUPS_FRAME_SPAN * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN); i < NUMGENERALPICKUPS / PICKUPS_FRAME_SPAN * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN + 1); i++) { -#endif - if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].Update(FindPlayerPed(), FindPlayerVehicle(), CWorld::PlayerInFocus)) { - AddToCollectedPickupsArray(i); - } - } -#undef PICKUPS_FRAME_SPAN - for (uint32 i = NUMGENERALPICKUPS; i < NUMPICKUPS; i++) { - if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].Update(FindPlayerPed(), FindPlayerVehicle(), CWorld::PlayerInFocus)) { - AddToCollectedPickupsArray(i); - } - } -} - -void -CPickups::DoPickUpEffects(CEntity *entity) -{ - if (entity->GetModelIndex() == MI_PICKUP_KILLFRENZY) - entity->m_flagD80 = CTheScripts::IsPlayerOnAMission() || CDarkel::FrenzyOnGoing() || !CGame::nastyGame; - - if (!entity->m_flagD80) { - float s = Sin((float)((CTimer::GetTimeInMilliseconds() + (uintptr)entity) & 0x7FF) * DEGTORAD(360.0f / 0x800)); - float modifiedSin = 0.3f * (s + 1.0f); - - - int16 colorId; - - if (entity->GetModelIndex() == MI_PICKUP_ADRENALINE || entity->GetModelIndex() == MI_PICKUP_CAMERA) - colorId = 11; - else if (entity->GetModelIndex() == MI_PICKUP_BODYARMOUR || entity->GetModelIndex() == MI_PICKUP_BRIBE) - colorId = 12; - else if (entity->GetModelIndex() == MI_PICKUP_INFO || entity->GetModelIndex() == MI_PICKUP_KILLFRENZY) - colorId = 13; - else if (entity->GetModelIndex() == MI_PICKUP_HEALTH || entity->GetModelIndex() == MI_PICKUP_BONUS) - colorId = 14; - else - colorId = FindColourIndexForWeaponMI(entity->GetModelIndex()); - - assert(colorId >= 0); - - CVector &pos = entity->GetPosition(); - - float colorModifier = ((CGeneral::GetRandomNumber() & 0x1F) * 0.015f + 1.0f) * modifiedSin * 0.15f; - CShadows::StoreStaticShadow( - (uintptr)entity, - SHADOWTYPE_ADDITIVE, - gpShadowExplosionTex, - &pos, - 2.0f, 0.0f, 0.0f, -2.0f, - 255, // this is 0 on PC which results in no shadow - aWeaponReds[colorId] * colorModifier, aWeaponGreens[colorId] * colorModifier, aWeaponBlues[colorId] * colorModifier, - 4.0f, 1.0f, 40.0f, false, 0.0f); - - float radius = (CGeneral::GetRandomNumber() & 0xF) * 0.1f + 3.0f; - CPointLights::AddLight(CPointLights::LIGHT_POINT, pos, CVector(0.0f, 0.0f, 0.0f), radius, aWeaponReds[colorId] * modifiedSin / 256.0f, aWeaponGreens[colorId] * modifiedSin / 256.0f, aWeaponBlues[colorId] * modifiedSin / 256.0f, CPointLights::FOG_NONE, true); - float size = (CGeneral::GetRandomNumber() & 0xF) * 0.0005f + 0.6f; - CCoronas::RegisterCorona( (uintptr)entity, - aWeaponReds[colorId] * modifiedSin / 2.0f, aWeaponGreens[colorId] * modifiedSin / 2.0f, aWeaponBlues[colorId] * modifiedSin / 2.0f, - 255, - pos, - size, 65.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); - - CObject *object = (CObject*)entity; - if (object->m_obj_flag2 || object->bOutOfStock || object->field_172) { - float dist = (TheCamera.GetPosition() - pos).Magnitude(); - const float MAXDIST = 12.0f; - - if (dist < MAXDIST && NumMessages < NUMPICKUPMESSAGES) { - RwV3d vecOut; - float fDistX, fDistY; - if (CSprite::CalcScreenCoors(entity->GetPosition() + CVector(0.0f, 0.0f, 0.7f), &vecOut, &fDistX, &fDistY, true)) { - aMessages[NumMessages].m_pos.x = vecOut.x; - aMessages[NumMessages].m_pos.y = vecOut.y; - aMessages[NumMessages].m_dist.x = fDistX; - aMessages[NumMessages].m_dist.y = fDistY; - aMessages[NumMessages].m_weaponType = WeaponForModel(entity->GetModelIndex()); - aMessages[NumMessages].m_color.red = aWeaponReds[colorId]; - aMessages[NumMessages].m_color.green = aWeaponGreens[colorId]; - aMessages[NumMessages].m_color.blue = aWeaponBlues[colorId]; - aMessages[NumMessages].m_color.alpha = (1.0f - dist / MAXDIST) * 128.0f; - aMessages[NumMessages].m_bOutOfStock = object->bOutOfStock; - aMessages[NumMessages].m_quantity = object->field_172; - NumMessages++; - } - } - } - - entity->GetMatrix().SetRotateZOnlyScaled((float)(CTimer::GetTimeInMilliseconds() & 0x7FF) * DEGTORAD(360.0f / 0x800), aWeaponScale[colorId]); - } -} - -void -CPickups::DoMineEffects(CEntity *entity) -{ - CVector &pos = entity->GetPosition(); - float dist = (TheCamera.GetPosition() - pos).Magnitude(); - const float MAXDIST = 20.0f; - - if (dist < MAXDIST) { - float s = Sin((float)((CTimer::GetTimeInMilliseconds() + (uintptr)entity) & 0x1FF) * DEGTORAD(360.0f / 0x200)); - - int32 red = (MAXDIST - dist) * (0.5f * s + 0.5f) / MAXDIST * 64.0f; - CShadows::StoreStaticShadow((uintptr)entity, SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos, - 2.0f, 0.0f, 0.0f, -2.0f, - 255, // this is 0 on PC which results in no shadow - red, 0, 0, - 4.0f, 1.0f, 40.0f, false, 0.0f); - CCoronas::RegisterCorona((uintptr)entity, red, 0, 0, 255, pos, 0.6f, 60.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); - } - - entity->GetMatrix().SetRotateZOnly((float)(CTimer::GetTimeInMilliseconds() & 0x3FF) * DEGTORAD(360.0f / 0x400)); -} - -void -CPickups::DoMoneyEffects(CEntity *entity) -{ - CVector &pos = entity->GetPosition(); - float dist = (TheCamera.GetPosition() - pos).Magnitude(); - const float MAXDIST = 20.0f; - - if (dist < MAXDIST) { - float s = Sin((float)((CTimer::GetTimeInMilliseconds() + (uintptr)entity) & 0x3FF) * DEGTORAD(360.0f / 0x400)); - - int32 green = (MAXDIST - dist) * (0.2f * s + 0.3f) / MAXDIST * 64.0f; - CShadows::StoreStaticShadow((uintptr)entity, SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos, - 2.0f, 0.0f, 0.0f, -2.0f, - 255, // this is 0 on PC which results in no shadow - 0, green, 0, - 4.0f, 1.0f, 40.0f, false, 0.0f); - CCoronas::RegisterCorona((uintptr)entity, 0, green, 0, 255, pos, 0.4f, 40.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); - } - - entity->GetMatrix().SetRotateZOnly((float)(CTimer::GetTimeInMilliseconds() & 0x7FF) * DEGTORAD(360.0f / 0x800)); -} - -void -CPickups::DoCollectableEffects(CEntity *entity) -{ - CVector &pos = entity->GetPosition(); - float dist = (TheCamera.GetPosition() - pos).Magnitude(); - const float MAXDIST = 14.0f; - - if (dist < MAXDIST) { - float s = Sin((float)((CTimer::GetTimeInMilliseconds() + (uintptr)entity) & 0x7FF) * DEGTORAD(360.0f / 0x800)); - - int32 color = (MAXDIST - dist) * (0.5f * s + 0.5f) / MAXDIST * 255.0f; - CShadows::StoreStaticShadow((uintptr)entity, SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos, - 2.0f, 0.0f, 0.0f, -2.0f, - 255, // this is 0 on PC which results in no shadow - color, color, color, - 4.0f, 1.0f, 40.0f, false, 0.0f); - CCoronas::RegisterCorona((uintptr)entity, color, color, color, 255, pos, 0.6f, 40.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); - } - - entity->GetMatrix().SetRotateZOnly((float)(CTimer::GetTimeInMilliseconds() & 0xFFF) * DEGTORAD(360.0f / 0x1000)); -} - -void -CPickups::RenderPickUpText() -{ - wchar *strToPrint; - for (int32 i = 0; i < NumMessages; i++) { - if (aMessages[i].m_quantity <= 39) { - switch (aMessages[i].m_quantity) // could use some enum maybe - { - case 0: - if (aMessages[i].m_weaponType == WEAPONTYPE_TOTALWEAPONS) { // unreachable code? - // what is this?? - sprintf(gString, "%d/%d", CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages, 2903); - } else { - if (aMessages[i].m_bOutOfStock) - strToPrint = TheText.Get("STOCK"); - else { - sprintf(gString, "$%d", CostOfWeapon[aMessages[i].m_weaponType]); - AsciiToUnicode(gString, gUString); - strToPrint = gUString; - } - } - break; - case 1: - strToPrint = TheText.Get("SECURI"); - break; - case 2: - strToPrint = TheText.Get("MOONBM"); - break; - case 3: - strToPrint = TheText.Get("COACH"); - break; - case 4: - strToPrint = TheText.Get("FLATBED"); - break; - case 5: - strToPrint = TheText.Get("LINERUN"); - break; - case 6: - strToPrint = TheText.Get("TRASHM"); - break; - case 7: - strToPrint = TheText.Get("PATRIOT"); - break; - case 8: - strToPrint = TheText.Get("WHOOPEE"); - break; - case 9: - strToPrint = TheText.Get("BLISTA"); - break; - case 10: - strToPrint = TheText.Get("MULE"); - break; - case 11: - strToPrint = TheText.Get("YANKEE"); - break; - case 12: - strToPrint = TheText.Get("BOBCAT"); - break; - case 13: - strToPrint = TheText.Get("DODO"); - break; - case 14: - strToPrint = TheText.Get("BUS"); - break; - case 15: - strToPrint = TheText.Get("RUMPO"); - break; - case 16: - strToPrint = TheText.Get("PONY"); - break; - case 17: - strToPrint = TheText.Get("SENTINL"); - break; - case 18: - strToPrint = TheText.Get("CHEETAH"); - break; - case 19: - strToPrint = TheText.Get("BANSHEE"); - break; - case 20: - strToPrint = TheText.Get("IDAHO"); - break; - case 21: - strToPrint = TheText.Get("INFERNS"); - break; - case 22: - strToPrint = TheText.Get("TAXI"); - break; - case 23: - strToPrint = TheText.Get("KURUMA"); - break; - case 24: - strToPrint = TheText.Get("STRETCH"); - break; - case 25: - strToPrint = TheText.Get("PEREN"); - break; - case 26: - strToPrint = TheText.Get("STINGER"); - break; - case 27: - strToPrint = TheText.Get("MANANA"); - break; - case 28: - strToPrint = TheText.Get("LANDSTK"); - break; - case 29: - strToPrint = TheText.Get("STALION"); - break; - case 30: - strToPrint = TheText.Get("BFINJC"); - break; - case 31: - strToPrint = TheText.Get("CABBIE"); - break; - case 32: - strToPrint = TheText.Get("ESPERAN"); - break; - case 33: - strToPrint = TheText.Get("FIRETRK"); - break; - case 34: - strToPrint = TheText.Get("AMBULAN"); - break; - case 35: - strToPrint = TheText.Get("ENFORCR"); - break; - case 36: - strToPrint = TheText.Get("FBICAR"); - break; - case 37: - strToPrint = TheText.Get("RHINO"); - break; - case 38: - strToPrint = TheText.Get("BARRCKS"); - break; - case 39: - strToPrint = TheText.Get("POLICAR"); - break; - default: - break; - } - } - CFont::SetPropOn(); - CFont::SetBackgroundOff(); - - const float MAX_SCALE = 1.0f; - - float fScaleY = aMessages[i].m_dist.y / 100.0f; - if (fScaleY > MAX_SCALE) fScaleY = MAX_SCALE; - - float fScaleX = aMessages[i].m_dist.x / 100.0f; - if (fScaleX > MAX_SCALE) fScaleX = MAX_SCALE; - - CFont::SetScale(fScaleX, fScaleY); - CFont::SetCentreOn(); - CFont::SetCentreSize(SCREEN_WIDTH); - CFont::SetJustifyOff(); - - CFont::SetColor(CRGBA(aMessages[i].m_color.red, aMessages[i].m_color.green, aMessages[i].m_color.blue, aMessages[i].m_color.alpha)); - CFont::SetBackGroundOnlyTextOff(); - CFont::SetFontStyle(FONT_BANK); - CFont::PrintString(aMessages[i].m_pos.x, aMessages[i].m_pos.y, strToPrint); - } - NumMessages = 0; -} - -void -CPickups::Load(uint8 *buf, uint32 size) -{ -INITSAVEBUF - - for (int32 i = 0; i < NUMPICKUPS; i++) { - aPickUps[i] = ReadSaveBuf(buf); - - if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].m_pObject != nil) - aPickUps[i].m_pObject = CPools::GetObjectPool()->GetSlot((int32)aPickUps[i].m_pObject - 1); - } - - CollectedPickUpIndex = ReadSaveBuf(buf); - ReadSaveBuf(buf); - NumMessages = 0; - - for (uint16 i = 0; i < NUMCOLLECTEDPICKUPS; i++) - aPickUpsCollected[i] = ReadSaveBuf(buf); - -VALIDATESAVEBUF(size) -} - -void -CPickups::Save(uint8 *buf, uint32 *size) -{ - *size = sizeof(aPickUps) + sizeof(uint16) + sizeof(uint16) + sizeof(aPickUpsCollected); - -INITSAVEBUF - - for (int32 i = 0; i < NUMPICKUPS; i++) { - CPickup *buf_pickup = WriteSaveBuf(buf, aPickUps[i]); - if (buf_pickup->m_eType != PICKUP_NONE && buf_pickup->m_pObject != nil) - buf_pickup->m_pObject = (CObject*)(CPools::GetObjectPool()->GetJustIndex(buf_pickup->m_pObject) + 1); - } - - WriteSaveBuf(buf, CollectedPickUpIndex); - WriteSaveBuf(buf, (uint16)0); // possibly was NumMessages - - for (uint16 i = 0; i < NUMCOLLECTEDPICKUPS; i++) - WriteSaveBuf(buf, aPickUpsCollected[i]); - -VALIDATESAVEBUF(*size) -} - -STARTPATCHES - InjectHook(0x430220, CPickups::Init, PATCH_JUMP); - InjectHook(0x4303D0, CPickups::Update, PATCH_JUMP); - InjectHook(0x432440, CPickups::RenderPickUpText, PATCH_JUMP); - InjectHook(0x431C30, CPickups::DoCollectableEffects, PATCH_JUMP); - InjectHook(0x431F40, CPickups::DoMoneyEffects, PATCH_JUMP); - InjectHook(0x4321C0, CPickups::DoMineEffects, PATCH_JUMP); - InjectHook(0x431520, CPickups::DoPickUpEffects, PATCH_JUMP); - InjectHook(0x4304B0, CPickups::GenerateNewOne, PATCH_JUMP); - InjectHook(0x430660, CPickups::GenerateNewOne_WeaponType, PATCH_JUMP); - InjectHook(0x4307A0, CPickups::RemovePickUp, PATCH_JUMP); - InjectHook(0x430800, CPickups::RemoveAllFloatingPickups, PATCH_JUMP); - InjectHook(0x433D60, CPickups::AddToCollectedPickupsArray, PATCH_JUMP); - InjectHook(0x430770, CPickups::IsPickUpPickedUp, PATCH_JUMP); - InjectHook(0x430690, CPickups::ModelForWeapon, PATCH_JUMP); - InjectHook(0x4306F0, CPickups::WeaponForModel, PATCH_JUMP); - InjectHook(0x431510, CPickups::FindColourIndexForWeaponMI, PATCH_JUMP);/**/ - InjectHook(0x433DF0, CPickups::GetActualPickupIndex, PATCH_JUMP); - InjectHook(0x433DB0, CPickups::GetNewUniquePickupIndex, PATCH_JUMP); - InjectHook(0x433B60, CPickups::PassTime, PATCH_JUMP); - InjectHook(0x4339F0, CPickups::GivePlayerGoodiesWithPickUpMI, PATCH_JUMP); - InjectHook(0x433F60, CPickups::Load, PATCH_JUMP); - InjectHook(0x433E40, CPickups::Save, PATCH_JUMP); - InjectHook(0x433BA0, &CPickup::GiveUsAPickUpObject, PATCH_JUMP); - InjectHook(0x430860, &CPickup::Update, PATCH_JUMP); -ENDPATCHES +#include "common.h" +#include "patcher.h" +#include "main.h" + +#include "Camera.h" +#include "Coronas.h" +#include "Darkel.h" +#include "Entity.h" +#include "Explosion.h" +#include "Font.h" +#include "Garages.h" +#include "General.h" +#include "ModelIndices.h" +#include "Object.h" +#include "Pad.h" +#include "Pickups.h" +#include "PlayerPed.h" +#include "Wanted.h" +#include "DMAudio.h" +#include "Fire.h" +#include "PointLights.h" +#include "Pools.h" +#ifdef FIX_BUGS +#include "Replay.h" +#endif +#include "Script.h" +#include "Shadows.h" +#include "SpecialFX.h" +#include "Sprite.h" +#include "Timer.h" +#include "WaterLevel.h" +#include "World.h" + +CPickup(&CPickups::aPickUps)[NUMPICKUPS] = *(CPickup(*)[NUMPICKUPS])*(uintptr*)0x878C98; +int16 CPickups::NumMessages;// = *(int16*)0x95CC98; +int32 CPickups::aPickUpsCollected[NUMCOLLECTEDPICKUPS];// = *(int32(*)[NUMCOLLECTEDPICKUPS])*(uintptr*)0x87C538; +int16 CPickups::CollectedPickUpIndex;// = *(int16*)0x95CC8A; + +// unused +bool &CPickups::bPickUpcamActivated = *(bool*)0x95CD71; +CVehicle *&CPickups::pPlayerVehicle = *(CVehicle**)0x8F29E8; +CVector &CPickups::StaticCamCoors = *(CVector*)0x9404C8; +uint32 &CPickups::StaticCamStartTime = *(uint32*)0x8E289C; + +tPickupMessage CPickups::aMessages[NUMPICKUPMESSAGES]; + +// 20 ?! Some Miami leftover? (Originally at 0x5ED8D4) +uint16 AmmoForWeapon[20] = { 0, 1, 45, 125, 25, 150, 300, 25, 5, 250, 5, 5, 0, 500, 0, 100, 0, 0, 0, 0 }; +uint16 AmmoForWeapon_OnStreet[20] = { 0, 1, 9, 25, 5, 30, 60, 5, 1, 50, 1, 1, 0, 200, 0, 100, 0, 0, 0, 0 }; +uint16 CostOfWeapon[20] = { 0, 10, 250, 800, 1500, 3000, 5000, 10000, 25000, 25000, 2000, 2000, 0, 50000, 0, 3000, 0, 0, 0, 0 }; + +uint8 aWeaponReds[] = { 255, 0, 128, 255, 255, 0, 255, 0, 128, 128, 255, 255, 128, 0, 255, 0 }; +uint8 aWeaponGreens[] = { 0, 255, 128, 255, 0, 255, 128, 255, 0, 255, 255, 0, 255, 0, 255, 0 }; +uint8 aWeaponBlues[] = { 0, 0, 255, 0, 255, 255, 0, 128, 255, 0, 255, 0, 128, 255, 0, 0 }; +float aWeaponScale[] = { 1.0f, 2.0f, 1.5f, 1.0f, 1.0f, 1.5f, 1.0f, 2.0f, 1.0f, 2.0f, 2.5f, 1.0f, 1.0f, 1.0f, 1.0f }; + +WRAPPER void CPacManPickups::Init(void) { EAXJMP(0x432760); } +WRAPPER void CPacManPickups::Update(void) { EAXJMP(0x432800); } +WRAPPER void CPacManPickups::GeneratePMPickUps(CVector, float, int16, uint8) { EAXJMP(0x432AE0); } +WRAPPER void CPacManPickups::GeneratePMPickUpsForRace(int32) { EAXJMP(0x432D50); } +WRAPPER void CPacManPickups::GenerateOnePMPickUp(CVector) { EAXJMP(0x432F20); } +WRAPPER void CPacManPickups::Render(void) { EAXJMP(0x432F60); } +WRAPPER void CPacManPickups::DoCleanUpPacManStuff(void) { EAXJMP(0x433150); } +WRAPPER void CPacManPickups::StartPacManRace(int32) { EAXJMP(0x433340); } +WRAPPER void CPacManPickups::StartPacManRecord(void) { EAXJMP(0x433360); } +WRAPPER uint32 CPacManPickups::QueryPowerPillsEatenInRace(void) { EAXJMP(0x4333A0); } +WRAPPER void CPacManPickups::ResetPowerPillsEatenInRace(void) { EAXJMP(0x4333B0); } +WRAPPER void CPacManPickups::CleanUpPacManStuff(void) { EAXJMP(0x4333C0); } +WRAPPER void CPacManPickups::StartPacManScramble(CVector, float, int16) { EAXJMP(0x4333D0); } +WRAPPER uint32 CPacManPickups::QueryPowerPillsCarriedByPlayer(void) { EAXJMP(0x4333F0); } +WRAPPER void CPacManPickups::ResetPowerPillsCarriedByPlayer(void) { EAXJMP(0x433410); } + + +void +CPickup::RemoveKeepType() +{ + CWorld::Remove(m_pObject); + delete m_pObject; + + m_bRemoved = true; + m_pObject = nil; +} + +void +CPickup::Remove() +{ + RemoveKeepType(); + m_eType = PICKUP_NONE; +} + +CObject * +CPickup::GiveUsAPickUpObject(int32 handle) +{ + CObject *object; + + if (handle <= 0) object = new CObject(m_eModelIndex, false); + else { + CPools::MakeSureSlotInObjectPoolIsEmpty(handle); + object = new(handle) CObject(m_eModelIndex, false); + } + + if (object == nil) return nil; + object->ObjectCreatedBy = MISSION_OBJECT; + object->GetPosition() = m_vecPos; + object->SetOrientation(0.0f, 0.0f, -HALFPI); + object->GetMatrix().UpdateRW(); + object->UpdateRwFrame(); + + object->bAffectedByGravity = false; + object->bExplosionProof = true; + object->bUsesCollision = false; + object->bIsPickup = true; + + object->field_172 = m_eModelIndex == MI_PICKUP_BONUS ? m_nQuantity : 0; + + switch (m_eType) + { + case PICKUP_IN_SHOP: + object->m_obj_flag2 = true; + object->bOutOfStock = false; + break; + case PICKUP_ON_STREET: + case PICKUP_ONCE: + case PICKUP_ONCE_TIMEOUT: + case PICKUP_COLLECTABLE1: + case PICKUP_MONEY: + case PICKUP_MINE_INACTIVE: + case PICKUP_MINE_ARMED: + case PICKUP_NAUTICAL_MINE_INACTIVE: + case PICKUP_NAUTICAL_MINE_ARMED: + case PICKUP_FLOATINGPACKAGE: + case PICKUP_ON_STREET_SLOW: + object->m_obj_flag2 = false; + object->bOutOfStock = false; + break; + case PICKUP_IN_SHOP_OUT_OF_STOCK: + object->m_obj_flag2 = false; + object->bOutOfStock = true; + object->bRenderScorched = true; + break; + case PICKUP_FLOATINGPACKAGE_FLOATING: + default: + break; + } + return object; +} + +bool +CPickup::CanBePickedUp(CPlayerPed *player) +{ + assert(m_pObject != nil); + bool cannotBePickedUp = + (m_pObject->GetModelIndex() == MI_PICKUP_BODYARMOUR && player->m_fArmour > 99.5f) + || (m_pObject->GetModelIndex() == MI_PICKUP_HEALTH && player->m_fHealth > 99.5f) + || (m_pObject->GetModelIndex() == MI_PICKUP_BRIBE && player->m_pWanted->m_nWantedLevel == 0) + || (m_pObject->GetModelIndex() == MI_PICKUP_KILLFRENZY && (CTheScripts::IsPlayerOnAMission() || CDarkel::FrenzyOnGoing() || !CGame::nastyGame)); + return !cannotBePickedUp; +} + +bool +CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId) +{ + float waterLevel; + + if (m_bRemoved) { + if (CTimer::GetTimeInMilliseconds() > m_nTimer) { + // respawn pickup if we're far enough + float dist = (FindPlayerCoors().x - m_vecPos.x) * (FindPlayerCoors().x - m_vecPos.x) + (FindPlayerCoors().y - m_vecPos.y) * (FindPlayerCoors().y - m_vecPos.y); + if (dist > 100.0f || m_eType == PICKUP_IN_SHOP && dist > 2.4f) { + m_pObject = GiveUsAPickUpObject(-1); + if (m_pObject) { + CWorld::Add(m_pObject); + m_bRemoved = false; + } + } + } + return false; + } + + if (!m_pObject) return false; + + if (!IsMine()) { + // let's check if we touched the pickup + bool isPickupTouched = false; + if (m_pObject->GetModelIndex() == MI_PICKUP_BRIBE) { + if (vehicle != nil) { + if (vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 2.0f)) + isPickupTouched = true; + } + else { + if (Abs(player->GetPosition().z - m_pObject->GetPosition().z) < 2.0f) { + if ((player->GetPosition().x - m_pObject->GetPosition().x) * (player->GetPosition().x - m_pObject->GetPosition().x) + + (player->GetPosition().y - m_pObject->GetPosition().y) * (player->GetPosition().y - m_pObject->GetPosition().y) < 1.8f) + isPickupTouched = true; + } + } + } else if (m_pObject->GetModelIndex() == MI_PICKUP_CAMERA) { + if (vehicle != nil && vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 2.0f)) { + isPickupTouched = true; + } + } else if (vehicle == nil) { + if (Abs(player->GetPosition().z - m_pObject->GetPosition().z) < 2.0f) { + if ((player->GetPosition().x - m_pObject->GetPosition().x) * (player->GetPosition().x - m_pObject->GetPosition().x) + + (player->GetPosition().y - m_pObject->GetPosition().y) * (player->GetPosition().y - m_pObject->GetPosition().y) < 1.8f) + isPickupTouched = true; + } + } + + // if we didn't then we've got nothing to do + if (isPickupTouched && CanBePickedUp(player)) { + CPad::GetPad(0)->StartShake(120, 100); + switch (m_eType) + { + case PICKUP_IN_SHOP: + if (CWorld::Players[playerId].m_nMoney < CostOfWeapon[CPickups::WeaponForModel(m_pObject->GetModelIndex())]) { + CGarages::TriggerMessage("PU_MONY", -1, 6000, -1); + } else { + CWorld::Players[playerId].m_nMoney -= CostOfWeapon[CPickups::WeaponForModel(m_pObject->GetModelIndex())]; + if (!CPickups::GivePlayerGoodiesWithPickUpMI(m_pObject->GetModelIndex(), playerId)) { + player->GiveWeapon(CPickups::WeaponForModel(m_pObject->GetModelIndex()), AmmoForWeapon[CPickups::WeaponForModel(m_pObject->GetModelIndex())]); + player->m_nSelectedWepSlot = player->GetWeaponSlot(CPickups::WeaponForModel(m_pObject->GetModelIndex())); + DMAudio.PlayFrontEndSound(SOUND_PICKUP_WEAPON_BOUGHT, m_pObject->GetModelIndex() - MI_GRENADE); + } + RemoveKeepType(); + m_nTimer = CTimer::GetTimeInMilliseconds() + 5000; + return true; + } + break; + case PICKUP_ON_STREET: + case PICKUP_ON_STREET_SLOW: + if (!CPickups::GivePlayerGoodiesWithPickUpMI(m_pObject->GetModelIndex(), playerId)) { + if (CPickups::WeaponForModel(m_pObject->GetModelIndex())) { + player->GiveWeapon(CPickups::WeaponForModel(m_pObject->GetModelIndex()), m_nQuantity != 0 ? m_nQuantity : AmmoForWeapon_OnStreet[CPickups::WeaponForModel(m_pObject->GetModelIndex())]); + if (player->m_nSelectedWepSlot == player->GetWeaponSlot(WEAPONTYPE_UNARMED)) { + player->m_nSelectedWepSlot = player->GetWeaponSlot(CPickups::WeaponForModel(m_pObject->GetModelIndex())); + } + DMAudio.PlayFrontEndSound(SOUND_PICKUP_WEAPON, m_pObject->GetModelIndex() - MI_GRENADE); + } else if (m_pObject->GetModelIndex() == MI_PICKUP_CAMERA && vehicle != nil) { + DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0); + CPickups::bPickUpcamActivated = true; + CPickups::pPlayerVehicle = FindPlayerVehicle(); + CPickups::StaticCamCoors = m_pObject->GetPosition(); + CPickups::StaticCamStartTime = CTimer::GetTimeInMilliseconds(); + } + } + if (m_eType == PICKUP_ON_STREET) { + m_nTimer = CTimer::GetTimeInMilliseconds() + 30000; + } else if (m_eType == PICKUP_ON_STREET_SLOW) { + if (MI_PICKUP_BRIBE == m_pObject->m_modelIndex) + m_nTimer = CTimer::GetTimeInMilliseconds() + 300000; + else + m_nTimer = CTimer::GetTimeInMilliseconds() + 720000; + } + + RemoveKeepType(); + return true; + case PICKUP_ONCE: + case PICKUP_ONCE_TIMEOUT: + if (!CPickups::GivePlayerGoodiesWithPickUpMI(m_pObject->GetModelIndex(), playerId)) { + if (CPickups::WeaponForModel(m_pObject->GetModelIndex())) { + player->GiveWeapon(CPickups::WeaponForModel(m_pObject->GetModelIndex()), m_nQuantity != 0 ? m_nQuantity : AmmoForWeapon[CPickups::WeaponForModel(m_pObject->GetModelIndex())]); + if (player->m_nSelectedWepSlot == player->GetWeaponSlot(WEAPONTYPE_UNARMED)) + player->m_nSelectedWepSlot = player->GetWeaponSlot(CPickups::WeaponForModel(m_pObject->GetModelIndex())); + } + DMAudio.PlayFrontEndSound(SOUND_PICKUP_WEAPON, m_pObject->GetModelIndex() - MI_GRENADE); + } + Remove(); + return true; + case PICKUP_COLLECTABLE1: + CWorld::Players[playerId].m_nCollectedPackages++; + CWorld::Players[playerId].m_nMoney += 1000; + + if (CWorld::Players[playerId].m_nCollectedPackages == CWorld::Players[playerId].m_nTotalPackages) { + printf("All collectables have been picked up\n"); + CGarages::TriggerMessage("CO_ALL", -1, 5000, -1); + CWorld::Players[CWorld::PlayerInFocus].m_nMoney += 1000000; + } else + CGarages::TriggerMessage("CO_ONE", CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages, 5000, CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages); + + Remove(); + DMAudio.PlayFrontEndSound(SOUND_PICKUP_HIDDEN_PACKAGE, 0); + return true; + case PICKUP_MONEY: + CWorld::Players[playerId].m_nMoney += m_nQuantity; + sprintf(gString, "$%d", m_nQuantity); +#ifdef MONEY_MESSAGES + CMoneyMessages::RegisterOne(m_vecPos + CVector(0.0f, 0.0f, 1.0f), gString, 0, 255, 0, 0.5f, 0.5f); +#endif + Remove(); + DMAudio.PlayFrontEndSound(SOUND_PICKUP_MONEY, 0); + return true; + //case PICKUP_IN_SHOP_OUT_OF_STOCK: + //case PICKUP_MINE_INACTIVE: + //case PICKUP_MINE_ARMED: + //case PICKUP_NAUTICAL_MINE_INACTIVE: + //case PICKUP_NAUTICAL_MINE_ARMED: + //case PICKUP_FLOATINGPACKAGE: + //case PICKUP_FLOATINGPACKAGE_FLOATING: + default: + break; + } + } + } else { + switch (m_eType) + { + case PICKUP_MINE_INACTIVE: + if (vehicle != nil && !vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 2.0f)) { + m_eType = PICKUP_MINE_ARMED; + m_nTimer = CTimer::GetTimeInMilliseconds() + 10000; + } + break; + case PICKUP_NAUTICAL_MINE_INACTIVE: + { + if (CWaterLevel::GetWaterLevel(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z + 5.0f, &waterLevel, false)) + m_pObject->GetPosition().z = waterLevel + 0.6f; + + m_pObject->GetMatrix().UpdateRW(); + m_pObject->UpdateRwFrame(); + + bool touched = false; + for (int32 i = CPools::GetVehiclePool()->GetSize()-1; i >= 0; i--) { + CVehicle *vehicle = CPools::GetVehiclePool()->GetSlot(i); + if (vehicle != nil && vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 1.5f)) { + touched = true; + break; // added break here + } + } + + if (!touched) { + m_eType = PICKUP_NAUTICAL_MINE_ARMED; + m_nTimer = CTimer::GetTimeInMilliseconds() + 10000; + } + break; + } + case PICKUP_NAUTICAL_MINE_ARMED: + if (CWaterLevel::GetWaterLevel(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z + 5.0f, &waterLevel, false)) + m_pObject->GetPosition().z = waterLevel + 0.6f; + + m_pObject->GetMatrix().UpdateRW(); + m_pObject->UpdateRwFrame(); + // no break here + case PICKUP_MINE_ARMED: + { + bool explode = false; + if (CTimer::GetTimeInMilliseconds() > m_nTimer) + explode = true; + else {// added else here since vehicle lookup is useless + for (int32 i = CPools::GetVehiclePool()->GetSize()-1; i >= 0; i--) { + CVehicle *vehicle = CPools::GetVehiclePool()->GetSlot(i); + if (vehicle != nil && vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 1.5f)) { + explode = true; + break; // added break here + } + } + } + if (explode) { + CExplosion::AddExplosion(nil, nil, EXPLOSION_MINE, m_pObject->GetPosition(), 0); + Remove(); + } + break; + } + case PICKUP_FLOATINGPACKAGE: + m_pObject->m_vecMoveSpeed.z -= 0.01f * CTimer::GetTimeStep(); + m_pObject->GetPosition() += m_pObject->GetMoveSpeed() * CTimer::GetTimeStep(); + + m_pObject->GetMatrix().UpdateRW(); + m_pObject->UpdateRwFrame(); + if (CWaterLevel::GetWaterLevel(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z + 5.0f, &waterLevel, 0) && waterLevel >= m_pObject->GetPosition().z) + m_eType = PICKUP_FLOATINGPACKAGE_FLOATING; + break; + case PICKUP_FLOATINGPACKAGE_FLOATING: + if (CWaterLevel::GetWaterLevel(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z + 5.0f, &waterLevel, 0)) + m_pObject->GetPosition().z = waterLevel; + + m_pObject->GetMatrix().UpdateRW(); + m_pObject->UpdateRwFrame(); + if (vehicle != nil && vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 2.0f)) { + Remove(); + DMAudio.PlayFrontEndSound(SOUND_PICKUP_FLOAT_PACKAGE, 0); + return true; + } + break; + } + } + if (!m_bRemoved && (m_eType == PICKUP_ONCE_TIMEOUT || m_eType == PICKUP_MONEY) && CTimer::GetTimeInMilliseconds() > m_nTimer) + Remove(); + return false; +} + +void +CPickups::Init(void) +{ + NumMessages = 0; + for (int i = 0; i < NUMPICKUPS; i++) { + aPickUps[i].m_eType = PICKUP_NONE; + aPickUps[i].m_nIndex = 1; + aPickUps[i].m_pObject = nil; + } + + for (int i = 0; i < NUMCOLLECTEDPICKUPS; i++) + aPickUpsCollected[i] = 0; + + CollectedPickUpIndex = 0; +} + +bool +CPickups::IsPickUpPickedUp(int32 pickupId) +{ + for (int i = 0; i < NUMCOLLECTEDPICKUPS; i++) { + if (pickupId == aPickUpsCollected[i]) { + aPickUpsCollected[i] = 0; + return true; + } + } + return false; +} + +void +CPickups::PassTime(uint32 time) +{ + for (int i = 0; i < NUMPICKUPS; i++) { + if (aPickUps[i].m_eType != PICKUP_NONE) { + if (aPickUps[i].m_nTimer <= time) + aPickUps[i].m_nTimer = 0; + else + aPickUps[i].m_nTimer -= time; + } + } +} + +int32 +CPickups::GetActualPickupIndex(int32 index) +{ + if (index == -1) return -1; + + // doesn't look nice + if ((uint16)((index & 0xFFFF0000) >> 16) != aPickUps[(uint16)index].m_nIndex) return -1; + return (uint16)index; +} + +bool +CPickups::GivePlayerGoodiesWithPickUpMI(int16 modelIndex, int playerIndex) +{ + CPlayerPed *player; + + if (playerIndex <= 0) player = CWorld::Players[CWorld::PlayerInFocus].m_pPed; + else player = CWorld::Players[playerIndex].m_pPed; + + if (modelIndex == MI_PICKUP_ADRENALINE) { + player->m_bAdrenalineActive = true; + player->m_nAdrenalineTime = CTimer::GetTimeInMilliseconds() + 20000; + player->m_fCurrentStamina = player->m_fMaxStamina; + DMAudio.PlayFrontEndSound(SOUND_PICKUP_ADRENALINE, 0); + return true; + } else if (modelIndex == MI_PICKUP_BODYARMOUR) { + player->m_fArmour = 100.0f; + DMAudio.PlayFrontEndSound(SOUND_PICKUP_ARMOUR, 0); + return true; + } else if (modelIndex == MI_PICKUP_INFO) { + DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0); + return true; + } else if (modelIndex == MI_PICKUP_HEALTH) { + player->m_fHealth = 100.0f; + DMAudio.PlayFrontEndSound(SOUND_PICKUP_HEALTH, 0); + return true; + } else if (modelIndex == MI_PICKUP_BONUS) { + DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0); + return true; + } else if (modelIndex == MI_PICKUP_BRIBE) { + int32 level = FindPlayerPed()->m_pWanted->m_nWantedLevel - 1; + if (level < 0) level = 0; + player->SetWantedLevel(level); + DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0); + return true; + } else if (modelIndex == MI_PICKUP_KILLFRENZY) { + DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0); + return true; + } + return false; +} + +void +CPickups::RemoveAllFloatingPickups() +{ + for (int i = 0; i < NUMPICKUPS; i++) { + if (aPickUps[i].m_eType == PICKUP_FLOATINGPACKAGE || aPickUps[i].m_eType == PICKUP_FLOATINGPACKAGE_FLOATING) { + if (aPickUps[i].m_pObject) { + CWorld::Remove(aPickUps[i].m_pObject); + delete aPickUps[i].m_pObject; + aPickUps[i].m_pObject = nil; + } + } + } +} + +void +CPickups::RemovePickUp(int32 pickupIndex) +{ + int32 index = CPickups::GetActualPickupIndex(pickupIndex); + if (index == -1) return; + + if (aPickUps[index].m_pObject) { + CWorld::Remove(aPickUps[index].m_pObject); + delete aPickUps[index].m_pObject; + aPickUps[index].m_pObject = nil; + } + aPickUps[index].m_eType = PICKUP_NONE; + aPickUps[index].m_bRemoved = true; +} + +int32 +CPickups::GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quantity) +{ + bool bFreeFound = false; + int32 slot = 0; + + if (type == PICKUP_FLOATINGPACKAGE || type == PICKUP_NAUTICAL_MINE_INACTIVE) { + for (slot = NUMPICKUPS; slot >= 0; slot--) { + if (aPickUps[slot].m_eType == PICKUP_NONE) { + bFreeFound = true; + break; + } + } + } else { + for (slot = 0; slot < NUMGENERALPICKUPS; slot++) { + if (aPickUps[slot].m_eType == PICKUP_NONE) { + bFreeFound = true; + break; + } + } + } + + if (!bFreeFound) + { + for (slot = 0; slot < NUMGENERALPICKUPS; slot++) { + if (aPickUps[slot].m_eType == PICKUP_MONEY) break; + } + + if (slot >= NUMGENERALPICKUPS) + { + for (slot = 0; slot < NUMGENERALPICKUPS; slot++) { + if (aPickUps[slot].m_eType == PICKUP_ONCE_TIMEOUT) break; + } + + if (slot >= NUMGENERALPICKUPS) return -1; + } + } + + if (slot >= NUMPICKUPS) return -1; + + aPickUps[slot].m_eType = (ePickupType)type; + aPickUps[slot].m_bRemoved = false; + aPickUps[slot].m_nQuantity = quantity; + if (type == PICKUP_ONCE_TIMEOUT) + aPickUps[slot].m_nTimer = CTimer::GetTimeInMilliseconds() + 20000; + else if (type == PICKUP_MONEY) + aPickUps[slot].m_nTimer = CTimer::GetTimeInMilliseconds() + 30000; + else if (type == PICKUP_MINE_INACTIVE || type == PICKUP_MINE_ARMED) { + aPickUps[slot].m_eType = PICKUP_MINE_INACTIVE; + aPickUps[slot].m_nTimer = CTimer::GetTimeInMilliseconds() + 1500; + } else if (type == PICKUP_NAUTICAL_MINE_INACTIVE || type == PICKUP_NAUTICAL_MINE_ARMED) { + aPickUps[slot].m_eType = PICKUP_NAUTICAL_MINE_INACTIVE; + aPickUps[slot].m_nTimer = CTimer::GetTimeInMilliseconds() + 1500; + } + aPickUps[slot].m_eModelIndex = modelIndex; + aPickUps[slot].m_vecPos = pos; + aPickUps[slot].m_pObject = aPickUps[slot].GiveUsAPickUpObject(-1); + if (aPickUps[slot].m_pObject) + CWorld::Add(aPickUps[slot].m_pObject); + return GetNewUniquePickupIndex(slot); +} + +int32 +CPickups::GenerateNewOne_WeaponType(CVector pos, eWeaponType weaponType, uint8 type, uint32 quantity) +{ + return GenerateNewOne(pos, ModelForWeapon(weaponType), type, quantity); +} + +int32 +CPickups::GetNewUniquePickupIndex(int32 slot) +{ + if (aPickUps[slot].m_nIndex >= 0xFFFE) + aPickUps[slot].m_nIndex = 1; + else + aPickUps[slot].m_nIndex++; + return slot | (aPickUps[slot].m_nIndex << 16); +} + +int32 +CPickups::ModelForWeapon(eWeaponType weaponType) +{ + switch (weaponType) + { + case WEAPONTYPE_BASEBALLBAT: return MI_BASEBALL_BAT; + case WEAPONTYPE_COLT45: return MI_COLT; + case WEAPONTYPE_UZI: return MI_UZI; + case WEAPONTYPE_SHOTGUN: return MI_SHOTGUN; + case WEAPONTYPE_AK47: return MI_AK47; + case WEAPONTYPE_M16: return MI_M16; + case WEAPONTYPE_SNIPERRIFLE: return MI_SNIPER; + case WEAPONTYPE_ROCKETLAUNCHER: return MI_ROCKETLAUNCHER; + case WEAPONTYPE_FLAMETHROWER: return MI_FLAMETHROWER; + case WEAPONTYPE_MOLOTOV: return MI_MOLOTOV; + case WEAPONTYPE_GRENADE: return MI_GRENADE; + } + return 0; +} + +eWeaponType +CPickups::WeaponForModel(int32 model) +{ + if (model == MI_PICKUP_BODYARMOUR) return WEAPONTYPE_ARMOUR; + switch (model) + { + case MI_GRENADE: return WEAPONTYPE_GRENADE; + case MI_AK47: return WEAPONTYPE_AK47; + case MI_BASEBALL_BAT: return WEAPONTYPE_BASEBALLBAT; + case MI_COLT: return WEAPONTYPE_COLT45; + case MI_MOLOTOV: return WEAPONTYPE_MOLOTOV; + case MI_ROCKETLAUNCHER: return WEAPONTYPE_ROCKETLAUNCHER; + case MI_SHOTGUN: return WEAPONTYPE_SHOTGUN; + case MI_SNIPER: return WEAPONTYPE_SNIPERRIFLE; + case MI_UZI: return WEAPONTYPE_UZI; + case MI_MISSILE: return WEAPONTYPE_UNARMED; + case MI_M16: return WEAPONTYPE_M16; + case MI_FLAMETHROWER: return WEAPONTYPE_FLAMETHROWER; + } + return WEAPONTYPE_UNARMED; +} + +int32 +CPickups::FindColourIndexForWeaponMI(int32 model) +{ + return WeaponForModel(model) - 1; +} + +void +CPickups::AddToCollectedPickupsArray(int32 index) +{ + aPickUpsCollected[CollectedPickUpIndex++] = index | (aPickUps[index].m_nIndex << 16); + if (CollectedPickUpIndex >= NUMCOLLECTEDPICKUPS) + CollectedPickUpIndex = 0; +} + +void +CPickups::Update() +{ +#ifdef FIX_BUGS // RIP speedrunning (solution from SA) + if (CReplay::IsPlayingBack()) + return; +#endif +#define PICKUPS_FRAME_SPAN (6) +#ifdef FIX_BUGS + for (uint32 i = NUMGENERALPICKUPS * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN) / PICKUPS_FRAME_SPAN; i < NUMGENERALPICKUPS * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN + 1) / PICKUPS_FRAME_SPAN; i++) { +#else // BUG: this code can only reach 318 out of 320 pickups + for (uint32 i = NUMGENERALPICKUPS / PICKUPS_FRAME_SPAN * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN); i < NUMGENERALPICKUPS / PICKUPS_FRAME_SPAN * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN + 1); i++) { +#endif + if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].Update(FindPlayerPed(), FindPlayerVehicle(), CWorld::PlayerInFocus)) { + AddToCollectedPickupsArray(i); + } + } +#undef PICKUPS_FRAME_SPAN + for (uint32 i = NUMGENERALPICKUPS; i < NUMPICKUPS; i++) { + if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].Update(FindPlayerPed(), FindPlayerVehicle(), CWorld::PlayerInFocus)) { + AddToCollectedPickupsArray(i); + } + } +} + +void +CPickups::DoPickUpEffects(CEntity *entity) +{ + if (entity->GetModelIndex() == MI_PICKUP_KILLFRENZY) + entity->m_flagD80 = CTheScripts::IsPlayerOnAMission() || CDarkel::FrenzyOnGoing() || !CGame::nastyGame; + + if (!entity->m_flagD80) { + float s = Sin((float)((CTimer::GetTimeInMilliseconds() + (uintptr)entity) & 0x7FF) * DEGTORAD(360.0f / 0x800)); + float modifiedSin = 0.3f * (s + 1.0f); + + + int16 colorId; + + if (entity->GetModelIndex() == MI_PICKUP_ADRENALINE || entity->GetModelIndex() == MI_PICKUP_CAMERA) + colorId = 11; + else if (entity->GetModelIndex() == MI_PICKUP_BODYARMOUR || entity->GetModelIndex() == MI_PICKUP_BRIBE) + colorId = 12; + else if (entity->GetModelIndex() == MI_PICKUP_INFO || entity->GetModelIndex() == MI_PICKUP_KILLFRENZY) + colorId = 13; + else if (entity->GetModelIndex() == MI_PICKUP_HEALTH || entity->GetModelIndex() == MI_PICKUP_BONUS) + colorId = 14; + else + colorId = FindColourIndexForWeaponMI(entity->GetModelIndex()); + + assert(colorId >= 0); + + CVector &pos = entity->GetPosition(); + + float colorModifier = ((CGeneral::GetRandomNumber() & 0x1F) * 0.015f + 1.0f) * modifiedSin * 0.15f; + CShadows::StoreStaticShadow( + (uintptr)entity, + SHADOWTYPE_ADDITIVE, + gpShadowExplosionTex, + &pos, + 2.0f, 0.0f, 0.0f, -2.0f, + 255, // this is 0 on PC which results in no shadow + aWeaponReds[colorId] * colorModifier, aWeaponGreens[colorId] * colorModifier, aWeaponBlues[colorId] * colorModifier, + 4.0f, 1.0f, 40.0f, false, 0.0f); + + float radius = (CGeneral::GetRandomNumber() & 0xF) * 0.1f + 3.0f; + CPointLights::AddLight(CPointLights::LIGHT_POINT, pos, CVector(0.0f, 0.0f, 0.0f), radius, aWeaponReds[colorId] * modifiedSin / 256.0f, aWeaponGreens[colorId] * modifiedSin / 256.0f, aWeaponBlues[colorId] * modifiedSin / 256.0f, CPointLights::FOG_NONE, true); + float size = (CGeneral::GetRandomNumber() & 0xF) * 0.0005f + 0.6f; + CCoronas::RegisterCorona( (uintptr)entity, + aWeaponReds[colorId] * modifiedSin / 2.0f, aWeaponGreens[colorId] * modifiedSin / 2.0f, aWeaponBlues[colorId] * modifiedSin / 2.0f, + 255, + pos, + size, 65.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); + + CObject *object = (CObject*)entity; + if (object->m_obj_flag2 || object->bOutOfStock || object->field_172) { + float dist = (TheCamera.GetPosition() - pos).Magnitude(); + const float MAXDIST = 12.0f; + + if (dist < MAXDIST && NumMessages < NUMPICKUPMESSAGES) { + RwV3d vecOut; + float fDistX, fDistY; + if (CSprite::CalcScreenCoors(entity->GetPosition() + CVector(0.0f, 0.0f, 0.7f), &vecOut, &fDistX, &fDistY, true)) { + aMessages[NumMessages].m_pos.x = vecOut.x; + aMessages[NumMessages].m_pos.y = vecOut.y; + aMessages[NumMessages].m_dist.x = fDistX; + aMessages[NumMessages].m_dist.y = fDistY; + aMessages[NumMessages].m_weaponType = WeaponForModel(entity->GetModelIndex()); + aMessages[NumMessages].m_color.red = aWeaponReds[colorId]; + aMessages[NumMessages].m_color.green = aWeaponGreens[colorId]; + aMessages[NumMessages].m_color.blue = aWeaponBlues[colorId]; + aMessages[NumMessages].m_color.alpha = (1.0f - dist / MAXDIST) * 128.0f; + aMessages[NumMessages].m_bOutOfStock = object->bOutOfStock; + aMessages[NumMessages].m_quantity = object->field_172; + NumMessages++; + } + } + } + + entity->GetMatrix().SetRotateZOnlyScaled((float)(CTimer::GetTimeInMilliseconds() & 0x7FF) * DEGTORAD(360.0f / 0x800), aWeaponScale[colorId]); + } +} + +void +CPickups::DoMineEffects(CEntity *entity) +{ + CVector &pos = entity->GetPosition(); + float dist = (TheCamera.GetPosition() - pos).Magnitude(); + const float MAXDIST = 20.0f; + + if (dist < MAXDIST) { + float s = Sin((float)((CTimer::GetTimeInMilliseconds() + (uintptr)entity) & 0x1FF) * DEGTORAD(360.0f / 0x200)); + + int32 red = (MAXDIST - dist) * (0.5f * s + 0.5f) / MAXDIST * 64.0f; + CShadows::StoreStaticShadow((uintptr)entity, SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos, + 2.0f, 0.0f, 0.0f, -2.0f, + 255, // this is 0 on PC which results in no shadow + red, 0, 0, + 4.0f, 1.0f, 40.0f, false, 0.0f); + CCoronas::RegisterCorona((uintptr)entity, red, 0, 0, 255, pos, 0.6f, 60.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); + } + + entity->GetMatrix().SetRotateZOnly((float)(CTimer::GetTimeInMilliseconds() & 0x3FF) * DEGTORAD(360.0f / 0x400)); +} + +void +CPickups::DoMoneyEffects(CEntity *entity) +{ + CVector &pos = entity->GetPosition(); + float dist = (TheCamera.GetPosition() - pos).Magnitude(); + const float MAXDIST = 20.0f; + + if (dist < MAXDIST) { + float s = Sin((float)((CTimer::GetTimeInMilliseconds() + (uintptr)entity) & 0x3FF) * DEGTORAD(360.0f / 0x400)); + + int32 green = (MAXDIST - dist) * (0.2f * s + 0.3f) / MAXDIST * 64.0f; + CShadows::StoreStaticShadow((uintptr)entity, SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos, + 2.0f, 0.0f, 0.0f, -2.0f, + 255, // this is 0 on PC which results in no shadow + 0, green, 0, + 4.0f, 1.0f, 40.0f, false, 0.0f); + CCoronas::RegisterCorona((uintptr)entity, 0, green, 0, 255, pos, 0.4f, 40.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); + } + + entity->GetMatrix().SetRotateZOnly((float)(CTimer::GetTimeInMilliseconds() & 0x7FF) * DEGTORAD(360.0f / 0x800)); +} + +void +CPickups::DoCollectableEffects(CEntity *entity) +{ + CVector &pos = entity->GetPosition(); + float dist = (TheCamera.GetPosition() - pos).Magnitude(); + const float MAXDIST = 14.0f; + + if (dist < MAXDIST) { + float s = Sin((float)((CTimer::GetTimeInMilliseconds() + (uintptr)entity) & 0x7FF) * DEGTORAD(360.0f / 0x800)); + + int32 color = (MAXDIST - dist) * (0.5f * s + 0.5f) / MAXDIST * 255.0f; + CShadows::StoreStaticShadow((uintptr)entity, SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &pos, + 2.0f, 0.0f, 0.0f, -2.0f, + 255, // this is 0 on PC which results in no shadow + color, color, color, + 4.0f, 1.0f, 40.0f, false, 0.0f); + CCoronas::RegisterCorona((uintptr)entity, color, color, color, 255, pos, 0.6f, 40.0f, CCoronas::TYPE_RING, CCoronas::FLARE_NONE, CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF, CCoronas::STREAK_OFF, 0.0f); + } + + entity->GetMatrix().SetRotateZOnly((float)(CTimer::GetTimeInMilliseconds() & 0xFFF) * DEGTORAD(360.0f / 0x1000)); +} + +void +CPickups::RenderPickUpText() +{ + wchar *strToPrint; + for (int32 i = 0; i < NumMessages; i++) { + if (aMessages[i].m_quantity <= 39) { + switch (aMessages[i].m_quantity) // could use some enum maybe + { + case 0: + if (aMessages[i].m_weaponType == WEAPONTYPE_TOTALWEAPONS) { // unreachable code? + // what is this?? + sprintf(gString, "%d/%d", CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages, 2903); + } else { + if (aMessages[i].m_bOutOfStock) + strToPrint = TheText.Get("STOCK"); + else { + sprintf(gString, "$%d", CostOfWeapon[aMessages[i].m_weaponType]); + AsciiToUnicode(gString, gUString); + strToPrint = gUString; + } + } + break; + case 1: + strToPrint = TheText.Get("SECURI"); + break; + case 2: + strToPrint = TheText.Get("MOONBM"); + break; + case 3: + strToPrint = TheText.Get("COACH"); + break; + case 4: + strToPrint = TheText.Get("FLATBED"); + break; + case 5: + strToPrint = TheText.Get("LINERUN"); + break; + case 6: + strToPrint = TheText.Get("TRASHM"); + break; + case 7: + strToPrint = TheText.Get("PATRIOT"); + break; + case 8: + strToPrint = TheText.Get("WHOOPEE"); + break; + case 9: + strToPrint = TheText.Get("BLISTA"); + break; + case 10: + strToPrint = TheText.Get("MULE"); + break; + case 11: + strToPrint = TheText.Get("YANKEE"); + break; + case 12: + strToPrint = TheText.Get("BOBCAT"); + break; + case 13: + strToPrint = TheText.Get("DODO"); + break; + case 14: + strToPrint = TheText.Get("BUS"); + break; + case 15: + strToPrint = TheText.Get("RUMPO"); + break; + case 16: + strToPrint = TheText.Get("PONY"); + break; + case 17: + strToPrint = TheText.Get("SENTINL"); + break; + case 18: + strToPrint = TheText.Get("CHEETAH"); + break; + case 19: + strToPrint = TheText.Get("BANSHEE"); + break; + case 20: + strToPrint = TheText.Get("IDAHO"); + break; + case 21: + strToPrint = TheText.Get("INFERNS"); + break; + case 22: + strToPrint = TheText.Get("TAXI"); + break; + case 23: + strToPrint = TheText.Get("KURUMA"); + break; + case 24: + strToPrint = TheText.Get("STRETCH"); + break; + case 25: + strToPrint = TheText.Get("PEREN"); + break; + case 26: + strToPrint = TheText.Get("STINGER"); + break; + case 27: + strToPrint = TheText.Get("MANANA"); + break; + case 28: + strToPrint = TheText.Get("LANDSTK"); + break; + case 29: + strToPrint = TheText.Get("STALION"); + break; + case 30: + strToPrint = TheText.Get("BFINJC"); + break; + case 31: + strToPrint = TheText.Get("CABBIE"); + break; + case 32: + strToPrint = TheText.Get("ESPERAN"); + break; + case 33: + strToPrint = TheText.Get("FIRETRK"); + break; + case 34: + strToPrint = TheText.Get("AMBULAN"); + break; + case 35: + strToPrint = TheText.Get("ENFORCR"); + break; + case 36: + strToPrint = TheText.Get("FBICAR"); + break; + case 37: + strToPrint = TheText.Get("RHINO"); + break; + case 38: + strToPrint = TheText.Get("BARRCKS"); + break; + case 39: + strToPrint = TheText.Get("POLICAR"); + break; + default: + break; + } + } + CFont::SetPropOn(); + CFont::SetBackgroundOff(); + + const float MAX_SCALE = 1.0f; + + float fScaleY = aMessages[i].m_dist.y / 100.0f; + if (fScaleY > MAX_SCALE) fScaleY = MAX_SCALE; + + float fScaleX = aMessages[i].m_dist.x / 100.0f; + if (fScaleX > MAX_SCALE) fScaleX = MAX_SCALE; + + CFont::SetScale(fScaleX, fScaleY); + CFont::SetCentreOn(); + CFont::SetCentreSize(SCREEN_WIDTH); + CFont::SetJustifyOff(); + + CFont::SetColor(CRGBA(aMessages[i].m_color.red, aMessages[i].m_color.green, aMessages[i].m_color.blue, aMessages[i].m_color.alpha)); + CFont::SetBackGroundOnlyTextOff(); + CFont::SetFontStyle(FONT_BANK); + CFont::PrintString(aMessages[i].m_pos.x, aMessages[i].m_pos.y, strToPrint); + } + NumMessages = 0; +} + +void +CPickups::Load(uint8 *buf, uint32 size) +{ +INITSAVEBUF + + for (int32 i = 0; i < NUMPICKUPS; i++) { + aPickUps[i] = ReadSaveBuf(buf); + + if (aPickUps[i].m_eType != PICKUP_NONE && aPickUps[i].m_pObject != nil) + aPickUps[i].m_pObject = CPools::GetObjectPool()->GetSlot((int32)aPickUps[i].m_pObject - 1); + } + + CollectedPickUpIndex = ReadSaveBuf(buf); + ReadSaveBuf(buf); + NumMessages = 0; + + for (uint16 i = 0; i < NUMCOLLECTEDPICKUPS; i++) + aPickUpsCollected[i] = ReadSaveBuf(buf); + +VALIDATESAVEBUF(size) +} + +void +CPickups::Save(uint8 *buf, uint32 *size) +{ + *size = sizeof(aPickUps) + sizeof(uint16) + sizeof(uint16) + sizeof(aPickUpsCollected); + +INITSAVEBUF + + for (int32 i = 0; i < NUMPICKUPS; i++) { + CPickup *buf_pickup = WriteSaveBuf(buf, aPickUps[i]); + if (buf_pickup->m_eType != PICKUP_NONE && buf_pickup->m_pObject != nil) + buf_pickup->m_pObject = (CObject*)(CPools::GetObjectPool()->GetJustIndex(buf_pickup->m_pObject) + 1); + } + + WriteSaveBuf(buf, CollectedPickUpIndex); + WriteSaveBuf(buf, (uint16)0); // possibly was NumMessages + + for (uint16 i = 0; i < NUMCOLLECTEDPICKUPS; i++) + WriteSaveBuf(buf, aPickUpsCollected[i]); + +VALIDATESAVEBUF(*size) +} + +STARTPATCHES + InjectHook(0x430220, CPickups::Init, PATCH_JUMP); + InjectHook(0x4303D0, CPickups::Update, PATCH_JUMP); + InjectHook(0x432440, CPickups::RenderPickUpText, PATCH_JUMP); + InjectHook(0x431C30, CPickups::DoCollectableEffects, PATCH_JUMP); + InjectHook(0x431F40, CPickups::DoMoneyEffects, PATCH_JUMP); + InjectHook(0x4321C0, CPickups::DoMineEffects, PATCH_JUMP); + InjectHook(0x431520, CPickups::DoPickUpEffects, PATCH_JUMP); + InjectHook(0x4304B0, CPickups::GenerateNewOne, PATCH_JUMP); + InjectHook(0x430660, CPickups::GenerateNewOne_WeaponType, PATCH_JUMP); + InjectHook(0x4307A0, CPickups::RemovePickUp, PATCH_JUMP); + InjectHook(0x430800, CPickups::RemoveAllFloatingPickups, PATCH_JUMP); + InjectHook(0x433D60, CPickups::AddToCollectedPickupsArray, PATCH_JUMP); + InjectHook(0x430770, CPickups::IsPickUpPickedUp, PATCH_JUMP); + InjectHook(0x430690, CPickups::ModelForWeapon, PATCH_JUMP); + InjectHook(0x4306F0, CPickups::WeaponForModel, PATCH_JUMP); + InjectHook(0x431510, CPickups::FindColourIndexForWeaponMI, PATCH_JUMP);/**/ + InjectHook(0x433DF0, CPickups::GetActualPickupIndex, PATCH_JUMP); + InjectHook(0x433DB0, CPickups::GetNewUniquePickupIndex, PATCH_JUMP); + InjectHook(0x433B60, CPickups::PassTime, PATCH_JUMP); + InjectHook(0x4339F0, CPickups::GivePlayerGoodiesWithPickUpMI, PATCH_JUMP); + InjectHook(0x433F60, CPickups::Load, PATCH_JUMP); + InjectHook(0x433E40, CPickups::Save, PATCH_JUMP); + InjectHook(0x433BA0, &CPickup::GiveUsAPickUpObject, PATCH_JUMP); + InjectHook(0x430860, &CPickup::Update, PATCH_JUMP); +ENDPATCHES diff --git a/src/control/Pickups.h b/src/control/Pickups.h index 4bb0ddff..3e075b24 100644 --- a/src/control/Pickups.h +++ b/src/control/Pickups.h @@ -1,124 +1,124 @@ -#pragma once -#include "Weapon.h" - -enum ePickupType : uint8 -{ - PICKUP_NONE = 0, - PICKUP_IN_SHOP, - PICKUP_ON_STREET, - PICKUP_ONCE, - PICKUP_ONCE_TIMEOUT, - PICKUP_COLLECTABLE1, - PICKUP_IN_SHOP_OUT_OF_STOCK, - PICKUP_MONEY, - PICKUP_MINE_INACTIVE, - PICKUP_MINE_ARMED, - PICKUP_NAUTICAL_MINE_INACTIVE, - PICKUP_NAUTICAL_MINE_ARMED, - PICKUP_FLOATINGPACKAGE, - PICKUP_FLOATINGPACKAGE_FLOATING, - PICKUP_ON_STREET_SLOW, - PICKUP_NUMOFTYPES -}; - -class CEntity; -class CObject; -class CVehicle; -class CPlayerPed; - -class CPickup -{ -public: - ePickupType m_eType; - bool m_bRemoved; - uint16 m_nQuantity; - CObject *m_pObject; - uint32 m_nTimer; - int16 m_eModelIndex; - uint16 m_nIndex; - CVector m_vecPos; - - CObject *GiveUsAPickUpObject(int32 handle); - bool Update(CPlayerPed *player, CVehicle *vehicle, int playerId); -private: - bool IsMine() { return m_eType >= PICKUP_MINE_INACTIVE && m_eType <= PICKUP_FLOATINGPACKAGE_FLOATING; } - inline bool CanBePickedUp(CPlayerPed *player); - void RemoveKeepType(); - void Remove(); -}; - -static_assert(sizeof(CPickup) == 0x1C, "CPickup: error"); - -struct tPickupMessage -{ - CVector2D m_pos; - eWeaponType m_weaponType; - CVector2D m_dist; - CRGBA m_color; - uint8 m_bOutOfStock : 1; - uint8 m_quantity; -}; - -class CPickups -{ - static int32 aPickUpsCollected[NUMCOLLECTEDPICKUPS]; - static int16 CollectedPickUpIndex; - static int16 NumMessages; - static tPickupMessage aMessages[NUMPICKUPMESSAGES]; -public: - static void Init(); - static void Update(); - static void RenderPickUpText(); - static void DoCollectableEffects(CEntity *ent); - static void DoMoneyEffects(CEntity *ent); - static void DoMineEffects(CEntity *ent); - static void DoPickUpEffects(CEntity *ent); - static int32 GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quantity); - static int32 GenerateNewOne_WeaponType(CVector pos, eWeaponType weaponType, uint8 type, uint32 quantity); - static void RemovePickUp(int32 pickupIndex); - static void RemoveAllFloatingPickups(); - static void AddToCollectedPickupsArray(int32 index); - static bool IsPickUpPickedUp(int32 pickupId); - static int32 ModelForWeapon(eWeaponType weaponType); - static enum eWeaponType WeaponForModel(int32 model); - static int32 FindColourIndexForWeaponMI(int32 model); - static int32 GetActualPickupIndex(int32 index); - static int32 GetNewUniquePickupIndex(int32 slot); - static void PassTime(uint32 time); - static bool GivePlayerGoodiesWithPickUpMI(int16 modelIndex, int playerIndex); - static void Load(uint8 *buf, uint32 size); - static void Save(uint8 *buf, uint32 *size); - - static CPickup(&aPickUps)[NUMPICKUPS]; - - // unused - static bool &bPickUpcamActivated; - static CVehicle *&pPlayerVehicle; - static CVector &StaticCamCoors; - static uint32 &StaticCamStartTime; -}; - -extern uint16 AmmoForWeapon[20]; -extern uint16 AmmoForWeapon_OnStreet[20]; -extern uint16 CostOfWeapon[20]; - -class CPacManPickups -{ -public: - static void Init(void); - static void Update(void); - static void GeneratePMPickUps(CVector, float, int16, uint8); - static void GeneratePMPickUpsForRace(int32); - static void GenerateOnePMPickUp(CVector); - static void Render(void); - static void DoCleanUpPacManStuff(void); - static void StartPacManRace(int32); - static void StartPacManRecord(void); - static uint32 QueryPowerPillsEatenInRace(void); - static void ResetPowerPillsEatenInRace(void); - static void CleanUpPacManStuff(void); - static void StartPacManScramble(CVector, float, int16); - static uint32 QueryPowerPillsCarriedByPlayer(void); - static void ResetPowerPillsCarriedByPlayer(void); - -}; +#pragma once +#include "Weapon.h" + +enum ePickupType : uint8 +{ + PICKUP_NONE = 0, + PICKUP_IN_SHOP, + PICKUP_ON_STREET, + PICKUP_ONCE, + PICKUP_ONCE_TIMEOUT, + PICKUP_COLLECTABLE1, + PICKUP_IN_SHOP_OUT_OF_STOCK, + PICKUP_MONEY, + PICKUP_MINE_INACTIVE, + PICKUP_MINE_ARMED, + PICKUP_NAUTICAL_MINE_INACTIVE, + PICKUP_NAUTICAL_MINE_ARMED, + PICKUP_FLOATINGPACKAGE, + PICKUP_FLOATINGPACKAGE_FLOATING, + PICKUP_ON_STREET_SLOW, + PICKUP_NUMOFTYPES +}; + +class CEntity; +class CObject; +class CVehicle; +class CPlayerPed; + +class CPickup +{ +public: + ePickupType m_eType; + bool m_bRemoved; + uint16 m_nQuantity; + CObject *m_pObject; + uint32 m_nTimer; + int16 m_eModelIndex; + uint16 m_nIndex; + CVector m_vecPos; + + CObject *GiveUsAPickUpObject(int32 handle); + bool Update(CPlayerPed *player, CVehicle *vehicle, int playerId); +private: + bool IsMine() { return m_eType >= PICKUP_MINE_INACTIVE && m_eType <= PICKUP_FLOATINGPACKAGE_FLOATING; } + inline bool CanBePickedUp(CPlayerPed *player); + void RemoveKeepType(); + void Remove(); +}; + +static_assert(sizeof(CPickup) == 0x1C, "CPickup: error"); + +struct tPickupMessage +{ + CVector2D m_pos; + eWeaponType m_weaponType; + CVector2D m_dist; + CRGBA m_color; + uint8 m_bOutOfStock : 1; + uint8 m_quantity; +}; + +class CPickups +{ + static int32 aPickUpsCollected[NUMCOLLECTEDPICKUPS]; + static int16 CollectedPickUpIndex; + static int16 NumMessages; + static tPickupMessage aMessages[NUMPICKUPMESSAGES]; +public: + static void Init(); + static void Update(); + static void RenderPickUpText(); + static void DoCollectableEffects(CEntity *ent); + static void DoMoneyEffects(CEntity *ent); + static void DoMineEffects(CEntity *ent); + static void DoPickUpEffects(CEntity *ent); + static int32 GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quantity); + static int32 GenerateNewOne_WeaponType(CVector pos, eWeaponType weaponType, uint8 type, uint32 quantity); + static void RemovePickUp(int32 pickupIndex); + static void RemoveAllFloatingPickups(); + static void AddToCollectedPickupsArray(int32 index); + static bool IsPickUpPickedUp(int32 pickupId); + static int32 ModelForWeapon(eWeaponType weaponType); + static enum eWeaponType WeaponForModel(int32 model); + static int32 FindColourIndexForWeaponMI(int32 model); + static int32 GetActualPickupIndex(int32 index); + static int32 GetNewUniquePickupIndex(int32 slot); + static void PassTime(uint32 time); + static bool GivePlayerGoodiesWithPickUpMI(int16 modelIndex, int playerIndex); + static void Load(uint8 *buf, uint32 size); + static void Save(uint8 *buf, uint32 *size); + + static CPickup(&aPickUps)[NUMPICKUPS]; + + // unused + static bool &bPickUpcamActivated; + static CVehicle *&pPlayerVehicle; + static CVector &StaticCamCoors; + static uint32 &StaticCamStartTime; +}; + +extern uint16 AmmoForWeapon[20]; +extern uint16 AmmoForWeapon_OnStreet[20]; +extern uint16 CostOfWeapon[20]; + +class CPacManPickups +{ +public: + static void Init(void); + static void Update(void); + static void GeneratePMPickUps(CVector, float, int16, uint8); + static void GeneratePMPickUpsForRace(int32); + static void GenerateOnePMPickUp(CVector); + static void Render(void); + static void DoCleanUpPacManStuff(void); + static void StartPacManRace(int32); + static void StartPacManRecord(void); + static uint32 QueryPowerPillsEatenInRace(void); + static void ResetPowerPillsEatenInRace(void); + static void CleanUpPacManStuff(void); + static void StartPacManScramble(CVector, float, int16); + static uint32 QueryPowerPillsCarriedByPlayer(void); + static void ResetPowerPillsCarriedByPlayer(void); + +}; diff --git a/src/control/PowerPoints.cpp b/src/control/PowerPoints.cpp index 4bc773a9..9a74e8d9 100644 --- a/src/control/PowerPoints.cpp +++ b/src/control/PowerPoints.cpp @@ -1,22 +1,22 @@ -#include "common.h" -#include "PowerPoints.h" - -// Some cut beta feature - -void CPowerPoint::Update() -{} - -void CPowerPoints::Init() -{} - -void CPowerPoints::Update() -{} - -void CPowerPoints::GenerateNewOne(float, float, float, float, float, float, uint8) -{} - -void CPowerPoints::Save(uint8**, uint32*) -{} - -void CPowerPoints::Load(uint8*, uint32) +#include "common.h" +#include "PowerPoints.h" + +// Some cut beta feature + +void CPowerPoint::Update() +{} + +void CPowerPoints::Init() +{} + +void CPowerPoints::Update() +{} + +void CPowerPoints::GenerateNewOne(float, float, float, float, float, float, uint8) +{} + +void CPowerPoints::Save(uint8**, uint32*) +{} + +void CPowerPoints::Load(uint8*, uint32) {} \ No newline at end of file diff --git a/src/control/PowerPoints.h b/src/control/PowerPoints.h index d7478076..ee3750cd 100644 --- a/src/control/PowerPoints.h +++ b/src/control/PowerPoints.h @@ -1,26 +1,26 @@ -#pragma once - -enum -{ - POWERPOINT_NONE = 0, - POWERPOINT_HEALTH, - POWERPOINT_HIDEOUT_INDUSTRIAL, - POWERPOINT_HIDEOUT_COMMERCIAL, - POWERPOINT_HIDEOUT_SUBURBAN -}; - -class CPowerPoint -{ -public: - void Update(); -}; - -class CPowerPoints -{ -public: - static void Init(); - static void Update(); - static void GenerateNewOne(float, float, float, float, float, float, uint8); - static void Save(uint8**, uint32*); - static void Load(uint8*, uint32); +#pragma once + +enum +{ + POWERPOINT_NONE = 0, + POWERPOINT_HEALTH, + POWERPOINT_HIDEOUT_INDUSTRIAL, + POWERPOINT_HIDEOUT_COMMERCIAL, + POWERPOINT_HIDEOUT_SUBURBAN +}; + +class CPowerPoint +{ +public: + void Update(); +}; + +class CPowerPoints +{ +public: + static void Init(); + static void Update(); + static void GenerateNewOne(float, float, float, float, float, float, uint8); + static void Save(uint8**, uint32*); + static void Load(uint8*, uint32); }; \ No newline at end of file diff --git a/src/control/Restart.cpp b/src/control/Restart.cpp index 8e983555..788a054a 100644 --- a/src/control/Restart.cpp +++ b/src/control/Restart.cpp @@ -21,234 +21,234 @@ CVector(&CRestart::PoliceRestartPoints)[NUM_RESTART_POINTS] = *(CVector(*)[NUM_R float(&CRestart::PoliceRestartHeadings)[NUM_RESTART_POINTS] = *(float(*)[NUM_RESTART_POINTS])*(uintptr*)0x6F1D20; uint16 &CRestart::NumberOfPoliceRestarts = *(uint16*)0x95CC44; -void -CRestart::Initialise() -{ - OverridePoliceStationLevel = LEVEL_NONE; - OverrideHospitalLevel = LEVEL_NONE; - bFadeInAfterNextArrest = true; - bFadeInAfterNextDeath = true; - OverrideHeading = 0.0f; - OverridePosition = CVector(0.0f, 0.0f, 0.0f); - bOverrideRestart = false; - NumberOfPoliceRestarts = 0; - NumberOfHospitalRestarts = 0; - - for (int i = 0; i < NUM_RESTART_POINTS; i++) { - HospitalRestartPoints[i] = CVector(0.0f, 0.0f, 0.0f); - HospitalRestartHeadings[i] = 0.0f; - PoliceRestartPoints[i] = CVector(0.0f, 0.0f, 0.0f); - PoliceRestartHeadings[i] = 0.0f; - } +void +CRestart::Initialise() +{ + OverridePoliceStationLevel = LEVEL_NONE; + OverrideHospitalLevel = LEVEL_NONE; + bFadeInAfterNextArrest = true; + bFadeInAfterNextDeath = true; + OverrideHeading = 0.0f; + OverridePosition = CVector(0.0f, 0.0f, 0.0f); + bOverrideRestart = false; + NumberOfPoliceRestarts = 0; + NumberOfHospitalRestarts = 0; + + for (int i = 0; i < NUM_RESTART_POINTS; i++) { + HospitalRestartPoints[i] = CVector(0.0f, 0.0f, 0.0f); + HospitalRestartHeadings[i] = 0.0f; + PoliceRestartPoints[i] = CVector(0.0f, 0.0f, 0.0f); + PoliceRestartHeadings[i] = 0.0f; + } +} + +void +CRestart::AddHospitalRestartPoint(const CVector &pos, float heading) +{ + HospitalRestartPoints[NumberOfHospitalRestarts] = pos; + HospitalRestartHeadings[NumberOfHospitalRestarts++] = heading; +} + +void +CRestart::AddPoliceRestartPoint(const CVector &pos, float heading) +{ + PoliceRestartPoints[NumberOfPoliceRestarts] = pos; + PoliceRestartHeadings[NumberOfPoliceRestarts++] = heading; +} + +void +CRestart::OverrideNextRestart(const CVector &pos, float heading) +{ + bOverrideRestart = true; + OverridePosition = pos; + OverrideHeading = heading; } -void -CRestart::AddHospitalRestartPoint(const CVector &pos, float heading) -{ - HospitalRestartPoints[NumberOfHospitalRestarts] = pos; - HospitalRestartHeadings[NumberOfHospitalRestarts++] = heading; +void +CRestart::CancelOverrideRestart() +{ + bOverrideRestart = false; } -void -CRestart::AddPoliceRestartPoint(const CVector &pos, float heading) -{ - PoliceRestartPoints[NumberOfPoliceRestarts] = pos; - PoliceRestartHeadings[NumberOfPoliceRestarts++] = heading; +void +CRestart::FindClosestHospitalRestartPoint(const CVector &pos, CVector *outPos, float *outHeading) +{ + if (bOverrideRestart) { + *outPos = OverridePosition; + *outHeading = OverrideHeading; + CancelOverrideRestart(); + return; + } + + eLevelName curlevel = CTheZones::FindZoneForPoint(pos); + float fMinDist = 16000000.0f; + int closestPoint = NUM_RESTART_POINTS; + + // find closest point on this level + for (int i = 0; i < NumberOfHospitalRestarts; i++) { + if (CTheZones::FindZoneForPoint(HospitalRestartPoints[i]) == (OverrideHospitalLevel != LEVEL_NONE ? OverrideHospitalLevel : curlevel)) { + float dist = (pos - HospitalRestartPoints[i]).MagnitudeSqr(); + if (fMinDist >= dist) { + fMinDist = dist; + closestPoint = i; + } + } + } + + // if we didn't find anything, find closest point on any level + if (closestPoint == NUM_RESTART_POINTS) { + for (int i = 0; i < NumberOfHospitalRestarts; i++) { + float dist = (pos - HospitalRestartPoints[i]).MagnitudeSqr(); + if (fMinDist >= dist) { + fMinDist = dist; + closestPoint = i; + } + } + } + + // if we still didn't find anything, find closest path node + if (closestPoint == NUM_RESTART_POINTS) { + *outPos = ThePaths.m_pathNodes[ThePaths.FindNodeClosestToCoors(pos, PATH_PED, 999999.9f)].pos; + *outHeading = 0.0f; + printf("Couldn't find a hospital restart zone near the player %f %f %f->%f %f %f\n", pos.x, pos.y, pos.z, outPos->x, outPos->y, outPos->z); + } else { + *outPos = HospitalRestartPoints[closestPoint]; + *outHeading = HospitalRestartHeadings[closestPoint]; + } } -void -CRestart::OverrideNextRestart(const CVector &pos, float heading) -{ - bOverrideRestart = true; - OverridePosition = pos; - OverrideHeading = heading; +void +CRestart::FindClosestPoliceRestartPoint(const CVector &pos, CVector *outPos, float *outHeading) +{ + if (bOverrideRestart) { + *outPos = OverridePosition; + *outHeading = OverrideHeading; + CancelOverrideRestart(); + return; + } + + eLevelName curlevel = CTheZones::FindZoneForPoint(pos); + float fMinDist = 16000000.0f; + int closestPoint = NUM_RESTART_POINTS; + + // find closest point on this level + for (int i = 0; i < NumberOfPoliceRestarts; i++) { + if (CTheZones::FindZoneForPoint(PoliceRestartPoints[i]) == (OverridePoliceStationLevel != LEVEL_NONE ? OverridePoliceStationLevel : curlevel)) { + float dist = (pos - PoliceRestartPoints[i]).MagnitudeSqr(); + if (fMinDist >= dist) { + fMinDist = dist; + closestPoint = i; + } + } + } + + // if we didn't find anything, find closest point on any level + if (closestPoint == NUM_RESTART_POINTS) { + for (int i = 0; i < NumberOfPoliceRestarts; i++) { + float dist = (pos - PoliceRestartPoints[i]).MagnitudeSqr(); + if (fMinDist >= dist) { + fMinDist = dist; + closestPoint = i; + } + } + } + + // if we still didn't find anything, find closest path node + if (closestPoint == NUM_RESTART_POINTS) { + printf("Couldn't find a police restart zone near the player\n"); + *outPos = ThePaths.m_pathNodes[ThePaths.FindNodeClosestToCoors(pos, PATH_PED, 999999.9f)].pos; + *outHeading = 0.0f; + } else { + *outPos = PoliceRestartPoints[closestPoint]; + *outHeading = PoliceRestartHeadings[closestPoint]; + } } -void -CRestart::CancelOverrideRestart() -{ - bOverrideRestart = false; +void +CRestart::LoadAllRestartPoints(uint8 *buf, uint32 size) +{ + Initialise(); + +INITSAVEBUF + CheckSaveHeader(buf, 'R','S','T','\0', size - SAVE_HEADER_SIZE); + + for (int i = 0; i < NUM_RESTART_POINTS; i++) { + HospitalRestartPoints[i] = ReadSaveBuf(buf); + HospitalRestartHeadings[i] = ReadSaveBuf(buf); + } + + for (int i = 0; i < NUM_RESTART_POINTS; i++) { + PoliceRestartPoints[i] = ReadSaveBuf(buf); + PoliceRestartHeadings[i] = ReadSaveBuf(buf); + } + + NumberOfHospitalRestarts = ReadSaveBuf(buf); + NumberOfPoliceRestarts = ReadSaveBuf(buf); + bOverrideRestart = ReadSaveBuf(buf); + + // skip something unused + ReadSaveBuf(buf); + ReadSaveBuf(buf); + + OverridePosition = ReadSaveBuf(buf); + OverrideHeading = ReadSaveBuf(buf); + bFadeInAfterNextDeath = ReadSaveBuf(buf); + bFadeInAfterNextArrest = ReadSaveBuf(buf); + OverrideHospitalLevel = ReadSaveBuf(buf); + OverridePoliceStationLevel = ReadSaveBuf(buf); +VALIDATESAVEBUF(size); } -void -CRestart::FindClosestHospitalRestartPoint(const CVector &pos, CVector *outPos, float *outHeading) -{ - if (bOverrideRestart) { - *outPos = OverridePosition; - *outHeading = OverrideHeading; - CancelOverrideRestart(); - return; - } - - eLevelName curlevel = CTheZones::FindZoneForPoint(pos); - float fMinDist = 16000000.0f; - int closestPoint = NUM_RESTART_POINTS; - - // find closest point on this level - for (int i = 0; i < NumberOfHospitalRestarts; i++) { - if (CTheZones::FindZoneForPoint(HospitalRestartPoints[i]) == (OverrideHospitalLevel != LEVEL_NONE ? OverrideHospitalLevel : curlevel)) { - float dist = (pos - HospitalRestartPoints[i]).MagnitudeSqr(); - if (fMinDist >= dist) { - fMinDist = dist; - closestPoint = i; - } - } - } - - // if we didn't find anything, find closest point on any level - if (closestPoint == NUM_RESTART_POINTS) { - for (int i = 0; i < NumberOfHospitalRestarts; i++) { - float dist = (pos - HospitalRestartPoints[i]).MagnitudeSqr(); - if (fMinDist >= dist) { - fMinDist = dist; - closestPoint = i; - } - } - } - - // if we still didn't find anything, find closest path node - if (closestPoint == NUM_RESTART_POINTS) { - *outPos = ThePaths.m_pathNodes[ThePaths.FindNodeClosestToCoors(pos, PATH_PED, 999999.9f)].pos; - *outHeading = 0.0f; - printf("Couldn't find a hospital restart zone near the player %f %f %f->%f %f %f\n", pos.x, pos.y, pos.z, outPos->x, outPos->y, outPos->z); - } else { - *outPos = HospitalRestartPoints[closestPoint]; - *outHeading = HospitalRestartHeadings[closestPoint]; - } +void +CRestart::SaveAllRestartPoints(uint8 *buf, uint32 *size) +{ + *size = SAVE_HEADER_SIZE + + sizeof(HospitalRestartPoints) + + sizeof(HospitalRestartHeadings) + + sizeof(PoliceRestartPoints) + + sizeof(PoliceRestartHeadings) + + sizeof(NumberOfHospitalRestarts) + + sizeof(NumberOfPoliceRestarts) + + sizeof(bOverrideRestart) + + sizeof(uint8) + + sizeof(uint16) + + sizeof(OverridePosition) + + sizeof(OverrideHeading) + + sizeof(bFadeInAfterNextDeath) + + sizeof(bFadeInAfterNextArrest) + + sizeof(OverrideHospitalLevel) + + sizeof(OverridePoliceStationLevel); // == 292 + +INITSAVEBUF + WriteSaveHeader(buf, 'R','S','T','\0', *size - SAVE_HEADER_SIZE); + + for (int i = 0; i < NUM_RESTART_POINTS; i++) { + WriteSaveBuf(buf, HospitalRestartPoints[i]); + WriteSaveBuf(buf, HospitalRestartHeadings[i]); + } + + for (int i = 0; i < NUM_RESTART_POINTS; i++) { + WriteSaveBuf(buf, PoliceRestartPoints[i]); + WriteSaveBuf(buf, PoliceRestartHeadings[i]); + } + + WriteSaveBuf(buf, NumberOfHospitalRestarts); + WriteSaveBuf(buf, NumberOfPoliceRestarts); + WriteSaveBuf(buf, bOverrideRestart); + + WriteSaveBuf(buf, (uint8)0); + WriteSaveBuf(buf, (uint16)0); + + WriteSaveBuf(buf, OverridePosition); + WriteSaveBuf(buf, OverrideHeading); + WriteSaveBuf(buf, bFadeInAfterNextDeath); + WriteSaveBuf(buf, bFadeInAfterNextArrest); + WriteSaveBuf(buf, OverrideHospitalLevel); + WriteSaveBuf(buf, OverridePoliceStationLevel); +VALIDATESAVEBUF(*size); } -void -CRestart::FindClosestPoliceRestartPoint(const CVector &pos, CVector *outPos, float *outHeading) -{ - if (bOverrideRestart) { - *outPos = OverridePosition; - *outHeading = OverrideHeading; - CancelOverrideRestart(); - return; - } - - eLevelName curlevel = CTheZones::FindZoneForPoint(pos); - float fMinDist = 16000000.0f; - int closestPoint = NUM_RESTART_POINTS; - - // find closest point on this level - for (int i = 0; i < NumberOfPoliceRestarts; i++) { - if (CTheZones::FindZoneForPoint(PoliceRestartPoints[i]) == (OverridePoliceStationLevel != LEVEL_NONE ? OverridePoliceStationLevel : curlevel)) { - float dist = (pos - PoliceRestartPoints[i]).MagnitudeSqr(); - if (fMinDist >= dist) { - fMinDist = dist; - closestPoint = i; - } - } - } - - // if we didn't find anything, find closest point on any level - if (closestPoint == NUM_RESTART_POINTS) { - for (int i = 0; i < NumberOfPoliceRestarts; i++) { - float dist = (pos - PoliceRestartPoints[i]).MagnitudeSqr(); - if (fMinDist >= dist) { - fMinDist = dist; - closestPoint = i; - } - } - } - - // if we still didn't find anything, find closest path node - if (closestPoint == NUM_RESTART_POINTS) { - printf("Couldn't find a police restart zone near the player\n"); - *outPos = ThePaths.m_pathNodes[ThePaths.FindNodeClosestToCoors(pos, PATH_PED, 999999.9f)].pos; - *outHeading = 0.0f; - } else { - *outPos = PoliceRestartPoints[closestPoint]; - *outHeading = PoliceRestartHeadings[closestPoint]; - } -} - -void -CRestart::LoadAllRestartPoints(uint8 *buf, uint32 size) -{ - Initialise(); - -INITSAVEBUF - CheckSaveHeader(buf, 'R','S','T','\0', size - SAVE_HEADER_SIZE); - - for (int i = 0; i < NUM_RESTART_POINTS; i++) { - HospitalRestartPoints[i] = ReadSaveBuf(buf); - HospitalRestartHeadings[i] = ReadSaveBuf(buf); - } - - for (int i = 0; i < NUM_RESTART_POINTS; i++) { - PoliceRestartPoints[i] = ReadSaveBuf(buf); - PoliceRestartHeadings[i] = ReadSaveBuf(buf); - } - - NumberOfHospitalRestarts = ReadSaveBuf(buf); - NumberOfPoliceRestarts = ReadSaveBuf(buf); - bOverrideRestart = ReadSaveBuf(buf); - - // skip something unused - ReadSaveBuf(buf); - ReadSaveBuf(buf); - - OverridePosition = ReadSaveBuf(buf); - OverrideHeading = ReadSaveBuf(buf); - bFadeInAfterNextDeath = ReadSaveBuf(buf); - bFadeInAfterNextArrest = ReadSaveBuf(buf); - OverrideHospitalLevel = ReadSaveBuf(buf); - OverridePoliceStationLevel = ReadSaveBuf(buf); -VALIDATESAVEBUF(size); -} - -void -CRestart::SaveAllRestartPoints(uint8 *buf, uint32 *size) -{ - *size = SAVE_HEADER_SIZE - + sizeof(HospitalRestartPoints) - + sizeof(HospitalRestartHeadings) - + sizeof(PoliceRestartPoints) - + sizeof(PoliceRestartHeadings) - + sizeof(NumberOfHospitalRestarts) - + sizeof(NumberOfPoliceRestarts) - + sizeof(bOverrideRestart) - + sizeof(uint8) - + sizeof(uint16) - + sizeof(OverridePosition) - + sizeof(OverrideHeading) - + sizeof(bFadeInAfterNextDeath) - + sizeof(bFadeInAfterNextArrest) - + sizeof(OverrideHospitalLevel) - + sizeof(OverridePoliceStationLevel); // == 292 - -INITSAVEBUF - WriteSaveHeader(buf, 'R','S','T','\0', *size - SAVE_HEADER_SIZE); - - for (int i = 0; i < NUM_RESTART_POINTS; i++) { - WriteSaveBuf(buf, HospitalRestartPoints[i]); - WriteSaveBuf(buf, HospitalRestartHeadings[i]); - } - - for (int i = 0; i < NUM_RESTART_POINTS; i++) { - WriteSaveBuf(buf, PoliceRestartPoints[i]); - WriteSaveBuf(buf, PoliceRestartHeadings[i]); - } - - WriteSaveBuf(buf, NumberOfHospitalRestarts); - WriteSaveBuf(buf, NumberOfPoliceRestarts); - WriteSaveBuf(buf, bOverrideRestart); - - WriteSaveBuf(buf, (uint8)0); - WriteSaveBuf(buf, (uint16)0); - - WriteSaveBuf(buf, OverridePosition); - WriteSaveBuf(buf, OverrideHeading); - WriteSaveBuf(buf, bFadeInAfterNextDeath); - WriteSaveBuf(buf, bFadeInAfterNextArrest); - WriteSaveBuf(buf, OverrideHospitalLevel); - WriteSaveBuf(buf, OverridePoliceStationLevel); -VALIDATESAVEBUF(*size); -} - - + STARTPATCHES InjectHook(0x435E20, &CRestart::Initialise, PATCH_JUMP); InjectHook(0x436100, &CRestart::AddHospitalRestartPoint, PATCH_JUMP); @@ -258,5 +258,5 @@ STARTPATCHES InjectHook(0x4361A0, &CRestart::FindClosestHospitalRestartPoint, PATCH_JUMP); InjectHook(0x436450, &CRestart::FindClosestPoliceRestartPoint, PATCH_JUMP); InjectHook(0x436B20, &CRestart::LoadAllRestartPoints, PATCH_JUMP); - InjectHook(0x436700, &CRestart::SaveAllRestartPoints, PATCH_JUMP); + InjectHook(0x436700, &CRestart::SaveAllRestartPoints, PATCH_JUMP); ENDPATCHES \ No newline at end of file -- cgit v1.2.3 From 8917567508f1c98ba96579fdc0516cd07902c74d Mon Sep 17 00:00:00 2001 From: Sergeanur Date: Fri, 10 Apr 2020 11:23:35 +0300 Subject: Fixing mixed IsCutsceneProcessing and IsRunning --- src/control/CarCtrl.cpp | 2 +- src/control/CarGen.cpp | 2 +- src/control/Script.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/control') diff --git a/src/control/CarCtrl.cpp b/src/control/CarCtrl.cpp index 3174a253..cdcfbba6 100644 --- a/src/control/CarCtrl.cpp +++ b/src/control/CarCtrl.cpp @@ -90,7 +90,7 @@ uint32 (&aCarsToKeepTime)[MAX_CARS_TO_KEEP] = *(uint32(*)[MAX_CARS_TO_KEEP])*(ui void CCarCtrl::GenerateRandomCars() { - if (CCutsceneMgr::IsCutsceneProcessing()) + if (CCutsceneMgr::IsRunning()) return; if (NumRandomCars < 30){ if (CountDownToCarsAtStart == 0){ diff --git a/src/control/CarGen.cpp b/src/control/CarGen.cpp index 49a96f50..721ac35a 100644 --- a/src/control/CarGen.cpp +++ b/src/control/CarGen.cpp @@ -242,7 +242,7 @@ void CCarGenerator::Load(uint8 *&buffer) void CTheCarGenerators::Process() { - if (FindPlayerTrain() || CCutsceneMgr::IsRunning()) + if (FindPlayerTrain() || CCutsceneMgr::IsCutsceneProcessing()) return; if (++CTheCarGenerators::ProcessCounter == 4) CTheCarGenerators::ProcessCounter = 0; diff --git a/src/control/Script.cpp b/src/control/Script.cpp index ddea0e3c..b7876172 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -8442,7 +8442,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command) CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]]; CPad::GetPad(ScriptParams[0])->DisablePlayerControls |= PLAYERCONTROL_DISABLED_80; pPlayerInfo->MakePlayerSafe(true); - CCutsceneMgr::SetRunning(true); + CCutsceneMgr::StartCutsceneProcessing(); return 0; } case COMMAND_USE_TEXT_COMMANDS: -- cgit v1.2.3 From 314bb83b9aa2f801f11fa5445e86f0e896484138 Mon Sep 17 00:00:00 2001 From: Nikolay Korolev Date: Fri, 10 Apr 2020 12:03:22 +0300 Subject: fixed intro crash --- src/control/Script.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/control') diff --git a/src/control/Script.cpp b/src/control/Script.cpp index b7876172..ff89f0fc 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -11373,15 +11373,15 @@ void CTheScripts::ClearSpaceForMissionEntity(const CVector& pos, CEntity* pEntit continue; CEntity* pFound = aEntities[i]; int cols; - if (CModelInfo::GetModelInfo(pEntity->GetModelIndex())->GetColModel()->numLines <= 0) - cols = CCollision::ProcessColModels(pEntity->GetMatrix(), *CModelInfo::GetModelInfo(pEntity->GetModelIndex())->GetColModel(), - pFound->GetMatrix(), *CModelInfo::GetModelInfo(pFound->GetModelIndex())->GetColModel(), aTempColPoints, nil, nil); + if (pEntity->GetColModel()->numLines <= 0) + cols = CCollision::ProcessColModels(pEntity->GetMatrix(), *pEntity->GetColModel(), + pFound->GetMatrix(), *pFound->GetColModel(), aTempColPoints, nil, nil); else { float lines[4]; lines[0] = lines[1] = lines[2] = lines[3] = 1.0f; - CColPoint tmp; - cols = CCollision::ProcessColModels(pEntity->GetMatrix(), *CModelInfo::GetModelInfo(pEntity->GetModelIndex())->GetColModel(), - pFound->GetMatrix(), *CModelInfo::GetModelInfo(pFound->GetModelIndex())->GetColModel(), aTempColPoints, &tmp, lines); + CColPoint tmp[4]; + cols = CCollision::ProcessColModels(pEntity->GetMatrix(), *pEntity->GetColModel(), + pFound->GetMatrix(), *pFound->GetColModel(), aTempColPoints,tmp, lines); } if (cols <= 0) continue; -- cgit v1.2.3