summaryrefslogtreecommitdiffstats
path: root/src/peds
diff options
context:
space:
mode:
authorNikolay Korolev <nickvnuk@gmail.com>2020-05-20 22:54:22 +0200
committerNikolay Korolev <nickvnuk@gmail.com>2020-05-20 22:54:22 +0200
commit510261cb058d00bc0388ad58a33b173e5b1536ac (patch)
tree2aa795fe25f5d3bc4fa22d93f7a966838e50b3b5 /src/peds
parentscript revision (diff)
parentPickup and audio fix (diff)
downloadre3-510261cb058d00bc0388ad58a33b173e5b1536ac.tar
re3-510261cb058d00bc0388ad58a33b173e5b1536ac.tar.gz
re3-510261cb058d00bc0388ad58a33b173e5b1536ac.tar.bz2
re3-510261cb058d00bc0388ad58a33b173e5b1536ac.tar.lz
re3-510261cb058d00bc0388ad58a33b173e5b1536ac.tar.xz
re3-510261cb058d00bc0388ad58a33b173e5b1536ac.tar.zst
re3-510261cb058d00bc0388ad58a33b173e5b1536ac.zip
Diffstat (limited to 'src/peds')
-rw-r--r--src/peds/CivilianPed.cpp2
-rw-r--r--src/peds/Ped.cpp364
-rw-r--r--src/peds/Ped.h5
-rw-r--r--src/peds/PlayerPed.cpp15
4 files changed, 221 insertions, 165 deletions
diff --git a/src/peds/CivilianPed.cpp b/src/peds/CivilianPed.cpp
index 48b1f6cd..dd438a3f 100644
--- a/src/peds/CivilianPed.cpp
+++ b/src/peds/CivilianPed.cpp
@@ -103,7 +103,7 @@ CCivilianPed::CivilianAI(void)
SetLookTimer(500);
} else if (closestThreatFlag == PED_FLAG_DEADPEDS) {
float eventDistSqr = (m_pEventEntity->GetPosition() - GetPosition()).MagnitudeSqr2D();
- if (IsGangMember() && m_nPedType == ((CPed*)m_pEventEntity)->m_nPedType) {
+ if (((CPed*)m_pEventEntity)->bIsDrowning || IsGangMember() && m_nPedType == ((CPed*)m_pEventEntity)->m_nPedType) {
if (eventDistSqr < sq(5.0f)) {
SetFindPathAndFlee(m_pEventEntity, 2000);
SetMoveState(PEDMOVE_RUN);
diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp
index 12870236..06012379 100644
--- a/src/peds/Ped.cpp
+++ b/src/peds/Ped.cpp
@@ -602,6 +602,9 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
bTurnedAroundOnAttractor = false;
bCarPassenger = false;
bMiamiViceCop = false;
+
+ bIsDrowning = false;
+ bCanDrownInWater = true;
#ifdef VC_PED_PORTS
bHeadStuckInCollision = false;
#endif
@@ -654,6 +657,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
m_nPedMoney = random % 25;
if (m_nPedMoney == 23)
m_nPedMoney = 400;
+ m_bleedCounter = 0;
#ifdef PED_SKIN
m_pWeaponModel = nil;
#endif
@@ -1285,7 +1289,7 @@ CPed::FinishedAttackCB(CAnimBlendAssociation *attackAssoc, void *arg)
}
}
-// --MIAMI: Done except melee weapons
+// --MIAMI: Done except commented things
void
CPed::Attack(void)
{
@@ -1297,7 +1301,6 @@ CPed::Attack(void)
float animLoopEnd;
CWeaponInfo *ourWeapon;
bool attackShouldContinue;
- AnimationId reloadAnim;
CAnimBlendAssociation *reloadAnimAssoc;
CAnimBlendAssociation *throwAssoc;
float delayBetweenAnimAndFire;
@@ -1311,7 +1314,6 @@ CPed::Attack(void)
attackShouldContinue = bIsAttacking;
reloadAnimAssoc = nil;
throwAssoc = nil;
- reloadAnim = NUM_ANIMS;
animLoopStart = ourWeapon->m_fAnimLoopStart;
animLoopEnd = ourWeapon->m_fAnimLoopEnd;
delayBetweenAnimAndFire = ourWeapon->m_fAnimFrameFire;
@@ -1462,66 +1464,104 @@ CPed::Attack(void)
m_pedIK.m_flags &= ~CPedIK::AIMS_WITH_ARM;
}
- // TODO(Miami): Chainsaw
- if (weaponAnimTime <= delayBetweenAnimAndFire || weaponAnimTime - weaponAnimAssoc->timeStep > delayBetweenAnimAndFire || !weaponAnimAssoc->IsRunning()) {
- if (weaponAnimAssoc->speed < 1.0f)
- weaponAnimAssoc->speed = 1.0f;
+ if (ourWeaponType != WEAPONTYPE_CHAINSAW
+ || !meleeAttackStarted && delayBetweenAnimAndFire - 0.5f >= weaponAnimAssoc->currentTime
+ || weaponAnimAssoc->currentTime - weaponAnimAssoc->timeStep > delayBetweenAnimAndFire) {
- } else {
- firePos = ourWeapon->m_vecFireOffset;
+ if (ourWeaponType == WEAPONTYPE_CHAINSAW) {
+#ifndef AUDIO_NOT_READY
+ DMAudio.PlayOneShot(m_audioEntityId, 52, 0.0f);
+#endif
+ } else if (weaponAnimTime <= delayBetweenAnimAndFire || weaponAnimTime - weaponAnimAssoc->timeStep > delayBetweenAnimAndFire || !weaponAnimAssoc->IsRunning()) {
+ if (weaponAnimAssoc->speed < 1.0f)
+ weaponAnimAssoc->speed = 1.0f;
- // TODO(Miami): Katana & Chainsaw
- if (ourWeapon->m_eWeaponFire == WEAPON_FIRE_MELEE) {
- firePos = GetMatrix() * firePos;
} else {
- TransformToNode(firePos, (weaponAnimAssoc->animId == ANIM_MELEE_ATTACK_2ND && ourWeapon->m_AnimToPlay == ASSOCGRP_UNARMED) ? PED_FOOTR : PED_HANDR);
- }
-
- GetWeapon()->Fire(this, &firePos);
+ firePos = ourWeapon->m_vecFireOffset;
- // TODO(Miami)
- if (ourWeaponType == WEAPONTYPE_MOLOTOV || ourWeaponType == WEAPONTYPE_GRENADE || ourWeaponType == WEAPONTYPE_DETONATOR_GRENADE
- /* ourWeaponType == WEAPONTYPE_TEARGAS*/) {
- RemoveWeaponModel(ourWeapon->m_nModelId);
- }
- if (!GetWeapon()->m_nAmmoTotal && ourWeaponFire != WEAPON_FIRE_MELEE && FindPlayerPed() != this) {
- SelectGunIfArmed();
- }
+ if (ourWeaponType != WEAPONTYPE_KATANA && ourWeaponType != WEAPONTYPE_CHAINSAW) {
+ if (ourWeapon->m_eWeaponFire != WEAPON_FIRE_MELEE) {
+ TransformToNode(firePos, (weaponAnimAssoc->animId == ANIM_MELEE_ATTACK_2ND && ourWeapon->m_AnimToPlay == ASSOCGRP_UNARMED) ? PED_FOOTR : PED_HANDR);
+ } else {
+ firePos = GetMatrix() * firePos;
+ }
+ } else {
+ if (weaponAnimAssoc->animId == ANIM_MELEE_ATTACK_2ND)
+ firePos.z = 0.7f * ourWeapon->m_fRadius - 1.0f;
- if (GetWeapon()->m_eWeaponState == WEAPONSTATE_MELEE_MADECONTACT) {
- int damagerType = 0;
- if (m_pDamageEntity && (m_fDamageImpulse == 0.0f || !m_pDamageEntity->IsBuilding())) {
- damagerType = m_pDamageEntity->GetType();
+ firePos = GetMatrix() * firePos;
+ }
+
+ GetWeapon()->Fire(this, &firePos);
+
+ // TODO(Miami): Teargas
+ if (ourWeaponType == WEAPONTYPE_MOLOTOV || ourWeaponType == WEAPONTYPE_GRENADE || ourWeaponType == WEAPONTYPE_DETONATOR_GRENADE
+ /* ourWeaponType == WEAPONTYPE_TEARGAS*/) {
+ RemoveWeaponModel(ourWeapon->m_nModelId);
}
- switch (ourWeapon->m_AnimToPlay) {
- case ASSOCGRP_UNARMED:
- if (weaponAnimAssoc->animId == ANIM_MELEE_ATTACK || weaponAnimAssoc->animId == ANIM_MELEE_ATTACK_START) {
+ if (!GetWeapon()->m_nAmmoTotal && ourWeaponFire != WEAPON_FIRE_MELEE && FindPlayerPed() != this) {
+ SelectGunIfArmed();
+ }
+
+ if (GetWeapon()->m_eWeaponState == WEAPONSTATE_MELEE_MADECONTACT) {
+ int damagerType = ENTITY_TYPE_NOTHING;
+ if (m_pDamageEntity && (m_fDamageImpulse == 0.0f || !m_pDamageEntity->IsBuilding())) {
+ damagerType = m_pDamageEntity->GetType();
+ }
+ switch (ourWeapon->m_AnimToPlay) {
+ case ASSOCGRP_UNARMED:
+ if (weaponAnimAssoc->animId == ANIM_MELEE_ATTACK || weaponAnimAssoc->animId == ANIM_MELEE_ATTACK_START) {
#ifdef AUDIO_NOT_READY
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_PUNCH_39, 0.0f);
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_PUNCH_39, 0.0f);
#else
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_PUNCH_39, (damagerType | (ourWeaponType << 8)));
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_PUNCH_39, (damagerType | (ourWeaponType << 8)));
#endif
- }
- break;
- case ASSOCGRP_KNIFE:
- case ASSOCGRP_BASEBALLBAT:
- case ASSOCGRP_GOLFCLUB:
- case ASSOCGRP_CHAINSAW:
+ }
+ break;
+ case ASSOCGRP_KNIFE:
+ case ASSOCGRP_BASEBALLBAT:
+ case ASSOCGRP_GOLFCLUB:
+ case ASSOCGRP_CHAINSAW:
#ifdef AUDIO_NOT_READY
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, 1.0f);
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, 1.0f);
#else
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, (damagerType | (ourWeaponType << 8)));
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, (damagerType | (ourWeaponType << 8)));
#endif
- break;
- default:
- break;
- }
+ break;
+ default:
+ break;
+ }
- if (bIsAttacking || CTimer::GetTimeInMilliseconds() < m_shootTimer) {
- weaponAnimAssoc->callbackType = 0;
+ if (bIsAttacking || CTimer::GetTimeInMilliseconds() < m_shootTimer) {
+ weaponAnimAssoc->callbackType = 0;
+ }
}
+
+ attackShouldContinue = false;
}
+ } else {
+ CVector firePos = ourWeapon->m_vecFireOffset;
+
+ if (weaponAnimAssoc->animId == 206)
+ firePos.z = 0.7f * ourWeapon->m_fRadius - 1.0f;
+
+ firePos = GetMatrix() * firePos;
+ GetWeapon()->Fire(this, &firePos);
+ if (GetWeapon()->m_eWeaponState == WEAPONSTATE_MELEE_MADECONTACT) {
+ int damagerType = ENTITY_TYPE_PED;
+ if (m_pDamageEntity)
+ damagerType = m_pDamageEntity->GetType();
+ DMAudio.PlayOneShot(m_audioEntityId, 54, (float)damagerType);
+ if (IsPlayer()) {
+ CPad::GetPad(0)->StartShake(240, 180);
+ }
+ } else {
+ DMAudio.PlayOneShot(m_audioEntityId, 53, 0.0f);
+ if (IsPlayer()) {
+ CPad::GetPad(0)->StartShake(240, 90);
+ }
+ }
attackShouldContinue = false;
}
@@ -1614,12 +1654,12 @@ CPed::Attack(void)
if (weaponAnimTime - 2.0f * weaponAnimAssoc->timeStep <= animLoopEnd
&& (bIsAttacking || CTimer::GetTimeInMilliseconds() < m_shootTimer)
&& (GetWeapon()->m_eWeaponState != WEAPONSTATE_RELOADING
- /* || GetWeapon()->m_nWeaponType == WEAPONTYPE_MINIGUN */)) {
+ /* || GetWeapon()->m_nWeaponType == WEAPONTYPE_MINIGUN */)) { // TODO(Miami): Minigun
PedOnGroundState pedOnGroundState;
if (ourWeapon->m_eWeaponFire == WEAPON_FIRE_MELEE &&
(CGame::nastyGame && ((pedOnGroundState = CheckForPedsOnGroundToAttack(this, nil)) > PED_IN_FRONT_OF_ATTACKER)
- || GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT && pedOnGroundState == NO_PED && bIsStanding && m_pCurSurface && m_pCurSurface->IsVehicle())) {
+ || ourWeaponType == WEAPONTYPE_BASEBALLBAT && pedOnGroundState == NO_PED && bIsStanding && m_pCurSurface && m_pCurSurface->IsVehicle())) {
AnimationId fireAnim = GetFireAnimGround(ourWeapon, false);
if (weaponAnimAssoc->animId == fireAnim)
@@ -1672,7 +1712,7 @@ CPed::Attack(void)
break;
}
#else
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, GetWeapon()->m_eWeaponType);
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, ourWeaponType);
#endif
}
@@ -1908,7 +1948,7 @@ CPed::BeingDraggedFromCar(void)
#ifdef VC_PED_PORTS
if (m_objective == OBJECTIVE_LEAVE_CAR_AND_DIE) {
if (m_pMyVehicle) {
- m_pMyVehicle->ProcessOpenDoor(m_vehEnterType, NUM_ANIMS, m_pVehicleAnim->currentTime * 5.0f);
+ m_pMyVehicle->ProcessOpenDoor(m_vehEnterType, NUM_STD_ANIMS, m_pVehicleAnim->currentTime * 5.0f);
}
}
#endif
@@ -4022,7 +4062,7 @@ CPed::SetDie(AnimationId animId, float delta, float speed)
}
m_nPedState = PED_DIE;
- if (animId == NUM_ANIMS) {
+ if (animId == NUM_STD_ANIMS) {
bIsPedDieAnimPlaying = false;
} else {
CAnimBlendAssociation *dieAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animId, delta);
@@ -4045,6 +4085,7 @@ CPed::SetDie(AnimationId animId, float delta, float speed)
m_bloodyFootprintCountOrDeathTime = CTimer::GetTimeInMilliseconds();
}
+// --MIAMI: Done except commented things
bool
CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPieceTypes pedPiece, uint8 direction)
{
@@ -4056,17 +4097,28 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
bool willLinger = false;
int random;
+ // TODO(Miami): PlayerInfo thingies here
+
if (player == this) {
if (!player->m_bCanBeDamaged)
return false;
+ if (damagedBy && damagedBy->IsPed() && ((CPed*)damagedBy)->m_nPedType == PEDTYPE_GANG7)
+ return false;
+
+ if ((method == WEAPONTYPE_FLAMETHROWER || method == WEAPONTYPE_MOLOTOV) && CWorld::Players[CWorld::PlayerInFocus].m_bFireproof)
+ return false;
+
player->AnnoyPlayerPed(false);
}
if (DyingOrDead())
return false;
- if (!bUsesCollision && method != WEAPONTYPE_DROWNING)
+ if (method == WEAPONTYPE_DROWNING && !bCanDrownInWater)
+ return false;
+
+ if (!bUsesCollision && (!bInVehicle || m_nPedState != PED_DRIVING) && method != WEAPONTYPE_DROWNING)
return false;
if (bOnlyDamagedByPlayer && damagedBy != player && damagedBy != FindPlayerVehicle() &&
@@ -4079,8 +4131,12 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
else
healthImpact = damage * m_pedStats->m_defendWeakness;
+ if (!IsPlayer() &&
+ (method == WEAPONTYPE_SCREWDRIVER || method == WEAPONTYPE_KNIFE || (method >= WEAPONTYPE_CLEAVER && method <= WEAPONTYPE_CHAINSAW)))
+ m_bleedCounter = 200;
+
bool detectDieAnim = true;
- if (m_nPedState == PED_FALL || m_nPedState == PED_GETUP) {
+ if (m_nPedState == PED_GETUP) {
if (!IsPedHeadAbovePos(-0.3f)) {
if (RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FRONTAL))
dieAnim = ANIM_FLOOR_HIT_F;
@@ -4089,20 +4145,36 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
dieDelta *= 2.0f;
dieSpeed = 0.5f;
detectDieAnim = false;
- } else if (m_nPedState == PED_FALL) {
- dieAnim = NUM_ANIMS;
- detectDieAnim = false;
}
+ } else if (m_nPedState == PED_FALL) {
+ CAnimBlendAssociation *fallAssoc = RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_PARTIAL);
+ if (!fallAssoc || fallAssoc->IsRunning()) {
+ if (fallAssoc && fallAssoc->blendDelta >= 0.0f)
+ dieAnim = NUM_STD_ANIMS;
+ else
+ dieAnim = ANIM_KO_SHOT_FRONT1;
+ } else {
+ if (fallAssoc->flags & ASSOC_FRONTAL)
+ dieAnim = ANIM_FLOOR_HIT_F;
+ else
+ dieAnim = ANIM_FLOOR_HIT;
+
+ dieDelta *= 2.0f;
+ dieSpeed = 0.5f;
+ }
+ detectDieAnim = false;
}
+
if (detectDieAnim) {
switch (method) {
case WEAPONTYPE_UNARMED:
+ case WEAPONTYPE_BRASSKNUCKLE:
if (bMeleeProof)
return false;
if (m_nPedState == PED_FALL) {
if (IsPedHeadAbovePos(-0.3f)) {
- dieAnim = NUM_ANIMS;
+ dieAnim = NUM_STD_ANIMS;
} else {
if (RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FRONTAL))
dieAnim = ANIM_FLOOR_HIT_F;
@@ -4130,19 +4202,28 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
}
}
break;
+ case WEAPONTYPE_SCREWDRIVER:
+ case WEAPONTYPE_GOLFCLUB:
+ case WEAPONTYPE_NIGHTSTICK:
+ case WEAPONTYPE_KNIFE:
case WEAPONTYPE_BASEBALLBAT:
+ case WEAPONTYPE_HAMMER:
+ case WEAPONTYPE_CLEAVER:
+ case WEAPONTYPE_MACHETE:
+ case WEAPONTYPE_KATANA:
+ case WEAPONTYPE_CHAINSAW:
if (bMeleeProof)
return false;
-#ifdef VC_PED_PORTS
- if (/*method != WEAPONTYPE_KATANA || */
+
+ if (method != WEAPONTYPE_KATANA ||
damagedBy != FindPlayerPed()
|| FindPlayerPed()->m_nPedState != PED_FIGHT
- /*|| FindPlayerPed()->m_lastFightMove != 28 && FindPlayerPed()->m_lastFightMove != 29 */
+ || FindPlayerPed()->m_lastFightMove != FIGHTMOVE_MELEE1 && FindPlayerPed()->m_lastFightMove != FIGHTMOVE_MELEE2
|| CGeneral::GetRandomNumber() & 3) {
if (m_nPedState == PED_FALL) {
if (IsPedHeadAbovePos(-0.3f)) {
- dieAnim = NUM_ANIMS;
+ dieAnim = NUM_STD_ANIMS;
} else {
if (RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FRONTAL))
dieAnim = ANIM_FLOOR_HIT_F;
@@ -4151,8 +4232,8 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
dieDelta = dieDelta * 2.0f;
dieSpeed = 0.5f;
}
- } else if (damagedBy != FindPlayerPed()) { // || FindPlayerPed()->m_lastFightMove != 29)
- //if (damagedBy != FindPlayerPed() || FindPlayerPed()->m_lastFightMove != 30) {
+ } else if (damagedBy != FindPlayerPed() || FindPlayerPed()->m_lastFightMove != FIGHTMOVE_MELEE2) {
+ if (damagedBy != FindPlayerPed() || FindPlayerPed()->m_lastFightMove != FIGHTMOVE_MELEE3) {
switch (direction) {
case 0:
dieAnim = ANIM_KO_SKID_FRONT;
@@ -4169,82 +4250,46 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
default:
break;
}
- //} else {
- // dieAnim = ANIM_KO_SHOT_STOM;
- //}
+ } else {
+ dieAnim = ANIM_KO_SHOT_STOM;
+ }
} else {
dieAnim = ANIM_KO_SHOT_FACE;
}
} else {
dieAnim = ANIM_KO_SHOT_FACE;
- // SpawnFlyingComponent in VC
RemoveBodyPart(PED_HEAD, direction);
headShot = true;
willLinger = true;
}
-#else
- if (m_nPedState == PED_FALL) {
- if (IsPedHeadAbovePos(-0.3f)) {
- dieAnim = NUM_ANIMS;
- } else {
- if (RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FRONTAL))
- 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;
- }
- }
-#endif
break;
case WEAPONTYPE_COLT45:
- case WEAPONTYPE_UZI:
+ case WEAPONTYPE_SHOTGUN:
+ // TODO(Miami): Shotguns
case WEAPONTYPE_TEC9:
+ case WEAPONTYPE_UZI:
case WEAPONTYPE_SILENCED_INGRAM:
case WEAPONTYPE_MP5:
- case WEAPONTYPE_SHOTGUN:
- case WEAPONTYPE_AK47:
case WEAPONTYPE_M16:
+ case WEAPONTYPE_AK47:
case WEAPONTYPE_SNIPERRIFLE:
+ case WEAPONTYPE_UZI_DRIVEBY:
+ // TODO(Miami): Laserscope, M60, Minigun
+
if (bBulletProof)
return false;
bool dontRemoveLimb;
if (IsPlayer() || bNoCriticalHits)
dontRemoveLimb = true;
- else {
- switch (method) {
- case WEAPONTYPE_SNIPERRIFLE:
- dontRemoveLimb = false;
- break;
- case WEAPONTYPE_M16:
- dontRemoveLimb = false;
- break;
- case WEAPONTYPE_SHOTGUN:
- dontRemoveLimb = CGeneral::GetRandomNumber() & 7;
- break;
- default:
- dontRemoveLimb = CGeneral::GetRandomNumber() & 15;
- break;
- }
- }
+ else if (method != WEAPONTYPE_M16 && method != WEAPONTYPE_AK47 && method != WEAPONTYPE_SNIPERRIFLE
+ /* method != WEAPONTYPE_LASERSCOPE */) { // TODO(Miami): Laserscope
+ if (method == WEAPONTYPE_SHOTGUN)
+ dontRemoveLimb = CGeneral::GetRandomNumber() & 7;
+ else
+ dontRemoveLimb = CGeneral::GetRandomNumber() & 15;
+ } else
+ dontRemoveLimb = false;
if (dontRemoveLimb) {
if (method == WEAPONTYPE_SHOTGUN) {
@@ -4309,8 +4354,8 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
}
}
break;
- case WEAPONTYPE_ROCKETLAUNCHER:
case WEAPONTYPE_GRENADE:
+ case WEAPONTYPE_ROCKETLAUNCHER:
case WEAPONTYPE_EXPLOSION:
if (bExplosionProof)
return false;
@@ -4407,7 +4452,7 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
default:
break;
}
- if (damagedBy) {
+ if (damagedBy && pedPiece != PEDPIECE_TORSO) {
CVehicle *vehicle = (CVehicle*)damagedBy;
if (method == WEAPONTYPE_RAMMEDBYCAR) {
float vehSpeed = vehicle->m_vecMoveSpeed.Magnitude();
@@ -4466,6 +4511,16 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss = CTimer::GetTimeInMilliseconds();
m_lastWepDam = method;
+ m_lastDamEntity = damagedBy;
+ }
+
+ if (method == WEAPONTYPE_FALL) {
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_ROLLOUT_LHS)) {
+ if (m_fHealth >= 1.0 && m_fHealth - healthImpact < 5.0f) {
+ m_fHealth = Min(m_fHealth, 5.0f);
+ return false;
+ }
+ }
}
if (m_fHealth - healthImpact >= 1.0f && !willLinger) {
@@ -4477,6 +4532,8 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
if (method != WEAPONTYPE_DROWNING) {
#ifdef VC_PED_PORTS
if (m_pMyVehicle) {
+
+ // TODO(Miami): Bikes
if (m_pMyVehicle->IsCar() && m_pMyVehicle->pDriver == this) {
if (m_pMyVehicle->GetStatus() == STATUS_SIMPLE) {
m_pMyVehicle->SetStatus(STATUS_PHYSICS);
@@ -4498,7 +4555,7 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
SetDie(dieAnim, dieDelta, dieSpeed);
/*
if (damagedBy == FindPlayerPed() && damagedBy != this) {
- // PlayerInfo stuff
+ // TODO(Miami): PlayerInfo stuff
}
*/
}
@@ -4527,7 +4584,7 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
if (player == this)
m_pMyVehicle->SetStatus(STATUS_PLAYER_DISABLED);
- SetDie(NUM_ANIMS, 4.0f, 0.0f);
+ SetDie(NUM_STD_ANIMS, 4.0f, 0.0f);
return true;
} else {
m_fHealth = 0.0f;
@@ -4535,7 +4592,7 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
if (damagedBy == player || damagedBy && damagedBy == FindPlayerVehicle()) {
- // There are PlayerInfo stuff here in VC
+ // TODO(Miami): PlayerInfo stuff
CDarkel::RegisterKillByPlayer(this, method, headShot);
m_threatEntity = player;
} else {
@@ -4626,7 +4683,7 @@ CPed::SetGetUp(void)
animAssoc->SetFinishCallback(PedGetupCB,this);
} else {
m_fHealth = 0.0f;
- SetDie(NUM_ANIMS, 4.0f, 0.0f);
+ SetDie(NUM_STD_ANIMS, 4.0f, 0.0f);
}
}
@@ -5037,7 +5094,7 @@ CPed::SetEvasiveStep(CEntity *reason, uint8 animType)
else if (animType < 2)
stepAnim = ANIM_EV_STEP;
else
- stepAnim = NUM_ANIMS;
+ stepAnim = NUM_STD_ANIMS;
}
if (!RpAnimBlendClumpGetAssociation(GetClump(), stepAnim)) {
CAnimBlendAssociation *stepAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, stepAnim, 8.0f);
@@ -5191,7 +5248,6 @@ CPed::SetAttack(CEntity *victim)
return;
}
- // TODO(Miami): Brass knuckles
if (GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED || curWeapon->m_bFightMode || GetWeapon()->m_eWeaponType == WEAPONTYPE_BRASSKNUCKLE) {
if (IsPlayer() ||
(m_nPedState != PED_FIGHT && m_nMoveState != PEDMOVE_NONE && m_nMoveState != PEDMOVE_STILL
@@ -5795,7 +5851,7 @@ CPed::SetFlee(CVector2D const &from, int time)
void
CPed::SetWaitState(eWaitState state, void *time)
{
- AnimationId waitAnim = NUM_ANIMS;
+ AnimationId waitAnim = NUM_STD_ANIMS;
CAnimBlendAssociation *animAssoc;
if (!IsPedInControl())
@@ -5882,10 +5938,10 @@ CPed::SetWaitState(eWaitState state, void *time)
case WAITSTATE_PLAYANIM_COWER:
waitAnim = ANIM_HANDSCOWER;
case WAITSTATE_PLAYANIM_HANDSUP:
- if (waitAnim == NUM_ANIMS)
+ if (waitAnim == NUM_STD_ANIMS)
waitAnim = ANIM_HANDSUP;
case WAITSTATE_PLAYANIM_HANDSCOWER:
- if (waitAnim == NUM_ANIMS)
+ if (waitAnim == NUM_STD_ANIMS)
waitAnim = ANIM_HANDSCOWER;
m_headingRate = 0.0f;
if (time)
@@ -5899,10 +5955,10 @@ CPed::SetWaitState(eWaitState state, void *time)
case WAITSTATE_PLAYANIM_DUCK:
waitAnim = ANIM_DUCK_DOWN;
case WAITSTATE_PLAYANIM_TAXI:
- if (waitAnim == NUM_ANIMS)
+ if (waitAnim == NUM_STD_ANIMS)
waitAnim = ANIM_IDLE_TAXI;
case WAITSTATE_PLAYANIM_CHAT:
- if (waitAnim == NUM_ANIMS)
+ if (waitAnim == NUM_STD_ANIMS)
waitAnim = ANIM_IDLE_CHAT;
if (time)
m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time;
@@ -6376,20 +6432,7 @@ CPed::CreateDeadPedMoney(void)
return;
CVector pickupPos = GetPosition();
- bool found;
-
- int pickupCount = Min(money / 20 + 1, 7);
- int moneyPerPickup = money / pickupCount;
-
- for(int i = 0; i < pickupCount; i++) {
- // (CGeneral::GetRandomNumber() % 256) * PI / 128 gives a float up to something TWOPI-ish.
- pickupPos.x += 1.5f * Sin((CGeneral::GetRandomNumber() % 256) * PI / 128);
- pickupPos.y += 1.5f * Cos((CGeneral::GetRandomNumber() % 256) * PI / 128);
- pickupPos.z = CWorld::FindGroundZFor3DCoord(pickupPos.x, pickupPos.y, pickupPos.z, &found) + 0.5f;
- if (found) {
- CPickups::GenerateNewOne(CVector(pickupPos.x, pickupPos.y, pickupPos.z), MI_MONEY, PICKUP_MONEY, moneyPerPickup + (CGeneral::GetRandomNumber() & 3));
- }
- }
+ CPickups::CreateSomeMoney(pickupPos, money);
m_nPedMoney = 0;
}
@@ -7683,7 +7726,7 @@ CPed::FinishedWaitCB(CAnimBlendAssociation *animAssoc, void *arg)
void
CPed::Wait(void)
{
- AnimationId mustHaveAnim = NUM_ANIMS;
+ AnimationId mustHaveAnim = NUM_STD_ANIMS;
CAnimBlendAssociation *animAssoc;
CPed *pedWeLook;
@@ -7853,7 +7896,7 @@ CPed::Wait(void)
mustHaveAnim = ANIM_HANDSUP;
case WAITSTATE_PLAYANIM_HANDSCOWER:
- if (mustHaveAnim == NUM_ANIMS)
+ if (mustHaveAnim == NUM_STD_ANIMS)
mustHaveAnim = ANIM_HANDSCOWER;
animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), mustHaveAnim);
@@ -7925,15 +7968,15 @@ CPed::Wait(void)
mustHaveAnim = ANIM_HANDSCOWER;
case WAITSTATE_PLAYANIM_DUCK:
- if (mustHaveAnim == NUM_ANIMS)
+ if (mustHaveAnim == NUM_STD_ANIMS)
mustHaveAnim = ANIM_DUCK_DOWN;
case WAITSTATE_PLAYANIM_TAXI:
- if (mustHaveAnim == NUM_ANIMS)
+ if (mustHaveAnim == NUM_STD_ANIMS)
mustHaveAnim = ANIM_IDLE_TAXI;
case WAITSTATE_PLAYANIM_CHAT:
- if (mustHaveAnim == NUM_ANIMS)
+ if (mustHaveAnim == NUM_STD_ANIMS)
mustHaveAnim = ANIM_IDLE_CHAT;
if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
@@ -8721,14 +8764,22 @@ CPed::SetLanding(void)
CAnimBlendAssociation *fallAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FALL_FALL);
CAnimBlendAssociation *landAssoc;
+ if (fallAssoc && bIsDrowning)
+ return;
+
RpAnimBlendClumpSetBlendDeltas(GetClump(), ASSOC_PARTIAL, -1000.0f);
- if (fallAssoc) {
+ if (fallAssoc || m_nPedType == PEDTYPE_COP && bKnockedUpIntoAir) {
landAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_FALL_COLLAPSE);
DMAudio.PlayOneShot(m_audioEntityId, SOUND_FALL_COLLAPSE, 1.0f);
if (IsPlayer())
Say(SOUND_PED_LAND);
+ if (m_nPedType == PEDTYPE_COP) {
+ if (bKnockedUpIntoAir)
+ bKnockedUpIntoAir = false;
+ }
+
} else {
landAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_FALL_LAND);
DMAudio.PlayOneShot(m_audioEntityId, SOUND_FALL_LAND, 1.0f);
@@ -9691,7 +9742,7 @@ CPed::MoveHeadToLook(void)
bool notRocketLauncher = false;
bool notTwoHanded = false;
- AnimationId animToPlay = NUM_ANIMS;
+ AnimationId animToPlay = NUM_STD_ANIMS;
if (!GetWeapon()->IsType2Handed())
notTwoHanded = true;
@@ -9720,7 +9771,7 @@ CPed::MoveHeadToLook(void)
animToPlay = ANIM_FUCKU;
}
- if (animToPlay != NUM_ANIMS) {
+ if (animToPlay != NUM_STD_ANIMS) {
CAnimBlendAssociation *newAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animToPlay, 4.0f);
if (newAssoc) {
@@ -9912,6 +9963,7 @@ CPed::ProcessControl(void)
bIsShooting = false;
BuildPedLists();
bIsInWater = false;
+ bIsDrowning = false;
ProcessBuoyancy();
if (m_nPedState != PED_ARRESTED) {
@@ -11209,8 +11261,11 @@ CPed::ProcessControl(void)
default: break;
}
SetMoveAnim();
- if (bPedIsBleeding) {
+ if (bPedIsBleeding || m_bleedCounter != 0) {
if (CGame::nastyGame) {
+ if (m_bleedCounter != 0)
+ m_bleedCounter--;
+
if (!(CTimer::GetFrameCounter() & 3)) {
CVector cameraDist = GetPosition() - TheCamera.GetPosition();
if (cameraDist.MagnitudeSqr() < sq(50.0f)) {
@@ -15928,6 +15983,7 @@ CPed::ProcessBuoyancy(void)
m_vecMoveSpeed.y *= speedMult;
m_vecMoveSpeed.z *= speedMult;
bIsStanding = false;
+ bIsDrowning = true;
InflictDamage(nil, WEAPONTYPE_DROWNING, 3.0f * CTimer::GetTimeStep(), PEDPIECE_TORSO, 0);
}
if (buoyancyImpulse.z / m_fMass > 0.002f * CTimer::GetTimeStep()) {
diff --git a/src/peds/Ped.h b/src/peds/Ped.h
index f5e6d95a..07c44fd5 100644
--- a/src/peds/Ped.h
+++ b/src/peds/Ped.h
@@ -444,8 +444,8 @@ public:
//uint32 b155_40
//uint32 b155_80
- //uint32 b156_1
- //uint32 b156_2
+ uint32 bIsDrowning : 1;
+ uint32 bCanDrownInWater : 1; // Originally bDrownsInWater
//uint32 b156_4
//uint32 b156_8
uint32 bIsPlayerFriend : 1;
@@ -578,6 +578,7 @@ public:
uint8 m_fightButtonPressure;
FightState m_fightState;
bool m_takeAStepAfterAttack;
+ uint8 m_bleedCounter;
CFire *m_pFire;
CEntity *m_pLookTarget;
float m_fLookDirection;
diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp
index 9f972882..f6f1cf05 100644
--- a/src/peds/PlayerPed.cpp
+++ b/src/peds/PlayerPed.cpp
@@ -1026,7 +1026,7 @@ CPlayerPed::ProcessAnimGroups(void)
if (m_fWalkAngle > 0.0f) {
if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER)
groupToSet = ASSOCGRP_ROCKETLEFT;
- else if (/*GetWeapon()->m_eWeaponType == WEAPONTYPE_CHAINSAW || */
+ else if (GetWeapon()->m_eWeaponType == WEAPONTYPE_CHAINSAW ||
GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER
/* || GetWeapon()->m_eWeaponType == WEAPONTYPE_MINIGUN*/ )
groupToSet = ASSOCGRP_CHAINSAWLEFT;
@@ -1035,7 +1035,7 @@ CPlayerPed::ProcessAnimGroups(void)
} else {
if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER)
groupToSet = ASSOCGRP_ROCKETRIGHT;
- else if (/*GetWeapon()->m_eWeaponType == WEAPONTYPE_CHAINSAW || */
+ else if (GetWeapon()->m_eWeaponType == WEAPONTYPE_CHAINSAW ||
GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER
/* || GetWeapon()->m_eWeaponType == WEAPONTYPE_MINIGUN*/)
groupToSet = ASSOCGRP_CHAINSAWRIGHT;
@@ -1045,7 +1045,7 @@ CPlayerPed::ProcessAnimGroups(void)
} else {
if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER)
groupToSet = ASSOCGRP_ROCKETBACK;
- else if (/*GetWeapon()->m_eWeaponType == WEAPONTYPE_CHAINSAW || */
+ else if (GetWeapon()->m_eWeaponType == WEAPONTYPE_CHAINSAW ||
GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER
/* || GetWeapon()->m_eWeaponType == WEAPONTYPE_MINIGUN*/)
groupToSet = ASSOCGRP_CHAINSAWBACK;
@@ -1057,9 +1057,9 @@ CPlayerPed::ProcessAnimGroups(void)
groupToSet = ASSOCGRP_PLAYERROCKET;
} else {
if (GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT
- /* || GetWeapon()->m_eWeaponType == WEAPONTYPE_MACHETE */)
+ || GetWeapon()->m_eWeaponType == WEAPONTYPE_MACHETE)
groupToSet = ASSOCGRP_PLAYERBBBAT;
- else if (/*GetWeapon()->m_eWeaponType == WEAPONTYPE_CHAINSAW || */
+ else if (GetWeapon()->m_eWeaponType == WEAPONTYPE_CHAINSAW ||
GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER
/* || GetWeapon()->m_eWeaponType == WEAPONTYPE_MINIGUN*/)
groupToSet = ASSOCGRP_PLAYERCHAINSAW;
@@ -1067,10 +1067,9 @@ CPlayerPed::ProcessAnimGroups(void)
// I hope this was inlined...
/*
&& GetWeapon()->m_eWeaponType != WEAPONTYPE_PYTHON*/ && GetWeapon()->m_eWeaponType != WEAPONTYPE_TEC9
- && GetWeapon()->m_eWeaponType != WEAPONTYPE_SILENCED_INGRAM && GetWeapon()->m_eWeaponType != WEAPONTYPE_MP5 /*
+ && GetWeapon()->m_eWeaponType != WEAPONTYPE_SILENCED_INGRAM && GetWeapon()->m_eWeaponType != WEAPONTYPE_MP5
&& GetWeapon()->m_eWeaponType != WEAPONTYPE_GOLFCLUB && GetWeapon()->m_eWeaponType != WEAPONTYPE_KATANA
- && GetWeapon()->m_eWeaponType != WEAPONTYPE_CAMERA
- */) {
+ /* && GetWeapon()->m_eWeaponType != WEAPONTYPE_CAMERA */) {
if (!GetWeapon()->IsType2Handed()) {
groupToSet = ASSOCGRP_PLAYER;
} else {