summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/control/GameLogic.cpp293
-rw-r--r--src/control/GameLogic.h13
-rw-r--r--src/control/Garages.cpp1
-rw-r--r--src/control/Garages.h1
-rw-r--r--src/control/Restart.cpp9
-rw-r--r--src/control/Restart.h8
-rw-r--r--src/core/Camera.cpp10
-rw-r--r--src/core/Camera.h1
-rw-r--r--src/core/CutsceneMgr.h2
-rw-r--r--src/core/PlayerInfo.cpp42
-rw-r--r--src/core/PlayerInfo.h2
-rw-r--r--src/core/Stats.cpp3
-rw-r--r--src/core/Stats.h4
-rw-r--r--src/core/Wanted.cpp2
-rw-r--r--src/core/Wanted.h1
-rw-r--r--src/core/World.cpp1
-rw-r--r--src/core/World.h1
-rw-r--r--src/peds/PlayerPed.cpp11
-rw-r--r--src/peds/PlayerPed.h1
19 files changed, 400 insertions, 6 deletions
diff --git a/src/control/GameLogic.cpp b/src/control/GameLogic.cpp
new file mode 100644
index 00000000..16727960
--- /dev/null
+++ b/src/control/GameLogic.cpp
@@ -0,0 +1,293 @@
+#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 "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)
+{
+ uint8 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();
+ CStreaming::LoadScene(pos);
+ CTimer::Update();
+}
+
+void
+CGameLogic::Update()
+{
+ CVector vecRestartPos;
+ float fRestartFloat;
+
+ if (CCutsceneMgr::ms_cutsceneProcessing) 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 = false;
+ CRestart::OverridePoliceStationLevel = false;
+ 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 = false;
+ CRestart::OverridePoliceStationLevel = false;
+ 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 = false;
+ CRestart::OverrideHospitalLevel = false;
+ 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_bloodyFootprintCount = 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);
+ENDPATCHES \ No newline at end of file
diff --git a/src/control/GameLogic.h b/src/control/GameLogic.h
new file mode 100644
index 00000000..db626558
--- /dev/null
+++ b/src/control/GameLogic.h
@@ -0,0 +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;
+}; \ No newline at end of file
diff --git a/src/control/Garages.cpp b/src/control/Garages.cpp
index b573921f..5f55ae66 100644
--- a/src/control/Garages.cpp
+++ b/src/control/Garages.cpp
@@ -71,6 +71,7 @@ bool CGarages::HasCarBeenCrushed(int32 handle)
WRAPPER void CGarages::TriggerMessage(const char *text, int16, uint16 time, int16) { EAXJMP(0x426B20); }
WRAPPER bool CGarages::IsPointWithinHideOutGarage(CVector&) { EAXJMP(0x428260); }
WRAPPER bool CGarages::IsPointWithinAnyGarage(CVector&) { EAXJMP(0x428320); }
+WRAPPER void CGarages::PlayerArrestedOrDied() { EAXJMP(0x427F60); }
#if 0
WRAPPER void CGarages::PrintMessages(void) { EAXJMP(0x426310); }
diff --git a/src/control/Garages.h b/src/control/Garages.h
index cc5fb62b..bcd966e8 100644
--- a/src/control/Garages.h
+++ b/src/control/Garages.h
@@ -27,4 +27,5 @@ public:
static bool HasCarBeenCrushed(int32);
static bool IsPointWithinHideOutGarage(CVector&);
static bool IsPointWithinAnyGarage(CVector&);
+ static void PlayerArrestedOrDied();
};
diff --git a/src/control/Restart.cpp b/src/control/Restart.cpp
index c5c46b51..40b95c23 100644
--- a/src/control/Restart.cpp
+++ b/src/control/Restart.cpp
@@ -2,6 +2,13 @@
#include "patcher.h"
#include "Restart.h"
+bool &CRestart::OverrideHospitalLevel = *(bool*)0x95CD4C;
+bool &CRestart::OverridePoliceStationLevel = *(bool*)0x95CD50;
+bool &CRestart::bFadeInAfterNextArrest = *(bool*)0x95CD69;
+bool &CRestart::bFadeInAfterNextDeath = *(bool*)0x95CD9D;
+
WRAPPER void CRestart::AddHospitalRestartPoint(const CVector&, float) { EAXJMP(0x436100); }
WRAPPER void CRestart::AddPoliceRestartPoint(const CVector&, float) { EAXJMP(0x436150); }
-WRAPPER void CRestart::OverrideNextRestart(const CVector&, float) { EAXJMP(0x4366C0); } \ No newline at end of file
+WRAPPER void CRestart::OverrideNextRestart(const CVector&, float) { EAXJMP(0x4366C0); }
+WRAPPER void CRestart::FindClosestHospitalRestartPoint(const CVector &, CVector *, float *) { EAXJMP(0x4361A0); }
+WRAPPER void CRestart::FindClosestPoliceRestartPoint(const CVector &, CVector *, float *) { EAXJMP(0x436450); } \ No newline at end of file
diff --git a/src/control/Restart.h b/src/control/Restart.h
index f49ed79c..9a4d2155 100644
--- a/src/control/Restart.h
+++ b/src/control/Restart.h
@@ -6,4 +6,12 @@ public:
static void AddPoliceRestartPoint(const CVector&, float);
static void AddHospitalRestartPoint(const CVector&, float);
static void OverrideNextRestart(const CVector&, float);
+
+ static void FindClosestHospitalRestartPoint(const CVector &, CVector *, float *);
+ static void FindClosestPoliceRestartPoint(const CVector &, CVector *, float *);
+
+ static bool &OverrideHospitalLevel;
+ static bool &OverridePoliceStationLevel;
+ static bool &bFadeInAfterNextArrest;
+ static bool &bFadeInAfterNextDeath;
};
diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp
index 775ab46a..28cced53 100644
--- a/src/core/Camera.cpp
+++ b/src/core/Camera.cpp
@@ -1349,6 +1349,14 @@ CCamera::TakeControlWithSpline(short nSwitch)
//FindPlayerPed(); // unused
};
+void CCamera::SetCameraDirectlyInFrontForFollowPed_CamOnAString()
+{
+ m_bCamDirectlyInFront = true;
+ CPlayerPed *player = FindPlayerPed();
+ if (player)
+ m_PedOrientForBehindOrInFront = CGeneral::GetATanOfXY(player->GetForward().x, player->GetForward().y);
+}
+
STARTPATCHES
InjectHook(0x42C760, (bool (CCamera::*)(const CVector &center, float radius, const CMatrix *mat))&CCamera::IsSphereVisible, PATCH_JUMP);
InjectHook(0x46FD00, &CCamera::SetFadeColour, PATCH_JUMP);
@@ -1357,6 +1365,8 @@ STARTPATCHES
InjectHook(0x46FD80, &CCamera::SetMotionBlurAlpha, PATCH_JUMP);
InjectHook(0x46F940, &CCamera::RenderMotionBlur, PATCH_JUMP);
+ InjectHook(0x46FC90, &CCamera::SetCameraDirectlyInFrontForFollowPed_CamOnAString, PATCH_JUMP);
+
InjectHook(0x456F40, WellBufferMe, PATCH_JUMP);
InjectHook(0x4582F0, &CCam::GetVectorsReadyForRW, PATCH_JUMP);
InjectHook(0x457710, &CCam::DoAverageOnVector, PATCH_JUMP);
diff --git a/src/core/Camera.h b/src/core/Camera.h
index 0fd372c3..7d765a06 100644
--- a/src/core/Camera.h
+++ b/src/core/Camera.h
@@ -489,6 +489,7 @@ int m_iModeObbeCamIsInForCar;
void SetCamCutSceneOffSet(const CVector&);
void TakeControlWithSpline(short);
void RestoreWithJumpCut(void);
+ void SetCameraDirectlyInFrontForFollowPed_CamOnAString(void);
void dtor(void) { this->CCamera::~CCamera(); }
};
diff --git a/src/core/CutsceneMgr.h b/src/core/CutsceneMgr.h
index 9b942030..7215a123 100644
--- a/src/core/CutsceneMgr.h
+++ b/src/core/CutsceneMgr.h
@@ -10,7 +10,6 @@ class CCutsceneHead;
class CCutsceneMgr
{
static bool &ms_running;
- static bool &ms_cutsceneProcessing;
static CCutsceneObject *(&ms_pCutsceneObjects)[NUMCUTSCENEOBJECTS];
static int32 &ms_numCutsceneObjs;
@@ -25,6 +24,7 @@ class CCutsceneMgr
public:
static CDirectory *&ms_pCutsceneDir;
static uint32 &ms_cutsceneLoadStatus;
+ static bool &ms_cutsceneProcessing;
static bool IsRunning(void) { return ms_running; }
static bool IsCutsceneProcessing(void) { return ms_cutsceneProcessing; }
diff --git a/src/core/PlayerInfo.cpp b/src/core/PlayerInfo.cpp
index dc72848d..be2c0687 100644
--- a/src/core/PlayerInfo.cpp
+++ b/src/core/PlayerInfo.cpp
@@ -5,25 +5,32 @@
#include "Frontend.h"
#include "Vehicle.h"
#include "PlayerSkin.h"
+#include "Darkel.h"
+#include "Messages.h"
+#include "Text.h"
+#include "Stats.h"
WRAPPER void CPlayerInfo::MakePlayerSafe(bool) { EAXJMP(0x4A1400); }
WRAPPER void CPlayerInfo::AwardMoneyForExplosion(CVehicle *vehicle) { EAXJMP(0x4A15F0); }
WRAPPER void CPlayerInfo::Process(void) { EAXJMP(0x49FD30); }
-void CPlayerInfo::SetPlayerSkin(char *skin)
+void
+CPlayerInfo::SetPlayerSkin(char *skin)
{
strncpy(m_aSkinName, skin, 32);
LoadPlayerSkin();
}
-CVector& CPlayerInfo::GetPos()
+CVector&
+CPlayerInfo::GetPos()
{
if (m_pPed->bInVehicle && m_pPed->m_pMyVehicle)
return m_pPed->m_pMyVehicle->GetPosition();
return m_pPed->GetPosition();
}
-void CPlayerInfo::LoadPlayerSkin()
+void
+CPlayerInfo::LoadPlayerSkin()
{
DeletePlayerSkin();
@@ -32,7 +39,8 @@ void CPlayerInfo::LoadPlayerSkin()
m_pSkinTexture = CPlayerSkin::GetSkinTexture(DEFAULT_SKIN_NAME);
}
-void CPlayerInfo::DeletePlayerSkin()
+void
+CPlayerInfo::DeletePlayerSkin()
{
if (m_pSkinTexture) {
RwTextureDestroy(m_pSkinTexture);
@@ -40,7 +48,33 @@ void CPlayerInfo::DeletePlayerSkin()
}
}
+void
+CPlayerInfo::KillPlayer()
+{
+ if (m_WBState != WBSTATE_PLAYING) return;
+
+ m_WBState = WBSTATE_WASTED;
+ m_nWBTime = CTimer::GetTimeInMilliseconds();
+ CDarkel::ResetOnPlayerDeath();
+ CMessages::AddBigMessage(TheText.Get("DEAD"), 4000, 2);
+ CStats::TimesDied++;
+}
+
+void
+CPlayerInfo::ArrestPlayer()
+{
+ if (m_WBState != WBSTATE_PLAYING) return;
+
+ m_WBState = WBSTATE_BUSTED;
+ m_nWBTime = CTimer::GetTimeInMilliseconds();
+ CDarkel::ResetOnPlayerDeath();
+ CMessages::AddBigMessage(TheText.Get("BUSTED"), 5000, 2);
+ CStats::TimesArrested++;
+}
+
STARTPATCHES
InjectHook(0x4A1700, &CPlayerInfo::LoadPlayerSkin, PATCH_JUMP);
InjectHook(0x4A1750, &CPlayerInfo::DeletePlayerSkin, PATCH_JUMP);
+InjectHook(0x4A12E0, &CPlayerInfo::KillPlayer, PATCH_JUMP);
+InjectHook(0x4A1330, &CPlayerInfo::ArrestPlayer, PATCH_JUMP);
ENDPATCHES
diff --git a/src/core/PlayerInfo.h b/src/core/PlayerInfo.h
index f0b879ee..5784e1fb 100644
--- a/src/core/PlayerInfo.h
+++ b/src/core/PlayerInfo.h
@@ -73,6 +73,8 @@ public:
void SetPlayerSkin(char* skin);
CVector& GetPos();
void Process(void);
+ void KillPlayer(void);
+ void ArrestPlayer(void);
};
static_assert(sizeof(CPlayerInfo) == 0x13C, "CPlayerInfo: error");
diff --git a/src/core/Stats.cpp b/src/core/Stats.cpp
index d4d91dac..9641e8f0 100644
--- a/src/core/Stats.cpp
+++ b/src/core/Stats.cpp
@@ -9,6 +9,9 @@ int32 &CStats::NumberKillFrenziesPassed = *(int32*)0x8E287C;
int32 &CStats::PeopleKilledByOthers = *(int32*)0x8E2C50;
int32 &CStats::HelisDestroyed = *(int32*)0x8E2A64;
int32 *CStats::PedsKilledOfThisType = (int32*)0x880DBC;
+int32 &CStats::TimesDied = *(int32*)0x8E2BDC;
+int32 &CStats::TimesArrested = *(int32*)0x8E2BEC;
+int32 &CStats::KillsSinceLastCheckpoint = *(int32*)0x8F2C8C;
void CStats::AnotherKillFrenzyPassed()
{
diff --git a/src/core/Stats.h b/src/core/Stats.h
index 53c40ca3..7bae8c51 100644
--- a/src/core/Stats.h
+++ b/src/core/Stats.h
@@ -11,7 +11,11 @@ public:
static int32 &PeopleKilledByOthers;
static int32 &HelisDestroyed;
static int32 *PedsKilledOfThisType; //[NUM_PEDTYPES]
+ static int32 &TimesDied;
+ static int32 &TimesArrested;
+ static int32 &KillsSinceLastCheckpoint;
public:
static void AnotherKillFrenzyPassed();
+ static void CheckPointReachedUnsuccessfully() { KillsSinceLastCheckpoint = 0; };
}; \ No newline at end of file
diff --git a/src/core/Wanted.cpp b/src/core/Wanted.cpp
index 26b115e3..bafe0ae1 100644
--- a/src/core/Wanted.cpp
+++ b/src/core/Wanted.cpp
@@ -12,6 +12,8 @@
int32 &CWanted::MaximumWantedLevel = *(int32*)0x5F7714; // 6
int32 &CWanted::nMaximumWantedLevel = *(int32*)0x5F7718; // 6400
+WRAPPER void CWanted::Reset() { EAXJMP(0x4AD790) };
+
void
CWanted::Initialise()
{
diff --git a/src/core/Wanted.h b/src/core/Wanted.h
index 34a4b58d..1303365d 100644
--- a/src/core/Wanted.h
+++ b/src/core/Wanted.h
@@ -76,6 +76,7 @@ public:
bool AddCrimeToQ(eCrimeType type, int32 id, const CVector &pos, bool reported, bool policeDoesntCare);
void ReportCrimeNow(eCrimeType type, const CVector &coors, bool policeDoesntCare);
void UpdateWantedLevel();
+ void Reset();
bool IsIgnored(void) { return m_bIgnoredByCops || m_bIgnoredByEveryone; }
diff --git a/src/core/World.cpp b/src/core/World.cpp
index 1598967a..3a8367f1 100644
--- a/src/core/World.cpp
+++ b/src/core/World.cpp
@@ -41,6 +41,7 @@ bool &CWorld::bIncludeCarTyres = *(bool*)0x95CDAA;
WRAPPER void CWorld::ShutDown(void) { EAXJMP(0x4AE450); }
WRAPPER void CWorld::RemoveReferencesToDeletedObject(CEntity*) { EAXJMP(0x4B3BF0); }
WRAPPER void CWorld::FindObjectsKindaColliding(const CVector &, float, bool, int16*, int16, CEntity **, bool, bool, bool, bool, bool){ EAXJMP(0x4B2A30); }
+WRAPPER void CWorld::ClearExcitingStuffFromArea(const CVector &pos, float radius, uint8) { EAXJMP(0x4B4E70) };
void
CWorld::Initialise()
diff --git a/src/core/World.h b/src/core/World.h
index 523585e7..f420207c 100644
--- a/src/core/World.h
+++ b/src/core/World.h
@@ -85,6 +85,7 @@ public:
}
}
static void ClearScanCodes(void);
+ static void ClearExcitingStuffFromArea(const CVector &pos, float radius, uint8);
static bool CameraToIgnoreThisObject(CEntity *ent);
diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp
index 668a6011..55906c38 100644
--- a/src/peds/PlayerPed.cpp
+++ b/src/peds/PlayerPed.cpp
@@ -4,6 +4,7 @@
#include "Camera.h"
#include "WeaponEffects.h"
#include "ModelIndices.h"
+#include "World.h"
CPlayerPed::~CPlayerPed()
{
@@ -103,6 +104,15 @@ CPlayerPed::ClearAdrenaline(void)
}
}
+CPlayerInfo *
+CPlayerPed::GetPlayerInfoForThisPlayerPed()
+{
+ if (CWorld::Players[0].m_pPed == this)
+ return &CWorld::Players[0];
+
+ return nil;
+}
+
class CPlayerPed_ : public CPlayerPed
{
public:
@@ -115,4 +125,5 @@ STARTPATCHES
InjectHook(0x4EFB30, &CPlayerPed_::dtor, PATCH_JUMP);
InjectHook(0x4F28A0, &CPlayerPed::ClearWeaponTarget, PATCH_JUMP);
InjectHook(0x4F3700, &CPlayerPed::AnnoyPlayerPed, PATCH_JUMP);
+ InjectHook(0x4F36C0, &CPlayerPed::GetPlayerInfoForThisPlayerPed, PATCH_JUMP);
ENDPATCHES
diff --git a/src/peds/PlayerPed.h b/src/peds/PlayerPed.h
index 136fcc48..bd24ecd0 100644
--- a/src/peds/PlayerPed.h
+++ b/src/peds/PlayerPed.h
@@ -53,6 +53,7 @@ public:
void SetMoveAnim(void);
void ProcessControl(void);
void ClearAdrenaline(void);
+ class CPlayerInfo *GetPlayerInfoForThisPlayerPed();
static void SetupPlayerPed(int32);
static void DeactivatePlayerPed(int32);