//----------------------------------------------------------------------------- // 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: //----------------------------------------------------------------------------- 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 }
void CHL2GameMovement::GetSortedDismountNodeList( const Vector &org, float radius, CFuncLadder *ladder, CUtlRBTree< NearbyDismount_t, int >& list ) { float radiusSqr = radius * radius; int i; int c = ladder->GetDismountCount(); for ( i = 0; i < c; i++ ) { CInfoLadderDismount *spot = ladder->GetDismount( i ); if ( !spot ) continue; float distSqr = ( spot->GetAbsOrigin() - org ).LengthSqr(); if ( distSqr > radiusSqr ) continue; NearbyDismount_t nd; nd.dismount = spot; nd.distSqr = distSqr; list.Insert( nd ); } }
//----------------------------------------------------------------------------- // Purpose: // *ladder - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CHL2GameMovement::ExitLadderViaDismountNode( CFuncLadder *ladder, bool strict, bool useAlternate ) { // Find the best ladder exit node float bestDot = -99999.0f; float bestDistance = 99999.0f; Vector bestDest; bool found = false; // For 'alternate' dismount bool foundAlternate = false; Vector alternateDest; float alternateDist = 99999.0f; CUtlRBTree< NearbyDismount_t, int > nearbyDismounts( 0, 0, NearbyDismountLessFunc ); GetSortedDismountNodeList( mv->GetAbsOrigin(), 100.0f, ladder, nearbyDismounts ); int i; for ( i = nearbyDismounts.FirstInorder(); i != nearbyDismounts.InvalidIndex() ; i = nearbyDismounts.NextInorder( i ) ) { CInfoLadderDismount *spot = nearbyDismounts[ i ].dismount; if ( !spot ) { Assert( !"What happened to the spot!!!" ); continue; } // See if it's valid to put the player there... Vector org = spot->GetAbsOrigin() + Vector( 0, 0, 1 ); trace_t tr; UTIL_TraceHull( org, org, GetPlayerMins( ( player->GetFlags() & FL_DUCKING ) ? true : false ), GetPlayerMaxs( ( player->GetFlags() & FL_DUCKING ) ? true : false ), MASK_PLAYERSOLID, player, COLLISION_GROUP_PLAYER_MOVEMENT, &tr ); // Nope... if ( tr.startsolid ) { continue; } // Find the best dot product Vector vecToSpot = org - ( mv->GetAbsOrigin() + player->GetViewOffset() ); vecToSpot.z = 0.0f; float d = VectorNormalize( vecToSpot ); float dot = vecToSpot.Dot( m_vecForward ); // We're not facing at it...ignore if ( dot < 0.5f ) { if( useAlternate && d < alternateDist ) { alternateDest = org; alternateDist = d; foundAlternate = true; } continue; } if ( dot > bestDot ) { bestDest = org; bestDistance = d; bestDot = dot; found = true; } } if ( found ) { // Require a more specific if ( strict && ( ( bestDot < 0.7f ) || ( bestDistance > 40.0f ) ) ) { return false; } StartForcedMove( false, player->MaxSpeed(), bestDest, NULL ); return true; } if( useAlternate ) { // Desperate. Don't refuse to let a person off of a ladder if it can be helped. Use the // alternate dismount if there is one. if( foundAlternate && alternateDist <= 60.0f ) { StartForcedMove( false, player->MaxSpeed(), alternateDest, NULL ); return true; } } return false; }