Added trigger push prediction

This commit is contained in:
Kamay Xutax 2024-08-23 06:42:34 +02:00
parent 14717d8092
commit 186b8c046d
7 changed files with 164 additions and 15 deletions

View file

@ -643,7 +643,7 @@ public:
// C_BaseEntity local functions
public:
void UpdatePartitionListEntry();
virtual void UpdatePartitionListEntry();
// This can be used to setup the entity as a client-only entity.
// Override this to perform per-entity clientside setup

View file

@ -174,6 +174,7 @@ $Project
$File "css_enhanced\c_filters.cpp"
$File "css_enhanced\c_triggers_base.cpp"
$File "css_enhanced\c_triggers.cpp"
$File "css_enhanced\c_trigger_push.cpp"
$File "css_enhanced\variant_t.cpp"
$File "hl2\C_Func_Monitor.cpp"
$File "geiger.cpp"

View file

@ -0,0 +1,122 @@
#include "cbase.h"
#include "datamap.h"
#include "util_shared.h"
#include "c_trigger_push.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
LINK_ENTITY_TO_CLASS( trigger_push, C_TriggerPush );
BEGIN_PREDICTION_DATA(C_TriggerPush)
DEFINE_PRED_FIELD(m_vecPushDir, FIELD_VECTOR, FTYPEDESC_INSENDTABLE),
DEFINE_PRED_FIELD(m_flAlternateTicksFix, FIELD_FLOAT, FTYPEDESC_INSENDTABLE),
DEFINE_PRED_FIELD(m_flPushSpeed, FIELD_FLOAT, FTYPEDESC_INSENDTABLE),
// DEFINE_PRED_ARRAY(m_hPredictedTouchingEntities, FIELD_EHANDLE, MAX_EDICTS, FTYPEDESC_PRIVATE),
// DEFINE_PRED_FIELD(m_iCountPredictedTouchingEntities, FIELD_INTEGER, FTYPEDESC_PRIVATE)
END_PREDICTION_DATA();
// Since this is called only during creation
// we allow a small margin for prediction errors here
IMPLEMENT_CLIENTCLASS_DT(C_TriggerPush, DT_TriggerPush, CTriggerPush)
RecvPropVector(RECVINFO(m_vecPushDir)),
RecvPropFloat(RECVINFO(m_flAlternateTicksFix)),
RecvPropFloat(RECVINFO(m_flPushSpeed)),
END_RECV_TABLE();
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pOther -
//-----------------------------------------------------------------------------
void C_TriggerPush::Touch( CBaseEntity *pOther )
{
if ( !pOther->IsSolid() || (pOther->GetMoveType() == MOVETYPE_PUSH || pOther->GetMoveType() == MOVETYPE_NONE ) )
return;
if (!PassesTriggerFilters(pOther))
return;
// FIXME: If something is hierarchically attached, should we try to push the parent?
if (pOther->GetMoveParent())
return;
// Transform the push dir into global space
Vector vecAbsDir;
VectorRotate( m_vecPushDir, EntityToWorldTransform(), vecAbsDir );
// Instant trigger, just transfer velocity and remove
if (HasSpawnFlags(SF_TRIG_PUSH_ONCE))
{
pOther->ApplyAbsVelocityImpulse( m_flPushSpeed * vecAbsDir );
if ( vecAbsDir.z > 0 )
{
pOther->SetGroundEntity( NULL );
}
// UTIL_Remove( this );
return;
}
switch( pOther->GetMoveType() )
{
case MOVETYPE_NONE:
case MOVETYPE_PUSH:
case MOVETYPE_NOCLIP:
break;
case MOVETYPE_VPHYSICS:
{
IPhysicsObject *pPhys = pOther->VPhysicsGetObject();
if ( pPhys )
{
// UNDONE: Assume the velocity is for a 100kg object, scale with mass
pPhys->ApplyForceCenter( m_flPushSpeed * vecAbsDir * 100.0f * gpGlobals->frametime );
return;
}
}
break;
default:
{
#if defined( HL2_DLL )
// HACK HACK HL2 players on ladders will only be disengaged if the sf is set, otherwise no push occurs.
if ( pOther->IsPlayer() &&
pOther->GetMoveType() == MOVETYPE_LADDER )
{
if ( !HasSpawnFlags(SF_TRIG_PUSH_AFFECT_PLAYER_ON_LADDER) )
{
// Ignore the push
return;
}
}
#endif
Vector vecPush = (m_flPushSpeed * vecAbsDir);
if ( pOther->GetFlags() & FL_BASEVELOCITY )
{
vecPush = vecPush + pOther->GetBaseVelocity();
}
if ( vecPush.z > 0 && (pOther->GetFlags() & FL_ONGROUND) )
{
pOther->SetGroundEntity( NULL );
Vector origin = pOther->GetAbsOrigin();
origin.z += 1.0f;
pOther->SetAbsOrigin( origin );
}
#ifdef HL1_DLL
// Apply the z velocity as a force so it counteracts gravity properly
Vector vecImpulse( 0, 0, vecPush.z * 0.025 );//magic hack number
pOther->ApplyAbsVelocityImpulse( vecImpulse );
// apply x, y as a base velocity so we travel at constant speed on conveyors
vecPush.z = 0;
#endif
pOther->SetBaseVelocity( vecPush );
pOther->AddFlag( FL_BASEVELOCITY );
}
break;
}
}

