QueryResponse CTFBotPayloadGuard::ShouldRetreat(const INextBot *nextbot) const
{
	CTFBot *actor = ToTFBot(nextbot->GetEntity());
	
	CHandle<CTeamTrainWatcher> watcher = TFGameRules()->GetPayloadToBlock(actor->GetTeamNumber());
	if (watcher != nullptr && watcher->IsTrainNearCheckpoint()) {
		return QueryResponse::NO;
	}
	
	return QueryResponse::DONTCARE;
}
Пример #2
0
	DETOUR_DECL_MEMBER(void, CTFPlayer_HandleCommand_JoinTeam, const char *team)
	{
		DETOUR_MEMBER_CALL(CTFPlayer_HandleCommand_JoinTeam)(team);
		
		auto player = reinterpret_cast<CTFPlayer *>(this);
		
		if (TFGameRules()->IsMannVsMachineMode() && player->GetTeamNumber() == TF_TEAM_RED) {
			CTFBot *bot = ToTFBot(player);
			if (bot != nullptr) {
				(void)bot->GetAutoTeam(5);
			}
		}
	}
Пример #3
0
	/* make the targeted player known to all bots even if not in their ordinary
	 * vision range; and if they're a spy, reveal their identity */
	void NotifyBotsAboutTarget()
	{
		for (int i = 1; i <= gpGlobals->maxClients; ++i) {
			CTFPlayer *player = ToTFPlayer(UTIL_PlayerByIndex(i));
			if (player == nullptr || !IsTheTarget(player)) continue;
			
			for (int j = 1; j <= gpGlobals->maxClients; ++j) {
				CTFBot *bot = ToTFBot(UTIL_PlayerByIndex(j));
				if (bot == nullptr || bot->GetTeamNumber() != TF_TEAM_BLUE) continue;
				
				if (player->IsPlayerClass(TF_CLASS_SPY)) {
					bot->RealizeSpy(player);
				}
				bot->GetVisionInterface()->AddKnownEntity(player);
			}
		}
	}
Пример #4
0
	/* ENHANCEMENT: make defender bots always aware of the bomb carrier(s) as
	 * well as tanks */
	void Enhancement_NotifyDefendersAboutBombs()
	{
#if 0
		std::set<CBaseEntity *> bombs;
		
		ForEachFlag([&](CCaptureFlag *flag, bool& done){
			CBaseEntity *owner = flag->GetOwnerEntity();
			if (owner == nullptr) return true;
			
			if (owner->GetTeamNumber() != TF_TEAM_BLUE) return true;
			
			CTFBot *carrier = ToTFBot(owner);
			if (carrier == nullptr) return true;
			
			bombs.insert(carrier);
			
			return true;
		});
		
		ForEachTank([&](CTFTankBoss *tank, bool& done){
			if (tank->GetTeamNumber() == TF_TEAM_BLUE) {
				bombs.insert(tank);
			}
			
			return true;
		});
		
		if (bombs.empty()) return;
		
		ForEachDefenderBot([&](CTFBot *bot, bool& done){
			if (!bot->IsAlive()) return true;
			
			IVision *vision = bot->GetVisionInterface();
			for (auto bomb : bombs) {
				vision->AddKnownEntity(bomb);
			}
			
			return true;
		});
#endif
	}
Пример #5
0
	bool IsPlayerMarkable(CTFBot *bot, CTFPlayer *victim)
	{
		/* must be alive */
		if (!victim->IsAlive()) return false;
		
		/* must be an enemy */
		if (bot->GetTeamNumber() == victim->GetTeamNumber()) return false;
		
		/* must be a giant */
		if (!victim->IsMiniBoss()) return false;
		
		/* must not already be marked for death */
		if (victim->m_Shared->InCond(TF_COND_MARKEDFORDEATH)) return false;
		
		/* must not be invulnerable */
		if (victim->m_Shared->IsInvulnerable()) return false;
		
		/* must not be a sentry buster */
		CTFBot *vbot = ToTFBot(victim);
		if (vbot != nullptr && vbot->GetMission() == CTFBot::MISSION_DESTROY_SENTRIES) return false;
		
		return true;
	}
Пример #6
0
//--------------------------------------------------------------------------------------------------------
// Return true if this cost applies to the given actor
bool CFuncNavCost::IsApplicableTo( CBaseCombatCharacter *who ) const
{
	if ( !who )
	{
		return false;
	}

	if ( m_team > 0 )
	{
		if ( who->GetTeamNumber() != m_team )
		{
			return false;
		}
	}

#ifdef TF_DLL
	// TODO: Make group comparison efficient and move to base combat character
	CTFBot *bot = ToTFBot( who );
	if ( bot )
	{
		if ( bot->HasTheFlag() )
		{
			if ( HasTag( "bomb_carrier" ) )
			{
				return true;
			}

			// check custom bomb_carrier tags for this bot
			for( int i=0; i<m_tags.Count(); ++i )
			{
				const char* pszTag = m_tags[i];
				if ( V_stristr( pszTag, "bomb_carrier" ) )
				{
					if ( bot->HasTag( pszTag ) )
					{
						return true;
					}
				}
			}

			// the bomb carrier only pays attention to bomb_carrier costs
			return false;
		}

		if ( bot->HasMission( CTFBot::MISSION_DESTROY_SENTRIES ) )
		{
			if ( HasTag( "mission_sentry_buster" ) )
			{
				return true;
			}
		}
		
		if ( bot->HasMission( CTFBot::MISSION_SNIPER ) )
		{
			if ( HasTag( "mission_sniper" ) )
			{
				return true;
			}
		}
		
		if ( bot->HasMission( CTFBot::MISSION_SPY ) )
		{
			if ( HasTag( "mission_spy" ) )
			{
				return true;
			}
		}

		if ( bot->HasMission( CTFBot::MISSION_REPROGRAMMED ) )
		{
			return false;
		}

		if ( !bot->IsOnAnyMission() )
		{
			if ( HasTag( "common" ) )
			{
				return true;
			}
		}

		if ( HasTag( bot->GetPlayerClass()->GetName() ) )
		{
			return true;
		}

		// check custom tags for this bot
		for( int i=0; i<m_tags.Count(); ++i )
		{
			if ( bot->HasTag( m_tags[i] ) )
			{
				return true;
			}
		}

		// this cost doesn't apply to me
		return false;
	}
#endif

	return false;
}
	void DrawOverlay_Bots()
	{
		float duration = cvar_overlay_duration.GetFloat();
		
		constexpr float base_x = 0.02f;
		constexpr float base_y = 0.02f;
		
		constexpr float col1_w = 0.04f; constexpr float col1_x = 0.00f;
		constexpr float col2_w = 0.04f; constexpr float col2_x = col1_x + col1_w;
		constexpr float col3_w = 0.04f; constexpr float col3_x = col2_x + col2_w;
		constexpr float col4_w = 0.10f; constexpr float col4_x = col3_x + col3_w;
		constexpr float col5_w = 0.12f; constexpr float col5_x = col4_x + col4_w;
		constexpr float col6_w = 0.00f; constexpr float col6_x = col5_x + col5_w;
		
		NDebugOverlay::ScreenText(base_x + col1_x, base_y, "ENTINDEX",  0xff, 0xff, 0xff, 0xff, duration);
		NDebugOverlay::ScreenText(base_x + col2_x, base_y, "TEAMNUM",   0xff, 0xff, 0xff, 0xff, duration);
		NDebugOverlay::ScreenText(base_x + col3_x, base_y, "ALIVE",     0xff, 0xff, 0xff, 0xff, duration);
		NDebugOverlay::ScreenText(base_x + col4_x, base_y, "ABSORIGIN", 0xff, 0xff, 0xff, 0xff, duration);
		NDebugOverlay::ScreenText(base_x + col5_x, base_y, "BOTNAME",   0xff, 0xff, 0xff, 0xff, duration);
		NDebugOverlay::ScreenText(base_x + col6_x, base_y, "BEHAVIOR",  0xff, 0xff, 0xff, 0xff, duration);
		
		float line_y = 0.0f;
		for (int i = 1; i <= gpGlobals->maxClients; ++i) {
			CTFBot *bot = ToTFBot(UTIL_PlayerByIndex(i));
			if (bot == nullptr) continue;
			
			line_y += 0.0140f;
			
			bool is_alive = bot->IsAlive();
			int teamnum = bot->GetTeamNumber();
			
			NDebugOverlay::ScreenText(base_x + col1_x, base_y + line_y, CFmtStrN<64>("#%d", i), 0xff, 0xff, 0xff, 0xff, duration);
			
			if (teamnum == TF_TEAM_BLUE) {
				NDebugOverlay::ScreenText(base_x + col2_x, base_y + line_y, "BLU", 0x40, 0x40, 0xff, 0xff, duration);
			} else if (teamnum == TEAM_SPECTATOR) {
				NDebugOverlay::ScreenText(base_x + col2_x, base_y + line_y, "SPEC", 0x80, 0x80, 0x80, 0xff, duration);
			} else {
				NDebugOverlay::ScreenText(base_x + col2_x, base_y + line_y, CFmtStrN<64>("%d", teamnum), 0xff, 0xff, 0xff, 0xff, duration);
			}
			
			if (is_alive) {
				NDebugOverlay::ScreenText(base_x + col3_x, base_y + line_y, "ALIVE", 0x40, 0xff, 0x40, 0xff, duration);
			} else {
				NDebugOverlay::ScreenText(base_x + col3_x, base_y + line_y, "DEAD", 0xff, 0x40, 0x40, 0xff, duration);
			}
			
			const Vector& absorigin = bot->GetAbsOrigin();
			NDebugOverlay::ScreenText(base_x + col4_x, base_y + line_y, CFmtStrN<256>("[ %+5.0f %+5.0f %+5.0f ]", absorigin.x, absorigin.y, absorigin.z), 0xff, 0xff, 0xff, 0xff, duration);
			
			NDebugOverlay::ScreenText(base_x + col5_x, base_y + line_y, bot->GetPlayerName(), 0xff, 0xff, 0xff, 0xff, duration);
			
			IIntention *intent = bot->GetIntentionInterface();
			auto behavior = rtti_cast<Behavior<CTFBot> *>(intent->FirstContainedResponder());
			if (behavior != nullptr) {
				auto action = rtti_cast<Action<CTFBot> *>(behavior->FirstContainedResponder());
				if (action != nullptr) {
					NDebugOverlay::ScreenText(base_x + col6_x, base_y + line_y, PleaseRemoveThis::DebugString(action), 0xff, 0xff, 0xff, 0xff, duration);
				} else {
					NDebugOverlay::ScreenText(base_x + col6_x, base_y + line_y, "(action is nullptr)", 0x80, 0x80, 0x80, 0xff, duration);
				}
			} else {
				NDebugOverlay::ScreenText(base_x + col6_x, base_y + line_y, "(behavior is nullptr)", 0x80, 0x80, 0x80, 0xff, duration);
			}
		}
	}