mirror of
https://github.com/halpz/re3.git
synced 2024-12-25 18:05:27 +00:00
commit
c17bbc62f5
|
@ -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; }
|
||||
|
|
|
@ -139,6 +139,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)
|
||||
{
|
||||
|
@ -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
|
||||
|
|
649
src/peds/Ped.cpp
649
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
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue