Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ ActionResult< CTFBot > CTFBotDeliverFlag::Update( CTFBot *me, float interval )

if ( UpgradeOverTime( me ) )
{
return SuspendFor( new CTFBotTaunt, "Taunting for our new upgrade" );
return SuspendFor( new CTFBotTaunt( NULL ), "Taunting for our new upgrade" );
}

return Continue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ ActionResult< CTFBot > CTFBotMobRush::Update( CTFBot *me, float interval )
if ( !m_victim->IsAlive() && me->IsRangeLessThan( m_victim, tf_bot_taunt_range.GetFloat() ) )
{
// we got 'em!
return ChangeTo( new CTFBotTaunt, "Taunt their corpse" );
return ChangeTo( new CTFBotTaunt( NULL ), "Taunt their corpse" );
}

if ( m_vocalizeTimer.IsElapsed() )
Expand Down
17 changes: 9 additions & 8 deletions src/game/server/tf/bot/behavior/tf_bot_behavior.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ ConVar tf_bot_sniper_aim_error( "tf_bot_sniper_aim_error", "0.01", FCVAR_CHEAT )
ConVar tf_bot_sniper_aim_steady_rate( "tf_bot_sniper_aim_steady_rate", "10", FCVAR_CHEAT );
ConVar tf_bot_debug_sniper( "tf_bot_debug_sniper", "0", FCVAR_CHEAT );
ConVar tf_bot_fire_weapon_min_time( "tf_bot_fire_weapon_min_time", "1", FCVAR_CHEAT );
ConVar tf_bot_taunt_victim_chance( "tf_bot_taunt_victim_chance", "20" ); // community requested this not be a cheat cvar
ConVar tf_bot_taunt_victim_chance( "tf_bot_taunt_victim_chance", "20", FCVAR_NONE, "Percent chance a bot will taunt a victim after a kill", true, 0.f, true, 100.f ); // community requested this not be a cheat cvar

ConVar tf_bot_notice_backstab_chance( "tf_bot_notice_backstab_chance", "25", FCVAR_CHEAT );
ConVar tf_bot_notice_backstab_min_range( "tf_bot_notice_backstab_min_range", "100", FCVAR_CHEAT );
Expand All @@ -51,7 +51,7 @@ ConVar tf_bot_hitscan_range_limit( "tf_bot_hitscan_range_limit", "1800", FCVAR_C
ConVar tf_bot_always_full_reload( "tf_bot_always_full_reload", "0", FCVAR_CHEAT );

ConVar tf_bot_fire_weapon_allowed( "tf_bot_fire_weapon_allowed", "1", FCVAR_CHEAT, "If zero, TFBots will not pull the trigger of their weapons (but will act like they did)" );
ConVar tf_bot_reevaluate_class_in_spawnroom( "tf_bot_reevaluate_class_in_spawnroom", "1", FCVAR_CHEAT, "If set, bots will opportunisticly switch class while in spawnrooms if their current class is no longer their first choice." );
ConVar tf_bot_reevaluate_class_in_spawnroom( "tf_bot_reevaluate_class_in_spawnroom", "1", FCVAR_CHEAT, "If set, bots will opportunistically switch class while in spawnrooms if their current class is no longer their first choice." );


//---------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -107,9 +107,10 @@ ActionResult< CTFBot > CTFBotMainAction::Update( CTFBot *me, float interval )
}

// Should I accept taunt from my partner?
if ( me->FindPartnerTauntInitiator() )
CTFPlayer* initiator = me->FindPartnerTauntInitiator();
if ( initiator )
{
return SuspendFor( new CTFBotTaunt, "Responding to teammate partner taunt" );
return SuspendFor( new CTFBotTaunt( initiator ), "Responding to teammate partner taunt" );
}

