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.
191 lines
5.3 KiB
191 lines
5.3 KiB
4 years ago
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
// tf_bot_engineer_build_teleport_exit.cpp
|
||
|
// Engineer building a teleport exit
|
||
|
// Michael Booth, May 2010
|
||
|
|
||
|
#include "cbase.h"
|
||
|
#include "nav_mesh.h"
|
||
|
#include "tf_player.h"
|
||
|
#include "tf_obj.h"
|
||
|
#include "tf_obj_sentrygun.h"
|
||
|
#include "tf_weapon_builder.h"
|
||
|
#include "bot/tf_bot.h"
|
||
|
#include "bot/behavior/engineer/tf_bot_engineer_build_teleport_exit.h"
|
||
|
#include "bot/behavior/tf_bot_get_ammo.h"
|
||
|
|
||
|
extern ConVar tf_bot_path_lookahead_range;
|
||
|
|
||
|
|
||
|
//---------------------------------------------------------------------------------------------
|
||
|
CTFBotEngineerBuildTeleportExit::CTFBotEngineerBuildTeleportExit( void )
|
||
|
{
|
||
|
m_hasPreciseBuildLocation = false;
|
||
|
}
|
||
|
|
||
|
|
||
|
//---------------------------------------------------------------------------------------------
|
||
|
CTFBotEngineerBuildTeleportExit::CTFBotEngineerBuildTeleportExit( const Vector &buildLocation, float buildAngle )
|
||
|
{
|
||
|
m_hasPreciseBuildLocation = true;
|
||
|
m_buildLocation = buildLocation;
|
||
|
m_buildAngle = buildAngle;
|
||
|
}
|
||
|
|
||
|
|
||
|
//---------------------------------------------------------------------------------------------
|
||
|
ActionResult< CTFBot > CTFBotEngineerBuildTeleportExit::OnStart( CTFBot *me, Action< CTFBot > *priorAction )
|
||
|
{
|
||
|
if ( !m_hasPreciseBuildLocation )
|
||
|
{
|
||
|
// if no specific build location given, just build right where we are
|
||
|
m_buildLocation = me->GetAbsOrigin();
|
||
|
}
|
||
|
|
||
|
m_giveUpTimer.Start( 3.1f );
|
||
|
m_path.Invalidate();
|
||
|
|
||
|
return Continue();
|
||
|
}
|
||
|
|
||
|
|
||
|
//---------------------------------------------------------------------------------------------
|
||
|
ActionResult< CTFBot > CTFBotEngineerBuildTeleportExit::Update( CTFBot *me, float interval )
|
||
|
{
|
||
|
if ( me->GetTimeSinceLastInjury() < 1.0f )
|
||
|
{
|
||
|
return Done( "Ouch! I'm under attack" );
|
||
|
}
|
||
|
|
||
|
CBaseObject *myTeleportEntrance = me->GetObjectOfType( OBJ_TELEPORTER, MODE_TELEPORTER_EXIT );
|
||
|
if ( myTeleportEntrance )
|
||
|
{
|
||
|
// successfully built
|
||
|
return Done( "Teleport exit built" );
|
||
|
}
|
||
|
|
||
|
|
||
|
// collect metal as we move to our build location
|
||
|
if ( me->CanBuild( OBJ_TELEPORTER, MODE_TELEPORTER_EXIT ) == CB_NEED_RESOURCES )
|
||
|
{
|
||
|
if ( m_getAmmoTimer.IsElapsed() && CTFBotGetAmmo::IsPossible( me ) )
|
||
|
{
|
||
|
// need more metal - get some
|
||
|
m_getAmmoTimer.Start( 1.0f );
|
||
|
return SuspendFor( new CTFBotGetAmmo, "Need more metal to build my Teleporter Exit" );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// move near our build position
|
||
|
const float buildRange = 50.0f;
|
||
|
if ( me->IsRangeGreaterThan( m_buildLocation, buildRange ) )
|
||
|
{
|
||
|
// move into position
|
||
|
if ( !m_path.IsValid() || m_repathTimer.IsElapsed() )
|
||
|
{
|
||
|
CTFBotPathCost cost( me, FASTEST_ROUTE );
|
||
|
m_path.Compute( me, m_buildLocation, cost );
|
||
|
|
||
|
m_repathTimer.Start( RandomFloat( 2.0f, 3.0f ) );
|
||
|
}
|
||
|
|
||
|
m_path.Update( me );
|
||
|
|
||
|
// don't give up until we've reached our build location
|
||
|
m_giveUpTimer.Reset();
|
||
|
|
||
|
return Continue();
|
||
|
}
|
||
|
|
||
|
// in position to build
|
||
|
if ( m_giveUpTimer.IsElapsed() )
|
||
|
{
|
||
|
return Done( "Taking too long - giving up" );
|
||
|
}
|
||
|
|
||
|
if ( m_hasPreciseBuildLocation )
|
||
|
{
|
||
|
me->GetBodyInterface()->AimHeadTowards( m_buildLocation, IBody::CRITICAL, 1.0f, NULL, "Looking toward my precise build location" );
|
||
|
|
||
|
// directly create a teleporter exit at the precise position and orientation desired
|
||
|
CObjectTeleporter *myTeleporterExit = (CObjectTeleporter *)CreateEntityByName( "obj_teleporter" );
|
||
|
if ( myTeleporterExit )
|
||
|
{
|
||
|
myTeleporterExit->SetObjectMode( MODE_TELEPORTER_EXIT );
|
||
|
myTeleporterExit->SetAbsOrigin( m_buildLocation );
|
||
|
myTeleporterExit->SetAbsAngles( QAngle( 0, m_buildAngle, 0 ) );
|
||
|
myTeleporterExit->Spawn();
|
||
|
|
||
|
myTeleporterExit->StartPlacement( me );
|
||
|
myTeleporterExit->StartBuilding( me );
|
||
|
myTeleporterExit->SetBuilder( me );
|
||
|
|
||
|
// teleporter exits are solid blockers - put engineer on top of exit or he'll be stuck
|
||
|
Vector myNewOrigin = me->GetAbsOrigin();
|
||
|
myNewOrigin.z += me->GetLocomotionInterface()->GetStepHeight();
|
||
|
|
||
|
me->SetAbsOrigin( myNewOrigin );
|
||
|
|
||
|
return Done( "Teleport exit built at precise location" );
|
||
|
}
|
||
|
|
||
|
return Continue();
|
||
|
}
|
||
|
|
||
|
|
||
|
// build exit roughly at this spot
|
||
|
CTFWeaponBase *myGun = me->GetActiveTFWeapon();
|
||
|
if ( myGun )
|
||
|
{
|
||
|
CTFWeaponBuilder *builder = dynamic_cast< CTFWeaponBuilder * >( myGun );
|
||
|
if ( builder )
|
||
|
{
|
||
|
if ( builder->IsValidPlacement() )
|
||
|
{
|
||
|
// place it down
|
||
|
me->PressFireButton();
|
||
|
}
|
||
|
else if ( m_searchTimer.IsElapsed() )
|
||
|
{
|
||
|
// rotate to find valid spot
|
||
|
Vector forward;
|
||
|
float angle = RandomFloat( -M_PI, M_PI );
|
||
|
FastSinCos( angle, &forward.y, &forward.x );
|
||
|
|
||
|
forward.z = 0.0f;
|
||
|
|
||
|
me->GetBodyInterface()->AimHeadTowards( me->EyePosition() - 100.0f * forward, IBody::CRITICAL, 1.0f, NULL, "Trying to place my teleport exit" );
|
||
|
|
||
|
m_searchTimer.Start( 1.0f );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// switch to teleporter builder
|
||
|
me->StartBuildingObjectOfType( OBJ_TELEPORTER, MODE_TELEPORTER_EXIT );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return Continue();
|
||
|
}
|
||
|
|
||
|
|
||
|
//---------------------------------------------------------------------------------------------
|
||
|
ActionResult< CTFBot > CTFBotEngineerBuildTeleportExit::OnResume( CTFBot *me, Action< CTFBot > *interruptingAction )
|
||
|
{
|
||
|
m_giveUpTimer.Reset();
|
||
|
m_path.Invalidate();
|
||
|
|
||
|
return Continue();
|
||
|
}
|
||
|
|
||
|
|
||
|
//---------------------------------------------------------------------------------------------
|
||
|
EventDesiredResult< CTFBot > CTFBotEngineerBuildTeleportExit::OnStuck( CTFBot *me )
|
||
|
{
|
||
|
m_path.Invalidate();
|
||
|
|
||
|
return TryContinue();
|
||
|
}
|
||
|
|
||
|
|