summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/control/Darkel.cpp2
-rw-r--r--src/control/Darkel.h2
-rw-r--r--src/modelinfo/PedModelInfo.cpp20
-rw-r--r--src/modelinfo/PedModelInfo.h4
-rw-r--r--src/peds/Ped.cpp955
-rw-r--r--src/peds/Ped.h35
-rw-r--r--src/peds/PedPlacement.cpp7
-rw-r--r--src/peds/PedPlacement.h2
-rw-r--r--src/peds/PlayerPed.cpp19
-rw-r--r--src/peds/PlayerPed.h3
-rw-r--r--src/vehicles/Vehicle.cpp4
11 files changed, 852 insertions, 201 deletions
diff --git a/src/control/Darkel.cpp b/src/control/Darkel.cpp
index 678fcd45..ad8d1176 100644
--- a/src/control/Darkel.cpp
+++ b/src/control/Darkel.cpp
@@ -141,7 +141,7 @@ void CDarkel::RegisterKillByPlayer(CPed *victim, eWeaponType weapontype, bool he
}
#endif
-void CDarkel::RegisterKillNotByPlayer()
+void CDarkel::RegisterKillNotByPlayer(CPed* victim, eWeaponType weapontype)
{
++CStats::NumberKillFrenziesPassed;
}
diff --git a/src/control/Darkel.h b/src/control/Darkel.h
index 35d849d2..77a14bb8 100644
--- a/src/control/Darkel.h
+++ b/src/control/Darkel.h
@@ -42,7 +42,7 @@ public:
static eKillFrenzyStatus ReadStatus();
static void RegisterCarBlownUpByPlayer(CVehicle *vehicle);
static void RegisterKillByPlayer(CPed *victim, eWeaponType weapontype, bool headshot = false);
- static void RegisterKillNotByPlayer();
+ static void RegisterKillNotByPlayer(CPed* victim, eWeaponType weapontype);
static void ResetModelsKilledByPlayer();
static void ResetOnPlayerDeath();
static void StartFrenzy(eWeaponType weaponType, int32 time, int16 kill, int32 modelId0, wchar *text, int32 modelId2, int32 modelId3, int32 modelId4, bool standardSound, bool needHeadShot);
diff --git a/src/modelinfo/PedModelInfo.cpp b/src/modelinfo/PedModelInfo.cpp
index 747cbc99..0ad218f3 100644
--- a/src/modelinfo/PedModelInfo.cpp
+++ b/src/modelinfo/PedModelInfo.cpp
@@ -1,5 +1,6 @@
#include "common.h"
#include "patcher.h"
+#include "Ped.h"
#include "NodeName.h"
#include "VisibilityPlugins.h"
#include "ModelInfo.h"
@@ -14,7 +15,7 @@ CPedModelInfo::DeleteRwObject(void)
}
RwObjectNameIdAssocation CPedModelInfo::m_pPedIds[12] = {
- { "Smid", PED_TORSO, 0, }, // that is strange...
+ { "Smid", PED_MID, 0, }, // that is strange...
{ "Shead", PED_HEAD, 0, },
{ "Supperarml", PED_UPPERARML, 0, },
{ "Supperarmr", PED_UPPERARMR, 0, },
@@ -109,17 +110,16 @@ struct ColNodeInfo
float radius;
};
-// TODO: find out piece types
#define NUMPEDINFONODES 8
ColNodeInfo m_pColNodeInfos[NUMPEDINFONODES] = {
- { nil, PED_HEAD, 6, 0.0f, 0.05f, 0.2f },
- { "Storso", 0, 0, 0.0f, 0.15f, 0.2f },
- { "Storso", 0, 0, 0.0f, -0.05f, 0.3f },
- { nil, PED_TORSO, 1, 0.0f, -0.07f, 0.3f },
- { nil, PED_UPPERARML, 2, 0.07f, -0.1f, 0.2f },
- { nil, PED_UPPERARMR, 3, -0.07f, -0.1f, 0.2f },
- { "Slowerlegl", 0, 4, 0.0f, 0.07f, 0.25f },
- { nil, PED_LOWERLEGR, 5, 0.0f, 0.07f, 0.25f },
+ { nil, PED_HEAD, PEDPIECE_HEAD, 0.0f, 0.05f, 0.2f },
+ { "Storso", PED_TORSO, PEDPIECE_NONE, 0.0f, 0.15f, 0.2f },
+ { "Storso", PED_TORSO, PEDPIECE_NONE, 0.0f, -0.05f, 0.3f },
+ { nil, PED_MID, PEDPIECE_BODY, 0.0f, -0.07f, 0.3f },
+ { nil, PED_UPPERARML, PEDPIECE_LEFTARM, 0.07f, -0.1f, 0.2f },
+ { nil, PED_UPPERARMR, PEDPIECE_RIGHTARM, -0.07f, -0.1f, 0.2f },
+ { "Slowerlegl", 0, PEDPIECE_LEFTLEG, 0.0f, 0.07f, 0.25f },
+ { nil, PED_LOWERLEGR, PEDPIECE_RIGHTLEG, 0.0f, 0.07f, 0.25f },
};
RwObject*
diff --git a/src/modelinfo/PedModelInfo.h b/src/modelinfo/PedModelInfo.h
index bec46b4e..483d13f8 100644
--- a/src/modelinfo/PedModelInfo.h
+++ b/src/modelinfo/PedModelInfo.h
@@ -3,8 +3,8 @@
#include "ClumpModelInfo.h"
enum PedNode {
- PED_WAIST,
- PED_TORSO, // Smid on PS2/PC, Storso on mobile/xbox
+ PED_TORSO,
+ PED_MID, // Smid on PS2/PC, Storso on mobile/xbox
PED_HEAD,
PED_UPPERARML,
PED_UPPERARMR,
diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp
index b1738465..47934a24 100644
--- a/src/peds/Ped.cpp
+++ b/src/peds/Ped.cpp
@@ -26,10 +26,10 @@
#include "Pad.h"
#include "Phones.h"
#include "EventList.h"
+#include "Darkel.h"
WRAPPER void CPed::KillPedWithCar(CVehicle *veh, float impulse) { EAXJMP(0x4EC430); }
WRAPPER void CPed::Say(uint16 audio) { EAXJMP(0x4E5A10); }
-WRAPPER void CPed::SetDie(AnimationId anim, float arg1, float arg2) { EAXJMP(0x4D37D0); }
WRAPPER void CPed::SetDead(void) { EAXJMP(0x4D3970); }
WRAPPER void CPed::SpawnFlyingComponent(int, int8) { EAXJMP(0x4EB060); }
WRAPPER void CPed::RestorePreviousState(void) { EAXJMP(0x4C5E30); }
@@ -54,6 +54,7 @@ WRAPPER void CPed::SetFollowPath(CVector) { EAXJMP(0x4D2EA0); }
bool &CPed::bNastyLimbsCheat = *(bool*)0x95CD44;
bool &CPed::bPedCheat2 = *(bool*)0x95CD5A;
bool &CPed::bPedCheat3 = *(bool*)0x95CD59;
+CColPoint &CPed::ms_tempColPoint = *(CColPoint*)0x62DB14;
uint16 &CPed::distanceMultToCountPedNear = *(uint16*)0x5F8C98;
@@ -383,10 +384,10 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
m_ped_flagC1 = false;
bRespondsToThreats = true;
- m_ped_flagC4 = true;
- m_ped_flagC8 = false;
+ bRenderPedInCar = true;
+ bChangedSeat = false;
m_ped_flagC10 = false;
- m_ped_flagC20 = false;
+ bBodyPartJustCameOff = false;
m_ped_flagC40 = false;
m_ped_flagC80 = false;
@@ -394,7 +395,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
m_ped_flagD2 = false;
m_ped_flagD4 = false;
m_ped_flagD8 = false;
- m_ped_flagD10 = false;
+ bIsPedDieAnimPlaying = false;
m_ped_flagD20 = false;
m_ped_flagD40 = false;
m_bScriptObjectiveCompleted = false;
@@ -672,7 +673,7 @@ CPed::AimGun(void)
if (m_pSeekTarget) {
if (m_pSeekTarget->IsPed()) {
- ((CPed*)m_pSeekTarget)->m_pedIK.GetComponentPosition(&pos, PED_TORSO);
+ ((CPed*)m_pSeekTarget)->m_pedIK.GetComponentPosition(&pos, PED_MID);
vector.x = pos.x;
vector.y = pos.y;
vector.z = pos.z;
@@ -712,7 +713,7 @@ CPed::ApplyHeadShot(eWeaponType weaponType, CVector pos, bool evenOnPlayer)
CPed::SetDie(ANIM_KO_SHOT_FRONT1, 4.0f, 0.0f);
}
- m_ped_flagC20 = true;
+ bBodyPartJustCameOff = true;
m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 150;
CParticle::AddParticle(PARTICLE_TEST, pos2,
@@ -736,7 +737,7 @@ CPed::ApplyHeadShot(eWeaponType weaponType, CVector pos, bool evenOnPlayer)
}
void
-CPed::RemoveBodyPart(PedNode nodeId, int8 unk)
+CPed::RemoveBodyPart(PedNode nodeId, int8 direction)
{
RwFrame *frame;
RwV3d pos;
@@ -745,7 +746,7 @@ CPed::RemoveBodyPart(PedNode nodeId, int8 unk)
if (frame) {
if (CGame::nastyGame) {
if (nodeId != PED_HEAD)
- CPed::SpawnFlyingComponent(nodeId, unk);
+ SpawnFlyingComponent(nodeId, direction);
RecurseFrameChildrenVisibilityCB(frame, nil);
pos.x = 0.0f;
@@ -767,7 +768,7 @@ CPed::RemoveBodyPart(PedNode nodeId, int8 unk)
nil, 0.0f, 0, 0, 0, 0);
}
}
- m_ped_flagC20 = true;
+ bBodyPartJustCameOff = true;
m_bodyPartBleeding = nodeId;
}
} else {
@@ -1046,184 +1047,186 @@ CPed::Attack(void)
weaponAnimAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ANIM_WEAPON_THROWU);
delayBetweenAnimAndFire = 0.2f;
}
- }
- if (weaponAnimAssoc) {
- animStart = ourWeapon->m_fAnimLoopStart;
- weaponAnimTime = weaponAnimAssoc->currentTime;
- if (weaponAnimTime > animStart && weaponAnimTime - weaponAnimAssoc->timeStep <= animStart) {
- if (ourWeapon->m_bCanAimWithArm)
- m_pedIK.m_flags |= CPedIK::FLAG_4;
- else
- m_pedIK.m_flags &= ~CPedIK::FLAG_4;
+
+ if (!weaponAnimAssoc) {
+ if (lastReloadWasInFuture) {
+ if (ourWeaponFire != WEAPON_FIRE_PROJECTILE || !IsPlayer() || ((CPlayerPed*)this)->field_1380) {
+ if (!CGame::nastyGame || ourWeaponFire != WEAPON_FIRE_MELEE || CheckForPedsOnGroundToAttack(((CPlayerPed*)this), nil) < PED_ON_THE_FLOOR) {
+ weaponAnimAssoc = CAnimManager::BlendAnimation((RpClump*)m_rwObject, ASSOCGRP_STD, ourWeapon->m_AnimToPlay, 8.0f);
+ }
+ else {
+ weaponAnimAssoc = CAnimManager::BlendAnimation((RpClump*)m_rwObject, ASSOCGRP_STD, ourWeapon->m_Anim2ToPlay, 8.0f);
+ }
+
+ weaponAnimAssoc->SetFinishCallback(CPed::FinishedAttackCB, this);
+ weaponAnimAssoc->flags |= ASSOC_RUNNING;
+
+ if (weaponAnimAssoc->currentTime == weaponAnimAssoc->hierarchy->totalLength)
+ weaponAnimAssoc->SetCurrentTime(0.0f);
+
+ if (IsPlayer()) {
+ ((CPlayerPed*)this)->field_1376 = 0.0f;
+ ((CPlayerPed*)this)->field_1380 = false;
+ }
+ }
+ } else
+ FinishedAttackCB(nil, this);
+
+ return;
}
+ }
- if (weaponAnimTime <= delayBetweenAnimAndFire || weaponAnimTime - weaponAnimAssoc->timeStep > delayBetweenAnimAndFire || !weaponAnimAssoc->IsRunning()) {
- if (weaponAnimAssoc->speed < 1.0f)
- weaponAnimAssoc->speed = 1.0f;
+ animStart = ourWeapon->m_fAnimLoopStart;
+ weaponAnimTime = weaponAnimAssoc->currentTime;
+ if (weaponAnimTime > animStart && weaponAnimTime - weaponAnimAssoc->timeStep <= animStart) {
+ if (ourWeapon->m_bCanAimWithArm)
+ m_pedIK.m_flags |= CPedIK::FLAG_4;
+ else
+ m_pedIK.m_flags &= ~CPedIK::FLAG_4;
+ }
- } else {
- firePos = ourWeapon->m_vecFireOffset;
- if (ourWeaponType == WEAPONTYPE_BASEBALLBAT) {
- if (weaponAnimAssoc->animId == ourWeapon->m_Anim2ToPlay)
- firePos.z = 0.7f * ourWeapon->m_fRadius - 1.0f;
-
- firePos = GetMatrix() * firePos;
- } else if (ourWeaponType != WEAPONTYPE_UNARMED) {
- if (weaponAnimAssoc->animId == ANIM_KICK_FLOOR)
- frame = GetNodeFrame(PED_FOOTR);
- else
- frame = GetNodeFrame(PED_HANDR);
+ if (weaponAnimTime <= delayBetweenAnimAndFire || weaponAnimTime - weaponAnimAssoc->timeStep > delayBetweenAnimAndFire || !weaponAnimAssoc->IsRunning()) {
+ if (weaponAnimAssoc->speed < 1.0f)
+ weaponAnimAssoc->speed = 1.0f;
- for (; frame; frame = RwFrameGetParent(frame))
- RwV3dTransformPoints((RwV3d*)firePos, (RwV3d*)firePos, 1, RwFrameGetMatrix(frame));
- } else {
- firePos = GetMatrix() * firePos;
- }
+ } else {
+ firePos = ourWeapon->m_vecFireOffset;
+ if (ourWeaponType == WEAPONTYPE_BASEBALLBAT) {
+ if (weaponAnimAssoc->animId == ourWeapon->m_Anim2ToPlay)
+ firePos.z = 0.7f * ourWeapon->m_fRadius - 1.0f;
+
+ firePos = GetMatrix() * firePos;
+ } else if (ourWeaponType != WEAPONTYPE_UNARMED) {
+ if (weaponAnimAssoc->animId == ANIM_KICK_FLOOR)
+ frame = GetNodeFrame(PED_FOOTR);
+ else
+ frame = GetNodeFrame(PED_HANDR);
+
+ for (; frame; frame = RwFrameGetParent(frame))
+ RwV3dTransformPoints((RwV3d*)firePos, (RwV3d*)firePos, 1, RwFrameGetMatrix(frame));
+ } else {
+ firePos = GetMatrix() * firePos;
+ }
- GetWeapon()->Fire(this, &firePos);
+ GetWeapon()->Fire(this, &firePos);
- if (ourWeaponType == WEAPONTYPE_MOLOTOV || ourWeaponType == WEAPONTYPE_GRENADE) {
- RemoveWeaponModel(ourWeapon->m_nModelId);
+ if (ourWeaponType == WEAPONTYPE_MOLOTOV || ourWeaponType == WEAPONTYPE_GRENADE) {
+ RemoveWeaponModel(ourWeapon->m_nModelId);
+ }
+ if (!GetWeapon()->m_nAmmoTotal && ourWeaponFire != WEAPON_FIRE_MELEE && FindPlayerPed() != this) {
+ SelectGunIfArmed();
+ }
+
+ if (GetWeapon()->m_eWeaponState != WEAPONSTATE_MELEE_MADECONTACT) {
+ // If reloading just began, start the animation
+ if (GetWeapon()->m_eWeaponState == WEAPONSTATE_RELOADING && reloadAnim != NUM_ANIMS && !reloadAnimAssoc) {
+ CAnimManager::BlendAnimation((RpClump*) m_rwObject, ASSOCGRP_STD, reloadAnim, 8.0f);
+ ClearLookFlag();
+ ClearAimFlag();
+ m_ped_flagA4 = false;
+ bIsPointingGunAt = false;
+ m_lastHitTime = CTimer::GetTimeInMilliseconds();
+ return;
}
- if (!GetWeapon()->m_nAmmoTotal && ourWeaponFire != WEAPON_FIRE_MELEE && FindPlayerPed() != this) {
- SelectGunIfArmed();
+ } else {
+ if (weaponAnimAssoc->animId == ANIM_WEAPON_BAT_V || weaponAnimAssoc->animId == ANIM_WEAPON_BAT_H) {
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, 1.0f);
+ } else if (weaponAnimAssoc->animId == ANIM_FIGHT_PPUNCH) {
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_PUNCH_ATTACK, 0.0f);
}
- if (GetWeapon()->m_eWeaponState != WEAPONSTATE_MELEE_MADECONTACT) {
- // If reloading just began, start the animation
- if (GetWeapon()->m_eWeaponState == WEAPONSTATE_RELOADING && reloadAnim != NUM_ANIMS && !reloadAnimAssoc) {
- CAnimManager::BlendAnimation((RpClump*) m_rwObject, ASSOCGRP_STD, reloadAnim, 8.0f);
- ClearLookFlag();
- ClearAimFlag();
- m_ped_flagA4 = false;
- bIsPointingGunAt = false;
- m_lastHitTime = CTimer::GetTimeInMilliseconds();
- return;
- }
- } else {
- if (weaponAnimAssoc->animId == ANIM_WEAPON_BAT_V || weaponAnimAssoc->animId == ANIM_WEAPON_BAT_H) {
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, 1.0f);
- } else if (weaponAnimAssoc->animId == ANIM_FIGHT_PPUNCH) {
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_PUNCH_ATTACK, 0.0f);
- }
-
- weaponAnimAssoc->speed = 0.5f;
+ weaponAnimAssoc->speed = 0.5f;
- // BUG: We currently don't know any situation this cond. could be true.
- if (m_ped_flagA4 || CTimer::GetTimeInMilliseconds() < m_lastHitTime) {
- weaponAnimAssoc->callbackType = 0;
- }
+ // BUG: We currently don't know any situation this cond. could be true.
+ if (m_ped_flagA4 || CTimer::GetTimeInMilliseconds() < m_lastHitTime) {
+ weaponAnimAssoc->callbackType = 0;
}
-
- lastReloadWasInFuture = false;
}
- if (ourWeaponType == WEAPONTYPE_SHOTGUN) {
- weaponAnimTime = weaponAnimAssoc->currentTime;
- firePos = ourWeapon->m_vecFireOffset;
+ lastReloadWasInFuture = false;
+ }
- if (weaponAnimTime > 1.0f && weaponAnimTime - weaponAnimAssoc->timeStep <= 1.0f && weaponAnimAssoc->IsRunning()) {
- for (frame = GetNodeFrame(PED_HANDR); frame; frame = RwFrameGetParent(frame))
- RwV3dTransformPoints((RwV3d*)firePos, (RwV3d*)firePos, 1, RwFrameGetMatrix(frame));
+ if (ourWeaponType == WEAPONTYPE_SHOTGUN) {
+ weaponAnimTime = weaponAnimAssoc->currentTime;
+ firePos = ourWeapon->m_vecFireOffset;
- CVector gunshellPos(
- firePos.x - 0.6f * GetForward().x,
- firePos.y - 0.6f * GetForward().y,
- firePos.z - 0.15f * GetUp().z
- );
+ if (weaponAnimTime > 1.0f && weaponAnimTime - weaponAnimAssoc->timeStep <= 1.0f && weaponAnimAssoc->IsRunning()) {
+ for (frame = GetNodeFrame(PED_HANDR); frame; frame = RwFrameGetParent(frame))
+ RwV3dTransformPoints((RwV3d*)firePos, (RwV3d*)firePos, 1, RwFrameGetMatrix(frame));
- CVector2D gunshellRot(
- GetRight().x,
- GetRight().y
- );
+ CVector gunshellPos(
+ firePos.x - 0.6f * GetForward().x,
+ firePos.y - 0.6f * GetForward().y,
+ firePos.z - 0.15f * GetUp().z
+ );
- gunshellRot.Normalise();
- GetWeapon()->AddGunshell(this, gunshellPos, gunshellRot, 0.025f);
- }
+ CVector2D gunshellRot(
+ GetRight().x,
+ GetRight().y
+ );
+
+ gunshellRot.Normalise();
+ GetWeapon()->AddGunshell(this, gunshellPos, gunshellRot, 0.025f);
}
- animLoopEnd = ourWeapon->m_fAnimLoopEnd;
- if (ourWeaponFire == WEAPON_FIRE_MELEE && weaponAnimAssoc->animId == ourWeapon->m_Anim2ToPlay)
- animLoopEnd = 3.4f/6.0f;
+ }
+ animLoopEnd = ourWeapon->m_fAnimLoopEnd;
+ if (ourWeaponFire == WEAPON_FIRE_MELEE && weaponAnimAssoc->animId == ourWeapon->m_Anim2ToPlay)
+ animLoopEnd = 3.4f/6.0f;
- weaponAnimTime = weaponAnimAssoc->currentTime;
+ weaponAnimTime = weaponAnimAssoc->currentTime;
- // Anim loop end, either start the loop again or finish the attack
- if (weaponAnimTime > animLoopEnd || !weaponAnimAssoc->IsRunning() && ourWeaponFire != WEAPON_FIRE_PROJECTILE) {
+ // Anim loop end, either start the loop again or finish the attack
+ if (weaponAnimTime > animLoopEnd || !weaponAnimAssoc->IsRunning() && ourWeaponFire != WEAPON_FIRE_PROJECTILE) {
- if (weaponAnimTime - 2.0f * weaponAnimAssoc->timeStep <= animLoopEnd
- && (m_ped_flagA4 || CTimer::GetTimeInMilliseconds() < m_lastHitTime)
- && GetWeapon()->m_eWeaponState != WEAPONSTATE_RELOADING) {
+ if (weaponAnimTime - 2.0f * weaponAnimAssoc->timeStep <= animLoopEnd
+ && (m_ped_flagA4 || CTimer::GetTimeInMilliseconds() < m_lastHitTime)
+ && GetWeapon()->m_eWeaponState != WEAPONSTATE_RELOADING) {
- weaponAnim = weaponAnimAssoc->animId;
- if (ourWeaponFire != WEAPON_FIRE_MELEE || CheckForPedsOnGroundToAttack(((CPlayerPed*)this), nil) < PED_ON_THE_FLOOR) {
- if (weaponAnim != ourWeapon->m_Anim2ToPlay || weaponAnim == ANIM_RBLOCK_CSHOOT) {
- weaponAnimAssoc->Start(ourWeapon->m_fAnimLoopStart);
- } else {
- CAnimManager::BlendAnimation((RpClump*) m_rwObject, ASSOCGRP_STD, ourWeapon->m_AnimToPlay, 8.0f);
- }
+ weaponAnim = weaponAnimAssoc->animId;
+ if (ourWeaponFire != WEAPON_FIRE_MELEE || CheckForPedsOnGroundToAttack(((CPlayerPed*)this), nil) < PED_ON_THE_FLOOR) {
+ if (weaponAnim != ourWeapon->m_Anim2ToPlay || weaponAnim == ANIM_RBLOCK_CSHOOT) {
+ weaponAnimAssoc->Start(ourWeapon->m_fAnimLoopStart);
} else {
- if (weaponAnim == ourWeapon->m_Anim2ToPlay)
- weaponAnimAssoc->SetCurrentTime(0.1f);
- else
- CAnimManager::BlendAnimation((RpClump*) m_rwObject, ASSOCGRP_STD, ourWeapon->m_Anim2ToPlay, 8.0f);
+ CAnimManager::BlendAnimation((RpClump*) m_rwObject, ASSOCGRP_STD, ourWeapon->m_AnimToPlay, 8.0f);
}
} else {
- ClearAimFlag();
-
- // Echoes of bullets, at the end of the attack. (Bug: doesn't play while reloading)
- if (weaponAnimAssoc->currentTime - weaponAnimAssoc->timeStep <= ourWeapon->m_fAnimLoopEnd) {
- switch (ourWeaponType) {
- case WEAPONTYPE_UZI:
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_UZI_BULLET_ECHO, 0.0f);
- break;
- case WEAPONTYPE_AK47:
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, 0.0f);
- break;
- case WEAPONTYPE_M16:
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_M16_BULLET_ECHO, 0.0f);
- break;
- default:
- break;
- }
- }
-
- // Fun fact: removing this part leds to reloading flamethrower
- if (ourWeaponType == WEAPONTYPE_FLAMETHROWER && weaponAnimAssoc->IsRunning()) {
- weaponAnimAssoc->flags |= ASSOC_DELETEFADEDOUT;
- weaponAnimAssoc->flags &= ~ASSOC_RUNNING;
- weaponAnimAssoc->blendDelta = -4.0f;
+ if (weaponAnim == ourWeapon->m_Anim2ToPlay)
+ weaponAnimAssoc->SetCurrentTime(0.1f);
+ else
+ CAnimManager::BlendAnimation((RpClump*) m_rwObject, ASSOCGRP_STD, ourWeapon->m_Anim2ToPlay, 8.0f);
+ }
+ } else {
+ ClearAimFlag();
+
+ // Echoes of bullets, at the end of the attack. (Bug: doesn't play while reloading)
+ if (weaponAnimAssoc->currentTime - weaponAnimAssoc->timeStep <= ourWeapon->m_fAnimLoopEnd) {
+ switch (ourWeaponType) {
+ case WEAPONTYPE_UZI:
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_UZI_BULLET_ECHO, 0.0f);
+ break;
+ case WEAPONTYPE_AK47:
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, 0.0f);
+ break;
+ case WEAPONTYPE_M16:
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_M16_BULLET_ECHO, 0.0f);
+ break;
+ default:
+ break;
}
}
- }
- if (weaponAnimAssoc->currentTime > delayBetweenAnimAndFire)
- lastReloadWasInFuture = false;
-
- m_ped_flagA4 = lastReloadWasInFuture;
- return;
- }
- if (lastReloadWasInFuture) {
- if (ourWeaponFire != WEAPON_FIRE_PROJECTILE || !CPed::IsPlayer() || ((CPlayerPed*)this)->field_1380) {
- if (!CGame::nastyGame || ourWeaponFire != WEAPON_FIRE_MELEE || CheckForPedsOnGroundToAttack(((CPlayerPed*)this), nil) < PED_ON_THE_FLOOR) {
- weaponAnimAssoc = CAnimManager::BlendAnimation((RpClump*)m_rwObject, ASSOCGRP_STD, ourWeapon->m_AnimToPlay, 8.0f);
- } else {
- weaponAnimAssoc = CAnimManager::BlendAnimation((RpClump*)m_rwObject, ASSOCGRP_STD, ourWeapon->m_Anim2ToPlay, 8.0f);
- }
-
- weaponAnimAssoc->SetFinishCallback(CPed::FinishedAttackCB, this);
- weaponAnimAssoc->flags |= ASSOC_RUNNING;
-
- if (weaponAnimAssoc->currentTime == weaponAnimAssoc->hierarchy->totalLength)
- weaponAnimAssoc->SetCurrentTime(0.0f);
-
- if (CPed::IsPlayer()) {
- ((CPlayerPed*)this)->field_1376 = 0.0f;
- ((CPlayerPed*)this)->field_1380 = false;
+ // Fun fact: removing this part leds to reloading flamethrower
+ if (ourWeaponType == WEAPONTYPE_FLAMETHROWER && weaponAnimAssoc->IsRunning()) {
+ weaponAnimAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ weaponAnimAssoc->flags &= ~ASSOC_RUNNING;
+ weaponAnimAssoc->blendDelta = -4.0f;
}
}
}
- else
- CPed::FinishedAttackCB(nil, this);
+ if (weaponAnimAssoc->currentTime > delayBetweenAnimAndFire)
+ lastReloadWasInFuture = false;
+
+ m_ped_flagA4 = lastReloadWasInFuture;
}
void
@@ -1276,25 +1279,26 @@ CPed::Duck(void)
void
CPed::ClearDuck(void)
{
- CAnimBlendAssociation *animAssoc;
+ CAnimBlendAssociation* animAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ANIM_DUCK_DOWN);
+ if (!animAssoc) {
+ animAssoc = RpAnimBlendClumpGetAssociation((RpClump*)m_rwObject, ANIM_DUCK_LOW);
- animAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ANIM_DUCK_DOWN);
- if (!animAssoc)
- animAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ANIM_DUCK_LOW);
+ if (!animAssoc) {
+ bIsDucking = false;
+ return;
+ }
+ }
- if (animAssoc) {
+ if (!bCrouchWhenShooting)
+ return;
- if (bCrouchWhenShooting) {
+ if (m_nPedState != PED_ATTACK && m_nPedState != PED_AIM_GUN)
+ return;
- if (m_nPedState == PED_ATTACK || m_nPedState == PED_AIM_GUN) {
- animAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ANIM_RBLOCK_CSHOOT);
- if (!animAssoc || animAssoc->blendDelta < 0.0f) {
- CAnimManager::BlendAnimation((RpClump*) m_rwObject, ASSOCGRP_STD, ANIM_RBLOCK_CSHOOT, 4.0f);
- }
- }
- }
- } else
- bIsDucking = false;
+ animAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ANIM_RBLOCK_CSHOOT);
+ if (!animAssoc || animAssoc->blendDelta < 0.0f) {
+ CAnimManager::BlendAnimation((RpClump*) m_rwObject, ASSOCGRP_STD, ANIM_RBLOCK_CSHOOT, 4.0f);
+ }
}
void
@@ -1563,7 +1567,7 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
if (CReplay::IsPlayingBack())
return;
- if (!m_ped_flagC8 && phase != LINE_UP_TO_CAR_2) {
+ if (!bChangedSeat && phase != LINE_UP_TO_CAR_2) {
if (RpAnimBlendClumpGetAssociation((RpClump*)m_rwObject, ANIM_CAR_SIT)) {
SetPedPositionInCar();
return;
@@ -1580,7 +1584,7 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
SetPedPositionInCar();
return;
}
- m_ped_flagC8 = 1;
+ bChangedSeat = true;
}
if (phase == LINE_UP_TO_CAR_START) {
m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
@@ -1970,7 +1974,7 @@ CPed::BuildPedLists(void)
static CPed *unsortedNearPeds[10];
uint16 nextNearPedSlot = 0;
- if ((CTimer::GetFrameCounter() + m_randomSeed) & 15) {
+ if ((CTimer::GetFrameCounter() + m_randomSeed) % 16) {
for(int i = 0; i < 10; ) {
if (m_nearPeds[i]) {
@@ -3113,7 +3117,7 @@ CPed::ClearAll(void)
ClearAimFlag();
ClearLookFlag();
bIsPointingGunAt = false;
- m_ped_flagC4 = true;
+ bRenderPedInCar = true;
m_ped_flagH1 = false;
m_pCollidingEntity = nil;
}
@@ -3136,6 +3140,597 @@ CPed::ClearAttack(void)
}
}
+void
+CPed::ClearAttackByRemovingAnim(void)
+{
+ if (m_nPedState != PED_ATTACK || bIsDucking)
+ return;
+
+ CWeaponInfo *weapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
+ CAnimBlendAssociation *weaponAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, weapon->m_AnimToPlay);
+ if (!weaponAssoc) {
+ weaponAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, weapon->m_Anim2ToPlay);
+
+ if (!weaponAssoc && weapon->m_bThrow)
+ weaponAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ANIM_WEAPON_THROWU);
+
+ if (!weaponAssoc) {
+ ClearAttack();
+ return;
+ }
+ }
+ weaponAssoc->blendDelta = -8.0f;
+ weaponAssoc->flags &= ~ASSOC_RUNNING;
+ weaponAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ weaponAssoc->SetDeleteCallback(FinishedAttackCB, this);
+}
+
+void
+CPed::StopNonPartialAnims(void)
+{
+ CAnimBlendAssociation* assoc;
+
+ for (assoc = RpAnimBlendClumpGetFirstAssociation((RpClump*)m_rwObject); assoc; assoc = RpAnimBlendGetNextAssociation(assoc)) {
+ if (!assoc->IsPartial())
+ assoc->flags &= ~ASSOC_RUNNING;
+ }
+}
+
+void
+CPed::SetStoredState(void)
+{
+ if (m_nLastPedState != PED_NONE || !CanPedReturnToState())
+ return;
+
+ if (m_nPedState == PED_WANDER_PATH) {
+ m_ped_flagC80 = true;
+ if (m_nMoveState == PEDMOVE_NONE || m_nMoveState == PEDMOVE_STILL)
+ m_nMoveState = PEDMOVE_WALK;
+ }
+ m_nLastPedState = m_nPedState;
+ if (m_nMoveState >= m_nPrevActionState)
+ m_nPrevActionState = m_nMoveState;
+}
+
+void
+CPed::SetDie(AnimationId animId, float delta, float speed)
+{
+ CPlayerPed *player = FindPlayerPed();
+ if (player == this) {
+ if (!player->m_bCanBeDamaged)
+ return;
+ }
+
+ m_threatEntity = nil;
+ if (m_nPedState == PED_DIE || m_nPedState == PED_DEAD)
+ return;
+
+ if (m_nPedState == PED_FALL || m_nPedState == PED_GETUP)
+ delta *= 0.5f;
+
+ SetStoredState();
+ ClearAll();
+ m_fHealth = 0.0f;
+ if (m_nPedState == PED_DRIVING) {
+ if (!IsPlayer())
+ FlagToDestroyWhenNextProcessed();
+ } else if (bInVehicle) {
+ if (m_pVehicleAnim)
+ m_pVehicleAnim->blendDelta = -1000.0f;
+ } else if (m_nPedState == PED_ENTER_CAR || m_nPedState == PED_CARJACK) {
+ QuitEnteringCar();
+ }
+
+ m_nPedState = PED_DIE;
+ if (animId == NUM_ANIMS) {
+ bIsPedDieAnimPlaying = false;
+ } else {
+ CAnimBlendAssociation *dieAssoc = CAnimManager::BlendAnimation((RpClump*) m_rwObject, ASSOCGRP_STD, animId, delta);
+ if (speed > 0.0f)
+ dieAssoc->speed = speed;
+
+ dieAssoc->flags &= ~ASSOC_FADEOUTWHENDONE;
+ if (dieAssoc->IsRunning()) {
+ dieAssoc->SetFinishCallback(FinishDieAnimCB, this);
+ bIsPedDieAnimPlaying = true;
+ }
+ }
+
+ Say(SOUND_PED_DEATH);
+ if (m_nLastPedState == PED_ENTER_CAR || m_nLastPedState == PED_CARJACK)
+ QuitEnteringCar();
+ if (!bInVehicle)
+ StopNonPartialAnims();
+
+ // ???
+ m_bloodyFootprintCount = CTimer::GetTimeInMilliseconds();
+}
+
+bool
+CPed::InflictDamage(CEntity* damagedBy, eWeaponType method, float damage, ePedPieceTypes pedPiece, uint8 direction)
+{
+ CPlayerPed *player = FindPlayerPed();
+ float dieDelta = 4.0f;
+ float dieSpeed = 0.0f;
+ AnimationId dieAnim = ANIM_KO_SHOT_FRONT1;
+ bool headShot = false;
+ bool willLinger = false;
+ int random;
+
+ if (player == this) {
+ if (!player->m_bCanBeDamaged)
+ return false;
+
+ player->AnnoyPlayerPed(false);
+ }
+
+ if (m_nPedState == PED_DIE || m_nPedState == PED_DEAD)
+ return false;
+
+ if (!bUsesCollision && method != WEAPONTYPE_WATER)
+ return false;
+
+ if (bOnlyDamagedByPlayer && damagedBy != player && damagedBy != FindPlayerVehicle() &&
+ method != WEAPONTYPE_WATER && method != WEAPONTYPE_EXPLOSION)
+ return false;
+
+ float healthImpact;
+ if (IsPlayer())
+ healthImpact = damage * 0.33f;
+ else
+ healthImpact = damage * m_pedStats->m_defendWeakness;
+
+ bool detectDieAnim = true;
+ if (m_nPedState == PED_FALL || m_nPedState == PED_GETUP) {
+ if (!IsPedHeadAbovePos(-0.3f)) {
+ if (RpAnimBlendClumpGetFirstAssociation((RpClump*) m_rwObject, ASSOC_FLAG800))
+ dieAnim = ANIM_FLOOR_HIT_F;
+ else
+ dieAnim = ANIM_FLOOR_HIT;
+ dieDelta *= 2.0f;
+ dieSpeed = 0.5f;
+ detectDieAnim = false;
+ } else if (m_nPedState == PED_FALL) {
+ dieAnim = NUM_ANIMS;
+ detectDieAnim = false;
+ }
+ }
+ if (detectDieAnim) {
+ switch (method) {
+ case WEAPONTYPE_UNARMED:
+ if (bMeleeProof)
+ return false;
+
+ if (m_nPedState == PED_FALL) {
+ if (IsPedHeadAbovePos(-0.3f)) {
+ dieAnim = NUM_ANIMS;
+ } else {
+ if (RpAnimBlendClumpGetFirstAssociation((RpClump*) m_rwObject, ASSOC_FLAG800))
+ dieAnim = ANIM_FLOOR_HIT_F;
+ else
+ dieAnim = ANIM_FLOOR_HIT;
+ dieDelta = dieDelta * 2.0f;
+ dieSpeed = 0.5f;
+ }
+ } else {
+ switch (direction) {
+ case 0:
+ dieAnim = ANIM_KO_SKID_FRONT;
+ break;
+ case 1:
+ dieAnim = ANIM_KO_SPIN_R;
+ break;
+ case 2:
+ dieAnim = ANIM_KO_SKID_BACK;
+ break;
+ case 3:
+ dieAnim = ANIM_KO_SPIN_L;
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case WEAPONTYPE_BASEBALLBAT:
+ if (bMeleeProof)
+ return false;
+
+ if (m_nPedState == PED_FALL) {
+ if (IsPedHeadAbovePos(-0.3f)) {
+ dieAnim = NUM_ANIMS;
+ } else {
+ if (RpAnimBlendClumpGetFirstAssociation((RpClump*) m_rwObject, 0x800u))
+ dieAnim = ANIM_FLOOR_HIT_F;
+ else
+ dieAnim = ANIM_FLOOR_HIT;
+ dieDelta = dieDelta * 2.0f;
+ dieSpeed = 0.5f;
+ }
+ } else {
+ switch (direction) {
+ case 0:
+ dieAnim = ANIM_KO_SKID_FRONT;
+ break;
+ case 1:
+ dieAnim = ANIM_KO_SPIN_R;
+ break;
+ case 2:
+ dieAnim = ANIM_KO_SKID_BACK;
+ break;
+ case 3:
+ dieAnim = ANIM_KO_SPIN_L;
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case WEAPONTYPE_COLT45:
+ case WEAPONTYPE_UZI:
+ case WEAPONTYPE_SHOTGUN:
+ case WEAPONTYPE_AK47:
+ case WEAPONTYPE_M16:
+ case WEAPONTYPE_SNIPERRIFLE:
+ if (bBulletProof)
+ return false;
+
+ bool dontRemoveLimb;
+ if (IsPlayer() || m_ped_flagI2)
+ dontRemoveLimb = true;
+ else {
+ switch (method)
+ {
+ case WEAPONTYPE_SNIPERRIFLE:
+ dontRemoveLimb = false;
+ break;
+ case WEAPONTYPE_M16:
+ dontRemoveLimb = false;
+ break;
+ case WEAPONTYPE_SHOTGUN:
+ dontRemoveLimb = CGeneral::GetRandomNumberInRange(0,7);
+ break;
+ default:
+ dontRemoveLimb = CGeneral::GetRandomNumberInRange(0,15);
+ break;
+ }
+ }
+
+ if (dontRemoveLimb) {
+ if (method == WEAPONTYPE_SHOTGUN) {
+ switch (direction) {
+ case 0:
+ dieAnim = ANIM_KO_SKID_FRONT;
+ break;
+ case 1:
+ dieAnim = ANIM_KO_SPIN_R;
+ break;
+ case 2:
+ dieAnim = ANIM_KO_SKID_BACK;
+ break;
+ case 3:
+ dieAnim = ANIM_KO_SPIN_L;
+ break;
+ default:
+ break;
+ }
+ } else
+ dieAnim = ANIM_KO_SHOT_FRONT1;
+
+ willLinger = false;
+ } else {
+ switch (pedPiece) {
+ case PEDPIECE_NONE:
+ willLinger = false;
+ dieAnim = ANIM_KO_SHOT_FRONT1;
+ break;
+ case PEDPIECE_BODY:
+ willLinger = false;
+ dieAnim = ANIM_KO_SHOT_STOM;
+ break;
+ case PEDPIECE_LEFTARM:
+ dieAnim = ANIM_KO_SHOT_ARML;
+ RemoveBodyPart(PED_UPPERARML, direction);
+ willLinger = true;
+ break;
+ case PEDPIECE_RIGHTARM:
+ dieAnim = ANIM_KO_SHOT_ARMR;
+ RemoveBodyPart(PED_UPPERARMR, direction);
+ willLinger = true;
+ break;
+ case PEDPIECE_LEFTLEG:
+ dieAnim = ANIM_KO_SHOT_LEGL;
+ RemoveBodyPart(PED_UPPERLEGL, direction);
+ willLinger = true;
+ break;
+ case PEDPIECE_RIGHTLEG:
+ dieAnim = ANIM_KO_SHOT_LEGR;
+ RemoveBodyPart(PED_UPPERLEGR, direction);
+ willLinger = true;
+ break;
+ case PEDPIECE_HEAD:
+ dieAnim = ANIM_KO_SHOT_FACE;
+ RemoveBodyPart(PED_HEAD, direction);
+ headShot = true;
+ willLinger = true;
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case WEAPONTYPE_ROCKETLAUNCHER:
+ case WEAPONTYPE_GRENADE:
+ case WEAPONTYPE_EXPLOSION:
+ if (bCanPointGunAtTarget)
+ return false;
+
+ if (CGame::nastyGame && !IsPlayer() && !bInVehicle &&
+ 1.0f + healthImpact > m_fArmour + m_fHealth) {
+
+ random = CGeneral::GetRandomNumber();
+ if (random & 1)
+ RemoveBodyPart(PED_UPPERARML, direction);
+ if (random & 2)
+ RemoveBodyPart(PED_UPPERLEGR, direction);
+ if (random & 4)
+ RemoveBodyPart(PED_HEAD, direction);
+ if (random & 8)
+ RemoveBodyPart(PED_UPPERARMR, direction);
+ if (random & 0x10)
+ RemoveBodyPart(PED_UPPERLEGL, direction);
+ if (bBodyPartJustCameOff)
+ willLinger = true;
+ }
+ // fall through
+ case WEAPONTYPE_MOLOTOV:
+ if (m_flagB2)
+ return false;
+
+ switch (direction) {
+ case 0:
+ dieAnim = ANIM_KO_SKID_FRONT;
+ break;
+ case 1:
+ dieAnim = ANIM_KO_SPIN_R;
+ break;
+ case 2:
+ dieAnim = ANIM_KO_SKID_BACK;
+ break;
+ case 3:
+ dieAnim = ANIM_KO_SPIN_L;
+ break;
+ default:
+ break;
+ }
+ break;
+ case WEAPONTYPE_FLAMETHROWER:
+ if (bFireProof)
+ return false;
+
+ dieAnim = ANIM_KO_SHOT_FRONT1;
+ break;
+ case WEAPONTYPE_RAMMEDBYCAR:
+ case WEAPONTYPE_RUNOVERBYCAR:
+ if (bCollisionProof)
+ return false;
+
+ random = CGeneral::GetRandomNumberInRange(0, 3);
+ switch (random) {
+ case 0:
+ if ((pedPiece != PEDPIECE_LEFTARM || random <= 1)
+ && (pedPiece != PEDPIECE_BODY || random != 1)) {
+ if (pedPiece == PEDPIECE_RIGHTARM && random > 1
+ || pedPiece == PEDPIECE_BODY && random == 2)
+
+ dieAnim = ANIM_KO_SPIN_L;
+ else
+ dieAnim = ANIM_KO_SKID_FRONT;
+ } else
+ dieAnim = ANIM_KO_SPIN_R;
+
+ break;
+ case 1:
+ if (m_nPedState == PED_DIVE_AWAY)
+ dieAnim = ANIM_KD_LEFT;
+ else
+ dieAnim = ANIM_KO_SPIN_R;
+ break;
+ case 2:
+ if ((pedPiece != PEDPIECE_LEFTARM || random <= 1)
+ && (pedPiece != PEDPIECE_BODY || random != 1)) {
+ if ((pedPiece != PEDPIECE_RIGHTARM || random <= 1)
+ && (pedPiece != PEDPIECE_BODY || random != 2)) {
+ dieAnim = ANIM_KO_SKID_BACK;
+ } else {
+ dieAnim = ANIM_KD_RIGHT;
+ }
+ } else
+ dieAnim = ANIM_KD_LEFT;
+ break;
+ case 3:
+ if (m_nPedState == PED_DIVE_AWAY)
+ dieAnim = ANIM_KD_RIGHT;
+ else
+ dieAnim = ANIM_KO_SPIN_L;
+ break;
+ default:
+ break;
+ }
+ if (damagedBy) {
+ CVehicle *vehicle = (CVehicle*)damagedBy;
+ if (method == WEAPONTYPE_RAMMEDBYCAR) {
+ float vehSpeed = vehicle->m_vecMoveSpeed.Magnitude();
+ dieDelta = 8.0f * vehSpeed + 4.0f;
+ } else {
+ float vehSpeed = vehicle->m_vecMoveSpeed.Magnitude();
+ dieDelta = 12.0f * vehSpeed + 4.0f;
+ dieSpeed = 16.0f * vehSpeed + 1.0f;
+ }
+ }
+ break;
+ case WEAPONTYPE_WATER:
+ dieAnim = ANIM_DROWN;
+ break;
+ case WEAPONTYPE_FALL_DAMAGE:
+ if (bCollisionProof)
+ return false;
+
+ switch (direction) {
+ case 0:
+ dieAnim = ANIM_KO_SKID_FRONT;
+ break;
+ case 1:
+ dieAnim = ANIM_KO_SPIN_R;
+ break;
+ case 2:
+ dieAnim = ANIM_KO_SKID_BACK;
+ break;
+ case 3:
+ dieAnim = ANIM_KO_SPIN_L;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (m_fArmour != 0.0f && method != WEAPONTYPE_WATER) {
+ if (player == this)
+ CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss = CTimer::GetTimeInMilliseconds();
+
+ if (healthImpact < m_fArmour) {
+ m_fArmour = m_fArmour - healthImpact;
+ healthImpact = 0.0f;
+ } else {
+ healthImpact = healthImpact - m_fArmour;
+ m_fArmour = 0.0f;
+ }
+ }
+
+ if (healthImpact != 0.0f) {
+ if (player == this)
+ CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss = CTimer::GetTimeInMilliseconds();
+
+ m_lastWepDam = method;
+ }
+
+ if (m_fHealth - healthImpact >= 1.0f && !willLinger) {
+ m_fHealth -= healthImpact;
+ return false;
+ }
+
+ if (bInVehicle) {
+ if (method != WEAPONTYPE_WATER) {
+ m_fHealth = 1.0f;
+ return false;
+ }
+ m_fHealth = 0.0f;
+ if (player == this)
+ m_pMyVehicle->m_status = STATUS_PLAYER_DISABLED;
+
+ SetDie(NUM_ANIMS, 4.0f, 0.0f);
+ return true;
+ } else {
+ m_fHealth = 0.0f;
+ SetDie(dieAnim, dieDelta, dieSpeed);
+
+ if (damagedBy == player || damagedBy && damagedBy == FindPlayerVehicle()) {
+ CDarkel::RegisterKillByPlayer(this, method, headShot);
+ m_threatEntity = player;
+ } else {
+ CDarkel::RegisterKillNotByPlayer(this, method);
+ }
+ // WAT?
+ if (method == WEAPONTYPE_WATER)
+ bIsInTheAir = false;
+
+ return true;
+ }
+}
+
+void
+CPed::ClearFlee(void)
+{
+ RestorePreviousState();
+ m_ped_flagD20 = false;
+ m_standardTimer = 0;
+ m_fleeTimer = 0;
+}
+
+void
+CPed::ClearFall(void)
+{
+ SetGetUp();
+}
+
+void
+CPed::SetGetUp(void)
+{
+ if (m_nPedState == PED_GETUP && m_ped_flagE20)
+ return;
+
+ if (!CanSetPedState())
+ return;
+
+ if (m_fHealth >= 1.0f || IsPedHeadAbovePos(-0.3f)) {
+ if (m_ped_flagC10) {
+ m_fRotationCur = CGeneral::LimitRadianAngle(m_fRotationCur);
+ m_fRotationCur -= 0.5*PI;
+ m_ped_flagC10 = false;
+ }
+ if (m_nPedState != PED_GETUP) {
+ SetStoredState();
+ m_nPedState = PED_GETUP;
+ }
+
+ CVehicle* collidingVeh = (CVehicle*)m_pCollidingEntity;
+ CVehicle *veh = (CVehicle*)CPedPlacement::IsPositionClearOfCars(&GetPosition());
+ if (veh && veh->m_vehType != VEHICLE_TYPE_BIKE ||
+ collidingVeh && collidingVeh->IsVehicle() && collidingVeh->m_vehType != VEHICLE_TYPE_BIKE
+ && ((CTimer::GetFrameCounter() + m_randomSeed % 256 + 5) % 8
+ || CCollision::ProcessColModels(GetMatrix(), *CModelInfo::GetModelInfo(m_modelIndex)->GetColModel(),
+ collidingVeh->GetMatrix(), *CModelInfo::GetModelInfo(collidingVeh->m_modelIndex)->GetColModel(),
+ &ms_tempColPoint, nil, nil) > 0)) {
+
+ m_ped_flagE20 = false;
+ if (IsPlayer())
+ InflictDamage(nil, WEAPONTYPE_RUNOVERBYCAR, CTimer::GetTimeStep(), PEDPIECE_NONE, 0);
+ else {
+ if (!CPad::GetPad(0)->ArePlayerControlsDisabled())
+ return;
+
+ InflictDamage(nil, WEAPONTYPE_RUNOVERBYCAR, 1000.0f, PEDPIECE_NONE, 0);
+ }
+ return;
+ }
+ m_ped_flagE20 = true;
+ m_pCollidingEntity = nil;
+ m_ped_flagH1 = false;
+ CAnimBlendAssociation *animAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ASSOC_REPEAT);
+ if (animAssoc) {
+ if (RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ASSOC_RUNNING)) {
+ CAnimManager::BlendAnimation((RpClump*) m_rwObject, m_animGroup, ANIM_RUN, 8.0f);
+ } else {
+ CAnimManager::BlendAnimation((RpClump*) m_rwObject, m_animGroup, ANIM_IDLE_STANCE, 8.0f);
+ }
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ }
+
+ if (RpAnimBlendClumpGetFirstAssociation((RpClump*) m_rwObject, ASSOC_FLAG800))
+ animAssoc = CAnimManager::BlendAnimation((RpClump*) m_rwObject, ASSOCGRP_STD, ANIM_GETUP_FRONT, 1000.0f);
+ else
+ animAssoc = CAnimManager::BlendAnimation((RpClump*) m_rwObject, ASSOCGRP_STD, ANIM_GETUP1, 1000.0f);
+
+ animAssoc->SetFinishCallback(PedGetupCB,this);
+ } else {
+ m_fHealth = 0.0f;
+ SetDie(NUM_ANIMS, 4.0f, 0.0f);
+ }
+}
+
WRAPPER void CPed::PedGetupCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4CE810); }
WRAPPER void CPed::PedStaggerCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4CE8D0); }
WRAPPER void CPed::PedEvadeCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4D36E0); }
@@ -3238,4 +3833,12 @@ STARTPATCHES
InjectHook(0x4D0BE0, &CPed::CheckIfInTheAir, PATCH_JUMP);
InjectHook(0x4C7F20, &CPed::ClearAll, PATCH_JUMP);
InjectHook(0x4E6790, &CPed::ClearAttack, PATCH_JUMP);
+ InjectHook(0x4E67F0, &CPed::ClearAttackByRemovingAnim, PATCH_JUMP);
+ InjectHook(0x4D37D0, &CPed::SetDie, PATCH_JUMP);
+ InjectHook(0x4C5D50, &CPed::StopNonPartialAnims, PATCH_JUMP);
+ InjectHook(0x4C5DB0, &CPed::SetStoredState, PATCH_JUMP);
+ InjectHook(0x4EA420, &CPed::InflictDamage, PATCH_JUMP);
+ InjectHook(0x4D1EA0, &CPed::ClearFlee, PATCH_JUMP);
+ InjectHook(0x4D0BB0, &CPed::ClearFall, PATCH_JUMP);
+ InjectHook(0x4D0F20, &CPed::SetGetUp, PATCH_JUMP);
ENDPATCHES
diff --git a/src/peds/Ped.h b/src/peds/Ped.h
index 2cc064a5..778a5b48 100644
--- a/src/peds/Ped.h
+++ b/src/peds/Ped.h
@@ -13,6 +13,17 @@
struct CPathNode;
+enum ePedPieceTypes
+{
+ PEDPIECE_NONE,
+ PEDPIECE_BODY,
+ PEDPIECE_LEFTARM,
+ PEDPIECE_RIGHTARM,
+ PEDPIECE_LEFTLEG,
+ PEDPIECE_RIGHTLEG,
+ PEDPIECE_HEAD,
+};
+
enum eWaitState {
WAITSTATE_FALSE,
WAITSTATE_TRAFFIC_LIGHTS,
@@ -196,10 +207,10 @@ public:
uint8 m_ped_flagC1 : 1;
uint8 bRespondsToThreats : 1;
- uint8 m_ped_flagC4 : 1; // false when in bus, bRenderPedInCar?
- uint8 m_ped_flagC8 : 1;
+ uint8 bRenderPedInCar : 1;
+ uint8 bChangedSeat : 1;
uint8 m_ped_flagC10 : 1; // related with phone
- uint8 m_ped_flagC20 : 1; // just left some body part?
+ uint8 bBodyPartJustCameOff : 1;
uint8 m_ped_flagC40 : 1;
uint8 m_ped_flagC80 : 1;
@@ -207,7 +218,7 @@ public:
uint8 m_ped_flagD2 : 1; // seen an event
uint8 m_ped_flagD4 : 1;
uint8 m_ped_flagD8 : 1;
- uint8 m_ped_flagD10 : 1;
+ uint8 bIsPedDieAnimPlaying : 1;
uint8 m_ped_flagD20 : 1;
uint8 m_ped_flagD40 : 1; // reset when objective changes
uint8 m_bScriptObjectiveCompleted : 1;
@@ -225,7 +236,7 @@ public:
uint8 m_ped_flagF2 : 1;
uint8 m_ped_flagF4 : 1;
uint8 m_ped_flagF8 : 1;
- uint8 m_ped_flagF10 : 1;
+ uint8 m_ped_flagF10 : 1; // set before "quickjack"
uint8 m_ped_flagF20 : 1;
uint8 m_ped_flagF40 : 1;
uint8 m_ped_flagF80 : 1;
@@ -249,7 +260,7 @@ public:
uint8 m_ped_flagH80 : 1;
uint8 m_ped_flagI1 : 1;
- uint8 m_ped_flagI2 : 1;
+ uint8 m_ped_flagI2 : 1; // limbs won't be removed if set
uint8 m_ped_flagI4 : 1;
uint8 bHasAlreadyBeenRecorded : 1;
uint8 m_ped_flagI10 : 1;
@@ -416,8 +427,8 @@ public:
void SetDie(AnimationId anim, float arg1, float arg2);
void SetDead(void);
void ApplyHeadShot(eWeaponType weaponType, CVector pos, bool evenOnPlayer);
- void RemoveBodyPart(PedNode nodeId, int8 unknown);
- void SpawnFlyingComponent(int, int8 unknown);
+ void RemoveBodyPart(PedNode nodeId, int8 direction);
+ void SpawnFlyingComponent(int, int8);
bool OurPedCanSeeThisOne(CEntity *target);
void Avoid(void);
void Attack(void);
@@ -472,6 +483,13 @@ public:
bool Seek(void);
void SetWanderPath(int8);
void SetFollowPath(CVector);
+ void ClearAttackByRemovingAnim(void);
+ void SetStoredState(void);
+ void StopNonPartialAnims(void);
+ bool InflictDamage(CEntity*, eWeaponType, float, ePedPieceTypes, uint8);
+ void ClearFlee(void);
+ void ClearFall(void);
+ void SetGetUp(void);
// Static methods
static void GetLocalPositionToOpenCarDoor(CVector *output, CVehicle *veh, uint32 enterType, float offset);
@@ -545,6 +563,7 @@ public:
static bool &bNastyLimbsCheat;
static bool &bPedCheat2;
static bool &bPedCheat3;
+ static CColPoint &ms_tempColPoint;
};
void FinishFuckUCB(CAnimBlendAssociation *assoc, void *arg);
diff --git a/src/peds/PedPlacement.cpp b/src/peds/PedPlacement.cpp
index e9a3f7d9..f292f4fa 100644
--- a/src/peds/PedPlacement.cpp
+++ b/src/peds/PedPlacement.cpp
@@ -35,6 +35,13 @@ CPedPlacement::FindZCoorForPed(CVector* pos)
pos->z = 1.04f + zForPed;
}
+CEntity*
+CPedPlacement::IsPositionClearOfCars(CVector* pos)
+{
+ return CWorld::TestSphereAgainstWorld(*pos, 0.25f, false, true, true, false, false, false, false);
+}
+
STARTPATCHES
InjectHook(0x4EE340, &CPedPlacement::FindZCoorForPed, PATCH_JUMP);
+ InjectHook(0x4EE310, &CPedPlacement::IsPositionClearOfCars, PATCH_JUMP);
ENDPATCHES
diff --git a/src/peds/PedPlacement.h b/src/peds/PedPlacement.h
index 4bd48b62..1edb50b4 100644
--- a/src/peds/PedPlacement.h
+++ b/src/peds/PedPlacement.h
@@ -1,8 +1,10 @@
#pragma once
class CVector;
+class CEntity;
class CPedPlacement {
public:
static void FindZCoorForPed(CVector* pos);
+ static CEntity* IsPositionClearOfCars(CVector*);
}; \ No newline at end of file
diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp
index 3bab2d31..d2bc494f 100644
--- a/src/peds/PlayerPed.cpp
+++ b/src/peds/PlayerPed.cpp
@@ -38,6 +38,24 @@ CPlayerPed::SetWantedLevelNoDrop(int32 level)
m_pWanted->SetWantedLevelNoDrop(level);
}
+// I don't know actual purpose of parameter
+void
+CPlayerPed::AnnoyPlayerPed(bool itsPolice)
+{
+ int8 *temper = &m_pedStats->m_temper;
+ if (*temper >= 52) {
+ if (itsPolice) {
+ if (*temper < 55) {
+ (*temper)++;
+ } else {
+ (*temper) = 46;
+ }
+ }
+ } else {
+ (*temper)++;
+ }
+}
+
class CPlayerPed_ : public CPlayerPed
{
@@ -48,4 +66,5 @@ public:
STARTPATCHES
InjectHook(0x4EFB30, &CPlayerPed_::dtor, PATCH_JUMP);
InjectHook(0x4F28A0, &CPlayerPed::ClearWeaponTarget, PATCH_JUMP);
+ InjectHook(0x4F3700, &CPlayerPed::AnnoyPlayerPed, PATCH_JUMP);
ENDPATCHES
diff --git a/src/peds/PlayerPed.h b/src/peds/PlayerPed.h
index 1dfa33fa..fa6d9d43 100644
--- a/src/peds/PlayerPed.h
+++ b/src/peds/PlayerPed.h
@@ -29,7 +29,7 @@ public:
bool m_bHasLockOnTarget;
int8 field_1406;
int8 field_1407;
- bool m_bAdrenalineTime;
+ uint32 m_bAdrenalineTime;
bool m_bCanBeDamaged;
int8 field_1413;
int8 field_1414;
@@ -46,6 +46,7 @@ public:
void SetWantedLevel(int32 level);
void SetWantedLevelNoDrop(int32 level);
void KeepAreaAroundPlayerClear(void);
+ void AnnoyPlayerPed(bool);
static void SetupPlayerPed(int32);
static void DeactivatePlayerPed(int32);
diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp
index f3a8f785..ea5dea73 100644
--- a/src/vehicles/Vehicle.cpp
+++ b/src/vehicles/Vehicle.cpp
@@ -603,7 +603,7 @@ CVehicle::SetUpDriver(void)
pDriver->bInVehicle = true;
pDriver->SetPedState(PED_DRIVING);
if(bIsBus)
- pDriver->m_ped_flagC4 = false;
+ pDriver->bRenderPedInCar = false;
return pDriver;
}
@@ -619,7 +619,7 @@ CVehicle::SetupPassenger(int n)
pPassengers[n]->bInVehicle = true;
pPassengers[n]->SetPedState(PED_DRIVING);
if(bIsBus)
- pPassengers[n]->m_ped_flagC4 = false;
+ pPassengers[n]->bRenderPedInCar = false;
return pPassengers[n];
}