summaryrefslogtreecommitdiffstats
path: root/src/peds
diff options
context:
space:
mode:
Diffstat (limited to 'src/peds')
-rw-r--r--src/peds/CivilianPed.cpp12
-rw-r--r--src/peds/Gangs.cpp87
-rw-r--r--src/peds/Gangs.h44
-rw-r--r--src/peds/Ped.cpp9
-rw-r--r--src/peds/PedIK.cpp4
-rw-r--r--src/peds/PedIK.h4
-rw-r--r--src/peds/PedType.h1
-rw-r--r--src/peds/PlayerPed.cpp3070
-rw-r--r--src/peds/Population.cpp86
-rw-r--r--src/peds/Population.h54
10 files changed, 1759 insertions, 1612 deletions
diff --git a/src/peds/CivilianPed.cpp b/src/peds/CivilianPed.cpp
index 533d7c98..a9e0580e 100644
--- a/src/peds/CivilianPed.cpp
+++ b/src/peds/CivilianPed.cpp
@@ -28,10 +28,8 @@ CCivilianPed::CivilianAI(void)
return;
if (m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT || m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS) {
- if (m_pedInObjective) {
- if (m_pedInObjective->IsPlayer())
- return;
- }
+ if (m_pedInObjective && m_pedInObjective->IsPlayer())
+ return;
}
if (CTimer::GetTimeInMilliseconds() <= m_lookTimer)
return;
@@ -75,7 +73,7 @@ CCivilianPed::CivilianAI(void)
} else {
SetMoveState(PEDMOVE_WALK);
}
- } else if (threatPed->IsPlayer() && FindPlayerPed()->m_pWanted->m_CurrentCops) {
+ } else if (threatPed->IsPlayer() && FindPlayerPed()->m_pWanted->m_CurrentCops != 0) {
SetFindPathAndFlee(m_threatEntity, 5000);
if (threatDistSqr < sq(10.0f)) {
SetMoveState(PEDMOVE_RUN);
@@ -170,8 +168,8 @@ CCivilianPed::CivilianAI(void)
if (m_threatEntity && m_threatEntity->IsPed()) {
CPed *threatPed = (CPed*)m_threatEntity;
if (m_pedStats->m_fear <= 100 - threatPed->m_pedStats->m_temper && threatPed->m_nPedType != PEDTYPE_COP) {
- if (threatPed->GetWeapon()->IsTypeMelee() || !GetWeapon()->IsTypeMelee()) {
- if (threatPed->IsPlayer() && FindPlayerPed()->m_pWanted->m_CurrentCops) {
+ if (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) {
SetFindPathAndFlee(m_threatEntity, 10000);
}
diff --git a/src/peds/Gangs.cpp b/src/peds/Gangs.cpp
new file mode 100644
index 00000000..c67fe599
--- /dev/null
+++ b/src/peds/Gangs.cpp
@@ -0,0 +1,87 @@
+#include "common.h"
+#include "patcher.h"
+#include "ModelIndices.h"
+#include "Gangs.h"
+#include "Weapon.h"
+
+CGangInfo CGangs::Gang[NUM_GANGS];
+
+CGangInfo::CGangInfo() :
+ m_nVehicleMI(MI_BUS),
+ m_nPedModelOverride(-1),
+ m_Weapon1(WEAPONTYPE_UNARMED),
+ m_Weapon2(WEAPONTYPE_UNARMED)
+{}
+
+void CGangs::Initialise(void)
+{
+ Gang[GANG_MAFIA].m_nVehicleMI = MI_MAFIA;
+ Gang[GANG_TRIAD].m_nVehicleMI = MI_BELLYUP;
+ Gang[GANG_DIABLOS].m_nVehicleMI = MI_DIABLOS;
+ Gang[GANG_YAKUZA].m_nVehicleMI = MI_YAKUZA;
+ Gang[GANG_YARDIE].m_nVehicleMI = MI_YARDIE;
+ Gang[GANG_COLUMB].m_nVehicleMI = MI_COLUMB;
+ Gang[GANG_HOODS].m_nVehicleMI = MI_HOODS;
+ Gang[GANG_7].m_nVehicleMI = -1;
+ Gang[GANG_8].m_nVehicleMI = -1;
+#ifdef FIX_BUGS
+ for (int i = 0; i < NUM_GANGS; i++)
+ Gang[i].m_nPedModelOverride = -1;
+#endif
+}
+
+void CGangs::SetGangVehicleModel(int16 gang, int32 model)
+{
+ GetGangInfo(gang)->m_nVehicleMI = model;
+}
+
+void CGangs::SetGangWeapons(int16 gang, int32 weapon1, int32 weapon2)
+{
+ CGangInfo *gi = GetGangInfo(gang);
+ gi->m_Weapon1 = weapon1;
+ gi->m_Weapon2 = weapon2;
+}
+
+void CGangs::SetGangPedModelOverride(int16 gang, int8 ovrd)
+{
+ GetGangInfo(gang)->m_nPedModelOverride = ovrd;
+}
+
+int8 CGangs::GetGangPedModelOverride(int16 gang)
+{
+ return GetGangInfo(gang)->m_nPedModelOverride;
+}
+
+void CGangs::SaveAllGangData(uint8 *buf, uint32 *size)
+{
+INITSAVEBUF
+
+ *size = SAVE_HEADER_SIZE + sizeof(Gang);
+ WriteSaveHeader(buf, 'G','N','G','\0', *size - SAVE_HEADER_SIZE);
+ for (int i = 0; i < NUM_GANGS; i++)
+ WriteSaveBuf(buf, Gang[i]);
+
+VALIDATESAVEBUF(*size);
+}
+
+void CGangs::LoadAllGangData(uint8 *buf, uint32 size)
+{
+ Initialise();
+
+INITSAVEBUF
+ CheckSaveHeader(buf, 'G','N','G','\0', size - SAVE_HEADER_SIZE);
+
+ for (int i = 0; i < NUM_GANGS; i++)
+ Gang[i] = ReadSaveBuf<CGangInfo>(buf);
+VALIDATESAVEBUF(size);
+}
+
+STARTPATCHES
+ InjectHook(0x4C3FB0, CGangs::Initialise, PATCH_JUMP);
+ InjectHook(0x4C4010, CGangs::SetGangVehicleModel, PATCH_JUMP);
+ InjectHook(0x4C4030, CGangs::SetGangWeapons, PATCH_JUMP);
+ InjectHook(0x4C4050, CGangs::SetGangPedModelOverride, PATCH_JUMP);
+ InjectHook(0x4C4070, CGangs::GetGangPedModelOverride, PATCH_JUMP);
+ InjectHook(0x4C4080, CGangs::SaveAllGangData, PATCH_JUMP);
+ InjectHook(0x4C4100, CGangs::LoadAllGangData, PATCH_JUMP);
+ENDPATCHES
diff --git a/src/peds/Gangs.h b/src/peds/Gangs.h
new file mode 100644
index 00000000..dd7a7f93
--- /dev/null
+++ b/src/peds/Gangs.h
@@ -0,0 +1,44 @@
+#pragma once
+
+struct CGangInfo
+{
+ int32 m_nVehicleMI;
+ int8 m_nPedModelOverride;
+ int32 m_Weapon1;
+ int32 m_Weapon2;
+
+ CGangInfo();
+};
+
+static_assert(sizeof(CGangInfo) == 0x10, "CGangInfo: error");
+
+enum {
+ GANG_MAFIA = 0,
+ GANG_TRIAD,
+ GANG_DIABLOS,
+ GANG_YAKUZA,
+ GANG_YARDIE,
+ GANG_COLUMB,
+ GANG_HOODS,
+ GANG_7,
+ GANG_8,
+ NUM_GANGS
+};
+
+class CGangs
+{
+public:
+ static void Initialise(void);
+ static void SetGangVehicleModel(int16, int32);
+ static void SetGangWeapons(int16, int32, int32);
+ static void SetGangPedModelOverride(int16, int8);
+ static int8 GetGangPedModelOverride(int16);
+ static void SaveAllGangData(uint8 *, uint32 *);
+ static void LoadAllGangData(uint8 *, uint32);
+
+ static int32 GetGangVehicleModel(int16 gang) { return Gang[gang].m_nVehicleMI; }
+ static CGangInfo *GetGangInfo(int16 gang) { return &Gang[gang]; }
+
+private:
+ static CGangInfo Gang[NUM_GANGS];
+};
diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp
index 54816b1c..cee2b323 100644
--- a/src/peds/Ped.cpp
+++ b/src/peds/Ped.cpp
@@ -676,7 +676,7 @@ RemoveAllModelCB(RwObject *object, void *data)
{
RpAtomic *atomic = (RpAtomic*)object;
if (CVisibilityPlugins::GetAtomicModelInfo(atomic)) {
- RpClumpRemoveAtomic(atomic->clump, atomic);
+ RpClumpRemoveAtomic(RpAtomicGetClump(atomic), atomic);
RpAtomicDestroy(atomic);
}
return object;
@@ -902,7 +902,7 @@ static RwObject*
SetPedAtomicVisibilityCB(RwObject* object, void* data)
{
if (data == nil)
- RpAtomicSetFlags(object, 0);
+ RpAtomicSetFlags((RpAtomic*)object, 0);
return object;
}
@@ -2733,7 +2733,6 @@ CPed::SetObjective(eObjective newObj, void *entity)
}
#ifdef VC_PED_PORTS
- SetObjectiveTimer(0);
ClearPointGunAt();
#endif
bObjectiveCompleted = false;
@@ -15027,7 +15026,7 @@ CPed::ProcessBuoyancy(void)
#endif
if (mod_Buoyancy.ProcessBuoyancy(this, GRAVITY * m_fMass * buoyancyLevel, &buoyancyPoint, &buoyancyImpulse)) {
- m_flagD8 = true;
+ bTouchingWater = true;
CEntity *entity;
CColPoint point;
if (CWorld::ProcessVerticalLine(GetPosition(), GetPosition().z - 3.0f, point, entity, false, true, false, false, false, false, false)
@@ -15093,7 +15092,7 @@ CPed::ProcessBuoyancy(void)
} else
return;
} else
- m_flagD8 = false;
+ bTouchingWater = false;
if (nGenerateWaterCircles && CTimer::GetTimeInMilliseconds() >= nGenerateWaterCircles) {
CVector pos = GetPosition();
diff --git a/src/peds/PedIK.cpp b/src/peds/PedIK.cpp
index cc4b0dd0..8e450ee6 100644
--- a/src/peds/PedIK.cpp
+++ b/src/peds/PedIK.cpp
@@ -340,7 +340,7 @@ CPedIK::RestoreLookAt(void)
}
void
-CPedIK::ExtractYawAndPitchWorld(RwMatrixTag *mat, float *yaw, float *pitch)
+CPedIK::ExtractYawAndPitchWorld(RwMatrix *mat, float *yaw, float *pitch)
{
float f = clamp(DotProduct(mat->up, CVector(0.0f, 1.0f, 0.0f)), -1.0f, 1.0f);
*yaw = Acos(f);
@@ -352,7 +352,7 @@ CPedIK::ExtractYawAndPitchWorld(RwMatrixTag *mat, float *yaw, float *pitch)
}
void
-CPedIK::ExtractYawAndPitchLocal(RwMatrixTag *mat, float *yaw, float *pitch)
+CPedIK::ExtractYawAndPitchLocal(RwMatrix *mat, float *yaw, float *pitch)
{
float f = clamp(DotProduct(mat->at, CVector(0.0f, 0.0f, 1.0f)), -1.0f, 1.0f);
*yaw = Acos(f);
diff --git a/src/peds/PedIK.h b/src/peds/PedIK.h
index df9017f3..7b82d1ac 100644
--- a/src/peds/PedIK.h
+++ b/src/peds/PedIK.h
@@ -54,8 +54,8 @@ public:
void GetComponentPosition(RwV3d *pos, uint32 node);
static RwMatrix *GetWorldMatrix(RwFrame *source, RwMatrix *destination);
void RotateTorso(AnimBlendFrameData* animBlend, LimbOrientation* limb, bool changeRoll);
- void ExtractYawAndPitchLocal(RwMatrixTag *mat, float *yaw, float *pitch);
- void ExtractYawAndPitchWorld(RwMatrixTag *mat, float *yaw, float *pitch);
+ void ExtractYawAndPitchLocal(RwMatrix *mat, float *yaw, float *pitch);
+ void ExtractYawAndPitchWorld(RwMatrix *mat, float *yaw, float *pitch);
LimbMoveStatus MoveLimb(LimbOrientation &limb, float approxPhi, float approxTheta, LimbMovementInfo &moveInfo);
bool RestoreGunPosn(void);
bool LookInDirection(float phi, float theta);
diff --git a/src/peds/PedType.h b/src/peds/PedType.h
index 1f3ecb59..3d927df5 100644
--- a/src/peds/PedType.h
+++ b/src/peds/PedType.h
@@ -85,6 +85,7 @@ public:
static uint32 GetFlag(int type) { return ms_apPedType[type]->m_flag; }
static uint32 GetAvoid(int type) { return ms_apPedType[type]->m_avoid; }
static uint32 GetThreats(int type) { return ms_apPedType[type]->m_threats; }
+ static void SetThreats(int type, uint32 threat) { ms_apPedType[type]->m_threats = threat; }
static void AddThreat(int type, int threat) { ms_apPedType[type]->m_threats |= threat; }
static void RemoveThreat(int type, int threat) { ms_apPedType[type]->m_threats &= ~threat; }
static bool IsThreat(int type, int threat) { return ms_apPedType[type]->m_threats & threat; }
diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp
index 6dbf7687..ccc0a43a 100644
--- a/src/peds/PlayerPed.cpp
+++ b/src/peds/PlayerPed.cpp
@@ -1,1535 +1,1535 @@
-#include "common.h"
-#include "patcher.h"
-#include "PlayerPed.h"
-#include "Wanted.h"
-#include "Fire.h"
-#include "DMAudio.h"
-#include "Pad.h"
-#include "Camera.h"
-#include "WeaponEffects.h"
-#include "ModelIndices.h"
-#include "World.h"
-#include "RpAnimBlend.h"
-#include "AnimBlendAssociation.h"
-#include "General.h"
-#include "Pools.h"
-#include "Darkel.h"
-#include "CarCtrl.h"
-
-#define PAD_MOVE_TO_GAME_WORLD_MOVE 60.0f
-
-CPlayerPed::~CPlayerPed()
-{
- delete m_pWanted;
-}
-
-CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
-{
- m_fMoveSpeed = 0.0f;
- SetModelIndex(MI_PLAYER);
- SetInitialState();
-
- m_pWanted = new CWanted();
- m_pWanted->Initialise();
- m_pArrestingCop = nil;
- m_currentWeapon = WEAPONTYPE_UNARMED;
- m_nSelectedWepSlot = WEAPONTYPE_UNARMED;
- m_nSpeedTimer = 0;
- m_bSpeedTimerFlag = false;
- m_pPointGunAt = nil;
- m_nPedState = PED_IDLE;
- m_fMaxStamina = 150.0f;
- m_fCurrentStamina = m_fMaxStamina;
- m_fStaminaProgress = 0.0f;
- m_nEvadeAmount = 0;
- field_1367 = 0;
- m_nShotDelay = 0;
- field_1376 = 0.0f;
- m_bHaveTargetSelected = false;
- m_bHasLockOnTarget = false;
- m_bCanBeDamaged = true;
- m_fWalkAngle = 0.0f;
- m_fFPSMoveHeading = 0.0f;
- m_nTargettableObjects[0] = m_nTargettableObjects[1] = m_nTargettableObjects[2] = m_nTargettableObjects[3] = -1;
- field_1413 = 0;
- for (int i = 0; i < 6; i++) {
- m_vecSafePos[i] = CVector(0.0f, 0.0f, 0.0f);
- m_pPedAtSafePos[i] = nil;
- }
-}
-
-void CPlayerPed::ClearWeaponTarget()
-{
- if (m_nPedType == PEDTYPE_PLAYER1) {
- m_pPointGunAt = nil;
- TheCamera.ClearPlayerWeaponMode();
- CWeaponEffects::ClearCrossHair();
- }
- ClearPointGunAt();
-}
-
-void
-CPlayerPed::SetWantedLevel(int32 level)
-{
- m_pWanted->SetWantedLevel(level);
-}
-
-void
-CPlayerPed::SetWantedLevelNoDrop(int32 level)
-{
- m_pWanted->SetWantedLevelNoDrop(level);
-}
-
-void
-CPlayerPed::MakeObjectTargettable(int32 handle)
-{
- for (int i = 0; i < ARRAY_SIZE(m_nTargettableObjects); i++) {
- if (
-#ifdef FIX_BUGS
- m_nTargettableObjects[i] == -1 ||
-#endif
- CPools::GetObjectPool()->GetAt(m_nTargettableObjects[i]) == nil) {
- m_nTargettableObjects[i] = handle;
- return;
- }
- }
-}
-
-// I don't know the actual purpose of parameter
-void
-CPlayerPed::AnnoyPlayerPed(bool annoyedByPassingEntity)
-{
- if (m_pedStats->m_temper < 52) {
- m_pedStats->m_temper++;
- } else {
- if (annoyedByPassingEntity) {
- if (m_pedStats->m_temper < 55) {
- m_pedStats->m_temper++;
- } else {
- m_pedStats->m_temper = 46;
- }
- }
- }
-}
-
-void
-CPlayerPed::ClearAdrenaline(void)
-{
- if (m_bAdrenalineActive && m_nAdrenalineTime != 0) {
- m_nAdrenalineTime = 0;
- CTimer::SetTimeScale(1.0f);
- }
-}
-
-CPlayerInfo *
-CPlayerPed::GetPlayerInfoForThisPlayerPed()
-{
- if (CWorld::Players[0].m_pPed == this)
- return &CWorld::Players[0];
-
- return nil;
-}
-
-void
-CPlayerPed::SetupPlayerPed(int32 index)
-{
- CPlayerPed *player = new CPlayerPed();
- CWorld::Players[index].m_pPed = player;
-
- player->SetOrientation(0.0f, 0.0f, 0.0f);
-
- CWorld::Add(player);
- player->m_wepAccuracy = 100;
-}
-
-void
-CPlayerPed::DeactivatePlayerPed(int32 index)
-{
- CWorld::Remove(CWorld::Players[index].m_pPed);
-}
-
-void
-CPlayerPed::ReactivatePlayerPed(int32 index)
-{
- CWorld::Add(CWorld::Players[index].m_pPed);
-}
-
-void
-CPlayerPed::UseSprintEnergy(void)
-{
- if (m_fCurrentStamina > -150.0f && !CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint
- && !m_bAdrenalineActive) {
- m_fCurrentStamina = m_fCurrentStamina - CTimer::GetTimeStep();
- m_fStaminaProgress = m_fStaminaProgress + CTimer::GetTimeStep();
- }
-
- if (m_fStaminaProgress >= 500.0f) {
- m_fStaminaProgress = 0;
- if (m_fMaxStamina < 1000.0f)
- m_fMaxStamina += 10.0f;
- }
-}
-
-void
-CPlayerPed::MakeChangesForNewWeapon(int8 weapon)
-{
- if (m_nPedState == PED_SNIPER_MODE) {
- RestorePreviousState();
- TheCamera.ClearPlayerWeaponMode();
- }
- SetCurrentWeapon(weapon);
-
- GetWeapon()->m_nAmmoInClip = min(GetWeapon()->m_nAmmoTotal, CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_nAmountofAmmunition);
-
- if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bCanAim))
- ClearWeaponTarget();
-
- CAnimBlendAssociation *weaponAnim = RpAnimBlendClumpGetAssociation(GetClump(), CWeaponInfo::GetWeaponInfo(WEAPONTYPE_SNIPERRIFLE)->m_AnimToPlay);
- if (weaponAnim) {
- weaponAnim->SetRun();
- weaponAnim->flags |= ASSOC_FADEOUTWHENDONE;
- }
- TheCamera.ClearPlayerWeaponMode();
-}
-
-void
-CPlayerPed::ReApplyMoveAnims(void)
-{
- static AnimationId moveAnims[] = { ANIM_WALK, ANIM_RUN, ANIM_SPRINT, ANIM_IDLE_STANCE, ANIM_WALK_START };
-
- for(int i = 0; i < ARRAY_SIZE(moveAnims); i++) {
- CAnimBlendAssociation *curMoveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), moveAnims[i]);
- if (curMoveAssoc) {
- if (strcmp(CAnimManager::GetAnimAssociation(m_animGroup, moveAnims[i])->hierarchy->name, curMoveAssoc->hierarchy->name) != 0) {
- CAnimBlendAssociation *newMoveAssoc = CAnimManager::AddAnimation(GetClump(), m_animGroup, moveAnims[i]);
- newMoveAssoc->blendDelta = curMoveAssoc->blendDelta;
- newMoveAssoc->blendAmount = curMoveAssoc->blendAmount;
- curMoveAssoc->blendDelta = -1000.0f;
- curMoveAssoc->flags |= ASSOC_DELETEFADEDOUT;
- }
- }
- }
-}
-
-void
-CPlayerPed::SetInitialState(void)
-{
- m_bAdrenalineActive = false;
- m_nAdrenalineTime = 0;
- CTimer::SetTimeStep(1.0f);
- m_pSeekTarget = nil;
- m_vecSeekPos = { 0.0f, 0.0f, 0.0f };
- m_fleeFromPosX = 0.0f;
- m_fleeFromPosY = 0.0f;
- m_fleeFrom = nil;
- m_fleeTimer = 0;
- m_objective = OBJECTIVE_NONE;
- m_prevObjective = OBJECTIVE_NONE;
- bUsesCollision = true;
- ClearAimFlag();
- ClearLookFlag();
- bIsPointingGunAt = false;
- bRenderPedInCar = true;
- if (m_pFire)
- m_pFire->Extinguish();
- RpAnimBlendClumpRemoveAllAssociations(GetClump());
- m_nPedState = PED_IDLE;
- SetMoveState(PEDMOVE_STILL);
- m_nLastPedState = PED_NONE;
- m_animGroup = ASSOCGRP_PLAYER;
- m_fMoveSpeed = 0.0f;
- m_nSelectedWepSlot = WEAPONTYPE_UNARMED;
- m_nEvadeAmount = 0;
- m_pEvadingFrom = nil;
- bIsPedDieAnimPlaying = false;
- SetRealMoveAnim();
- m_bCanBeDamaged = true;
- m_pedStats->m_temper = 50;
- m_fWalkAngle = 0.0f;
-}
-
-void
-CPlayerPed::SetRealMoveAnim(void)
-{
- CAnimBlendAssociation *curWalkAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WALK);
- CAnimBlendAssociation *curRunAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN);
- CAnimBlendAssociation *curSprintAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_SPRINT);
- CAnimBlendAssociation *curWalkStartAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WALK_START);
- CAnimBlendAssociation *curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_STANCE);
- CAnimBlendAssociation *curRunStopAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN_STOP);
- CAnimBlendAssociation *curRunStopRAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN_STOP_R);
- if (bResetWalkAnims) {
- if (curWalkAssoc)
- curWalkAssoc->SetCurrentTime(0.0f);
- if (curRunAssoc)
- curRunAssoc->SetCurrentTime(0.0f);
- if (curSprintAssoc)
- curSprintAssoc->SetCurrentTime(0.0f);
- bResetWalkAnims = false;
- }
-
- if (!curIdleAssoc)
- curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED);
- if (!curIdleAssoc)
- curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE);
-
- if ((!curRunStopAssoc || !(curRunStopAssoc->IsRunning())) && (!curRunStopRAssoc || !(curRunStopRAssoc->IsRunning()))) {
-
- if (curRunStopAssoc && curRunStopAssoc->blendDelta >= 0.0f || curRunStopRAssoc && curRunStopRAssoc->blendDelta >= 0.0f) {
- if (curRunStopAssoc) {
- curRunStopAssoc->flags |= ASSOC_DELETEFADEDOUT;
- curRunStopAssoc->blendAmount = 1.0f;
- curRunStopAssoc->blendDelta = -8.0f;
- } else if (curRunStopRAssoc) {
- curRunStopRAssoc->flags |= ASSOC_DELETEFADEDOUT;
- curRunStopRAssoc->blendAmount = 1.0f;
- curRunStopRAssoc->blendDelta = -8.0f;
- }
-
- RestoreHeadingRate();
- if (!curIdleAssoc) {
- if (m_fCurrentStamina < 0.0f && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f,
- nil, true, false, false, false, false, false)) {
- curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 8.0f);
-
- } else {
- curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 8.0f);
- }
- m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(2500, 4000);
- }
- curIdleAssoc->blendAmount = 0.0f;
- curIdleAssoc->blendDelta = 8.0f;
-
- } else if (m_fMoveSpeed == 0.0f && !curSprintAssoc) {
- if (!curIdleAssoc) {
- if (m_fCurrentStamina < 0.0f && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f,
- nil, true, false, false, false, false, false)) {
- curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 4.0f);
-
- } else {
- curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f);
- }
-
- m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(2500, 4000);
- }
-
- if (m_fCurrentStamina > 0.0f && curIdleAssoc->animId == ANIM_IDLE_TIRED) {
- CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f);
-
- } else if (m_nPedState != PED_FIGHT) {
- if (m_fCurrentStamina < 0.0f && curIdleAssoc->animId != ANIM_IDLE_TIRED
- && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f, nil, true, false, false, false, false, false)) {
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 4.0f);
-
- } else if (curIdleAssoc->animId != ANIM_IDLE_STANCE) {
- CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f);
- }
- }
-
- m_nMoveState = PEDMOVE_STILL;
- } else {
- if (curIdleAssoc) {
- if (curWalkStartAssoc) {
- curWalkStartAssoc->blendAmount = 1.0f;
- curWalkStartAssoc->blendDelta = 0.0f;
- } else {
- curWalkStartAssoc = CAnimManager::AddAnimation(GetClump(), m_animGroup, ANIM_WALK_START);
- }
- if (curWalkAssoc)
- curWalkAssoc->SetCurrentTime(0.0f);
- if (curRunAssoc)
- curRunAssoc->SetCurrentTime(0.0f);
-
- delete curIdleAssoc;
- delete RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED);
- delete RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE);
- delete curSprintAssoc;
-
- curSprintAssoc = nil;
- m_nMoveState = PEDMOVE_WALK;
- }
- if (curRunStopAssoc) {
- delete curRunStopAssoc;
- RestoreHeadingRate();
- }
- if (curRunStopRAssoc) {
- delete curRunStopRAssoc;
- RestoreHeadingRate();
- }
- if (!curWalkAssoc) {
- curWalkAssoc = CAnimManager::AddAnimation(GetClump(), m_animGroup, ANIM_WALK);
- curWalkAssoc->blendAmount = 0.0f;
- }
- if (!curRunAssoc) {
- curRunAssoc = CAnimManager::AddAnimation(GetClump(), m_animGroup, ANIM_RUN);
- curRunAssoc->blendAmount = 0.0f;
- }
- if (curWalkStartAssoc && !(curWalkStartAssoc->IsRunning())) {
- delete curWalkStartAssoc;
- curWalkStartAssoc = nil;
- curWalkAssoc->SetRun();
- curRunAssoc->SetRun();
- }
- if (m_nMoveState == PEDMOVE_SPRINT) {
- if (m_fCurrentStamina < 0.0f && (m_fCurrentStamina <= -150.0f || !curSprintAssoc || curSprintAssoc->blendDelta < 0.0f))
- m_nMoveState = PEDMOVE_STILL;
-
- if (curWalkStartAssoc)
- m_nMoveState = PEDMOVE_STILL;
- }
-
- if (curSprintAssoc && (m_nMoveState != PEDMOVE_SPRINT || m_fMoveSpeed < 0.4f)) {
- if (curSprintAssoc->blendAmount == 0.0f) {
- curSprintAssoc->blendDelta = -1000.0f;
- curSprintAssoc->flags |= ASSOC_DELETEFADEDOUT;
-
- } else if (curSprintAssoc->blendDelta >= 0.0f || curSprintAssoc->blendAmount >= 0.8f) {
- if (m_fMoveSpeed < 0.4f) {
- AnimationId runStopAnim;
- if (curSprintAssoc->currentTime / curSprintAssoc->hierarchy->totalLength < 0.5) // double
- runStopAnim = ANIM_RUN_STOP;
- else
- runStopAnim = ANIM_RUN_STOP_R;
- CAnimBlendAssociation* newRunStopAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, runStopAnim);
- newRunStopAssoc->blendAmount = 1.0f;
- newRunStopAssoc->SetDeleteCallback(RestoreHeadingRateCB, this);
- m_headingRate = 0.0f;
- curSprintAssoc->flags |= ASSOC_DELETEFADEDOUT;
- curSprintAssoc->blendDelta = -1000.0f;
- curWalkAssoc->flags &= ~ASSOC_RUNNING;
- curWalkAssoc->blendAmount = 0.0f;
- curWalkAssoc->blendDelta = 0.0f;
- curRunAssoc->flags &= ~ASSOC_RUNNING;
- curRunAssoc->blendAmount = 0.0f;
- curRunAssoc->blendDelta = 0.0f;
- } else if (curSprintAssoc->blendDelta >= 0.0f) {
-
- // Stop sprinting when tired
- curSprintAssoc->flags |= ASSOC_DELETEFADEDOUT;
- curSprintAssoc->blendDelta = -1.0f;
- curRunAssoc->blendDelta = 1.0f;
- }
- } else if (m_fMoveSpeed < 1.0f) {
- curSprintAssoc->blendDelta = -8.0f;
- curRunAssoc->blendDelta = 8.0f;
- }
- } else if (curWalkStartAssoc) {
- curWalkAssoc->flags &= ~ASSOC_RUNNING;
- curRunAssoc->flags &= ~ASSOC_RUNNING;
- curWalkAssoc->blendAmount = 0.0f;
- curRunAssoc->blendAmount = 0.0f;
-
- } else if (m_nMoveState == PEDMOVE_SPRINT) {
- if (curSprintAssoc) {
- if (curSprintAssoc->blendDelta < 0.0f) {
- curSprintAssoc->blendDelta = 2.0f;
- curRunAssoc->blendDelta = -2.0f;
- }
- } else {
- curWalkAssoc->blendAmount = 0.0f;
- curRunAssoc->blendAmount = 1.0f;
- curSprintAssoc = CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_SPRINT, 2.0f);
- }
- UseSprintEnergy();
- } else {
- if (m_fMoveSpeed < 1.0f) {
- curWalkAssoc->blendAmount = 1.0f;
- curRunAssoc->blendAmount = 0.0f;
- m_nMoveState = PEDMOVE_WALK;
- } else if (m_fMoveSpeed < 2.0f) {
- curWalkAssoc->blendAmount = 2.0f - m_fMoveSpeed;
- curRunAssoc->blendAmount = m_fMoveSpeed - 1.0f;
- m_nMoveState = PEDMOVE_RUN;
- } else {
- curWalkAssoc->blendAmount = 0.0f;
- curRunAssoc->blendAmount = 1.0f;
- m_nMoveState = PEDMOVE_RUN;
- }
- }
- }
- }
- if (m_bAdrenalineActive) {
- if (CTimer::GetTimeInMilliseconds() > m_nAdrenalineTime) {
- m_bAdrenalineActive = false;
- CTimer::SetTimeScale(1.0f);
- if (curWalkStartAssoc)
- curWalkStartAssoc->speed = 1.0f;
- if (curWalkAssoc)
- curWalkAssoc->speed = 1.0f;
- if (curRunAssoc)
- curRunAssoc->speed = 1.0f;
- if (curSprintAssoc)
- curSprintAssoc->speed = 1.0f;
- } else {
- CTimer::SetTimeScale(1.0f / 3);
- if (curWalkStartAssoc)
- curWalkStartAssoc->speed = 2.0f;
- if (curWalkAssoc)
- curWalkAssoc->speed = 2.0f;
- if (curRunAssoc)
- curRunAssoc->speed = 2.0f;
- if (curSprintAssoc)
- curSprintAssoc->speed = 2.0f;
- }
- }
-}
-
-void
-CPlayerPed::RestoreSprintEnergy(float restoreSpeed)
-{
- if (m_fCurrentStamina < m_fMaxStamina)
- m_fCurrentStamina += restoreSpeed * CTimer::GetTimeStep() * 0.5f;
-}
-
-bool
-CPlayerPed::DoWeaponSmoothSpray(void)
-{
- if (m_nPedState == PED_ATTACK && !m_pPointGunAt) {
- eWeaponType weapon = GetWeapon()->m_eWeaponType;
- if (weapon == WEAPONTYPE_FLAMETHROWER || weapon == WEAPONTYPE_COLT45 || weapon == WEAPONTYPE_UZI || weapon == WEAPONTYPE_SHOTGUN ||
- weapon == WEAPONTYPE_AK47 || weapon == WEAPONTYPE_M16 || weapon == WEAPONTYPE_HELICANNON)
- return true;
- }
- return false;
-}
-
-void
-CPlayerPed::DoStuffToGoOnFire(void)
-{
- if (m_nPedState == PED_SNIPER_MODE)
- TheCamera.ClearPlayerWeaponMode();
-}
-
-bool
-CPlayerPed::DoesTargetHaveToBeBroken(CVector target, CWeapon *weaponUsed)
-{
- CVector distVec = target - GetPosition();
-
- if (distVec.Magnitude() > CWeaponInfo::GetWeaponInfo(weaponUsed->m_eWeaponType)->m_fRange)
- return true;
-
- if (weaponUsed->m_eWeaponType != WEAPONTYPE_SHOTGUN && weaponUsed->m_eWeaponType != WEAPONTYPE_AK47)
- return false;
-
- distVec.Normalise();
-
- if (DotProduct(distVec,GetForward()) < 0.4f)
- return true;
-
- return false;
-}
-
-// Cancels landing anim while running & jumping? I think
-void
-CPlayerPed::RunningLand(CPad *padUsed)
-{
- CAnimBlendAssociation *landAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FALL_LAND);
- if (landAssoc && landAssoc->currentTime == 0.0f && m_fMoveSpeed > 1.5f
- && padUsed && (padUsed->GetPedWalkLeftRight() != 0.0f || padUsed->GetPedWalkUpDown() != 0.0f)) {
-
- landAssoc->blendDelta = -1000.0f;
- landAssoc->flags |= ASSOC_DELETEFADEDOUT;
-
- CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_JUMP_LAND)->SetFinishCallback(FinishJumpCB, this);
-
- if (m_nPedState == PED_JUMP)
- RestorePreviousState();
- }
-}
-
-bool
-CPlayerPed::IsThisPedAttackingPlayer(CPed *suspect)
-{
- if (suspect->m_pPointGunAt == this)
- return true;
-
- switch (suspect->m_objective) {
- case OBJECTIVE_KILL_CHAR_ON_FOOT:
- case OBJECTIVE_KILL_CHAR_ANY_MEANS:
- if (suspect->m_pedInObjective == this)
- return true;
-
- break;
- default:
- break;
- }
- return false;
-}
-
-void
-CPlayerPed::PlayerControlSniper(CPad *padUsed)
-{
- ProcessWeaponSwitch(padUsed);
- TheCamera.PlayerExhaustion = (1.0f - (m_fCurrentStamina - -150.0f) / 300.0f) * 0.9f + 0.1f;
-
- if (!padUsed->GetTarget()) {
- RestorePreviousState();
- TheCamera.ClearPlayerWeaponMode();
- }
-
- if (padUsed->WeaponJustDown()) {
- CVector firePos(0.0f, 0.0f, 0.6f);
- firePos = GetMatrix() * firePos;
- GetWeapon()->Fire(this, &firePos);
- }
- GetWeapon()->Update(m_audioEntityId);
-}
-
-// I think R* also used goto in here.
-void
-CPlayerPed::ProcessWeaponSwitch(CPad *padUsed)
-{
- if (CDarkel::FrenzyOnGoing())
- goto switchDetectDone;
-
- if (padUsed->CycleWeaponRightJustDown() && !m_pPointGunAt) {
-
- if (TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON_RUNABOUT
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER_RUNABOUT
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER_RUNABOUT) {
-
- for (m_nSelectedWepSlot = m_currentWeapon + 1; m_nSelectedWepSlot < WEAPONTYPE_TOTAL_INVENTORY_WEAPONS; ++m_nSelectedWepSlot) {
- if (HasWeapon(m_nSelectedWepSlot) && GetWeapon(m_nSelectedWepSlot).HasWeaponAmmoToBeUsed()) {
- goto switchDetectDone;
- }
- }
- m_nSelectedWepSlot = WEAPONTYPE_UNARMED;
- }
- } else if (padUsed->CycleWeaponLeftJustDown() && !m_pPointGunAt) {
- if (TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER) {
-
- for (m_nSelectedWepSlot = m_currentWeapon - 1; ; --m_nSelectedWepSlot) {
- if (m_nSelectedWepSlot < WEAPONTYPE_UNARMED)
- m_nSelectedWepSlot = WEAPONTYPE_DETONATOR;
-
- if (HasWeapon(m_nSelectedWepSlot) && GetWeapon(m_nSelectedWepSlot).HasWeaponAmmoToBeUsed()) {
- goto switchDetectDone;
- }
- }
- }
- } else if (CWeaponInfo::GetWeaponInfo((eWeaponType)m_currentWeapon)->m_eWeaponFire != WEAPON_FIRE_MELEE) {
- if (GetWeapon(m_currentWeapon).m_nAmmoTotal <= 0) {
- if (TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER) {
-
- for (m_nSelectedWepSlot = m_currentWeapon - 1; m_nSelectedWepSlot >= 0; --m_nSelectedWepSlot) {
- if (m_nSelectedWepSlot == WEAPONTYPE_BASEBALLBAT && HasWeapon(WEAPONTYPE_BASEBALLBAT)
- || GetWeapon(m_nSelectedWepSlot).m_nAmmoTotal > 0 && m_nSelectedWepSlot != WEAPONTYPE_MOLOTOV && m_nSelectedWepSlot != WEAPONTYPE_GRENADE) {
- goto switchDetectDone;
- }
- }
- m_nSelectedWepSlot = WEAPONTYPE_UNARMED;
- }
- }
- }
-
-switchDetectDone:
- if (m_nSelectedWepSlot != m_currentWeapon) {
- if (m_nPedState != PED_ATTACK && m_nPedState != PED_AIM_GUN && m_nPedState != PED_FIGHT)
- MakeChangesForNewWeapon(m_nSelectedWepSlot);
- }
-}
-
-void
-CPlayerPed::PlayerControlM16(CPad *padUsed)
-{
- ProcessWeaponSwitch(padUsed);
- TheCamera.PlayerExhaustion = (1.0f - (m_fCurrentStamina - -150.0f) / 300.0f) * 0.9f + 0.1f;
-
- if (!padUsed->GetTarget()) {
- RestorePreviousState();
- TheCamera.ClearPlayerWeaponMode();
- }
-
- if (padUsed->GetWeapon()) {
- CVector firePos(0.0f, 0.0f, 0.6f);
- firePos = GetMatrix() * firePos;
- GetWeapon()->Fire(this, &firePos);
- }
- GetWeapon()->Update(m_audioEntityId);
-}
-
-void
-CPlayerPed::PlayerControlFighter(CPad *padUsed)
-{
- float leftRight = padUsed->GetPedWalkLeftRight();
- float upDown = padUsed->GetPedWalkUpDown();
- float padMove = CVector2D(leftRight, upDown).Magnitude();
-
- if (padMove > 0.0f) {
- m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(0.0f, 0.0f, -leftRight, upDown) - TheCamera.Orientation;
- m_takeAStepAfterAttack = padMove > 2 * PAD_MOVE_TO_GAME_WORLD_MOVE;
- if (padUsed->GetSprint() && padMove > 1 * PAD_MOVE_TO_GAME_WORLD_MOVE)
- bIsAttacking = false;
- }
-
- if (!CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy && padUsed->JumpJustDown()) {
- if (m_nEvadeAmount != 0 && m_pEvadingFrom) {
- SetEvasiveDive((CPhysical*)m_pEvadingFrom, 1);
- m_nEvadeAmount = 0;
- m_pEvadingFrom = nil;
- } else {
- SetJump();
- }
- }
-}
-
-void
-CPlayerPed::PlayerControl1stPersonRunAround(CPad *padUsed)
-{
- float leftRight = padUsed->GetPedWalkLeftRight();
- float upDown = padUsed->GetPedWalkUpDown();
- float padMove = CVector2D(leftRight, upDown).Magnitude();
- float padMoveInGameUnit = padMove / PAD_MOVE_TO_GAME_WORLD_MOVE;
- if (padMoveInGameUnit > 0.0f) {
-#ifdef FREE_CAM
- if (!CCamera::bFreeCam)
- m_fRotationDest = CGeneral::LimitRadianAngle(TheCamera.Orientation);
- else
- m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(0.0f, 0.0f, -leftRight, upDown) - TheCamera.Orientation;
-#else
- m_fRotationDest = CGeneral::LimitRadianAngle(TheCamera.Orientation);
-#endif
- m_fMoveSpeed = min(padMoveInGameUnit, 0.07f * CTimer::GetTimeStep() + m_fMoveSpeed);
- } else {
- m_fMoveSpeed = 0.0f;
- }
-
- if (m_nPedState == PED_JUMP) {
- if (bIsInTheAir) {
- if (bUsesCollision && !bHitSteepSlope &&
- (!bHitSomethingLastFrame || m_vecDamageNormal.z > 0.6f)
- && m_fDistanceTravelled < CTimer::GetTimeStep() * 0.02 && m_vecMoveSpeed.MagnitudeSqr() < 0.01f) {
-
- float angleSin = Sin(m_fRotationCur); // originally sin(DEGTORAD(RADTODEG(m_fRotationCur))) o_O
- float angleCos = Cos(m_fRotationCur);
- ApplyMoveForce(-angleSin * 3.0f, 3.0f * angleCos, 0.05f);
- }
- } else if (bIsLanding) {
- m_fMoveSpeed = 0.0f;
- }
- }
- if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy)
- && padUsed->GetSprint()) {
- m_nMoveState = PEDMOVE_SPRINT;
- }
- if (m_nPedState != PED_FIGHT)
- SetRealMoveAnim();
-
- if (!bIsInTheAir && !(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy)
- && padUsed->JumpJustDown() && m_nPedState != PED_JUMP) {
- ClearAttack();
- ClearWeaponTarget();
- if (m_nEvadeAmount != 0 && m_pEvadingFrom) {
- SetEvasiveDive((CPhysical*)m_pEvadingFrom, 1);
- m_nEvadeAmount = 0;
- m_pEvadingFrom = nil;
- } else {
- SetJump();
- }
- }
-}
-
-void
-CPlayerPed::KeepAreaAroundPlayerClear(void)
-{
- BuildPedLists();
- for (int i = 0; i < m_numNearPeds; ++i) {
- CPed *nearPed = m_nearPeds[i];
- if (nearPed->CharCreatedBy == RANDOM_CHAR && !nearPed->DyingOrDead()) {
- if (nearPed->GetIsOnScreen()) {
- if (nearPed->m_objective == OBJECTIVE_NONE) {
- nearPed->SetFindPathAndFlee(this, 5000, true);
- } else {
- if (nearPed->EnteringCar())
- nearPed->QuitEnteringCar();
-
- nearPed->ClearObjective();
- }
- } else {
- nearPed->FlagToDestroyWhenNextProcessed();
- }
- }
- }
- CVector playerPos = (InVehicle() ? m_pMyVehicle->GetPosition() : GetPosition());
-
- CVector pos = GetPosition();
- int16 lastVehicle;
- CEntity *vehicles[8];
- CWorld::FindObjectsInRange(pos, CHECK_NEARBY_THINGS_MAX_DIST, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
-
- for (int i = 0; i < lastVehicle; i++) {
- CVehicle *veh = (CVehicle*)vehicles[i];
- if (veh->VehicleCreatedBy != MISSION_VEHICLE) {
- if (veh->m_status != STATUS_PLAYER && veh->m_status != STATUS_PLAYER_DISABLED) {
- if ((veh->GetPosition() - playerPos).MagnitudeSqr() > 25.0f) {
- veh->AutoPilot.m_nTempAction = TEMPACT_WAIT;
- veh->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 5000;
- } else {
- if (DotProduct2D(playerPos - veh->GetPosition(), veh->GetForward()) > 0.0f)
- veh->AutoPilot.m_nTempAction = TEMPACT_REVERSE;
- else
- veh->AutoPilot.m_nTempAction = TEMPACT_GOFORWARD;
-
- veh->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 2000;
- }
- CCarCtrl::PossiblyRemoveVehicle(veh);
- }
- }
- }
-}
-
-void
-CPlayerPed::EvaluateNeighbouringTarget(CEntity *candidate, CEntity **targetPtr, float *lastCloseness, float distLimit, float angleOffset, bool lookToLeft)
-{
- CVector distVec = candidate->GetPosition() - GetPosition();
- if (distVec.Magnitude2D() <= distLimit) {
- if (!DoesTargetHaveToBeBroken(candidate->GetPosition(), GetWeapon())) {
-#ifdef VC_PED_PORTS
- float angleBetweenUs = CGeneral::GetATanOfXY(candidate->GetPosition().x - TheCamera.GetPosition().x,
- candidate->GetPosition().y - TheCamera.GetPosition().y);
-#else
- float angleBetweenUs = CGeneral::GetATanOfXY(distVec.x, distVec.y);
-#endif
- angleBetweenUs = CGeneral::LimitAngle(angleBetweenUs - angleOffset);
- float closeness;
- if (lookToLeft) {
- closeness = angleBetweenUs > 0.0f ? -Abs(angleBetweenUs) : -100000.0f;
- } else {
- closeness = angleBetweenUs > 0.0f ? -100000.0f : -Abs(angleBetweenUs);
- }
-
- if (closeness > *lastCloseness) {
- *targetPtr = candidate;
- *lastCloseness = closeness;
- }
- }
- }
-}
-
-void
-CPlayerPed::EvaluateTarget(CEntity *candidate, CEntity **targetPtr, float *lastCloseness, float distLimit, float angleOffset, bool priority)
-{
- CVector distVec = candidate->GetPosition() - GetPosition();
- float dist = distVec.Magnitude2D();
- if (dist <= distLimit) {
- if (!DoesTargetHaveToBeBroken(candidate->GetPosition(), GetWeapon())) {
- float angleBetweenUs = CGeneral::GetATanOfXY(distVec.x, distVec.y);
- angleBetweenUs = CGeneral::LimitAngle(angleBetweenUs - angleOffset);
-
- float closeness = -dist - 5.0f * Abs(angleBetweenUs);
- if (priority) {
- closeness += 5.0f;
- }
-
- if (closeness > *lastCloseness) {
- *targetPtr = candidate;
- *lastCloseness = closeness;
- }
- }
- }
-}
-
-bool
-CPlayerPed::FindNextWeaponLockOnTarget(CEntity *previousTarget, bool lookToLeft)
-{
- CEntity *nextTarget = nil;
- float weaponRange = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_fRange;
- // nextTarget = nil;
- float lastCloseness = -10000.0f;
- // unused
- // CGeneral::GetATanOfXY(GetForward().x, GetForward().y);
- CVector distVec = previousTarget->GetPosition() - GetPosition();
- float referenceBeta = CGeneral::GetATanOfXY(distVec.x, distVec.y);
-
- for (int h = CPools::GetPedPool()->GetSize() - 1; h >= 0; h--) {
- CPed *pedToCheck = CPools::GetPedPool()->GetSlot(h);
- if (pedToCheck) {
- if (pedToCheck != FindPlayerPed() && pedToCheck != previousTarget) {
- if (!pedToCheck->DyingOrDead() && !pedToCheck->bInVehicle
- && pedToCheck->m_leader != FindPlayerPed() && OurPedCanSeeThisOne(pedToCheck)) {
-
- EvaluateNeighbouringTarget(pedToCheck, &nextTarget, &lastCloseness,
- weaponRange, referenceBeta, lookToLeft);
- }
- }
- }
- }
- for (int i = 0; i < ARRAY_SIZE(m_nTargettableObjects); i++) {
- CObject *obj = CPools::GetObjectPool()->GetAt(m_nTargettableObjects[i]);
- if (obj)
- EvaluateNeighbouringTarget(obj, &nextTarget, &lastCloseness, weaponRange, referenceBeta, lookToLeft);
- }
- if (!nextTarget)
- return false;
-
- m_pPointGunAt = nextTarget;
- if (nextTarget)
- nextTarget->RegisterReference((CEntity**)&m_pPointGunAt);
- SetPointGunAt(nextTarget);
- return true;
-}
-
-bool
-CPlayerPed::FindWeaponLockOnTarget(void)
-{
- CEntity *nextTarget = nil;
- float weaponRange = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_fRange;
-
- if (m_pPointGunAt) {
- CVector distVec = m_pPointGunAt->GetPosition() - GetPosition();
- if (distVec.Magnitude2D() > weaponRange) {
- m_pPointGunAt = nil;
- return false;
- } else {
- return true;
- }
- }
-
- // nextTarget = nil;
- float lastCloseness = -10000.0f;
- float referenceBeta = CGeneral::GetATanOfXY(GetForward().x, GetForward().y);
- for (int h = CPools::GetPedPool()->GetSize() - 1; h >= 0; h--) {
- CPed *pedToCheck = CPools::GetPedPool()->GetSlot(h);
- if (pedToCheck) {
- if (pedToCheck != FindPlayerPed()) {
- if (!pedToCheck->DyingOrDead() && !pedToCheck->bInVehicle
- && pedToCheck->m_leader != FindPlayerPed() && OurPedCanSeeThisOne(pedToCheck)) {
-
- EvaluateTarget(pedToCheck, &nextTarget, &lastCloseness,
- weaponRange, referenceBeta, IsThisPedAttackingPlayer(pedToCheck));
- }
- }
- }
- }
- for (int i = 0; i < ARRAY_SIZE(m_nTargettableObjects); i++) {
- CObject *obj = CPools::GetObjectPool()->GetAt(m_nTargettableObjects[i]);
- if (obj)
- EvaluateTarget(obj, &nextTarget, &lastCloseness, weaponRange, referenceBeta, false);
- }
- if (!nextTarget)
- return false;
-
- m_pPointGunAt = nextTarget;
- if (nextTarget)
- nextTarget->RegisterReference((CEntity**)&m_pPointGunAt);
- SetPointGunAt(nextTarget);
- return true;
-}
-
-void
-CPlayerPed::ProcessAnimGroups(void)
-{
- AssocGroupId groupToSet;
- if ((m_fWalkAngle <= -DEGTORAD(50.0f) || m_fWalkAngle >= DEGTORAD(50.0f))
- && TheCamera.Cams[TheCamera.ActiveCam].Using3rdPersonMouseCam()
- && CanStrafeOrMouseControl()) {
-
- if (m_fWalkAngle >= -DEGTORAD(130.0f) && m_fWalkAngle <= DEGTORAD(130.0f)) {
- if (m_fWalkAngle > 0.0f) {
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER)
- groupToSet = ASSOCGRP_ROCKETLEFT;
- else
- groupToSet = ASSOCGRP_PLAYERLEFT;
- } else {
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER)
- groupToSet = ASSOCGRP_ROCKETRIGHT;
- else
- groupToSet = ASSOCGRP_PLAYERRIGHT;
- }
- } else {
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER)
- groupToSet = ASSOCGRP_ROCKETBACK;
- else
- groupToSet = ASSOCGRP_PLAYERBACK;
- }
- } else {
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER) {
- groupToSet = ASSOCGRP_PLAYERROCKET;
- } else {
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT) {
- groupToSet = ASSOCGRP_PLAYERBBBAT;
- } else if (GetWeapon()->m_eWeaponType != WEAPONTYPE_COLT45 && GetWeapon()->m_eWeaponType != WEAPONTYPE_UZI) {
- if (!GetWeapon()->IsType2Handed()) {
- groupToSet = ASSOCGRP_PLAYER;
- } else {
- groupToSet = ASSOCGRP_PLAYER2ARMED;
- }
- } else {
- groupToSet = ASSOCGRP_PLAYER1ARMED;
- }
- }
- }
-
- if (m_animGroup != groupToSet) {
- m_animGroup = groupToSet;
- ReApplyMoveAnims();
- }
-}
-
-void
-CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
-{
- CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
- if (m_bHasLockOnTarget && !m_pPointGunAt) {
- TheCamera.ClearPlayerWeaponMode();
- CWeaponEffects::ClearCrossHair();
- ClearPointGunAt();
- }
- if (!m_pFire) {
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER ||
- GetWeapon()->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE || GetWeapon()->m_eWeaponType == WEAPONTYPE_M16) {
- if (padUsed->TargetJustDown()) {
- SetStoredState();
- m_nPedState = PED_SNIPER_MODE;
-#ifdef FREE_CAM
- if (CCamera::bFreeCam && TheCamera.Cams[0].Using3rdPersonMouseCam()) {
- m_fRotationCur = CGeneral::LimitRadianAngle(-TheCamera.Orientation);
- SetHeading(m_fRotationCur);
- }
-#endif
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER)
- TheCamera.SetNewPlayerWeaponMode(CCam::MODE_ROCKETLAUNCHER, 0, 0);
- else if (GetWeapon()->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE)
- TheCamera.SetNewPlayerWeaponMode(CCam::MODE_SNIPER, 0, 0);
- else
- TheCamera.SetNewPlayerWeaponMode(CCam::MODE_M16_1STPERSON, 0, 0);
-
- m_fMoveSpeed = 0.0f;
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_STANCE, 1000.0f);
- }
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER || GetWeapon()->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE
- || TheCamera.PlayerWeaponMode.Mode == CCam::MODE_M16_1STPERSON)
- return;
- }
- }
-
- if (padUsed->GetWeapon() && m_nMoveState != PEDMOVE_SPRINT) {
- if (m_nSelectedWepSlot == m_currentWeapon) {
- if (m_pPointGunAt) {
-#ifdef FREE_CAM
- if (CCamera::bFreeCam && weaponInfo->m_eWeaponFire == WEAPON_FIRE_MELEE && m_fMoveSpeed < 1.0f)
- StartFightAttack(padUsed->GetWeapon());
- else
-#endif
- SetAttack(m_pPointGunAt);
- } else if (m_currentWeapon != WEAPONTYPE_UNARMED) {
- if (m_nPedState == PED_ATTACK) {
- if (padUsed->WeaponJustDown()) {
- m_bHaveTargetSelected = true;
- } else if (!m_bHaveTargetSelected) {
- field_1376 += CTimer::GetTimeStepNonClipped();
- }
- } else {
- field_1376 = 0.0f;
- m_bHaveTargetSelected = false;
- }
- SetAttack(nil);
- } else if (padUsed->WeaponJustDown()) {
- if (m_fMoveSpeed < 1.0f)
- StartFightAttack(padUsed->GetWeapon());
- else
- SetAttack(nil);
- }
- }
- } else {
- m_pedIK.m_flags &= ~CPedIK::LOOKAROUND_HEAD_ONLY;
- if (m_nPedState == PED_ATTACK) {
- m_bHaveTargetSelected = true;
- bIsAttacking = false;
- }
- }
-
-#ifdef FREE_CAM
- // Rotate player/arm when shooting. We don't have auto-rotation anymore
- if (CCamera::m_bUseMouse3rdPerson && CCamera::bFreeCam &&
- m_nSelectedWepSlot == m_currentWeapon && m_nMoveState != PEDMOVE_SPRINT) {
-
- // Weapons except throwable and melee ones
- if (weaponInfo->m_bCanAim || weaponInfo->m_b1stPerson || weaponInfo->m_bExpands) {
- if ((padUsed->GetTarget() && weaponInfo->m_bCanAimWithArm) || padUsed->GetWeapon()) {
- float limitedCam = CGeneral::LimitRadianAngle(-TheCamera.Orientation);
-
- // On this one we can rotate arm.
- if (weaponInfo->m_bCanAimWithArm) {
- if (!padUsed->GetWeapon()) { // making this State != ATTACK still stops it after attack. Re-start it immediately!
- SetPointGunAt(nil);
- bIsPointingGunAt = false; // to not stop after attack
- }
-
- SetLookFlag(limitedCam, true);
- SetAimFlag(limitedCam);
-#ifdef VC_PED_PORTS
- SetLookTimer(INT_MAX); // removing this makes head move for real, but I experinced some bugs.
-#endif
- } else {
- m_fRotationDest = limitedCam;
- m_headingRate = 50.0f;
-
- // Anim. fix for shotgun, ak47 and m16 (we must finish rot. it quickly)
- if (weaponInfo->m_bCanAim && padUsed->WeaponJustDown()) {
- m_fRotationCur = CGeneral::LimitRadianAngle(m_fRotationCur);
- float limitedRotDest = m_fRotationDest;
-
- if (m_fRotationCur - PI > m_fRotationDest) {
- limitedRotDest += 2 * PI;
- } else if (PI + m_fRotationCur < m_fRotationDest) {
- limitedRotDest -= 2 * PI;
- }
-
- m_fRotationCur += (limitedRotDest - m_fRotationCur) / 2;
- }
- }
- } else if (weaponInfo->m_bCanAimWithArm)
- ClearPointGunAt();
- else
- RestoreHeadingRate();
- }
- }
-#endif
-
- if (padUsed->GetTarget() && m_nSelectedWepSlot == m_currentWeapon && m_nMoveState != PEDMOVE_SPRINT) {
- if (m_pPointGunAt) {
- // what??
- if (!m_pPointGunAt
-#ifdef FREE_CAM
- || (!CCamera::bFreeCam && CCamera::m_bUseMouse3rdPerson)
-#else
- || CCamera::m_bUseMouse3rdPerson
-#endif
- || m_pPointGunAt->IsPed() && ((CPed*)m_pPointGunAt)->bInVehicle) {
- ClearWeaponTarget();
- return;
- }
- if (CPlayerPed::DoesTargetHaveToBeBroken(m_pPointGunAt->GetPosition(), GetWeapon())) {
- ClearWeaponTarget();
- return;
- }
- if (m_pPointGunAt) {
- if (padUsed->ShiftTargetLeftJustDown())
- FindNextWeaponLockOnTarget(m_pPointGunAt, true);
- if (padUsed->ShiftTargetRightJustDown())
- FindNextWeaponLockOnTarget(m_pPointGunAt, false);
- }
- TheCamera.SetNewPlayerWeaponMode(CCam::MODE_SYPHON, 0, 0);
- TheCamera.UpdateAimingCoors(m_pPointGunAt->GetPosition());
- }
-#ifdef FREE_CAM
- else if ((CCamera::bFreeCam && weaponInfo->m_eWeaponFire == WEAPON_FIRE_MELEE) || (weaponInfo->m_bCanAim && !CCamera::m_bUseMouse3rdPerson)) {
-#else
- else if (weaponInfo->m_bCanAim && !CCamera::m_bUseMouse3rdPerson) {
-#endif
- if (padUsed->TargetJustDown())
- FindWeaponLockOnTarget();
- }
- } else if (m_pPointGunAt) {
- ClearWeaponTarget();
- }
-
- if (m_pPointGunAt) {
-#ifndef VC_PED_PORTS
- CVector markPos = m_pPointGunAt->GetPosition();
-#else
- CVector markPos;
- if (m_pPointGunAt->IsPed()) {
- ((CPed*)m_pPointGunAt)->m_pedIK.GetComponentPosition((RwV3d*)markPos, PED_MID);
- } else {
- markPos = m_pPointGunAt->GetPosition();
- }
-#endif
- if (bCanPointGunAtTarget) {
- CWeaponEffects::MarkTarget(markPos, 64, 0, 0, 255, 0.8f);
- } else {
- CWeaponEffects::MarkTarget(markPos, 64, 32, 0, 255, 0.8f);
- }
- }
- m_bHasLockOnTarget = m_pPointGunAt != nil;
-}
-
-void
-CPlayerPed::PlayerControlZelda(CPad *padUsed)
-{
- bool doSmoothSpray = DoWeaponSmoothSpray();
- float camOrientation = TheCamera.Orientation;
- float leftRight = padUsed->GetPedWalkLeftRight();
- float upDown = padUsed->GetPedWalkUpDown();
- float padMoveInGameUnit;
- bool smoothSprayWithoutMove = false;
-
- if (doSmoothSpray && upDown > 0.0f) {
- padMoveInGameUnit = 0.0f;
- smoothSprayWithoutMove = true;
- } else {
- padMoveInGameUnit = CVector2D(leftRight, upDown).Magnitude() / PAD_MOVE_TO_GAME_WORLD_MOVE;
- }
-
- if (padMoveInGameUnit > 0.0f || smoothSprayWithoutMove) {
- float padHeading = CGeneral::GetRadianAngleBetweenPoints(0.0f, 0.0f, -leftRight, upDown);
- float neededTurn = CGeneral::LimitRadianAngle(padHeading - camOrientation);
- if (doSmoothSpray) {
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER || GetWeapon()->m_eWeaponType == WEAPONTYPE_COLT45
- || GetWeapon()->m_eWeaponType == WEAPONTYPE_UZI)
- m_fRotationDest = m_fRotationCur - leftRight / 128.0f * (PI / 80.0f) * CTimer::GetTimeStep();
- else
- m_fRotationDest = m_fRotationCur - leftRight / 128.0f * (PI / 128.0f) * CTimer::GetTimeStep();
- } else {
- m_fRotationDest = neededTurn;
- }
-
- float maxAcc = 0.07f * CTimer::GetTimeStep();
- m_fMoveSpeed = min(padMoveInGameUnit, m_fMoveSpeed + maxAcc);
-
- } else {
- m_fMoveSpeed = 0.0f;
- }
-
- if (m_nPedState == PED_JUMP) {
- if (bIsInTheAir) {
- if (bUsesCollision && !bHitSteepSlope &&
- (!bHitSomethingLastFrame || m_vecDamageNormal.z > 0.6f)
- && m_fDistanceTravelled < CTimer::GetTimeStep() * 0.02 && m_vecMoveSpeed.MagnitudeSqr() < 0.01f) {
-
- float angleSin = Sin(m_fRotationCur); // originally sin(DEGTORAD(RADTODEG(m_fRotationCur))) o_O
- float angleCos = Cos(m_fRotationCur);
- ApplyMoveForce(-angleSin * 3.0f, 3.0f * angleCos, 0.05f);
- }
- } else if (bIsLanding) {
- m_fMoveSpeed = 0.0f;
- }
- }
-
- if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy)
- && padUsed->GetSprint()) {
- m_nMoveState = PEDMOVE_SPRINT;
- }
- if (m_nPedState != PED_FIGHT)
- SetRealMoveAnim();
-
- if (!bIsInTheAir && !(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy)
- && padUsed->JumpJustDown() && m_nPedState != PED_JUMP) {
- ClearAttack();
- ClearWeaponTarget();
- if (m_nEvadeAmount != 0 && m_pEvadingFrom) {
- SetEvasiveDive((CPhysical*)m_pEvadingFrom, 1);
- m_nEvadeAmount = 0;
- m_pEvadingFrom = nil;
- } else {
- SetJump();
- }
- }
-}
-
-void
-CPlayerPed::ProcessControl(void)
-{
- if (m_nEvadeAmount != 0)
- --m_nEvadeAmount;
-
- if (m_nEvadeAmount == 0)
- m_pEvadingFrom = nil;
-
- if (m_pCurrentPhysSurface && m_pCurrentPhysSurface->IsVehicle() && ((CVehicle*)m_pCurrentPhysSurface)->IsBoat()) {
- bTryingToReachDryLand = true;
- } else if (!(((uint8)CTimer::GetFrameCounter() + m_randomSeed) & 0xF)) {
- CVehicle *nearVeh = (CVehicle*)CWorld::TestSphereAgainstWorld(GetPosition(), 7.0f, nil,
- false, true, false, false, false, false);
- if (nearVeh && nearVeh->IsBoat())
- bTryingToReachDryLand = true;
- else
- bTryingToReachDryLand = false;
- }
- CPed::ProcessControl();
- if (bWasPostponed)
- return;
-
- CPad *padUsed = CPad::GetPad(0);
- m_pWanted->Update();
- CEntity::PruneReferences();
-
- if (m_nMoveState != PEDMOVE_RUN && m_nMoveState != PEDMOVE_SPRINT)
- RestoreSprintEnergy(1.0f);
- else if (m_nMoveState == PEDMOVE_RUN)
- RestoreSprintEnergy(0.3f);
-
- if (m_nPedState == PED_DEAD) {
- ClearWeaponTarget();
- return;
- }
- if (m_nPedState == PED_DIE) {
- ClearWeaponTarget();
- if (CTimer::GetTimeInMilliseconds() > m_bloodyFootprintCountOrDeathTime + 4000)
- SetDead();
- return;
- }
- if (m_nPedState == PED_DRIVING && m_objective != OBJECTIVE_LEAVE_VEHICLE) {
- if (m_pMyVehicle->IsCar() && ((CAutomobile*)m_pMyVehicle)->Damage.GetDoorStatus(DOOR_FRONT_LEFT) == DOOR_STATUS_SWINGING) {
- CAnimBlendAssociation *rollDoorAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_ROLLDOOR);
- if (!rollDoorAssoc) {
- rollDoorAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_ROLLDOOR_LOW);
- }
-
- // These comparisons are wrong, they return uint16
- if (m_pMyVehicle->m_nGettingOutFlags & CAR_DOOR_FLAG_LF || rollDoorAssoc || padUsed
- && (padUsed->GetAccelerate() != 0.0f || padUsed->GetSteeringLeftRight() != 0.0f
- || padUsed->GetBrake() != 0.0f)) {
-
- if (rollDoorAssoc)
- m_pMyVehicle->ProcessOpenDoor(CAR_DOOR_LF, ANIM_CAR_ROLLDOOR, rollDoorAssoc->currentTime);
- } else {
- m_pMyVehicle->m_nGettingOutFlags |= CAR_DOOR_FLAG_LF;
- if (m_pMyVehicle->bLowVehicle)
- rollDoorAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_ROLLDOOR_LOW);
- else
- rollDoorAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_ROLLDOOR);
-
- rollDoorAssoc->SetFinishCallback(PedAnimDoorCloseRollingCB, this);
- }
- }
- return;
- }
- if (m_objective == OBJECTIVE_NONE)
- m_nMoveState = PEDMOVE_STILL;
- if (bIsLanding)
- RunningLand(padUsed);
- if (padUsed && padUsed->WeaponJustDown() && m_nPedState != PED_SNIPER_MODE) {
-
- // ...Really?
- eWeaponType playerWeapon = FindPlayerPed()->GetWeapon()->m_eWeaponType;
- if (playerWeapon == WEAPONTYPE_SNIPERRIFLE) {
- DMAudio.PlayFrontEndSound(SOUND_WEAPON_SNIPER_SHOT_NO_ZOOM, 0);
- } else if (playerWeapon == WEAPONTYPE_ROCKETLAUNCHER) {
- DMAudio.PlayFrontEndSound(SOUND_WEAPON_ROCKET_SHOT_NO_ZOOM, 0);
- }
- }
-
- switch (m_nPedState) {
- case PED_NONE:
- case PED_IDLE:
- case PED_FLEE_POS:
- case PED_FLEE_ENTITY:
- case PED_ATTACK:
- case PED_FIGHT:
- case PED_AIM_GUN:
- if (!RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FLAG400)) {
- if (TheCamera.Cams[0].Using3rdPersonMouseCam()) {
- if (padUsed)
- PlayerControl1stPersonRunAround(padUsed);
- } else if (m_nPedState == PED_FIGHT) {
- if (padUsed)
- PlayerControlFighter(padUsed);
- } else if (padUsed) {
- PlayerControlZelda(padUsed);
- }
- }
- if (IsPedInControl() && padUsed)
- ProcessPlayerWeapon(padUsed);
- break;
- case PED_LOOK_ENTITY:
- case PED_LOOK_HEADING:
- case PED_WANDER_RANGE:
- case PED_WANDER_PATH:
- case PED_PURSUE:
- case PED_FOLLOW_PATH:
- case PED_ROCKET_ODE:
- case PED_DUMMY:
- case PED_PAUSE:
- case PED_FACE_PHONE:
- case PED_MAKE_CALL:
- case PED_CHAT:
- case PED_MUG:
- case PED_AI_CONTROL:
- case PED_FOLLOW_ROUTE:
- case PED_CPR:
- case PED_SOLICIT:
- case PED_BUY_ICECREAM:
- case PED_INVESTIGATE:
- case PED_STEP_AWAY:
- case PED_ON_FIRE:
- case PED_UNKNOWN:
- case PED_STATES_NO_AI:
- case PED_STAGGER:
- case PED_DIVE_AWAY:
- case PED_STATES_NO_ST:
- case PED_ARREST_PLAYER:
- case PED_DRIVING:
- case PED_PASSENGER:
- case PED_TAXI_PASSENGER:
- case PED_OPEN_DOOR:
- case PED_DIE:
- case PED_DEAD:
- case PED_HANDS_UP:
- break;
- case PED_SEEK_ENTITY:
- m_vecSeekPos = m_pSeekTarget->GetPosition();
-
- // fall through
- case PED_SEEK_POS:
- switch (m_nMoveState) {
- case PEDMOVE_WALK:
- m_fMoveSpeed = 1.0f;
- break;
- case PEDMOVE_RUN:
- m_fMoveSpeed = 1.8f;
- break;
- case PEDMOVE_SPRINT:
- m_fMoveSpeed = 2.5f;
- break;
- default:
- m_fMoveSpeed = 0.0f;
- break;
- }
- SetRealMoveAnim();
- if (Seek()) {
- RestorePreviousState();
- SetMoveState(PEDMOVE_STILL);
- }
- break;
- case PED_SNIPER_MODE:
- if (FindPlayerPed()->GetWeapon()->m_eWeaponType == WEAPONTYPE_M16) {
- if (padUsed)
- PlayerControlM16(padUsed);
- } else if (padUsed) {
- PlayerControlSniper(padUsed);
- }
- break;
- case PED_SEEK_CAR:
- case PED_SEEK_IN_BOAT:
- if (bVehEnterDoorIsBlocked || bKindaStayInSamePlace) {
- m_fMoveSpeed = 0.0f;
- } else {
- m_fMoveSpeed = min(2.0f, 2.0f * (m_vecSeekPos - GetPosition()).Magnitude2D());
- }
- if (padUsed && !padUsed->ArePlayerControlsDisabled()) {
- if (padUsed->GetTarget() || padUsed->GetLeftStickXJustDown() || padUsed->GetLeftStickYJustDown() ||
- padUsed->GetDPadUpJustDown() || padUsed->GetDPadDownJustDown() || padUsed->GetDPadLeftJustDown() ||
- padUsed->GetDPadRightJustDown()) {
-
- RestorePreviousState();
- if (m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER || m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) {
- RestorePreviousObjective();
- }
- }
- }
- if (padUsed && padUsed->GetSprint())
- m_nMoveState = PEDMOVE_SPRINT;
- SetRealMoveAnim();
- break;
- case PED_JUMP:
- if (padUsed)
- PlayerControlZelda(padUsed);
- if (bIsLanding)
- break;
-
- // This has been added later it seems
- return;
- case PED_FALL:
- case PED_GETUP:
- case PED_ENTER_TRAIN:
- case PED_EXIT_TRAIN:
- case PED_CARJACK:
- case PED_DRAG_FROM_CAR:
- case PED_ENTER_CAR:
- case PED_STEAL_CAR:
- case PED_EXIT_CAR:
- ClearWeaponTarget();
- break;
- case PED_ARRESTED:
- if (m_nLastPedState == PED_DRAG_FROM_CAR && m_pVehicleAnim)
- BeingDraggedFromCar();
- break;
- }
- if (padUsed && IsPedShootable()) {
- ProcessWeaponSwitch(padUsed);
- GetWeapon()->Update(m_audioEntityId);
- }
- ProcessAnimGroups();
- if (padUsed) {
- if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_FOLLOWPED
- && TheCamera.Cams[TheCamera.ActiveCam].DirectionWasLooking == LOOKING_BEHIND) {
-
- m_lookTimer = 0;
- float camAngle = CGeneral::LimitRadianAngle(TheCamera.Cams[TheCamera.ActiveCam].Front.Heading());
- float angleBetweenPlayerAndCam = Abs(camAngle - m_fRotationCur);
- if (m_nPedState != PED_ATTACK
- && angleBetweenPlayerAndCam > DEGTORAD(30.0f) && angleBetweenPlayerAndCam < DEGTORAD(330.0f)) {
-
- if (angleBetweenPlayerAndCam > DEGTORAD(150.0f) && angleBetweenPlayerAndCam < DEGTORAD(210.0f)) {
- float rightTurnAngle = CGeneral::LimitRadianAngle(m_fRotationCur - DEGTORAD(150.0f));
- float leftTurnAngle = CGeneral::LimitRadianAngle(DEGTORAD(150.0f) + m_fRotationCur);
- if (m_fLookDirection != 999999.0f) {
- if (Abs(rightTurnAngle - m_fLookDirection) < Abs(leftTurnAngle - m_fLookDirection))
- camAngle = rightTurnAngle;
- else
- camAngle = leftTurnAngle;
- } else {
- camAngle = rightTurnAngle;
- }
- }
- SetLookFlag(camAngle, true);
- SetLookTimer(CTimer::GetTimeStepInMilliseconds() * 5.0f);
- } else {
- ClearLookFlag();
- }
- }
- }
- if (m_nMoveState == PEDMOVE_SPRINT && bIsLooking) {
- ClearLookFlag();
- SetLookTimer(250);
- }
-
- if (m_vecMoveSpeed.Magnitude2D() < 0.1f) {
- if (m_nSpeedTimer) {
- if (CTimer::GetTimeInMilliseconds() > m_nSpeedTimer)
- m_bSpeedTimerFlag = true;
- } else {
- m_nSpeedTimer = CTimer::GetTimeInMilliseconds() + 500;
- }
- } else {
- m_nSpeedTimer = 0;
- m_bSpeedTimerFlag = false;
- }
-}
-
-#include <new>
-
-class CPlayerPed_ : public CPlayerPed
-{
-public:
- CPlayerPed* ctor(void) { return ::new (this) CPlayerPed(); }
- void dtor(void) { CPlayerPed::~CPlayerPed(); }
- void SetMoveAnim_(void) { CPlayerPed::SetMoveAnim(); }
- void ProcessControl_(void) { CPlayerPed::ProcessControl(); }
-};
-
-STARTPATCHES
- InjectHook(0x4EF7E0, &CPlayerPed_::ctor, PATCH_JUMP);
- InjectHook(0x4EFB30, &CPlayerPed_::dtor, PATCH_JUMP);
- InjectHook(0x4F3760, &CPlayerPed_::SetMoveAnim_, PATCH_JUMP);
- InjectHook(0x4EFD90, &CPlayerPed_::ProcessControl_, PATCH_JUMP);
- InjectHook(0x4F28A0, &CPlayerPed::ClearWeaponTarget, PATCH_JUMP);
- InjectHook(0x4F3700, &CPlayerPed::AnnoyPlayerPed, PATCH_JUMP);
- InjectHook(0x4F36C0, &CPlayerPed::GetPlayerInfoForThisPlayerPed, PATCH_JUMP);
- InjectHook(0x4F2560, &CPlayerPed::MakeChangesForNewWeapon, PATCH_JUMP);
- InjectHook(0x4F07C0, &CPlayerPed::ReApplyMoveAnims, PATCH_JUMP);
- InjectHook(0x4F0880, &CPlayerPed::SetRealMoveAnim, PATCH_JUMP);
- InjectHook(0x4F1810, &CPlayerPed::PlayerControlFighter, PATCH_JUMP);
- InjectHook(0x4F1340, &CPlayerPed::RestoreSprintEnergy, PATCH_JUMP);
- InjectHook(0x4F1380, &CPlayerPed::DoWeaponSmoothSpray, PATCH_JUMP);
- InjectHook(0x4F36E0, &CPlayerPed::DoStuffToGoOnFire, PATCH_JUMP);
- InjectHook(0x4F3350, &CPlayerPed::DoesTargetHaveToBeBroken, PATCH_JUMP);
- InjectHook(0x4F31D0, &CPlayerPed::RunningLand, PATCH_JUMP);
- InjectHook(0x4F2D00, &CPlayerPed::IsThisPedAttackingPlayer, PATCH_JUMP);
- InjectHook(0x4F1CF0, &CPlayerPed::PlayerControlSniper, PATCH_JUMP);
- InjectHook(0x4F2310, &CPlayerPed::ProcessWeaponSwitch, PATCH_JUMP);
- InjectHook(0x4F1DF0, &CPlayerPed::PlayerControlM16, PATCH_JUMP);
- InjectHook(0x4F3460, &CPlayerPed::KeepAreaAroundPlayerClear, PATCH_JUMP);
- InjectHook(0x4F1970, &CPlayerPed::PlayerControl1stPersonRunAround, PATCH_JUMP);
- InjectHook(0x4F1EF0, &CPlayerPed::ProcessPlayerWeapon, PATCH_JUMP);
- InjectHook(0x4F2640, &CPlayerPed::ProcessAnimGroups, PATCH_JUMP);
-ENDPATCHES
+#include "common.h"
+#include "patcher.h"
+#include "PlayerPed.h"
+#include "Wanted.h"
+#include "Fire.h"
+#include "DMAudio.h"
+#include "Pad.h"
+#include "Camera.h"
+#include "WeaponEffects.h"
+#include "ModelIndices.h"
+#include "World.h"
+#include "RpAnimBlend.h"
+#include "AnimBlendAssociation.h"
+#include "General.h"
+#include "Pools.h"
+#include "Darkel.h"
+#include "CarCtrl.h"
+
+#define PAD_MOVE_TO_GAME_WORLD_MOVE 60.0f
+
+CPlayerPed::~CPlayerPed()
+{
+ delete m_pWanted;
+}
+
+CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
+{
+ m_fMoveSpeed = 0.0f;
+ SetModelIndex(MI_PLAYER);
+ SetInitialState();
+
+ m_pWanted = new CWanted();
+ m_pWanted->Initialise();
+ m_pArrestingCop = nil;
+ m_currentWeapon = WEAPONTYPE_UNARMED;
+ m_nSelectedWepSlot = WEAPONTYPE_UNARMED;
+ m_nSpeedTimer = 0;
+ m_bSpeedTimerFlag = false;
+ m_pPointGunAt = nil;
+ m_nPedState = PED_IDLE;
+ m_fMaxStamina = 150.0f;
+ m_fCurrentStamina = m_fMaxStamina;
+ m_fStaminaProgress = 0.0f;
+ m_nEvadeAmount = 0;
+ field_1367 = 0;
+ m_nShotDelay = 0;
+ field_1376 = 0.0f;
+ m_bHaveTargetSelected = false;
+ m_bHasLockOnTarget = false;
+ m_bCanBeDamaged = true;
+ m_fWalkAngle = 0.0f;
+ m_fFPSMoveHeading = 0.0f;
+ m_nTargettableObjects[0] = m_nTargettableObjects[1] = m_nTargettableObjects[2] = m_nTargettableObjects[3] = -1;
+ field_1413 = 0;
+ for (int i = 0; i < 6; i++) {
+ m_vecSafePos[i] = CVector(0.0f, 0.0f, 0.0f);
+ m_pPedAtSafePos[i] = nil;
+ }
+}
+
+void CPlayerPed::ClearWeaponTarget()
+{
+ if (m_nPedType == PEDTYPE_PLAYER1) {
+ m_pPointGunAt = nil;
+ TheCamera.ClearPlayerWeaponMode();
+ CWeaponEffects::ClearCrossHair();
+ }
+ ClearPointGunAt();
+}
+
+void
+CPlayerPed::SetWantedLevel(int32 level)
+{
+ m_pWanted->SetWantedLevel(level);
+}
+
+void
+CPlayerPed::SetWantedLevelNoDrop(int32 level)
+{
+ m_pWanted->SetWantedLevelNoDrop(level);
+}
+
+void
+CPlayerPed::MakeObjectTargettable(int32 handle)
+{
+ for (int i = 0; i < ARRAY_SIZE(m_nTargettableObjects); i++) {
+ if (
+#ifdef FIX_BUGS
+ m_nTargettableObjects[i] == -1 ||
+#endif
+ CPools::GetObjectPool()->GetAt(m_nTargettableObjects[i]) == nil) {
+ m_nTargettableObjects[i] = handle;
+ return;
+ }
+ }
+}
+
+// I don't know the actual purpose of parameter
+void
+CPlayerPed::AnnoyPlayerPed(bool annoyedByPassingEntity)
+{
+ if (m_pedStats->m_temper < 52) {
+ m_pedStats->m_temper++;
+ } else {
+ if (annoyedByPassingEntity) {
+ if (m_pedStats->m_temper < 55) {
+ m_pedStats->m_temper++;
+ } else {
+ m_pedStats->m_temper = 46;
+ }
+ }
+ }
+}
+
+void
+CPlayerPed::ClearAdrenaline(void)
+{
+ if (m_bAdrenalineActive && m_nAdrenalineTime != 0) {
+ m_nAdrenalineTime = 0;
+ CTimer::SetTimeScale(1.0f);
+ }
+}
+
+CPlayerInfo *
+CPlayerPed::GetPlayerInfoForThisPlayerPed()
+{
+ if (CWorld::Players[0].m_pPed == this)
+ return &CWorld::Players[0];
+
+ return nil;
+}
+
+void
+CPlayerPed::SetupPlayerPed(int32 index)
+{
+ CPlayerPed *player = new CPlayerPed();
+ CWorld::Players[index].m_pPed = player;
+
+ player->SetOrientation(0.0f, 0.0f, 0.0f);
+
+ CWorld::Add(player);
+ player->m_wepAccuracy = 100;
+}
+
+void
+CPlayerPed::DeactivatePlayerPed(int32 index)
+{
+ CWorld::Remove(CWorld::Players[index].m_pPed);
+}
+
+void
+CPlayerPed::ReactivatePlayerPed(int32 index)
+{
+ CWorld::Add(CWorld::Players[index].m_pPed);
+}
+
+void
+CPlayerPed::UseSprintEnergy(void)
+{
+ if (m_fCurrentStamina > -150.0f && !CWorld::Players[CWorld::PlayerInFocus].m_bInfiniteSprint
+ && !m_bAdrenalineActive) {
+ m_fCurrentStamina = m_fCurrentStamina - CTimer::GetTimeStep();
+ m_fStaminaProgress = m_fStaminaProgress + CTimer::GetTimeStep();
+ }
+
+ if (m_fStaminaProgress >= 500.0f) {
+ m_fStaminaProgress = 0;
+ if (m_fMaxStamina < 1000.0f)
+ m_fMaxStamina += 10.0f;
+ }
+}
+
+void
+CPlayerPed::MakeChangesForNewWeapon(int8 weapon)
+{
+ if (m_nPedState == PED_SNIPER_MODE) {
+ RestorePreviousState();
+ TheCamera.ClearPlayerWeaponMode();
+ }
+ SetCurrentWeapon(weapon);
+
+ GetWeapon()->m_nAmmoInClip = min(GetWeapon()->m_nAmmoTotal, CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_nAmountofAmmunition);
+
+ if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bCanAim))
+ ClearWeaponTarget();
+
+ CAnimBlendAssociation *weaponAnim = RpAnimBlendClumpGetAssociation(GetClump(), CWeaponInfo::GetWeaponInfo(WEAPONTYPE_SNIPERRIFLE)->m_AnimToPlay);
+ if (weaponAnim) {
+ weaponAnim->SetRun();
+ weaponAnim->flags |= ASSOC_FADEOUTWHENDONE;
+ }
+ TheCamera.ClearPlayerWeaponMode();
+}
+
+void
+CPlayerPed::ReApplyMoveAnims(void)
+{
+ static AnimationId moveAnims[] = { ANIM_WALK, ANIM_RUN, ANIM_SPRINT, ANIM_IDLE_STANCE, ANIM_WALK_START };
+
+ for(int i = 0; i < ARRAY_SIZE(moveAnims); i++) {
+ CAnimBlendAssociation *curMoveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), moveAnims[i]);
+ if (curMoveAssoc) {
+ if (strcmp(CAnimManager::GetAnimAssociation(m_animGroup, moveAnims[i])->hierarchy->name, curMoveAssoc->hierarchy->name) != 0) {
+ CAnimBlendAssociation *newMoveAssoc = CAnimManager::AddAnimation(GetClump(), m_animGroup, moveAnims[i]);
+ newMoveAssoc->blendDelta = curMoveAssoc->blendDelta;
+ newMoveAssoc->blendAmount = curMoveAssoc->blendAmount;
+ curMoveAssoc->blendDelta = -1000.0f;
+ curMoveAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ }
+ }
+ }
+}
+
+void
+CPlayerPed::SetInitialState(void)
+{
+ m_bAdrenalineActive = false;
+ m_nAdrenalineTime = 0;
+ CTimer::SetTimeStep(1.0f);
+ m_pSeekTarget = nil;
+ m_vecSeekPos = { 0.0f, 0.0f, 0.0f };
+ m_fleeFromPosX = 0.0f;
+ m_fleeFromPosY = 0.0f;
+ m_fleeFrom = nil;
+ m_fleeTimer = 0;
+ m_objective = OBJECTIVE_NONE;
+ m_prevObjective = OBJECTIVE_NONE;
+ bUsesCollision = true;
+ ClearAimFlag();
+ ClearLookFlag();
+ bIsPointingGunAt = false;
+ bRenderPedInCar = true;
+ if (m_pFire)
+ m_pFire->Extinguish();
+ RpAnimBlendClumpRemoveAllAssociations(GetClump());
+ m_nPedState = PED_IDLE;
+ SetMoveState(PEDMOVE_STILL);
+ m_nLastPedState = PED_NONE;
+ m_animGroup = ASSOCGRP_PLAYER;
+ m_fMoveSpeed = 0.0f;
+ m_nSelectedWepSlot = WEAPONTYPE_UNARMED;
+ m_nEvadeAmount = 0;
+ m_pEvadingFrom = nil;
+ bIsPedDieAnimPlaying = false;
+ SetRealMoveAnim();
+ m_bCanBeDamaged = true;
+ m_pedStats->m_temper = 50;
+ m_fWalkAngle = 0.0f;
+}
+
+void
+CPlayerPed::SetRealMoveAnim(void)
+{
+ CAnimBlendAssociation *curWalkAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WALK);
+ CAnimBlendAssociation *curRunAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN);
+ CAnimBlendAssociation *curSprintAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_SPRINT);
+ CAnimBlendAssociation *curWalkStartAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WALK_START);
+ CAnimBlendAssociation *curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_STANCE);
+ CAnimBlendAssociation *curRunStopAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN_STOP);
+ CAnimBlendAssociation *curRunStopRAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN_STOP_R);
+ if (bResetWalkAnims) {
+ if (curWalkAssoc)
+ curWalkAssoc->SetCurrentTime(0.0f);
+ if (curRunAssoc)
+ curRunAssoc->SetCurrentTime(0.0f);
+ if (curSprintAssoc)
+ curSprintAssoc->SetCurrentTime(0.0f);
+ bResetWalkAnims = false;
+ }
+
+ if (!curIdleAssoc)
+ curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED);
+ if (!curIdleAssoc)
+ curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE);
+
+ if ((!curRunStopAssoc || !(curRunStopAssoc->IsRunning())) && (!curRunStopRAssoc || !(curRunStopRAssoc->IsRunning()))) {
+
+ if (curRunStopAssoc && curRunStopAssoc->blendDelta >= 0.0f || curRunStopRAssoc && curRunStopRAssoc->blendDelta >= 0.0f) {
+ if (curRunStopAssoc) {
+ curRunStopAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ curRunStopAssoc->blendAmount = 1.0f;
+ curRunStopAssoc->blendDelta = -8.0f;
+ } else if (curRunStopRAssoc) {
+ curRunStopRAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ curRunStopRAssoc->blendAmount = 1.0f;
+ curRunStopRAssoc->blendDelta = -8.0f;
+ }
+
+ RestoreHeadingRate();
+ if (!curIdleAssoc) {
+ if (m_fCurrentStamina < 0.0f && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f,
+ nil, true, false, false, false, false, false)) {
+ curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 8.0f);
+
+ } else {
+ curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 8.0f);
+ }
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(2500, 4000);
+ }
+ curIdleAssoc->blendAmount = 0.0f;
+ curIdleAssoc->blendDelta = 8.0f;
+
+ } else if (m_fMoveSpeed == 0.0f && !curSprintAssoc) {
+ if (!curIdleAssoc) {
+ if (m_fCurrentStamina < 0.0f && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f,
+ nil, true, false, false, false, false, false)) {
+ curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 4.0f);
+
+ } else {
+ curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f);
+ }
+
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(2500, 4000);
+ }
+
+ if (m_fCurrentStamina > 0.0f && curIdleAssoc->animId == ANIM_IDLE_TIRED) {
+ CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f);
+
+ } else if (m_nPedState != PED_FIGHT) {
+ if (m_fCurrentStamina < 0.0f && curIdleAssoc->animId != ANIM_IDLE_TIRED
+ && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f, nil, true, false, false, false, false, false)) {
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 4.0f);
+
+ } else if (curIdleAssoc->animId != ANIM_IDLE_STANCE) {
+ CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f);
+ }
+ }
+
+ m_nMoveState = PEDMOVE_STILL;
+ } else {
+ if (curIdleAssoc) {
+ if (curWalkStartAssoc) {
+ curWalkStartAssoc->blendAmount = 1.0f;
+ curWalkStartAssoc->blendDelta = 0.0f;
+ } else {
+ curWalkStartAssoc = CAnimManager::AddAnimation(GetClump(), m_animGroup, ANIM_WALK_START);
+ }
+ if (curWalkAssoc)
+ curWalkAssoc->SetCurrentTime(0.0f);
+ if (curRunAssoc)
+ curRunAssoc->SetCurrentTime(0.0f);
+
+ delete curIdleAssoc;
+ delete RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED);
+ delete RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE);
+ delete curSprintAssoc;
+
+ curSprintAssoc = nil;
+ m_nMoveState = PEDMOVE_WALK;
+ }
+ if (curRunStopAssoc) {
+ delete curRunStopAssoc;
+ RestoreHeadingRate();
+ }
+ if (curRunStopRAssoc) {
+ delete curRunStopRAssoc;
+ RestoreHeadingRate();
+ }
+ if (!curWalkAssoc) {
+ curWalkAssoc = CAnimManager::AddAnimation(GetClump(), m_animGroup, ANIM_WALK);
+ curWalkAssoc->blendAmount = 0.0f;
+ }
+ if (!curRunAssoc) {
+ curRunAssoc = CAnimManager::AddAnimation(GetClump(), m_animGroup, ANIM_RUN);
+ curRunAssoc->blendAmount = 0.0f;
+ }
+ if (curWalkStartAssoc && !(curWalkStartAssoc->IsRunning())) {
+ delete curWalkStartAssoc;
+ curWalkStartAssoc = nil;
+ curWalkAssoc->SetRun();
+ curRunAssoc->SetRun();
+ }
+ if (m_nMoveState == PEDMOVE_SPRINT) {
+ if (m_fCurrentStamina < 0.0f && (m_fCurrentStamina <= -150.0f || !curSprintAssoc || curSprintAssoc->blendDelta < 0.0f))
+ m_nMoveState = PEDMOVE_STILL;
+
+ if (curWalkStartAssoc)
+ m_nMoveState = PEDMOVE_STILL;
+ }
+
+ if (curSprintAssoc && (m_nMoveState != PEDMOVE_SPRINT || m_fMoveSpeed < 0.4f)) {
+ if (curSprintAssoc->blendAmount == 0.0f) {
+ curSprintAssoc->blendDelta = -1000.0f;
+ curSprintAssoc->flags |= ASSOC_DELETEFADEDOUT;
+
+ } else if (curSprintAssoc->blendDelta >= 0.0f || curSprintAssoc->blendAmount >= 0.8f) {
+ if (m_fMoveSpeed < 0.4f) {
+ AnimationId runStopAnim;
+ if (curSprintAssoc->currentTime / curSprintAssoc->hierarchy->totalLength < 0.5) // double
+ runStopAnim = ANIM_RUN_STOP;
+ else
+ runStopAnim = ANIM_RUN_STOP_R;
+ CAnimBlendAssociation* newRunStopAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, runStopAnim);
+ newRunStopAssoc->blendAmount = 1.0f;
+ newRunStopAssoc->SetDeleteCallback(RestoreHeadingRateCB, this);
+ m_headingRate = 0.0f;
+ curSprintAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ curSprintAssoc->blendDelta = -1000.0f;
+ curWalkAssoc->flags &= ~ASSOC_RUNNING;
+ curWalkAssoc->blendAmount = 0.0f;
+ curWalkAssoc->blendDelta = 0.0f;
+ curRunAssoc->flags &= ~ASSOC_RUNNING;
+ curRunAssoc->blendAmount = 0.0f;
+ curRunAssoc->blendDelta = 0.0f;
+ } else if (curSprintAssoc->blendDelta >= 0.0f) {
+
+ // Stop sprinting when tired
+ curSprintAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ curSprintAssoc->blendDelta = -1.0f;
+ curRunAssoc->blendDelta = 1.0f;
+ }
+ } else if (m_fMoveSpeed < 1.0f) {
+ curSprintAssoc->blendDelta = -8.0f;
+ curRunAssoc->blendDelta = 8.0f;
+ }
+ } else if (curWalkStartAssoc) {
+ curWalkAssoc->flags &= ~ASSOC_RUNNING;
+ curRunAssoc->flags &= ~ASSOC_RUNNING;
+ curWalkAssoc->blendAmount = 0.0f;
+ curRunAssoc->blendAmount = 0.0f;
+
+ } else if (m_nMoveState == PEDMOVE_SPRINT) {
+ if (curSprintAssoc) {
+ if (curSprintAssoc->blendDelta < 0.0f) {
+ curSprintAssoc->blendDelta = 2.0f;
+ curRunAssoc->blendDelta = -2.0f;
+ }
+ } else {
+ curWalkAssoc->blendAmount = 0.0f;
+ curRunAssoc->blendAmount = 1.0f;
+ curSprintAssoc = CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_SPRINT, 2.0f);
+ }
+ UseSprintEnergy();
+ } else {
+ if (m_fMoveSpeed < 1.0f) {
+ curWalkAssoc->blendAmount = 1.0f;
+ curRunAssoc->blendAmount = 0.0f;
+ m_nMoveState = PEDMOVE_WALK;
+ } else if (m_fMoveSpeed < 2.0f) {
+ curWalkAssoc->blendAmount = 2.0f - m_fMoveSpeed;
+ curRunAssoc->blendAmount = m_fMoveSpeed - 1.0f;
+ m_nMoveState = PEDMOVE_RUN;
+ } else {
+ curWalkAssoc->blendAmount = 0.0f;
+ curRunAssoc->blendAmount = 1.0f;
+ m_nMoveState = PEDMOVE_RUN;
+ }
+ }
+ }
+ }
+ if (m_bAdrenalineActive) {
+ if (CTimer::GetTimeInMilliseconds() > m_nAdrenalineTime) {
+ m_bAdrenalineActive = false;
+ CTimer::SetTimeScale(1.0f);
+ if (curWalkStartAssoc)
+ curWalkStartAssoc->speed = 1.0f;
+ if (curWalkAssoc)
+ curWalkAssoc->speed = 1.0f;
+ if (curRunAssoc)
+ curRunAssoc->speed = 1.0f;
+ if (curSprintAssoc)
+ curSprintAssoc->speed = 1.0f;
+ } else {
+ CTimer::SetTimeScale(1.0f / 3);
+ if (curWalkStartAssoc)
+ curWalkStartAssoc->speed = 2.0f;
+ if (curWalkAssoc)
+ curWalkAssoc->speed = 2.0f;
+ if (curRunAssoc)
+ curRunAssoc->speed = 2.0f;
+ if (curSprintAssoc)
+ curSprintAssoc->speed = 2.0f;
+ }
+ }
+}
+
+void
+CPlayerPed::RestoreSprintEnergy(float restoreSpeed)
+{
+ if (m_fCurrentStamina < m_fMaxStamina)
+ m_fCurrentStamina += restoreSpeed * CTimer::GetTimeStep() * 0.5f;
+}
+
+bool
+CPlayerPed::DoWeaponSmoothSpray(void)
+{
+ if (m_nPedState == PED_ATTACK && !m_pPointGunAt) {
+ eWeaponType weapon = GetWeapon()->m_eWeaponType;
+ if (weapon == WEAPONTYPE_FLAMETHROWER || weapon == WEAPONTYPE_COLT45 || weapon == WEAPONTYPE_UZI || weapon == WEAPONTYPE_SHOTGUN ||
+ weapon == WEAPONTYPE_AK47 || weapon == WEAPONTYPE_M16 || weapon == WEAPONTYPE_HELICANNON)
+ return true;
+ }
+ return false;
+}
+
+void
+CPlayerPed::DoStuffToGoOnFire(void)
+{
+ if (m_nPedState == PED_SNIPER_MODE)
+ TheCamera.ClearPlayerWeaponMode();
+}
+
+bool
+CPlayerPed::DoesTargetHaveToBeBroken(CVector target, CWeapon *weaponUsed)
+{
+ CVector distVec = target - GetPosition();
+
+ if (distVec.Magnitude() > CWeaponInfo::GetWeaponInfo(weaponUsed->m_eWeaponType)->m_fRange)
+ return true;
+
+ if (weaponUsed->m_eWeaponType != WEAPONTYPE_SHOTGUN && weaponUsed->m_eWeaponType != WEAPONTYPE_AK47)
+ return false;
+
+ distVec.Normalise();
+
+ if (DotProduct(distVec,GetForward()) < 0.4f)
+ return true;
+
+ return false;
+}
+
+// Cancels landing anim while running & jumping? I think
+void
+CPlayerPed::RunningLand(CPad *padUsed)
+{
+ CAnimBlendAssociation *landAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FALL_LAND);
+ if (landAssoc && landAssoc->currentTime == 0.0f && m_fMoveSpeed > 1.5f
+ && padUsed && (padUsed->GetPedWalkLeftRight() != 0.0f || padUsed->GetPedWalkUpDown() != 0.0f)) {
+
+ landAssoc->blendDelta = -1000.0f;
+ landAssoc->flags |= ASSOC_DELETEFADEDOUT;
+
+ CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_JUMP_LAND)->SetFinishCallback(FinishJumpCB, this);
+
+ if (m_nPedState == PED_JUMP)
+ RestorePreviousState();
+ }
+}
+
+bool
+CPlayerPed::IsThisPedAttackingPlayer(CPed *suspect)
+{
+ if (suspect->m_pPointGunAt == this)
+ return true;
+
+ switch (suspect->m_objective) {
+ case OBJECTIVE_KILL_CHAR_ON_FOOT:
+ case OBJECTIVE_KILL_CHAR_ANY_MEANS:
+ if (suspect->m_pedInObjective == this)
+ return true;
+
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
+void
+CPlayerPed::PlayerControlSniper(CPad *padUsed)
+{
+ ProcessWeaponSwitch(padUsed);
+ TheCamera.PlayerExhaustion = (1.0f - (m_fCurrentStamina - -150.0f) / 300.0f) * 0.9f + 0.1f;
+
+ if (!padUsed->GetTarget()) {
+ RestorePreviousState();
+ TheCamera.ClearPlayerWeaponMode();
+ }
+
+ if (padUsed->WeaponJustDown()) {
+ CVector firePos(0.0f, 0.0f, 0.6f);
+ firePos = GetMatrix() * firePos;
+ GetWeapon()->Fire(this, &firePos);
+ }
+ GetWeapon()->Update(m_audioEntityId);
+}
+
+// I think R* also used goto in here.
+void
+CPlayerPed::ProcessWeaponSwitch(CPad *padUsed)
+{
+ if (CDarkel::FrenzyOnGoing())
+ goto switchDetectDone;
+
+ if (padUsed->CycleWeaponRightJustDown() && !m_pPointGunAt) {
+
+ if (TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON_RUNABOUT
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER_RUNABOUT
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER_RUNABOUT) {
+
+ for (m_nSelectedWepSlot = m_currentWeapon + 1; m_nSelectedWepSlot < WEAPONTYPE_TOTAL_INVENTORY_WEAPONS; ++m_nSelectedWepSlot) {
+ if (HasWeapon(m_nSelectedWepSlot) && GetWeapon(m_nSelectedWepSlot).HasWeaponAmmoToBeUsed()) {
+ goto switchDetectDone;
+ }
+ }
+ m_nSelectedWepSlot = WEAPONTYPE_UNARMED;
+ }
+ } else if (padUsed->CycleWeaponLeftJustDown() && !m_pPointGunAt) {
+ if (TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER) {
+
+ for (m_nSelectedWepSlot = m_currentWeapon - 1; ; --m_nSelectedWepSlot) {
+ if (m_nSelectedWepSlot < WEAPONTYPE_UNARMED)
+ m_nSelectedWepSlot = WEAPONTYPE_DETONATOR;
+
+ if (HasWeapon(m_nSelectedWepSlot) && GetWeapon(m_nSelectedWepSlot).HasWeaponAmmoToBeUsed()) {
+ goto switchDetectDone;
+ }
+ }
+ }
+ } else if (CWeaponInfo::GetWeaponInfo((eWeaponType)m_currentWeapon)->m_eWeaponFire != WEAPON_FIRE_MELEE) {
+ if (GetWeapon(m_currentWeapon).m_nAmmoTotal <= 0) {
+ if (TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER
+ && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER) {
+
+ for (m_nSelectedWepSlot = m_currentWeapon - 1; m_nSelectedWepSlot >= 0; --m_nSelectedWepSlot) {
+ if (m_nSelectedWepSlot == WEAPONTYPE_BASEBALLBAT && HasWeapon(WEAPONTYPE_BASEBALLBAT)
+ || GetWeapon(m_nSelectedWepSlot).m_nAmmoTotal > 0 && m_nSelectedWepSlot != WEAPONTYPE_MOLOTOV && m_nSelectedWepSlot != WEAPONTYPE_GRENADE) {
+ goto switchDetectDone;
+ }
+ }
+ m_nSelectedWepSlot = WEAPONTYPE_UNARMED;
+ }
+ }
+ }
+
+switchDetectDone:
+ if (m_nSelectedWepSlot != m_currentWeapon) {
+ if (m_nPedState != PED_ATTACK && m_nPedState != PED_AIM_GUN && m_nPedState != PED_FIGHT)
+ MakeChangesForNewWeapon(m_nSelectedWepSlot);
+ }
+}
+
+void
+CPlayerPed::PlayerControlM16(CPad *padUsed)
+{
+ ProcessWeaponSwitch(padUsed);
+ TheCamera.PlayerExhaustion = (1.0f - (m_fCurrentStamina - -150.0f) / 300.0f) * 0.9f + 0.1f;
+
+ if (!padUsed->GetTarget()) {
+ RestorePreviousState();
+ TheCamera.ClearPlayerWeaponMode();
+ }
+
+ if (padUsed->GetWeapon()) {
+ CVector firePos(0.0f, 0.0f, 0.6f);
+ firePos = GetMatrix() * firePos;
+ GetWeapon()->Fire(this, &firePos);
+ }
+ GetWeapon()->Update(m_audioEntityId);
+}
+
+void
+CPlayerPed::PlayerControlFighter(CPad *padUsed)
+{
+ float leftRight = padUsed->GetPedWalkLeftRight();
+ float upDown = padUsed->GetPedWalkUpDown();
+ float padMove = CVector2D(leftRight, upDown).Magnitude();
+
+ if (padMove > 0.0f) {
+ m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(0.0f, 0.0f, -leftRight, upDown) - TheCamera.Orientation;
+ m_takeAStepAfterAttack = padMove > 2 * PAD_MOVE_TO_GAME_WORLD_MOVE;
+ if (padUsed->GetSprint() && padMove > 1 * PAD_MOVE_TO_GAME_WORLD_MOVE)
+ bIsAttacking = false;
+ }
+
+ if (!CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy && padUsed->JumpJustDown()) {
+ if (m_nEvadeAmount != 0 && m_pEvadingFrom) {
+ SetEvasiveDive((CPhysical*)m_pEvadingFrom, 1);
+ m_nEvadeAmount = 0;
+ m_pEvadingFrom = nil;
+ } else {
+ SetJump();
+ }
+ }
+}
+
+void
+CPlayerPed::PlayerControl1stPersonRunAround(CPad *padUsed)
+{
+ float leftRight = padUsed->GetPedWalkLeftRight();
+ float upDown = padUsed->GetPedWalkUpDown();
+ float padMove = CVector2D(leftRight, upDown).Magnitude();
+ float padMoveInGameUnit = padMove / PAD_MOVE_TO_GAME_WORLD_MOVE;
+ if (padMoveInGameUnit > 0.0f) {
+#ifdef FREE_CAM
+ if (!CCamera::bFreeCam)
+ m_fRotationDest = CGeneral::LimitRadianAngle(TheCamera.Orientation);
+ else
+ m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(0.0f, 0.0f, -leftRight, upDown) - TheCamera.Orientation;
+#else
+ m_fRotationDest = CGeneral::LimitRadianAngle(TheCamera.Orientation);
+#endif
+ m_fMoveSpeed = min(padMoveInGameUnit, 0.07f * CTimer::GetTimeStep() + m_fMoveSpeed);
+ } else {
+ m_fMoveSpeed = 0.0f;
+ }
+
+ if (m_nPedState == PED_JUMP) {
+ if (bIsInTheAir) {
+ if (bUsesCollision && !bHitSteepSlope &&
+ (!bHitSomethingLastFrame || m_vecDamageNormal.z > 0.6f)
+ && m_fDistanceTravelled < CTimer::GetTimeStep() * 0.02 && m_vecMoveSpeed.MagnitudeSqr() < 0.01f) {
+
+ float angleSin = Sin(m_fRotationCur); // originally sin(DEGTORAD(RADTODEG(m_fRotationCur))) o_O
+ float angleCos = Cos(m_fRotationCur);
+ ApplyMoveForce(-angleSin * 3.0f, 3.0f * angleCos, 0.05f);
+ }
+ } else if (bIsLanding) {
+ m_fMoveSpeed = 0.0f;
+ }
+ }
+ if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy)
+ && padUsed->GetSprint()) {
+ m_nMoveState = PEDMOVE_SPRINT;
+ }
+ if (m_nPedState != PED_FIGHT)
+ SetRealMoveAnim();
+
+ if (!bIsInTheAir && !(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy)
+ && padUsed->JumpJustDown() && m_nPedState != PED_JUMP) {
+ ClearAttack();
+ ClearWeaponTarget();
+ if (m_nEvadeAmount != 0 && m_pEvadingFrom) {
+ SetEvasiveDive((CPhysical*)m_pEvadingFrom, 1);
+ m_nEvadeAmount = 0;
+ m_pEvadingFrom = nil;
+ } else {
+ SetJump();
+ }
+ }
+}
+
+void
+CPlayerPed::KeepAreaAroundPlayerClear(void)
+{
+ BuildPedLists();
+ for (int i = 0; i < m_numNearPeds; ++i) {
+ CPed *nearPed = m_nearPeds[i];
+ if (nearPed->CharCreatedBy == RANDOM_CHAR && !nearPed->DyingOrDead()) {
+ if (nearPed->GetIsOnScreen()) {
+ if (nearPed->m_objective == OBJECTIVE_NONE) {
+ nearPed->SetFindPathAndFlee(this, 5000, true);
+ } else {
+ if (nearPed->EnteringCar())
+ nearPed->QuitEnteringCar();
+
+ nearPed->ClearObjective();
+ }
+ } else {
+ nearPed->FlagToDestroyWhenNextProcessed();
+ }
+ }
+ }
+ CVector playerPos = (InVehicle() ? m_pMyVehicle->GetPosition() : GetPosition());
+
+ CVector pos = GetPosition();
+ int16 lastVehicle;
+ CEntity *vehicles[8];
+ CWorld::FindObjectsInRange(pos, CHECK_NEARBY_THINGS_MAX_DIST, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
+
+ for (int i = 0; i < lastVehicle; i++) {
+ CVehicle *veh = (CVehicle*)vehicles[i];
+ if (veh->VehicleCreatedBy != MISSION_VEHICLE) {
+ if (veh->m_status != STATUS_PLAYER && veh->m_status != STATUS_PLAYER_DISABLED) {
+ if ((veh->GetPosition() - playerPos).MagnitudeSqr() > 25.0f) {
+ veh->AutoPilot.m_nTempAction = TEMPACT_WAIT;
+ veh->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 5000;
+ } else {
+ if (DotProduct2D(playerPos - veh->GetPosition(), veh->GetForward()) > 0.0f)
+ veh->AutoPilot.m_nTempAction = TEMPACT_REVERSE;
+ else
+ veh->AutoPilot.m_nTempAction = TEMPACT_GOFORWARD;
+
+ veh->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 2000;
+ }
+ CCarCtrl::PossiblyRemoveVehicle(veh);
+ }
+ }
+ }
+}
+
+void
+CPlayerPed::EvaluateNeighbouringTarget(CEntity *candidate, CEntity **targetPtr, float *lastCloseness, float distLimit, float angleOffset, bool lookToLeft)
+{
+ CVector distVec = candidate->GetPosition() - GetPosition();
+ if (distVec.Magnitude2D() <= distLimit) {
+ if (!DoesTargetHaveToBeBroken(candidate->GetPosition(), GetWeapon())) {
+#ifdef VC_PED_PORTS
+ float angleBetweenUs = CGeneral::GetATanOfXY(candidate->GetPosition().x - TheCamera.GetPosition().x,
+ candidate->GetPosition().y - TheCamera.GetPosition().y);
+#else
+ float angleBetweenUs = CGeneral::GetATanOfXY(distVec.x, distVec.y);
+#endif
+ angleBetweenUs = CGeneral::LimitAngle(angleBetweenUs - angleOffset);
+ float closeness;
+ if (lookToLeft) {
+ closeness = angleBetweenUs > 0.0f ? -Abs(angleBetweenUs) : -100000.0f;
+ } else {
+ closeness = angleBetweenUs > 0.0f ? -100000.0f : -Abs(angleBetweenUs);
+ }
+
+ if (closeness > *lastCloseness) {
+ *targetPtr = candidate;
+ *lastCloseness = closeness;
+ }
+ }
+ }
+}
+
+void
+CPlayerPed::EvaluateTarget(CEntity *candidate, CEntity **targetPtr, float *lastCloseness, float distLimit, float angleOffset, bool priority)
+{
+ CVector distVec = candidate->GetPosition() - GetPosition();
+ float dist = distVec.Magnitude2D();
+ if (dist <= distLimit) {
+ if (!DoesTargetHaveToBeBroken(candidate->GetPosition(), GetWeapon())) {
+ float angleBetweenUs = CGeneral::GetATanOfXY(distVec.x, distVec.y);
+ angleBetweenUs = CGeneral::LimitAngle(angleBetweenUs - angleOffset);
+
+ float closeness = -dist - 5.0f * Abs(angleBetweenUs);
+ if (priority) {
+ closeness += 5.0f;
+ }
+
+ if (closeness > *lastCloseness) {
+ *targetPtr = candidate;
+ *lastCloseness = closeness;
+ }
+ }
+ }
+}
+
+bool
+CPlayerPed::FindNextWeaponLockOnTarget(CEntity *previousTarget, bool lookToLeft)
+{
+ CEntity *nextTarget = nil;
+ float weaponRange = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_fRange;
+ // nextTarget = nil;
+ float lastCloseness = -10000.0f;
+ // unused
+ // CGeneral::GetATanOfXY(GetForward().x, GetForward().y);
+ CVector distVec = previousTarget->GetPosition() - GetPosition();
+ float referenceBeta = CGeneral::GetATanOfXY(distVec.x, distVec.y);
+
+ for (int h = CPools::GetPedPool()->GetSize() - 1; h >= 0; h--) {
+ CPed *pedToCheck = CPools::GetPedPool()->GetSlot(h);
+ if (pedToCheck) {
+ if (pedToCheck != FindPlayerPed() && pedToCheck != previousTarget) {
+ if (!pedToCheck->DyingOrDead() && !pedToCheck->bInVehicle
+ && pedToCheck->m_leader != FindPlayerPed() && OurPedCanSeeThisOne(pedToCheck)) {
+
+ EvaluateNeighbouringTarget(pedToCheck, &nextTarget, &lastCloseness,
+ weaponRange, referenceBeta, lookToLeft);
+ }
+ }
+ }
+ }
+ for (int i = 0; i < ARRAY_SIZE(m_nTargettableObjects); i++) {
+ CObject *obj = CPools::GetObjectPool()->GetAt(m_nTargettableObjects[i]);
+ if (obj)
+ EvaluateNeighbouringTarget(obj, &nextTarget, &lastCloseness, weaponRange, referenceBeta, lookToLeft);
+ }
+ if (!nextTarget)
+ return false;
+
+ m_pPointGunAt = nextTarget;
+ if (nextTarget)
+ nextTarget->RegisterReference((CEntity**)&m_pPointGunAt);
+ SetPointGunAt(nextTarget);
+ return true;
+}
+
+bool
+CPlayerPed::FindWeaponLockOnTarget(void)
+{
+ CEntity *nextTarget = nil;
+ float weaponRange = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_fRange;
+
+ if (m_pPointGunAt) {
+ CVector distVec = m_pPointGunAt->GetPosition() - GetPosition();
+ if (distVec.Magnitude2D() > weaponRange) {
+ m_pPointGunAt = nil;
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ // nextTarget = nil;
+ float lastCloseness = -10000.0f;
+ float referenceBeta = CGeneral::GetATanOfXY(GetForward().x, GetForward().y);
+ for (int h = CPools::GetPedPool()->GetSize() - 1; h >= 0; h--) {
+ CPed *pedToCheck = CPools::GetPedPool()->GetSlot(h);
+ if (pedToCheck) {
+ if (pedToCheck != FindPlayerPed()) {
+ if (!pedToCheck->DyingOrDead() && !pedToCheck->bInVehicle
+ && pedToCheck->m_leader != FindPlayerPed() && OurPedCanSeeThisOne(pedToCheck)) {
+
+ EvaluateTarget(pedToCheck, &nextTarget, &lastCloseness,
+ weaponRange, referenceBeta, IsThisPedAttackingPlayer(pedToCheck));
+ }
+ }
+ }
+ }
+ for (int i = 0; i < ARRAY_SIZE(m_nTargettableObjects); i++) {
+ CObject *obj = CPools::GetObjectPool()->GetAt(m_nTargettableObjects[i]);
+ if (obj)
+ EvaluateTarget(obj, &nextTarget, &lastCloseness, weaponRange, referenceBeta, false);
+ }
+ if (!nextTarget)
+ return false;
+
+ m_pPointGunAt = nextTarget;
+ if (nextTarget)
+ nextTarget->RegisterReference((CEntity**)&m_pPointGunAt);
+ SetPointGunAt(nextTarget);
+ return true;
+}
+
+void
+CPlayerPed::ProcessAnimGroups(void)
+{
+ AssocGroupId groupToSet;
+ if ((m_fWalkAngle <= -DEGTORAD(50.0f) || m_fWalkAngle >= DEGTORAD(50.0f))
+ && TheCamera.Cams[TheCamera.ActiveCam].Using3rdPersonMouseCam()
+ && CanStrafeOrMouseControl()) {
+
+ if (m_fWalkAngle >= -DEGTORAD(130.0f) && m_fWalkAngle <= DEGTORAD(130.0f)) {
+ if (m_fWalkAngle > 0.0f) {
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER)
+ groupToSet = ASSOCGRP_ROCKETLEFT;
+ else
+ groupToSet = ASSOCGRP_PLAYERLEFT;
+ } else {
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER)
+ groupToSet = ASSOCGRP_ROCKETRIGHT;
+ else
+ groupToSet = ASSOCGRP_PLAYERRIGHT;
+ }
+ } else {
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER)
+ groupToSet = ASSOCGRP_ROCKETBACK;
+ else
+ groupToSet = ASSOCGRP_PLAYERBACK;
+ }
+ } else {
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER) {
+ groupToSet = ASSOCGRP_PLAYERROCKET;
+ } else {
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT) {
+ groupToSet = ASSOCGRP_PLAYERBBBAT;
+ } else if (GetWeapon()->m_eWeaponType != WEAPONTYPE_COLT45 && GetWeapon()->m_eWeaponType != WEAPONTYPE_UZI) {
+ if (!GetWeapon()->IsType2Handed()) {
+ groupToSet = ASSOCGRP_PLAYER;
+ } else {
+ groupToSet = ASSOCGRP_PLAYER2ARMED;
+ }
+ } else {
+ groupToSet = ASSOCGRP_PLAYER1ARMED;
+ }
+ }
+ }
+
+ if (m_animGroup != groupToSet) {
+ m_animGroup = groupToSet;
+ ReApplyMoveAnims();
+ }
+}
+
+void
+CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
+{
+ CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
+ if (m_bHasLockOnTarget && !m_pPointGunAt) {
+ TheCamera.ClearPlayerWeaponMode();
+ CWeaponEffects::ClearCrossHair();
+ ClearPointGunAt();
+ }
+ if (!m_pFire) {
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER ||
+ GetWeapon()->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE || GetWeapon()->m_eWeaponType == WEAPONTYPE_M16) {
+ if (padUsed->TargetJustDown()) {
+ SetStoredState();
+ m_nPedState = PED_SNIPER_MODE;
+#ifdef FREE_CAM
+ if (CCamera::bFreeCam && TheCamera.Cams[0].Using3rdPersonMouseCam()) {
+ m_fRotationCur = CGeneral::LimitRadianAngle(-TheCamera.Orientation);
+ SetHeading(m_fRotationCur);
+ }
+#endif
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER)
+ TheCamera.SetNewPlayerWeaponMode(CCam::MODE_ROCKETLAUNCHER, 0, 0);
+ else if (GetWeapon()->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE)
+ TheCamera.SetNewPlayerWeaponMode(CCam::MODE_SNIPER, 0, 0);
+ else
+ TheCamera.SetNewPlayerWeaponMode(CCam::MODE_M16_1STPERSON, 0, 0);
+
+ m_fMoveSpeed = 0.0f;
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_STANCE, 1000.0f);
+ }
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER || GetWeapon()->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE
+ || TheCamera.PlayerWeaponMode.Mode == CCam::MODE_M16_1STPERSON)
+ return;
+ }
+ }
+
+ if (padUsed->GetWeapon() && m_nMoveState != PEDMOVE_SPRINT) {
+ if (m_nSelectedWepSlot == m_currentWeapon) {
+ if (m_pPointGunAt) {
+#ifdef FREE_CAM
+ if (CCamera::bFreeCam && weaponInfo->m_eWeaponFire == WEAPON_FIRE_MELEE && m_fMoveSpeed < 1.0f)
+ StartFightAttack(padUsed->GetWeapon());
+ else
+#endif
+ SetAttack(m_pPointGunAt);
+ } else if (m_currentWeapon != WEAPONTYPE_UNARMED) {
+ if (m_nPedState == PED_ATTACK) {
+ if (padUsed->WeaponJustDown()) {
+ m_bHaveTargetSelected = true;
+ } else if (!m_bHaveTargetSelected) {
+ field_1376 += CTimer::GetTimeStepNonClipped();
+ }
+ } else {
+ field_1376 = 0.0f;
+ m_bHaveTargetSelected = false;
+ }
+ SetAttack(nil);
+ } else if (padUsed->WeaponJustDown()) {
+ if (m_fMoveSpeed < 1.0f)
+ StartFightAttack(padUsed->GetWeapon());
+ else
+ SetAttack(nil);
+ }
+ }
+ } else {
+ m_pedIK.m_flags &= ~CPedIK::LOOKAROUND_HEAD_ONLY;
+ if (m_nPedState == PED_ATTACK) {
+ m_bHaveTargetSelected = true;
+ bIsAttacking = false;
+ }
+ }
+
+#ifdef FREE_CAM
+ // Rotate player/arm when shooting. We don't have auto-rotation anymore
+ if (CCamera::m_bUseMouse3rdPerson && CCamera::bFreeCam &&
+ m_nSelectedWepSlot == m_currentWeapon && m_nMoveState != PEDMOVE_SPRINT) {
+
+ // Weapons except throwable and melee ones
+ if (weaponInfo->m_bCanAim || weaponInfo->m_b1stPerson || weaponInfo->m_bExpands) {
+ if ((padUsed->GetTarget() && weaponInfo->m_bCanAimWithArm) || padUsed->GetWeapon()) {
+ float limitedCam = CGeneral::LimitRadianAngle(-TheCamera.Orientation);
+
+ // On this one we can rotate arm.
+ if (weaponInfo->m_bCanAimWithArm) {
+ if (!padUsed->GetWeapon()) { // making this State != ATTACK still stops it after attack. Re-start it immediately!
+ SetPointGunAt(nil);
+ bIsPointingGunAt = false; // to not stop after attack
+ }
+
+ SetLookFlag(limitedCam, true);
+ SetAimFlag(limitedCam);
+#ifdef VC_PED_PORTS
+ SetLookTimer(INT_MAX); // removing this makes head move for real, but I experinced some bugs.
+#endif
+ } else {
+ m_fRotationDest = limitedCam;
+ m_headingRate = 50.0f;
+
+ // Anim. fix for shotgun, ak47 and m16 (we must finish rot. it quickly)
+ if (weaponInfo->m_bCanAim && padUsed->WeaponJustDown()) {
+ m_fRotationCur = CGeneral::LimitRadianAngle(m_fRotationCur);
+ float limitedRotDest = m_fRotationDest;
+
+ if (m_fRotationCur - PI > m_fRotationDest) {
+ limitedRotDest += 2 * PI;
+ } else if (PI + m_fRotationCur < m_fRotationDest) {
+ limitedRotDest -= 2 * PI;
+ }
+
+ m_fRotationCur += (limitedRotDest - m_fRotationCur) / 2;
+ }
+ }
+ } else if (weaponInfo->m_bCanAimWithArm)
+ ClearPointGunAt();
+ else
+ RestoreHeadingRate();
+ }
+ }
+#endif
+
+ if (padUsed->GetTarget() && m_nSelectedWepSlot == m_currentWeapon && m_nMoveState != PEDMOVE_SPRINT) {
+ if (m_pPointGunAt) {
+ // what??
+ if (!m_pPointGunAt
+#ifdef FREE_CAM
+ || (!CCamera::bFreeCam && CCamera::m_bUseMouse3rdPerson)
+#else
+ || CCamera::m_bUseMouse3rdPerson
+#endif
+ || m_pPointGunAt->IsPed() && ((CPed*)m_pPointGunAt)->bInVehicle) {
+ ClearWeaponTarget();
+ return;
+ }
+ if (CPlayerPed::DoesTargetHaveToBeBroken(m_pPointGunAt->GetPosition(), GetWeapon())) {
+ ClearWeaponTarget();
+ return;
+ }
+ if (m_pPointGunAt) {
+ if (padUsed->ShiftTargetLeftJustDown())
+ FindNextWeaponLockOnTarget(m_pPointGunAt, true);
+ if (padUsed->ShiftTargetRightJustDown())
+ FindNextWeaponLockOnTarget(m_pPointGunAt, false);
+ }
+ TheCamera.SetNewPlayerWeaponMode(CCam::MODE_SYPHON, 0, 0);
+ TheCamera.UpdateAimingCoors(m_pPointGunAt->GetPosition());
+ }
+#ifdef FREE_CAM
+ else if ((CCamera::bFreeCam && weaponInfo->m_eWeaponFire == WEAPON_FIRE_MELEE) || (weaponInfo->m_bCanAim && !CCamera::m_bUseMouse3rdPerson)) {
+#else
+ else if (weaponInfo->m_bCanAim && !CCamera::m_bUseMouse3rdPerson) {
+#endif
+ if (padUsed->TargetJustDown())
+ FindWeaponLockOnTarget();
+ }
+ } else if (m_pPointGunAt) {
+ ClearWeaponTarget();
+ }
+
+ if (m_pPointGunAt) {
+#ifndef VC_PED_PORTS
+ CVector markPos = m_pPointGunAt->GetPosition();
+#else
+ CVector markPos;
+ if (m_pPointGunAt->IsPed()) {
+ ((CPed*)m_pPointGunAt)->m_pedIK.GetComponentPosition((RwV3d*)markPos, PED_MID);
+ } else {
+ markPos = m_pPointGunAt->GetPosition();
+ }
+#endif
+ if (bCanPointGunAtTarget) {
+ CWeaponEffects::MarkTarget(markPos, 64, 0, 0, 255, 0.8f);
+ } else {
+ CWeaponEffects::MarkTarget(markPos, 64, 32, 0, 255, 0.8f);
+ }
+ }
+ m_bHasLockOnTarget = m_pPointGunAt != nil;
+}
+
+void
+CPlayerPed::PlayerControlZelda(CPad *padUsed)
+{
+ bool doSmoothSpray = DoWeaponSmoothSpray();
+ float camOrientation = TheCamera.Orientation;
+ float leftRight = padUsed->GetPedWalkLeftRight();
+ float upDown = padUsed->GetPedWalkUpDown();
+ float padMoveInGameUnit;
+ bool smoothSprayWithoutMove = false;
+
+ if (doSmoothSpray && upDown > 0.0f) {
+ padMoveInGameUnit = 0.0f;
+ smoothSprayWithoutMove = true;
+ } else {
+ padMoveInGameUnit = CVector2D(leftRight, upDown).Magnitude() / PAD_MOVE_TO_GAME_WORLD_MOVE;
+ }
+
+ if (padMoveInGameUnit > 0.0f || smoothSprayWithoutMove) {
+ float padHeading = CGeneral::GetRadianAngleBetweenPoints(0.0f, 0.0f, -leftRight, upDown);
+ float neededTurn = CGeneral::LimitRadianAngle(padHeading - camOrientation);
+ if (doSmoothSpray) {
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER || GetWeapon()->m_eWeaponType == WEAPONTYPE_COLT45
+ || GetWeapon()->m_eWeaponType == WEAPONTYPE_UZI)
+ m_fRotationDest = m_fRotationCur - leftRight / 128.0f * (PI / 80.0f) * CTimer::GetTimeStep();
+ else
+ m_fRotationDest = m_fRotationCur - leftRight / 128.0f * (PI / 128.0f) * CTimer::GetTimeStep();
+ } else {
+ m_fRotationDest = neededTurn;
+ }
+
+ float maxAcc = 0.07f * CTimer::GetTimeStep();
+ m_fMoveSpeed = min(padMoveInGameUnit, m_fMoveSpeed + maxAcc);
+
+ } else {
+ m_fMoveSpeed = 0.0f;
+ }
+
+ if (m_nPedState == PED_JUMP) {
+ if (bIsInTheAir) {
+ if (bUsesCollision && !bHitSteepSlope &&
+ (!bHitSomethingLastFrame || m_vecDamageNormal.z > 0.6f)
+ && m_fDistanceTravelled < CTimer::GetTimeStep() * 0.02 && m_vecMoveSpeed.MagnitudeSqr() < 0.01f) {
+
+ float angleSin = Sin(m_fRotationCur); // originally sin(DEGTORAD(RADTODEG(m_fRotationCur))) o_O
+ float angleCos = Cos(m_fRotationCur);
+ ApplyMoveForce(-angleSin * 3.0f, 3.0f * angleCos, 0.05f);
+ }
+ } else if (bIsLanding) {
+ m_fMoveSpeed = 0.0f;
+ }
+ }
+
+ if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy)
+ && padUsed->GetSprint()) {
+ m_nMoveState = PEDMOVE_SPRINT;
+ }
+ if (m_nPedState != PED_FIGHT)
+ SetRealMoveAnim();
+
+ if (!bIsInTheAir && !(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy)
+ && padUsed->JumpJustDown() && m_nPedState != PED_JUMP) {
+ ClearAttack();
+ ClearWeaponTarget();
+ if (m_nEvadeAmount != 0 && m_pEvadingFrom) {
+ SetEvasiveDive((CPhysical*)m_pEvadingFrom, 1);
+ m_nEvadeAmount = 0;
+ m_pEvadingFrom = nil;
+ } else {
+ SetJump();
+ }
+ }
+}
+
+void
+CPlayerPed::ProcessControl(void)
+{
+ if (m_nEvadeAmount != 0)
+ --m_nEvadeAmount;
+
+ if (m_nEvadeAmount == 0)
+ m_pEvadingFrom = nil;
+
+ if (m_pCurrentPhysSurface && m_pCurrentPhysSurface->IsVehicle() && ((CVehicle*)m_pCurrentPhysSurface)->IsBoat()) {
+ bTryingToReachDryLand = true;
+ } else if (!(((uint8)CTimer::GetFrameCounter() + m_randomSeed) & 0xF)) {
+ CVehicle *nearVeh = (CVehicle*)CWorld::TestSphereAgainstWorld(GetPosition(), 7.0f, nil,
+ false, true, false, false, false, false);
+ if (nearVeh && nearVeh->IsBoat())
+ bTryingToReachDryLand = true;
+ else
+ bTryingToReachDryLand = false;
+ }
+ CPed::ProcessControl();
+ if (bWasPostponed)
+ return;
+
+ CPad *padUsed = CPad::GetPad(0);
+ m_pWanted->Update();
+ CEntity::PruneReferences();
+
+ if (m_nMoveState != PEDMOVE_RUN && m_nMoveState != PEDMOVE_SPRINT)
+ RestoreSprintEnergy(1.0f);
+ else if (m_nMoveState == PEDMOVE_RUN)
+ RestoreSprintEnergy(0.3f);
+
+ if (m_nPedState == PED_DEAD) {
+ ClearWeaponTarget();
+ return;
+ }
+ if (m_nPedState == PED_DIE) {
+ ClearWeaponTarget();
+ if (CTimer::GetTimeInMilliseconds() > m_bloodyFootprintCountOrDeathTime + 4000)
+ SetDead();
+ return;
+ }
+ if (m_nPedState == PED_DRIVING && m_objective != OBJECTIVE_LEAVE_VEHICLE) {
+ if (m_pMyVehicle->IsCar() && ((CAutomobile*)m_pMyVehicle)->Damage.GetDoorStatus(DOOR_FRONT_LEFT) == DOOR_STATUS_SWINGING) {
+ CAnimBlendAssociation *rollDoorAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_ROLLDOOR);
+ if (!rollDoorAssoc) {
+ rollDoorAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_ROLLDOOR_LOW);
+ }
+
+ // These comparisons are wrong, they return uint16
+ if (m_pMyVehicle->m_nGettingOutFlags & CAR_DOOR_FLAG_LF || rollDoorAssoc || padUsed
+ && (padUsed->GetAccelerate() != 0.0f || padUsed->GetSteeringLeftRight() != 0.0f
+ || padUsed->GetBrake() != 0.0f)) {
+
+ if (rollDoorAssoc)
+ m_pMyVehicle->ProcessOpenDoor(CAR_DOOR_LF, ANIM_CAR_ROLLDOOR, rollDoorAssoc->currentTime);
+ } else {
+ m_pMyVehicle->m_nGettingOutFlags |= CAR_DOOR_FLAG_LF;
+ if (m_pMyVehicle->bLowVehicle)
+ rollDoorAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_ROLLDOOR_LOW);
+ else
+ rollDoorAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_ROLLDOOR);
+
+ rollDoorAssoc->SetFinishCallback(PedAnimDoorCloseRollingCB, this);
+ }
+ }
+ return;
+ }
+ if (m_objective == OBJECTIVE_NONE)
+ m_nMoveState = PEDMOVE_STILL;
+ if (bIsLanding)
+ RunningLand(padUsed);
+ if (padUsed && padUsed->WeaponJustDown() && m_nPedState != PED_SNIPER_MODE) {
+
+ // ...Really?
+ eWeaponType playerWeapon = FindPlayerPed()->GetWeapon()->m_eWeaponType;
+ if (playerWeapon == WEAPONTYPE_SNIPERRIFLE) {
+ DMAudio.PlayFrontEndSound(SOUND_WEAPON_SNIPER_SHOT_NO_ZOOM, 0);
+ } else if (playerWeapon == WEAPONTYPE_ROCKETLAUNCHER) {
+ DMAudio.PlayFrontEndSound(SOUND_WEAPON_ROCKET_SHOT_NO_ZOOM, 0);
+ }
+ }
+
+ switch (m_nPedState) {
+ case PED_NONE:
+ case PED_IDLE:
+ case PED_FLEE_POS:
+ case PED_FLEE_ENTITY:
+ case PED_ATTACK:
+ case PED_FIGHT:
+ case PED_AIM_GUN:
+ if (!RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FLAG400)) {
+ if (TheCamera.Cams[0].Using3rdPersonMouseCam()) {
+ if (padUsed)
+ PlayerControl1stPersonRunAround(padUsed);
+ } else if (m_nPedState == PED_FIGHT) {
+ if (padUsed)
+ PlayerControlFighter(padUsed);
+ } else if (padUsed) {
+ PlayerControlZelda(padUsed);
+ }
+ }
+ if (IsPedInControl() && padUsed)
+ ProcessPlayerWeapon(padUsed);
+ break;
+ case PED_LOOK_ENTITY:
+ case PED_LOOK_HEADING:
+ case PED_WANDER_RANGE:
+ case PED_WANDER_PATH:
+ case PED_PURSUE:
+ case PED_FOLLOW_PATH:
+ case PED_ROCKET_ODE:
+ case PED_DUMMY:
+ case PED_PAUSE:
+ case PED_FACE_PHONE:
+ case PED_MAKE_CALL:
+ case PED_CHAT:
+ case PED_MUG:
+ case PED_AI_CONTROL:
+ case PED_FOLLOW_ROUTE:
+ case PED_CPR:
+ case PED_SOLICIT:
+ case PED_BUY_ICECREAM:
+ case PED_INVESTIGATE:
+ case PED_STEP_AWAY:
+ case PED_ON_FIRE:
+ case PED_UNKNOWN:
+ case PED_STATES_NO_AI:
+ case PED_STAGGER:
+ case PED_DIVE_AWAY:
+ case PED_STATES_NO_ST:
+ case PED_ARREST_PLAYER:
+ case PED_DRIVING:
+ case PED_PASSENGER:
+ case PED_TAXI_PASSENGER:
+ case PED_OPEN_DOOR:
+ case PED_DIE:
+ case PED_DEAD:
+ case PED_HANDS_UP:
+ break;
+ case PED_SEEK_ENTITY:
+ m_vecSeekPos = m_pSeekTarget->GetPosition();
+
+ // fall through
+ case PED_SEEK_POS:
+ switch (m_nMoveState) {
+ case PEDMOVE_WALK:
+ m_fMoveSpeed = 1.0f;
+ break;
+ case PEDMOVE_RUN:
+ m_fMoveSpeed = 1.8f;
+ break;
+ case PEDMOVE_SPRINT:
+ m_fMoveSpeed = 2.5f;
+ break;
+ default:
+ m_fMoveSpeed = 0.0f;
+ break;
+ }
+ SetRealMoveAnim();
+ if (Seek()) {
+ RestorePreviousState();
+ SetMoveState(PEDMOVE_STILL);
+ }
+ break;
+ case PED_SNIPER_MODE:
+ if (FindPlayerPed()->GetWeapon()->m_eWeaponType == WEAPONTYPE_M16) {
+ if (padUsed)
+ PlayerControlM16(padUsed);
+ } else if (padUsed) {
+ PlayerControlSniper(padUsed);
+ }
+ break;
+ case PED_SEEK_CAR:
+ case PED_SEEK_IN_BOAT:
+ if (bVehEnterDoorIsBlocked || bKindaStayInSamePlace) {
+ m_fMoveSpeed = 0.0f;
+ } else {
+ m_fMoveSpeed = min(2.0f, 2.0f * (m_vecSeekPos - GetPosition()).Magnitude2D());
+ }
+ if (padUsed && !padUsed->ArePlayerControlsDisabled()) {
+ if (padUsed->GetTarget() || padUsed->GetLeftStickXJustDown() || padUsed->GetLeftStickYJustDown() ||
+ padUsed->GetDPadUpJustDown() || padUsed->GetDPadDownJustDown() || padUsed->GetDPadLeftJustDown() ||
+ padUsed->GetDPadRightJustDown()) {
+
+ RestorePreviousState();
+ if (m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER || m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) {
+ RestorePreviousObjective();
+ }
+ }
+ }
+ if (padUsed && padUsed->GetSprint())
+ m_nMoveState = PEDMOVE_SPRINT;
+ SetRealMoveAnim();
+ break;
+ case PED_JUMP:
+ if (padUsed)
+ PlayerControlZelda(padUsed);
+ if (bIsLanding)
+ break;
+
+ // This has been added later it seems
+ return;
+ case PED_FALL:
+ case PED_GETUP:
+ case PED_ENTER_TRAIN:
+ case PED_EXIT_TRAIN:
+ case PED_CARJACK:
+ case PED_DRAG_FROM_CAR:
+ case PED_ENTER_CAR:
+ case PED_STEAL_CAR:
+ case PED_EXIT_CAR:
+ ClearWeaponTarget();
+ break;
+ case PED_ARRESTED:
+ if (m_nLastPedState == PED_DRAG_FROM_CAR && m_pVehicleAnim)
+ BeingDraggedFromCar();
+ break;
+ }
+ if (padUsed && IsPedShootable()) {
+ ProcessWeaponSwitch(padUsed);
+ GetWeapon()->Update(m_audioEntityId);
+ }
+ ProcessAnimGroups();
+ if (padUsed) {
+ if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_FOLLOWPED
+ && TheCamera.Cams[TheCamera.ActiveCam].DirectionWasLooking == LOOKING_BEHIND) {
+
+ m_lookTimer = 0;
+ float camAngle = CGeneral::LimitRadianAngle(TheCamera.Cams[TheCamera.ActiveCam].Front.Heading());
+ float angleBetweenPlayerAndCam = Abs(camAngle - m_fRotationCur);
+ if (m_nPedState != PED_ATTACK
+ && angleBetweenPlayerAndCam > DEGTORAD(30.0f) && angleBetweenPlayerAndCam < DEGTORAD(330.0f)) {
+
+ if (angleBetweenPlayerAndCam > DEGTORAD(150.0f) && angleBetweenPlayerAndCam < DEGTORAD(210.0f)) {
+ float rightTurnAngle = CGeneral::LimitRadianAngle(m_fRotationCur - DEGTORAD(150.0f));
+ float leftTurnAngle = CGeneral::LimitRadianAngle(DEGTORAD(150.0f) + m_fRotationCur);
+ if (m_fLookDirection != 999999.0f) {
+ if (Abs(rightTurnAngle - m_fLookDirection) < Abs(leftTurnAngle - m_fLookDirection))
+ camAngle = rightTurnAngle;
+ else
+ camAngle = leftTurnAngle;
+ } else {
+ camAngle = rightTurnAngle;
+ }
+ }
+ SetLookFlag(camAngle, true);
+ SetLookTimer(CTimer::GetTimeStepInMilliseconds() * 5.0f);
+ } else {
+ ClearLookFlag();
+ }
+ }
+ }
+ if (m_nMoveState == PEDMOVE_SPRINT && bIsLooking) {
+ ClearLookFlag();
+ SetLookTimer(250);
+ }
+
+ if (m_vecMoveSpeed.Magnitude2D() < 0.1f) {
+ if (m_nSpeedTimer) {
+ if (CTimer::GetTimeInMilliseconds() > m_nSpeedTimer)
+ m_bSpeedTimerFlag = true;
+ } else {
+ m_nSpeedTimer = CTimer::GetTimeInMilliseconds() + 500;
+ }
+ } else {
+ m_nSpeedTimer = 0;
+ m_bSpeedTimerFlag = false;
+ }
+}
+
+#include <new>
+
+class CPlayerPed_ : public CPlayerPed
+{
+public:
+ CPlayerPed* ctor(void) { return ::new (this) CPlayerPed(); }
+ void dtor(void) { CPlayerPed::~CPlayerPed(); }
+ void SetMoveAnim_(void) { CPlayerPed::SetMoveAnim(); }
+ void ProcessControl_(void) { CPlayerPed::ProcessControl(); }
+};
+
+STARTPATCHES
+ InjectHook(0x4EF7E0, &CPlayerPed_::ctor, PATCH_JUMP);
+ InjectHook(0x4EFB30, &CPlayerPed_::dtor, PATCH_JUMP);
+ InjectHook(0x4F3760, &CPlayerPed_::SetMoveAnim_, PATCH_JUMP);
+ InjectHook(0x4EFD90, &CPlayerPed_::ProcessControl_, PATCH_JUMP);
+ InjectHook(0x4F28A0, &CPlayerPed::ClearWeaponTarget, PATCH_JUMP);
+ InjectHook(0x4F3700, &CPlayerPed::AnnoyPlayerPed, PATCH_JUMP);
+ InjectHook(0x4F36C0, &CPlayerPed::GetPlayerInfoForThisPlayerPed, PATCH_JUMP);
+ InjectHook(0x4F2560, &CPlayerPed::MakeChangesForNewWeapon, PATCH_JUMP);
+ InjectHook(0x4F07C0, &CPlayerPed::ReApplyMoveAnims, PATCH_JUMP);
+ InjectHook(0x4F0880, &CPlayerPed::SetRealMoveAnim, PATCH_JUMP);
+ InjectHook(0x4F1810, &CPlayerPed::PlayerControlFighter, PATCH_JUMP);
+ InjectHook(0x4F1340, &CPlayerPed::RestoreSprintEnergy, PATCH_JUMP);
+ InjectHook(0x4F1380, &CPlayerPed::DoWeaponSmoothSpray, PATCH_JUMP);
+ InjectHook(0x4F36E0, &CPlayerPed::DoStuffToGoOnFire, PATCH_JUMP);
+ InjectHook(0x4F3350, &CPlayerPed::DoesTargetHaveToBeBroken, PATCH_JUMP);
+ InjectHook(0x4F31D0, &CPlayerPed::RunningLand, PATCH_JUMP);
+ InjectHook(0x4F2D00, &CPlayerPed::IsThisPedAttackingPlayer, PATCH_JUMP);
+ InjectHook(0x4F1CF0, &CPlayerPed::PlayerControlSniper, PATCH_JUMP);
+ InjectHook(0x4F2310, &CPlayerPed::ProcessWeaponSwitch, PATCH_JUMP);
+ InjectHook(0x4F1DF0, &CPlayerPed::PlayerControlM16, PATCH_JUMP);
+ InjectHook(0x4F3460, &CPlayerPed::KeepAreaAroundPlayerClear, PATCH_JUMP);
+ InjectHook(0x4F1970, &CPlayerPed::PlayerControl1stPersonRunAround, PATCH_JUMP);
+ InjectHook(0x4F1EF0, &CPlayerPed::ProcessPlayerWeapon, PATCH_JUMP);
+ InjectHook(0x4F2640, &CPlayerPed::ProcessAnimGroups, PATCH_JUMP);
+ENDPATCHES
diff --git a/src/peds/Population.cpp b/src/peds/Population.cpp
index 3bf81066..6959487f 100644
--- a/src/peds/Population.cpp
+++ b/src/peds/Population.cpp
@@ -29,39 +29,54 @@
#define PED_REMOVE_DIST (MIN_CREATION_DIST + CREATION_RANGE + 1.0f)
#define PED_REMOVE_DIST_SPECIAL (MIN_CREATION_DIST + CREATION_RANGE + 15.0f) // for peds with bCullExtraFarAway flag
-// TO-DO: These are hard-coded, reverse them.
-// More clearly they're transition areas between zones.
-RegenerationPoint (&aSafeZones)[8] = *(RegenerationPoint(*)[8]) * (uintptr*)0x5FA578;
-
-//PedGroup (&CPopulation::ms_pPedGroups)[NUMPEDGROUPS] = *(PedGroup(*)[NUMPEDGROUPS]) * (uintptr*)0x6E9248;
-PedGroup CPopulation::ms_pPedGroups[NUMPEDGROUPS];
-bool &CPopulation::ms_bGivePedsWeapons = *(bool*)0x95CCF6;
-int32 &CPopulation::m_AllRandomPedsThisType = *(int32*)0x5FA570;
-float &CPopulation::PedDensityMultiplier = *(float*)0x5FA56C;
-uint32 &CPopulation::ms_nTotalMissionPeds = *(uint32*)0x8F5F70;
-int32 &CPopulation::MaxNumberOfPedsInUse = *(int32*)0x5FA574;
-uint32& CPopulation::ms_nNumCivMale = *(uint32*)0x8F2548;
-uint32& CPopulation::ms_nNumCivFemale = *(uint32*)0x8F5F44;
-uint32& CPopulation::ms_nNumCop = *(uint32*)0x885AFC;
-bool& CPopulation::bZoneChangeHasHappened = *(bool*)0x95CD79;
-uint32& CPopulation::ms_nNumEmergency = *(uint32*)0x94071C;
-int8& CPopulation::m_CountDownToPedsAtStart = *(int8*)0x95CD4F;
-uint32& CPopulation::ms_nNumGang1 = *(uint32*)0x8F1B1C;
-uint32& CPopulation::ms_nNumGang2 = *(uint32*)0x8F1B14;
-uint32& CPopulation::ms_nTotalPeds = *(uint32*)0x95CB50;
-uint32& CPopulation::ms_nNumGang3 = *(uint32*)0x8F2548;
-uint32& CPopulation::ms_nTotalGangPeds = *(uint32*)0x885AF0;
-uint32& CPopulation::ms_nNumGang4 = *(uint32*)0x8F1B2C;
-uint32& CPopulation::ms_nTotalCivPeds = *(uint32*)0x8F2C3C;
-uint32& CPopulation::ms_nNumGang5 = *(uint32*)0x8F1B30;
-uint32& CPopulation::ms_nNumDummy = *(uint32*)0x8F1A98;
-uint32& CPopulation::ms_nNumGang6 = *(uint32*)0x8F1B20;
-uint32& CPopulation::ms_nNumGang9 = *(uint32*)0x8F1B10;
-uint32& CPopulation::ms_nNumGang7 = *(uint32*)0x8F1B28;
-uint32& CPopulation::ms_nNumGang8 = *(uint32*)0x8F1B0C;
-CVector &CPopulation::RegenerationPoint_a = *(CVector*)0x8E2AA4;
-CVector &CPopulation::RegenerationPoint_b = *(CVector*)0x8E2A98;
-CVector &CPopulation::RegenerationForward = *(CVector*)0x8F1AD4;
+// Transition areas between zones
+const RegenerationPoint aSafeZones[] = {
+ { LEVEL_INDUSTRIAL, LEVEL_COMMERCIAL, 400.0f, 814.0f, -954.0f, -903.0f, 30.0f, 100.0f,
+ CVector(790.0f, -917.0f, 39.0f), CVector(775.0f, -921.0f, 39.0f), CVector(424.0f, -942.0f, 38.0f), CVector(439.0f, -938.0f, 38.0f) },
+ { LEVEL_INDUSTRIAL, LEVEL_COMMERCIAL, 555.0f, 711.0f, 118.0f, 186.0f, -30.0f, -10.0f,
+ CVector(698.0f, 182.0f, -20.0f), CVector(681.0f, 178.0f, -20.0f), CVector(586.0f, 144.0f, -20.0f), CVector(577.0f, 135.0f, -20.0f) },
+ { LEVEL_INDUSTRIAL, LEVEL_COMMERCIAL, 26.0f, 44.0f, 124.0f, 87.0f, 20.0f, 6.0f,
+ CVector(736.0f, -117.0f, -13.0f), CVector(730.0f, -115.0f, -13.0f), CVector(635.0f, -93.0f, -12.5f), CVector(650.0f, -89.0f, -12.5f) },
+ { LEVEL_INDUSTRIAL, LEVEL_COMMERCIAL, 45.0f, 34.0f, 780.0f, 750.0f, 25.0f, 6.0f,
+ CVector(729.0f, -764.0f, -18.0f), CVector(720.0f, -769.0f, -17.0f), CVector(652.0f, -774.0f, -10.5f), CVector(659.0f, -770.0f, -10.5f) },
+ { LEVEL_COMMERCIAL, LEVEL_SUBURBAN, 532.0f, 136.0f, 668.0f, 599.0f, 4.0f, 0.0f,
+ CVector(-172.0f, -619.0f, 44.0f), CVector(-183.0f, -623.0f, 44.0f), CVector(-511.0f, -645.0f, 41.0f), CVector(-493.0f, -639.0f, 41.5f) },
+ { LEVEL_COMMERCIAL, LEVEL_SUBURBAN, 325.0f, 175.0f, 7.0f, 5.0f, 30.0f, 10.0f,
+ CVector(-185.0f, 40.8f, -20.5f), CVector(-202.0f, 37.0f, -20.5f), CVector(-315.0f, 65.5f, -20.5f), CVector(-306.0f, 62.4f, -20.5f) },
+ { LEVEL_COMMERCIAL, LEVEL_SUBURBAN, 410.0f, 310.0f, 1055.0f, 1030.0f, 20.0f, 6.0f,
+ CVector(-321.0f, -1043.0f, -13.2f), CVector(-328.0f, -1045.0f, -13.2f), CVector(-398.0f, -1044.0f, -13.5f), CVector(-390.0f, -1040.5f, -13.5f) },
+ { LEVEL_COMMERCIAL, LEVEL_SUBURBAN, 425.0f, 280.0f, 471.0f, 447.0f, 20.0f, 5.0f,
+ CVector(-292.0f, -457.0f, -11.6f), CVector(-310.0f, -461.0f, -11.6f), CVector(-413.0f, -461.0f, -11.5f), CVector(-399.0f, -457.0f, -11.3f) }
+}; // *(RegenerationPoint(*)[8]) * (uintptr*)0x5FA578;
+
+PedGroup CPopulation::ms_pPedGroups[NUMPEDGROUPS]; // = *(PedGroup(*)[NUMPEDGROUPS]) * (uintptr*)0x6E9248;
+bool CPopulation::ms_bGivePedsWeapons; // = *(bool*)0x95CCF6;
+int32 CPopulation::m_AllRandomPedsThisType = -1; // = *(int32*)0x5FA570;
+float CPopulation::PedDensityMultiplier = 1.0f; // = *(float*)0x5FA56C;
+uint32 CPopulation::ms_nTotalMissionPeds; // = *(uint32*)0x8F5F70;
+int32 CPopulation::MaxNumberOfPedsInUse = 25; // *(int32*)0x5FA574;
+uint32 CPopulation::ms_nNumCivMale; // = *(uint32*)0x8F2548;
+uint32 CPopulation::ms_nNumCivFemale; // = *(uint32*)0x8F5F44;
+uint32 CPopulation::ms_nNumCop; // = *(uint32*)0x885AFC;
+bool CPopulation::bZoneChangeHasHappened; // = *(bool*)0x95CD79;
+uint32 CPopulation::ms_nNumEmergency; // = *(uint32*)0x94071C;
+int8 CPopulation::m_CountDownToPedsAtStart; // = *(int8*)0x95CD4F;
+uint32 CPopulation::ms_nNumGang1; // = *(uint32*)0x8F1B1C;
+uint32 CPopulation::ms_nNumGang2; // = *(uint32*)0x8F1B14;
+uint32 CPopulation::ms_nTotalPeds; // = *(uint32*)0x95CB50;
+uint32 CPopulation::ms_nNumGang3; // = *(uint32*)0x8F2548;
+uint32 CPopulation::ms_nTotalGangPeds; // = *(uint32*)0x885AF0;
+uint32 CPopulation::ms_nNumGang4; // = *(uint32*)0x8F1B2C;
+uint32 CPopulation::ms_nTotalCivPeds; // = *(uint32*)0x8F2C3C;
+uint32 CPopulation::ms_nNumGang5; // = *(uint32*)0x8F1B30;
+uint32 CPopulation::ms_nNumDummy; // = *(uint32*)0x8F1A98;
+uint32 CPopulation::ms_nNumGang6; // = *(uint32*)0x8F1B20;
+uint32 CPopulation::ms_nNumGang9; // = *(uint32*)0x8F1B10;
+uint32 CPopulation::ms_nNumGang7; // = *(uint32*)0x8F1B28;
+uint32 CPopulation::ms_nNumGang8; // = *(uint32*)0x8F1B0C;
+CVector CPopulation::RegenerationPoint_a; // = *(CVector*)0x8E2AA4;
+CVector CPopulation::RegenerationPoint_b; // = *(CVector*)0x8E2A98;
+CVector CPopulation::RegenerationForward; // = *(CVector*)0x8F1AD4;
void
CPopulation::Initialise()
@@ -704,12 +719,15 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree
if (i != 0) {
// Gang member
newPed->SetLeader(gangLeader);
+#ifndef FIX_BUGS
+ // seems to be a miami leftover (this code is not on PS2) but gang peds end up just being frozen
newPed->m_nPedState = PED_UNKNOWN;
gangLeader->m_nPedState = PED_UNKNOWN;
newPed->m_fRotationCur = CGeneral::GetRadianAngleBetweenPoints(
gangLeader->GetPosition().x, gangLeader->GetPosition().y,
newPed->GetPosition().x, newPed->GetPosition().y);
newPed->m_fRotationDest = newPed->m_fRotationCur;
+#endif
} else {
gangLeader = newPed;
}
@@ -964,7 +982,7 @@ CPopulation::ConvertToRealObject(CDummyObject *dummy)
} else if (obj->m_modelIndex == MI_BUOY) {
obj->bIsStatic = false;
obj->m_vecMoveSpeed = CVector(0.0f, 0.0f, -0.001f);
- obj->m_flagD8 = true;
+ obj->bTouchingWater = true;
obj->AddToMovingList();
}
}
diff --git a/src/peds/Population.h b/src/peds/Population.h
index f9e6c3b7..aa8129c0 100644
--- a/src/peds/Population.h
+++ b/src/peds/Population.h
@@ -34,33 +34,33 @@ class CPopulation
{
public:
static PedGroup ms_pPedGroups[NUMPEDGROUPS];
- static bool &ms_bGivePedsWeapons;
- static int32 &m_AllRandomPedsThisType;
- static float &PedDensityMultiplier;
- static uint32 &ms_nTotalMissionPeds;
- static int32 &MaxNumberOfPedsInUse;
- static uint32& ms_nNumCivMale;
- static uint32 &ms_nNumCivFemale;
- static uint32 &ms_nNumCop;
- static bool &bZoneChangeHasHappened;
- static uint32 &ms_nNumEmergency;
- static int8& m_CountDownToPedsAtStart;
- static uint32& ms_nNumGang1;
- static uint32& ms_nNumGang2;
- static uint32& ms_nTotalPeds;
- static uint32& ms_nNumGang3;
- static uint32& ms_nTotalGangPeds;
- static uint32& ms_nNumGang4;
- static uint32& ms_nTotalCivPeds;
- static uint32& ms_nNumGang5;
- static uint32& ms_nNumDummy;
- static uint32& ms_nNumGang6;
- static uint32& ms_nNumGang9;
- static uint32& ms_nNumGang7;
- static uint32& ms_nNumGang8;
- static CVector& RegenerationPoint_a;
- static CVector& RegenerationPoint_b;
- static CVector& RegenerationForward;
+ static bool ms_bGivePedsWeapons;
+ static int32 m_AllRandomPedsThisType;
+ static float PedDensityMultiplier;
+ static uint32 ms_nTotalMissionPeds;
+ static int32 MaxNumberOfPedsInUse;
+ static uint32 ms_nNumCivMale;
+ static uint32 ms_nNumCivFemale;
+ static uint32 ms_nNumCop;
+ static bool bZoneChangeHasHappened;
+ static uint32 ms_nNumEmergency;
+ static int8 m_CountDownToPedsAtStart;
+ static uint32 ms_nNumGang1;
+ static uint32 ms_nNumGang2;
+ static uint32 ms_nTotalPeds;
+ static uint32 ms_nNumGang3;
+ static uint32 ms_nTotalGangPeds;
+ static uint32 ms_nNumGang4;
+ static uint32 ms_nTotalCivPeds;
+ static uint32 ms_nNumGang5;
+ static uint32 ms_nNumDummy;
+ static uint32 ms_nNumGang6;
+ static uint32 ms_nNumGang9;
+ static uint32 ms_nNumGang7;
+ static uint32 ms_nNumGang8;
+ static CVector RegenerationPoint_a;
+ static CVector RegenerationPoint_b;
+ static CVector RegenerationForward;
static void Initialise();
static void Update(void);