Restored beta police system(disabled), fixes from miami, debug info for CFO crash (#639)

This commit is contained in:
erorcun
2020-07-01 15:28:43 +03:00
committed by GitHub
parent 779d4e02a4
commit eda50bc32b
14 changed files with 430 additions and 158 deletions

View File

@ -10,6 +10,30 @@
#include "Vehicle.h"
#include "SurfaceTable.h"
#ifdef PEDS_REPORT_CRIMES_ON_PHONE
eCrimeType
EventTypeToCrimeType(eEventType event)
{
eCrimeType crime;
switch (event) {
case EVENT_ASSAULT: crime = CRIME_HIT_PED; break;
case EVENT_RUN_REDLIGHT: crime = CRIME_RUN_REDLIGHT; break;
case EVENT_ASSAULT_POLICE: crime = CRIME_HIT_COP; break;
case EVENT_GUNSHOT: crime = CRIME_POSSESSION_GUN; break;
case EVENT_STEAL_CAR: crime = CRIME_STEAL_CAR; break;
case EVENT_HIT_AND_RUN: crime = CRIME_RUNOVER_PED; break;
case EVENT_HIT_AND_RUN_COP: crime = CRIME_RUNOVER_COP; break;
case EVENT_SHOOT_PED: crime = CRIME_SHOOT_PED; break;
case EVENT_SHOOT_COP: crime = CRIME_SHOOT_COP; break;
case EVENT_PED_SET_ON_FIRE: crime = CRIME_PED_BURNED; break;
case EVENT_COP_SET_ON_FIRE: crime = CRIME_COP_BURNED; break;
case EVENT_CAR_SET_ON_FIRE: crime = CRIME_VEHICLE_BURNED; break;
default: crime = CRIME_NONE; break;
}
return crime;
}
#endif
CCivilianPed::CCivilianPed(ePedType pedtype, uint32 mi) : CPed(pedtype)
{
SetModelIndex(mi);
@ -113,25 +137,20 @@ CCivilianPed::CivilianAI(void)
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;
#ifdef PEDS_REPORT_CRIMES_ON_PHONE
int32 eventId = CheckForPlayerCrimes((CPed*)m_pEventEntity);
eCrimeType crime = (eventId == -1 ? CRIME_NONE : EventTypeToCrimeType(gaEvent[eventId].type));
bool eligibleToReport = crime != CRIME_NONE && 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;
#ifdef PEDS_REPORT_CRIMES_ON_PHONE
int32 eventId = CheckForPlayerCrimes((CPed*)m_pEventEntity);
eCrimeType crime = (eventId == -1 ? CRIME_NONE : EventTypeToCrimeType(gaEvent[eventId].type));
bool eligibleToReport = crime != CRIME_NONE && m_pedStats->m_fear <= m_pedStats->m_lawfulness && m_pedStats->m_temper <= m_pedStats->m_fear;
if(!eligibleToReport || !RunToReportCrime(crime))
#endif
{
@ -165,22 +184,48 @@ CCivilianPed::CivilianAI(void)
}
}
} else {
#ifdef PEDS_REPORT_CRIMES_ON_PHONE
bool youShouldRunEventually = false;
bool dontGoToPhone = false;
#endif
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(m_currentWeapon).IsTypeMelee() || !GetWeapon()->IsTypeMelee()) {
if (threatPed->IsPlayer() && FindPlayerPed()->m_pWanted->m_CurrentCops != 0) {
if (m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT || m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS) {
#ifdef PEDS_REPORT_CRIMES_ON_PHONE
dontGoToPhone = true;
#endif
SetFindPathAndFlee(m_threatEntity, 10000);
}
} else {
#ifdef PEDS_REPORT_CRIMES_ON_PHONE
dontGoToPhone = true;
#endif
SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, m_threatEntity);
}
}
} else {
#ifdef PEDS_REPORT_CRIMES_ON_PHONE
youShouldRunEventually = true;
#else
SetFindPathAndFlee(m_threatEntity, 10000, true);
#endif
}
}
#ifdef PEDS_REPORT_CRIMES_ON_PHONE
if (!dontGoToPhone) {
int32 eventId = CheckForPlayerCrimes(nil);
eCrimeType crime = (eventId == -1 ? CRIME_NONE : EventTypeToCrimeType(gaEvent[eventId].type));
bool eligibleToReport = crime != CRIME_NONE && m_pedStats->m_fear <= m_pedStats->m_lawfulness;
if ((!eligibleToReport || !RunToReportCrime(crime)) && youShouldRunEventually) {
SetFindPathAndFlee(m_threatEntity, 10000, true);
}
}
#endif
}
}
@ -217,15 +262,18 @@ CCivilianPed::ProcessControl(void)
if (Seek()) {
if ((m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT || m_objective == OBJECTIVE_RUN_TO_AREA) && m_pNextPathNode) {
m_pNextPathNode = nil;
#ifdef TOGGLEABLE_BETA_FEATURES
#ifdef PEDS_REPORT_CRIMES_ON_PHONE
} else if (bRunningToPhone && m_objective < OBJECTIVE_FLEE_TILL_SAFE) {
if (!isPhoneAvailable(m_phoneId)) {
RestorePreviousState();
crimeReporters[m_phoneId] = nil;
if (crimeReporters[m_phoneId] == this)
crimeReporters[m_phoneId] = nil;
m_phoneId = -1;
bRunningToPhone = false;
} else {
crimeReporters[m_phoneId] = this;
m_facePhoneStart = true;
m_nPedState = PED_FACE_PHONE;
}
#else

View File

@ -118,9 +118,8 @@ void *CPed::operator new(size_t sz, int handle) { return CPools::GetPedPool()->N
void CPed::operator delete(void *p, size_t sz) { CPools::GetPedPool()->Delete((CPed*)p); }
void CPed::operator delete(void *p, int handle) { CPools::GetPedPool()->Delete((CPed*)p); }
#ifdef TOGGLEABLE_BETA_FEATURES
#ifdef DEBUGMENU
bool CPed::bPopHeadsOnHeadshot = false;
bool CPed::bMakePedsRunToPhonesToReportCrimes = false;
#endif
CPed::~CPed(void)
@ -683,7 +682,7 @@ CPed::RemoveBodyPart(PedNode nodeId, int8 direction)
if(!IsClumpSkinned(GetClump()))
#endif
{
#ifdef TOGGLEABLE_BETA_FEATURES
#ifdef DEBUGMENU
if (bPopHeadsOnHeadshot || nodeId != PED_HEAD)
#else
if (nodeId != PED_HEAD)
@ -2014,18 +2013,19 @@ CPed::SortPeds(CPed **list, int min, int max)
void
CPed::BuildPedLists(void)
{
if ((CTimer::GetFrameCounter() + (m_randomSeed % 256)) % 16) {
if ((CTimer::GetFrameCounter() + m_randomSeed) % 16) {
for(int i = 0; i < ARRAY_SIZE(m_nearPeds); ) {
bool removePed = false;
if (m_nearPeds[i]) {
if (m_nearPeds[i]->IsPointerValid()) {
float distSqr = (GetPosition() - m_nearPeds[i]->GetPosition()).MagnitudeSqr2D();
if (distSqr < 900.0f) {
i++;
continue;
}
}
if (distSqr > 900.0f)
removePed = true;
} else
removePed = true;
}
if (removePed) {
// If we arrive here, the ped we're checking isn't "near", so we should remove it.
for (int j = i; j < ARRAY_SIZE(m_nearPeds) - 1; j++) {
m_nearPeds[j] = m_nearPeds[j + 1];
@ -2033,7 +2033,7 @@ CPed::BuildPedLists(void)
}
// Above loop won't work when it's 9, so we need to empty slot 9.
m_nearPeds[9] = nil;
m_numNearPeds--;
m_numNearPeds--;
} else
i++;
}
@ -3078,47 +3078,106 @@ CPed::CheckAroundForPossibleCollisions(void)
}
}
#ifdef PEDS_REPORT_CRIMES_ON_PHONE
void
ReportPhonePickUpCB(CAnimBlendAssociation* assoc, void* arg)
{
CPed* ped = (CPed*)arg;
ped->m_nMoveState = PEDMOVE_STILL;
CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_IDLE_STANCE, 8.0f);
if (assoc->blendAmount > 0.5f && ped) {
CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_PHONE_TALK, 8.0f);
}
}
void
ReportPhonePutDownCB(CAnimBlendAssociation* assoc, void* arg)
{
assoc->flags |= ASSOC_DELETEFADEDOUT;
assoc->blendDelta = -1000.0f;
CPed* ped = (CPed*)arg;
if (ped->m_phoneId != -1 && crimeReporters[ped->m_phoneId] == ped) {
crimeReporters[ped->m_phoneId] = nil;
gPhoneInfo.m_aPhones[ped->m_phoneId].m_nState = PHONE_STATE_FREE;
ped->m_phoneId = -1;
}
if (assoc->blendAmount > 0.5f)
ped->bUpdateAnimHeading = true;
ped->SetWanderPath(CGeneral::GetRandomNumber() & 7);
}
#endif
bool
CPed::MakePhonecall(void)
{
#ifdef TOGGLEABLE_BETA_FEATURES
if (bMakePedsRunToPhonesToReportCrimes)
if (!IsPlayer() && CTimer::GetTimeInMilliseconds() > m_phoneTalkTimer - 7000 && bRunningToPhone) {
#ifdef PEDS_REPORT_CRIMES_ON_PHONE
if (!IsPlayer() && CTimer::GetTimeInMilliseconds() > m_phoneTalkTimer - 7000 && bRunningToPhone) {
FindPlayerPed()->m_pWanted->RegisterCrime_Immediately(m_crimeToReportOnPhone, GetPosition(),
(m_crimeToReportOnPhone == CRIME_POSSESSION_GUN ? (uintptr)m_threatEntity : (uintptr)((CPed*)m_pEventEntity)->m_threatEntity), false);
bRunningToPhone = false;
}
FindPlayerPed()->m_pWanted->RegisterCrime_Immediately(m_crimeToReportOnPhone, GetPosition(),
(m_crimeToReportOnPhone == CRIME_POSSESSION_GUN ? (uintptr)m_threatEntity : (uintptr)m_victimOfPlayerCrime), false);
if (m_crimeToReportOnPhone != CRIME_POSSESSION_GUN)
FindPlayerPed()->m_pWanted->SetWantedLevelNoDrop(1);
bRunningToPhone = false;
}
#endif
if (CTimer::GetTimeInMilliseconds() <= m_phoneTalkTimer)
return false;
SetIdle();
gPhoneInfo.m_aPhones[m_phoneId].m_nState = PHONE_STATE_FREE;
#ifdef TOGGLEABLE_BETA_FEATURES
crimeReporters[m_phoneId] = nil;
#ifdef PEDS_REPORT_CRIMES_ON_PHONE
CAnimBlendAssociation* talkAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_PHONE_TALK);
if (talkAssoc && talkAssoc->blendAmount > 0.5f) {
CAnimBlendAssociation* endAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_PHONE_OUT, 8.0f);
endAssoc->flags &= ~ASSOC_DELETEFADEDOUT;
endAssoc->SetFinishCallback(ReportPhonePutDownCB, this);
}
#endif
SetIdle();
gPhoneInfo.m_aPhones[m_phoneId].m_nState = PHONE_STATE_FREE;
#ifndef PEDS_REPORT_CRIMES_ON_PHONE
m_phoneId = -1;
#endif
// Because SetWanderPath is now done async in ReportPhonePutDownCB
#ifdef PEDS_REPORT_CRIMES_ON_PHONE
return false;
#else
return true;
#endif
}
bool
CPed::FacePhone(void)
{
// FIX: This function was broken since it's left unused early in development.
#ifdef FIX_BUGS
// This function was broken since it's left unused early in development.
#ifdef PEDS_REPORT_CRIMES_ON_PHONE
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;
if (m_facePhoneStart) {
m_lookTimer = 0;
SetLookFlag(phoneDir, true);
m_lookTimer = CTimer::GetTimeInMilliseconds() + 3000;
m_facePhoneStart = false;
}
return turnDone;
if (bIsLooking && TurnBody()) {
ClearLookFlag();
SetIdle();
m_phoneTalkTimer = CTimer::GetTimeInMilliseconds() + 10000;
CAnimBlendAssociation* assoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_PHONE_IN, 4.0f);
assoc->SetFinishCallback(ReportPhonePickUpCB, this);
return true;
}
return false;
#else
float currentRot = RADTODEG(m_fRotationCur);
float phoneDir = CGeneral::GetRadianAngleBetweenPoints(
@ -3165,6 +3224,63 @@ CPed::CheckForDeadPeds(void)
return nil;
}
#ifdef PEDS_REPORT_CRIMES_ON_PHONE
// returns event id, parameter is optional
int32
CPed::CheckForPlayerCrimes(CPed *victim)
{
int i;
float dist;
float mindist = 60.0f;
CPlayerPed *player = FindPlayerPed();
int32 victimRef = (victim ? CPools::GetPedRef(victim) : 0);
int event = -1;
for (i = 0; i < NUMEVENTS; i++) {
if (gaEvent[i].type == EVENT_NULL || gaEvent[i].type > EVENT_CAR_SET_ON_FIRE)
continue;
// those are already handled in game, also DEAD_PED isn't registered alone, most of the time there is SHOOT_PED etc.
if (gaEvent[i].type == EVENT_DEAD_PED || gaEvent[i].type == EVENT_GUNSHOT || gaEvent[i].type == EVENT_EXPLOSION)
continue;
if (victim && gaEvent[i].entityRef != victimRef)
continue;
if (gaEvent[i].criminal != player)
continue;
dist = (GetPosition() - gaEvent[i].posn).Magnitude();
if (dist < mindist) {
mindist = dist;
event = i;
}
}
if (event != -1) {
if (victim) {
m_victimOfPlayerCrime = victim;
} else {
switch (gaEvent[event].entityType) {
case EVENT_ENTITY_PED:
m_victimOfPlayerCrime = CPools::GetPed(gaEvent[event].entityRef);
break;
case EVENT_ENTITY_VEHICLE:
m_victimOfPlayerCrime = CPools::GetVehicle(gaEvent[event].entityRef);
break;
case EVENT_ENTITY_OBJECT:
m_victimOfPlayerCrime = CPools::GetObject(gaEvent[event].entityRef);
break;
default:
break;
}
}
}
return event;
}
#endif
bool
CPed::CheckForExplosions(CVector2D &area)
{
@ -4542,6 +4658,14 @@ CPed::SetEvasiveDive(CPhysical *reason, uint8 onlyRandomJump)
wanted->RegisterCrime_Immediately(CRIME_SPEEDING, GetPosition(), (uintptr)this, false);
}
}
#ifdef PEDS_REPORT_CRIMES_ON_PHONE
else if (reason->IsVehicle()) {
if (veh->pDriver && veh->pDriver->IsPlayer()) {
CWanted* wanted = FindPlayerPed()->m_pWanted;
wanted->RegisterCrime(CRIME_RECKLESS_DRIVING, GetPosition(), (uintptr)this, false);
}
}
#endif
}
void
@ -5384,61 +5508,15 @@ CPed::CollideWithPed(CPed *collideWith)
SetDirectionToWalkAroundObject(collideWith);
}
} else {
#ifdef VC_PED_PORTS
if (FindPlayerPed() != m_pedInObjective
|| m_objective != OBJECTIVE_KILL_CHAR_ANY_MEANS && m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT
|| collideWith == m_pedInObjective) {
#endif
if (weAreMissionChar || m_pedStats->m_fear <= 100 - collideWith->m_pedStats->m_temper
|| (collideWith->IsPlayer() || collideWith->m_nMoveState == PEDMOVE_NONE || collideWith->m_nMoveState == PEDMOVE_STILL) &&
(!collideWith->IsPlayer() || ((CPlayerPed*)collideWith)->m_fMoveSpeed <= 1.0f)) {
SetDirectionToWalkAroundObject(collideWith);
if (!weAreMissionChar)
Say(SOUND_PED_CHAT);
} else {
SetEvasiveStep(collideWith, 2);
}
#ifdef VC_PED_PORTS
} else if (collideWith->m_nMoveState != PEDMOVE_STILL && GetWeapon()->IsTypeMelee()
&& collideWith->m_pedInObjective == m_pedInObjective) {
int colliderIsAtPlayerSafePosID = -1;
int weAreAtPlayerSafePosID = -1;
for (int i = 0; i < ARRAY_SIZE(((CPlayerPed*)m_pedInObjective)->m_pPedAtSafePos); i++) {
CPed *pedAtSafePos = ((CPlayerPed*)m_pedInObjective)->m_pPedAtSafePos[i];
if (pedAtSafePos == this) {
weAreAtPlayerSafePosID = i;
} else if (pedAtSafePos == collideWith) {
colliderIsAtPlayerSafePosID = i;
}
}
bool weAreCloserToTargetThenCollider = false;
if ((GetPosition() - m_vecSeekPos).MagnitudeSqr2D() < (collideWith->GetPosition() - m_vecSeekPos).MagnitudeSqr2D())
weAreCloserToTargetThenCollider = true;
if (weAreAtPlayerSafePosID <= 0 || weAreCloserToTargetThenCollider) {
if (!weAreCloserToTargetThenCollider) {
int time = 300;
SetWaitState(WAITSTATE_CROSS_ROAD_LOOK, &time);
m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + time;
}
} else if (colliderIsAtPlayerSafePosID <= 0) {
if (collideWith->m_pedInObjective == FindPlayerPed()) {
// VC specific
// ((CPlayerPed*)m_pedInObjective)->RemovePedFromMeleeList(this);
int time = 500;
SetWaitState(WAITSTATE_CROSS_ROAD_LOOK, &time);
m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + time;
}
} else {
int time = 300;
SetWaitState(WAITSTATE_CROSS_ROAD_LOOK, &time);
m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + time;
}
} else {
if (weAreMissionChar || m_pedStats->m_fear <= 100 - collideWith->m_pedStats->m_temper
|| (collideWith->IsPlayer() || collideWith->m_nMoveState == PEDMOVE_NONE || collideWith->m_nMoveState == PEDMOVE_STILL) &&
(!collideWith->IsPlayer() || ((CPlayerPed*)collideWith)->m_fMoveSpeed <= 1.0f)) {
SetDirectionToWalkAroundObject(collideWith);
if (!weAreMissionChar)
Say(SOUND_PED_CHAT);
} else {
SetEvasiveStep(collideWith, 2);
}
#endif
}
} else {
if (m_pedStats->m_temper <= m_pedStats->m_fear
@ -5452,12 +5530,20 @@ CPed::CollideWithPed(CPed *collideWith)
} else {
TurnBody();
SetAttack(collideWith);
#ifdef VC_PED_PORTS
m_fRotationCur = 0.3f + m_fRotationCur;
m_fRotationDest = m_fRotationCur;
#endif
}
m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(250, 450);
}
}
} else {
#ifdef VC_PED_PORTS
if (m_pedInObjective && (collideWith == m_pedInObjective || collideWith->m_pedInObjective == m_pedInObjective) && CTimer::GetTimeInMilliseconds() > m_nPedStateTimer) {
#else
if (m_pedInObjective && collideWith == m_pedInObjective && CTimer::GetTimeInMilliseconds() > m_nPedStateTimer) {
#endif
if (heLooksToUs) {
SetEvasiveStep(collideWith, 1);
m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 3000;
@ -5466,7 +5552,11 @@ CPed::CollideWithPed(CPed *collideWith)
if (m_pedStats != collideWith->m_pedStats) {
if (collideWith->m_pedStats->m_fear <= 100 - m_pedStats->m_temper) {
if (collideWith->m_pedStats->m_fear <= 100 - m_pedStats->m_temper
#ifdef VC_PED_PORTS
|| collideWith->IsPlayer() || CTimer::GetTimeInMilliseconds() < m_nPedStateTimer
#endif
) {
if (collideWith->IsPlayer()) {
// He's on our right side
@ -5476,16 +5566,19 @@ CPed::CollideWithPed(CPed *collideWith)
m_fRotationCur += m_headingRate;
} else {
// He's on our right side
if (DotProduct(posDiff, GetRight()) <= 0.0f)
m_fRotationCur -= m_headingRate;
if (DotProduct(posDiff, collideWith->GetRight()) <= 0.0f)
collideWith->m_fRotationCur -= collideWith->m_headingRate;
else
m_fRotationCur += m_headingRate;
collideWith->m_fRotationCur += collideWith->m_headingRate;
}
} else {
SetLookFlag(collideWith, false);
TurnBody();
animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FIGHT_PPUNCH, 8.0f);
animAssoc->flags |= ASSOC_FADEOUTWHENDONE;
#ifdef VC_PED_PORTS
m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 2000;
#endif
if (!heIsMissionChar) {
CVector2D posDiff2D(posDiff);
int direction = collideWith->GetLocalDirection(posDiff2D);
@ -8423,10 +8516,6 @@ CPed::KillPedWithCar(CVehicle *car, float impulse)
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);
#ifdef TOGGLEABLE_BETA_FEATURES
if (bMakePedsRunToPhonesToReportCrimes)
m_ped_flagI40 = true;
#endif
}
ePedPieceTypes pieceToDamage;
@ -8966,7 +9055,11 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg)
return;
if (!ped->EnteringCar()) {
ped->QuitEnteringCar();
#ifdef VC_PED_PORTS
if (ped->m_nPedState != PED_DRIVING)
#endif
ped->QuitEnteringCar();
return;
}
if (ped->m_fHealth == 0.0f) {
@ -10558,7 +10651,11 @@ CPed::PedAnimDoorOpenCB(CAnimBlendAssociation* animAssoc, void* arg)
return;
if (!ped->EnteringCar()) {
ped->QuitEnteringCar();
#ifdef VC_PED_PORTS
if (ped->m_nPedState != PED_DRIVING)
#endif
ped->QuitEnteringCar();
return;
}
@ -11589,16 +11686,21 @@ 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 that's not true, someone made it up.
bool
CPed::RunToReportCrime(eCrimeType crimeToReport)
{
#ifdef TOGGLEABLE_BETA_FEATURES
if (!bMakePedsRunToPhonesToReportCrimes)
return false;
#ifdef PEDS_REPORT_CRIMES_ON_PHONE
if (bRunningToPhone) {
if (!isPhoneAvailable(m_phoneId)) {
m_phoneId = -1;
bIsRunning = false;
ClearSeek(); // clears bRunningToPhone
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)
@ -11612,11 +11714,13 @@ CPed::RunToReportCrime(eCrimeType crimeToReport)
return false;
CPhone *phone = &gPhoneInfo.m_aPhones[phoneId];
#ifndef PEDS_REPORT_CRIMES_ON_PHONE
if (phone->m_nState != PHONE_STATE_FREE)
return false;
#endif
bRunningToPhone = true;
SetSeek(phone->m_pEntity->GetPosition() - phone->m_pEntity->GetForward(), 1.3f); // original: phone.m_vecPos, 0.3f
SetSeek(phone->m_pEntity->GetMatrix() * -phone->m_pEntity->GetForward(), 1.0f); // original: phone.m_vecPos, 0.3f
SetMoveState(PEDMOVE_RUN);
bIsRunning = true; // not there in original
m_phoneId = phoneId;
@ -13672,6 +13776,11 @@ CPed::SetSeekCar(CVehicle *car, uint32 doorNode)
if (m_nPedState == PED_SEEK_CAR)
return;
#ifdef VC_PED_PORTS
if (!CanSetPedState() || m_nPedState == PED_DRIVING)
return;
#endif
SetStoredState();
m_pSeekTarget = car;
m_pSeekTarget->RegisterReference((CEntity**) &m_pSeekTarget);
@ -13789,14 +13898,13 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
if (m_nMoveState == PEDMOVE_NONE || m_nMoveState == PEDMOVE_STILL)
return;
#ifdef TOGGLEABLE_BETA_FEATURES
if (!bMakePedsRunToPhonesToReportCrimes)
#ifndef PEDS_REPORT_CRIMES_ON_PHONE
if (CharCreatedBy != MISSION_CHAR && obj->GetModelIndex() == MI_PHONEBOOTH1) {
bool isRunning = m_nMoveState == PEDMOVE_RUN || m_nMoveState == PEDMOVE_SPRINT;
SetFindPathAndFlee(obj, 5000, !isRunning);
return;
}
#endif
if (CharCreatedBy != MISSION_CHAR && obj->GetModelIndex() == MI_PHONEBOOTH1) {
bool isRunning = m_nMoveState == PEDMOVE_RUN || m_nMoveState == PEDMOVE_SPRINT;
SetFindPathAndFlee(obj, 5000, !isRunning);
return;
}
CVector2D adjustedColMin(objColMin.x - 0.35f, objColMin.y - 0.35f);
CVector2D adjustedColMax(objColMax.x + 0.35f, objColMax.y + 0.35f);

View File

@ -385,9 +385,8 @@ public:
#ifdef PED_SKIN
uint32 bDontAcceptIKLookAts : 1; // TODO: find uses of this
#endif
// our own flags
uint32 m_ped_flagI40 : 1; // bMakePedsRunToPhonesToReportCrimes makes use of this as runover by car indicator
uint32 m_ped_flagI80 : 1; // KANGAROO_CHEAT define makes use of this as cheat toggle
uint32 m_ped_flagI40 : 1;
uint32 m_ped_flagI80 : 1; // originally unused, KANGAROO_CHEAT define makes use of this as cheat toggle
uint8 CharCreatedBy;
eObjective m_objective;
@ -454,6 +453,10 @@ public:
float m_distanceToCountSeekDone;
bool bRunningToPhone;
int16 m_phoneId;
#ifdef PEDS_REPORT_CRIMES_ON_PHONE
bool m_facePhoneStart;
CEntity *m_victimOfPlayerCrime;
#endif
eCrimeType m_crimeToReportOnPhone;
uint32 m_phoneTalkTimer;
CAccident *m_lastAccident;
@ -588,6 +591,9 @@ public:
bool MakePhonecall(void);
bool FacePhone(void);
CPed *CheckForDeadPeds(void);
#ifdef PEDS_REPORT_CRIMES_ON_PHONE
int32 CheckForPlayerCrimes(CPed *victim = nil);
#endif
bool CheckForExplosions(CVector2D &area);
CPed *CheckForGunShots(void);
PointBlankNecessity CheckForPointBlankPeds(CPed*);
@ -872,9 +878,8 @@ public:
static bool bPedCheat3;
static CVector2D ms_vec2DFleePosition;
#ifdef TOGGLEABLE_BETA_FEATURES
#ifdef DEBUGMENU
static bool bPopHeadsOnHeadshot;
static bool bMakePedsRunToPhonesToReportCrimes;
#endif
#ifndef MASTER