Added eventqueue prediction
This commit is contained in:
parent
4878bce085
commit
ef7097f389
3 changed files with 107 additions and 45 deletions
|
@ -67,9 +67,15 @@ public:
|
||||||
|
|
||||||
void Dump( void );
|
void Dump( void );
|
||||||
|
|
||||||
|
inline EventQueuePrioritizedEvent_t* GetFirstPriorityEvent()
|
||||||
|
{
|
||||||
|
return m_Events.m_pNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddEvent( EventQueuePrioritizedEvent_t* event );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void AddEvent( EventQueuePrioritizedEvent_t *event );
|
|
||||||
void RemoveEvent( EventQueuePrioritizedEvent_t *pe );
|
void RemoveEvent( EventQueuePrioritizedEvent_t *pe );
|
||||||
|
|
||||||
DECLARE_SIMPLE_DATADESC();
|
DECLARE_SIMPLE_DATADESC();
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "prediction_private.h"
|
#include "prediction_private.h"
|
||||||
#include "ivrenderview.h"
|
#include "ivrenderview.h"
|
||||||
#include "iinput.h"
|
#include "iinput.h"
|
||||||
|
#include "strtools.h"
|
||||||
#include "usercmd.h"
|
#include "usercmd.h"
|
||||||
#include <vgui_controls/Controls.h>
|
#include <vgui_controls/Controls.h>
|
||||||
#include <vgui/ISurface.h>
|
#include <vgui/ISurface.h>
|
||||||
|
@ -1353,90 +1354,132 @@ void CPrediction::RestorePredictedTouched( int current_command )
|
||||||
{
|
{
|
||||||
VPROF( "CPrediction::RestorePredictedTouched" );
|
VPROF( "CPrediction::RestorePredictedTouched" );
|
||||||
|
|
||||||
if (m_nCommandsPredicted == 0)
|
if ( m_nCommandsPredicted == 0 )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool saveDisableTouchFuncs = CBaseEntity::sm_bDisableTouchFuncs;
|
bool saveDisableTouchFuncs = CBaseEntity::sm_bDisableTouchFuncs;
|
||||||
|
|
||||||
// Don't call StartTouch/EndTouch here, let run command do it.
|
// Don't call StartTouch/EndTouch here, let run command do it.
|
||||||
CBaseEntity::sm_bDisableTouchFuncs = true;
|
CBaseEntity::sm_bDisableTouchFuncs = true;
|
||||||
|
|
||||||
int pc = predictables->GetPredictableCount();
|
int pc = predictables->GetPredictableCount();
|
||||||
int p;
|
int p;
|
||||||
for ( p = 0; p < pc; p++ )
|
for ( p = 0; p < pc; p++ )
|
||||||
{
|
{
|
||||||
C_BaseEntity *ent = predictables->GetPredictable( p );
|
C_BaseEntity* ent = predictables->GetPredictable( p );
|
||||||
if ( !ent )
|
if ( !ent )
|
||||||
continue;
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
auto& savedTouchList = m_touchedHistory[current_command % MULTIPLAYER_BACKUP][ent->index];
|
auto& savedTouchList = m_touchedHistory[current_command % MULTIPLAYER_BACKUP][ent->index];
|
||||||
|
|
||||||
C_BaseEntity::PhysicsRemoveTouchedList(ent);
|
C_BaseEntity::PhysicsRemoveTouchedList( ent );
|
||||||
|
|
||||||
for ( int i = 0; i < savedTouchList.savedTouches.Count(); i++ )
|
for ( int i = 0; i < savedTouchList.savedTouches.Count(); i++ )
|
||||||
{
|
{
|
||||||
SavedTouch_t& touch = savedTouchList.savedTouches[i];
|
SavedTouch_t& touch = savedTouchList.savedTouches[i];
|
||||||
auto pEntity = ClientEntityList().GetBaseEntity(touch.entityTouched);
|
auto pEntity = ClientEntityList().GetBaseEntity( touch.entityTouched );
|
||||||
|
|
||||||
// Entity doesn't exist anymore, don't bother ...
|
// Entity doesn't exist anymore, don't bother ...
|
||||||
if (!pEntity)
|
if ( !pEntity )
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ent->PhysicsMarkEntityAsTouched(pEntity);
|
ent->PhysicsMarkEntityAsTouched( pEntity );
|
||||||
pEntity->PhysicsMarkEntityAsTouched( ent );
|
pEntity->PhysicsMarkEntityAsTouched( ent );
|
||||||
}
|
|
||||||
|
|
||||||
if (ent->IsTrigger())
|
|
||||||
{
|
|
||||||
auto trigger = static_cast<C_BaseTrigger*>(ent);
|
|
||||||
trigger->m_hTouchingEntities = savedTouchList.touchedTriggerEntities;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
CBaseEntity::sm_bDisableTouchFuncs = saveDisableTouchFuncs;
|
if ( ent->IsTrigger() )
|
||||||
|
{
|
||||||
|
auto trigger = static_cast< C_BaseTrigger* >( ent );
|
||||||
|
trigger->m_hTouchingEntities = savedTouchList.touchedTriggerEntities;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CBaseEntity::sm_bDisableTouchFuncs = saveDisableTouchFuncs;
|
||||||
|
|
||||||
|
auto& savedEventQueue = m_eventQueueHistory[current_command % MULTIPLAYER_BACKUP];
|
||||||
|
|
||||||
|
for ( auto&& event : savedEventQueue )
|
||||||
|
{
|
||||||
|
EventQueuePrioritizedEvent_t* newEvent = new EventQueuePrioritizedEvent_t;
|
||||||
|
|
||||||
|
newEvent->m_flFireTime = event.m_flFireTime;
|
||||||
|
newEvent->m_iTarget = event.m_iTarget;
|
||||||
|
newEvent->m_iTargetInput = event.m_iTargetInput;
|
||||||
|
newEvent->m_pEntTarget = event.m_pEntTarget;
|
||||||
|
newEvent->m_pActivator = event.m_pActivator;
|
||||||
|
newEvent->m_pCaller = event.m_pCaller;
|
||||||
|
newEvent->m_VariantValue = event.m_VariantValue;
|
||||||
|
newEvent->m_iOutputID = event.m_iOutputID;
|
||||||
|
|
||||||
|
g_EventQueue.AddEvent( newEvent );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPrediction::StorePredictedTouched( int current_command )
|
void CPrediction::StorePredictedTouched( int current_command )
|
||||||
{
|
{
|
||||||
VPROF( "CPrediction::StorePredictedTouched" );
|
VPROF( "CPrediction::StorePredictedTouched" );
|
||||||
|
|
||||||
int pc = predictables->GetPredictableCount();
|
int pc = predictables->GetPredictableCount();
|
||||||
int p;
|
int p;
|
||||||
|
|
||||||
for ( p = 0; p < pc; p++ )
|
for ( p = 0; p < pc; p++ )
|
||||||
{
|
{
|
||||||
C_BaseEntity *ent = predictables->GetPredictable( p );
|
C_BaseEntity* ent = predictables->GetPredictable( p );
|
||||||
if ( !ent )
|
if ( !ent )
|
||||||
continue;
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
touchlink_t* link = nullptr;
|
auto root = ( touchlink_t* )ent->GetDataObject( TOUCHLINK );
|
||||||
auto root = ( touchlink_t * )ent->GetDataObject( TOUCHLINK );
|
auto& savedTouchList = m_touchedHistory[current_command % MULTIPLAYER_BACKUP][ent->index];
|
||||||
auto &savedTouchList = m_touchedHistory[current_command % MULTIPLAYER_BACKUP][ent->index];
|
|
||||||
|
|
||||||
savedTouchList.savedTouches.RemoveAll();
|
savedTouchList.savedTouches.RemoveAll();
|
||||||
|
|
||||||
if ( root )
|
if ( root )
|
||||||
{
|
{
|
||||||
for (link = root->nextLink; link != root; link = link->nextLink)
|
for ( auto link = root->nextLink; link != root; link = link->nextLink )
|
||||||
{
|
{
|
||||||
SavedTouch_t touch;
|
SavedTouch_t touch;
|
||||||
touch.entityTouched = link->entityTouched->index;
|
touch.entityTouched = link->entityTouched->index;
|
||||||
touch.touchStamp = link->touchStamp;
|
touch.touchStamp = link->touchStamp;
|
||||||
touch.flags = link->flags;
|
touch.flags = link->flags;
|
||||||
savedTouchList.savedTouches.AddToTail(touch);
|
savedTouchList.savedTouches.AddToTail( touch );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ent->IsTrigger())
|
if ( ent->IsTrigger() )
|
||||||
{
|
{
|
||||||
auto trigger = static_cast<C_BaseTrigger*>(ent);
|
auto trigger = static_cast< C_BaseTrigger* >( ent );
|
||||||
savedTouchList.touchedTriggerEntities = trigger->m_hTouchingEntities;
|
savedTouchList.touchedTriggerEntities = trigger->m_hTouchingEntities;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& savedEventQueue = m_eventQueueHistory[current_command % MULTIPLAYER_BACKUP];
|
||||||
|
savedEventQueue.RemoveAll();
|
||||||
|
|
||||||
|
for ( auto pEvent = g_EventQueue.GetFirstPriorityEvent(); pEvent != NULL; pEvent = pEvent->m_pNext )
|
||||||
|
{
|
||||||
|
EventQueueForHistory event;
|
||||||
|
event.m_flFireTime = pEvent->m_flFireTime;
|
||||||
|
event.m_iOutputID = pEvent->m_iOutputID;
|
||||||
|
Q_strcpy( event.m_iTarget, pEvent->m_iTarget );
|
||||||
|
Q_strcpy( event.m_iTargetInput, pEvent->m_iTargetInput );
|
||||||
|
event.m_pEntTarget = pEvent->m_pEntTarget;
|
||||||
|
event.m_pActivator = pEvent->m_pActivator;
|
||||||
|
event.m_pCaller = pEvent->m_pCaller;
|
||||||
|
event.m_VariantValue = pEvent->m_VariantValue;
|
||||||
|
|
||||||
|
savedEventQueue.AddToTail( event );
|
||||||
|
}
|
||||||
|
|
||||||
|
// This will be reconstructed later.
|
||||||
|
g_EventQueue.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -1761,16 +1804,15 @@ bool CPrediction::PerformPrediction( bool received_new_world_update, C_BasePlaye
|
||||||
|
|
||||||
RunSimulation( current_command, curtime, cmd, localPlayer );
|
RunSimulation( current_command, curtime, cmd, localPlayer );
|
||||||
|
|
||||||
StorePredictedTouched( current_command );
|
|
||||||
|
|
||||||
gpGlobals->curtime = curtime;
|
gpGlobals->curtime = curtime;
|
||||||
gpGlobals->frametime = m_bEnginePaused ? 0 : TICK_INTERVAL;
|
gpGlobals->frametime = m_bEnginePaused ? 0 : TICK_INTERVAL;
|
||||||
|
|
||||||
// Call untouch on any entities no longer predicted to be touching
|
Untouch();
|
||||||
Untouch();
|
|
||||||
|
|
||||||
ServiceEventQueue( NULL );
|
ServiceEventQueue( NULL );
|
||||||
|
|
||||||
|
StorePredictedTouched( current_command );
|
||||||
|
|
||||||
// Store intermediate data into appropriate slot
|
// Store intermediate data into appropriate slot
|
||||||
StorePredictionResults( i - 1 ); // Note that I starts at 1
|
StorePredictionResults( i - 1 ); // Note that I starts at 1
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "c_baseentity.h"
|
#include "c_baseentity.h"
|
||||||
#include "const.h"
|
#include "const.h"
|
||||||
#include "datamodel/dmelementhandle.h"
|
#include "datamodel/dmelementhandle.h"
|
||||||
|
#include "platform.h"
|
||||||
#include "touchlink.h"
|
#include "touchlink.h"
|
||||||
#include "utlvector.h"
|
#include "utlvector.h"
|
||||||
#if !defined( PREDICTION_H )
|
#if !defined( PREDICTION_H )
|
||||||
|
@ -167,7 +168,20 @@ private:
|
||||||
CUtlVector<EHANDLE> touchedTriggerEntities;
|
CUtlVector<EHANDLE> touchedTriggerEntities;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct EventQueueForHistory
|
||||||
|
{
|
||||||
|
float m_flFireTime;
|
||||||
|
char m_iTarget[MAX_PATH]; // TODO_ENHANCED: We need to rename this to some hash here ...
|
||||||
|
char m_iTargetInput[MAX_PATH]; // TODO_ENHANCED: We need to rename this to some hash here ...
|
||||||
|
EHANDLE m_pActivator;
|
||||||
|
EHANDLE m_pCaller;
|
||||||
|
int m_iOutputID;
|
||||||
|
EHANDLE m_pEntTarget;
|
||||||
|
variant_t m_VariantValue;
|
||||||
|
};
|
||||||
|
|
||||||
TouchedHistory m_touchedHistory[MULTIPLAYER_BACKUP][MAX_EDICTS];
|
TouchedHistory m_touchedHistory[MULTIPLAYER_BACKUP][MAX_EDICTS];
|
||||||
|
CUtlVector<EventQueueForHistory> m_eventQueueHistory[MULTIPLAYER_BACKUP];
|
||||||
|
|
||||||
// TODO_ENHANCED: checks if this affects vehicles properly too! It should.
|
// TODO_ENHANCED: checks if this affects vehicles properly too! It should.
|
||||||
enum INTERPOLATION_CONTEXT
|
enum INTERPOLATION_CONTEXT
|
||||||
|
|
Loading…
Add table
Reference in a new issue