View file

@ -0,0 +1,22 @@
#ifndef C_TRIGGERS_PUSH_H
#define C_TRIGGERS_PUSH_H
#include "c_triggers.h"
#include "predictable_entity.h"
class C_TriggerPush : public C_BaseTrigger
{
public:
DECLARE_CLASS( C_TriggerPush, C_BaseTrigger );
DECLARE_NETWORKCLASS();
DECLARE_PREDICTABLE();
virtual void Touch( CBaseEntity *pOther );
Vector m_vecPushDir;
float m_flAlternateTicksFix; // Scale factor to apply to the push speed when running with alternate ticks
float m_flPushSpeed;
};
#endif // C_TRIGGERS_PUSH_H

View file

@ -47,9 +47,9 @@ public:
void Enable( void );
void Disable( void );
void Spawn( void );
void UpdateOnRemove( void );
void UpdatePartitionListEntry();
virtual void Spawn( void );
virtual void UpdateOnRemove( void );
virtual void UpdatePartitionListEntry();
void TouchTest( void );
virtual bool IsTrigger( void ) { return true; };

View file

@ -508,7 +508,6 @@ void C_BaseTrigger::InputEndTouch( inputdata_t &inputdata )
//-----------------------------------------------------------------------------
void C_BaseTrigger::StartTouch(CBaseEntity *pOther)
{
printf("start touch\n");
if (PassesTriggerFilters(pOther))
{
EHANDLE hOther;
@ -525,7 +524,6 @@ void C_BaseTrigger::StartTouch(CBaseEntity *pOther)
if ( bAdded && ( m_hTouchingEntities.Count() == 1 ) )
{
printf("really start touch\n");
// First entity to touch us that passes our filters
m_OnStartTouchAll.FireOutput( pOther, this );
}
@ -539,10 +537,8 @@ void C_BaseTrigger::StartTouch(CBaseEntity *pOther)
//-----------------------------------------------------------------------------
void C_BaseTrigger::EndTouch(CBaseEntity *pOther)
{
printf("end touch\n");
if ( IsTouching( pOther ) )
{
printf("really end touch\n");
EHANDLE hOther;
hOther = pOther;
m_hTouchingEntities.FindAndRemove( hOther );

View file

@ -10,6 +10,7 @@
#include "dt_send.h"
#include "dt_utlvector_send.h"
#include "player.h"
#include "predictable_entity.h"
#include "saverestore.h"
#include "gamerules.h"
#include "entityapi.h"
@ -2155,24 +2156,31 @@ class CTriggerPush : public CBaseTrigger
{
public:
DECLARE_CLASS( CTriggerPush, CBaseTrigger );
DECLARE_NETWORKCLASS();
void Spawn( void );
void Activate( void );
void Touch( CBaseEntity *pOther );
void Untouch( CBaseEntity *pOther );
Vector m_vecPushDir;
CNetworkVar(Vector, m_vecPushDir);
DECLARE_DATADESC();
float m_flAlternateTicksFix; // Scale factor to apply to the push speed when running with alternate ticks
float m_flPushSpeed;
CNetworkVar(float, m_flAlternateTicksFix); // Scale factor to apply to the push speed when running with alternate ticks
CNetworkVar(float, m_flPushSpeed);
};
IMPLEMENT_SERVERCLASS_ST(CTriggerPush, DT_TriggerPush)
SendPropVector(SENDINFO(m_vecPushDir)),
SendPropFloat(SENDINFO(m_flAlternateTicksFix)),
SendPropFloat(SENDINFO(m_flPushSpeed)),
END_SEND_TABLE();
BEGIN_DATADESC( CTriggerPush )
DEFINE_KEYFIELD( m_vecPushDir, FIELD_VECTOR, "pushdir" ),
DEFINE_KEYFIELD( m_flAlternateTicksFix, FIELD_FLOAT, "alternateticksfix" ),
//DEFINE_FIELD( m_flPushSpeed, FIELD_FLOAT ),
DEFINE_FIELD( m_flPushSpeed, FIELD_FLOAT ),
END_DATADESC()
LINK_ENTITY_TO_CLASS( trigger_push, CTriggerPush );
@ -2185,11 +2193,11 @@ void CTriggerPush::Spawn()
{
// Convert pushdir from angles to a vector
Vector vecAbsDir;
QAngle angPushDir = QAngle(m_vecPushDir.x, m_vecPushDir.y, m_vecPushDir.z);
QAngle angPushDir = QAngle(m_vecPushDir->x, m_vecPushDir->y, m_vecPushDir->z);
AngleVectors(angPushDir, &vecAbsDir);
// Transform the vector into entity space
VectorIRotate( vecAbsDir, EntityToWorldTransform(), m_vecPushDir );
VectorIRotate( vecAbsDir, EntityToWorldTransform(), m_vecPushDir.GetForModify() );
BaseClass::Spawn();
@ -2198,7 +2206,7 @@ void CTriggerPush::Spawn()
if (m_flSpeed == 0)
{
m_flSpeed = 100;
}
}
}