diff options
| author | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
|---|---|---|
| committer | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
| commit | 39ed87570bdb2f86969d4be821c94b722dc71179 (patch) | |
| tree | abc53757f75f40c80278e87650ea92808274aa59 /sp/src/game/shared/func_ladder.cpp | |
| download | source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip | |
First version of the SOurce SDK 2013
Diffstat (limited to 'sp/src/game/shared/func_ladder.cpp')
| -rw-r--r-- | sp/src/game/shared/func_ladder.cpp | 513 |
1 files changed, 513 insertions, 0 deletions
diff --git a/sp/src/game/shared/func_ladder.cpp b/sp/src/game/shared/func_ladder.cpp new file mode 100644 index 00000000..4bd0c5ff --- /dev/null +++ b/sp/src/game/shared/func_ladder.cpp @@ -0,0 +1,513 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+#include "cbase.h"
+#include "func_ladder.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+#if !defined( CLIENT_DLL )
+/*static*/ ConVar sv_showladders( "sv_showladders", "0", 0, "Show bbox and dismount points for all ladders (must be set before level load.)\n" );
+#endif
+
+CUtlVector< CFuncLadder * > CFuncLadder::s_Ladders;
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CFuncLadder::CFuncLadder() :
+ m_bDisabled( false )
+{
+ s_Ladders.AddToTail( this );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CFuncLadder::~CFuncLadder()
+{
+ s_Ladders.FindAndRemove( this );
+}
+
+int CFuncLadder::GetLadderCount()
+{
+ return s_Ladders.Count();
+}
+
+CFuncLadder *CFuncLadder::GetLadder( int index )
+{
+ if ( index < 0 || index >= s_Ladders.Count() )
+ return NULL;
+
+ return s_Ladders[ index ];
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CFuncLadder::Spawn()
+{
+ BaseClass::Spawn();
+
+ // Entity is symbolid
+ SetSolid( SOLID_NONE );
+ SetMoveType( MOVETYPE_NONE );
+ SetCollisionGroup( COLLISION_GROUP_NONE );
+
+ //AddFlag( FL_WORLDBRUSH );
+ SetModelName( NULL_STRING );
+
+ // Make entity invisible
+ AddEffects( EF_NODRAW );
+ // No model but should still network
+ AddEFlags( EFL_FORCE_CHECK_TRANSMIT );
+
+ Vector playerMins = VEC_HULL_MIN;
+ Vector playerMaxs = VEC_HULL_MAX;
+
+ // This will swap them if they are inverted
+ SetEndPoints( m_vecPlayerMountPositionTop, m_vecPlayerMountPositionBottom );
+
+#if !defined( CLIENT_DLL )
+ trace_t bottomtrace, toptrace;
+ UTIL_TraceHull( m_vecPlayerMountPositionBottom, m_vecPlayerMountPositionBottom,
+ playerMins, playerMaxs, MASK_PLAYERSOLID_BRUSHONLY, NULL, COLLISION_GROUP_PLAYER_MOVEMENT, &bottomtrace );
+ UTIL_TraceHull( m_vecPlayerMountPositionTop, m_vecPlayerMountPositionTop,
+ playerMins, playerMaxs, MASK_PLAYERSOLID_BRUSHONLY, NULL, COLLISION_GROUP_PLAYER_MOVEMENT, &toptrace );
+
+ if ( bottomtrace.startsolid || toptrace.startsolid )
+ {
+ if ( bottomtrace.startsolid )
+ {
+ DevMsg( 1, "Warning, funcladder with blocked bottom point (%.2f %.2f %.2f) stuck in (%s)\n",
+ m_vecPlayerMountPositionBottom.GetX(),
+ m_vecPlayerMountPositionBottom.GetY(),
+ m_vecPlayerMountPositionBottom.GetZ(),
+ bottomtrace.m_pEnt
+ ?
+ UTIL_VarArgs( "%s/%s", bottomtrace.m_pEnt->GetClassname(), bottomtrace.m_pEnt->GetEntityName().ToCStr() )
+ :
+ "NULL" );
+ }
+ if ( toptrace.startsolid )
+ {
+ DevMsg( 1, "Warning, funcladder with blocked top point (%.2f %.2f %.2f) stuck in (%s)\n",
+ m_vecPlayerMountPositionTop.GetX(),
+ m_vecPlayerMountPositionTop.GetY(),
+ m_vecPlayerMountPositionTop.GetZ(),
+ toptrace.m_pEnt
+ ?
+ UTIL_VarArgs( "%s/%s", toptrace.m_pEnt->GetClassname(), toptrace.m_pEnt->GetEntityName().ToCStr() )
+ :
+ "NULL" );
+ }
+
+ // Force geometry overlays on, but only if developer 2 is set...
+ if ( developer.GetInt() > 1 )
+ {
+ m_debugOverlays |= OVERLAY_TEXT_BIT;
+ }
+ }
+
+ m_vecPlayerMountPositionTop -= GetAbsOrigin();
+ m_vecPlayerMountPositionBottom -= GetAbsOrigin();
+
+ // Compute mins, maxs of points
+ //
+ Vector mins( MAX_COORD_INTEGER, MAX_COORD_INTEGER, MAX_COORD_INTEGER );
+ Vector maxs( -MAX_COORD_INTEGER, -MAX_COORD_INTEGER, -MAX_COORD_INTEGER );
+ int i;
+ for ( i = 0; i < 3; i++ )
+ {
+ if ( m_vecPlayerMountPositionBottom.m_Value[ i ] < mins[ i ] )
+ {
+ mins[ i ] = m_vecPlayerMountPositionBottom.m_Value[ i ];
+ }
+ if ( m_vecPlayerMountPositionBottom.m_Value[ i ] > maxs[ i ] )
+ {
+ maxs[ i ] = m_vecPlayerMountPositionBottom.m_Value[ i ];
+ }
+ if ( m_vecPlayerMountPositionTop.m_Value[ i ] < mins[ i ] )
+ {
+ mins[ i ] = m_vecPlayerMountPositionTop.m_Value[ i ];
+ }
+ if ( m_vecPlayerMountPositionTop.m_Value[ i ] > maxs[ i ] )
+ {
+ maxs[ i ] = m_vecPlayerMountPositionTop.m_Value[ i ];
+ }
+ }
+
+ // Expand mins/maxs by player hull size
+ mins += playerMins;
+ maxs += playerMaxs;
+
+ UTIL_SetSize( this, mins, maxs );
+
+ m_bFakeLadder = HasSpawnFlags(SF_LADDER_DONTGETON);
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Called after all entities have spawned or after reload from .sav file
+//-----------------------------------------------------------------------------
+void CFuncLadder::Activate()
+{
+ // Chain to base class
+ BaseClass::Activate();
+
+#if !defined( CLIENT_DLL )
+ // Re-hook up ladder dismount points
+ SearchForDismountPoints();
+
+ // Show debugging UI if it's active
+ if ( sv_showladders.GetBool() )
+ {
+ m_debugOverlays |= OVERLAY_TEXT_BIT;
+ }
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CFuncLadder::SearchForDismountPoints()
+{
+#if !defined( CLIENT_DLL )
+ CUtlVector< CInfoLadderDismountHandle > allNodes;
+
+ Vector topPos;
+ Vector bottomPos;
+
+ GetTopPosition( topPos );
+ GetBottomPosition( bottomPos );
+
+ float dismount_radius = 100.0f;
+
+ Vector vecBottomToTop = topPos - bottomPos;
+ float ladderLength = VectorNormalize( vecBottomToTop );
+
+ float recheck = 40.0f;
+
+ // add both sets of nodes
+ FindNearbyDismountPoints( topPos, dismount_radius, m_Dismounts );
+ FindNearbyDismountPoints( bottomPos, dismount_radius, m_Dismounts );
+
+ while ( 1 )
+ {
+ ladderLength -= recheck;
+ if ( ladderLength <= 0.0f )
+ break;
+ bottomPos += recheck * vecBottomToTop;
+ FindNearbyDismountPoints( bottomPos, dismount_radius, m_Dismounts );
+ }
+#endif
+}
+
+void CFuncLadder::SetEndPoints( const Vector& p1, const Vector& p2 )
+{
+ m_vecPlayerMountPositionTop = p1;
+ m_vecPlayerMountPositionBottom = p2;
+
+ if ( m_vecPlayerMountPositionBottom.GetZ() > m_vecPlayerMountPositionTop.GetZ() )
+ {
+ Vector temp = m_vecPlayerMountPositionBottom;
+ m_vecPlayerMountPositionBottom = m_vecPlayerMountPositionTop;
+ m_vecPlayerMountPositionTop = temp;
+ }
+
+#if !defined( CLIENT_DLL)
+ Vector playerMins = VEC_HULL_MIN;
+ Vector playerMaxs = VEC_HULL_MAX;
+
+ trace_t result;
+ UTIL_TraceHull( m_vecPlayerMountPositionTop + Vector( 0, 0, 4 ), m_vecPlayerMountPositionTop,
+ playerMins, playerMaxs, MASK_PLAYERSOLID_BRUSHONLY, NULL, COLLISION_GROUP_PLAYER_MOVEMENT, &result );
+
+ if ( !result.startsolid )
+ {
+ m_vecPlayerMountPositionTop = result.endpos;
+ }
+
+ UTIL_TraceHull( m_vecPlayerMountPositionBottom + Vector( 0, 0, 4 ), m_vecPlayerMountPositionBottom,
+ playerMins, playerMaxs, MASK_PLAYERSOLID_BRUSHONLY, NULL, COLLISION_GROUP_PLAYER_MOVEMENT, &result );
+
+ if ( !result.startsolid )
+ {
+ m_vecPlayerMountPositionBottom = result.endpos;
+ }
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CFuncLadder::DrawDebugGeometryOverlays()
+{
+#if !defined( CLIENT_DLL )
+
+ BaseClass::DrawDebugGeometryOverlays();
+
+ Vector playerMins = VEC_HULL_MIN;
+ Vector playerMaxs = VEC_HULL_MAX;
+
+ Vector topPosition;
+ Vector bottomPosition;
+
+ GetTopPosition( topPosition );
+ GetBottomPosition( bottomPosition );
+
+ NDebugOverlay::Box( topPosition, playerMins, playerMaxs, 255,0,0,127, 0 );
+ NDebugOverlay::Box( bottomPosition, playerMins, playerMaxs, 0,0,255,127, 0 );
+
+ NDebugOverlay::EntityBounds(this, 200, 180, 63, 63, 0);
+
+ trace_t bottomtrace;
+ UTIL_TraceHull( m_vecPlayerMountPositionBottom, m_vecPlayerMountPositionBottom,
+ playerMins, playerMaxs, MASK_PLAYERSOLID_BRUSHONLY, NULL, COLLISION_GROUP_PLAYER_MOVEMENT, &bottomtrace );
+
+ int c = m_Dismounts.Count();
+ for ( int i = 0 ; i < c ; i++ )
+ {
+ CInfoLadderDismount *pt = m_Dismounts[ i ];
+ if ( !pt )
+ continue;
+
+ NDebugOverlay::Box(pt->GetAbsOrigin(),Vector( -16, -16, 0 ), Vector( 16, 16, 8 ), 150,0,0, 63, 0);
+ }
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : org -
+//-----------------------------------------------------------------------------
+void CFuncLadder::GetTopPosition( Vector& org )
+{
+ ComputeAbsPosition( m_vecPlayerMountPositionTop + GetLocalOrigin(), &org );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : org -
+//-----------------------------------------------------------------------------
+void CFuncLadder::GetBottomPosition( Vector& org )
+{
+ ComputeAbsPosition( m_vecPlayerMountPositionBottom + GetLocalOrigin(), &org );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : bottomToTopVec -
+//-----------------------------------------------------------------------------
+void CFuncLadder::ComputeLadderDir( Vector& bottomToTopVec )
+{
+ Vector top;
+ Vector bottom;
+
+ GetTopPosition( top );
+ GetBottomPosition( bottom );
+
+ bottomToTopVec = top - bottom;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : int
+//-----------------------------------------------------------------------------
+int CFuncLadder::GetDismountCount() const
+{
+ return m_Dismounts.Count();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : index -
+// Output : CInfoLadderDismountHandle
+//-----------------------------------------------------------------------------
+CInfoLadderDismount *CFuncLadder::GetDismount( int index )
+{
+ if ( index < 0 || index >= m_Dismounts.Count() )
+ return NULL;
+ return m_Dismounts[ index ];
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : origin -
+// radius -
+// list -
+//-----------------------------------------------------------------------------
+void CFuncLadder::FindNearbyDismountPoints( const Vector& origin, float radius, CUtlVector< CInfoLadderDismountHandle >& list )
+{
+#if !defined( CLIENT_DLL )
+ CBaseEntity *pEntity = NULL;
+ while ( (pEntity = gEntList.FindEntityByClassnameWithin( pEntity, "info_ladder_dismount", origin, radius)) != NULL )
+ {
+ CInfoLadderDismount *landingspot = static_cast< CInfoLadderDismount * >( pEntity );
+ Assert( landingspot );
+
+ // If spot has a target, then if the target is not this ladder, don't add to our list.
+ if ( landingspot->m_target != NULL_STRING )
+ {
+ if ( landingspot->GetNextTarget() != this )
+ {
+ continue;
+ }
+ }
+
+ CInfoLadderDismountHandle handle;
+ handle = landingspot;
+ if ( list.Find( handle ) == list.InvalidIndex() )
+ {
+ list.AddToTail( handle );
+ }
+ }
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : &inputdata -
+//-----------------------------------------------------------------------------
+void CFuncLadder::InputEnable( inputdata_t &inputdata )
+{
+ m_bDisabled = false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : &inputdata -
+//-----------------------------------------------------------------------------
+void CFuncLadder::InputDisable( inputdata_t &inputdata )
+{
+ m_bDisabled = true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *pPlayer -
+//-----------------------------------------------------------------------------
+void CFuncLadder::PlayerGotOn( CBasePlayer *pPlayer )
+{
+#if !defined( CLIENT_DLL )
+ m_OnPlayerGotOnLadder.FireOutput(this, pPlayer);
+ pPlayer->EmitSound( "Ladder.StepRight" );
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *pPlayer -
+//-----------------------------------------------------------------------------
+void CFuncLadder::PlayerGotOff( CBasePlayer *pPlayer )
+{
+#if !defined( CLIENT_DLL )
+ m_OnPlayerGotOffLadder.FireOutput(this, pPlayer);
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CFuncLadder::DontGetOnLadder( void ) const
+{
+ return m_bFakeLadder;
+}
+
+#if !defined(CLIENT_DLL)
+const char *CFuncLadder::GetSurfacePropName()
+{
+ if ( !m_surfacePropName )
+ return NULL;
+ return m_surfacePropName.ToCStr();
+}
+#endif
+
+IMPLEMENT_NETWORKCLASS_ALIASED( FuncLadder, DT_FuncLadder );
+
+BEGIN_NETWORK_TABLE( CFuncLadder, DT_FuncLadder )
+#if !defined( CLIENT_DLL )
+ SendPropVector( SENDINFO( m_vecPlayerMountPositionTop ), SPROP_COORD ),
+ SendPropVector( SENDINFO( m_vecPlayerMountPositionBottom ), SPROP_COORD ),
+ SendPropVector( SENDINFO( m_vecLadderDir ), SPROP_COORD ),
+ SendPropBool( SENDINFO( m_bFakeLadder ) ),
+// SendPropStringT( SENDINFO(m_surfacePropName) ),
+#else
+ RecvPropVector( RECVINFO( m_vecPlayerMountPositionTop ) ),
+ RecvPropVector( RECVINFO( m_vecPlayerMountPositionBottom )),
+ RecvPropVector( RECVINFO( m_vecLadderDir )),
+ RecvPropBool( RECVINFO( m_bFakeLadder ) ),
+#endif
+END_NETWORK_TABLE()
+
+LINK_ENTITY_TO_CLASS( func_useableladder, CFuncLadder );
+
+//---------------------------------------------------------
+// Save/Restore
+//---------------------------------------------------------
+BEGIN_DATADESC( CFuncLadder )
+ DEFINE_KEYFIELD( m_vecPlayerMountPositionTop, FIELD_VECTOR, "point0" ),
+ DEFINE_KEYFIELD( m_vecPlayerMountPositionBottom, FIELD_VECTOR, "point1" ),
+
+ DEFINE_FIELD( m_vecLadderDir, FIELD_VECTOR ),
+ // DEFINE_FIELD( m_Dismounts, FIELD_UTLVECTOR ),
+
+ DEFINE_FIELD( m_bFakeLadder, FIELD_BOOLEAN ),
+ DEFINE_KEYFIELD( m_bDisabled, FIELD_BOOLEAN, "StartDisabled" ),
+
+#if !defined( CLIENT_DLL )
+ DEFINE_KEYFIELD( m_surfacePropName,FIELD_STRING, "ladderSurfaceProperties" ),
+ DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ),
+ DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ),
+
+ DEFINE_OUTPUT( m_OnPlayerGotOnLadder, "OnPlayerGotOnLadder" ),
+ DEFINE_OUTPUT( m_OnPlayerGotOffLadder, "OnPlayerGotOffLadder" ),
+#endif
+
+END_DATADESC()
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CInfoLadderDismount::DrawDebugGeometryOverlays()
+{
+#if !defined( CLIENT_DLL )
+ BaseClass::DrawDebugGeometryOverlays();
+
+ if ( developer.GetBool() )
+ {
+ NDebugOverlay::Box( GetAbsOrigin(), Vector( -16, -16, 0 ), Vector( 16, 16, 8 ), 127, 127, 127, 127, 0 );
+ }
+#endif
+}
+
+#if defined( GAME_DLL )
+int CFuncLadder::UpdateTransmitState()
+{
+ // transmit if in PVS for clientside prediction
+ return SetTransmitState( FL_EDICT_PVSCHECK );
+}
+#endif
+
+IMPLEMENT_NETWORKCLASS_ALIASED( InfoLadderDismount, DT_InfoLadderDismount );
+
+BEGIN_NETWORK_TABLE( CInfoLadderDismount, DT_InfoLadderDismount )
+END_NETWORK_TABLE()
+
+LINK_ENTITY_TO_CLASS( info_ladder_dismount, CInfoLadderDismount );
+
+#if defined(GAME_DLL)
+const char *FuncLadder_GetSurfaceprops(CBaseEntity *pLadderEntity)
+{
+ CFuncLadder *pLadder = dynamic_cast<CFuncLadder *>(pLadderEntity);
+ if ( pLadder )
+ {
+ if ( pLadder->GetSurfacePropName() )
+ return pLadder->GetSurfacePropName();
+ }
+ return "ladder";
+}
+#endif
\ No newline at end of file |