etqw-sdk/source/game/AntiLag.h

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