Merge pull request #147 from erorcun/erorcun

The Peds, mainly dying/injuring
This commit is contained in:
aap 2019-07-18 15:19:34 +02:00 committed by GitHub
commit 82be466013
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 861 additions and 212 deletions

View File

@ -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;
}

View File

@ -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);

View File

@ -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", 0, PEDPIECE_TORSO, 0.0f, 0.15f, 0.2f },
{ "Storso", 0, PEDPIECE_TORSO, 0.0f, -0.05f, 0.3f },
{ nil, PED_MID, PEDPIECE_MID, 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*

View File

@ -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,

View File

@ -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,8 +1047,35 @@ CPed::Attack(void)
weaponAnimAssoc = RpAnimBlendClumpGetAssociation((RpClump*) m_rwObject, ANIM_WEAPON_THROWU);
delayBetweenAnimAndFire = 0.2f;
}
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);
}
if (weaponAnimAssoc) {
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;
}
}
animStart = ourWeapon->m_fAnimLoopStart;
weaponAnimTime = weaponAnimAssoc->currentTime;
if (weaponAnimTime > animStart && weaponAnimTime - weaponAnimAssoc->timeStep <= animStart) {
@ -1199,31 +1227,6 @@ CPed::Attack(void)
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;
}
}
}
else
CPed::FinishedAttackCB(nil, this);
}
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;
}
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_TORSO:
willLinger = false;
dieAnim = ANIM_KO_SHOT_FRONT1;
break;
case PEDPIECE_MID:
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_MID || random != 1)) {
if (pedPiece == PEDPIECE_RIGHTARM && random > 1
|| pedPiece == PEDPIECE_MID && 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_MID || random != 1)) {
if ((pedPiece != PEDPIECE_RIGHTARM || random <= 1)
&& (pedPiece != PEDPIECE_MID || 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_TORSO, 0);
else {
if (!CPad::GetPad(0)->ArePlayerControlsDisabled())
return;
InflictDamage(nil, WEAPONTYPE_RUNOVERBYCAR, 1000.0f, PEDPIECE_TORSO, 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

View File

@ -13,6 +13,17 @@
struct CPathNode;
enum ePedPieceTypes
{
PEDPIECE_TORSO,
PEDPIECE_MID,
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; // if set, limbs won't came off
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);

View File

@ -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

View File

@ -1,8 +1,10 @@
#pragma once
class CVector;
class CEntity;
class CPedPlacement {
public:
static void FindZCoorForPed(CVector* pos);
static CEntity* IsPositionClearOfCars(CVector*);
};

View File

@ -38,6 +38,22 @@ CPlayerPed::SetWantedLevelNoDrop(int32 level)
m_pWanted->SetWantedLevelNoDrop(level);
}
// I don't know the actual purpose of parameter
void
CPlayerPed::AnnoyPlayerPed(bool itsPolice)
{
if (m_pedStats->m_temper < 52) {
m_pedStats->m_temper++;
} else {
if (itsPolice) {
if (m_pedStats->m_temper < 55) {
m_pedStats->m_temper++;
} else {
m_pedStats->m_temper = 46;
}
}
}
}
class CPlayerPed_ : public CPlayerPed
{
@ -48,4 +64,5 @@ public:
STARTPATCHES
InjectHook(0x4EFB30, &CPlayerPed_::dtor, PATCH_JUMP);
InjectHook(0x4F28A0, &CPlayerPed::ClearWeaponTarget, PATCH_JUMP);
InjectHook(0x4F3700, &CPlayerPed::AnnoyPlayerPed, PATCH_JUMP);
ENDPATCHES

View File

@ -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);

View File

@ -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];
}