//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ // //=============================================================================// // cs_simple_hostage.h // Simple CS1.6 level hostage // Author: Michael S. Booth, July 2004 #ifndef _CS_SIMPLE_HOSTAGE_H_ #define _CS_SIMPLE_HOSTAGE_H_ #include "nav_mesh.h" #include "cs_nav_path.h" #include "cs_nav_pathfind.h" #include "improv_locomotor.h" #include "cs_playeranimstate.h" class CCSPlayer; //---------------------------------------------------------------------------------------------------------------- /** * A Counter-Strike Hostage */ class CHostage : public CBaseCombatCharacter, public CImprovLocomotor, public ICSPlayerAnimStateHelpers { public: DECLARE_CLASS( CHostage, CBaseCombatCharacter ); DECLARE_SERVERCLASS(); DECLARE_DATADESC(); CHostage( void ); virtual ~CHostage(); public: virtual void Spawn( void ); virtual void Precache(); int ObjectCaps( void ) { return (BaseClass::ObjectCaps() | FCAP_IMPULSE_USE); } // make hostage "useable" virtual void PhysicsSimulate( void ); virtual int OnTakeDamage_Alive( const CTakeDamageInfo &info ); virtual void TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator ); virtual void Event_Killed( const CTakeDamageInfo &info ); virtual void Touch( CBaseEntity *other ); // in contact with "other" void HostageRescueZoneTouch( inputdata_t &inputdata ); // invoked when hostage touches a rescue zone void HostageThink( void ); // periodic update to initiate behaviors void GiveCTUseBonus( CCSPlayer *rescuer ); // give bonus to CT's for talking to a hostage void CheckForHostageAbuse( CCSPlayer *player ); // check for hostage-killer abuse // queries bool IsFollowingSomeone( void ); bool IsFollowing( const CBaseEntity *entity ); bool IsValid( void ) const; bool IsRescuable( void ) const; bool IsRescued( void ) const; bool IsOnGround( void ) const; bool IsVisible( const Vector &pos, bool testFOV = false ) const; // return true if hostage can see position // hostage states void Idle( void ); // stand idle void Follow( CCSPlayer *leader ); // begin following "leader" CCSPlayer *GetLeader( void ) const; // return our leader, or NULL void FaceTowards( const Vector &target, float deltaT ); // rotate body to face towards "target" void ApplyForce( const Vector &force ) { m_accel += force; } // apply a force to the hostage unsigned int PhysicsSolidMaskForEntity() const; Class_T Classify ( void ) { return CLASS_PLAYER_ALLY; } public: // begin CImprovLocomotor ----------------------------------------------------------------------------------------------------------------- virtual const Vector &GetCentroid( void ) const; virtual const Vector &GetFeet( void ) const; // return position of "feet" - point below centroid of improv at feet level virtual const Vector &GetEyes( void ) const; virtual float GetMoveAngle( void ) const; // return direction of movement virtual CNavArea *GetLastKnownArea( void ) const; virtual bool GetSimpleGroundHeightWithFloor( const Vector &pos, float *height, Vector *normal = NULL ); // find "simple" ground height, treating current nav area as part of the floor virtual void Crouch( void ); virtual void StandUp( void ); // "un-crouch" virtual bool IsCrouching( void ) const; virtual void Jump( void ); // initiate a jump virtual bool IsJumping( void ) const; virtual void Run( void ); // set movement speed to running virtual void Walk( void ); // set movement speed to walking virtual bool IsRunning( void ) const; virtual void StartLadder( const CNavLadder *ladder, NavTraverseType how, const Vector &approachPos, const Vector &departPos ); // invoked when a ladder is encountered while following a path virtual bool TraverseLadder( const CNavLadder *ladder, NavTraverseType how, const Vector &approachPos, const Vector &departPos, float deltaT ); // traverse given ladder virtual bool IsUsingLadder( void ) const; virtual void TrackPath( const Vector &pathGoal, float deltaT ); // move along path by following "pathGoal" virtual void OnMoveToSuccess( const Vector &goal ); // invoked when an improv reaches its MoveTo goal virtual void OnMoveToFailure( const Vector &goal, MoveToFailureType reason ); // invoked when an improv fails to reach a MoveTo goal // end CImprovLocomotor ------------------------------------------------------------------------------------------------------------------- // ICSPlayerAnimState overrides. public: virtual CWeaponCSBase* CSAnim_GetActiveWeapon(); virtual bool CSAnim_CanMove(); protected: virtual void HostageUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); private: float GetModifiedDamage( float flDamage, int nHitGroup ); ICSPlayerAnimState *m_PlayerAnimState; IMPLEMENT_NETWORK_VAR_FOR_DERIVED( m_iMaxHealth ); IMPLEMENT_NETWORK_VAR_FOR_DERIVED( m_iHealth ); IMPLEMENT_NETWORK_VAR_FOR_DERIVED( m_lifeState ); CNetworkVar( bool, m_isRescued ); // true if the hostage has been rescued CNetworkVar( EHANDLE, m_leader ); // the player we are following void UpdateFollowing( float deltaT ); // do following behavior int m_lastLeaderID; CountdownTimer m_reuseTimer; // to throttle how often hostage can be used bool m_hasBeenUsed; // flag to give first rescuer bonus money Vector m_vel; Vector m_accel; bool m_isRunning; // true if hostage move speed is to run (walk if false) bool m_isCrouching; // true if hostage is crouching CountdownTimer m_jumpTimer; // if zero, we can jump bool m_isWaitingForLeader; // true if we are waiting for our rescuer to move CCSNavPath m_path; // current path to follow CountdownTimer m_repathTimer; // throttle pathfinder CountdownTimer m_inhibitDoorTimer; CNavPathFollower m_pathFollower; // path tracking mechanism CountdownTimer m_inhibitObstacleAvoidanceTimer; // when active, turn off path following feelers CNavArea *m_lastKnownArea; // last area we were in void Wiggle( void ); // attempt to wiggle-out of begin stuck CountdownTimer m_wiggleTimer; // for wiggling NavRelativeDirType m_wiggleDirection; bool m_isAdjusted; // hack for adjusting bounding box float m_disappearTime; // has finished fading, remove me void PushawayThink( void ); // pushes physics objects away from the hostage void AvoidPhysicsProps( void ); // guides the hostage away from physics props }; //-------------------------------------------------------------------------------------------------------------- /** * Functor used with NavAreaBuildPath() for building Hostage paths. * Once we hook up crouching and ladders, this can be removed and ShortestPathCost() can be used instead. */ class HostagePathCost { public: // HPE_TODO[pmf]: check that these new parameters are okay to be ignored float operator() ( CNavArea *area, CNavArea *fromArea, const CNavLadder *ladder, const CFuncElevator *elevator, float length ) { if (fromArea == NULL) { // first area in path, no cost return 0.0f; } else { // if this area isn't available to hostages, skip it if ( area->GetAttributes() & NAV_MESH_NO_HOSTAGES ) { return -1.0f; } // compute distance travelled along path so far float dist; if (ladder) { // can't traverse ladders return -1.0f; } else { dist = (area->GetCenter() - fromArea->GetCenter()).Length(); } float cost = dist + fromArea->GetCostSoFar(); if (area->GetAttributes() & NAV_MESH_CROUCH) // && !(area->GetAttributes() & NAV_MESH_JUMP)) { // can't traverse areas that require crouching return -1.0f; } // if this is a "jump" area, add penalty if (area->GetAttributes() & NAV_MESH_JUMP) { const float jumpPenalty = 5.0f; cost += jumpPenalty * dist; } return cost; } } }; //-------------------------------------------------------------------------------------------------------------- // All the hostage entities. extern CUtlVector< CHostage * > g_Hostages; //-------------------------------------------------------------------------------------------------------------- /** * Iterate over all active hostages in the game, invoking functor on each. * If functor returns false, stop iteration and return false. */ template < typename Functor > bool ForEachHostage( Functor &func ) { for( int i=0; iIsValid() ) continue; if ( func( hostage ) == false ) return false; } return true; } #endif // _CS_SIMPLE_HOSTAGE_H_