diff options
Diffstat (limited to 'game/server/tf/bot/behavior/medic/tf_bot_medic_retreat.cpp')
| -rw-r--r-- | game/server/tf/bot/behavior/medic/tf_bot_medic_retreat.cpp | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/game/server/tf/bot/behavior/medic/tf_bot_medic_retreat.cpp b/game/server/tf/bot/behavior/medic/tf_bot_medic_retreat.cpp new file mode 100644 index 0000000..d3d8ed6 --- /dev/null +++ b/game/server/tf/bot/behavior/medic/tf_bot_medic_retreat.cpp @@ -0,0 +1,144 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// tf_bot_retreat.cpp +// Retreat towards our spawn to find another patient +// Michael Booth, May 2009 + +#include "cbase.h" +#include "tf_player.h" +#include "tf_gamerules.h" +#include "tf_weapon_medigun.h" +#include "bot/tf_bot.h" +#include "bot/behavior/medic/tf_bot_medic_retreat.h" + +#include "nav_mesh.h" + +extern ConVar tf_bot_path_lookahead_range; +extern ConVar tf_bot_medic_follow_range; +extern ConVar tf_bot_force_class; + + +//--------------------------------------------------------------------------------------------- +ActionResult< CTFBot > CTFBotMedicRetreat::OnStart( CTFBot *me, Action< CTFBot > *priorAction ) +{ + CTFNavArea *homeArea = me->GetSpawnArea(); + + if ( homeArea == NULL ) + { + return Done( "No home area!" ); + } + + m_path.SetMinLookAheadDistance( tf_bot_path_lookahead_range.GetFloat() ); + + CTFBotPathCost cost( me, FASTEST_ROUTE ); + m_path.Compute( me, homeArea->GetCenter(), cost ); + + return Continue(); +} + + +//--------------------------------------------------------------------------------------------- +class CUsefulHealTargetFilter : public INextBotEntityFilter +{ +public: + CUsefulHealTargetFilter( int team ) + { + m_team = team; + } + + virtual bool IsAllowed( CBaseEntity *entity ) const + { + if ( entity && entity->IsPlayer() && entity->GetTeamNumber() == m_team ) + { + return !ToTFPlayer( entity )->IsPlayerClass( TF_CLASS_MEDIC ) && !ToTFPlayer( entity )->IsPlayerClass( TF_CLASS_SNIPER ); + } + return false; + } + + int m_team; +}; + + +//--------------------------------------------------------------------------------------------- +ActionResult< CTFBot > CTFBotMedicRetreat::Update( CTFBot *me, float interval ) +{ + // equip the syringegun and defend ourselves! + CTFWeaponBase *myWeapon = me->m_Shared.GetActiveTFWeapon(); + if ( myWeapon ) + { + if ( myWeapon->GetWeaponID() != TF_WEAPON_SYRINGEGUN_MEDIC ) + { + CBaseCombatWeapon *syringeGun = me->Weapon_GetSlot( TF_WPN_TYPE_PRIMARY ); + + if ( syringeGun ) + { + me->Weapon_Switch( syringeGun ); + } + } + } + + m_path.Update( me ); + + // look around to try to spot a friend to heal + if ( m_lookAroundTimer.IsElapsed() ) + { + m_lookAroundTimer.Start( RandomFloat( 0.33f, 1.0f ) ); + + QAngle angle; + angle.x = 0.0f; + angle.y = RandomFloat( -180.0f, 180.0f ); + angle.z = 0.0f; + + Vector forward; + AngleVectors( angle, &forward ); + + me->GetBodyInterface()->AimHeadTowards( me->EyePosition() + forward, IBody::IMPORTANT, 0.1f, NULL, "Looking for someone to heal" ); + } + + // if we see a friend, heal them + CUsefulHealTargetFilter filter( me->GetTeamNumber() ); + const CKnownEntity *known = me->GetVisionInterface()->GetClosestKnown( filter ); + if ( known ) + { + return Done( "I know of a teammate" ); + } + + return Continue(); +} + + +//--------------------------------------------------------------------------------------------- +ActionResult< CTFBot > CTFBotMedicRetreat::OnResume( CTFBot *me, Action< CTFBot > *interruptingAction ) +{ + CTFBotPathCost cost( me, FASTEST_ROUTE ); + m_path.Compute( me, me->GetSpawnArea()->GetCenter(), cost ); + + return Continue(); +} + + +//--------------------------------------------------------------------------------------------- +EventDesiredResult< CTFBot > CTFBotMedicRetreat::OnStuck( CTFBot *me ) +{ + CTFBotPathCost cost( me, FASTEST_ROUTE ); + m_path.Compute( me, me->GetSpawnArea()->GetCenter(), cost ); + + return TryContinue(); +} + + +//--------------------------------------------------------------------------------------------- +EventDesiredResult< CTFBot > CTFBotMedicRetreat::OnMoveToFailure( CTFBot *me, const Path *path, MoveToFailureType reason ) +{ + CTFBotPathCost cost( me, FASTEST_ROUTE ); + m_path.Compute( me, me->GetSpawnArea()->GetCenter(), cost ); + + return TryContinue(); +} + + +//--------------------------------------------------------------------------------------------- +QueryResultType CTFBotMedicRetreat::ShouldAttack( const INextBot *me, const CKnownEntity *them ) const +{ + // defend ourselves! + return ANSWER_YES; +} |