aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/server/triggers.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mp/src/game/server/triggers.cpp')
-rw-r--r--mp/src/game/server/triggers.cpp162
1 files changed, 152 insertions, 10 deletions
diff --git a/mp/src/game/server/triggers.cpp b/mp/src/game/server/triggers.cpp
index 742976fb..1e317567 100644
--- a/mp/src/game/server/triggers.cpp
+++ b/mp/src/game/server/triggers.cpp
@@ -475,6 +475,7 @@ void CBaseTrigger::StartTouch(CBaseEntity *pOther)
{
// First entity to touch us that passes our filters
m_OnStartTouchAll.FireOutput( pOther, this );
+ StartTouchAll();
}
}
}
@@ -514,7 +515,10 @@ void CBaseTrigger::EndTouch(CBaseEntity *pOther)
else if ( hOther->IsPlayer() && !hOther->IsAlive() )
{
#ifdef STAGING_ONLY
- AssertMsg( 0, CFmtStr( "Dead player [%s] is still touching this trigger at [%f %f %f]", hOther->GetEntityName().ToCStr(), XYZ( hOther->GetAbsOrigin() ) ) );
+ if ( !HushAsserts() )
+ {
+ AssertMsg( false, "Dead player [%s] is still touching this trigger at [%f %f %f]", hOther->GetEntityName().ToCStr(), XYZ( hOther->GetAbsOrigin() ) );
+ }
Warning( "Dead player [%s] is still touching this trigger at [%f %f %f]", hOther->GetEntityName().ToCStr(), XYZ( hOther->GetAbsOrigin() ) );
#endif
m_hTouchingEntities.Remove( i );
@@ -530,6 +534,7 @@ void CBaseTrigger::EndTouch(CBaseEntity *pOther)
if ( !bFoundOtherTouchee /*&& !m_bDisabled*/ )
{
m_OnEndTouchAll.FireOutput(pOther, this);
+ EndTouchAll();
}
}
}
@@ -634,8 +639,8 @@ void CTriggerRemove::Touch( CBaseEntity *pOther )
BEGIN_DATADESC( CTriggerHurt )
// Function Pointers
- DEFINE_FUNCTION( RadiationThink ),
- DEFINE_FUNCTION( HurtThink ),
+ DEFINE_FUNCTION( CTriggerHurtShim::RadiationThinkShim ),
+ DEFINE_FUNCTION( CTriggerHurtShim::HurtThinkShim ),
// Fields
DEFINE_FIELD( m_flOriginalDamage, FIELD_FLOAT ),
@@ -661,6 +666,7 @@ END_DATADESC()
LINK_ENTITY_TO_CLASS( trigger_hurt, CTriggerHurt );
+IMPLEMENT_AUTO_LIST( ITriggerHurtAutoList );
//-----------------------------------------------------------------------------
// Purpose: Called when spawning, after keyvalues have been handled.
@@ -677,7 +683,7 @@ void CTriggerHurt::Spawn( void )
SetThink( NULL );
if (m_bitsDamageInflict & DMG_RADIATION)
{
- SetThink ( &CTriggerHurt::RadiationThink );
+ SetThink ( &CTriggerHurtShim::RadiationThinkShim );
SetNextThink( gpGlobals->curtime + random->RandomFloat(0.0, 0.5) );
}
}
@@ -723,6 +729,15 @@ bool CTriggerHurt::HurtEntity( CBaseEntity *pOther, float damage )
if ( !pOther->m_takedamage || !PassesTriggerFilters(pOther) )
return false;
+ // If player is disconnected, we're probably in this routine via the
+ // PhysicsRemoveTouchedList() function to make sure all Untouch()'s are called for the
+ // player. Calling TakeDamage() in this case can get into the speaking criteria, which
+ // will then loop through the control points and the touched list again. We shouldn't
+ // need to hurt players that are disconnected, so skip all of this...
+ bool bPlayerDisconnected = pOther->IsPlayer() && ( ((CBasePlayer *)pOther)->IsConnected() == false );
+ if ( bPlayerDisconnected )
+ return false;
+
if ( damage < 0 )
{
pOther->TakeHealth( -damage, m_bitsDamageInflict );
@@ -862,11 +877,29 @@ void CTriggerHurt::Touch( CBaseEntity *pOther )
{
if ( m_pfnThink == NULL )
{
- SetThink( &CTriggerHurt::HurtThink );
+ SetThink( &CTriggerHurtShim::HurtThinkShim );
SetNextThink( gpGlobals->curtime );
}
}
+//-----------------------------------------------------------------------------
+// Purpose: Checks if this point is in any trigger_hurt zones with positive damage
+//-----------------------------------------------------------------------------
+bool IsTakingTriggerHurtDamageAtPoint( const Vector &vecPoint )
+{
+ for ( int i = 0; i < ITriggerHurtAutoList::AutoList().Count(); i++ )
+ {
+ // Some maps use trigger_hurt with negative values as healing triggers; don't consider those
+ CTriggerHurt *pTrigger = static_cast<CTriggerHurt*>( ITriggerHurtAutoList::AutoList()[i] );
+ if ( !pTrigger->m_bDisabled && pTrigger->PointIsWithin( vecPoint ) && pTrigger->m_flDamage > 0.f )
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
// ##################################################################################
// >> TriggerMultiple
@@ -2310,8 +2343,8 @@ class CTriggerTeleport : public CBaseTrigger
public:
DECLARE_CLASS( CTriggerTeleport, CBaseTrigger );
- void Spawn( void );
- void Touch( CBaseEntity *pOther );
+ virtual void Spawn( void ) OVERRIDE;
+ virtual void Touch( CBaseEntity *pOther ) OVERRIDE;
string_t m_iLandmark;
@@ -2326,14 +2359,11 @@ BEGIN_DATADESC( CTriggerTeleport )
END_DATADESC()
-
-
void CTriggerTeleport::Spawn( void )
{
InitTrigger();
}
-
//-----------------------------------------------------------------------------
// Purpose: Teleports the entity that touched us to the location of our target,
// setting the toucher's angles to our target's angles if they are a
@@ -2416,6 +2446,46 @@ LINK_ENTITY_TO_CLASS( info_teleport_destination, CPointEntity );
//-----------------------------------------------------------------------------
+// Teleport Relative trigger
+//-----------------------------------------------------------------------------
+class CTriggerTeleportRelative : public CBaseTrigger
+{
+public:
+ DECLARE_CLASS(CTriggerTeleportRelative, CBaseTrigger);
+
+ virtual void Spawn( void ) OVERRIDE;
+ virtual void Touch( CBaseEntity *pOther ) OVERRIDE;
+
+ Vector m_TeleportOffset;
+
+ DECLARE_DATADESC();
+};
+
+LINK_ENTITY_TO_CLASS( trigger_teleport_relative, CTriggerTeleportRelative );
+BEGIN_DATADESC( CTriggerTeleportRelative )
+ DEFINE_KEYFIELD( m_TeleportOffset, FIELD_VECTOR, "teleportoffset" )
+END_DATADESC()
+
+
+void CTriggerTeleportRelative::Spawn( void )
+{
+ InitTrigger();
+}
+
+void CTriggerTeleportRelative::Touch( CBaseEntity *pOther )
+{
+ if ( !PassesTriggerFilters(pOther) )
+ {
+ return;
+ }
+
+ const Vector finalPos = m_TeleportOffset + WorldSpaceCenter();
+ const Vector *momentum = &vec3_origin;
+
+ pOther->Teleport( &finalPos, NULL, momentum );
+}
+
+//-----------------------------------------------------------------------------
// Purpose: Saves the game when the player touches the trigger. Can be enabled or disabled
//-----------------------------------------------------------------------------
class CTriggerToggleSave : public CBaseTrigger
@@ -4822,6 +4892,78 @@ void CServerRagdollTrigger::EndTouch(CBaseEntity *pOther)
}
}
+
+//-----------------------------------------------------------------------------
+// Purpose: A trigger that adds impulse to touching entities
+//-----------------------------------------------------------------------------
+class CTriggerApplyImpulse : public CBaseTrigger
+{
+public:
+ DECLARE_CLASS( CTriggerApplyImpulse, CBaseTrigger );
+ DECLARE_DATADESC();
+
+ CTriggerApplyImpulse();
+
+ void Spawn( void );
+
+ void InputApplyImpulse( inputdata_t& );
+
+private:
+ Vector m_vecImpulseDir;
+ float m_flForce;
+};
+
+
+BEGIN_DATADESC( CTriggerApplyImpulse )
+ DEFINE_KEYFIELD( m_vecImpulseDir, FIELD_VECTOR, "impulse_dir" ),
+ DEFINE_KEYFIELD( m_flForce, FIELD_FLOAT, "force" ),
+ DEFINE_INPUTFUNC( FIELD_VOID, "ApplyImpulse", InputApplyImpulse ),
+END_DATADESC()
+
+
+LINK_ENTITY_TO_CLASS( trigger_apply_impulse, CTriggerApplyImpulse );
+
+
+CTriggerApplyImpulse::CTriggerApplyImpulse()
+{
+ m_flForce = 300.f;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTriggerApplyImpulse::Spawn()
+{
+ // Convert pushdir from angles to a vector
+ Vector vecAbsDir;
+ QAngle angPushDir = QAngle(m_vecImpulseDir.x, m_vecImpulseDir.y, m_vecImpulseDir.z);
+ AngleVectors(angPushDir, &vecAbsDir);
+
+ // Transform the vector into entity space
+ VectorIRotate( vecAbsDir, EntityToWorldTransform(), m_vecImpulseDir );
+
+ BaseClass::Spawn();
+
+ InitTrigger();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CTriggerApplyImpulse::InputApplyImpulse( inputdata_t& )
+{
+ Vector vecImpulse = m_flForce * m_vecImpulseDir;
+ FOR_EACH_VEC( m_hTouchingEntities, i )
+ {
+ if ( m_hTouchingEntities[i] )
+ {
+ m_hTouchingEntities[i]->ApplyAbsVelocityImpulse( vecImpulse );
+ }
+ }
+}
+
#ifdef HL1_DLL
//----------------------------------------------------------------------------------
// func_friction