mirror of
https://git.rip/DMCA_FUCKER/re3.git
synced 2024-12-24 00:20:01 +00:00
CCivilianPed done & restore peds running to phone
This commit is contained in:
parent
a7d0404c89
commit
680fe0f7e6
|
@ -72,7 +72,7 @@ CPhoneInfo::Load(uint8 *buf, uint32 size)
|
||||||
INITSAVEBUF
|
INITSAVEBUF
|
||||||
m_nMax = ReadSaveBuf<int32>(buf);
|
m_nMax = ReadSaveBuf<int32>(buf);
|
||||||
m_nNum = ReadSaveBuf<int32>(buf);
|
m_nNum = ReadSaveBuf<int32>(buf);
|
||||||
for (int i = 0; i < 50; i++) {
|
for (int i = 0; i < NUMPHONES; i++) {
|
||||||
m_aPhones[i] = ReadSaveBuf<CPhone>(buf);
|
m_aPhones[i] = ReadSaveBuf<CPhone>(buf);
|
||||||
// It's saved as building pool index in save file, convert it to true entity
|
// It's saved as building pool index in save file, convert it to true entity
|
||||||
if (m_aPhones[i].m_pEntity) {
|
if (m_aPhones[i].m_pEntity) {
|
||||||
|
@ -174,7 +174,7 @@ CPhoneInfo::Save(uint8 *buf, uint32 *size)
|
||||||
INITSAVEBUF
|
INITSAVEBUF
|
||||||
WriteSaveBuf(buf, m_nMax);
|
WriteSaveBuf(buf, m_nMax);
|
||||||
WriteSaveBuf(buf, m_nNum);
|
WriteSaveBuf(buf, m_nNum);
|
||||||
for(int phoneId = 0; phoneId < 50; phoneId++) {
|
for(int phoneId = 0; phoneId < NUMPHONES; phoneId++) {
|
||||||
CPhone* phone = WriteSaveBuf(buf, m_aPhones[phoneId]);
|
CPhone* phone = WriteSaveBuf(buf, m_aPhones[phoneId]);
|
||||||
|
|
||||||
// Convert entity pointer to building pool index while saving
|
// Convert entity pointer to building pool index while saving
|
||||||
|
|
|
@ -7,7 +7,7 @@ class CAnimBlendAssociation;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PHONE_STATE_FREE,
|
PHONE_STATE_FREE,
|
||||||
PHONE_STATE_1,
|
PHONE_STATE_REPORTING_CRIME, // CCivilianPed::ProcessControl sets it but unused
|
||||||
PHONE_STATE_2,
|
PHONE_STATE_2,
|
||||||
PHONE_STATE_MESSAGE_REMOVED,
|
PHONE_STATE_MESSAGE_REMOVED,
|
||||||
PHONE_STATE_ONETIME_MESSAGE_SET,
|
PHONE_STATE_ONETIME_MESSAGE_SET,
|
||||||
|
@ -18,14 +18,18 @@ enum {
|
||||||
PHONE_STATE_9
|
PHONE_STATE_9
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CPhone
|
class CPhone
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
CVector m_vecPos;
|
CVector m_vecPos;
|
||||||
wchar *m_apMessages[6];
|
wchar *m_apMessages[6];
|
||||||
uint32 m_lastTimeRepeatedMsgShown;
|
uint32 m_lastTimeRepeatedMsgShown;
|
||||||
CEntity *m_pEntity; // it's building pool index in save files
|
CEntity *m_pEntity; // stored as building pool index in save files
|
||||||
int32 m_nState;
|
int32 m_nState;
|
||||||
uint8 field_30;
|
uint8 field_30;
|
||||||
|
|
||||||
|
CPhone() { }
|
||||||
|
~CPhone() { }
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(CPhone) == 0x34, "CPhone: error");
|
static_assert(sizeof(CPhone) == 0x34, "CPhone: error");
|
||||||
|
@ -40,7 +44,7 @@ public:
|
||||||
|
|
||||||
int32 m_nMax;
|
int32 m_nMax;
|
||||||
int32 m_nNum;
|
int32 m_nNum;
|
||||||
CPhone m_aPhones[50];
|
CPhone m_aPhones[NUMPHONES];
|
||||||
|
|
||||||
CPhoneInfo() { }
|
CPhoneInfo() { }
|
||||||
~CPhoneInfo() { }
|
~CPhoneInfo() { }
|
||||||
|
|
|
@ -27,13 +27,13 @@ public:
|
||||||
int32 m_nCollectedPackages;
|
int32 m_nCollectedPackages;
|
||||||
int32 m_nTotalPackages;
|
int32 m_nTotalPackages;
|
||||||
uint32 m_nLastBumpPlayerCarTimer;
|
uint32 m_nLastBumpPlayerCarTimer;
|
||||||
int32 m_nSwitchTaxiTime;
|
uint32 m_nSwitchTaxiTime;
|
||||||
bool m_bSwitchTaxi;
|
bool m_bSwitchTaxi;
|
||||||
int8 field_197;
|
int8 field_197;
|
||||||
int8 field_198;
|
int8 field_198;
|
||||||
int8 field_199;
|
int8 field_199;
|
||||||
int32 m_nNextSexFrequencyUpdateTime;
|
uint32 m_nNextSexFrequencyUpdateTime;
|
||||||
int32 m_nNextSexMoneyUpdateTime;
|
uint32 m_nNextSexMoneyUpdateTime;
|
||||||
int32 m_nSexFrequency;
|
int32 m_nSexFrequency;
|
||||||
CCivilianPed *m_pHooker;
|
CCivilianPed *m_pHooker;
|
||||||
int8 m_WBState; // eWastedBustedState
|
int8 m_WBState; // eWastedBustedState
|
||||||
|
@ -55,7 +55,7 @@ public:
|
||||||
int8 field_254;
|
int8 field_254;
|
||||||
int8 field_255;
|
int8 field_255;
|
||||||
float m_fRoadDensity;
|
float m_fRoadDensity;
|
||||||
int32 m_nPreviousTimeRewardedForExplosion;
|
uint32 m_nPreviousTimeRewardedForExplosion;
|
||||||
int32 m_nExplosionsSinceLastReward;
|
int32 m_nExplosionsSinceLastReward;
|
||||||
int32 field_268;
|
int32 field_268;
|
||||||
int32 field_272;
|
int32 field_272;
|
||||||
|
|
|
@ -87,6 +87,7 @@ enum Config {
|
||||||
NUM_FIRES = 40,
|
NUM_FIRES = 40,
|
||||||
|
|
||||||
NUMPEDROUTES = 200,
|
NUMPEDROUTES = 200,
|
||||||
|
NUMPHONES = 50,
|
||||||
|
|
||||||
NUMVISIBLEENTITIES = 2000,
|
NUMVISIBLEENTITIES = 2000,
|
||||||
NUMINVISIBLEENTITIES = 150,
|
NUMINVISIBLEENTITIES = 150,
|
||||||
|
@ -145,6 +146,7 @@ enum Config {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define FIX_BUGS // fixes bugs that we've came across during reversing, TODO: use this more
|
#define FIX_BUGS // fixes bugs that we've came across during reversing, TODO: use this more
|
||||||
|
#define TOGGLEABLE_BETA_FEATURES // toggleable from debug menu. doesn't have too many things
|
||||||
|
|
||||||
// Pad
|
// Pad
|
||||||
#define KANGAROO_CHEAT
|
#define KANGAROO_CHEAT
|
||||||
|
|
|
@ -349,10 +349,11 @@ DebugMenuPopulate(void)
|
||||||
DebugMenuAddVarBool8("Debug", "Don't render Objects", (int8*)&gbDontRenderObjects, nil);
|
DebugMenuAddVarBool8("Debug", "Don't render Objects", (int8*)&gbDontRenderObjects, nil);
|
||||||
|
|
||||||
DebugMenuAddCmd("Debug", "Make peds follow you in formation", LetThemFollowYou);
|
DebugMenuAddCmd("Debug", "Make peds follow you in formation", LetThemFollowYou);
|
||||||
#ifndef MASTER
|
#ifdef TOGGLEABLE_BETA_FEATURES
|
||||||
DebugMenuAddVarBool8("Debug", "Toggle unused fight feature", (int8*)&CPed::bUnusedFightThingOnPlayer, nil);
|
DebugMenuAddVarBool8("Debug", "Toggle unused fight feature", (int8*)&CPed::bUnusedFightThingOnPlayer, nil);
|
||||||
DebugMenuAddVarBool8("Debug", "Toggle banned particles", (int8*)&CParticle::bEnableBannedParticles, nil);
|
DebugMenuAddVarBool8("Debug", "Toggle banned particles", (int8*)&CParticle::bEnableBannedParticles, nil);
|
||||||
DebugMenuAddVarBool8("Debug", "Toggle popping heads on headshot", (int8*)&CPed::bPopHeadsOnHeadshot, nil);
|
DebugMenuAddVarBool8("Debug", "Toggle popping heads on headshot", (int8*)&CPed::bPopHeadsOnHeadshot, nil);
|
||||||
|
DebugMenuAddVarBool8("Debug", "Toggle peds running to phones to report crimes", (int8*)&CPed::bMakePedsRunToPhonesToReportCrimes, nil);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DebugMenuAddCmd("Debug", "Start Credits", CCredits::Start);
|
DebugMenuAddCmd("Debug", "Start Credits", CCredits::Start);
|
||||||
|
|
|
@ -2,25 +2,420 @@
|
||||||
#include "patcher.h"
|
#include "patcher.h"
|
||||||
#include "CivilianPed.h"
|
#include "CivilianPed.h"
|
||||||
#include "Phones.h"
|
#include "Phones.h"
|
||||||
|
#include "General.h"
|
||||||
WRAPPER void CCivilianPed::ProcessControl(void) { EAXJMP(0x4BFFE0); }
|
#include "PlayerPed.h"
|
||||||
|
#include "World.h"
|
||||||
|
#include "Vehicle.h"
|
||||||
|
#include "SurfaceTable.h"
|
||||||
|
|
||||||
CCivilianPed::CCivilianPed(int pedtype, int mi) : CPed(pedtype)
|
CCivilianPed::CCivilianPed(int pedtype, int mi) : CPed(pedtype)
|
||||||
{
|
{
|
||||||
SetModelIndex(mi);
|
SetModelIndex(mi);
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < ARRAY_SIZE(m_nearPeds); i++) {
|
||||||
m_nearPeds[i] = nil;
|
m_nearPeds[i] = nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CCivilianPed::CivilianAI(void)
|
||||||
|
{
|
||||||
|
#ifdef TOGGLEABLE_BETA_FEATURES
|
||||||
|
if (bRunningToPhone && m_nPedState != PED_SEEK_POS && m_nPedState != PED_FALL && m_nPedState != PED_GETUP &&
|
||||||
|
m_nPedState != PED_DIVE_AWAY && m_nPedState != PED_MAKE_CALL && m_nPedState != PED_FACE_PHONE) {
|
||||||
|
bRunningToPhone = false;
|
||||||
|
if (gPhoneInfo.m_aPhones[m_phoneId].m_nState == PHONE_STATE_REPORTING_CRIME)
|
||||||
|
gPhoneInfo.m_aPhones[m_phoneId].m_nState = PHONE_STATE_FREE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (CTimer::GetTimeInMilliseconds() <= m_fleeTimer || m_objective != OBJECTIVE_NONE && !bRespondsToThreats
|
||||||
|
|| !IsPedInControl()) {
|
||||||
|
|
||||||
|
if (m_objective == OBJECTIVE_GUARD_SPOT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT || m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS) {
|
||||||
|
if (m_pedInObjective) {
|
||||||
|
if (m_pedInObjective->IsPlayer())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (CTimer::GetTimeInMilliseconds() <= m_lookTimer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
uint32 closestThreatFlag = ScanForThreats();
|
||||||
|
if (closestThreatFlag == PED_FLAG_EXPLOSION) {
|
||||||
|
float angleToFace = CGeneral::GetRadianAngleBetweenPoints(
|
||||||
|
m_eventOrThreat.x, m_eventOrThreat.y,
|
||||||
|
GetPosition().x, GetPosition().y);
|
||||||
|
SetLookFlag(angleToFace, true);
|
||||||
|
SetLookTimer(500);
|
||||||
|
|
||||||
|
} else if (closestThreatFlag == PED_FLAG_GUN) {
|
||||||
|
SetLookFlag(m_threatEntity, true);
|
||||||
|
SetLookTimer(500);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint32 closestThreatFlag = ScanForThreats();
|
||||||
|
if (closestThreatFlag == PED_FLAG_GUN) {
|
||||||
|
if (!m_threatEntity || !m_threatEntity->IsPed())
|
||||||
|
return;
|
||||||
|
|
||||||
|
CPed *threatPed = (CPed*)m_threatEntity;
|
||||||
|
float threatDistSqr = (m_threatEntity->GetPosition() - GetPosition()).MagnitudeSqr2D();
|
||||||
|
if (m_pedStats->m_fear <= m_pedStats->m_lawfulness) {
|
||||||
|
if (m_pedStats->m_temper <= m_pedStats->m_fear) {
|
||||||
|
if (!threatPed->IsPlayer() || !RunToReportCrime(CRIME_POSSESSION_GUN)) {
|
||||||
|
if (threatDistSqr < sq(10.0f)) {
|
||||||
|
Say(SOUND_PED_FLEE_SPRINT);
|
||||||
|
SetFlee(m_threatEntity, 10000);
|
||||||
|
bUsePedNodeSeek = true;
|
||||||
|
m_pNextPathNode = nil;
|
||||||
|
} else {
|
||||||
|
SetFlee(m_threatEntity->GetPosition(), 5000);
|
||||||
|
bUsePedNodeSeek = true;
|
||||||
|
m_pNextPathNode = nil;
|
||||||
|
SetMoveState(PEDMOVE_WALK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (m_objective != OBJECTIVE_NONE || GetWeapon()->IsTypeMelee()) {
|
||||||
|
SetFlee(m_threatEntity, 5000);
|
||||||
|
bUsePedNodeSeek = true;
|
||||||
|
m_pNextPathNode = nil;
|
||||||
|
if (threatDistSqr < sq(20.0f)) {
|
||||||
|
SetMoveState(PEDMOVE_RUN);
|
||||||
|
Say(SOUND_PED_FLEE_SPRINT);
|
||||||
|
} else {
|
||||||
|
SetMoveState(PEDMOVE_WALK);
|
||||||
|
}
|
||||||
|
} else if (threatPed->IsPlayer() && FindPlayerPed()->m_pWanted->m_CurrentCops) {
|
||||||
|
SetFlee(m_threatEntity, 5000);
|
||||||
|
bUsePedNodeSeek = true;
|
||||||
|
m_pNextPathNode = nil;
|
||||||
|
if (threatDistSqr < sq(10.0f)) {
|
||||||
|
SetMoveState(PEDMOVE_RUN);
|
||||||
|
} else {
|
||||||
|
SetMoveState(PEDMOVE_WALK);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, m_threatEntity);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (threatDistSqr < sq(10.0f)) {
|
||||||
|
Say(SOUND_PED_FLEE_SPRINT);
|
||||||
|
SetFlee(m_threatEntity, 10000);
|
||||||
|
bUsePedNodeSeek = true;
|
||||||
|
m_pNextPathNode = nil;
|
||||||
|
SetMoveState(PEDMOVE_SPRINT);
|
||||||
|
} else {
|
||||||
|
Say(SOUND_PED_FLEE_SPRINT);
|
||||||
|
SetFlee(m_threatEntity, 5000);
|
||||||
|
bUsePedNodeSeek = true;
|
||||||
|
m_pNextPathNode = nil;
|
||||||
|
SetMoveState(PEDMOVE_RUN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SetLookFlag(m_threatEntity, false);
|
||||||
|
SetLookTimer(500);
|
||||||
|
} else if (closestThreatFlag == PED_FLAG_DEADPEDS) {
|
||||||
|
float eventDistSqr = (m_pEventEntity->GetPosition() - GetPosition()).MagnitudeSqr2D();
|
||||||
|
if (IsGangMember() && m_nPedType == ((CPed*)m_pEventEntity)->m_nPedType) {
|
||||||
|
if (eventDistSqr < sq(5.0f)) {
|
||||||
|
SetFlee(m_pEventEntity, 2000);
|
||||||
|
bUsePedNodeSeek = true;
|
||||||
|
m_pNextPathNode = nil;
|
||||||
|
SetMoveState(PEDMOVE_RUN);
|
||||||
|
}
|
||||||
|
} else if (IsGangMember() || eventDistSqr > sq(5.0f)) {
|
||||||
|
bool investigateDeadPed = true;
|
||||||
|
CEntity *killerOfDeadPed = ((CPed*)m_pEventEntity)->m_threatEntity;
|
||||||
|
if (killerOfDeadPed && killerOfDeadPed->IsPed()) {
|
||||||
|
CVector killerPos = killerOfDeadPed->GetPosition();
|
||||||
|
CVector deadPedPos = m_pEventEntity->GetPosition();
|
||||||
|
if (CVector2D(killerPos - deadPedPos).MagnitudeSqr() < sq(10.0f))
|
||||||
|
investigateDeadPed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TOGGLEABLE_BETA_FEATURES
|
||||||
|
eCrimeType crime = (((CPed*)m_pEventEntity)->m_ped_flagI40 ?
|
||||||
|
(((CPed*)m_pEventEntity)->m_nPedType == PEDTYPE_COP ? CRIME_RUNOVER_COP : CRIME_RUNOVER_PED) :
|
||||||
|
(((CPed*)m_pEventEntity)->m_nPedType == PEDTYPE_COP ? CRIME_SHOOT_COP : CRIME_SHOOT_PED));
|
||||||
|
bool eligibleToReport = bMakePedsRunToPhonesToReportCrimes && killerOfDeadPed && killerOfDeadPed->IsPed() && ((CPed*)killerOfDeadPed)->IsPlayer() &&
|
||||||
|
m_pedStats->m_fear <= m_pedStats->m_lawfulness && m_pedStats->m_temper <= m_pedStats->m_fear;
|
||||||
|
if (IsGangMember() || !eligibleToReport || !RunToReportCrime(crime))
|
||||||
|
#endif
|
||||||
|
if (investigateDeadPed)
|
||||||
|
SetInvestigateEvent(EVENT_DEAD_PED, CVector2D(m_pEventEntity->GetPosition()), 1.0f, 20000, 0.0f);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
#ifdef TOGGLEABLE_BETA_FEATURES
|
||||||
|
CEntity* killerOfDeadPed = ((CPed*)m_pEventEntity)->m_threatEntity;
|
||||||
|
eCrimeType crime = (((CPed*)m_pEventEntity)->m_ped_flagI40 ?
|
||||||
|
(((CPed*)m_pEventEntity)->m_nPedType == PEDTYPE_COP ? CRIME_RUNOVER_COP : CRIME_RUNOVER_PED) :
|
||||||
|
(((CPed*)m_pEventEntity)->m_nPedType == PEDTYPE_COP ? CRIME_SHOOT_COP : CRIME_SHOOT_PED));
|
||||||
|
bool eligibleToReport = bMakePedsRunToPhonesToReportCrimes && killerOfDeadPed && killerOfDeadPed->IsPed() && ((CPed*)killerOfDeadPed)->IsPlayer() &&
|
||||||
|
m_pedStats->m_fear <= m_pedStats->m_lawfulness && m_pedStats->m_temper <= m_pedStats->m_fear;
|
||||||
|
if(!eligibleToReport || !RunToReportCrime(crime))
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
SetFlee(m_pEventEntity, 5000);
|
||||||
|
bUsePedNodeSeek = true;
|
||||||
|
m_pNextPathNode = nil;
|
||||||
|
SetMoveState(PEDMOVE_RUN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (closestThreatFlag == PED_FLAG_EXPLOSION) {
|
||||||
|
CVector2D eventDistVec = m_eventOrThreat - GetPosition();
|
||||||
|
float eventDistSqr = eventDistVec.MagnitudeSqr();
|
||||||
|
if (eventDistSqr < sq(20.0f)) {
|
||||||
|
Say(SOUND_PED_FLEE_SPRINT);
|
||||||
|
SetFlee(m_eventOrThreat, 2000);
|
||||||
|
float angleToFace = CGeneral::GetRadianAngleBetweenPoints(
|
||||||
|
m_eventOrThreat.x, m_eventOrThreat.y,
|
||||||
|
GetPosition().x, GetPosition().y);
|
||||||
|
SetLookFlag(angleToFace, true);
|
||||||
|
SetLookTimer(500);
|
||||||
|
} else if (eventDistSqr < sq(40.0f)) {
|
||||||
|
if (m_ped_flagD2) {
|
||||||
|
if (CharCreatedBy != MISSION_CHAR && !IsGangMember())
|
||||||
|
SetInvestigateEvent(EVENT_EXPLOSION, m_eventOrThreat, 6.0f, 30000, 0.0f);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
float eventHeading = CGeneral::GetRadianAngleBetweenPoints(eventDistVec.x, eventDistVec.y, 0.0f, 0.0f);
|
||||||
|
eventHeading = CGeneral::LimitRadianAngle(eventHeading);
|
||||||
|
if (eventHeading < 0.0f)
|
||||||
|
eventHeading = eventHeading + TWOPI;
|
||||||
|
|
||||||
|
SetWanderPath(eventHeading / 8.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (m_threatEntity && m_threatEntity->IsPed()) {
|
||||||
|
CPed *threatPed = (CPed*)m_threatEntity;
|
||||||
|
if (m_pedStats->m_fear <= 100 - threatPed->m_pedStats->m_temper && threatPed->m_nPedType != PEDTYPE_COP) {
|
||||||
|
if (threatPed->GetWeapon()->IsTypeMelee() || !GetWeapon()->IsTypeMelee()) {
|
||||||
|
if (threatPed->IsPlayer() && FindPlayerPed()->m_pWanted->m_CurrentCops) {
|
||||||
|
if (m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT || m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS) {
|
||||||
|
SetFlee(m_threatEntity, 10000);
|
||||||
|
bUsePedNodeSeek = true;
|
||||||
|
m_pNextPathNode = nil;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, m_threatEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SetFlee(m_threatEntity, 10000);
|
||||||
|
bUsePedNodeSeek = true;
|
||||||
|
m_pNextPathNode = nil;
|
||||||
|
SetMoveState(PEDMOVE_WALK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CCivilianPed::ProcessControl(void)
|
||||||
|
{
|
||||||
|
if (m_nZoneLevel > LEVEL_NONE && m_nZoneLevel != CCollision::ms_collisionInMemory)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CPed::ProcessControl();
|
||||||
|
|
||||||
|
if (bWasPostponed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (DyingOrDead())
|
||||||
|
return;
|
||||||
|
|
||||||
|
GetWeapon()->Update(m_audioEntityId);
|
||||||
|
switch (m_nPedState) {
|
||||||
|
case PED_WANDER_RANGE:
|
||||||
|
case PED_WANDER_PATH:
|
||||||
|
if (IsVisible())
|
||||||
|
ScanForInterestingStuff();
|
||||||
|
break;
|
||||||
|
case PED_SEEK_ENTITY:
|
||||||
|
if (!m_pSeekTarget) {
|
||||||
|
RestorePreviousState();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m_vecSeekPos = m_pSeekTarget->GetPosition();
|
||||||
|
|
||||||
|
// fall through
|
||||||
|
case PED_SEEK_POS:
|
||||||
|
if (Seek()) {
|
||||||
|
if ((m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT || m_objective == OBJECTIVE_RUN_TO_AREA) && m_pNextPathNode) {
|
||||||
|
m_pNextPathNode = nil;
|
||||||
|
} else if (bRunningToPhone) {
|
||||||
|
if (gPhoneInfo.m_aPhones[m_phoneId].m_nState != PHONE_STATE_FREE) {
|
||||||
|
RestorePreviousState();
|
||||||
|
m_phoneId = -1;
|
||||||
|
#ifdef FIX_BUGS
|
||||||
|
bRunningToPhone = false;
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
gPhoneInfo.m_aPhones[m_phoneId].m_nState = PHONE_STATE_REPORTING_CRIME;
|
||||||
|
m_nPedState = PED_FACE_PHONE;
|
||||||
|
}
|
||||||
|
} else if (m_objective != OBJECTIVE_KILL_CHAR_ANY_MEANS && m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT) {
|
||||||
|
if (m_objective == OBJECTIVE_FOLLOW_PED_IN_FORMATION) {
|
||||||
|
if (m_moved.Magnitude() == 0.0f) {
|
||||||
|
if (m_pedInObjective->m_nMoveState == PEDMOVE_STILL)
|
||||||
|
m_fRotationDest = m_pedInObjective->m_fRotationCur;
|
||||||
|
}
|
||||||
|
} else if (m_objective == OBJECTIVE_GOTO_CHAR_ON_FOOT
|
||||||
|
&& m_pedInObjective && m_pedInObjective->m_nMoveState != PEDMOVE_STILL) {
|
||||||
|
SetMoveState(m_pedInObjective->m_nMoveState);
|
||||||
|
} else if (m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT || m_objective == OBJECTIVE_RUN_TO_AREA) {
|
||||||
|
SetIdle();
|
||||||
|
} else {
|
||||||
|
RestorePreviousState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef TOGGLEABLE_BETA_FEATURES
|
||||||
|
else if (bRunningToPhone) {
|
||||||
|
// Designed for running to phone, but never used
|
||||||
|
CheckAroundForPossibleCollisions();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case PED_FACE_PHONE:
|
||||||
|
if (FacePhone())
|
||||||
|
m_nPedState = PED_MAKE_CALL;
|
||||||
|
break;
|
||||||
|
case PED_MAKE_CALL:
|
||||||
|
if (MakePhonecall())
|
||||||
|
SetWanderPath(CGeneral::GetRandomNumber() & 7);
|
||||||
|
break;
|
||||||
|
case PED_MUG:
|
||||||
|
Mug();
|
||||||
|
break;
|
||||||
|
case PED_SOLICIT:
|
||||||
|
Solicit();
|
||||||
|
break;
|
||||||
|
case PED_UNKNOWN:
|
||||||
|
{
|
||||||
|
int pedsInSameState = 0;
|
||||||
|
Idle();
|
||||||
|
for (int i = 0; i < m_numNearPeds; ++i) {
|
||||||
|
CPed *nearPed = m_nearPeds[i];
|
||||||
|
if (nearPed->m_nPedType == m_nPedType && nearPed->m_nPedState == PED_UNKNOWN) {
|
||||||
|
++pedsInSameState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pedsInSameState < 5) {
|
||||||
|
for (int j = 0; j < m_numNearPeds; ++j) {
|
||||||
|
CPed *nearPed = m_nearPeds[j];
|
||||||
|
if (nearPed->m_nPedType == m_nPedType && nearPed->m_nPedState == PED_WANDER_PATH) {
|
||||||
|
nearPed->m_nPedState = PED_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PED_DRIVING:
|
||||||
|
if (m_nPedType != PEDTYPE_PROSTITUTE)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (CWorld::Players[CWorld::PlayerInFocus].m_pHooker != this)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nNextSexFrequencyUpdateTime) {
|
||||||
|
if (m_nPedState == PED_DRIVING
|
||||||
|
&& m_pMyVehicle->pDriver && m_pMyVehicle->pDriver->IsPlayer() && m_pMyVehicle->pDriver->m_nPedState == PED_DRIVING) {
|
||||||
|
CColPoint foundCol;
|
||||||
|
CEntity* foundEnt;
|
||||||
|
|
||||||
|
CWorld::ProcessVerticalLine(m_pMyVehicle->GetPosition(), -100.0f,
|
||||||
|
foundCol, foundEnt, true, false, false, false, false, false, nil);
|
||||||
|
|
||||||
|
if (m_pMyVehicle->m_vecMoveSpeed.MagnitudeSqr() < sq(0.01f)
|
||||||
|
&& foundCol.surfaceB != SURFACE_DEFAULT && foundCol.surfaceB != SURFACE_TARMAC && foundCol.surfaceB != SURFACE_PAVEMENT) {
|
||||||
|
|
||||||
|
if (m_pMyVehicle->CarHasRoof()) {
|
||||||
|
m_pMyVehicle->ApplyTurnForce(0.0f, 0.0f, CGeneral::GetRandomNumberInRange(-0.8f, -1.2f) * m_fMass,
|
||||||
|
GetPosition().x - m_pMyVehicle->GetPosition().x, GetPosition().y - m_pMyVehicle->GetPosition().y, 0.0f);
|
||||||
|
|
||||||
|
DMAudio.PlayOneShot(m_pMyVehicle->m_audioEntityId, SOUND_CAR_JERK, 0.0f);
|
||||||
|
|
||||||
|
int playerSexFrequency = CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency;
|
||||||
|
if (CWorld::Players[CWorld::PlayerInFocus].m_nMoney >= 10 && playerSexFrequency > 250) {
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_nNextSexFrequencyUpdateTime = CTimer::GetTimeInMilliseconds() + playerSexFrequency;
|
||||||
|
if (playerSexFrequency >= 350) {
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency = max(250, playerSexFrequency - 30);
|
||||||
|
} else {
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency = max(250, playerSexFrequency - 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pMyVehicle->pDriver->m_fHealth = min(125.0f, 1.0f + m_pMyVehicle->pDriver->m_fHealth);
|
||||||
|
if (CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency == 250)
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_nNextSexFrequencyUpdateTime = CTimer::GetTimeInMilliseconds() + 3000;
|
||||||
|
} else {
|
||||||
|
bWanderPathAfterExitingCar = true;
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_pHooker = nil;
|
||||||
|
SetObjective(OBJECTIVE_LEAVE_VEHICLE, m_pMyVehicle);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bWanderPathAfterExitingCar = true;
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_pHooker = nil;
|
||||||
|
m_pMyVehicle->pDriver->m_fHealth = 125.0f;
|
||||||
|
SetObjective(OBJECTIVE_LEAVE_VEHICLE, m_pMyVehicle);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_nNextSexFrequencyUpdateTime = CTimer::GetTimeInMilliseconds() + 3000;
|
||||||
|
int playerSexFrequency = CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency;
|
||||||
|
if (playerSexFrequency >= 1000 || playerSexFrequency <= 250)
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency = 1200;
|
||||||
|
else
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency = 250;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bWanderPathAfterExitingCar = true;
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_pHooker = nil;
|
||||||
|
SetObjective(OBJECTIVE_LEAVE_VEHICLE, m_pMyVehicle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nNextSexMoneyUpdateTime) {
|
||||||
|
int playerMoney = CWorld::Players[CWorld::PlayerInFocus].m_nMoney;
|
||||||
|
if (playerMoney <= 1) {
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency = 250;
|
||||||
|
} else {
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_nMoney = max(0, playerMoney - 1);
|
||||||
|
}
|
||||||
|
CWorld::Players[CWorld::PlayerInFocus].m_nNextSexMoneyUpdateTime = CTimer::GetTimeInMilliseconds() + 1000;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (IsPedInControl())
|
||||||
|
CivilianAI();
|
||||||
|
|
||||||
|
if (CTimer::GetTimeInMilliseconds() > m_timerUnused) {
|
||||||
|
m_stateUnused = 0;
|
||||||
|
m_timerUnused = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_moved.Magnitude() > 0.0f)
|
||||||
|
Avoid();
|
||||||
|
}
|
||||||
|
|
||||||
class CCivilianPed_ : public CCivilianPed
|
class CCivilianPed_ : public CCivilianPed
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CCivilianPed *ctor(int pedtype, int mi) { return ::new (this) CCivilianPed(pedtype, mi); };
|
CCivilianPed *ctor(int pedtype, int mi) { return ::new (this) CCivilianPed(pedtype, mi); };
|
||||||
void dtor(void) { CCivilianPed::~CCivilianPed(); }
|
void dtor(void) { CCivilianPed::~CCivilianPed(); }
|
||||||
|
void ProcessControl_(void) { CCivilianPed::ProcessControl(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
STARTPATCHES
|
STARTPATCHES
|
||||||
InjectHook(0x4BFF30, &CCivilianPed_::ctor, PATCH_JUMP);
|
InjectHook(0x4BFF30, &CCivilianPed_::ctor, PATCH_JUMP);
|
||||||
InjectHook(0x4BFFC0, &CCivilianPed_::dtor, PATCH_JUMP);
|
InjectHook(0x4BFFC0, &CCivilianPed_::dtor, PATCH_JUMP);
|
||||||
|
InjectHook(0x4BFFE0, &CCivilianPed_::ProcessControl_, PATCH_JUMP);
|
||||||
|
|
||||||
|
InjectHook(0x4C07A0, &CCivilianPed::CivilianAI, PATCH_JUMP);
|
||||||
ENDPATCHES
|
ENDPATCHES
|
||||||
|
|
|
@ -8,6 +8,7 @@ public:
|
||||||
CCivilianPed(int, int);
|
CCivilianPed(int, int);
|
||||||
~CCivilianPed(void) { }
|
~CCivilianPed(void) { }
|
||||||
|
|
||||||
|
void CivilianAI(void);
|
||||||
void ProcessControl(void);
|
void ProcessControl(void);
|
||||||
};
|
};
|
||||||
static_assert(sizeof(CCivilianPed) == 0x53C, "CCivilianPed: error");
|
static_assert(sizeof(CCivilianPed) == 0x53C, "CCivilianPed: error");
|
||||||
|
|
214
src/peds/Ped.cpp
214
src/peds/Ped.cpp
|
@ -272,10 +272,14 @@ static char WaitStateText[][16] = {
|
||||||
"Finish Flee",
|
"Finish Flee",
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef MASTER
|
#ifdef TOGGLEABLE_BETA_FEATURES
|
||||||
int nDisplayDebugInfo = 0;
|
|
||||||
bool CPed::bUnusedFightThingOnPlayer = false;
|
bool CPed::bUnusedFightThingOnPlayer = false;
|
||||||
bool CPed::bPopHeadsOnHeadshot = false;
|
bool CPed::bPopHeadsOnHeadshot = false;
|
||||||
|
bool CPed::bMakePedsRunToPhonesToReportCrimes = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MASTER
|
||||||
|
int nDisplayDebugInfo = 0;
|
||||||
|
|
||||||
void
|
void
|
||||||
CPed::SwitchDebugDisplay(void)
|
CPed::SwitchDebugDisplay(void)
|
||||||
|
@ -286,7 +290,7 @@ CPed::SwitchDebugDisplay(void)
|
||||||
void
|
void
|
||||||
CPed::DebugRenderOnePedText(void)
|
CPed::DebugRenderOnePedText(void)
|
||||||
{
|
{
|
||||||
if ((GetPosition() - TheCamera.GetPosition()).MagnitudeSqr() < 900.0f) {
|
if ((GetPosition() - TheCamera.GetPosition()).MagnitudeSqr() < sq(30.0f)) {
|
||||||
float width, height;
|
float width, height;
|
||||||
RwV3d screenCoords;
|
RwV3d screenCoords;
|
||||||
CVector bitAbove = GetPosition();
|
CVector bitAbove = GetPosition();
|
||||||
|
@ -300,7 +304,7 @@ CPed::DebugRenderOnePedText(void)
|
||||||
CFont::SetBackgroundOn();
|
CFont::SetBackgroundOn();
|
||||||
|
|
||||||
// Originally both of them were being divided by 60.0f.
|
// Originally both of them were being divided by 60.0f.
|
||||||
float xScale = min(width / 190.0f, 0.7f);
|
float xScale = min(width / 240.0f, 0.7f);
|
||||||
float yScale = min(height / 80.0f, 0.7f);
|
float yScale = min(height / 80.0f, 0.7f);
|
||||||
|
|
||||||
CFont::SetScale(SCREEN_SCALE_X(xScale), SCREEN_SCALE_Y(yScale));
|
CFont::SetScale(SCREEN_SCALE_X(xScale), SCREEN_SCALE_Y(yScale));
|
||||||
|
@ -866,7 +870,7 @@ CPed::RemoveBodyPart(PedNode nodeId, int8 direction)
|
||||||
frame = GetNodeFrame(nodeId);
|
frame = GetNodeFrame(nodeId);
|
||||||
if (frame) {
|
if (frame) {
|
||||||
if (CGame::nastyGame) {
|
if (CGame::nastyGame) {
|
||||||
#ifndef MASTER
|
#ifdef TOGGLEABLE_BETA_FEATURES
|
||||||
if (bPopHeadsOnHeadshot || nodeId != PED_HEAD)
|
if (bPopHeadsOnHeadshot || nodeId != PED_HEAD)
|
||||||
#else
|
#else
|
||||||
if (nodeId != PED_HEAD)
|
if (nodeId != PED_HEAD)
|
||||||
|
@ -2998,7 +3002,7 @@ CPed::ReactToAttack(CEntity *attacker)
|
||||||
|
|
||||||
CCarCtrl::SwitchVehicleToRealPhysics(m_pMyVehicle);
|
CCarCtrl::SwitchVehicleToRealPhysics(m_pMyVehicle);
|
||||||
m_pMyVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
|
m_pMyVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
|
||||||
m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 60.0f * m_pMyVehicle->pHandling->Transmission.fUnkMaxVelocity;
|
m_pMyVehicle->AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * m_pMyVehicle->pHandling->Transmission.fUnkMaxVelocity;
|
||||||
m_pMyVehicle->m_status = STATUS_PHYSICS;
|
m_pMyVehicle->m_status = STATUS_PHYSICS;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
|
@ -3046,7 +3050,7 @@ bool
|
||||||
CPed::TurnBody(void)
|
CPed::TurnBody(void)
|
||||||
{
|
{
|
||||||
float lookDir;
|
float lookDir;
|
||||||
bool doneSmoothly = true;
|
bool turnDone = true;
|
||||||
|
|
||||||
if (m_pLookTarget) {
|
if (m_pLookTarget) {
|
||||||
CVector &lookPos = m_pLookTarget->GetPosition();
|
CVector &lookPos = m_pLookTarget->GetPosition();
|
||||||
|
@ -3071,18 +3075,19 @@ CPed::TurnBody(void)
|
||||||
m_fRotationDest = limitedLookDir;
|
m_fRotationDest = limitedLookDir;
|
||||||
|
|
||||||
if (Abs(neededTurn) > 0.05f) {
|
if (Abs(neededTurn) > 0.05f) {
|
||||||
doneSmoothly = false;
|
turnDone = false;
|
||||||
currentRot -= neededTurn * 0.2f;
|
currentRot -= neededTurn * 0.2f;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_fRotationCur = currentRot;
|
m_fRotationCur = currentRot;
|
||||||
m_fLookDirection = limitedLookDir;
|
m_fLookDirection = limitedLookDir;
|
||||||
return doneSmoothly;
|
return turnDone;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CPed::Chat(void)
|
CPed::Chat(void)
|
||||||
{
|
{
|
||||||
|
// We're already looking to our partner
|
||||||
if (bIsLooking && TurnBody())
|
if (bIsLooking && TurnBody())
|
||||||
ClearLookFlag();
|
ClearLookFlag();
|
||||||
|
|
||||||
|
@ -3157,7 +3162,7 @@ CPed::CheckAroundForPossibleCollisions(void)
|
||||||
if (radius > 4.5f || radius < 1.0f)
|
if (radius > 4.5f || radius < 1.0f)
|
||||||
radius = 1.0f;
|
radius = 1.0f;
|
||||||
|
|
||||||
// According to code, developers gave up calculating Z diff. later.
|
// Developers gave up calculating Z diff. later according to asm.
|
||||||
float diff = CVector(ourCentre - objCentre).MagnitudeSqr2D();
|
float diff = CVector(ourCentre - objCentre).MagnitudeSqr2D();
|
||||||
|
|
||||||
if (sq(radius + 1.0f) > diff)
|
if (sq(radius + 1.0f) > diff)
|
||||||
|
@ -3168,6 +3173,15 @@ CPed::CheckAroundForPossibleCollisions(void)
|
||||||
bool
|
bool
|
||||||
CPed::MakePhonecall(void)
|
CPed::MakePhonecall(void)
|
||||||
{
|
{
|
||||||
|
#ifdef TOGGLEABLE_BETA_FEATURES
|
||||||
|
if (bMakePedsRunToPhonesToReportCrimes)
|
||||||
|
if (!IsPlayer() && CTimer::GetTimeInMilliseconds() > m_phoneTalkTimer - 7000 && bRunningToPhone) {
|
||||||
|
|
||||||
|
FindPlayerPed()->m_pWanted->RegisterCrime_Immediately(m_crimeToReportOnPhone, GetPosition(),
|
||||||
|
(m_crimeToReportOnPhone == CRIME_POSSESSION_GUN ? (int)m_threatEntity : (int)((CPed*)m_pEventEntity)->m_threatEntity), false);
|
||||||
|
bRunningToPhone = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (CTimer::GetTimeInMilliseconds() <= m_phoneTalkTimer)
|
if (CTimer::GetTimeInMilliseconds() <= m_phoneTalkTimer)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -3180,8 +3194,22 @@ CPed::MakePhonecall(void)
|
||||||
bool
|
bool
|
||||||
CPed::FacePhone(void)
|
CPed::FacePhone(void)
|
||||||
{
|
{
|
||||||
// FIX: I don't think this function was working correctly, they confused LimitAngle with LimitRadianAngle etc., so I fixed them
|
// FIX: This function was broken since it's left unused early in development.
|
||||||
float currentRot = m_fRotationCur;
|
#ifdef FIX_BUGS
|
||||||
|
float phoneDir = CGeneral::GetRadianAngleBetweenPoints(
|
||||||
|
gPhoneInfo.m_aPhones[m_phoneId].m_vecPos.x, gPhoneInfo.m_aPhones[m_phoneId].m_vecPos.y,
|
||||||
|
GetPosition().x, GetPosition().y);
|
||||||
|
|
||||||
|
SetLookFlag(phoneDir, false);
|
||||||
|
bool turnDone = TurnBody();
|
||||||
|
if (turnDone) {
|
||||||
|
SetIdle();
|
||||||
|
ClearLookFlag();
|
||||||
|
m_phoneTalkTimer = CTimer::GetTimeInMilliseconds() + 10000;
|
||||||
|
}
|
||||||
|
return turnDone;
|
||||||
|
#else
|
||||||
|
float currentRot = RADTODEG(m_fRotationCur);
|
||||||
float phoneDir = CGeneral::GetRadianAngleBetweenPoints(
|
float phoneDir = CGeneral::GetRadianAngleBetweenPoints(
|
||||||
gPhoneInfo.m_aPhones[m_phoneId].m_vecPos.x,
|
gPhoneInfo.m_aPhones[m_phoneId].m_vecPos.x,
|
||||||
gPhoneInfo.m_aPhones[m_phoneId].m_vecPos.y,
|
gPhoneInfo.m_aPhones[m_phoneId].m_vecPos.y,
|
||||||
|
@ -3189,14 +3217,13 @@ CPed::FacePhone(void)
|
||||||
GetPosition().y);
|
GetPosition().y);
|
||||||
|
|
||||||
SetLookFlag(phoneDir, false);
|
SetLookFlag(phoneDir, false);
|
||||||
|
phoneDir = CGeneral::LimitAngle(phoneDir);
|
||||||
phoneDir = CGeneral::LimitRadianAngle(phoneDir);
|
|
||||||
m_moved = CVector2D(0.0f, 0.0f);
|
m_moved = CVector2D(0.0f, 0.0f);
|
||||||
|
|
||||||
if (currentRot - PI > phoneDir)
|
if (currentRot - 180.0f > phoneDir)
|
||||||
phoneDir += 2 * PI;
|
phoneDir += 2 * 180.0f;
|
||||||
else if (PI + currentRot < phoneDir)
|
else if (180.0f + currentRot < phoneDir)
|
||||||
phoneDir -= 2 * PI;
|
phoneDir -= 2 * 180.0f;
|
||||||
|
|
||||||
float neededTurn = currentRot - phoneDir;
|
float neededTurn = currentRot - phoneDir;
|
||||||
|
|
||||||
|
@ -3206,9 +3233,10 @@ CPed::FacePhone(void)
|
||||||
m_phoneTalkTimer = CTimer::GetTimeInMilliseconds() + 10000;
|
m_phoneTalkTimer = CTimer::GetTimeInMilliseconds() + 10000;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
m_fRotationCur -= neededTurn * 0.2f;
|
m_fRotationCur = DEGTORAD(currentRot - neededTurn * 0.2f);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CPed *
|
CPed *
|
||||||
|
@ -4292,7 +4320,7 @@ CPed::RestorePreviousState(void)
|
||||||
if (!bFindNewNodeAfterStateRestore) {
|
if (!bFindNewNodeAfterStateRestore) {
|
||||||
if (m_pNextPathNode) {
|
if (m_pNextPathNode) {
|
||||||
CVector diff = m_pNextPathNode->pos - GetPosition();
|
CVector diff = m_pNextPathNode->pos - GetPosition();
|
||||||
if (diff.MagnitudeSqr() < 49.0f) {
|
if (diff.MagnitudeSqr() < sq(7.0f)) {
|
||||||
SetMoveState(PEDMOVE_WALK);
|
SetMoveState(PEDMOVE_WALK);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -4581,7 +4609,7 @@ CPed::SetEvasiveDive(CPhysical *reason, uint8 onlyRandomJump)
|
||||||
|
|
||||||
if (reason->IsVehicle() && m_nPedType == PEDTYPE_COP) {
|
if (reason->IsVehicle() && m_nPedType == PEDTYPE_COP) {
|
||||||
if (veh->pDriver && veh->pDriver->IsPlayer()) {
|
if (veh->pDriver && veh->pDriver->IsPlayer()) {
|
||||||
CWanted *wanted = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted;
|
CWanted *wanted = FindPlayerPed()->m_pWanted;
|
||||||
wanted->RegisterCrime_Immediately(CRIME_RECKLESS_DRIVING, GetPosition(), (int)this, false);
|
wanted->RegisterCrime_Immediately(CRIME_RECKLESS_DRIVING, GetPosition(), (int)this, false);
|
||||||
wanted->RegisterCrime_Immediately(CRIME_SPEEDING, GetPosition(), (int)this, false);
|
wanted->RegisterCrime_Immediately(CRIME_SPEEDING, GetPosition(), (int)this, false);
|
||||||
}
|
}
|
||||||
|
@ -4796,7 +4824,7 @@ CPed::StartFightAttack(uint8 buttonPressure)
|
||||||
animAssoc->SetFinishCallback(FinishFightMoveCB, this);
|
animAssoc->SetFinishCallback(FinishFightMoveCB, this);
|
||||||
m_fightState = FIGHTSTATE_NO_MOVE;
|
m_fightState = FIGHTSTATE_NO_MOVE;
|
||||||
m_takeAStepAfterAttack = false;
|
m_takeAStepAfterAttack = false;
|
||||||
#ifndef MASTER
|
#ifdef TOGGLEABLE_BETA_FEATURES
|
||||||
m_takeAStepAfterAttack = IsPlayer() && bUnusedFightThingOnPlayer;
|
m_takeAStepAfterAttack = IsPlayer() && bUnusedFightThingOnPlayer;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -5880,6 +5908,13 @@ CPed::SetDead(void)
|
||||||
if (m_nPedState == PED_DRIVING)
|
if (m_nPedState == PED_DRIVING)
|
||||||
bIsVisible = false;
|
bIsVisible = false;
|
||||||
|
|
||||||
|
#ifdef TOGGLEABLE_BETA_FEATURES
|
||||||
|
if (bRunningToPhone) {
|
||||||
|
if (gPhoneInfo.m_aPhones[m_phoneId].m_nState == PHONE_STATE_REPORTING_CRIME)
|
||||||
|
gPhoneInfo.m_aPhones[m_phoneId].m_nState = PHONE_STATE_FREE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
m_nPedState = PED_DEAD;
|
m_nPedState = PED_DEAD;
|
||||||
m_pVehicleAnim = nil;
|
m_pVehicleAnim = nil;
|
||||||
m_pCollidingEntity = nil;
|
m_pCollidingEntity = nil;
|
||||||
|
@ -7426,7 +7461,7 @@ CPed::Flee(void)
|
||||||
if (CTimer::GetTimeInMilliseconds() > m_fleeTimer && m_fleeTimer) {
|
if (CTimer::GetTimeInMilliseconds() > m_fleeTimer && m_fleeTimer) {
|
||||||
bool mayFinishFleeing = true;
|
bool mayFinishFleeing = true;
|
||||||
if (m_nPedState == PED_FLEE_ENTITY) {
|
if (m_nPedState == PED_FLEE_ENTITY) {
|
||||||
if ((CVector2D(GetPosition()) - ms_vec2DFleePosition).MagnitudeSqr() < 900.0f)
|
if ((CVector2D(GetPosition()) - ms_vec2DFleePosition).MagnitudeSqr() < sq(30.0f))
|
||||||
mayFinishFleeing = false;
|
mayFinishFleeing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7946,7 +7981,7 @@ CPed::Idle(void)
|
||||||
CVector doorPos = GetPositionToOpenCarDoor(veh, m_vehEnterType);
|
CVector doorPos = GetPositionToOpenCarDoor(veh, m_vehEnterType);
|
||||||
CVector doorDist = GetPosition() - doorPos;
|
CVector doorDist = GetPosition() - doorPos;
|
||||||
|
|
||||||
if (doorDist.MagnitudeSqr() < 0.25f) {
|
if (doorDist.MagnitudeSqr() < sq(0.5f)) {
|
||||||
SetMoveState(PEDMOVE_WALK);
|
SetMoveState(PEDMOVE_WALK);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -8324,7 +8359,7 @@ CPed::InvestigateEvent(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < m_numNearPeds; i++) {
|
for (int i = 0; i < m_numNearPeds; i++) {
|
||||||
if ((m_eventOrThreat - m_nearPeds[i]->GetPosition()).MagnitudeSqr() < 0.16f) {
|
if ((m_eventOrThreat - m_nearPeds[i]->GetPosition()).MagnitudeSqr() < sq(0.4f)) {
|
||||||
SetMoveState(PEDMOVE_STILL);
|
SetMoveState(PEDMOVE_STILL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -8531,6 +8566,10 @@ CPed::KillPedWithCar(CVehicle *car, float impulse)
|
||||||
|
|
||||||
if (car->pDriver) {
|
if (car->pDriver) {
|
||||||
CEventList::RegisterEvent((m_nPedType == PEDTYPE_COP ? EVENT_HIT_AND_RUN_COP : EVENT_HIT_AND_RUN), EVENT_ENTITY_PED, this, car->pDriver, 1000);
|
CEventList::RegisterEvent((m_nPedType == PEDTYPE_COP ? EVENT_HIT_AND_RUN_COP : EVENT_HIT_AND_RUN), EVENT_ENTITY_PED, this, car->pDriver, 1000);
|
||||||
|
#ifdef TOGGLEABLE_BETA_FEATURES
|
||||||
|
if (bMakePedsRunToPhonesToReportCrimes)
|
||||||
|
m_ped_flagI40 = true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ePedPieceTypes pieceToDamage;
|
ePedPieceTypes pieceToDamage;
|
||||||
|
@ -8659,7 +8698,7 @@ CPed::LookForInterestingNodes(void)
|
||||||
objMat = &veh->GetMatrix();
|
objMat = &veh->GetMatrix();
|
||||||
effectPos = veh->GetMatrix() * effect->pos;
|
effectPos = veh->GetMatrix() * effect->pos;
|
||||||
effectDist = effectPos - GetPosition();
|
effectDist = effectPos - GetPosition();
|
||||||
if (effectDist.MagnitudeSqr() < 64.0f) {
|
if (effectDist.MagnitudeSqr() < sq(8.0f)) {
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -8677,7 +8716,7 @@ CPed::LookForInterestingNodes(void)
|
||||||
objMat = &obj->GetMatrix();
|
objMat = &obj->GetMatrix();
|
||||||
effectPos = obj->GetMatrix() * effect->pos;
|
effectPos = obj->GetMatrix() * effect->pos;
|
||||||
effectDist = effectPos - GetPosition();
|
effectDist = effectPos - GetPosition();
|
||||||
if (effectDist.MagnitudeSqr() < 64.0f) {
|
if (effectDist.MagnitudeSqr() < sq(8.0f)) {
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -8695,7 +8734,7 @@ CPed::LookForInterestingNodes(void)
|
||||||
objMat = &building->GetMatrix();
|
objMat = &building->GetMatrix();
|
||||||
effectPos = building->GetMatrix() * effect->pos;
|
effectPos = building->GetMatrix() * effect->pos;
|
||||||
effectDist = effectPos - GetPosition();
|
effectDist = effectPos - GetPosition();
|
||||||
if (effectDist.MagnitudeSqr() < 64.0f) {
|
if (effectDist.MagnitudeSqr() < sq(8.0f)) {
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -8713,7 +8752,7 @@ CPed::LookForInterestingNodes(void)
|
||||||
objMat = &building->GetMatrix();
|
objMat = &building->GetMatrix();
|
||||||
effectPos = building->GetMatrix() * effect->pos;
|
effectPos = building->GetMatrix() * effect->pos;
|
||||||
effectDist = effectPos - GetPosition();
|
effectDist = effectPos - GetPosition();
|
||||||
if (effectDist.MagnitudeSqr() < 64.0f) {
|
if (effectDist.MagnitudeSqr() < sq(8.0f)) {
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -10343,6 +10382,11 @@ CPed::ProcessControl(void)
|
||||||
#ifdef CAR_AIRBREAK
|
#ifdef CAR_AIRBREAK
|
||||||
if (!pad->ArePlayerControlsDisabled()) {
|
if (!pad->ArePlayerControlsDisabled()) {
|
||||||
if (pad->GetHorn()) {
|
if (pad->GetHorn()) {
|
||||||
|
float c = Cos(m_fRotationCur);
|
||||||
|
float s = Sin(m_fRotationCur);
|
||||||
|
m_pMyVehicle->GetRight() = CVector(c, 0.0f, 0.0f);
|
||||||
|
m_pMyVehicle->GetForward() = CVector(0.0f, s, 0.0f);
|
||||||
|
m_pMyVehicle->GetUp() = CVector(0.0f, 0.0f, 1.0f);
|
||||||
if (pad->GetAccelerate()) {
|
if (pad->GetAccelerate()) {
|
||||||
m_pMyVehicle->ApplyMoveForce(GetForward() * 30.0f);
|
m_pMyVehicle->ApplyMoveForce(GetForward() * 30.0f);
|
||||||
} else if (pad->GetBrake()) {
|
} else if (pad->GetBrake()) {
|
||||||
|
@ -10461,7 +10505,7 @@ CPed::ProcessControl(void)
|
||||||
if (CGame::nastyGame) {
|
if (CGame::nastyGame) {
|
||||||
if (!(CTimer::GetFrameCounter() & 3)) {
|
if (!(CTimer::GetFrameCounter() & 3)) {
|
||||||
CVector cameraDist = GetPosition() - TheCamera.GetPosition();
|
CVector cameraDist = GetPosition() - TheCamera.GetPosition();
|
||||||
if (cameraDist.MagnitudeSqr() < 2500.0f) {
|
if (cameraDist.MagnitudeSqr() < sq(50.0f)) {
|
||||||
|
|
||||||
float length = (CGeneral::GetRandomNumber() & 127) * 0.0015f + 0.15f;
|
float length = (CGeneral::GetRandomNumber() & 127) * 0.0015f + 0.15f;
|
||||||
CVector bloodPos(
|
CVector bloodPos(
|
||||||
|
@ -11617,12 +11661,20 @@ CPed::PedStaggerCB(CAnimBlendAssociation* animAssoc, void* arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// It's "CPhoneInfo::ProcessNearestFreePhone" in PC IDB, but it's not true, someone made it up.
|
// It's "CPhoneInfo::ProcessNearestFreePhone" in PC IDB, but it's not true, someone made it up.
|
||||||
// TO-DO: No peds run to phones to report crimes. Make this work.
|
|
||||||
bool
|
bool
|
||||||
CPed::RunToReportCrime(eCrimeType crimeToReport)
|
CPed::RunToReportCrime(eCrimeType crimeToReport)
|
||||||
{
|
{
|
||||||
|
#ifdef TOGGLEABLE_BETA_FEATURES
|
||||||
|
if (!bMakePedsRunToPhonesToReportCrimes)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (bRunningToPhone)
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
// They changed true into false to make this function unusable. So running to phone actually starts but first frame after that cancels it.
|
||||||
if (m_nPedState == PED_SEEK_POS)
|
if (m_nPedState == PED_SEEK_POS)
|
||||||
return false;
|
return false;
|
||||||
|
#endif
|
||||||
|
|
||||||
CVector pos = GetPosition();
|
CVector pos = GetPosition();
|
||||||
int phoneId = gPhoneInfo.FindNearestFreePhone(&pos);
|
int phoneId = gPhoneInfo.FindNearestFreePhone(&pos);
|
||||||
|
@ -11634,8 +11686,11 @@ CPed::RunToReportCrime(eCrimeType crimeToReport)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bRunningToPhone = true;
|
bRunningToPhone = true;
|
||||||
|
SetSeek(gPhoneInfo.m_aPhones[phoneId].m_vecPos, 0.7f); // original: 0.35f
|
||||||
SetMoveState(PEDMOVE_RUN);
|
SetMoveState(PEDMOVE_RUN);
|
||||||
SetSeek(gPhoneInfo.m_aPhones[phoneId].m_vecPos, 0.3f);
|
#ifdef FIX_BUGS
|
||||||
|
bIsRunning = true;
|
||||||
|
#endif
|
||||||
m_phoneId = phoneId;
|
m_phoneId = phoneId;
|
||||||
m_crimeToReportOnPhone = crimeToReport;
|
m_crimeToReportOnPhone = crimeToReport;
|
||||||
return true;
|
return true;
|
||||||
|
@ -11688,7 +11743,7 @@ CPed::RegisterThreatWithGangPeds(CEntity *attacker)
|
||||||
if (nearVehDriver && nearVehDriver != this && nearVehDriver->m_nPedType == m_nPedType) {
|
if (nearVehDriver && nearVehDriver != this && nearVehDriver->m_nPedType == m_nPedType) {
|
||||||
|
|
||||||
if (nearVeh->IsVehicleNormal() && nearVeh->IsCar()) {
|
if (nearVeh->IsVehicleNormal() && nearVeh->IsCar()) {
|
||||||
nearVeh->AutoPilot.m_nCruiseSpeed = 60.0f * nearVeh->pHandling->Transmission.fUnkMaxVelocity * 0.8f;
|
nearVeh->AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * nearVeh->pHandling->Transmission.fUnkMaxVelocity * 0.8f;
|
||||||
nearVeh->AutoPilot.m_nCarMission = MISSION_RAMPLAYER_FARAWAY;
|
nearVeh->AutoPilot.m_nCarMission = MISSION_RAMPLAYER_FARAWAY;
|
||||||
nearVeh->m_status = STATUS_PHYSICS;
|
nearVeh->m_status = STATUS_PHYSICS;
|
||||||
nearVeh->AutoPilot.m_nTempAction = TEMPACT_NONE;
|
nearVeh->AutoPilot.m_nTempAction = TEMPACT_NONE;
|
||||||
|
@ -12338,7 +12393,7 @@ CPed::PossiblyFindBetterPosToSeekCar(CVector *pos, CVehicle *veh)
|
||||||
|
|
||||||
helperPos = GetPosition() - foundPos;
|
helperPos = GetPosition() - foundPos;
|
||||||
helperPos.z = 0.0f;
|
helperPos.z = 0.0f;
|
||||||
if (helperPos.MagnitudeSqr() <= 0.25f)
|
if (helperPos.MagnitudeSqr() <= sq(0.5f))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
pos->x = foundPos.x;
|
pos->x = foundPos.x;
|
||||||
|
@ -12468,16 +12523,16 @@ CPed::ProcessObjective(void)
|
||||||
}
|
}
|
||||||
if (bInVehicle && m_pMyVehicle) {
|
if (bInVehicle && m_pMyVehicle) {
|
||||||
if (distWithTarget.Magnitude() >= 20.0f
|
if (distWithTarget.Magnitude() >= 20.0f
|
||||||
|| m_pMyVehicle->m_vecMoveSpeed.MagnitudeSqr() >= 0.0004f) {
|
|| m_pMyVehicle->m_vecMoveSpeed.MagnitudeSqr() >= sq(0.02f)) {
|
||||||
if (m_pMyVehicle->pDriver == this
|
if (m_pMyVehicle->pDriver == this
|
||||||
&& !m_pMyVehicle->m_nGettingInFlags) {
|
&& !m_pMyVehicle->m_nGettingInFlags) {
|
||||||
m_pMyVehicle->m_status = STATUS_PHYSICS;
|
m_pMyVehicle->m_status = STATUS_PHYSICS;
|
||||||
m_pMyVehicle->AutoPilot.m_nPrevRouteNode = 0;
|
m_pMyVehicle->AutoPilot.m_nPrevRouteNode = 0;
|
||||||
if (m_nPedType == PEDTYPE_COP) {
|
if (m_nPedType == PEDTYPE_COP) {
|
||||||
m_pMyVehicle->AutoPilot.m_nCruiseSpeed = (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->m_nWantedLevel * 0.1f + 0.6f) * (60.0f * m_pMyVehicle->pHandling->Transmission.fUnkMaxVelocity);
|
m_pMyVehicle->AutoPilot.m_nCruiseSpeed = (FindPlayerPed()->m_pWanted->m_nWantedLevel * 0.1f + 0.6f) * (GAME_SPEED_TO_CARAI_SPEED * m_pMyVehicle->pHandling->Transmission.fUnkMaxVelocity);
|
||||||
m_pMyVehicle->AutoPilot.m_nCarMission = CCarAI::FindPoliceCarMissionForWantedLevel();
|
m_pMyVehicle->AutoPilot.m_nCarMission = CCarAI::FindPoliceCarMissionForWantedLevel();
|
||||||
} else {
|
} else {
|
||||||
m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 60.0f * m_pMyVehicle->pHandling->Transmission.fUnkMaxVelocity * 0.8f;
|
m_pMyVehicle->AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * m_pMyVehicle->pHandling->Transmission.fUnkMaxVelocity * 0.8f;
|
||||||
m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_RAMPLAYER_FARAWAY;
|
m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_RAMPLAYER_FARAWAY;
|
||||||
}
|
}
|
||||||
m_pMyVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
|
m_pMyVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
|
||||||
|
@ -13221,7 +13276,7 @@ CPed::ProcessObjective(void)
|
||||||
if (bInVehicle && m_pMyVehicle) {
|
if (bInVehicle && m_pMyVehicle) {
|
||||||
CCarAI::GetCarToGoToCoors(m_pMyVehicle, &m_nextRoutePointPos);
|
CCarAI::GetCarToGoToCoors(m_pMyVehicle, &m_nextRoutePointPos);
|
||||||
CCarCtrl::RegisterVehicleOfInterest(m_pMyVehicle);
|
CCarCtrl::RegisterVehicleOfInterest(m_pMyVehicle);
|
||||||
if (distWithTarget.MagnitudeSqr() < 400.0f) {
|
if (distWithTarget.MagnitudeSqr() < sq(20.0f)) {
|
||||||
m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0;
|
m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0;
|
||||||
CPed::ForceStoredObjective(OBJECTIVE_GOTO_AREA_ANY_MEANS);
|
CPed::ForceStoredObjective(OBJECTIVE_GOTO_AREA_ANY_MEANS);
|
||||||
SetObjective(OBJECTIVE_LEAVE_VEHICLE, m_pMyVehicle);
|
SetObjective(OBJECTIVE_LEAVE_VEHICLE, m_pMyVehicle);
|
||||||
|
@ -13460,8 +13515,8 @@ CPed::ProcessObjective(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
float distWithTargetScSqr = distWithTarget.MagnitudeSqr();
|
float distWithTargetScSqr = distWithTarget.MagnitudeSqr();
|
||||||
if (distWithTargetScSqr <= 100.0f) {
|
if (distWithTargetScSqr <= sq(10.0f)) {
|
||||||
if (distWithTargetScSqr <= 1.96f) {
|
if (distWithTargetScSqr <= sq(1.4f)) {
|
||||||
CAnimBlendAssociation *reloadAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_AK_RELOAD);
|
CAnimBlendAssociation *reloadAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_AK_RELOAD);
|
||||||
m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(
|
m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(
|
||||||
m_pedInObjective->GetPosition().x, m_pedInObjective->GetPosition().y,
|
m_pedInObjective->GetPosition().x, m_pedInObjective->GetPosition().y,
|
||||||
|
@ -13724,15 +13779,19 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
|
||||||
if (m_nMoveState == PEDMOVE_NONE || m_nMoveState == PEDMOVE_STILL)
|
if (m_nMoveState == PEDMOVE_NONE || m_nMoveState == PEDMOVE_STILL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (CharCreatedBy != MISSION_CHAR && obj->m_modelIndex == MI_PHONEBOOTH1) {
|
#ifdef TOGGLEABLE_BETA_FEATURES
|
||||||
bool isRunning = m_nMoveState == PEDMOVE_RUN || m_nMoveState == PEDMOVE_SPRINT;
|
if (!bMakePedsRunToPhonesToReportCrimes)
|
||||||
SetFlee(obj, 5000);
|
#endif
|
||||||
bUsePedNodeSeek = true;
|
if (CharCreatedBy != MISSION_CHAR && obj->m_modelIndex == MI_PHONEBOOTH1) {
|
||||||
m_pNextPathNode = nil;
|
bool isRunning = m_nMoveState == PEDMOVE_RUN || m_nMoveState == PEDMOVE_SPRINT;
|
||||||
if (!isRunning)
|
SetFlee(obj, 5000);
|
||||||
SetMoveState(PEDMOVE_WALK);
|
bUsePedNodeSeek = true;
|
||||||
return;
|
m_pNextPathNode = nil;
|
||||||
}
|
if (!isRunning)
|
||||||
|
SetMoveState(PEDMOVE_WALK);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
CVector2D adjustedColMin(objColMin.x - 0.35f, objColMin.y - 0.35f);
|
CVector2D adjustedColMin(objColMin.x - 0.35f, objColMin.y - 0.35f);
|
||||||
CVector2D adjustedColMax(objColMax.x + 0.35f, objColMax.y + 0.35f);
|
CVector2D adjustedColMax(objColMax.x + 0.35f, objColMax.y + 0.35f);
|
||||||
|
|
||||||
|
@ -14427,7 +14486,7 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints)
|
||||||
#else
|
#else
|
||||||
float speedSqr = 0.0f;
|
float speedSqr = 0.0f;
|
||||||
if (!m_ped_flagA2) {
|
if (!m_ped_flagA2) {
|
||||||
if (m_vecMoveSpeed.z >= -0.25f && (speedSqr = m_vecMoveSpeed.MagnitudeSqr()) <= 0.25f) {
|
if (m_vecMoveSpeed.z >= -0.25f && (speedSqr = m_vecMoveSpeed.MagnitudeSqr()) <= sq(0.5f)) {
|
||||||
|
|
||||||
if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FALL_FALL) && -0.016f * CTimer::GetTimeStep() > m_vecMoveSpeed.z) {
|
if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FALL_FALL) && -0.016f * CTimer::GetTimeStep() > m_vecMoveSpeed.z) {
|
||||||
InflictDamage(collidingEnt, WEAPONTYPE_FALL_DAMAGE, 15.0f, PEDPIECE_TORSO, 2);
|
InflictDamage(collidingEnt, WEAPONTYPE_FALL_DAMAGE, 15.0f, PEDPIECE_TORSO, 2);
|
||||||
|
@ -15354,7 +15413,7 @@ CPed::ScanForInterestingStuff(void)
|
||||||
for (int i = 0; i < m_numNearPeds; ++i) {
|
for (int i = 0; i < m_numNearPeds; ++i) {
|
||||||
CPed *nearPed = m_nearPeds[i];
|
CPed *nearPed = m_nearPeds[i];
|
||||||
|
|
||||||
if ((nearPed->GetPosition() - GetPosition()).MagnitudeSqr() > 49.0f)
|
if ((nearPed->GetPosition() - GetPosition()).MagnitudeSqr() > sq(7.0f))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if ((nearPed->m_nPedType == PEDTYPE_CIVFEMALE || nearPed->m_nPedType == PEDTYPE_CIVMALE
|
if ((nearPed->m_nPedType == PEDTYPE_CIVFEMALE || nearPed->m_nPedType == PEDTYPE_CIVMALE
|
||||||
|
@ -15520,7 +15579,7 @@ CPed::ScanForThreats(void)
|
||||||
|
|
||||||
CPed *deadPed = nil;
|
CPed *deadPed = nil;
|
||||||
if (fearFlags & PED_FLAG_DEADPEDS && CharCreatedBy != MISSION_CHAR
|
if (fearFlags & PED_FLAG_DEADPEDS && CharCreatedBy != MISSION_CHAR
|
||||||
&& (deadPed = CheckForDeadPeds()) != nil && (deadPed->GetPosition() - ourPos).MagnitudeSqr() < 400.0f) {
|
&& (deadPed = CheckForDeadPeds()) != nil && (deadPed->GetPosition() - ourPos).MagnitudeSqr() < sq(20.0f)) {
|
||||||
m_pEventEntity = deadPed;
|
m_pEventEntity = deadPed;
|
||||||
m_pEventEntity->RegisterReference((CEntity **) &m_pEventEntity);
|
m_pEventEntity->RegisterReference((CEntity **) &m_pEventEntity);
|
||||||
return PED_FLAG_DEADPEDS;
|
return PED_FLAG_DEADPEDS;
|
||||||
|
@ -15747,21 +15806,21 @@ CPed::SeekCar(void)
|
||||||
}
|
}
|
||||||
bool foundBetterPosToSeek = PossiblyFindBetterPosToSeekCar(&dest, vehToSeek);
|
bool foundBetterPosToSeek = PossiblyFindBetterPosToSeekCar(&dest, vehToSeek);
|
||||||
m_vecSeekPos = dest;
|
m_vecSeekPos = dest;
|
||||||
float distToDest = (m_vecSeekPos - GetPosition()).MagnitudeSqr();
|
float distToDestSqr = (m_vecSeekPos - GetPosition()).MagnitudeSqr();
|
||||||
#ifndef VC_PED_PORTS
|
#ifndef VC_PED_PORTS
|
||||||
if (bIsRunning)
|
if (bIsRunning)
|
||||||
SetMoveState(PEDMOVE_RUN);
|
SetMoveState(PEDMOVE_RUN);
|
||||||
#else
|
#else
|
||||||
if (bIsRunning ||
|
if (bIsRunning ||
|
||||||
vehToSeek->pDriver && distToDest > 4.0f && (Abs(vehToSeek->m_vecMoveSpeed.x) > 0.01f || Abs(vehToSeek->m_vecMoveSpeed.y) > 0.01f))
|
vehToSeek->pDriver && distToDestSqr > sq(2.0f) && (Abs(vehToSeek->m_vecMoveSpeed.x) > 0.01f || Abs(vehToSeek->m_vecMoveSpeed.y) > 0.01f))
|
||||||
SetMoveState(PEDMOVE_RUN);
|
SetMoveState(PEDMOVE_RUN);
|
||||||
#endif
|
#endif
|
||||||
else if (distToDest < 4.0f)
|
else if (distToDestSqr < sq(2.0f))
|
||||||
SetMoveState(PEDMOVE_WALK);
|
SetMoveState(PEDMOVE_WALK);
|
||||||
|
|
||||||
if (distToDest >= 1.0f)
|
if (distToDestSqr >= 1.0f)
|
||||||
bCanPedEnterSeekedCar = false;
|
bCanPedEnterSeekedCar = false;
|
||||||
else if (2.0f * vehToSeek->GetColModel()->boundingBox.max.x > distToDest)
|
else if (2.0f * vehToSeek->GetColModel()->boundingBox.max.x > distToDestSqr)
|
||||||
bCanPedEnterSeekedCar = true;
|
bCanPedEnterSeekedCar = true;
|
||||||
|
|
||||||
if (vehToSeek->m_nGettingInFlags & GetCarDoorFlag(m_vehEnterType))
|
if (vehToSeek->m_nGettingInFlags & GetCarDoorFlag(m_vehEnterType))
|
||||||
|
@ -17145,6 +17204,46 @@ CPed::SetCarJack(CVehicle* car)
|
||||||
SetCarJack_AllClear(car, m_vehEnterType, doorFlag);
|
SetCarJack_AllClear(car, m_vehEnterType, doorFlag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPed::Solicit(void)
|
||||||
|
{
|
||||||
|
if (m_standardTimer >= CTimer::GetTimeInMilliseconds() && m_carInObjective) {
|
||||||
|
CVector doorPos = GetPositionToOpenCarDoor(m_carInObjective, m_vehEnterType, 0.0f);
|
||||||
|
SetMoveState(PEDMOVE_STILL);
|
||||||
|
|
||||||
|
// Game uses GetAngleBetweenPoints and converts it to radian
|
||||||
|
m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(
|
||||||
|
doorPos.x, doorPos.y,
|
||||||
|
GetPosition().x, GetPosition().y);
|
||||||
|
|
||||||
|
if (m_fRotationDest < 0.0f) {
|
||||||
|
m_fRotationDest = m_fRotationDest + TWOPI;
|
||||||
|
} else if (m_fRotationDest > TWOPI) {
|
||||||
|
m_fRotationDest = m_fRotationDest - TWOPI;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((GetPosition() - doorPos).MagnitudeSqr() <= 1.0f)
|
||||||
|
return;
|
||||||
|
CAnimBlendAssociation *talkAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_HOOKERTALK);
|
||||||
|
if (talkAssoc) {
|
||||||
|
talkAssoc->blendDelta = -1000.0f;
|
||||||
|
talkAssoc->flags |= ASSOC_DELETEFADEDOUT;
|
||||||
|
}
|
||||||
|
RestorePreviousState();
|
||||||
|
RestorePreviousObjective();
|
||||||
|
SetObjectiveTimer(10000);
|
||||||
|
} else if (!m_carInObjective) {
|
||||||
|
RestorePreviousState();
|
||||||
|
RestorePreviousObjective();
|
||||||
|
SetObjectiveTimer(10000);
|
||||||
|
} else if (CWorld::Players[CWorld::PlayerInFocus].m_nMoney <= 100) {
|
||||||
|
m_carInObjective = nil;
|
||||||
|
} else {
|
||||||
|
m_pVehicleAnim = nil;
|
||||||
|
SetLeader(m_carInObjective->pDriver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class CPed_ : public CPed
|
class CPed_ : public CPed
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -17377,4 +17476,5 @@ STARTPATCHES
|
||||||
InjectHook(0x4E5570, &CPed::WarpPedToNearEntityOffScreen, PATCH_JUMP);
|
InjectHook(0x4E5570, &CPed::WarpPedToNearEntityOffScreen, PATCH_JUMP);
|
||||||
InjectHook(0x4E52A0, &CPed::WarpPedToNearLeaderOffScreen, PATCH_JUMP);
|
InjectHook(0x4E52A0, &CPed::WarpPedToNearLeaderOffScreen, PATCH_JUMP);
|
||||||
InjectHook(0x4E0220, &CPed::SetCarJack, PATCH_JUMP);
|
InjectHook(0x4E0220, &CPed::SetCarJack, PATCH_JUMP);
|
||||||
|
InjectHook(0x4D6780, &CPed::Solicit, PATCH_JUMP);
|
||||||
ENDPATCHES
|
ENDPATCHES
|
|
@ -246,6 +246,8 @@ enum PedState
|
||||||
PED_UNKNOWN, // HANG_OUT in Fire_Head's idb
|
PED_UNKNOWN, // HANG_OUT in Fire_Head's idb
|
||||||
|
|
||||||
PED_STATES_NO_AI,
|
PED_STATES_NO_AI,
|
||||||
|
|
||||||
|
// One of these states isn't on PS2 - start
|
||||||
PED_JUMP,
|
PED_JUMP,
|
||||||
PED_FALL,
|
PED_FALL,
|
||||||
PED_GETUP,
|
PED_GETUP,
|
||||||
|
@ -256,6 +258,8 @@ enum PedState
|
||||||
PED_ENTER_TRAIN,
|
PED_ENTER_TRAIN,
|
||||||
PED_EXIT_TRAIN,
|
PED_EXIT_TRAIN,
|
||||||
PED_ARREST_PLAYER,
|
PED_ARREST_PLAYER,
|
||||||
|
// One of these states isn't on PS2 - end
|
||||||
|
|
||||||
PED_DRIVING,
|
PED_DRIVING,
|
||||||
PED_PASSENGER,
|
PED_PASSENGER,
|
||||||
PED_TAXI_PASSENGER,
|
PED_TAXI_PASSENGER,
|
||||||
|
@ -371,8 +375,8 @@ public:
|
||||||
#else
|
#else
|
||||||
uint8 m_ped_flagI20 : 1;
|
uint8 m_ped_flagI20 : 1;
|
||||||
#endif
|
#endif
|
||||||
uint8 m_ped_flagI40 : 1;
|
uint8 m_ped_flagI40 : 1; // bMakePedsRunToPhonesToReportCrimes makes use of this as runover by car indicator
|
||||||
uint8 m_ped_flagI80 : 1;
|
uint8 m_ped_flagI80 : 1; // KANGAROO_CHEAT define makes use of this as cheat toggle
|
||||||
|
|
||||||
uint8 stuff10[3];
|
uint8 stuff10[3];
|
||||||
uint8 CharCreatedBy;
|
uint8 CharCreatedBy;
|
||||||
|
@ -407,7 +411,7 @@ public:
|
||||||
int32 m_nPrevMoveState;
|
int32 m_nPrevMoveState;
|
||||||
eWaitState m_nWaitState;
|
eWaitState m_nWaitState;
|
||||||
uint32 m_nWaitTimer;
|
uint32 m_nWaitTimer;
|
||||||
void *m_pPathNodesStates[8]; // seems unused, probably leftover from VC
|
void *m_pPathNodesStates[8]; // unused, probably leftover from VC
|
||||||
CVector2D m_stPathNodeStates[10];
|
CVector2D m_stPathNodeStates[10];
|
||||||
uint16 m_nPathNodes;
|
uint16 m_nPathNodes;
|
||||||
int16 m_nCurPathNode;
|
int16 m_nCurPathNode;
|
||||||
|
@ -691,6 +695,7 @@ public:
|
||||||
void WarpPedIntoCar(CVehicle*);
|
void WarpPedIntoCar(CVehicle*);
|
||||||
void SetCarJack(CVehicle*);
|
void SetCarJack(CVehicle*);
|
||||||
bool WarpPedToNearLeaderOffScreen(void);
|
bool WarpPedToNearLeaderOffScreen(void);
|
||||||
|
void Solicit(void);
|
||||||
|
|
||||||
// Static methods
|
// Static methods
|
||||||
static CVector GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float offset);
|
static CVector GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float offset);
|
||||||
|
@ -798,10 +803,13 @@ public:
|
||||||
static CVector2D ms_vec2DFleePosition;
|
static CVector2D ms_vec2DFleePosition;
|
||||||
static CPedAudioData (&CommentWaitTime)[38];
|
static CPedAudioData (&CommentWaitTime)[38];
|
||||||
|
|
||||||
#ifndef MASTER
|
#ifdef TOGGLEABLE_BETA_FEATURES
|
||||||
static bool bUnusedFightThingOnPlayer;
|
static bool bUnusedFightThingOnPlayer;
|
||||||
static bool bPopHeadsOnHeadshot;
|
static bool bPopHeadsOnHeadshot;
|
||||||
|
static bool bMakePedsRunToPhonesToReportCrimes;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MASTER
|
||||||
// Mobile things
|
// Mobile things
|
||||||
static void SwitchDebugDisplay(void);
|
static void SwitchDebugDisplay(void);
|
||||||
void DebugRenderOnePedText(void);
|
void DebugRenderOnePedText(void);
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include "ParticleObject.h"
|
#include "ParticleObject.h"
|
||||||
#include "Particle.h"
|
#include "Particle.h"
|
||||||
|
|
||||||
#ifndef MASTER
|
#ifdef TOGGLEABLE_BETA_FEATURES
|
||||||
bool CParticle::bEnableBannedParticles = false;
|
bool CParticle::bEnableBannedParticles = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -772,7 +772,7 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe
|
||||||
{
|
{
|
||||||
if ( CTimer::GetIsPaused() )
|
if ( CTimer::GetIsPaused() )
|
||||||
return NULL;
|
return NULL;
|
||||||
#ifndef MASTER
|
#ifdef TOGGLEABLE_BETA_FEATURES
|
||||||
if(!bEnableBannedParticles)
|
if(!bEnableBannedParticles)
|
||||||
#endif
|
#endif
|
||||||
if ( ( type == PARTICLE_ENGINE_SMOKE
|
if ( ( type == PARTICLE_ENGINE_SMOKE
|
||||||
|
@ -1462,7 +1462,7 @@ void CParticle::Render()
|
||||||
|
|
||||||
tParticleType type = psystem->m_Type;
|
tParticleType type = psystem->m_Type;
|
||||||
|
|
||||||
#ifndef MASTER
|
#ifdef TOGGLEABLE_BETA_FEATURES
|
||||||
if (!bEnableBannedParticles)
|
if (!bEnableBannedParticles)
|
||||||
#endif
|
#endif
|
||||||
if ( type == PARTICLE_ENGINE_SMOKE
|
if ( type == PARTICLE_ENGINE_SMOKE
|
||||||
|
|
|
@ -1918,7 +1918,7 @@ CAutomobile::Render(void)
|
||||||
CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
|
CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
|
||||||
|
|
||||||
if(GetModelIndex() == MI_RHINO && m_aCarNodes[CAR_BONNET]){
|
if(GetModelIndex() == MI_RHINO && m_aCarNodes[CAR_BONNET]){
|
||||||
// Rhino has no bonnet...what are we doing here?
|
// Rotate Rhino turret
|
||||||
CMatrix m;
|
CMatrix m;
|
||||||
CVector p;
|
CVector p;
|
||||||
m.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_BONNET]));
|
m.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_BONNET]));
|
||||||
|
|
Loading…
Reference in a new issue