This commit is contained in:
eray orçunus 2019-09-13 22:04:55 +03:00
parent 4041159855
commit 88f0ef75e8
8 changed files with 678 additions and 259 deletions

View File

@ -67,6 +67,7 @@ int32 (&CCarCtrl::TotalNumOfCarsOfRating)[7] = *(int32(*)[7])*(uintptr*)0x8F1A60
int32 (&CCarCtrl::NextCarOfRating)[7] = *(int32(*)[7])*(uintptr*)0x9412AC;
int32 (&CCarCtrl::CarArrays)[7][MAX_CAR_MODELS_IN_ARRAY] = *(int32(*)[7][MAX_CAR_MODELS_IN_ARRAY])*(uintptr*)0x6EB860;
CVehicle* (&apCarsToKeep)[MAX_CARS_TO_KEEP] = *(CVehicle*(*)[MAX_CARS_TO_KEEP])*(uintptr*)0x70D830;
uint32 (&aCarsToKeepTime)[MAX_CARS_TO_KEEP] = *(uint32(*)[MAX_CARS_TO_KEEP])*(uintptr*)0x87F9A8;
WRAPPER void CCarCtrl::SwitchVehicleToRealPhysics(CVehicle*) { EAXJMP(0x41F7F0); }
WRAPPER void CCarCtrl::UpdateCarCount(CVehicle*, bool) { EAXJMP(0x4202E0); }
@ -745,6 +746,34 @@ CCarCtrl::IsThisVehicleInteresting(CVehicle* pVehicle)
return false;
}
void
CCarCtrl::RegisterVehicleOfInterest(CVehicle* pVehicle)
{
for(int i = 0; i < MAX_CARS_TO_KEEP; i++) {
if (apCarsToKeep[i] == pVehicle) {
aCarsToKeepTime[i] = CTimer::GetTimeInMilliseconds();
return;
}
}
for (int i = 0; i < MAX_CARS_TO_KEEP; i++) {
if (!apCarsToKeep[i]) {
apCarsToKeep[i] = pVehicle;
aCarsToKeepTime[i] = CTimer::GetTimeInMilliseconds();
return;
}
}
uint32 oldestCarWeKeepTime = UINT_MAX;
int oldestCarWeKeepIndex = 0;
for (int i = 0; i < MAX_CARS_TO_KEEP; i++) {
if (apCarsToKeep[i] && aCarsToKeepTime[i] < oldestCarWeKeepTime) {
oldestCarWeKeepTime = aCarsToKeepTime[i];
oldestCarWeKeepIndex = i;
}
}
apCarsToKeep[oldestCarWeKeepIndex] = pVehicle;
aCarsToKeepTime[oldestCarWeKeepIndex] = CTimer::GetTimeInMilliseconds();
}
void
CCarCtrl::UpdateCarOnRails(CVehicle* pVehicle)
{

View File

@ -58,6 +58,7 @@ public:
static void RemoveDistantCars(void);
static void PossiblyRemoveVehicle(CVehicle*);
static bool IsThisVehicleInteresting(CVehicle*);
static void RegisterVehicleOfInterest(CVehicle*);
static int32 CountCarsOfType(int32 mi);
static void SlowCarOnRailsDownForTrafficAndLights(CVehicle*);
static bool PickNextNodeAccordingStrategy(CVehicle*);

View File

@ -1459,7 +1459,7 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
A->m_phy_flagA80 = true;
}else if(A->IsPed() && Aped->m_pCollidingEntity == B){
skipCollision = true;
if(!Aped->m_ped_flagH1)
if(!Aped->bKnockedUpIntoAir)
A->m_phy_flagA80 = true;
}else if(B->IsPed() && Bped->m_pCollidingEntity == A){
skipCollision = true;

View File

@ -38,6 +38,8 @@
#include "Font.h"
#include "Text.h"
#include "CopPed.h"
#include "Script.h"
#include "CarCtrl.h"
WRAPPER void CPed::SpawnFlyingComponent(int, int8) { EAXJMP(0x4EB060); }
WRAPPER void CPed::SetPedPositionInCar(void) { EAXJMP(0x4D4970); }
@ -61,6 +63,7 @@ WRAPPER void CPed::WanderPath(void) { EAXJMP(0x4D28D0); }
WRAPPER void CPed::ReactToPointGun(CEntity*) { EAXJMP(0x4DD980); }
WRAPPER void CPed::SeekCar(void) { EAXJMP(0x4D3F90); }
WRAPPER void CPed::SeekBoatPosition(void) { EAXJMP(0x4E4C70); }
WRAPPER bool CPed::PositionPedOutOfCollision(void) { EAXJMP(0x4E4F30); }
CPed *gapTempPedList[50];
uint16 gnNumTempPedList;
@ -468,7 +471,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
m_ped_flagC40 = false;
bFindNewNodeAfterStateRestore = false;
m_ped_flagD1 = false;
bHasACamera = false;
m_ped_flagD2 = false;
m_ped_flagD4 = false;
m_ped_flagD8 = false;
@ -484,7 +487,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
bIsDucking = false;
bGetUpAnimStarted = false;
bDoBloodyFootprints = false;
m_ped_flagE80 = false;
bFleeAfterExitingCar = false;
bWanderPathAfterExitingCar = false;
m_ped_flagF2 = false;
@ -501,10 +504,10 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
bStartWanderPathOnFoot = false;
m_ped_flagG10 = false;
bBusJacked = false;
m_ped_flagG40 = false;
bGonnaKillTheCarJacker = false;
bFadeOut = false;
m_ped_flagH1 = false;
bKnockedUpIntoAir = false;
m_ped_flagH2 = false;
m_ped_flagH4 = false;
bClearObjective = false;
@ -523,7 +526,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
#endif
if ((CGeneral::GetRandomNumber() & 3) == 0)
m_ped_flagD1 = true;
bHasACamera = true;
m_audioEntityId = DMAudio.CreateEntity(AUDIOTYPE_PHYSICAL, this);
DMAudio.SetEntityStatus(m_audioEntityId, 1);
@ -2476,7 +2479,7 @@ CPed::SetLeader(CEntity *leader)
void
CPed::SetObjective(eObjective newObj, void *entity)
{
if (m_nPedState == PED_DIE || m_nPedState == PED_DEAD)
if (DyingOrDead())
return;
if (m_prevObjective == newObj) {
@ -2635,7 +2638,7 @@ CPed::SetIdle(void)
void
CPed::SetObjective(eObjective newObj)
{
if (m_nPedState == PED_DIE || m_nPedState == PED_DEAD)
if (DyingOrDead())
return;
if (newObj == OBJECTIVE_NONE) {
@ -2691,7 +2694,7 @@ CPed::SetObjective(eObjective newObj)
void
CPed::SetObjective(eObjective newObj, int16 routePoint, int16 routeType)
{
if (m_nPedState == PED_DIE || m_nPedState == PED_DEAD)
if (DyingOrDead())
return;
if (m_prevObjective == newObj && m_prevObjective != OBJECTIVE_NONE)
@ -2805,7 +2808,7 @@ CPed::QuitEnteringCar(void)
CWeaponInfo *curWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
AddWeaponModel(curWeapon->m_nModelId);
}
if (m_nPedState == PED_DIE || m_nPedState == PED_DEAD) {
if (DyingOrDead()) {
animAssoc = m_pVehicleAnim;
if (animAssoc) {
animAssoc->blendDelta = -4.0f;
@ -3200,7 +3203,7 @@ CPed::ClearAll(void)
ClearLookFlag();
bIsPointingGunAt = false;
bRenderPedInCar = true;
m_ped_flagH1 = false;
bKnockedUpIntoAir = false;
m_pCollidingEntity = nil;
}
@ -3284,7 +3287,7 @@ CPed::SetDie(AnimationId animId, float delta, float speed)
}
m_threatEntity = nil;
if (m_nPedState == PED_DIE || m_nPedState == PED_DEAD)
if (DyingOrDead())
return;
if (m_nPedState == PED_FALL || m_nPedState == PED_GETUP)
@ -3346,7 +3349,7 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
player->AnnoyPlayerPed(false);
}
if (m_nPedState == PED_DIE || m_nPedState == PED_DEAD)
if (DyingOrDead())
return false;
if (!bUsesCollision && method != WEAPONTYPE_WATER)
@ -3789,7 +3792,7 @@ CPed::SetGetUp(void)
}
bGetUpAnimStarted = true;
m_pCollidingEntity = nil;
m_ped_flagH1 = false;
bKnockedUpIntoAir = false;
CAnimBlendAssociation *animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_SPRINT);
if (animAssoc) {
if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN)) {
@ -3867,12 +3870,11 @@ void
CPed::ClearObjective(void)
{
if (IsPedInControl() || m_nPedState == PED_DRIVING) {
m_objective = OBJECTIVE_NONE;
if (m_nPedState == PED_DRIVING && m_pMyVehicle) {
if (m_pMyVehicle->pDriver != this) {
bWanderPathAfterExitingCar = true;
SetObjective(OBJECTIVE_LEAVE_VEHICLE, m_pMyVehicle);
}
@ -4735,7 +4737,7 @@ CPed::FightStrike(CVector &touchedNodePos)
PlayHitSound(nearPed);
m_fightState = FIGHTSTATE_JUST_ATTACKED;
RpAnimBlendClumpGetAssociation(GetClump(), tFightMoves[m_lastFightMove].animId)->speed = 0.6f;
if (nearPed->m_nPedState != PED_DIE && nearPed->m_nPedState != PED_DEAD) {
if (!nearPed->DyingOrDead()) {
nearPed->InflictDamage(this, WEAPONTYPE_UNARMED, damageMult * 3.0f, closestPedPiece, direction);
}
@ -4795,7 +4797,7 @@ CPed::FightStrike(CVector &touchedNodePos)
void
CPed::SetFall(int extraTime, AnimationId animId, uint8 evenIfNotInControl)
{
if (!IsPedInControl() && (!evenIfNotInControl || m_nPedState == PED_DIE || m_nPedState == PED_DEAD))
if (!IsPedInControl() && (!evenIfNotInControl || DyingOrDead()))
return;
ClearLookFlag();
@ -5820,7 +5822,7 @@ CPed::EndFight(uint8 endType)
void
CPed::EnterCar(void)
{
if (m_pMyVehicle && m_pMyVehicle->m_status != STATUS_WRECKED && m_fHealth > 0.0f) {
if (!m_pMyVehicle->IsWrecked() && m_fHealth > 0.0f) {
CVehicle *veh = (CVehicle*)m_pSeekTarget;
// Not used.
@ -6597,7 +6599,7 @@ CPed::Wait(void)
CAnimBlendAssociation *animAssoc;
CPed *pedWeLook;
if (m_nPedState == PED_DIE || m_nPedState == PED_DEAD) {
if (DyingOrDead()) {
m_nWaitState = WAITSTATE_FALSE;
RestoreHeadingRate();
return;
@ -7612,7 +7614,7 @@ CPed::InTheAir(void)
bitBelow.z -= 4.04f;
if (m_vecMoveSpeed.z < 0.0f && !bIsPedDieAnimPlaying) {
if (m_nPedState != PED_DIE && m_nPedState != PED_DEAD) {
if (!DyingOrDead()) {
if (CWorld::ProcessLineOfSight(ourPos, bitBelow, foundCol, foundEnt, true, true, false, true, false, false, false)) {
if (GetPosition().z - foundCol.point.z < 1.3f)
SetLanding();
@ -7629,7 +7631,7 @@ CPed::InTheAir(void)
void
CPed::SetLanding(void)
{
if (m_nPedState == PED_DIE || m_nPedState == PED_DEAD)
if (DyingOrDead())
return;
CAnimBlendAssociation *fallAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FALL_FALL);
@ -7802,7 +7804,7 @@ CPed::InvestigateEvent(void)
case EVENT_FIRE:
case EVENT_EXPLOSION:
if (m_ped_flagD1 && CTimer::GetTimeInMilliseconds() > m_lookTimer) {
if (bHasACamera && CTimer::GetTimeInMilliseconds() > m_lookTimer) {
animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_CAM);
if (!animAssoc)
animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_STANCE);
@ -8001,6 +8003,7 @@ CPed::KillPedWithCar(CVehicle *car, float impulse)
if (m_pCurSurface->IsVehicle() && (((CVehicle*)m_pCurSurface)->m_vehType == VEHICLE_TYPE_BOAT || IsPlayer()))
return;
}
CVector distVec = GetPosition() - car->GetPosition();
if ((impulse > 12.0f || car->m_modelIndex == MI_TRAIN) && !IsPlayer()) {
@ -8157,14 +8160,14 @@ CPed::KillPedWithCar(CVehicle *car, float impulse)
}
CPed::InflictDamage(car, killMethod, 1000.0f, pieceToDamage, damageDir);
if ((m_nPedState == PED_DIE || m_nPedState == PED_DEAD)
if (DyingOrDead()
&& bIsPedDieAnimPlaying && !m_pCollidingEntity) {
m_pCollidingEntity = car;
}
if (nodeToDamage == PED_MID)
m_ped_flagH1 = true;
bKnockedUpIntoAir = true;
else
m_ped_flagH1 = false;
bKnockedUpIntoAir = false;
distVec.Normalise();
car->ApplyMoveForce(distVec * -100.0f);
@ -8191,7 +8194,7 @@ CPed::KillPedWithCar(CVehicle *car, float impulse)
m_pCollidingEntity = car;
}
m_ped_flagH1 = false;
bKnockedUpIntoAir = false;
if (car->m_modelIndex != MI_TRAIN && !m_ped_flagD2) {
m_vecMoveSpeed = car->m_vecMoveSpeed * 0.75f;
}
@ -8653,7 +8656,9 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg)
if (animAssoc)
animAssoc->blendDelta = -1000.0f;
if (veh && veh->m_status != STATUS_WRECKED) {
if (veh->IsWrecked())
return;
if (ped->m_nPedState != PED_ENTER_CAR && ped->m_nPedState != PED_CARJACK) {
ped->QuitEnteringCar();
return;
@ -8748,17 +8753,14 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg)
ped->m_pVehicleAnim->SetFinishCallback(PedAnimDoorOpenCB, ped);
} else {
AnimationId animToPlay;
if (enterDoor != DOOR_FRONT_LEFT && enterDoor != DOOR_REAR_LEFT)
animToPlay = ANIM_CAR_DOORLOCKED_RHS;
ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_DOORLOCKED_RHS);
else
animToPlay = ANIM_CAR_DOORLOCKED_LHS;
ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_DOORLOCKED_LHS);
ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, animToPlay);
ped->bCancelEnteringCar = true;
ped->m_pVehicleAnim->SetFinishCallback(PedAnimDoorOpenCB, ped);
}
}
}
void
@ -8806,14 +8808,13 @@ CPed::ProcessControl(void)
for (int i = 0; i < m_numNearPeds; ++i) {
CPed *nearPed = m_nearPeds[i];
PedState nearPedState = nearPed->m_nPedState;
if (nearPedState != PED_DIE && nearPedState != PED_DEAD) {
if (!nearPed->DyingOrDead()) {
CVector dist = nearPed->GetPosition() - GetPosition();
if (dist.MagnitudeSqr() < sq(timeDependentDist)) {
nearPed->m_bloodyFootprintCount = 200;
nearPed->bDoBloodyFootprints = true;
if (nearPed->IsPlayer()) {
if (!nearPed->bIsLooking && nearPedState != PED_ATTACK) {
if (!nearPed->bIsLooking && nearPed->m_nPedState != PED_ATTACK) {
int16 camMode = TheCamera.Cams[TheCamera.ActiveCam].Mode;
if (camMode != CCam::MODE_SNIPER
&& camMode != CCam::MODE_ROCKET
@ -9275,7 +9276,7 @@ CPed::ProcessControl(void)
ApplyMoveForce(forceDir);
}
if (bIsInTheAir && m_nPedState != PED_DIE && m_nPedState != PED_DEAD) {
if (bIsInTheAir && !DyingOrDead()) {
if (m_nPedStateTimer <= 1000 && m_nPedStateTimer) {
forceDir = GetPosition() - m_vecHitLastPos;
} else {
@ -9831,7 +9832,7 @@ CPed::PedAnimDoorCloseCB(CAnimBlendAssociation *animAssoc, void *arg)
CAutomobile *veh = (CAutomobile*)(ped->m_pMyVehicle);
if (!veh || veh->m_status == STATUS_WRECKED || ped->m_nPedState == PED_DIE || ped->m_nPedState == PED_DEAD)
if (veh->IsWrecked() || ped->DyingOrDead())
return;
if (ped->m_nPedState == PED_CARJACK || ped->m_nPedState == PED_ENTER_CAR) {
@ -9867,7 +9868,7 @@ CPed::PedAnimDoorCloseCB(CAnimBlendAssociation *animAssoc, void *arg)
ped->SetObjective(OBJECTIVE_LEAVE_VEHICLE, veh);
if (!ped->IsPlayer())
ped->m_ped_flagE80 = true;
ped->bFleeAfterExitingCar = true;
ped->bUsePedNodeSeek = true;
ped->m_pNextPathNode = nil;
@ -9920,7 +9921,7 @@ CPed::PedAnimDoorOpenCB(CAnimBlendAssociation* animAssoc, void* arg)
if (animAssoc)
animAssoc->blendDelta = -1000.0f;
if (!veh || veh->m_status == STATUS_WRECKED)
if (veh->IsWrecked())
return;
if (ped->m_nPedState != PED_CARJACK && ped->m_nPedState != PED_ENTER_CAR) {
@ -10155,19 +10156,19 @@ CPed::PedAnimGetInCB(CAnimBlendAssociation *animAssoc, void *arg)
if (animAssoc)
animAssoc->blendDelta = -1000.0f;
if (!veh || veh->m_status == STATUS_WRECKED)
if (veh->IsWrecked() || ped->DyingOrDead())
return;
if (ped->m_nPedState != PED_DIE && ped->m_nPedState != PED_DEAD) {
if (ped->m_nPedState != PED_CARJACK && ped->m_nPedState != PED_ENTER_CAR) {
ped->QuitEnteringCar();
return;
}
if (ped->IsPlayer() && ped->m_ped_flagG40 && ((CPlayerPed*)ped)->m_pArrestingCop) {
if (ped->IsPlayer() && ped->bGonnaKillTheCarJacker && ((CPlayerPed*)ped)->m_pArrestingCop) {
PedSetInCarCB(nil, ped);
ped->m_nLastPedState = ped->m_nPedState;
ped->m_nPedState = PED_ARRESTED;
ped->m_ped_flagG40 = false;
ped->bGonnaKillTheCarJacker = false;
if (veh) {
veh->m_nNumGettingIn = 0;
veh->m_nGettingInFlags = 0;
@ -10237,9 +10238,9 @@ CPed::PedAnimGetInCB(CAnimBlendAssociation *animAssoc, void *arg)
if (driver->m_pedStats->m_temper <= driver->m_pedStats->m_fear
|| driver->CharCreatedBy == MISSION_CHAR
|| veh->VehicleCreatedBy == MISSION_VEHICLE) {
driver->m_ped_flagE80 = true;
driver->bFleeAfterExitingCar = true;
} else {
driver->m_ped_flagG40 = true;
driver->bGonnaKillTheCarJacker = true;
veh->pDriver->SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, ped);
if (veh->pDriver->m_nPedType == PEDTYPE_COP && ped->IsPlayer()) {
@ -10278,7 +10279,6 @@ CPed::PedAnimGetInCB(CAnimBlendAssociation *animAssoc, void *arg)
ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, animToPlay);
ped->m_pVehicleAnim->SetFinishCallback(PedAnimDoorCloseCB, ped);
}
}
}
void
@ -10297,7 +10297,7 @@ CPed::PedAnimPullPedOutCB(CAnimBlendAssociation* animAssoc, void* arg)
animAssoc->blendDelta = -1000.0f;
if (ped->m_nPedState == PED_CARJACK || ped->m_nPedState == PED_ENTER_CAR) {
if (!veh || veh->m_status == STATUS_WRECKED)
if (veh->IsWrecked())
return;
bool isLow = veh->bLowVehicle;
@ -10455,7 +10455,7 @@ CPed::PedAnimStepOutCarCB(CAnimBlendAssociation* animAssoc, void* arg)
return;
}
if (ped->m_ped_flagE80 || ped->m_ped_flagG40) {
if (ped->bFleeAfterExitingCar || ped->bGonnaKillTheCarJacker) {
// POTENTIAL BUG? Why DOOR_FRONT_LEFT instead of door variable? or vice versa?
if (!veh->IsDoorMissing(door))
((CAutomobile*)veh)->Damage.SetDoorStatus(DOOR_FRONT_LEFT, DOOR_STATUS_SWINGING);
@ -10483,16 +10483,387 @@ CPed::PedAnimStepOutCarCB(CAnimBlendAssociation* animAssoc, void* arg)
return;
}
WRAPPER void CPed::PedGetupCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4CE810); }
void
CPed::PedEvadeCB(CAnimBlendAssociation* animAssoc, void* arg)
{
CPed* ped = (CPed*)arg;
if (!animAssoc) {
ped->ClearLookFlag();
if (ped->m_nPedState != PED_DIVE_AWAY && ped->m_nPedState != PED_STEP_AWAY)
return;
ped->RestorePreviousState();
} else if (animAssoc->animId == ANIM_EV_DIVE) {
ped->bUpdateAnimHeading = true;
ped->ClearLookFlag();
if (ped->m_nPedState == PED_DIVE_AWAY)
{
ped->m_getUpTimer = CTimer::GetTimeInMilliseconds() + 1;
ped->m_nPedState = PED_FALL;
}
animAssoc->flags &= ~ASSOC_FADEOUTWHENDONE;
animAssoc->flags |= ASSOC_DELETEFADEDOUT;
} else if (animAssoc->flags & ASSOC_FADEOUTWHENDONE) {
ped->ClearLookFlag();
if (ped->m_nPedState != PED_DIVE_AWAY && ped->m_nPedState != PED_STEP_AWAY)
return;
ped->RestorePreviousState();
} else if (ped->m_nPedState != PED_ARRESTED) {
animAssoc->flags |= ASSOC_DELETEFADEDOUT;
if (animAssoc->blendDelta >= 0.0f)
animAssoc->blendDelta = -4.0f;
ped->ClearLookFlag();
if (ped->m_nPedState == PED_DIVE_AWAY || ped->m_nPedState == PED_STEP_AWAY) {
ped->RestorePreviousState();
}
}
}
void
CPed::PedGetupCB(CAnimBlendAssociation* animAssoc, void* arg)
{
CPed* ped = (CPed*)arg;
if (ped->m_nPedState == PED_GETUP)
RpAnimBlendClumpSetBlendDeltas(ped->GetClump(), ASSOC_PARTIAL, -1000.0f);
ped->bFallenDown = false;
animAssoc->blendDelta = -1000.0f;
if (ped->m_nPedState == PED_GETUP)
ped->RestorePreviousState();
if (ped->m_nPedState != PED_FLEE_POS && ped->m_nPedState != PED_FLEE_ENTITY)
ped->SetMoveState(PEDMOVE_STILL);
else
ped->SetMoveState(PEDMOVE_RUN);
ped->SetMoveAnim();
ped->bGetUpAnimStarted = false;
}
void
CPed::PedLandCB(CAnimBlendAssociation* animAssoc, void* arg)
{
CPed* ped = (CPed*)arg;
animAssoc->blendDelta = -1000.0f;
ped->bIsLanding = false;
if (ped->m_nPedState == PED_JUMP)
ped->RestorePreviousState();
}
void
CPed::PedSetDraggedOutCarPositionCB(CAnimBlendAssociation* animAssoc, void* arg)
{
CPed *ped = (CPed*)arg;
ped->bUsesCollision = true;
ped->RestartNonPartialAnims();
bool itsRearDoor = false;
if (ped->m_vehEnterType == CAR_DOOR_RF || ped->m_vehEnterType == CAR_DOOR_RR)
itsRearDoor = true;
CMatrix pedMat(ped->GetMatrix());
CVector posAfterBeingDragged = Multiply3x3(pedMat, (itsRearDoor ? -vecPedDraggedOutCarAnimOffset : vecPedDraggedOutCarAnimOffset));
posAfterBeingDragged += ped->GetPosition();
posAfterBeingDragged.z += 1.0f;
CPedPlacement::FindZCoorForPed(&posAfterBeingDragged);
ped->m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
ped->GetPosition() = posAfterBeingDragged;
if (ped->m_pMyVehicle && !ped->m_pMyVehicle->IsRoomForPedToLeaveCar(ped->m_vehEnterType, &vecPedDraggedOutCarAnimOffset)) {
ped->PositionPedOutOfCollision();
}
if (!ped->CanSetPedState())
return;
if (!ped->m_pMyVehicle) {
ped->SetIdle();
ped->SetGetUp();
return;
}
CPed *driver = ped->m_pMyVehicle->pDriver;
if (ped->IsPlayer()) {
ped->SetIdle();
} else if (ped->bFleeAfterExitingCar) {
ped->bFleeAfterExitingCar = false;
ped->SetFlee(ped->m_pMyVehicle->GetPosition(), 4000);
} else if (ped->bWanderPathAfterExitingCar) {
ped->SetWanderPath(CGeneral::GetRandomNumberInRange(0.0f, 8.0f));
ped->bWanderPathAfterExitingCar = false;
} else if (ped->bGonnaKillTheCarJacker) {
// Kill objective is already set at this point.
ped->bGonnaKillTheCarJacker = false;
if (!ped->m_pedInObjective || !(CGeneral::GetRandomNumber() & 1)) {
if (!driver || driver == ped || driver->IsPlayer() && CTheScripts::IsPlayerOnAMission()) {
ped->m_nPedState = PED_NONE;
ped->m_nLastPedState = PED_NONE;
ped->SetFlee(ped->m_pMyVehicle->GetPosition(), 4000);
} else {
ped->ClearObjective();
ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, ped->m_pMyVehicle);
}
}
} else if (ped->m_pedStats->m_temper > ped->m_pedStats->m_fear && ped->CharCreatedBy != MISSION_CHAR
&& ped->m_pMyVehicle->VehicleCreatedBy != MISSION_VEHICLE && driver
&& driver->IsPlayer() && !CTheScripts::IsPlayerOnAMission()) {
if (CGeneral::GetRandomNumber() & 1)
ped->SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, driver);
else
ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, ped->m_pMyVehicle);
} else {
ped->m_nPedState = PED_NONE;
ped->m_nLastPedState = PED_NONE;
ped->SetFlee(ped->m_pMyVehicle->GetPosition(), 10000);
ped->bUsePedNodeSeek = true;
ped->m_pNextPathNode = nil;
}
ped->SetGetUp();
}
void
CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg)
{
CPed *ped = (CPed*)arg;
CVehicle *veh = ped->m_pMyVehicle;
// Pointless code
if (!veh)
return;
if (veh->IsWrecked() || ped->DyingOrDead())
return;
ped->bInVehicle = true;
if (ped->m_nPedType == PEDTYPE_PROSTITUTE) {
if (veh->pDriver) {
if (veh->pDriver->IsPlayer() && ped->CharCreatedBy == RANDOM_CHAR) {
CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency = 1000;
CWorld::Players[CWorld::PlayerInFocus].m_nNextSexMoneyUpdateTime = CTimer::GetTimeInMilliseconds() + 1000;
CWorld::Players[CWorld::PlayerInFocus].m_nNextSexFrequencyUpdateTime = CTimer::GetTimeInMilliseconds() + 3000;
CWorld::Players[CWorld::PlayerInFocus].m_pHooker = (CCivilianPed*)ped;
}
}
}
if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER)
veh->m_veh_flagC10 = false;
if (veh->m_nNumGettingIn)
--veh->m_nNumGettingIn;
if (ped->IsPlayer() && ((CPlayerPed*)ped)->m_bAdrenalineActive)
((CPlayerPed*)ped)->ClearAdrenaline();
if (veh->IsBoat()) {
if (ped->IsPlayer()) {
if (veh->m_status == STATUS_SIMPLE) {
veh->m_vecMoveSpeed = CVector(0.0f, 0.0f, -0.00001f);
veh->m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f);
}
veh->m_status = STATUS_PLAYER;
AudioManager.PlayerJustGotInCar();
}
veh->SetDriver(ped);
if (!veh->bEngineOn)
veh->bEngineOn = true;
ped->m_nPedState = PED_DRIVING;
ped->StopNonPartialAnims();
return;
}
if (ped->m_pVehicleAnim)
ped->m_pVehicleAnim->blendDelta = -1000.0f;
ped->bDoBloodyFootprints = false;
if (veh->m_nAlarmState == -1)
veh->m_nAlarmState = 15000;
if (ped->IsPlayer()) {
if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) {
if (veh->m_status == STATUS_SIMPLE) {
veh->m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
veh->m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f);
}
veh->m_status = STATUS_PLAYER;
}
AudioManager.PlayerJustGotInCar();
} else if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) {
if (veh->m_status == STATUS_SIMPLE) {
veh->m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
veh->m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f);
}
veh->m_status = STATUS_PHYSICS;
}
if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) {
for (int i = 0; i < veh->m_nNumMaxPassengers; ++i) {
CPed *passenger = veh->pPassengers[i];
if (passenger && passenger->CharCreatedBy == RANDOM_CHAR)
passenger->SetObjective(OBJECTIVE_LEAVE_VEHICLE, veh);
}
} else if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER) {
if (ped->m_nPedState == PED_CARJACK) {
veh->AddPassenger(ped, 0);
ped->m_nPedState = PED_DRIVING;
ped->RestorePreviousObjective();
ped->SetObjective(OBJECTIVE_LEAVE_VEHICLE, veh);
} else if (veh->pDriver && ped->CharCreatedBy == RANDOM_CHAR) {
veh->AutoPilot.m_nCruiseSpeed = 17;
}
}
if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER || ped->m_nPedState == PED_CARJACK) {
veh->SetDriver(ped);
if (veh->VehicleCreatedBy == PARKED_VEHICLE) {
veh->VehicleCreatedBy = RANDOM_VEHICLE;
++CCarCtrl::NumRandomCars;
--CCarCtrl::NumParkedCars;
}
if (veh->bIsAmbulanceOnDuty) {
veh->bIsAmbulanceOnDuty = false;
--CCarCtrl::NumAmbulancesOnDuty;
}
if (veh->bIsFireTruckOnDuty) {
veh->bIsFireTruckOnDuty = false;
--CCarCtrl::NumFiretrucksOnDuty;
}
if (ped->m_nPedType == PEDTYPE_COP && veh->IsLawEnforcementVehicle())
veh->ChangeLawEnforcerState(true);
if (!veh->bEngineOn) {
veh->bEngineOn = true;
DMAudio.PlayOneShot(ped->m_audioEntityId, SOUND_CAR_ENGINE_START, 1.0f);
}
if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER && ped->CharCreatedBy == RANDOM_CHAR
&& ped != FindPlayerPed() && ped->m_nPedType != PEDTYPE_EMERGENCY) {
CCarCtrl::JoinCarWithRoadSystem(veh);
veh->AutoPilot.m_nCarMission = MISSION_CRUISE;
veh->AutoPilot.m_nTempAction = TEMPACT_NONE;
veh->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
veh->AutoPilot.m_nCruiseSpeed = 25;
}
ped->m_nPedState = PED_DRIVING;
if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) {
if (ped->m_prevObjective == OBJECTIVE_RUN_TO_AREA || ped->m_prevObjective == OBJECTIVE_GOTO_CHAR_ON_FOOT || ped->m_prevObjective == OBJECTIVE_KILL_CHAR_ON_FOOT)
ped->m_prevObjective = OBJECTIVE_NONE;
ped->RestorePreviousObjective();
}
} else if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER) {
switch (ped->m_vehEnterType) {
if (!veh->bIsBus) {
case CAR_DOOR_RF:
veh->AddPassenger(ped, 0);
break;
case CAR_DOOR_RR:
veh->AddPassenger(ped, 2);
break;
case CAR_DOOR_LR:
veh->AddPassenger(ped, 1);
break;
}
default:
veh->AddPassenger(ped);
break;
}
ped->m_nPedState = PED_DRIVING;
if (ped->m_prevObjective == OBJECTIVE_RUN_TO_AREA || ped->m_prevObjective == OBJECTIVE_GOTO_CHAR_ON_FOOT || ped->m_prevObjective == OBJECTIVE_KILL_CHAR_ON_FOOT)
ped->m_prevObjective = OBJECTIVE_NONE;
ped->RestorePreviousObjective();
}
veh->m_nGettingInFlags &= ~GetCarDoorFlag(ped->m_vehEnterType);
if (veh->bIsBus && !veh->m_nGettingInFlags)
((CAutomobile*)veh)->SetBusDoorTimer(1000, 1);
switch (ped->m_objective) {
case OBJECTIVE_KILL_CHAR_ON_FOOT:
case OBJECTIVE_KILL_CHAR_ANY_MEANS:
case OBJECTIVE_LEAVE_VEHICLE:
case OBJECTIVE_FOLLOW_CAR_IN_CAR:
case OBJECTIVE_GOTO_AREA_ANY_MEANS:
case OBJECTIVE_GOTO_AREA_ON_FOOT:
case OBJECTIVE_RUN_TO_AREA:
break;
default:
ped->SetObjective(OBJECTIVE_NONE);
}
if (veh->pDriver == ped) {
if (veh->bLowVehicle) {
ped->m_pVehicleAnim = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_LSIT, 100.0f);
} else {
ped->m_pVehicleAnim = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_SIT, 100.0f);
}
} else if (veh->bLowVehicle) {
ped->m_pVehicleAnim = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_SITPLO, 100.0f);
} else {
ped->m_pVehicleAnim = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_SITP, 100.0f);
}
ped->StopNonPartialAnims();
if (veh->bIsBus)
ped->bRenderPedInCar = false;
// FIX: RegisterVehicleOfInterest not just registers the vehicle, but also updates register time. So remove the IsThisVehicleInteresting check.
#ifndef FIX_BUGS
if (ped->IsPlayer() && !CCarCtrl::IsThisVehicleInteresting(veh) && veh->VehicleCreatedBy != MISSION_VEHICLE) {
#else
if (ped->IsPlayer() && veh->VehicleCreatedBy != MISSION_VEHICLE) {
#endif
CCarCtrl::RegisterVehicleOfInterest(veh);
if (!veh->bHasBeenOwnedByPlayer && veh->VehicleCreatedBy != MISSION_VEHICLE)
CEventList::RegisterEvent(EVENT_STEAL_CAR, EVENT_ENTITY_VEHICLE, veh, ped, 1500);
veh->bHasBeenOwnedByPlayer = true;
}
ped->bChangedSeat = true;
}
void
CPed::PedSetInTrainCB(CAnimBlendAssociation* animAssoc, void* arg)
{
CPed* ped = (CPed*)arg;
CVehicle* veh = ped->m_pMyVehicle;
if (!veh)
return;
ped->bInVehicle = true;
ped->m_nPedState = PED_DRIVING;
ped->RestorePreviousObjective();
ped->SetMoveState(PEDMOVE_STILL);
veh->AddPassenger(ped);
}
WRAPPER void CPed::PedStaggerCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4CE8D0); }
WRAPPER void CPed::PedEvadeCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4D36E0); }
WRAPPER void CPed::PedSetInCarCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4CF220); }
WRAPPER void CPed::PedSetOutCarCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4CE8F0); }
WRAPPER void CPed::PedSetQuickDraggedOutCarPositionCB(CAnimBlendAssociation *dragAssoc, void *arg) { EAXJMP(0x4E2480); }
WRAPPER void CPed::PedSetDraggedOutCarPositionCB(CAnimBlendAssociation *dragAssoc, void *arg) { EAXJMP(0x4E2920); }
WRAPPER void CPed::PedSetInTrainCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4E3290); }
WRAPPER void CPed::PedSetOutTrainCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4E36E0); }
WRAPPER void CPed::PedLandCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x4CE8A0); }
class CPed_ : public CPed
{
@ -10677,4 +11048,10 @@ STARTPATCHES
InjectHook(0x4DEC80, &CPed::PedAnimGetInCB, PATCH_JUMP);
InjectHook(0x4DEAF0, &CPed::PedAnimPullPedOutCB, PATCH_JUMP);
InjectHook(0x4DF5C0, &CPed::PedAnimStepOutCarCB, PATCH_JUMP);
InjectHook(0x4D36E0, &CPed::PedEvadeCB, PATCH_JUMP);
InjectHook(0x4CE810, &CPed::PedGetupCB, PATCH_JUMP);
InjectHook(0x4CE8A0, &CPed::PedLandCB, PATCH_JUMP);
InjectHook(0x4E2920, &CPed::PedSetDraggedOutCarPositionCB, PATCH_JUMP);
InjectHook(0x4CF220, &CPed::PedSetInCarCB, PATCH_JUMP);
InjectHook(0x4E3290, &CPed::PedSetInTrainCB, PATCH_JUMP);
ENDPATCHES

View File

@ -277,7 +277,7 @@ public:
uint8 bIsLanding : 1;
uint8 bIsRunning : 1; // on some conditions
uint8 bHitSomethingLastFrame : 1;
uint8 m_ped_flagB80 : 1; // something related with reaction to colliding vehicle
uint8 m_ped_flagB80 : 1; // bIsNearCar? something related with reaction to colliding vehicle
uint8 m_ped_flagC1 : 1;
uint8 bRespondsToThreats : 1;
@ -288,9 +288,9 @@ public:
uint8 m_ped_flagC40 : 1;
uint8 bFindNewNodeAfterStateRestore : 1;
uint8 m_ped_flagD1 : 1; // so far only used for reaction type to fire/explosion
uint8 m_ped_flagD2 : 1; // set when event has been seen
uint8 m_ped_flagD4 : 1; // so far only creates blood pool in hands up state
uint8 bHasACamera : 1; // does ped possess a camera to document accidents involves fire/explosion
uint8 m_ped_flagD2 : 1; // set when ped witnessed an event
uint8 m_ped_flagD4 : 1; // bPedIsBleeding? so far only creates blood pool in hands up state
uint8 m_ped_flagD8 : 1;
uint8 bIsPedDieAnimPlaying : 1;
uint8 bUsePedNodeSeek : 1;
@ -304,11 +304,11 @@ public:
uint8 bIsDucking : 1;
uint8 bGetUpAnimStarted : 1;
uint8 bDoBloodyFootprints : 1;
uint8 m_ped_flagE80 : 1; // bDontDragMeOutCar? bStayInCarOnJack?
uint8 bFleeAfterExitingCar : 1;
uint8 bWanderPathAfterExitingCar : 1;
uint8 m_ped_flagF2 : 1;
uint8 m_ped_flagF4 : 1; // Unfinished feature from VC
uint8 m_ped_flagF4 : 1; // Unfinished feature from VC, probably bDontDragMeOutCar
uint8 m_ped_flagF8 : 1;
uint8 bWillBeQuickJacked : 1;
uint8 bCancelEnteringCar : 1; // after door is opened or couldn't be opened due to it's locked
@ -317,14 +317,14 @@ public:
uint8 m_ped_flagG1 : 1;
uint8 m_ped_flagG2 : 1;
uint8 m_ped_flagG4 : 1;
uint8 m_ped_flagG4 : 1; // bStillOnValidPoly?
uint8 bStartWanderPathOnFoot : 1; // exits the car if he's in it, reset after path found
uint8 m_ped_flagG10 : 1;
uint8 m_ped_flagG10 : 1; // bOnBoat? (but not in the sense of driving)
uint8 bBusJacked : 1;
uint8 m_ped_flagG40 : 1; // had to exit car due to someone jacked it from RF door
uint8 bGonnaKillTheCarJacker : 1; // only set when car is jacked from right door
uint8 bFadeOut : 1;
uint8 m_ped_flagH1 : 1;
uint8 bKnockedUpIntoAir : 1; // has ped been knocked up into the air by a car collision
uint8 m_ped_flagH2 : 1;
uint8 m_ped_flagH4 : 1;
uint8 bClearObjective : 1;
@ -645,6 +645,7 @@ public:
void ReactToPointGun(CEntity*);
void SeekCar(void);
void SeekBoatPosition(void);
bool PositionPedOutOfCollision(void);
// Static methods
static CVector GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float offset);
@ -722,6 +723,7 @@ public:
RwFrame *GetNodeFrame(int nodeId) { return m_pFrames[nodeId]->frame; }
PedState GetPedState(void) { return m_nPedState; }
void SetPedState(PedState state) { m_nPedState = state; }
bool DyingOrDead(void) { return m_nPedState == PED_DIE || m_nPedState == PED_DEAD; }
// set by 0482:set_threat_reaction_range_multiplier opcode
static uint16 &nThreatReactionRangeMultiplier;

