238 lines
6.7 KiB
C
238 lines
6.7 KiB
C
|
// Copyright (C) 2007 Id Software, Inc.
|
||
|
//
|
||
|
|
||
|
#ifndef __GAME_ANTILAG_H__
|
||
|
#define __GAME_ANTILAG_H__
|
||
|
|
||
|
static const int MAX_ANTILAG_SETS = 48;
|
||
|
static const int MAX_ANTILAG_POINTS = 20;
|
||
|
|
||
|
// #define ANTILAG_LOGGING
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
|
||
|
sdAntiLagSet
|
||
|
Set of points the player could be at after continuing moving from one branch point
|
||
|
|
||
|
===============================================================================
|
||
|
*/
|
||
|
class sdAntiLagEntity;
|
||
|
|
||
|
class sdAntiLagSet {
|
||
|
public:
|
||
|
sdAntiLagSet();
|
||
|
|
||
|
virtual void Reset();
|
||
|
virtual void Setup( sdAntiLagEntity& antiLagEntity );
|
||
|
virtual void Setup( sdAntiLagEntity& antiLagEntity, sdAntiLagSet& baseSet );
|
||
|
virtual void Update() = 0;
|
||
|
virtual void DebugDraw();
|
||
|
|
||
|
const idVec3* GetPointForTime( int time );
|
||
|
|
||
|
inline bool IsValid() const { return branchTime > 0; };
|
||
|
inline const idVec3& GetBranchPoint() const { return points[ 0 ]; }
|
||
|
inline int GetBranchTime() const { return branchTime; }
|
||
|
inline const idBounds& GetBounds() const { return bounds; }
|
||
|
inline const idBounds& GetEntityBounds() const { return entityBounds; }
|
||
|
inline const idVec3& GetVelocity() const { return velocity; }
|
||
|
inline bool OnGround() const { return onGround; }
|
||
|
|
||
|
bool IsValidFor( int clientNum ) const { return clientsValidFor.Get( clientNum ) > 0; }
|
||
|
void SetValidFor( int clientNum ) { clientsValidFor.Set( clientNum ); }
|
||
|
|
||
|
bool IsUserCommandOnly() const { return userCommandOnly; }
|
||
|
int GetBaseBranchTime() const { return baseBranchTime; }
|
||
|
protected:
|
||
|
idVec3 velocity;
|
||
|
|
||
|
int branchTime;
|
||
|
int timeUpto;
|
||
|
bool onGround;
|
||
|
|
||
|
idVec3 points[ MAX_ANTILAG_POINTS ];
|
||
|
idBounds entityBounds;
|
||
|
idBounds bounds;
|
||
|
|
||
|
sdAntiLagEntity* antiLagEntity;
|
||
|
|
||
|
sdBitField< MAX_CLIENTS > clientsValidFor;
|
||
|
|
||
|
// support for branching off branches based on user command updates
|
||
|
bool userCommandOnly;
|
||
|
int baseBranchTime;
|
||
|
};
|
||
|
|
||
|
class sdAntiLagSetGeneric : public sdAntiLagSet {
|
||
|
public:
|
||
|
virtual void Setup( sdAntiLagEntity& antiLagEntity );
|
||
|
virtual void Setup( sdAntiLagEntity& antiLagEntity, sdAntiLagSet& baseSet );
|
||
|
virtual void Update();
|
||
|
|
||
|
const idVec3& GetAcceleration() const { return acceleration; }
|
||
|
|
||
|
protected:
|
||
|
idVec3 acceleration;
|
||
|
};
|
||
|
|
||
|
class sdAntiLagSetPlayer : public sdAntiLagSet {
|
||
|
public:
|
||
|
virtual void Setup( sdAntiLagEntity& antiLagEntity );
|
||
|
virtual void Setup( sdAntiLagEntity& antiLagEntity, sdAntiLagSet& baseSet );
|
||
|
virtual void Update();
|
||
|
|
||
|
const idVec3& GetGravity() const { return gravity; }
|
||
|
const idVec3& GetGroundNormal() const { return groundNormal; }
|
||
|
waterLevel_t GetWaterLevel() const { return waterLevel; }
|
||
|
|
||
|
protected:
|
||
|
// simulate player move!
|
||
|
float CmdScale( int fwd, int right, int up, bool noVertical ) const;
|
||
|
idVec2 CalcDesiredWalkMove( int fwd, int right ) const;
|
||
|
void Accelerate( const idVec3 &wishdir, const float wishspeed, const float accel );
|
||
|
void WalkMove();
|
||
|
void Friction();
|
||
|
|
||
|
idVec3 gravity;
|
||
|
idVec3 groundNormal;
|
||
|
|
||
|
waterLevel_t waterLevel;
|
||
|
|
||
|
float walkSpeedFwd;
|
||
|
float walkSpeedBack;
|
||
|
float walkSpeedSide;
|
||
|
|
||
|
idVec3 viewForward;
|
||
|
idVec3 viewRight;
|
||
|
float playerSpeed;
|
||
|
|
||
|
int cmdForwardMove;
|
||
|
int cmdRightMove;
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
|
||
|
sdAntiLagEntity
|
||
|
|
||
|
===============================================================================
|
||
|
*/
|
||
|
class sdAntiLagEntity {
|
||
|
public:
|
||
|
sdAntiLagEntity() {
|
||
|
for ( int i = 0; i < MAX_ANTILAG_SETS; i++ ) {
|
||
|
antiLagSets[ i ] = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
virtual void Create();
|
||
|
virtual void Destroy();
|
||
|
|
||
|
virtual void Reset();
|
||
|
void Init( const idEntity* self );
|
||
|
|
||
|
virtual void Update();
|
||
|
void CreateBranch( int clientNum );
|
||
|
void CreateUserCommandBranch( int clientNum );
|
||
|
idBounds GetBounds();
|
||
|
sdAntiLagSet* GetAntiLagSet( int clientNum );
|
||
|
|
||
|
const idVec3& GetClientEstimate( int clientNum ) { return clientEstimates[ clientNum ].GetLastReturned(); }
|
||
|
|
||
|
sdAntiLagSet& GetMostRecentBranch() { return *antiLagSets[ ( antiLagUpto + MAX_ANTILAG_SETS - 1 ) % MAX_ANTILAG_SETS ]; }
|
||
|
|
||
|
idEntity* GetSelf() const { return self; }
|
||
|
|
||
|
|
||
|
|
||
|
#ifdef ANTILAG_LOGGING
|
||
|
float antiLagDistances[ MAX_CLIENTS ];
|
||
|
#endif
|
||
|
|
||
|
protected:
|
||
|
|
||
|
idEntityPtr< idEntity > self;
|
||
|
|
||
|
// antilag branches
|
||
|
sdAntiLagSet* antiLagSets[ MAX_ANTILAG_SETS ];
|
||
|
int antiLagUpto;
|
||
|
|
||
|
// estimate of where all the other clients think this entity is
|
||
|
sdPredictionErrorDecay_Origin clientEstimates[ MAX_CLIENTS ];
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
|
||
|
sdAntiLagPlayer
|
||
|
|
||
|
===============================================================================
|
||
|
*/
|
||
|
class sdAntiLagPlayer : public sdAntiLagEntity {
|
||
|
public:
|
||
|
virtual void Create();
|
||
|
virtual void Destroy();
|
||
|
|
||
|
void Trace( trace_t& result, const idVec3& start, const idVec3& end, int shooterIndex );
|
||
|
|
||
|
protected:
|
||
|
sdAntiLagSetPlayer playerSets[ MAX_ANTILAG_SETS ];
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
|
||
|
sdAntiLagManager
|
||
|
|
||
|
===============================================================================
|
||
|
*/
|
||
|
class sdAntiLagManagerLocal {
|
||
|
public:
|
||
|
sdAntiLagManagerLocal();
|
||
|
|
||
|
void OnMapLoad();
|
||
|
void OnMapShutdown();
|
||
|
|
||
|
void Think();
|
||
|
|
||
|
void ResetForPlayer( const idPlayer* self );
|
||
|
void CreateBranch( const idPlayer* self );
|
||
|
void CreateUserCommandBranch( const idPlayer* self );
|
||
|
void Trace( trace_t& result, const idVec3& start, const idVec3& end, int mask, idPlayer* clientShooting, idEntity* ignore );
|
||
|
|
||
|
sdAntiLagPlayer& GetAntiLagPlayer( int index );
|
||
|
|
||
|
idClipModel* GetModelForBounds( const idBounds& bounds );
|
||
|
|
||
|
void OnNetworkEvent( int clientNum, const idBitMsg& msg );
|
||
|
|
||
|
const idVec3& GetLastTraceHitOrigin( int clientId ) const { return lastTraceHitOrigin[ clientId ]; }
|
||
|
void SetLastTraceHitOrigin( int clientId, const idVec3& origin ) { lastTraceHitOrigin[ clientId ] = origin; }
|
||
|
|
||
|
protected:
|
||
|
#ifdef ANTILAG_LOGGING
|
||
|
idFile* logFile;
|
||
|
idFile* clientLogFile;
|
||
|
|
||
|
idVec3 lastStart;
|
||
|
idVec3 lastEnd;
|
||
|
int lastTime;
|
||
|
|
||
|
void SendTrace( const idVec3& start, const idVec3& end );
|
||
|
void RecordServerTrace( trace_t& result, const idVec3& start, const idVec3& end, idPlayer* clientShooting );
|
||
|
void RecordTrace( int time, bool server, const idVec3& start, const idVec3& end, int shooter );
|
||
|
#endif
|
||
|
|
||
|
|
||
|
sdAntiLagPlayer players[ MAX_CLIENTS ];
|
||
|
idVec3 lastTraceHitOrigin[ MAX_CLIENTS ];
|
||
|
|
||
|
idList< idClipModel* > cachedPlayerModels;
|
||
|
};
|
||
|
|
||
|
typedef sdSingleton< sdAntiLagManagerLocal > sdAntiLagManager;
|
||
|
|
||
|
|
||
|
#endif /* !__GAME_ANTILAG_H__ */
|