summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
authorerorcun <erayorcunus@gmail.com>2020-01-12 00:11:47 +0100
committerGitHub <noreply@github.com>2020-01-12 00:11:47 +0100
commit2d00d7b3e2026283498c6274ae2533211ea48f53 (patch)
treedc5d7e408858a5574d70d927eee670f1c9165cc6 /src/core
parentMerge pull request #292 from erorcun/erorcun (diff)
parentAccidentManager (diff)
downloadre3-2d00d7b3e2026283498c6274ae2533211ea48f53.tar
re3-2d00d7b3e2026283498c6274ae2533211ea48f53.tar.gz
re3-2d00d7b3e2026283498c6274ae2533211ea48f53.tar.bz2
re3-2d00d7b3e2026283498c6274ae2533211ea48f53.tar.lz
re3-2d00d7b3e2026283498c6274ae2533211ea48f53.tar.xz
re3-2d00d7b3e2026283498c6274ae2533211ea48f53.tar.zst
re3-2d00d7b3e2026283498c6274ae2533211ea48f53.zip
Diffstat (limited to 'src/core')
-rw-r--r--src/core/Accident.cpp134
-rw-r--r--src/core/Accident.h32
-rw-r--r--src/core/Game.cpp2
3 files changed, 167 insertions, 1 deletions
diff --git a/src/core/Accident.cpp b/src/core/Accident.cpp
new file mode 100644
index 00000000..d8313ddc
--- /dev/null
+++ b/src/core/Accident.cpp
@@ -0,0 +1,134 @@
+#include "common.h"
+#include "patcher.h"
+#include "Accident.h"
+
+#include "Ped.h"
+#include "Pools.h"
+#include "World.h"
+
+CAccidentManager& gAccidentManager = *(CAccidentManager*)0x87FD10;
+
+CAccident*
+CAccidentManager::GetNextFreeAccident()
+{
+ for (int i = 0; i < NUM_ACCIDENTS; i++) {
+ if (m_aAccidents[i].m_pVictim == nil)
+ return &m_aAccidents[i];
+ }
+
+ return nil;
+}
+
+void
+CAccidentManager::ReportAccident(CPed *ped)
+{
+ if (!ped->IsPlayer() && ped->CharCreatedBy != MISSION_CHAR && !ped->bRenderScorched && !ped->bBodyPartJustCameOff && ped->bAllowMedicsToReviveMe && !ped->bIsInWater) {
+ for (int i = 0; i < NUM_ACCIDENTS; i++) {
+ if (m_aAccidents[i].m_pVictim != nil && m_aAccidents[i].m_pVictim == ped)
+ return;
+ }
+
+ if (ped->m_pCurrentPhysSurface == nil) {
+ CVector point = ped->GetPosition();
+ point.z -= 2.0f;
+
+ CColPoint colPoint;
+ CEntity *pEntity;
+
+ if (!CWorld::ProcessVerticalLine(point, -100.0f, colPoint, pEntity, true, false, false, false, false, false, nil)) {
+ CAccident *accident = GetNextFreeAccident();
+ if (accident != nil) {
+ accident->m_pVictim = ped;
+ ped->RegisterReference((CEntity**)&accident->m_pVictim);
+ accident->m_nMedicsPerformingCPR = 0;
+ accident->m_nMedicsAttending = 0;
+ ped->m_lastAccident = accident;
+ WorkToDoForMedics();
+ }
+ }
+ }
+ }
+}
+
+void
+CAccidentManager::Update()
+{
+ int32 e;
+ if (CEventList::GetEvent(EVENT_INJURED_PED, &e)) {
+ CPed *ped = CPools::GetPed(gaEvent[e].entityRef);
+ if (ped) {
+ ReportAccident(ped);
+ CEventList::ClearEvent(e);
+ }
+ }
+}
+
+CAccident*
+CAccidentManager::FindNearestAccident(CVector vecPos, float *pDistance)
+{
+ for (int i = 0; i < MAX_MEDICS_TO_ATTEND_ACCIDENT; i++){
+ int accidentId = -1;
+ float minDistance = 999999;
+ for (int j = 0; j < NUM_ACCIDENTS; j++){
+ CPed* pVictim = m_aAccidents[j].m_pVictim;
+ if (!pVictim)
+ continue;
+ if (pVictim->CharCreatedBy == MISSION_CHAR)
+ continue;
+ if (pVictim->m_fHealth != 0.0f)
+ continue;
+ if (m_aAccidents[j].m_nMedicsPerformingCPR != i)
+ continue;
+ float distance = (pVictim->GetPosition() - vecPos).Magnitude2D();
+ if (distance / 2 > pVictim->GetPosition().z - vecPos.z && distance < minDistance){
+ minDistance = distance;
+ accidentId = j;
+ }
+ }
+ *pDistance = minDistance;
+ if (accidentId != -1)
+ return &m_aAccidents[accidentId];
+ }
+ return nil;
+}
+
+uint16
+CAccidentManager::CountActiveAccidents()
+{
+ uint16 accidents = 0;
+ for (int i = 0; i < NUM_ACCIDENTS; i++) {
+ if (m_aAccidents[i].m_pVictim)
+ accidents++;
+ }
+ return accidents;
+}
+
+bool
+CAccidentManager::WorkToDoForMedics()
+{
+ for (int i = 0; i < NUM_ACCIDENTS; i++) {
+ if (m_aAccidents[i].m_pVictim != nil && m_aAccidents[i].m_nMedicsAttending < MAX_MEDICS_TO_ATTEND_ACCIDENT)
+ return true;
+ }
+ return false;
+}
+
+bool
+CAccidentManager::UnattendedAccidents()
+{
+ for (int i = 0; i < NUM_ACCIDENTS; i++) {
+ if (m_aAccidents[i].m_pVictim != nil && m_aAccidents[i].m_nMedicsAttending == 0)
+ return true;
+ }
+ return false;
+}
+
+STARTPATCHES
+ InjectHook(0x4565A0, &CAccidentManager::GetNextFreeAccident, PATCH_JUMP);
+ InjectHook(0x4565D0, &CAccidentManager::ReportAccident, PATCH_JUMP);
+ InjectHook(0x456710, &CAccidentManager::Update, PATCH_JUMP);
+ InjectHook(0x456760, &CAccidentManager::FindNearestAccident, PATCH_JUMP);
+ InjectHook(0x456880, &CAccidentManager::CountActiveAccidents, PATCH_JUMP);
+ InjectHook(0x4568A0, &CAccidentManager::WorkToDoForMedics, PATCH_JUMP);
+ InjectHook(0x4568D0, &CAccidentManager::UnattendedAccidents, PATCH_JUMP);
+ENDPATCHES
diff --git a/src/core/Accident.h b/src/core/Accident.h
new file mode 100644
index 00000000..69889645
--- /dev/null
+++ b/src/core/Accident.h
@@ -0,0 +1,32 @@
+#pragma once
+#include "common.h"
+#include "config.h"
+
+class CPed;
+
+class CAccident
+{
+public:
+ CPed *m_pVictim;
+ uint32 m_nMedicsAttending;
+ uint32 m_nMedicsPerformingCPR;
+ CAccident() : m_pVictim(nil), m_nMedicsAttending(0), m_nMedicsPerformingCPR(0) {}
+};
+
+class CAccidentManager
+{
+ CAccident m_aAccidents[NUM_ACCIDENTS];
+ enum {
+ MAX_MEDICS_TO_ATTEND_ACCIDENT = 2
+ };
+public:
+ CAccident *GetNextFreeAccident();
+ void ReportAccident(CPed *ped);
+ void Update();
+ CAccident *FindNearestAccident(CVector vecPos, float *pDistance);
+ uint16 CountActiveAccidents();
+ bool UnattendedAccidents();
+ bool WorkToDoForMedics();
+};
+
+extern CAccidentManager& gAccidentManager; \ No newline at end of file
diff --git a/src/core/Game.cpp b/src/core/Game.cpp
index b2bac8dd..08751cf9 100644
--- a/src/core/Game.cpp
+++ b/src/core/Game.cpp
@@ -2,7 +2,7 @@
#include "patcher.h"
#include "Game.h"
#include "main.h"
-#include "AccidentManager.h"
+#include "Accident.h"
#include "Antennas.h"
#include "Bridge.h"
#include "Camera.h"