122 lines
No EOL
3.4 KiB
C++
122 lines
No EOL
3.4 KiB
C++
#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;
|
|
}
|
|
} |