etqw-sdk/source/game/physics/Physics_Player.h

388 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__ */