Files
expvintl 419f2e4752 init
2025-02-23 17:40:52 +08:00

259 lines
7.7 KiB
C++

// Filename : TaskNMHighFall.h
// Description: Natural Motion high fall class (FSM version)
#ifndef INC_TASKNMHIGHFALL_H_
#define INC_TASKNMHIGHFALL_H_
// --- Include Files ------------------------------------------------------------
// Game headers
#include "Task/System/Task.h"
#include "Task\System\TaskTypes.h"
#include "Task/Physics/TaskNM.h"
#include "Task/Physics/TaskNMBrace.h"
#include "Task/Physics/GrabHelper.h"
// ------------------------------------------------------------------------------
// high fall
// triggers: fall from a height to try and land on feet
//
class CTaskNMHighFall : public CTaskNMBehaviour
{
public:
struct Tunables : CTuning
{
Tunables();
s32 m_HighFallTimeToBlockInjuredOnGround;
CTaskNMBehaviour::Tunables::TunableForce m_PitchInDirectionForce;
s32 m_PitchInDirectionComponent;
CTaskNMBehaviour::Tunables::TunableForce m_StuntJumpPitchInDirectionForce;
s32 m_StuntJumpPitchInDirectionComponent;
CNmTuningSet m_Start;
CNmTuningSet m_Update;
// contextual modifiers for the start message
CNmTuningSet m_InAir;
CNmTuningSet m_Vault;
CNmTuningSet m_FromCarHit;
CNmTuningSet m_SlopeSlide;
CNmTuningSet m_TeeterEdge;
CNmTuningSet m_StuntJump;
CNmTuningSet m_SprintExhausted;
CNmTuningSet m_OnBalanceFailedSprintExhausted;
bool m_DisableStartMessageForSprintExhausted;
CNmTuningSet m_JumpCollision;
CNmTuningSet m_HighHighFallStart;
CNmTuningSet m_HighHighFallEnd;
CNmTuningSet m_SuperHighFallStart;
CTaskNMBehaviour::Tunables::StandardBlendOutThresholds m_BlendOut;
CTaskNMBehaviour::Tunables::BlendOutThreshold m_PlayerQuickBlendOut;
CTaskNMBehaviour::Tunables::BlendOutThreshold m_MpPlayerQuickBlendOut;
float m_MaxHealthLossForQuickGetup;
float m_MinHealthForQuickGetup;
float m_MpMaxHealthLossForQuickGetup;
float m_MpMinHealthForQuickGetup;
bool m_UseRemainingMinTimeForGroundWrithe;
u32 m_MinTimeRemainingForGroundWrithe;
u32 m_MinTimeElapsedForGroundWrithe;
float m_DistanceZThresholdForHighHighFall;
float m_VelocityZThresholdForHighHighFall;
float m_VelocityZThresholdForSuperHighFall;
float m_RagdollComponentAirResistanceMinStiffness[RAGDOLL_NUM_JOINTS];
float m_RagdollComponentAirResistanceForce[RAGDOLL_NUM_COMPONENTS];
u8 m_AirResistanceOption;
#if __BANK
void PreAddWidgets(bkBank& bank);
#endif
PAR_PARSABLE;
};
enum eHighFallEntryType { // keep in sync with commands_task.sch - HIGH_FALL_ENTRY_TYPE
HIGHFALL_IN_AIR,
HIGHFALL_VAULT,
HIGHFALL_FROM_CAR_HIT,
HIGHFALL_SLOPE_SLIDE,
HIGHFALL_TEETER_EDGE,
HIGHFALL_SPRINT_EXHAUSTED,
HIGHFALL_STUNT_JUMP,
HIGHFALL_JUMP_COLLISION,
NUM_HIGHFALL_TYPES
};
#if !__FINAL
static const char * GetEntryTypeName(eHighFallEntryType type)
{
static const char* s_EntryTypeNames[NUM_HIGHFALL_TYPES] =
{
"HIGHFALL_IN_AIR",
"HIGHFALL_VAULT",
"HIGHFALL_FROM_CAR_HIT",
"HIGHFALL_SLOPE_SLIDE",
"HIGHFALL_TEETER_EDGE",
"HIGHFALL_SPRINT_EXHAUSTED",
"HIGHFALL_STUNT_JUMP",
"HIGHFALL_JUMP_COLLISION",
};
if (type>=HIGHFALL_IN_AIR && type < NUM_HIGHFALL_TYPES)
return s_EntryTypeNames[type];
else
return "UNKNOWN ENTRY TYPE!";
}
#endif // !__FINAL
CTaskNMHighFall(u32 nMinTime, const CGrabHelper* pGrabHelper=NULL, eHighFallEntryType eType = HIGHFALL_IN_AIR, const Vector3 *pitchDirOverride = NULL, bool blockEarlyGetup = false);
~CTaskNMHighFall();
protected:
CTaskNMHighFall(const CTaskNMHighFall& otherTask);
public:
void SetPitchDirectionOverride(const Vector3 &vel) { m_PitchDirOverride = vel; }
void SetEntryType(eHighFallEntryType eType) { m_eType = eType; }
eHighFallEntryType GetEntryType() const { return m_eType; }
bool HasBalanceFailed() const { return m_bBalanceFailed; }
virtual void CleanUp();
virtual bool IsInScope(const CPed* pPed);
virtual bool HandlesDeadPed(){ return true; }
virtual bool ShouldContinueAfterDeath() const {return true;}
bool HandleRagdollImpact(float fMag, const CEntity* pEntity, const Vector3& vPedNormal, int nComponent, phMaterialMgr::Id nMaterialId);
virtual bool ShouldAbortForWeaponDamage(CEntity* UNUSED_PARAM(pFiringEntity), const CWeaponInfo* pWeaponInfo, const f32 UNUSED_PARAM(fWeaponDamage), const fwFlags32& UNUSED_PARAM(flags),
const bool UNUSED_PARAM(bWasKilledOrInjured), const Vector3& UNUSED_PARAM(vStart), WorldProbe::CShapeTestHitPoint* UNUSED_PARAM(pResult),
const Vector3& UNUSED_PARAM(vRagdollImpulseDir), const f32 UNUSED_PARAM(fRagdollImpulseMag))
{
// Don't abort high fall for unknown damage, even when dead (because we're going to continue running after death)
if (pWeaponInfo->GetDamageType() == DAMAGE_TYPE_UNKNOWN)
{
return false;
}
else
{
return true;
}
}
////////////////////////
// CTaskSimple functions
#if !__FINAL
virtual atString GetName() const {return m_strTaskAndStateName;}
#endif
virtual aiTask* Copy() const {return rage_new CTaskNMHighFall(*this);}
virtual int GetTaskTypeInternal() const {return CTaskTypes::TASK_NM_HIGH_FALL;}
////////////////////////
// CTaskFSMClone functions
virtual CTaskInfo* CreateQueriableState() const;
void SetMaxTime(u16 maxTime) { m_nMaxTime = maxTime; }
///////////////////////////
// CTaskNMBehaviour functions
virtual void BehaviourFailure(CPed* pPed, ARTFeedbackInterfaceGta* pFeedbackInterface);
virtual void BehaviourSuccess(CPed* pPed, ARTFeedbackInterfaceGta* pFeedbackInterface);
virtual void BehaviourFinish(CPed* pPed, ARTFeedbackInterfaceGta* pFeedbackInterface);
virtual void BehaviourEvent(CPed* pPed, ARTFeedbackInterfaceGta* pFeedbackInterface);
virtual bool ProcessPhysics(float fTimeStep, int nTimeSlice);
bool GetIsNetworkBlenderOffForHighFall() {return m_bNetworkBlenderOffForHighFall;}
protected:
virtual void StartBehaviour(CPed* pPed);
virtual void ControlBehaviour(CPed* pPed);
virtual bool FinishConditions(CPed* pPed);
virtual void StartAnimatedFallback(CPed* pPed);
virtual bool ControlAnimatedFallback(CPed* pPed);
virtual void AddStartMessages(CPed* pPed, CNmMessageList& list);
//////////////////////////
// Local functions and data
CGrabHelper& GetGrabHelper() {return m_GrabHelper;}
private:
bool m_bDoingHighHighFall : 1;
bool m_bDoingSuperHighFall : 1;
bool m_bNetworkBlenderOffForHighFall : 1; //latched true if the task sees a fall greater than the m_bDoingHighHighFall test height to prevent clone warp corrections while falling from great heights
bool m_bBalanceFailed : 1;
bool m_foundgrab : 1;
bool m_SideStabilizationApplied : 1;
bool m_BlockEarlyGetup : 1;
bool m_bUsePitchInDirectionForce : 1;
float m_StartingHealth;
Vector3 m_PitchDirOverride;
CGrabHelper m_GrabHelper;
eHighFallEntryType m_eType;
#if !__FINAL
// For debugging the internal state machine.
atString m_strTaskAndStateName;
#endif // !__FINAL
// tunable by widgets
public:
static const char* ms_TypeToString[NUM_HIGHFALL_TYPES];
static Tunables sm_Tunables;
};
//
// Task info for CTaskNMHighFall
//
class CClonedNMHighFallInfo : public CSerialisedFSMTaskInfo
{
public:
CClonedNMHighFallInfo(u32 highFallType);
CClonedNMHighFallInfo();
~CClonedNMHighFallInfo() {}
virtual s32 GetTaskInfoType( ) const {return INFO_TYPE_NM_HIGHFALL;}
// the clone task is created by the CTaskNMControl clone task
virtual bool AutoCreateCloneTask(CPed* UNUSED_PARAM(pPed)) { return false; }
virtual CTaskFSMClone *CreateCloneFSMTask();
void Serialise(CSyncDataBase& serialiser)
{
CSerialisedFSMTaskInfo::Serialise(serialiser);
SERIALISE_UNSIGNED(serialiser, m_highFallType, SIZEOF_HIGHFALL_TYPE, "High fall type");
}
private:
CClonedNMHighFallInfo(const CClonedNMHighFallInfo &);
CClonedNMHighFallInfo &operator=(const CClonedNMHighFallInfo &);
static const unsigned int SIZEOF_HIGHFALL_TYPE = datBitsNeeded<CTaskNMHighFall::NUM_HIGHFALL_TYPES>::COUNT;
u32 m_highFallType;
};
#endif // ! INC_TASKNMHIGHFALL_H_