View File

@ -94,6 +94,15 @@ CPlayerPed::AnnoyPlayerPed(bool annoyedByPassingEntity)
}
}
void
CPlayerPed::ClearAdrenaline(void)
{
if (m_bAdrenalineActive && m_nAdrenalineTime != 0) {
m_nAdrenalineTime = 0;
CTimer::SetTimeStep(1.0f);
}
}
class CPlayerPed_ : public CPlayerPed
{
public:

View File

@ -29,7 +29,7 @@ public:
bool m_bHasLockOnTarget;
int8 field_1406;
int8 field_1407;
uint32 m_bAdrenalineTime;
uint32 m_nAdrenalineTime;
bool m_bCanBeDamaged;
int8 field_1413;
int8 field_1414;
@ -52,6 +52,7 @@ public:
void SetInitialState(void);
void SetMoveAnim(void);
void ProcessControl(void);
void ClearAdrenaline(void);
static void SetupPlayerPed(int32);
static void DeactivatePlayerPed(int32);

View File

@ -269,7 +269,7 @@ public:
bool ShufflePassengersToMakeSpace(void);
bool IsAlarmOn(void) { return m_nAlarmState != 0 && m_nAlarmState != -1; }
bool IsWrecked(void) { return !this || m_status == STATUS_WRECKED; }
CVehicleModelInfo* GetModelInfo() { return (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex()); }
static bool &bWheelsOnlyCheat;