summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreray orçunus <erayorcunus@gmail.com>2019-08-10 18:15:22 +0300
committereray orçunus <erayorcunus@gmail.com>2019-08-11 20:31:36 +0300
commitbe1c7b0761c2de0362a47ecfff616a8931b54805 (patch)
tree2f0c6d7eac06333b4f04eb3002700e4c3d067f34
parent0bd681abc514d5a3627edea40b24347696ac8908 (diff)
P.e.d.s. and fixes
-rw-r--r--src/core/General.h15
-rw-r--r--src/core/re3.cpp16
-rw-r--r--src/peds/Ped.cpp649
-rw-r--r--src/peds/Ped.h31
-rw-r--r--src/vehicles/Automobile.h18
5 files changed, 627 insertions, 102 deletions
diff --git a/src/core/General.h b/src/core/General.h
index fe277689..12f781d4 100644
--- a/src/core/General.h
+++ b/src/core/General.h
@@ -96,6 +96,21 @@ public:
}
}
+ // should return direction in 0-8 range. fits perfectly to peds' path directions.
+ static int CGeneral::GetNodeHeadingFromVector(float x, float y)
+ {
+ float angle = CGeneral::GetRadianAngleBetweenPoints(x, y, 0.0f, 0.0f);
+ if (angle < 0.0f)
+ angle += TWOPI;
+
+ angle = DEGTORAD(22.5f) + TWOPI - angle;
+
+ if (angle >= TWOPI)
+ angle -= TWOPI;
+
+ return (int)floorf(angle / DEGTORAD(45.0f));
+ }
+
// not too sure about all these...
static uint16 GetRandomNumber(void)
{ return myrand() & MYRAND_MAX; }
diff --git a/src/core/re3.cpp b/src/core/re3.cpp
index 9fe53579..dc501075 100644
--- a/src/core/re3.cpp
+++ b/src/core/re3.cpp
@@ -140,6 +140,20 @@ SpawnCar(int id)
}
static void
+LetThemFollowYou(void) {
+ CPed* player = (CPed*) FindPlayerPed();
+ for (int i = 0; i < player->m_numNearPeds; i++) {
+
+ CPed* nearPed = player->m_nearPeds[i];
+ if (nearPed && !nearPed->IsPlayer()) {
+ nearPed->SetObjective(OBJECTIVE_FOLLOW_PED_IN_FORMATION, (void*)player);
+ nearPed->m_pedFormation = rand() & 7;
+ nearPed->bScriptObjectiveCompleted = false;
+ }
+ }
+}
+
+static void
FixCar(void)
{
CVehicle *veh = FindPlayerVehicle();
@@ -335,6 +349,8 @@ DebugMenuPopulate(void)
DebugMenuAddVarBool8("Debug", "Don't render Peds", (int8*)&gbDontRenderPeds, nil);
DebugMenuAddVarBool8("Debug", "Don't render Vehicles", (int8*)&gbDontRenderVehicles, nil);
DebugMenuAddVarBool8("Debug", "Don't render Objects", (int8*)&gbDontRenderObjects, nil);
+
+ DebugMenuAddCmd("Debug", "Make peds around you follow you", LetThemFollowYou);
#ifndef FINAL
DebugMenuAddVarBool8("Debug", "Toggle unused fight feature", (int8*)&CPed::bUnusedFightThingOnPlayer, nil);
#endif
diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp
index f349ae6d..dac17f30 100644
--- a/src/peds/Ped.cpp
+++ b/src/peds/Ped.cpp
@@ -45,7 +45,6 @@ WRAPPER void CPed::SetMoveAnim(void) { EAXJMP(0x4C5A40); }
WRAPPER void CPed::SetFollowRoute(int16, int16) { EAXJMP(0x4DD690); }
WRAPPER void CPed::SetDuck(uint32) { EAXJMP(0x4E4920); }
WRAPPER void CPed::RegisterThreatWithGangPeds(CEntity*) { EAXJMP(0x4E3870); }
-WRAPPER bool CPed::Seek(void) { EAXJMP(0x4D1640); }
WRAPPER void CPed::SetFollowPath(CVector) { EAXJMP(0x4D2EA0); }
WRAPPER void CPed::RemoveInCarAnims(void) { EAXJMP(0x4E4E20); }
WRAPPER void CPed::StartFightDefend(uint8, uint8, uint8) { EAXJMP(0x4E7780); }
@@ -58,19 +57,22 @@ bool &CPed::bNastyLimbsCheat = *(bool*)0x95CD44;
bool &CPed::bPedCheat2 = *(bool*)0x95CD5A;
bool &CPed::bPedCheat3 = *(bool*)0x95CD59;
-CColPoint &CPed::ms_tempColPoint = *(CColPoint*)0x62DB14;
+CColPoint &CPed::aTempPedColPts = *(CColPoint*)0x62DB14;
-// TODO: PedAudioData should be hardcoded into exe, and it isn't reversed yet.
-CPedAudioData (&CPed::PedAudioData)[38] = *(CPedAudioData(*)[38]) * (uintptr*)0x5F94C4;
+// TODO: CommentWaitTime should be hardcoded into exe, and it isn't reversed yet.
+CPedAudioData (&CPed::CommentWaitTime)[38] = *(CPedAudioData(*)[38]) * (uintptr*)0x5F94C4;
uint16 &CPed::nPlayerInComboMove = *(uint16*)0x95CC58;
FightMove (&CPed::tFightMoves)[24] = * (FightMove(*)[24]) * (uintptr*)0x5F9844;
-uint16 &CPed::distanceMultToCountPedNear = *(uint16*)0x5F8C98;
+uint16 &CPed::nThreatReactionRangeMultiplier = *(uint16*)0x5F8C98;
-CVector &CPed::offsetToOpenRegularCarDoor = *(CVector*)0x62E030;
-CVector &CPed::offsetToOpenLowCarDoor = *(CVector*)0x62E03C;
-CVector &CPed::offsetToOpenVanDoor = *(CVector*)0x62E048;
+CVector &CPed::vecPedCarDoorAnimOffset = *(CVector*)0x62E030;
+CVector &CPed::vecPedCarDoorLoAnimOffset = *(CVector*)0x62E03C;
+CVector &CPed::vecPedVanRearDoorAnimOffset = *(CVector*)0x62E048;
+CVector &CPed::vecPedQuickDraggedOutCarAnimOffset = *(CVector*)0x62E06C;
+
+CVector2D &CPed::ms_vec2DFleePosition = *(CVector2D*)0x6EDF70;
#ifndef FINAL
bool CPed::bUnusedFightThingOnPlayer = false;
@@ -290,7 +292,6 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
m_type = ENTITY_TYPE_PED;
bPedPhysics = true;
bUseCollisionRecords = true;
-// m_status = STATUS_SIMPLE;
m_vecAnimMoveDelta.x = 0.0f;
m_vecAnimMoveDelta.y = 0.0f;
@@ -314,7 +315,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
m_vecOffsetSeek.y = 0.0f;
m_vecOffsetSeek.z = 0.0f;
m_pedFormation = 0;
- m_lastThreatTimer = 0;
+ m_collidingThingTimer = 0;
m_nPedStateTimer = 0;
m_actionX = 0;
m_actionY = 0;
@@ -338,9 +339,9 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
m_pCurrentPhysSurface = nil;
m_vecOffsetFromPhysSurface = CVector(0.0f, 0.0f, 0.0f);
m_pSeekTarget = nil;
- m_vecSeekVehicle = CVector(0.0f, 0.0f, 0.0f);
+ m_vecSeekPos = CVector(0.0f, 0.0f, 0.0f);
m_wepSkills = 0;
- field_318 = 1.0f;
+ m_distanceToCountSeekDone = 1.0f;
bRunningToPhone = false;
m_phoneId = -1;
m_lastAccident = 0;
@@ -366,8 +367,8 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
m_nPathNodes = 0;
m_nCurPathNode = 0;
m_nPathState = 0;
- m_pNextPathNode = nil;
m_pLastPathNode = nil;
+ m_pNextPathNode = nil;
m_routeLastPoint = -1;
m_routePoints = 0;
m_routePos = 0;
@@ -393,7 +394,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
bIsTalking = false;
bIsInTheAir = false;
bIsLanding = false;
- m_ped_flagB20 = false;
+ bIsRunning = false;
m_ped_flagB40 = false;
m_ped_flagB80 = false;
@@ -1477,13 +1478,13 @@ CPed::GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float seatP
vehModel = (CVehicleModelInfo*) CModelInfo::GetModelInfo(veh->m_modelIndex);
if (veh->bIsVan && (component == CAR_DOOR_LR || component == CAR_DOOR_RR)) {
seatOffset = 0.0f;
- vehDoorOffset = offsetToOpenVanDoor;
+ vehDoorOffset = vecPedVanRearDoorAnimOffset;
} else {
seatOffset = veh->pHandling->fSeatOffsetDistance * seatPosMult;
if (veh->bLowVehicle) {
- vehDoorOffset = offsetToOpenLowCarDoor;
+ vehDoorOffset = vecPedCarDoorLoAnimOffset;
} else {
- vehDoorOffset = offsetToOpenRegularCarDoor;
+ vehDoorOffset = vecPedCarDoorAnimOffset;
}
}
@@ -1544,12 +1545,12 @@ CPed::GetPositionToOpenCarDoor(CVehicle *veh, uint32 component)
CVector localVehDoorOffset;
if (veh->bIsVan && (component == VEHICLE_ENTER_REAR_LEFT || component == VEHICLE_ENTER_REAR_RIGHT)) {
- localVehDoorOffset = offsetToOpenVanDoor;
+ localVehDoorOffset = vecPedVanRearDoorAnimOffset;
} else {
if (veh->bIsLow) {
- localVehDoorOffset = offsetToOpenLowCarDoor;
+ localVehDoorOffset = vecPedCarDoorLoAnimOffset;
} else {
- localVehDoorOffset = offsetToOpenRegularCarDoor;
+ localVehDoorOffset = vecPedCarDoorAnimOffset;
}
}
@@ -1993,8 +1994,8 @@ CPed::SortPeds(CPed **list, int min, int max)
void
CPed::BuildPedLists(void)
{
- static CPed *unsortedNearPeds[10];
- uint16 nextNearPedSlot = 0;
+ static CPed *gapTempPedList[10]; // unsorted
+ static int16 gnNumTempPedList;
if ((CTimer::GetFrameCounter() + (m_randomSeed % 256)) % 16) {
@@ -2026,6 +2027,7 @@ CPed::BuildPedLists(void)
(centre.y - 20.0f) * 0.025f + 50.0f,
(centre.x + 20.0f) * 0.025f + 50.0f,
(centre.y + 20.0f) * 0.025f + 50.0f);
+ gnNumTempPedList = 0;
for(int y = rect.top; y <= rect.bottom; y++) {
for(int x = rect.left; x <= rect.right; x++) {
@@ -2033,19 +2035,18 @@ CPed::BuildPedLists(void)
CPed *ped = (CPed*)pedPtrNode->item;
if (ped != this && !ped->bInVehicle) {
float dist = (ped->GetPosition() - GetPosition()).Magnitude2D();
- if (distanceMultToCountPedNear * 30.0f > dist)
- {
- unsortedNearPeds[nextNearPedSlot] = ped;
- nextNearPedSlot++;
+ if (nThreatReactionRangeMultiplier * 30.0f > dist) {
+ gapTempPedList[gnNumTempPedList] = ped;
+ gnNumTempPedList++;
}
}
}
}
}
- unsortedNearPeds[nextNearPedSlot] = nil;
- SortPeds(unsortedNearPeds, 0, nextNearPedSlot - 1);
+ gapTempPedList[gnNumTempPedList] = nil;
+ SortPeds(gapTempPedList, 0, gnNumTempPedList - 1);
for (m_numNearPeds = 0; m_numNearPeds < 10; m_numNearPeds++) {
- CPed *ped = unsortedNearPeds[m_numNearPeds];
+ CPed *ped = gapTempPedList[m_numNearPeds];
if (!ped)
break;
@@ -2489,9 +2490,9 @@ CPed::SetObjective(eObjective newObj, void *entity)
case OBJECTIVE_KILL_CHAR_ON_FOOT:
case OBJECTIVE_KILL_CHAR_ANY_MEANS:
case OBJECTIVE_MUG_CHAR:
- m_pLastPathNode = nil;
+ m_pNextPathNode = nil;
bIsFleeing = false;
- m_vecSeekVehicle = CVector(0.0f, 0.0f, 0.0f);
+ m_vecSeekPos = CVector(0.0f, 0.0f, 0.0f);
m_pedInObjective = (CPed*)entity;
m_pedInObjective->RegisterReference((CEntity**)&m_pedInObjective);
m_pLookTarget = (CEntity*)entity;
@@ -2501,7 +2502,7 @@ CPed::SetObjective(eObjective newObj, void *entity)
case OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS:
case OBJECTIVE_GOTO_CHAR_ON_FOOT:
case OBJECTIVE_FIGHT_CHAR:
- m_vecSeekVehicle = CVector(0.0f, 0.0f, 0.0f);
+ m_vecSeekPos = CVector(0.0f, 0.0f, 0.0f);
m_pedInObjective = (CPed*)entity;
m_pedInObjective->RegisterReference((CEntity**)&m_pedInObjective);
break;
@@ -2542,7 +2543,7 @@ CPed::SetObjective(eObjective newObj, void *entity)
m_carInObjective->RegisterReference((CEntity**)&m_carInObjective);
m_pSeekTarget = m_carInObjective;
m_pSeekTarget->RegisterReference((CEntity**)&m_pSeekTarget);
- m_vecSeekVehicle = CVector(0.0f, 0.0f, 0.0f);
+ m_vecSeekPos = CVector(0.0f, 0.0f, 0.0f);
if (newObj == OBJECTIVE_SOLICIT) {
m_objectiveTimer = CTimer::GetTimeInMilliseconds() + 10000;
} else if (m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER && CharCreatedBy == MISSION_CHAR &&
@@ -3131,7 +3132,7 @@ CPed::ClearAll(void)
m_nPedState = PED_NONE;
m_nMoveState = PEDMOVE_NONE;
m_pSeekTarget = nil;
- m_vecSeekVehicle = CVector(0.0f, 0.0f, 0.0f);
+ m_vecSeekPos = CVector(0.0f, 0.0f, 0.0f);
m_fleeFromPosX = 0.0f;
m_fleeFromPosY = 0.0f;
m_fleeFrom = nil;
@@ -3715,7 +3716,7 @@ CPed::SetGetUp(void)
&& ((CTimer::GetFrameCounter() + m_randomSeed % 256 + 5) % 8
|| CCollision::ProcessColModels(GetMatrix(), *CModelInfo::GetModelInfo(m_modelIndex)->GetColModel(),
collidingVeh->GetMatrix(), *CModelInfo::GetModelInfo(collidingVeh->m_modelIndex)->GetColModel(),
- &ms_tempColPoint, nil, nil) > 0)) {
+ &aTempPedColPts, nil, nil) > 0)) {
bGetUpAnimStarted = false;
if (IsPlayer())
@@ -3856,11 +3857,11 @@ CPed::SetWanderPath(int8 pathStateDest)
if (pathStateDest == 0)
pathStateDest = CGeneral::GetRandomNumberInRange(1, 7);
- ThePaths.FindNextNodeWandering(PATH_PED, GetPosition(), &m_pNextPathNode, &m_pLastPathNode,
+ ThePaths.FindNextNodeWandering(PATH_PED, GetPosition(), &m_pLastPathNode, &m_pNextPathNode,
m_nPathState, &nextPathState);
// Circular loop until we find a node for current m_nPathState
- while (!m_pLastPathNode) {
+ while (!m_pNextPathNode) {
m_nPathState = (m_nPathState+1) % 8;
// We're at where we started and couldn't find any node
@@ -3869,7 +3870,7 @@ CPed::SetWanderPath(int8 pathStateDest)
SetIdle();
return false;
}
- ThePaths.FindNextNodeWandering(PATH_PED, GetPosition(), &m_pNextPathNode, &m_pLastPathNode,
+ ThePaths.FindNextNodeWandering(PATH_PED, GetPosition(), &m_pLastPathNode, &m_pNextPathNode,
m_nPathState, &nextPathState);
}
@@ -3877,7 +3878,7 @@ CPed::SetWanderPath(int8 pathStateDest)
m_nPathState = nextPathState;
m_nPedState = PED_WANDER_PATH;
SetMoveState(PEDMOVE_WALK);
- m_ped_flagB20 = false;
+ bIsRunning = false;
return true;
}
} else {
@@ -3962,10 +3963,10 @@ CPed::RestorePreviousState(void)
break;
case PED_WANDER_PATH:
m_nPedState = PED_WANDER_PATH;
- m_ped_flagB20 = false;
+ bIsRunning = false;
if (!m_ped_flagC80) {
- if (m_pLastPathNode) {
- CVector diff = m_pLastPathNode->pos - GetPosition();
+ if (m_pNextPathNode) {
+ CVector diff = m_pNextPathNode->pos - GetPosition();
if (diff.MagnitudeSqr() < 49.0f) {
SetMoveState(PEDMOVE_WALK);
break;
@@ -4385,7 +4386,7 @@ CPed::SetAttack(CEntity* victim)
}
animAssoc->SetRun();
- if (animAssoc->currentTime != animAssoc->hierarchy->totalLength)
+ if (animAssoc->currentTime == animAssoc->hierarchy->totalLength)
animAssoc->SetCurrentTime(0.0f);
animAssoc->SetFinishCallback(FinishedAttackCB, this);
@@ -4814,7 +4815,7 @@ CPed::SetFlee(CVector2D &from, int time)
}
bIsFleeing = true;
- m_pLastPathNode = nil;
+ m_pNextPathNode = nil;
m_fleeTimer = CTimer::GetTimeInMilliseconds() + time;
float angleToFace = CGeneral::GetRadianAngleBetweenPoints(
@@ -5073,9 +5074,9 @@ CPed::Say(uint16 audio)
if (audioToPlay < m_queuedSound) {
if (audioToPlay != m_lastQueuedSound || audioToPlay == SOUND_PED_DEATH
- || PedAudioData[audioToPlay - SOUND_PED_DEATH].m_nOverrideMaxRandomDelayTime
+ || CommentWaitTime[audioToPlay - SOUND_PED_DEATH].m_nOverrideMaxRandomDelayTime
+ m_lastSoundStart
- + (uint32) CGeneral::GetRandomNumberInRange(0, PedAudioData[audioToPlay - SOUND_PED_DEATH].m_nMaxRandomDelayTime) <= CTimer::GetTimeInMilliseconds()) {
+ + (uint32) CGeneral::GetRandomNumberInRange(0, CommentWaitTime[audioToPlay - SOUND_PED_DEATH].m_nMaxRandomDelayTime) <= CTimer::GetTimeInMilliseconds()) {
m_queuedSound = audioToPlay;
}
}
@@ -5111,10 +5112,10 @@ CPed::CollideWithPed(CPed *collideWith)
if (collideWith->m_nMoveState != PEDMOVE_STILL
&& (!collideWith->IsPlayer() || collideWith->IsPlayer() && CPad::GetPad(0)->ArePlayerControlsDisabled())) {
- float weAndCarDist = (GetPosition() - m_vecSeekVehicle).MagnitudeSqr2D();
- float heAndCarDist = (collideWith->GetPosition() - m_vecSeekVehicle).MagnitudeSqr2D();
+ float seekPosDist = (GetPosition() - m_vecSeekPos).MagnitudeSqr2D();
+ float heAndSeekPosDist = (collideWith->GetPosition() - m_vecSeekPos).MagnitudeSqr2D();
- if (weAndCarDist <= heAndCarDist) {
+ if (seekPosDist <= heAndSeekPosDist) {
waitTime = 1000;
collideWith->SetWaitState(WAITSTATE_CROSS_ROAD_LOOK, &waitTime);
collideWith->m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + waitTime;
@@ -5286,7 +5287,7 @@ CPed::CollideWithPed(CPed *collideWith)
SetFlee(collideWith, 5000);
bIsFleeing = true;
- m_pLastPathNode = nil;
+ m_pNextPathNode = nil;
if (!doWeRun)
SetMoveState(PEDMOVE_WALK);
}
@@ -5477,7 +5478,7 @@ CPed::SetDead(void)
}
void
-CPed::SetSeek(CEntity *seeking, float unk)
+CPed::SetSeek(CEntity *seeking, float distanceToCountDone)
{
if (!IsPedInControl())
return;
@@ -5492,17 +5493,17 @@ CPed::SetSeek(CEntity *seeking, float unk)
SetStoredState();
m_nPedState = PED_SEEK_ENTITY;
- field_318 = unk;
+ m_distanceToCountSeekDone = distanceToCountDone;
m_pSeekTarget = seeking;
m_pSeekTarget->RegisterReference((CEntity **) &m_pSeekTarget);
SetMoveState(PEDMOVE_STILL);
}
void
-CPed::SetSeek(CVector pos, float unk)
+CPed::SetSeek(CVector pos, float distanceToCountDone)
{
if (!IsPedInControl()
- || (m_nPedState == PED_SEEK_POS && m_vecSeekVehicle.x != pos.x && m_vecSeekVehicle.y != pos.y))
+ || (m_nPedState == PED_SEEK_POS && m_vecSeekPos.x == pos.x && m_vecSeekPos.y == pos.y))
return;
if (GetWeapon()->m_eWeaponType == WEAPONTYPE_M16
@@ -5517,8 +5518,8 @@ CPed::SetSeek(CVector pos, float unk)
SetStoredState();
m_nPedState = PED_SEEK_POS;
- field_318 = unk;
- m_vecSeekVehicle = pos;
+ m_distanceToCountSeekDone = distanceToCountDone;
+ m_vecSeekPos = pos;
}
void
@@ -5662,7 +5663,7 @@ CPed::DuckAndCover(void)
&& CWorld::GetIsLineOfSightClear(GetPosition(), duckPos, 1, 0, 0, 1, 0, 0, 0)) {
SetSeek(duckPos, 1.0f);
m_headingRate = 15.0f;
- m_ped_flagB20 = true;
+ bIsRunning = true;
bDuckAndCover = true;
justDucked = true;
m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + 500;
@@ -5689,7 +5690,7 @@ CPed::DuckAndCover(void)
bKindaStayInSamePlace = true;
bDuckAndCover = false;
- m_vecSeekVehicle = CVector(0.0f, 0.0f, 0.0f);
+ m_vecSeekPos = CVector(0.0f, 0.0f, 0.0f);
if (m_pSeekTarget && m_pSeekTarget->IsVehicle())
((CVehicle*)m_pSeekTarget)->m_numPedsUseItAsCover++;
@@ -5769,7 +5770,7 @@ CPed::GetNearestTrainPedPosition(CVehicle *train, CVector &enterPos)
CVector leftEntryPos, rightEntryPos, midEntryPos;
float distLeftEntry, distRightEntry, distMidEntry;
- // enterStepOffset = offsetToOpenRegularCarDoor;
+ // enterStepOffset = vecPedCarDoorAnimOffset;
enterStepOffset = CVector(1.5f, 0.0f, 0.0f);
if (train->pPassengers[TRAIN_POS_LEFT_ENTRY]) {
@@ -6240,7 +6241,7 @@ CPed::Fight(void)
animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, tFightMoves[m_lastFightMove].animId, 4.0f);
animAssoc->SetFinishCallback(FinishFightMoveCB, this);
- if (m_fightUnk2 == -2 && animAssoc->currentTime == 0.0f) {
+ if (m_fightUnk2 == -2 && animAssoc->currentTime != 0.0f) {
animAssoc->SetCurrentTime(0.0f);
animAssoc->SetRun();
}
@@ -6294,16 +6295,16 @@ SelectClosestNodeForSeek(CPed *ped, CPathNode *node, CVector2D closeDist, CVecto
CPathNode *testNode = &ThePaths.m_pathNodes[ThePaths.m_connections[i + node->firstLink]];
if (testNode && testNode != closeNode && testNode != closeNode2) {
- CVector2D posDiff(ped->m_vecSeekVehicle - testNode->pos);
+ CVector2D posDiff(ped->m_vecSeekPos - testNode->pos);
float dist = posDiff.MagnitudeSqr();
if (farDist.MagnitudeSqr() > dist) {
if (closeDist.MagnitudeSqr() <= dist) {
- ped->m_pLastPathNode = closeNode;
+ ped->m_pNextPathNode = closeNode;
closeDist = posDiff;
} else {
- ped->m_pLastPathNode = (closeNode2 ? closeNode2 : testNode);
+ ped->m_pNextPathNode = (closeNode2 ? closeNode2 : testNode);
farDist = posDiff;
}
}
@@ -6317,37 +6318,37 @@ SelectClosestNodeForSeek(CPed *ped, CPathNode *node, CVector2D closeDist, CVecto
bool
CPed::FindBestCoordsFromNodes(CVector unused, CVector *bestCoords)
{
- if (m_pLastPathNode || !bIsFleeing)
+ if (m_pNextPathNode || !bIsFleeing)
return false;
CVector ourPos = GetPosition();
int closestNodeId = ThePaths.FindNodeClosestToCoors(GetPosition(), 1, 999999.9f, false, false);
- CVector seekObjPos = m_vecSeekVehicle;
+ CVector seekObjPos = m_vecSeekPos;
seekObjPos.z += 1.0f;
if (CWorld::GetIsLineOfSightClear(ourPos, seekObjPos, true, false, false, true, false, false, false))
return false;
- m_pLastPathNode = nil;
+ m_pNextPathNode = nil;
- CVector2D seekObjDist (m_vecSeekVehicle - ourPos);
+ CVector2D seekPosDist (m_vecSeekPos - ourPos);
CPathNode *closestNode = &ThePaths.m_pathNodes[closestNodeId];
- CVector2D closeDist(m_vecSeekVehicle - closestNode->pos);
+ CVector2D closeDist(m_vecSeekPos - closestNode->pos);
- SelectClosestNodeForSeek(this, closestNode, closeDist, seekObjDist, closestNode, nil);
+ SelectClosestNodeForSeek(this, closestNode, closeDist, seekPosDist, closestNode, nil);
// Above function decided that going to the next node is more logical than seeking the object.
- if (m_pLastPathNode) {
+ if (m_pNextPathNode) {
- CVector pathToNextNode = m_pLastPathNode->pos - ourPos;
- if (pathToNextNode.MagnitudeSqr2D() < seekObjDist.MagnitudeSqr()) {
- *bestCoords = m_pLastPathNode->pos;
+ CVector pathToNextNode = m_pNextPathNode->pos - ourPos;
+ if (pathToNextNode.MagnitudeSqr2D() < seekPosDist.MagnitudeSqr()) {
+ *bestCoords = m_pNextPathNode->pos;
return true;
}
- m_pLastPathNode = nil;
+ m_pNextPathNode = nil;
}
return false;
@@ -6449,11 +6450,11 @@ CPed::FinishLaunchCB(CAnimBlendAssociation *animAssoc, void *arg)
if (TheCamera.Cams[0].Using3rdPersonMouseCam()) {
float fpsAngle = ped->WorkOutHeadingForMovingFirstPerson(ped->m_fRotationCur);
- ped->m_vecMoveSpeed.x = -velocityFromAnim * sin(fpsAngle);
- ped->m_vecMoveSpeed.y = velocityFromAnim * cos(fpsAngle);
+ ped->m_vecMoveSpeed.x = -velocityFromAnim * Sin(fpsAngle);
+ ped->m_vecMoveSpeed.y = velocityFromAnim * Cos(fpsAngle);
} else {
- ped->m_vecMoveSpeed.x = -velocityFromAnim * sin(ped->m_fRotationCur);
- ped->m_vecMoveSpeed.y = velocityFromAnim * cos(ped->m_fRotationCur);
+ ped->m_vecMoveSpeed.x = -velocityFromAnim * Sin(ped->m_fRotationCur);
+ ped->m_vecMoveSpeed.y = velocityFromAnim * Cos(ped->m_fRotationCur);
}
}
@@ -6574,8 +6575,8 @@ CPed::Wait(void)
case WAITSTATE_HITWALL:
if (CTimer::GetTimeInMilliseconds() <= m_nWaitTimer) {
- if (m_lastThreatTimer > CTimer::GetTimeInMilliseconds()) {
- m_lastThreatTimer = CTimer::GetTimeInMilliseconds() + 2500;
+ if (m_collidingThingTimer > CTimer::GetTimeInMilliseconds()) {
+ m_collidingThingTimer = CTimer::GetTimeInMilliseconds() + 2500;
}
} else {
m_nWaitState = WAITSTATE_FALSE;
@@ -6591,8 +6592,8 @@ CPed::Wait(void)
ClearInvestigateEvent();
}
- if (m_lastThreatTimer > CTimer::GetTimeInMilliseconds()) {
- m_lastThreatTimer = CTimer::GetTimeInMilliseconds() + 2500;
+ if (m_collidingThingTimer > CTimer::GetTimeInMilliseconds()) {
+ m_collidingThingTimer = CTimer::GetTimeInMilliseconds() + 2500;
}
break;
@@ -6659,7 +6660,7 @@ CPed::Wait(void)
break;
}
- animAssoc = CAnimManager::BlendAnimation(GetClump(), m_animGroup, animToRun, 4.0f);
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animToRun, 4.0f);
if (animToRun == ANIM_TURN_180)
animAssoc->SetFinishCallback(FinishedWaitCB, this);
@@ -6710,7 +6711,7 @@ CPed::Wait(void)
if (m_nPedState == PED_FLEE_ENTITY || m_nPedState == PED_FLEE_POS) {
bIsFleeing = true;
- m_pLastPathNode = nil;
+ m_pNextPathNode = nil;
}
if (m_nMoveState != PEDMOVE_RUN)
SetMoveState(PEDMOVE_WALK);
@@ -6728,7 +6729,7 @@ CPed::Wait(void)
if (m_nPedState == PED_FLEE_ENTITY || m_nPedState == PED_FLEE_POS)
{
bIsFleeing = true;
- m_pLastPathNode = nil;
+ m_pNextPathNode = nil;
}
SetMoveState(PEDMOVE_RUN);
Say(SOUND_PED_FLEE_RUN);
@@ -6789,6 +6790,478 @@ CPed::Wait(void)
RestoreHeadingRate();
}
+bool
+CPed::Seek(void)
+{
+ float distanceToCountItDone = m_distanceToCountSeekDone;
+ eMoveState nextMove = PEDMOVE_NONE;
+
+ if (m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER) {
+
+ if (m_nPedState != PED_EXIT_TRAIN && m_nPedState != PED_ENTER_TRAIN && m_nPedState != PED_SEEK_IN_BOAT &&
+ m_objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER && m_objective != OBJECTIVE_SOLICIT && !bDuckAndCover) {
+
+ if ((!m_pedInObjective || !m_pedInObjective->bInVehicle)
+ && !((CTimer::GetFrameCounter() + (m_randomSeed % 256) + 17) & 7)) {
+
+ CEntity *foundEnt = CWorld::TestSphereAgainstWorld(m_vecSeekPos, 0.4f, nil,
+ false, true, false, false, false, false);
+
+ if (foundEnt) {
+ if (!foundEnt->IsVehicle() || ((CVehicle*)foundEnt)->m_vehType == VEHICLE_TYPE_CAR) {
+ distanceToCountItDone = 2.5f;
+ } else {
+ CVehicleModelInfo *vehModel = (CVehicleModelInfo*) CModelInfo::GetModelInfo(foundEnt->m_modelIndex);
+ float yLength = vehModel->GetColModel()->boundingBox.max.y
+ - vehModel->GetColModel()->boundingBox.min.y;
+ distanceToCountItDone = yLength * 0.55f;
+ }
+ }
+ }
+ }
+ }
+
+ if (!m_pSeekTarget && m_nPedState == PED_SEEK_ENTITY)
+ ClearSeek();
+
+ float seekPosDist = (m_vecSeekPos - GetPosition()).Magnitude2D();
+ if (seekPosDist < 2.0f || m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT) {
+
+ if (m_objective == OBJECTIVE_FOLLOW_PED_IN_FORMATION) {
+
+ if (m_pedInObjective->m_nMoveState != PEDMOVE_STILL)
+ nextMove = m_pedInObjective->m_nMoveState;
+ } else
+ nextMove = PEDMOVE_WALK;
+
+ } else if (m_objective != OBJECTIVE_FOLLOW_PED_IN_FORMATION) {
+
+ if (m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT || m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS || m_objective == OBJECTIVE_RUN_TO_AREA || bIsRunning)
+ nextMove = PEDMOVE_RUN;
+ else
+ nextMove = PEDMOVE_WALK;
+
+ } else if (seekPosDist <= 2.0f) {
+
+ if (m_pedInObjective->m_nMoveState != PEDMOVE_STILL)
+ nextMove = m_pedInObjective->m_nMoveState;
+
+ } else {
+ nextMove = PEDMOVE_RUN;
+ }
+
+ if (m_nPedState == PED_SEEK_ENTITY) {
+ if (m_pSeekTarget->IsPed()) {
+ if (((CPed*)m_pSeekTarget)->bInVehicle)
+ distanceToCountItDone += 2.0f;
+ }
+ }
+
+ if (seekPosDist >= distanceToCountItDone) {
+ if (bIsRunning)
+ nextMove = PEDMOVE_RUN;
+
+ if (CTimer::GetTimeInMilliseconds() <= m_nPedStateTimer) {
+
+ if (m_actionX != 0.0f && m_actionY != 0.0f) {
+
+ m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(
+ m_actionX, m_actionY,
+ GetPosition().x, GetPosition().y);
+
+ float neededTurn = Abs(m_fRotationDest - m_fRotationCur);
+
+ if (neededTurn > PI)
+ neededTurn = TWOPI - neededTurn;
+
+ if (neededTurn > HALFPI) {
+ if (seekPosDist >= 1.0f) {
+ if (seekPosDist < 2.0f) {
+ if (bIsRunning)
+ nextMove = PEDMOVE_RUN;
+ else
+ nextMove = PEDMOVE_WALK;
+ }
+ } else {
+ nextMove = PEDMOVE_STILL;
+ }
+ }
+
+ CVector2D moveDist(GetPosition().x - m_actionX, GetPosition().y - m_actionY);
+ if (moveDist.Magnitude() < 0.5f) {
+ m_nPedStateTimer = 0;
+ m_actionX = 0;
+ m_actionY = 0;
+ }
+ }
+ } else {
+ m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(
+ m_vecSeekPos.x, m_vecSeekPos.y,
+ GetPosition().x, GetPosition().y);
+
+ float neededTurn = Abs(m_fRotationDest - m_fRotationCur);
+
+ if (neededTurn > PI)
+ neededTurn = TWOPI - neededTurn;
+
+ if (neededTurn > HALFPI) {
+ if (seekPosDist >= 1.0 && neededTurn <= DEGTORAD(135.0f)) {
+ if (seekPosDist < 2.0f)
+ nextMove = PEDMOVE_WALK;
+ } else {
+ nextMove = PEDMOVE_STILL;
+ }
+ }
+ }
+
+ if (((m_nPedState == PED_FLEE_POS || m_nPedState == PED_FLEE_ENTITY) && m_nMoveState < nextMove)
+ || (m_nPedState != PED_FLEE_POS && m_nPedState != PED_FLEE_ENTITY && m_objective != OBJECTIVE_GOTO_CHAR_ON_FOOT && m_nWaitState == WAITSTATE_FALSE)) {
+
+ SetMoveState(nextMove);
+ }
+
+ SetMoveAnim();
+ return false;
+ }
+
+ if ((m_objective != OBJECTIVE_FOLLOW_PED_IN_FORMATION || m_pedInObjective->m_nMoveState == PEDMOVE_STILL) && m_nMoveState != PEDMOVE_STILL) {
+ m_nPedStateTimer = 0;
+ m_actionX = 0;
+ m_actionY = 0;
+ }
+
+ if (m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT || m_objective == OBJECTIVE_RUN_TO_AREA || m_objective == OBJECTIVE_GOTO_AREA_ANY_MEANS) {
+ if (m_pNextPathNode)
+ m_pNextPathNode = nil;
+ else
+ bScriptObjectiveCompleted = true;
+
+ bIsFleeing = true;
+ }
+
+ if (SeekFollowingPath(nil))
+ m_nCurPathNode++;
+
+ return true;
+}
+
+bool
+CPed::SeekFollowingPath(CVector *unused)
+{
+ return m_nCurPathNode <= m_nPathNodes && m_nPathNodes;
+}
+
+void
+CPed::Flee(void)
+{
+ if (CTimer::GetTimeInMilliseconds() > m_fleeTimer && m_fleeTimer) {
+ bool mayFinishFleeing = true;
+ if (m_nPedState == PED_FLEE_ENTITY) {
+ if ((CVector2D(GetPosition()) - ms_vec2DFleePosition).MagnitudeSqr() < 900.0f)
+ mayFinishFleeing = false;
+ }
+
+ if (mayFinishFleeing) {
+ eMoveState moveState = m_nMoveState;
+ ClearFlee();
+
+ if (m_objective == OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE || m_objective == OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS)
+ RestorePreviousObjective();
+
+ if ((m_nPedState == PED_IDLE || m_nPedState == PED_WANDER_PATH) && CGeneral::GetRandomNumber() & 1) {
+ SetWaitState(moveState <= PEDMOVE_WALK ? WAITSTATE_CROSS_ROAD_LOOK : WAITSTATE_FINISH_FLEE, nil);
+ }
+ return;
+ }
+ m_fleeTimer = CTimer::GetTimeInMilliseconds() + 5000;
+ }
+
+ if (bIsFleeing) {
+ CPathNode *realLastNode = nil;
+ uint8 nextDirection = 0;
+ uint8 curDirectionShouldBe = 9; // means not defined yet
+
+ if (m_nPedStateTimer < CTimer::GetTimeInMilliseconds()
+ && m_collidingThingTimer < CTimer::GetTimeInMilliseconds()) {
+
+ if (m_pNextPathNode && CTimer::GetTimeInMilliseconds() > m_standardTimer) {
+
+ curDirectionShouldBe = CGeneral::GetNodeHeadingFromVector(GetPosition().x - ms_vec2DFleePosition.x, GetPosition().y - ms_vec2DFleePosition.y);
+ if (m_nPathState < curDirectionShouldBe)
+ m_nPathState += 8;
+
+ int dirDiff = m_nPathState - curDirectionShouldBe;
+ if (dirDiff > 2 && dirDiff < 6) {
+ realLastNode = nil;
+ m_pLastPathNode = m_pNextPathNode;
+ m_pNextPathNode = 0;
+ }
+ }
+
+ if (m_pNextPathNode) {
+ m_vecSeekPos = m_pNextPathNode->pos;
+ if (m_nMoveState == PEDMOVE_RUN)
+ bIsRunning = true;
+
+ eMoveState moveState = m_nMoveState;
+ if (Seek()) {
+ realLastNode = m_pLastPathNode;
+ m_pLastPathNode = m_pNextPathNode;
+ m_pNextPathNode = nil;
+ }
+ bIsRunning = false;
+ SetMoveState(moveState);
+ }
+ }
+
+ if (!m_pNextPathNode) {
+ if (curDirectionShouldBe == 9) {
+ curDirectionShouldBe = CGeneral::GetNodeHeadingFromVector(GetPosition().x - ms_vec2DFleePosition.x, GetPosition().y - ms_vec2DFleePosition.y);
+ }
+ ThePaths.FindNextNodeWandering(PATH_PED, GetPosition(), &m_pLastPathNode, &m_pNextPathNode,
+ curDirectionShouldBe,
+ &nextDirection);
+
+ if (curDirectionShouldBe < nextDirection)
+ curDirectionShouldBe += 8;
+
+ if (m_pNextPathNode && m_pNextPathNode != realLastNode && m_pNextPathNode != m_pLastPathNode && curDirectionShouldBe - nextDirection != 4) {
+ m_nPathState = nextDirection;
+ m_standardTimer = CTimer::GetTimeInMilliseconds() + 2000;
+ } else {
+ bIsFleeing = false;
+ SetMoveState(PEDMOVE_RUN);
+ Flee();
+ }
+ }
+ return;
+ }
+
+ if ((m_nPedState == PED_FLEE_ENTITY || m_nPedState == PED_ON_FIRE) && m_nPedStateTimer < CTimer::GetTimeInMilliseconds()) {
+
+ float angleToFleeFromPos = CGeneral::GetRadianAngleBetweenPoints(
+ GetPosition().x,
+ GetPosition().y,
+ ms_vec2DFleePosition.x,
+ ms_vec2DFleePosition.y);
+
+ m_fRotationDest = CGeneral::LimitRadianAngle(angleToFleeFromPos);
+
+ if (m_fRotationCur - PI > m_fRotationDest)
+ m_fRotationDest += TWOPI;
+ else if (PI + m_fRotationCur < m_fRotationDest)
+ m_fRotationDest -= TWOPI;
+ }
+
+ if (CTimer::GetTimeInMilliseconds() & 0x20) {
+ //CVector forwardPos = GetPosition();
+ CMatrix forwardMat(GetMatrix());
+ forwardMat.GetPosition() += Multiply3x3(forwardMat, CVector(0.0f, 4.0f, 0.0f));
+ CVector forwardPos = forwardMat.GetPosition();
+
+ CEntity *foundEnt;
+ CColPoint foundCol;
+ bool found = CWorld::ProcessVerticalLine(forwardPos, forwardMat.GetPosition().z - 100.0f, foundCol, foundEnt, 1, 0, 0, 0, 1, 0, 0);
+
+ if (!found || Abs(forwardPos.z - forwardMat.GetPosition().z) > 1.0f) {
+ m_fRotationDest += DEGTORAD(112.5f);
+ m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 2000;
+ }
+ }
+
+ if (CTimer::GetTimeInMilliseconds() >= m_collidingThingTimer)
+ return;
+
+ if (!m_collidingEntityWhileFleeing)
+ return;
+
+ double damagingThingPriorityMult = (double)(m_collidingThingTimer - CTimer::GetTimeInMilliseconds()) * 2.0 / 2500;
+
+ if (damagingThingPriorityMult <= 1.5) {
+
+ double angleToFleeEntity = CGeneral::GetRadianAngleBetweenPoints(
+ GetPosition().x,
+ GetPosition().y,
+ m_collidingEntityWhileFleeing->GetPosition().x,
+ m_collidingEntityWhileFleeing->GetPosition().y);
+ angleToFleeEntity = CGeneral::LimitRadianAngle(angleToFleeEntity);
+
+ // It includes projectiles, but is everything collides with us included?
+ double angleToFleeDamagingThing = CGeneral::GetRadianAngleBetweenPoints(
+ m_vecDamageNormal.x,
+ m_vecDamageNormal.y,
+ 0.0,
+ 0.0);
+ angleToFleeDamagingThing = CGeneral::LimitRadianAngle(angleToFleeDamagingThing);
+
+ if (angleToFleeEntity - PI > angleToFleeDamagingThing)
+ angleToFleeDamagingThing += TWOPI;
+ else if (PI + angleToFleeEntity < angleToFleeDamagingThing)
+ angleToFleeDamagingThing -= TWOPI;
+
+ if (damagingThingPriorityMult <= 1.0) {
+ // Range [0.0, 1.0]
+
+ double angleToFleeBoth = (angleToFleeDamagingThing + angleToFleeEntity) * 0.5;
+
+ if (m_fRotationDest - PI > angleToFleeBoth)
+ angleToFleeBoth += TWOPI;
+ else if (PI + m_fRotationDest < angleToFleeBoth)
+ angleToFleeBoth -= TWOPI;
+
+ m_fRotationDest = (1.0 - damagingThingPriorityMult) * m_fRotationDest + damagingThingPriorityMult * angleToFleeBoth;
+ } else {
+ // Range (1.0, 1.5]
+
+ double adjustedMult = (damagingThingPriorityMult - 1.0) * 2.0;
+ m_fRotationDest = angleToFleeEntity * (1.0 - adjustedMult) + adjustedMult * angleToFleeDamagingThing;
+ }
+ } else {
+ m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(
+ m_vecDamageNormal.x,
+ m_vecDamageNormal.y,
+ 0.0f,
+ 0.0f);
+ m_fRotationDest = CGeneral::LimitRadianAngle(m_fRotationDest);
+ }
+
+ m_fRotationCur = CGeneral::LimitRadianAngle(m_fRotationCur);
+
+ if (m_fRotationCur - PI > m_fRotationDest)
+ m_fRotationDest += TWOPI;
+ else if (PI + m_fRotationCur < m_fRotationDest)
+ m_fRotationDest -= TWOPI;
+
+}
+
+void
+CPed::FollowPath(void)
+{
+ m_vecSeekPos.x = m_stPathNodeStates[m_nCurPathNode].x;
+ m_vecSeekPos.y = m_stPathNodeStates[m_nCurPathNode].y;
+ m_vecSeekPos.z = GetPosition().z;
+
+ // Mysterious code
+/* int v4 = 0;
+ int maxNodeIndex = m_nPathNodes - 1;
+ if (maxNodeIndex > 0) {
+ if (maxNodeIndex > 8) {
+ while (v4 < maxNodeIndex - 8)
+ v4 += 8;
+ }
+
+ while (v4 < maxNodeIndex)
+ v4++;
+
+ }
+*/
+ if (Seek()) {
+ m_nCurPathNode++;
+ if (m_nCurPathNode == m_nPathNodes)
+ RestorePreviousState();
+ }
+}
+
+CVector
+CPed::GetFormationPosition(void)
+{
+ CPed *referencePed = m_pedInObjective;
+
+ if (referencePed->m_nPedState == PED_DEAD) {
+ CPed *referencePedOfReference = referencePed->m_pedInObjective;
+ if (!referencePedOfReference) {
+ m_pedInObjective = nil;
+ return GetPosition();
+ }
+ m_pedInObjective = referencePed = referencePedOfReference;
+ }
+
+ CVector formationOffset;
+ switch (m_pedFormation) {
+ case 1:
+ formationOffset = CVector(0.0f, -1.5f, 0.0f);
+ break;
+ case 2:
+ formationOffset = CVector(-1.5f, -1.5f, 0.0f);
+ break;
+ case 3:
+ formationOffset = CVector(1.5f, -1.5f, 0.0f);
+ break;
+ case 4:
+ formationOffset = CVector(-1.5f, 1.5f, 0.0f);
+ break;
+ case 5:
+ formationOffset = CVector(1.5f, 1.5f, 0.0f);
+ break;
+ case 6:
+ formationOffset = CVector(-1.5f, 0.0f, 0.0f);
+ break;
+ case 7:
+ formationOffset = CVector(1.5f, 0.0f, 0.0f);
+ break;
+ case 8:
+ formationOffset = CVector(0.0f, 1.5f, 0.0f);
+ break;
+ default:
+ formationOffset = CVector(0.0f, 0.0f, 0.0f);
+ break;
+ }
+ return formationOffset + referencePed->GetPosition();
+}
+
+void
+CPed::GetNearestDoor(CVehicle *veh, CVector &posToOpen)
+{
+ CVector *enterOffset = nil;
+ if (m_vehEnterType == CAR_DOOR_LF && veh->pDriver
+ || m_vehEnterType == CAR_DOOR_RF && veh->pPassengers[0]
+ || m_vehEnterType == CAR_DOOR_LR && veh->pPassengers[1]
+ || m_vehEnterType == CAR_DOOR_RR && veh->pPassengers[2])
+ {
+ enterOffset = &vecPedQuickDraggedOutCarAnimOffset;
+ }
+
+ CVector lfPos = GetPositionToOpenCarDoor(veh, CAR_DOOR_LF);
+ CVector rfPos = GetPositionToOpenCarDoor(veh, CAR_DOOR_RF);
+
+ // Right front door is closer
+ if ((lfPos - GetPosition()).MagnitudeSqr2D() >= (rfPos - GetPosition()).MagnitudeSqr2D()) {
+
+ if (veh->IsRoomForPedToLeaveCar(CAR_DOOR_RF, enterOffset)) {
+
+ CPed *rfPassenger = veh->pPassengers[0];
+ if (!rfPassenger
+ || rfPassenger->m_leader != this && !m_ped_flagF4 && (veh->VehicleCreatedBy != MISSION_VEHICLE || m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER)
+ || veh->IsRoomForPedToLeaveCar(CAR_DOOR_LF, enterOffset) == 0) {
+
+ if ((veh->m_nGettingInFlags & CAR_DOOR_FLAG_RF) == 0
+ || veh->IsRoomForPedToLeaveCar(CAR_DOOR_LF, enterOffset) == 0) {
+ m_vehEnterType = CAR_DOOR_RF;
+ posToOpen = rfPos;
+ return;
+ }
+ }
+ } else {
+ if (!veh->IsRoomForPedToLeaveCar(CAR_DOOR_LF, enterOffset))
+ return;
+ }
+ m_vehEnterType = CAR_DOOR_LF;
+ posToOpen = lfPos;
+ return;
+ }
+
+ if (veh->IsRoomForPedToLeaveCar(CAR_DOOR_LF, enterOffset)) {
+ m_vehEnterType = CAR_DOOR_LF;
+ posToOpen = lfPos;
+ return;
+ }
+
+ if (veh->IsRoomForPedToLeaveCar(CAR_DOOR_RF, enterOffset)) {
+ m_vehEnterType = CAR_DOOR_RF;
+ posToOpen = rfPos;
+ }
+}
+
WRAPPER void CPed::PedGetupCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4CE810); }
WRAPPER void CPed::PedStaggerCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4CE8D0); }
WRAPPER void CPed::PedEvadeCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4D36E0); }
@@ -6952,4 +7425,10 @@ STARTPATCHES
InjectHook(0x4D6520, &CPed::FinishedWaitCB, PATCH_JUMP);
InjectHook(0x4D5D80, &CPed::Wait, PATCH_JUMP);
InjectHook(0x4E3A90, &CPed::FindBestCoordsFromNodes, PATCH_JUMP);
+ InjectHook(0x4D2E70, &CPed::SeekFollowingPath, PATCH_JUMP);
+ InjectHook(0x4D1640, &CPed::Seek, PATCH_JUMP);
+ InjectHook(0x4D3020, &CPed::FollowPath, PATCH_JUMP);
+ InjectHook(0x4D1ED0, &CPed::Flee, PATCH_JUMP);
+ InjectHook(0x4E1CF0, &CPed::GetNearestDoor, PATCH_JUMP);
+ InjectHook(0x4DF420, &CPed::GetFormationPosition, PATCH_JUMP);
ENDPATCHES \ No newline at end of file
diff --git a/src/peds/Ped.h b/src/peds/Ped.h
index d078f4d4..091a9cd6 100644
--- a/src/peds/Ped.h
+++ b/src/peds/Ped.h
@@ -260,7 +260,7 @@ public:
uint8 bIsTalking : 1;
uint8 bIsInTheAir : 1;
uint8 bIsLanding : 1;
- uint8 m_ped_flagB20 : 1;
+ uint8 bIsRunning : 1; // not fleeing
uint8 m_ped_flagB40 : 1;
uint8 m_ped_flagB80 : 1;
@@ -370,8 +370,8 @@ public:
private:
int8 _pad2B5[3];
public:
- CPathNode *m_pNextPathNode;
CPathNode *m_pLastPathNode;
+ CPathNode *m_pNextPathNode;
float m_fHealth;
float m_fArmour;
int16 m_routeLastPoint;
@@ -389,12 +389,12 @@ public:
CEntity *m_pCurrentPhysSurface;
CVector m_vecOffsetFromPhysSurface;
CEntity *m_pCurSurface;
- CVector m_vecSeekVehicle;
+ CVector m_vecSeekPos;
CEntity *m_pSeekTarget;
CVehicle *m_pMyVehicle;
bool bInVehicle;
uint8 pad_315[3];
- float field_318;
+ float m_distanceToCountSeekDone;
bool bRunningToPhone;
uint8 field_31D;
int16 m_phoneId;
@@ -407,8 +407,8 @@ public:
float m_fleeFromPosY;
CEntity *m_fleeFrom;
uint32 m_fleeTimer;
- uint32 field_344;
- uint32 m_lastThreatTimer; // I don't think so
+ CEntity* m_collidingEntityWhileFleeing;
+ uint32 m_collidingThingTimer;
CEntity *m_pCollidingEntity;
uint8 m_stateUnused;
uint8 pad_351[3];
@@ -600,6 +600,11 @@ public:
bool FindBestCoordsFromNodes(CVector unused, CVector* a6);
void Wait(void);
void ProcessObjective(void);
+ bool SeekFollowingPath(CVector*);
+ void Flee(void);
+ void FollowPath(void);
+ CVector GetFormationPosition(void);
+ void GetNearestDoor(CVehicle*, CVector&);
// Static methods
static CVector GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float offset);
@@ -669,18 +674,20 @@ public:
void SetPedState(PedState state) { m_nPedState = state; }
// set by 0482:set_threat_reaction_range_multiplier opcode
- static uint16 &distanceMultToCountPedNear;
+ static uint16 &nThreatReactionRangeMultiplier;
- static CVector &offsetToOpenRegularCarDoor;
- static CVector &offsetToOpenLowCarDoor;
- static CVector &offsetToOpenVanDoor;
+ static CVector &vecPedCarDoorAnimOffset;
+ static CVector &vecPedCarDoorLoAnimOffset;
+ static CVector &vecPedVanRearDoorAnimOffset;
+ static CVector &vecPedQuickDraggedOutCarAnimOffset;
static bool &bNastyLimbsCheat;
static bool &bPedCheat2;
static bool &bPedCheat3;
- static CColPoint &ms_tempColPoint;
+ static CVector2D &ms_vec2DFleePosition;
+ static CColPoint &aTempPedColPts;
static uint16 &nPlayerInComboMove;
static FightMove (&tFightMoves)[24];
- static CPedAudioData (&PedAudioData)[38];
+ static CPedAudioData (&CommentWaitTime)[38];
#ifndef FINAL
static bool bUnusedFightThingOnPlayer;
diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h
index e6b64e6e..4dd3a087 100644
--- a/src/vehicles/Automobile.h
+++ b/src/vehicles/Automobile.h
@@ -58,6 +58,14 @@ enum eBombType
CARBOMB_ONIGNITIONACTIVE,
};
+enum {
+ CAR_DOOR_FLAG_UNKNOWN = 0x0,
+ CAR_DOOR_FLAG_LF = 0x1,
+ CAR_DOOR_FLAG_LR = 0x2,
+ CAR_DOOR_FLAG_RF = 0x4,
+ CAR_DOOR_FLAG_RR = 0x8
+};
+
class CAutomobile : public CVehicle
{
public:
@@ -189,14 +197,14 @@ static_assert(sizeof(CAutomobile) == 0x5A8, "CAutomobile: error");
inline uint8 GetCarDoorFlag(int32 carnode) {
switch (carnode) {
case CAR_DOOR_LF:
- return 1;
+ return CAR_DOOR_FLAG_LF;
case CAR_DOOR_LR:
- return 2;
+ return CAR_DOOR_FLAG_LR;
case CAR_DOOR_RF:
- return 4;
+ return CAR_DOOR_FLAG_RF;
case CAR_DOOR_RR:
- return 8;
+ return CAR_DOOR_FLAG_RR;
default:
- return 0;
+ return CAR_DOOR_FLAG_UNKNOWN;
}
}