This repository has been archived by the owner. It is now read-only.
Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Merge pull request #291 from Sergeanur/AccidentManager
AccidentManager
- Loading branch information
Showing
with
143 additions
and 66 deletions.
- +0 −1 README.md
- +0 −59 src/control/AccidentManager.cpp
- +1 −1 src/control/CarAI.cpp
- +1 −1 src/control/CarCtrl.cpp
- +134 −0 src/core/Accident.cpp
- +5 −2 src/{control/AccidentManager.h → core/Accident.h}
- +1 −1 src/core/Game.cpp
- +1 −1 src/peds/EmergencyPed.cpp
There are no files selected for viewing
| @@ -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 | |||