Improved prediction & fix being 1 off tick problems

This commit is contained in:
Kamay Xutax 2024-07-13 19:18:03 +02:00
parent cd6ecdc726
commit f8c641a9e5
13 changed files with 120 additions and 52 deletions

View file

@ -1357,6 +1357,9 @@ public:
bool BecameDormantThisPacket( void ) const;
void SetDormantPredictable( bool dormant );
// TODO_ENHANCED: make trigger predictables.
virtual void GetGroundVelocityToApply( Vector &vecGroundVel ) { vecGroundVel = GetBaseVelocity(); }
int GetWaterLevel() const;
void SetWaterLevel( int nLevel );
int GetWaterType() const;

View file

@ -5,6 +5,7 @@
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include <stdarg.h>
#include "engine/IEngineSound.h"
#include "filesystem.h"
@ -110,6 +111,19 @@ bool CMoveHelperClient::AddToTouched( const trace_t& tr, const Vector& impactvel
{
int i;
auto pPlayer = C_BasePlayer::GetLocalPlayer();
if ( !pPlayer )
return false;
if ( !tr.m_pEnt )
return false;
if ( tr.m_pEnt == pPlayer->GetBaseEntity() )
{
Assert( !"CMoveHelperClient::AddToTouched: Tried to add self to touchlist!!!" );
return false;
}
// Look for duplicates
for (i = 0; i < m_TouchList.Size(); i++)
{
@ -148,6 +162,10 @@ void CMoveHelperClient::ProcessImpacts( void )
// Touch other objects that were intersected during the movement.
for (int i = 0 ; i < m_TouchList.Size(); i++)
{
// We didn't touch an entity ...
if (!m_TouchList[i].trace.m_pEnt)
continue;
// Run the impact function as if we had run it during movement.
C_BaseEntity *entity = ClientEntityList().GetEnt( m_TouchList[i].trace.m_pEnt->entindex() );
if ( !entity )

View file

@ -6,7 +6,9 @@
//=============================================================================//
#include "cbase.h"
#include "prediction.h"
#include "cdll_client_int.h"
#include "igamemovement.h"
#include "mathlib/mathlib.h"
#include "prediction_private.h"
#include "ivrenderview.h"
#include "iinput.h"
@ -687,12 +689,26 @@ void CPrediction::FinishMove( C_BasePlayer *player, CUserCmd *ucmd, CMoveData *m
player->m_RefEHandle = move->m_nPlayerHandle;
player->m_vecVelocity = move->m_vecVelocity;
player->SetLocalVelocity(move->m_vecVelocity);
player->m_vecNetworkOrigin = move->GetAbsOrigin();
player->m_Local.m_nOldButtons = move->m_nButtons;
float pitch = move->m_vecAngles[PITCH];
if (pitch > 180.0f)
{
pitch -= 360.0f;
}
pitch = clamp(pitch, -90.f, 90.f);
move->m_vecAngles[PITCH] = pitch;
player->SetPoseParameter(player->LookupPoseParameter("body_pitch"), pitch);
player->SetLocalAngles(move->m_vecAngles);
// NOTE: Don't copy this. the movement code modifies its local copy but is not expecting to be authoritative
//player->m_flMaxspeed = move->m_flClientMaxSpeed;
@ -816,6 +832,39 @@ void CPrediction::RunPostThink( C_BasePlayer *player )
#endif
}
void CPrediction::CheckMovingGround( CBasePlayer *player, double frametime )
{
VPROF( "CPrediction::CheckMovingGround()" );
CBaseEntity *groundentity;
if ( player->GetFlags() & FL_ONGROUND )
{
groundentity = player->GetGroundEntity();
if ( groundentity && ( groundentity->GetFlags() & FL_CONVEYOR) )
{
Vector vecNewVelocity;
groundentity->GetGroundVelocityToApply( vecNewVelocity );
if ( player->GetFlags() & FL_BASEVELOCITY )
{
vecNewVelocity += player->GetBaseVelocity();
}
player->SetBaseVelocity( vecNewVelocity );
player->AddFlag( FL_BASEVELOCITY );
}
}
if ( !( player->GetFlags() & FL_BASEVELOCITY ) )
{
// Apply momentum (add in half of the previous frame of velocity first)
player->ApplyAbsVelocityImpulse( (1.0 + ( frametime * 0.5 )) * player->GetBaseVelocity() );
player->SetBaseVelocity( vec3_origin );
}
player->RemoveFlag( FL_BASEVELOCITY );
}
//-----------------------------------------------------------------------------
// Purpose: Predicts a single movement command for player
// Input : *moveHelper -
@ -830,15 +879,20 @@ void CPrediction::RunCommand( C_BasePlayer *player, CUserCmd *ucmd, IMoveHelper
char sz[ 32 ];
Q_snprintf( sz, sizeof( sz ), "runcommand%04d", ucmd->command_number );
PREDICTION_TRACKVALUECHANGESCOPE( sz );
#endif
#endif
StartCommand( player, ucmd );
// Set globals appropriately
gpGlobals->curtime = player->m_nTickBase * TICK_INTERVAL;
gpGlobals->frametime = m_bEnginePaused ? 0 : TICK_INTERVAL;
g_pGameMovement->StartTrackPredictionErrors( player );
gpGlobals->frametime = m_bEnginePaused ? 0 : TICK_INTERVAL;
// Run post think after PreThink/Think function, this makes a room space for local interpolation.
gpGlobals->curtime = (player->m_nTickBase - 1) * TICK_INTERVAL;
RunPostThink( player );
gpGlobals->curtime = player->m_nTickBase * TICK_INTERVAL;
// TODO
// TODO: Check for impulse predicted?
@ -868,11 +922,20 @@ void CPrediction::RunCommand( C_BasePlayer *player, CUserCmd *ucmd, IMoveHelper
// Get button states
player->UpdateButtonState( ucmd->buttons );
// TODO
// CheckMovingGround( player, ucmd->frametime );
// CheckMovingGround( player, gpGlobals->frametime );
// TODO
// g_pMoveData->m_vecOldAngles = player->pl.v_angle;
g_pMoveData->m_vecOldAngles = player->pl.v_angle;
// TODO_ENHANCED: this will be implemented with trigger prediction update
// // Copy from command to player unless game .dll has set angle using fixangle
// if ( player->pl.fixangle == FIXANGLE_NONE )
// {
// player->pl.v_angle = ucmd->viewangles;
// }
// else if( player->pl.fixangle == FIXANGLE_RELATIVE )
// {
// player->pl.v_angle = ucmd->viewangles + player->pl.anglechange;
// }
// Copy from command to player unless game .dll has set angle using fixangle
// if ( !player->pl.fixangle )
@ -905,7 +968,7 @@ void CPrediction::RunCommand( C_BasePlayer *player, CUserCmd *ucmd, IMoveHelper
FinishMove( player, ucmd, g_pMoveData );
RunPostThink( player );
moveHelper->ProcessImpacts();
g_pGameMovement->FinishTrackPredictionErrors( player );

View file

@ -91,7 +91,7 @@ protected:
void RunPreThink( C_BasePlayer *player );
void RunThink (C_BasePlayer *ent, double frametime );
void RunPostThink( C_BasePlayer *player );
void CheckMovingGround( CBasePlayer *player, double frametime );
private:
virtual void _Update
(

View file

@ -210,7 +210,6 @@ public:
SetAbsVelocity( m_hPlayer->GetAbsVelocity() );
AddSolidFlags( FSOLID_NOT_SOLID );
ChangeTeam( m_hPlayer->GetTeamNumber() );
// UseClientSideAnimation();
}
public:
@ -417,9 +416,6 @@ CCSPlayer::CCSPlayer()
{
m_PlayerAnimState = CreatePlayerAnimState( this, this, LEGANIM_9WAY, true );
// TODO: one day we need to remove this shit.
// UseClientSideAnimation();
m_iLastWeaponFireUsercmd = 0;
m_iAddonBits = 0;
m_bEscaped = false;

View file

@ -103,9 +103,6 @@ CHostage::CHostage()
{
g_Hostages.AddToTail( this );
m_PlayerAnimState = CreateHostageAnimState( this, this, LEGANIM_8WAY, false );
// ENHANCED_TODO: remove this
// UseClientSideAnimation();
SetBloodColor( BLOOD_COLOR_RED );
}

View file

@ -7913,14 +7913,6 @@ void CMovementSpeedMod::InputSpeedMod(inputdata_t &data)
}
}
void SendProxy_CropFlagsToPlayerFlagBitsLength( const SendProp *pProp, const void *pStruct, const void *pVarData, DVariant *pOut, int iElement, int objectID)
{
int mask = (1<<PLAYER_FLAG_BITS) - 1;
int data = *(int *)pVarData;
pOut->m_Int = ( data & mask );
}
// -------------------------------------------------------------------------------- //
// SendTable for CPlayerState.
// -------------------------------------------------------------------------------- //
@ -8003,7 +7995,7 @@ void SendProxy_CropFlagsToPlayerFlagBitsLength( const SendProp *pProp, const voi
SendPropInt (SENDINFO(m_iBonusProgress), 15 ),
SendPropInt (SENDINFO(m_iBonusChallenge), 4 ),
SendPropFloat (SENDINFO(m_flMaxspeed), 12, SPROP_ROUNDDOWN, 0.0f, 2048.0f ), // CL
SendPropInt (SENDINFO(m_fFlags), PLAYER_FLAG_BITS, SPROP_UNSIGNED|SPROP_CHANGES_OFTEN, SendProxy_CropFlagsToPlayerFlagBitsLength ),
SendPropInt (SENDINFO(m_fFlags)),
SendPropInt (SENDINFO(m_iObserverMode), 3, SPROP_UNSIGNED ),
SendPropEHandle (SENDINFO(m_hObserverTarget) ),
SendPropInt (SENDINFO(m_iFOV), 8, SPROP_UNSIGNED ),

View file

@ -316,7 +316,6 @@ void CommentarySystem_PePlayerRunCommand( CBasePlayer *player, CUserCmd *ucmd );
//-----------------------------------------------------------------------------
void CPlayerMove::RunCommand ( CBasePlayer *player, CUserCmd *ucmd, IMoveHelper *moveHelper )
{
const float playerCurTime = player->m_nTickBase * TICK_INTERVAL;
const float playerFrameTime = player->m_bGamePaused ? 0 : TICK_INTERVAL;
const float flTimeAllowedForProcessing = player->ConsumeMovementTimeForUserCmdProcessing( playerFrameTime );
if ( !player->IsBot() && ( flTimeAllowedForProcessing < playerFrameTime ) )
@ -338,9 +337,16 @@ void CPlayerMove::RunCommand ( CBasePlayer *player, CUserCmd *ucmd, IMoveHelper
StartCommand( player, ucmd );
// Set globals appropriately
gpGlobals->curtime = playerCurTime;
g_pGameMovement->StartTrackPredictionErrors( player );
gpGlobals->frametime = playerFrameTime;
gpGlobals->curtime = (player->m_nTickBase - 1) * TICK_INTERVAL;
// Run post think first, this will let some space for client side interpolation.
RunPostThink( player );
// Set globals appropriately
gpGlobals->curtime = player->m_nTickBase * TICK_INTERVAL;
extern ConVar sv_showhitboxes;
@ -381,8 +387,6 @@ void CPlayerMove::RunCommand ( CBasePlayer *player, CUserCmd *ucmd, IMoveHelper
}
*/
g_pGameMovement->StartTrackPredictionErrors( player );
CommentarySystem_PePlayerRunCommand( player, ucmd );
// Do weapon selection
@ -458,8 +462,6 @@ void CPlayerMove::RunCommand ( CBasePlayer *player, CUserCmd *ucmd, IMoveHelper
moveHelper->ProcessImpacts();
VPROF_SCOPE_END();
RunPostThink( player );
g_pGameMovement->FinishTrackPredictionErrors( player );
FinishCommand( player );

View file

@ -440,7 +440,7 @@ void CLagCompensationManager::BacktrackPlayer( CBasePlayer *pPlayer, CUserCmd *c
return;
}
// TODO: do proper teleportation checks.
// TODO_ENHANCED: do proper teleportation checks.
// did we find a context smaller than target time ?
if ( recordSim->m_flSimulationTime <= flTargetSimulationTime )

View file

@ -70,7 +70,7 @@ BEGIN_NETWORK_TABLE( CBaseGrenade, DT_BaseGrenade )
SendPropVector( SENDINFO( m_vecVelocity ), 0, SPROP_NOSCALE ),
// HACK: Use same flag bits as player for now
SendPropInt ( SENDINFO(m_fFlags), PLAYER_FLAG_BITS, SPROP_UNSIGNED, SendProxy_CropFlagsToPlayerFlagBitsLength ),
SendPropInt ( SENDINFO(m_fFlags) ),
#else
RecvPropFloat( RECVINFO( m_flDamage ) ),
RecvPropFloat( RECVINFO( m_DmgRadius ) ),

2
ivp

@ -1 +1 @@
Subproject commit 47533475e01cbff05fbc3bbe8b4edc485f292cea
Subproject commit c7c407320533bdce609712dbd535862a065c7da7

View file

@ -32,16 +32,15 @@ public:
CNetworkVar( bool, deadflag );
// Viewing angle (player only)
QAngle v_angle;
// 0:nothing, 1:force view angles, 2:add avelocity
int fixangle;
// delta angle for fixangle == FIXANGLE_RELATIVE
QAngle anglechange;
// The client .dll only cares about deadflag
// the game and engine .dlls need to worry about the rest of this data
#if !defined( CLIENT_DLL )
// Player's network name
string_t netname;
// 0:nothing, 1:force view angles, 2:add avelocity
int fixangle;
// delta angle for fixangle == FIXANGLE_RELATIVE
QAngle anglechange;
// flag to single the HLTV/Replay fake client, not transmitted
bool hltv;
bool replay;

View file

@ -161,8 +161,6 @@
// NON-PLAYER SPECIFIC (i.e., not used by GameMovement or the client .dll ) -- Can still be applied to players, though
#define FL_INWATER (1<<10) // In water
// NOTE if you move things up, make sure to change this value
#define PLAYER_FLAG_BITS 11
#define FL_FLY (1<<11) // Changes the SV_Movestep() behavior to not need to be on ground
#define FL_SWIM (1<<12) // Changes the SV_Movestep() behavior to not need to be on ground (but stay in water)