summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/control/Pickups.cpp1
-rw-r--r--src/control/Restart.cpp262
-rw-r--r--src/control/Restart.h23
-rw-r--r--src/peds/Ped.cpp20
-rw-r--r--src/peds/Ped.h1
-rw-r--r--src/vehicles/Automobile.cpp2
-rw-r--r--src/vehicles/Automobile.h2
-rw-r--r--src/vehicles/Vehicle.h2
8 files changed, 294 insertions, 19 deletions
diff --git a/src/control/Pickups.cpp b/src/control/Pickups.cpp
index 93d73121..3ba01e46 100644
--- a/src/control/Pickups.cpp
+++ b/src/control/Pickups.cpp
@@ -355,6 +355,7 @@ CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId)
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;
}
diff --git a/src/control/Restart.cpp b/src/control/Restart.cpp
index 40b95c23..8e983555 100644
--- a/src/control/Restart.cpp
+++ b/src/control/Restart.cpp
@@ -1,14 +1,262 @@
#include "common.h"
#include "patcher.h"
#include "Restart.h"
+#include "Zones.h"
+#include "PathFind.h"
-bool &CRestart::OverrideHospitalLevel = *(bool*)0x95CD4C;
-bool &CRestart::OverridePoliceStationLevel = *(bool*)0x95CD50;
+uint8 &CRestart::OverrideHospitalLevel = *(uint8*)0x95CD4C;
+uint8 &CRestart::OverridePoliceStationLevel = *(uint8*)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); }
-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
+bool &CRestart::bOverrideRestart = *(bool*)0x95CD5D;
+CVector &CRestart::OverridePosition = *(CVector*)0x8E2C00;
+float &CRestart::OverrideHeading = *(float*)0x8F2A18;
+
+CVector(&CRestart::HospitalRestartPoints)[NUM_RESTART_POINTS] = *(CVector(*)[NUM_RESTART_POINTS])*(uintptr*)0x87F9B0;
+float(&CRestart::HospitalRestartHeadings)[NUM_RESTART_POINTS] = *(float(*)[NUM_RESTART_POINTS])*(uintptr*)0x6F1D40;
+uint16 &CRestart::NumberOfHospitalRestarts = *(uint16*)0x95CC46;
+
+CVector(&CRestart::PoliceRestartPoints)[NUM_RESTART_POINTS] = *(CVector(*)[NUM_RESTART_POINTS])*(uintptr*)0x846228;
+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::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::CancelOverrideRestart()
+{
+ bOverrideRestart = false;
+}
+
+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::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<CVector>(buf);
+ HospitalRestartHeadings[i] = ReadSaveBuf<float>(buf);
+ }
+
+ for (int i = 0; i < NUM_RESTART_POINTS; i++) {
+ PoliceRestartPoints[i] = ReadSaveBuf<CVector>(buf);
+ PoliceRestartHeadings[i] = ReadSaveBuf<float>(buf);
+ }
+
+ NumberOfHospitalRestarts = ReadSaveBuf<uint16>(buf);
+ NumberOfPoliceRestarts = ReadSaveBuf<uint16>(buf);
+ bOverrideRestart = ReadSaveBuf<bool>(buf);
+
+ // skip something unused
+ ReadSaveBuf<uint8>(buf);
+ ReadSaveBuf<uint16>(buf);
+
+ OverridePosition = ReadSaveBuf<CVector>(buf);
+ OverrideHeading = ReadSaveBuf<float>(buf);
+ bFadeInAfterNextDeath = ReadSaveBuf<bool>(buf);
+ bFadeInAfterNextArrest = ReadSaveBuf<bool>(buf);
+ OverrideHospitalLevel = ReadSaveBuf<uint8>(buf);
+ OverridePoliceStationLevel = ReadSaveBuf<uint8>(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);
+ InjectHook(0x436150, &CRestart::AddPoliceRestartPoint, PATCH_JUMP);
+ InjectHook(0x4366C0, &CRestart::OverrideNextRestart, PATCH_JUMP);
+ InjectHook(0x4366F0, &CRestart::CancelOverrideRestart, PATCH_JUMP);
+ InjectHook(0x4361A0, &CRestart::FindClosestHospitalRestartPoint, PATCH_JUMP);
+ InjectHook(0x436450, &CRestart::FindClosestPoliceRestartPoint, PATCH_JUMP);
+ InjectHook(0x436B20, &CRestart::LoadAllRestartPoints, PATCH_JUMP);
+ InjectHook(0x436700, &CRestart::SaveAllRestartPoints, PATCH_JUMP);
+ENDPATCHES \ No newline at end of file
diff --git a/src/control/Restart.h b/src/control/Restart.h
index 9a4d2155..fb7806db 100644
--- a/src/control/Restart.h
+++ b/src/control/Restart.h
@@ -1,5 +1,7 @@
#pragma once
+#define NUM_RESTART_POINTS 8
+
class CRestart
{
public:
@@ -9,9 +11,26 @@ public:
static void FindClosestHospitalRestartPoint(const CVector &, CVector *, float *);
static void FindClosestPoliceRestartPoint(const CVector &, CVector *, float *);
+ static void Initialise();
+ static void CancelOverrideRestart();
+
+ static void LoadAllRestartPoints(uint8 *buf, uint32 size);
+ static void SaveAllRestartPoints(uint8 *buf, uint32 *size);
- static bool &OverrideHospitalLevel;
- static bool &OverridePoliceStationLevel;
+ static uint8 &OverrideHospitalLevel;
+ static uint8 &OverridePoliceStationLevel;
static bool &bFadeInAfterNextArrest;
static bool &bFadeInAfterNextDeath;
+
+ static bool &bOverrideRestart;
+ static CVector &OverridePosition;
+ static float &OverrideHeading;
+
+ static CVector(&HospitalRestartPoints)[NUM_RESTART_POINTS];
+ static float (&HospitalRestartHeadings)[NUM_RESTART_POINTS];
+ static uint16 &NumberOfHospitalRestarts;
+
+ static CVector (&PoliceRestartPoints)[NUM_RESTART_POINTS];
+ static float (&PoliceRestartHeadings)[NUM_RESTART_POINTS];
+ static uint16 &NumberOfPoliceRestarts;
};
diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp
index 87a0829e..1ecb3037 100644
--- a/src/peds/Ped.cpp
+++ b/src/peds/Ped.cpp
@@ -6134,7 +6134,7 @@ CPed::EndFight(uint8 endType)
void
CPed::EnterCar(void)
{
- if (!m_pMyVehicle->IsWrecked() && m_fHealth > 0.0f) {
+ if (IsNotInWreckedVehicle() && m_fHealth > 0.0f) {
CVehicle *veh = (CVehicle*)m_pSeekTarget;
// Not used.
@@ -9022,7 +9022,7 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg)
if (animAssoc)
animAssoc->blendDelta = -1000.0f;
- if (veh->IsWrecked())
+ if (!ped->IsNotInWreckedVehicle())
return;
if (ped->m_nPedState != PED_ENTER_CAR && ped->m_nPedState != PED_CARJACK) {
@@ -10484,7 +10484,7 @@ CPed::PedAnimDoorCloseCB(CAnimBlendAssociation *animAssoc, void *arg)
CAutomobile *veh = (CAutomobile*)(ped->m_pMyVehicle);
- if (veh->IsWrecked() || ped->DyingOrDead())
+ if (!ped->IsNotInWreckedVehicle() || ped->DyingOrDead())
return;
if (ped->m_nPedState == PED_CARJACK || ped->m_nPedState == PED_ENTER_CAR) {
@@ -10577,7 +10577,7 @@ CPed::PedAnimDoorOpenCB(CAnimBlendAssociation* animAssoc, void* arg)
if (animAssoc)
animAssoc->blendDelta = -1000.0f;
- if (veh->IsWrecked())
+ if (!ped->IsNotInWreckedVehicle())
return;
if (ped->m_nPedState != PED_CARJACK && ped->m_nPedState != PED_ENTER_CAR) {
@@ -10816,7 +10816,7 @@ CPed::PedAnimGetInCB(CAnimBlendAssociation *animAssoc, void *arg)
if (animAssoc)
animAssoc->blendDelta = -1000.0f;
- if (veh->IsWrecked() || ped->DyingOrDead())
+ if (!ped->IsNotInWreckedVehicle() || ped->DyingOrDead())
return;
if (ped->m_nPedState != PED_CARJACK && ped->m_nPedState != PED_ENTER_CAR) {
@@ -10957,7 +10957,7 @@ CPed::PedAnimPullPedOutCB(CAnimBlendAssociation* animAssoc, void* arg)
animAssoc->blendDelta = -1000.0f;
if (ped->m_nPedState == PED_CARJACK || ped->m_nPedState == PED_ENTER_CAR) {
- if (veh->IsWrecked())
+ if (!ped->IsNotInWreckedVehicle())
return;
bool isLow = veh->bLowVehicle;
@@ -11322,7 +11322,7 @@ CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg)
if (!veh)
return;
- if (veh->IsWrecked() || ped->DyingOrDead())
+ if (!ped->IsNotInWreckedVehicle() || ped->DyingOrDead())
return;
ped->bInVehicle = true;
@@ -14631,6 +14631,12 @@ CPed::SetRadioStation(void)
}
}
+bool
+CPed::IsNotInWreckedVehicle()
+{
+ return m_pMyVehicle != nil && !m_pMyVehicle->IsWrecked();
+}
+
class CPed_ : public CPed
{
public:
diff --git a/src/peds/Ped.h b/src/peds/Ped.h
index 74d85e56..d5146b7b 100644
--- a/src/peds/Ped.h
+++ b/src/peds/Ped.h
@@ -764,6 +764,7 @@ public:
void SetPedState(PedState state) { m_nPedState = state; }
bool DyingOrDead(void) { return m_nPedState == PED_DIE || m_nPedState == PED_DEAD; }
void ReplaceWeaponWhenExitingVehicle(void);
+ bool IsNotInWreckedVehicle();
// set by 0482:set_threat_reaction_range_multiplier opcode
static uint16 &nThreatReactionRangeMultiplier;
diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp
index 2329a9d9..12c9c940 100644
--- a/src/vehicles/Automobile.cpp
+++ b/src/vehicles/Automobile.cpp
@@ -128,7 +128,7 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
m_fGasPedal = 0.0f;
m_fBrakePedal = 0.0f;
m_pSetOnFireEntity = nil;
- m_fGasPedalAudio = 0;
+ m_fGasPedalAudio = 0.0f;
bNotDamagedUpsideDown = false;
bMoreResistantToDamage = false;
m_fVelocityChangeForAudio = 0.0f;
diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h
index 6203957d..534f28a4 100644
--- a/src/vehicles/Automobile.h
+++ b/src/vehicles/Automobile.h
@@ -117,7 +117,7 @@ public:
uint8 m_nWheelsOnGround;
uint8 m_nDriveWheelsOnGround;
uint8 m_nDriveWheelsOnGroundPrev;
- int32 m_fGasPedalAudio;
+ float m_fGasPedalAudio;
tWheelState m_aWheelState[4];
static bool &m_sAllTaxiLights;
diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h
index db0485a9..ffc2ca45 100644
--- a/src/vehicles/Vehicle.h
+++ b/src/vehicles/Vehicle.h
@@ -266,7 +266,7 @@ public:
bool ShufflePassengersToMakeSpace(void);
bool IsAlarmOn(void) { return m_nAlarmState != 0 && m_nAlarmState != -1; }
- bool IsWrecked(void) { return !this || m_status == STATUS_WRECKED; }
+ bool IsWrecked(void) { return m_status == STATUS_WRECKED; }
CVehicleModelInfo* GetModelInfo() { return (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()); }
static bool &bWheelsOnlyCheat;