// make sure our vision FOV matches the player's
Expand Down Expand Up @@ -571,18 +572,18 @@ EventDesiredResult< CTFBot > CTFBotMainAction::OnOtherKilled( CTFBot *me, CBaseC

if ( !ToTFPlayer( victim )->IsBot() && me->IsEnemy( victim ) && me->IsSelf( info.GetAttacker() ) )
{
bool isTaunting = !me->HasTheFlag() && RandomFloat( 0.0f, 100.0f ) <= tf_bot_taunt_victim_chance.GetFloat();
bool shouldTaunt = !me->HasTheFlag() && RandomFloat( 0.0f, 100.0f ) < tf_bot_taunt_victim_chance.GetFloat();
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the <= was causing a bug where even at cvar 0 they could taunt


if ( TFGameRules()->IsMannVsMachineMode() && me->IsMiniBoss() )
{
// Bosses don't taunt puny humans
isTaunting = false;
shouldTaunt = false;
}

if ( isTaunting )
if ( shouldTaunt )
{
// we just killed a human - taunt!
return TrySuspendFor( new CTFBotTaunt, RESULT_IMPORTANT, "Taunting our victim" );
return TrySuspendFor( new CTFBotTaunt( NULL ), RESULT_IMPORTANT, "Taunting our victim" );
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/game/server/tf/bot/behavior/tf_bot_tactical_monitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ ActionResult< CTFBot > CTFBotTacticalMonitor::Update( CTFBot *me, float interval
// don't ack again for awhile
m_acknowledgeRetryTimer.Start( RandomFloat( 10.0f, 20.0f ) );

return SuspendFor( new CTFBotTaunt, "Acknowledging friendly human attention" );
return SuspendFor( new CTFBotTaunt( NULL ), "Acknowledging friendly human attention" );
}
}
}
Expand Down Expand Up @@ -419,7 +419,7 @@ EventDesiredResult< CTFBot > CTFBotTacticalMonitor::OnCommandString( CTFBot *me,
}
else if ( FStrEq( command, "taunt" ) )
{
return TrySuspendFor( new CTFBotTaunt(), RESULT_TRY, "Received command to taunt" );
return TrySuspendFor( new CTFBotTaunt( NULL ), RESULT_TRY, "Received command to taunt" );
}
else if ( FStrEq( command, "cloak" ) )
{
Expand Down
127 changes: 118 additions & 9 deletions src/game/server/tf/bot/behavior/tf_bot_taunt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,24 @@
#include "bot/behavior/tf_bot_taunt.h"


ConVar tf_bot_taunt_stop_chance( "tf_bot_taunt_stop_chance", "30", FCVAR_NONE, "Percent chance a bot will stop taunting for looping/mimic taunts, checked every 5 seconds except in setup", true, 0.f, true, 100.f );


CTFBotTaunt::CTFBotTaunt( CTFPlayer *partner )
{
m_partner = partner;
}


//---------------------------------------------------------------------------------------------
ActionResult< CTFBot > CTFBotTaunt::OnStart( CTFBot *me, Action< CTFBot > *priorAction )
{
// wait a short random time so entire mob doesn't taunt in unison
m_tauntTimer.Start( RandomFloat( 0, 1.0f ) );
m_tauntTimer.Start( RandomFloat( 0, 1.f ) );
m_didTaunt = false;
m_currTauntTurnSpeed = 0.f;
m_targetTauntYaw = 0.f;
m_hasTauntYaw = false;

return Continue();
}
Expand All @@ -25,29 +37,126 @@ ActionResult< CTFBot > CTFBotTaunt::Update( CTFBot *me, float interval )
{
if ( m_tauntTimer.IsElapsed() )
{
const float tauntStopCheckInterval = 5.f;
if ( m_didTaunt )
{
// Stop taunting after a while
if ( m_tauntEndTimer.IsElapsed() && me->m_Shared.GetTauntIndex() == TAUNT_LONG )
// Stop taunting when the timer is up
if ( m_tauntEndTimer.HasStarted() && m_tauntEndTimer.IsElapsed() && me->m_Shared.GetTauntIndex() == TAUNT_LONG )
{
me->ReleaseForwardButton();
me->EndLongTaunt();
}

if ( me->m_Shared.InCond( TF_COND_TAUNTING ) == false )
if ( !me->IsTaunting() )
{
return Done( "Taunt finished" );
}
}

if ( m_partner != NULL && m_partner->IsTaunting() && me->CanMoveDuringTaunt() )
{
if ( m_tauntStopCheckTimer.HasStarted() && m_tauntStopCheckTimer.IsElapsed() )
{
// if not in setup, roll to stop taunting early
if ( !TFGameRules()->InSetup() && RandomFloat( 0.0f, 100.0f ) < tf_bot_taunt_stop_chance.GetFloat() )
{
m_tauntEndTimer.Start( RandomFloat( 0.8f, 2.f ) );
m_tauntStopCheckTimer.Invalidate();
}
else
{
m_tauntStopCheckTimer.Start( tauntStopCheckInterval );
}
}

// store taunt yaw now that we are actually taunting
if ( !m_hasTauntYaw )
{
m_targetTauntYaw = me->GetTauntYaw();
m_hasTauntYaw = true;
}

const float nearbyRange = 50.f;
const float maxFacingAngle = 10.f;

// if outside range of the target, move towards them and turn to face them
if ( me->IsRangeGreaterThan( m_partner, nearbyRange ) )
{
// Force move forwards
me->PressForwardButton( interval );

Vector toPartner = m_partner->GetAbsOrigin() - me->GetAbsOrigin();
toPartner.z = 0.f;
// diff > maxFacingAngle or < -maxFacingAngle requires turning
float diff = UTIL_AngleDiff( UTIL_VecToYaw( toPartner ), m_targetTauntYaw );

float flTauntTurnAccelerationTime = me->GetTauntTurnAccelerationTime();
// Ported from C_TFPlayer::CreateMove
float flSign = fabsf( diff ) > maxFacingAngle ? 1.f : -1.f;
float flMaxTurnSpeed = me->GetTauntTurnSpeed();
if ( flTauntTurnAccelerationTime > 0.f )
{
m_currTauntTurnSpeed = clamp( m_currTauntTurnSpeed + flSign * ( interval / flTauntTurnAccelerationTime ) * flMaxTurnSpeed, 0.f, flMaxTurnSpeed );
}
else
{
m_currTauntTurnSpeed = flMaxTurnSpeed;
}

float flSmoothTurnSpeed = 0.f;
if ( flMaxTurnSpeed > 0.f )
{
flSmoothTurnSpeed = SimpleSpline( m_currTauntTurnSpeed / flMaxTurnSpeed ) * flMaxTurnSpeed;
}

// mimics angMoveAngle handling from C_TFPlayer::CreateMove
// target yaw accumulates even if current taunt yaw/AimHeadTowards hasn't caught up
if ( diff > maxFacingAngle )
{
m_targetTauntYaw += flSmoothTurnSpeed * interval;
}
else if ( diff < -maxFacingAngle )
{
m_targetTauntYaw -= flSmoothTurnSpeed * interval;
}

// calculates a world point to look at based on target yaw so we get smooth turning
Vector aimDir;
AngleVectors( QAngle( 0.f, m_targetTauntYaw, 0.f ), &aimDir );
me->GetBodyInterface()->AimHeadTowards( me->EyePosition() + 100.0f * aimDir, IBody::CRITICAL, interval, NULL, "Taunt partner" );
}
else
{
m_currTauntTurnSpeed = 0.f;
m_targetTauntYaw = me->GetTauntYaw();
me->ReleaseForwardButton();
}
}
else
{
m_currTauntTurnSpeed = 0.f;
me->ReleaseForwardButton();
}

const float maxRange = 600.f;

// Start a timer to end our taunt if partner missing, partner not taunting, or can't see/too far from partner
if ( !m_tauntEndTimer.HasStarted()
&& ( m_partner == NULL
|| !m_partner->IsTaunting()
|| !me->GetVisionInterface()->IsLineOfSightClearToEntity( m_partner )
|| me->IsRangeGreaterThan( m_partner, maxRange ) ) )
{
m_tauntEndTimer.Start( RandomFloat( 0.8f, 2.f ) );
m_tauntStopCheckTimer.Invalidate();
}
}
else
{
me->HandleTauntCommand();
// Start a timer to end our taunt in case we're still going after awhile
m_tauntEndTimer.Start( RandomFloat( 3.f, 5.f ) );

m_didTaunt = true;
m_tauntStopCheckTimer.Start( tauntStopCheckInterval );
}
}

return Continue();
}

8 changes: 7 additions & 1 deletion src/game/server/tf/bot/behavior/tf_bot_taunt.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,26 @@
#ifndef TF_BOT_TAUNT_H
#define TF_BOT_TAUNT_H


//-----------------------------------------------------------------------------
class CTFBotTaunt : public Action< CTFBot >
{
public:
CTFBotTaunt( CTFPlayer *partner );

virtual ActionResult< CTFBot > OnStart( CTFBot *me, Action< CTFBot > *priorAction );
virtual ActionResult< CTFBot > Update( CTFBot *me, float interval );

virtual const char *GetName( void ) const { return "Taunt"; };

private:
CHandle< CTFPlayer > m_partner;
CountdownTimer m_tauntTimer;
CountdownTimer m_tauntEndTimer;
CountdownTimer m_tauntStopCheckTimer;
bool m_didTaunt;
float m_currTauntTurnSpeed;
float m_targetTauntYaw;
bool m_hasTauntYaw;
};


Expand Down
1 change: 1 addition & 0 deletions src/game/server/tf/tf_player.h
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,7 @@ class CTFPlayer : public CBaseMultiplayerPlayer, public IHasAttributes, public I
bool IsTauntForceMovingForward() const { return m_bTauntForceMoveForward; }
float GetTauntMoveAcceleration() const { return m_flTauntMoveAccelerationTime; }
float GetTauntMoveSpeed() const { return m_flTauntForceMoveForwardSpeed; }
float GetTauntTurnSpeed() const { return m_flTauntTurnSpeed; }
float GetTauntTurnAccelerationTime() const { return m_flTauntTurnAccelerationTime; }
virtual int GetAllowedTauntPartnerTeam() const;
CEconItemView *GetTauntEconItemView() { return m_TauntEconItemView.IsValid() ? &m_TauntEconItemView : NULL; }
Expand Down
19 changes: 14 additions & 5 deletions src/game/shared/tf/tf_gamemovement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -657,11 +657,20 @@ bool CTFGameMovement::TauntMove( void )
flMoveDir += mv->m_flForwardMove / cl_backspeed.GetFloat();
}

