387 lines
14 KiB
C++
387 lines
14 KiB
C++
// Copyright (C) 2007 Id Software, Inc.
|
|
//
|
|
|
|
#ifndef __PHYSICS_PLAYER_H__
|
|
#define __PHYSICS_PLAYER_H__
|
|
|
|
/*
|
|
===================================================================================
|
|
|
|
Player physics
|
|
|
|
Simulates the motion of a player through the environment. Input from the
|
|
player is used to allow a certain degree of control over the motion.
|
|
|
|
===================================================================================
|
|
*/
|
|
|
|
#include "Physics_Actor.h"
|
|
|
|
class sdLadderEntity;
|
|
|
|
extern const idBounds playerProneLegsBounds;
|
|
|
|
// movementFlags
|
|
const int PMF_DUCKED = 0x00000001; // set when ducking
|
|
const int PMF_JUMPED = 0x00000002; // set when the player jumped this frame
|
|
const int PMF_STEPPED_UP = 0x00000004; // set when the player stepped up this frame
|
|
const int PMF_STEPPED_DOWN = 0x00000008; // set when the player stepped down this frame
|
|
const int PMF_JUMP_HELD = 0x00000010; // set when jump button is held down
|
|
const int PMF_TIME_LAND = 0x00000020; // movementTime is time before rejump
|
|
const int PMF_TIME_KNOCKBACK = 0x00000040; // movementTime is an air-accelerate only time
|
|
const int PMF_TIME_WATERJUMP = 0x00000080; // movementTime is waterjump
|
|
const int PMF_PRONE = 0x00000100;
|
|
const int PMF_CROUCH_HELD = 0x00000200; // set when crouch button is held down
|
|
const int PMF_ALL_TIMES = (PMF_TIME_WATERJUMP|PMF_TIME_LAND|PMF_TIME_KNOCKBACK);
|
|
|
|
// movementType
|
|
typedef enum {
|
|
PM_NORMAL, // normal physics
|
|
PM_DEAD, // no acceleration or turning, but free falling
|
|
PM_SPECTATOR, // flying without gravity but with collision detection
|
|
PM_FREEZE, // stuck in place without control
|
|
PM_NOCLIP, // flying without collision detection nor gravity
|
|
} pmtype_t;
|
|
|
|
typedef enum {
|
|
WATERLEVEL_NONE,
|
|
WATERLEVEL_FEET,
|
|
WATERLEVEL_WAIST,
|
|
WATERLEVEL_HEAD
|
|
} waterLevel_t;
|
|
|
|
enum proneResult_t {
|
|
PR_FAILED = BITT< 0 >::VALUE,
|
|
PR_BREAK = BITT< 1 >::VALUE,
|
|
PR_NOGROUND = BITT< 2 >::VALUE,
|
|
};
|
|
|
|
#define MAXTOUCH 32
|
|
|
|
typedef struct playerPState_s {
|
|
idVec3 origin;
|
|
idVec3 velocity;
|
|
idVec3 pushVelocity;
|
|
float stepUp;
|
|
float proneOffset;
|
|
int movementType;
|
|
int movementFlags;
|
|
int movementTime;
|
|
} playerPState_t;
|
|
|
|
class sdPlayerPhysicsNetworkData : public sdEntityStateNetworkData {
|
|
public:
|
|
sdPlayerPhysicsNetworkData( void ) { ; }
|
|
|
|
virtual void MakeDefault( void );
|
|
|
|
virtual void Write( idFile* file ) const;
|
|
virtual void Read( idFile* file );
|
|
|
|
idVec3 origin;
|
|
idVec3 velocity;
|
|
int movementTime;
|
|
int movementFlags;
|
|
};
|
|
|
|
class sdPlayerPhysicsBroadcastData : public sdEntityStateNetworkData {
|
|
public:
|
|
sdPlayerPhysicsBroadcastData( void ) { ; }
|
|
|
|
virtual void MakeDefault( void );
|
|
|
|
virtual void Write( idFile* file ) const;
|
|
virtual void Read( idFile* file );
|
|
|
|
idVec3 pushVelocity;
|
|
idVec3 localOrigin;
|
|
bool frozen;
|
|
int proneChangeEndTime;
|
|
int jumpAllowedTime;
|
|
};
|
|
|
|
class idPhysics_Player : public idPhysics_Actor {
|
|
public:
|
|
CLASS_PROTOTYPE( idPhysics_Player );
|
|
|
|
enum proneTimes_t { PT_STAND_TO_PRONE, PT_CROUCH_TO_PRONE, PT_PRONE_TO_CROUCH, PT_PRONE_TO_STAND, PT_MAX };
|
|
|
|
idPhysics_Player( void );
|
|
virtual ~idPhysics_Player( void );
|
|
|
|
// initialisation
|
|
void SetSpeed( float newWalkSpeedFwd, float newWalkSpeedBack, float newWalkSpeedSide, float newCrouchSpeed, float newProneSpeed );
|
|
void SetMaxStepHeight( const float newMaxStepHeight );
|
|
float GetMaxStepHeight( void ) const;
|
|
void SetMaxJumpHeight( const float newMaxJumpHeight );
|
|
void SetMovementType( const pmtype_t type );
|
|
void SetPlayerInput( const usercmd_t& cmd, const idAngles &newViewAngles, bool allowMovement );
|
|
void SetKnockBack( const int knockBackTime );
|
|
// feed back from last physics frame
|
|
const idVec3& PlayerGetOrigin( void ) const; // != GetOrigin
|
|
|
|
void SetupPlayerClipModels();
|
|
void SetupVehicleClipModels( float playerHeight );
|
|
|
|
virtual int VehiclePush( bool stuck, float timeDelta, idVec3& move, idClipModel* pusher, int pushCount );
|
|
|
|
static void SetupUsercmdForDirection( const idVec2 &dir, float forwardSpeed, float backwardSpeed, float sideSpeed, usercmd_t &cmd );
|
|
|
|
public: // common physics interface
|
|
bool Evaluate( int timeStepMSec, int endTimeMSec );
|
|
void UpdateTime( int endTimeMSec );
|
|
int GetTime( void ) const;
|
|
|
|
void GetImpactInfo( const int id, const idVec3 &point, impactInfo_t *info ) const;
|
|
void ApplyImpulse( const int id, const idVec3 &point, const idVec3 &impulse );
|
|
bool IsAtRest( void ) const;
|
|
int GetRestStartTime( void ) const;
|
|
|
|
void SaveState( void );
|
|
void RestoreState( void );
|
|
|
|
void SetOrigin( const idVec3 &newOrigin, int id = -1 );
|
|
void SetAxis( const idMat3 &newAxis, int id = -1 );
|
|
|
|
void SetContents( int contents, int id = -1 );
|
|
idClipModel* GetClipModel( int id = 0 ) const;
|
|
|
|
void Translate( const idVec3 &translation, int id = -1 );
|
|
void Rotate( const idRotation &rotation, int id = -1 );
|
|
|
|
void SetLinearVelocity( const idVec3 &newLinearVelocity, int id = 0 );
|
|
|
|
const idVec3 & GetLinearVelocity( int id = 0 ) const;
|
|
|
|
void SetPushed( int deltaTime );
|
|
const idVec3 & GetPushedLinearVelocity( const int id = 0 ) const;
|
|
void ClearPushedVelocity( void );
|
|
|
|
static void CalcSpectateBounds( idBounds& bounds );
|
|
static void CalcNormalBounds( idBounds& bounds );
|
|
|
|
const idVec3& GetGroundNormal( void ) const { return groundTrace.c.normal; }
|
|
bool EvaluateContacts( CLIP_DEBUG_PARMS_DECLARATION_ONLY );
|
|
|
|
void SetMaster( idEntity *master, const bool orientated = true );
|
|
|
|
virtual const idVec3& GetOrigin( int id = -1 ) const;
|
|
|
|
virtual void SetSelf( idEntity *e );
|
|
|
|
virtual void ApplyNetworkState( networkStateMode_t mode, const sdEntityStateNetworkData& newState );
|
|
virtual bool CheckNetworkStateChanges( networkStateMode_t mode, const sdEntityStateNetworkData& baseState ) const;
|
|
virtual void WriteNetworkState( networkStateMode_t mode, const sdEntityStateNetworkData& baseState, sdEntityStateNetworkData& newState, idBitMsg& msg ) const;
|
|
virtual void ReadNetworkState( networkStateMode_t mode, const sdEntityStateNetworkData& baseState, sdEntityStateNetworkData& newState, const idBitMsg& msg ) const;
|
|
virtual void ResetNetworkState( networkStateMode_t mode, const sdEntityStateNetworkData& newState );
|
|
virtual sdEntityStateNetworkData* CreateNetworkStructure( networkStateMode_t mode ) const;
|
|
|
|
virtual float InWater( void ) const { return waterFraction; }
|
|
|
|
waterLevel_t GetWaterLevel( void ) const { return waterLevel; }
|
|
bool HasJumped( void ) const { return ( ( current.movementFlags & PMF_JUMPED ) != 0 ); }
|
|
bool HasSteppedUp( void ) const { return ( ( current.movementFlags & ( PMF_STEPPED_UP | PMF_STEPPED_DOWN ) ) != 0 ); }
|
|
float GetStepUp( void ) const { return current.stepUp; }
|
|
bool IsCrouching( void ) const { return ( ( current.movementFlags & PMF_DUCKED ) != 0 ); }
|
|
bool IsProne( void ) const { return ( ( current.movementFlags & PMF_PRONE ) != 0 ); }
|
|
bool OnLadder( void ) const;
|
|
idVec3 GetLadderNormal( void ) const;
|
|
void SetFrozen( bool _frozen ) { frozen = _frozen; }
|
|
bool IsFrozen( void ) const { return frozen; }
|
|
bool IsGrounded( void ) const { return groundPlane; }
|
|
|
|
bool IsLeaning( void ) const { return ( leanOffset != 0.0f ) ? true : false; }
|
|
|
|
void EnterProne( void );
|
|
bool LeaveProne( bool crouch );
|
|
void ResetProne( void );
|
|
|
|
void CheckLean( bool allow );
|
|
|
|
void SetGroundAccel( float value ) { pm_accelerate = value; }
|
|
void SetAirAccel( float value ) { pm_airAccelerate = value; }
|
|
void SetWaterAccel( float value ) { pm_waterAccelerate = value; }
|
|
void SetFlyAccel( float value ) { pm_flyAccelerate = value; }
|
|
|
|
float GetCurrentAimSpeed( void ) const { return playerSpeed; }
|
|
|
|
void SetGroundFriction( float value ) { pm_friction = value; }
|
|
void SetAirFriction( float value ) { pm_airFriction = value; }
|
|
void SetWaterFriction( float value ) { pm_waterFriction = value; }
|
|
void SetFlyGroundFriction( float value ) { pm_flyFriction = value; }
|
|
void SetNoclipFriction( float value ) { pm_noclipFriction = value; }
|
|
|
|
|
|
idVec3 GetProneLegsPos( const idVec3& startOrg, const idAngles& angles ) const;
|
|
const idVec3& GetProneOffset( void ) const { return proneModelOffset; }
|
|
int ProneCheck( const idVec3& startOrg, const idAngles& angles, float* offset = NULL, idVec3* modelOffset = NULL ) const;
|
|
int GetProneChangeEndTime( void ) const { return proneChangeEndTime; }
|
|
|
|
void SetProneTime( proneTimes_t proneTime, int valueMS ) { assert( proneTime < PT_MAX ); proneTimes[ proneTime ] = valueMS; }
|
|
int GetProneTime( proneTimes_t proneTime ) { assert( proneTime < PT_MAX ); return proneTimes[ proneTime ]; }
|
|
|
|
float GetLeanOffset( void ) const { return leanOffset; }
|
|
|
|
bool TryProne( void );
|
|
|
|
void UpdateBounds( void );
|
|
|
|
void UpdateCollisionMerge( void );
|
|
void ResetCollisionMerge( const idVec3& origin );
|
|
|
|
const idClipModel* GetNormalClipModel( void ) const { return clipModel_normal; }
|
|
const idClipModel* GetCrouchClipModel( void ) const { return clipModel_crouch; }
|
|
const idClipModel* GetProneClipModel( void ) const { return clipModel_prone; }
|
|
const idClipModel* GetProneLegsClipModel( void ) const { return proneLegsClipModel; }
|
|
const idClipModel* GetHeadClipModel( void ) const { return headClipModel; }
|
|
|
|
void EnableHeadClipModel( void );
|
|
void DisableHeadClipModel( void );
|
|
|
|
// getters for antilag
|
|
float GetGroundAccel( void ) const { return pm_accelerate; }
|
|
float GetAirAccel( void ) const { return pm_airAccelerate; }
|
|
float GetGroundFriction( void ) const { return pm_friction; }
|
|
float GetAirFriction( void ) const { return pm_airFriction; }
|
|
float GetWaterFriction( void ) const { return pm_waterFriction; }
|
|
float GetStopSpeed( void ) const { return pm_stopSpeed; }
|
|
float GetSwimScale( void ) const { return pm_swimScale; }
|
|
float GetWalkSpeedFwd( void ) const { return walkSpeedFwd; }
|
|
float GetWalkSpeedBack( void ) const { return walkSpeedBack; }
|
|
float GetWalkSpeedSide( void ) const { return walkSpeedSide; }
|
|
idAngles GetViewAngles( void ) const { return viewAngles; }
|
|
float GetLastSnapshotTime( void ) const { return lastSnapshotTime; }
|
|
|
|
protected:
|
|
// player physics state
|
|
playerPState_t current;
|
|
playerPState_t saved;
|
|
idVec3 localOrigin;
|
|
|
|
// collision merging state & flags
|
|
idVec3 lastClippedOrigin;
|
|
int numMergedFrames;
|
|
bool mergeThisFrame;
|
|
bool skipContactsThisFrame;
|
|
|
|
// properties
|
|
float walkSpeedFwd;
|
|
float walkSpeedBack;
|
|
float walkSpeedSide;
|
|
float crouchSpeed;
|
|
float proneSpeed;
|
|
float maxStepHeight;
|
|
float maxJumpHeight;
|
|
|
|
idClipModel* proneLegsClipModel;
|
|
idClipModel* shotClipModel;
|
|
idClipModel* headClipModel;
|
|
|
|
void BuildClipModel( const idBounds& bounds, bool useCylinder, idClipModel*& model );
|
|
idClipModel* clipModel_normal;
|
|
idClipModel* clipModel_normalShot;
|
|
idClipModel* clipModel_crouch;
|
|
idClipModel* clipModel_crouchShot;
|
|
idClipModel* clipModel_prone;
|
|
idClipModel* clipModel_proneShot;
|
|
idClipModel* clipModel_dead;
|
|
idClipModel* clipModel_deadShot;
|
|
idClipModel* clipModel_vehicle;
|
|
idClipModel* clipModel_vehicleShot;
|
|
idClipModel* groundCheckModel;
|
|
|
|
idPlayer* playerSelf;
|
|
|
|
int proneChangeEndTime;
|
|
|
|
// player input
|
|
usercmd_t command;
|
|
idAngles viewAngles;
|
|
bool movementAllowed;
|
|
|
|
// run-time variables
|
|
int framemsec;
|
|
float frametime;
|
|
float playerSpeed;
|
|
idVec3 viewForward;
|
|
idVec3 viewRight;
|
|
float leanFraction;
|
|
float leanOffset;
|
|
|
|
// walk movement
|
|
bool walking;
|
|
bool groundPlane;
|
|
trace_t groundTrace;
|
|
const idMaterial* groundMaterial;
|
|
|
|
idVec3 proneModelOffset;
|
|
|
|
// ladder movement
|
|
idEntityPtr< sdLadderEntity > ladder;
|
|
|
|
// results of last evaluate
|
|
waterLevel_t waterLevel;
|
|
float waterFraction;
|
|
float waterHeightAboveGround;
|
|
|
|
//
|
|
bool frozen;
|
|
|
|
float pm_stopSpeed;
|
|
float pm_swimScale;
|
|
float pm_ladderSpeed;
|
|
float pm_stepScale;
|
|
|
|
float pm_accelerate;
|
|
float pm_airAccelerate;
|
|
float pm_waterAccelerate;
|
|
float pm_flyAccelerate;
|
|
|
|
float pm_friction;
|
|
float pm_airFriction;
|
|
float pm_waterFriction;
|
|
float pm_flyFriction;
|
|
float pm_noclipFriction;
|
|
|
|
int proneTimes[ PT_MAX ];
|
|
|
|
int jumpAllowedTime;
|
|
|
|
int lastSnapshotTime;
|
|
|
|
public:
|
|
static idVec3 AdjustVertically( const idVec3 &normal, const idVec3 &_in );
|
|
|
|
static void CalcDesiredWalkMove( int fwd, int right, float walkSpeedFwd, float walkSpeedSide, float walkSpeedBack, idVec2& output );
|
|
|
|
protected:
|
|
bool CanCrouch( void );
|
|
bool CanProne( void );
|
|
float CmdScale( const usercmd_t& cmd, bool noVertical ) const;
|
|
idVec2 CalcDesiredWalkMove( const usercmd_t& cmd ) const;
|
|
void Accelerate( const idVec3 &wishdir, const float wishspeed, const float accel );
|
|
bool SlideMove( bool gravity, bool stepUp, bool stepDown, bool push, int vehiclePush );
|
|
void Friction( void );
|
|
void WaterJumpMove( void );
|
|
virtual void WaterMove( void );
|
|
virtual void FlyMove( void );
|
|
virtual void AirMove( bool allowLean );
|
|
virtual void WalkMove( bool allowLean );
|
|
virtual void DeadMove( void );
|
|
virtual void NoclipMove( void );
|
|
virtual void SpectatorMove( void );
|
|
virtual void LadderMove( void );
|
|
void CorrectAllSolid( trace_t &trace, int contents );
|
|
void FinishProneChange( void );
|
|
virtual void CheckGround( void );
|
|
virtual void CheckStance( void );
|
|
sdLadderEntity* FindLadder( const idVec3& origin, sdLadderEntity** ladders, int numLadders, const idVec3& direction );
|
|
virtual void CheckLadder( void );
|
|
virtual bool CheckJump( void );
|
|
virtual bool CheckWaterJump( void );
|
|
void SetWaterLevel( void );
|
|
void DropTimers( void );
|
|
void MovePlayer( int msec );
|
|
};
|
|
|
|
#endif /* !__PHYSICS_PLAYER_H__ */
|