You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
132 lines
3.4 KiB
132 lines
3.4 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// crybaby_boss_escape.cpp |
|
// Crybaby Boss runs to the pit in Mann Manor to escape |
|
// Michael Booth, October 2011 |
|
|
|
#include "cbase.h" |
|
|
|
#include "nav_mesh.h" |
|
#include "tf_player.h" |
|
|
|
#include "../headless_hatman.h" |
|
#include "crybaby_boss_escape.h" |
|
#include "crybaby_boss_attack.h" |
|
|
|
extern ConVar tf_bot_path_lookahead_range; |
|
|
|
|
|
//--------------------------------------------------------------------------------------------- |
|
ActionResult< CHeadlessHatman > CCryBabyBossEscape::OnStart( CHeadlessHatman *me, Action< CHeadlessHatman > *priorAction ) |
|
{ |
|
m_path.SetMinLookAheadDistance( tf_bot_path_lookahead_range.GetFloat() ); |
|
|
|
return Continue(); |
|
} |
|
|
|
|
|
//--------------------------------------------------------------------------------------------- |
|
ActionResult< CHeadlessHatman > CCryBabyBossEscape::Update( CHeadlessHatman *me, float interval ) |
|
{ |
|
// any nearby player that taunts me, enrages me and provokes me to attack them! |
|
CUtlVector< CTFPlayer * > playerVector; |
|
CollectPlayers( &playerVector, TEAM_ANY, COLLECT_ONLY_LIVING_PLAYERS ); |
|
|
|
for( int i=0; i<playerVector.Count(); ++i ) |
|
{ |
|
if ( playerVector[i]->m_Shared.InCond( TF_COND_TAUNTING ) ) |
|
{ |
|
const float noticeTauntRange = 750.0f; |
|
if ( me->IsRangeLessThan( playerVector[i], noticeTauntRange ) ) |
|
{ |
|
if ( playerVector[i]->IsLookingTowards( me ) ) |
|
{ |
|
if ( me->IsLineOfSightClear( playerVector[i] ) ) |
|
{ |
|
return SuspendFor( new CCryBabyBossAttack( playerVector[i] ), "DON'T LAUGH AT ME!!!" ); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
// push players away to avoid penetration issues |
|
const float pushRange = 250.0f; |
|
const float pushForce = 200.0f; |
|
|
|
for( int i=0; i<playerVector.Count(); ++i ) |
|
{ |
|
CTFPlayer *player = playerVector[i]; |
|
|
|
Vector toPlayer = player->EyePosition() - me->GetAbsOrigin(); |
|
float range = toPlayer.NormalizeInPlace(); |
|
|
|
if ( range < pushRange ) |
|
{ |
|
// make sure we push players up and away |
|
toPlayer.z = 0.0f; |
|
toPlayer.NormalizeInPlace(); |
|
toPlayer.z = 1.0f; |
|
|
|
Vector push = pushForce * toPlayer; |
|
|
|
player->ApplyAbsVelocityImpulse( push ); |
|
} |
|
} |
|
|
|
// run to the pit and escape |
|
if ( m_repathTimer.IsElapsed() ) |
|
{ |
|
m_repathTimer.Start( RandomFloat( 1.0f, 2.0f ) ); |
|
|
|
CHeadlessHatmanPathCost cost( me ); |
|
|
|
// hack for now |
|
CNavArea *goalArea = TheNavMesh->GetNavAreaByID( 27 ); |
|
if ( !goalArea ) |
|
{ |
|
return Done( "No goal area!" ); |
|
} |
|
|
|
m_path.Compute( me, goalArea->GetCenter(), cost ); |
|
} |
|
|
|
m_path.Update( me ); |
|
|
|
// animation state |
|
if ( me->GetLocomotionInterface()->IsAttemptingToMove() ) |
|
{ |
|
// play running animation |
|
if ( !me->GetBodyInterface()->IsActivity( ACT_MP_RUN_MELEE ) ) |
|
{ |
|
me->GetBodyInterface()->StartActivity( ACT_MP_RUN_MELEE ); |
|
} |
|
|
|
if ( m_footfallTimer.IsElapsed() ) |
|
{ |
|
m_footfallTimer.Start( 0.25f ); |
|
|
|
// periodically shake nearby players' screens when we're moving |
|
UTIL_ScreenShake( me->GetAbsOrigin(), 15.0f, 5.0f, 1.0f, 1000.0f, SHAKE_START ); |
|
} |
|
} |
|
else |
|
{ |
|
// standing still |
|
if ( !me->GetBodyInterface()->IsActivity( ACT_MP_STAND_ITEM1 ) ) |
|
{ |
|
me->GetBodyInterface()->StartActivity( ACT_MP_STAND_ITEM1 ); |
|
} |
|
} |
|
|
|
return Continue(); |
|
} |
|
|
|
|
|
//--------------------------------------------------------------------------------------------- |
|
EventDesiredResult< CHeadlessHatman > CCryBabyBossEscape::OnMoveToSuccess( CHeadlessHatman *me, const Path *path ) |
|
{ |
|
UTIL_Remove( me ); |
|
|
|
return TryDone( RESULT_CRITICAL, "Reached escape pit" ); |
|
} |
|
|
|
|