// No need to read buttons explicitly anymore, since that input is already included in m_flForwardMove
/* if ( mv->m_nButtons & IN_FORWARD )
flMoveDir += 1.f;
if ( mv->m_nButtons & IN_BACK )
flMoveDir += -1.f; */
// Bots set m_flForwardMove to PlayerLocomotion::GetRunSpeed, not cl_forwardspeed.
// Fix their values so that they can TauntMove at the correct speed
if ( m_pTFPlayer->IsBot() )
{
// Bots never end up pressing both of these at once
if ( mv->m_nButtons & IN_FORWARD )
{
flMoveDir = 1.f;
}
else if ( mv->m_nButtons & IN_BACK )
{
flMoveDir = -1.f;
}
}

// Clamp to [0,1], just in case.
if ( flMoveDir > 1.0f )
Expand Down
3 changes: 0 additions & 3 deletions src/game/shared/tf/tf_playeranimstate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -380,9 +380,6 @@ void CTFPlayerAnimState::Update( float eyeYaw, float eyePitch )
// Compute the player sequences.
ComputeSequences( pStudioHdr );

CTFPlayer *pTauntPartner = pTFPlayer->GetTauntPartner();

Vector vPositionToFace = ( pTauntPartner ? pTauntPartner->GetAbsOrigin() : vec3_origin );
Comment on lines -383 to -385
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was entirely unused, and hence cleaned up.

bool bInTaunt = pTFPlayer->m_Shared.InCond( TF_COND_TAUNTING );
bool bInKart = pTFPlayer->m_Shared.InCond( TF_COND_HALLOWEEN_KART );
bool bIsImmobilized = bInTaunt || pTFPlayer->m_Shared.IsControlStunned();
Expand Down