ValveSoftware / Source-1-Games

Source 1 based games such as TF2 and Counter-Strike: Source
660 stars 76 forks source link

[TF2] Bots: Fix SeekAndDestroy so bots move as intended on maps they don't support (one line of code) #4581

Open ChampionCynthia opened 1 year ago

ChampionCynthia commented 1 year ago

Hello,

When a TFBot spawns, it goes through a number of behaviors, and most notably ScenarioMonitor. This behavior determines the main behavior the bot should follow. For instance, it will tell Soldier bots to attack the enemy control points, Snipers to lurk, Engineers to build and Spies to infiltrate the enemy base, etc.

Intended behavior

When the gamemode that is currently running on the map is unsupported, bots fall back to the SeekAndDestroy behavior, which tells them to move around the map and kill any player they come across without any additional goal.

Problem

Bots actually leave the SeekAndDestroy behavior immediately and thus never move.

Cause

The problem is that main behaviors created by ScenarioMonitor are supposed to never return. Once a bot enters the CapturePoint behavior, it cannot exit it. But unlike other main behaviors, SeekAndDestroy was designed as a sub-behavior for the Control Point gamemodes, and thus it actually returns on several conditions.

The fact that bots stay still on maps they don't support is caused by a condition in CTFBotSeekAndDestroy::Update:

if ( !TFGameRules()->RoundHasBeenWon() && me->GetTimeLeftToCapture() < tf_bot_offense_must_push_time.GetFloat() )
{
    return Done( "Time to push for the objective" );
}

On unsupported maps, CTFBot::GetTimeLeftToCapture() returns zero, so this condition is true and the behavior exits, causing bots to remain stuck in the ScenarioMonitor behavior which is essentially where the Capture The Flag code was placed for some reason.

This is easily verifiable by running the game with -dev and using nb_debug BEHAVIOR:

trade_psykopat20001

Setting the cheat-locked tf_bot_offense_must_push_time ConVar to 0 invalidates the condition and actually allows the bots to roam around the map as intended:

trade_psykopat20002

Solution

Because SeekAndDestroy is only used as a sub-behavior in Control Point gamemodes, this issue could be fixed using this:

if ( TFGameRules()->GetGameType() == TF_GAMETYPE_CP && !TFGameRules()->RoundHasBeenWon() && me->GetTimeLeftToCapture() < tf_bot_offense_must_push_time.GetFloat() )
{
    return Done( "Time to push for the objective" );
}

The TF_GAMETYPE_CP comprises any map that has Control Points and isn't Arena, so:

Bots will function only on maps that have active info_player_teamspawn entities contained in active func_respawnroom entities, but that is intended. Some Arena maps (arena_granary, arena_sawmill and arena_byre) don't have these entities so Engineers can build in the spawn rooms, and thus bots won't work there without manually creating these entities (through VScript for example).

Bots will also stop working correctly on Arena once a teamplay_point_startcapture or teamplay_point_captured event occurs as the SeekAndDestroy behavior is programmed to exit when they happen, but this is outside the scope of this issue.

Cheers.

condor00fr commented 1 year ago

Now THIS would do wonders for MvM, custom gamemodes made with Vscript and this fix combined could make for some pretty intresting results. Need it now pls

ChampionCynthia commented 1 year ago

@condor00fr This is not enough for MvM as red TFBots actually enter the same behaviors as the blue ones.

Having red TFBots use SeekAndDestroy in Mann VS Machine requires another change.

I created #4584 as a result for your suggestion.

TOYSIPO commented 4 months ago

Seconding this. Fixes like these are more important than people realize. As this game ages, bot support and quality should be a focus for the TF team. It would be nice if there were more ways for users to solve their own problems.