Пример #1
0
// Return the number of bots following the given player
int GetBotFollowCount(CBasePlayer *pLeader)
{
	int count = 0;
	for (int i = 1; i <= gpGlobals->maxClients; i++)
	{
		CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);

		if (!pPlayer)
			continue;

		if (FNullEnt(pPlayer->pev))
			continue;

		if (FStrEq(STRING(pPlayer->pev->netname), ""))
			continue;

		if (!pPlayer->IsBot())
			continue;

 		if (!pPlayer->IsAlive())
 			continue;

		CCSBot *pBot = static_cast<CCSBot *>(pPlayer);
		if (pBot->IsBot() && pBot->GetFollowLeader() == pLeader)
			count++;
	}

	return count;
}
Пример #2
0
int GetBotFollowCount(CBasePlayer *leader)
{
	int count = 0;

	for (int i = 1; i <= gpGlobals->maxClients; ++i)
	{
		CBaseEntity *entity = UTIL_PlayerByIndex(i);

		if (entity == NULL)
			continue;

		if (FNullEnt(entity->pev))
			continue;

		if (FStrEq(STRING(entity->pev->netname), ""))
			continue;

		CBasePlayer *player = static_cast<CBasePlayer *>(entity);

		if (!player->IsBot())
			continue;

 		if (!player->IsAlive())
 			continue;

		CCSBot *bot = dynamic_cast<CCSBot *>(player);
		if (bot != NULL && bot->GetFollowLeader() == leader)
			++count;
	}

	return count;
}
Пример #3
0
/* <36b5fa> ../cstrike/dlls/bot/cs_bot_manager.cpp:415 */
void CCSBotManager::__MAKE_VHOOK(ClientDisconnect)(CBasePlayer *pPlayer)
{
	if (!pPlayer || !pPlayer->IsBot())
		return;

	CCSBot *pBot = static_cast<CCSBot *>(pPlayer);
	entvars_t *temp = VARS(pPlayer->edict());

	pBot->Disconnect();

	if (pPlayer->pev->classname)
		RemoveEntityHashValue(pPlayer->pev, STRING(pPlayer->pev->classname), CLASSNAME);

	FREE_PRIVATE(pPlayer->edict());

	CBasePlayer *player = GetClassPtr((CBasePlayer *)temp);
	AddEntityHashValue(player->pev, STRING(player->pev->classname), CLASSNAME);
	player->pev->flags = FL_DORMANT;
}
Пример #4
0
/* <36ace2> ../cstrike/dlls/bot/cs_bot_manager.cpp:484 */
void CCSBotManager::__MAKE_VHOOK(ServerCommand)(const char *pcmd)
{
	if (!m_bServerActive || !UTIL_IsGame("czero"))
		return;

	char buffer[400];
	const char *msg = CMD_ARGV(1);

	if (FStrEq(pcmd, "bot_about"))
	{
		Q_sprintf(buffer, "\n--------------------------------------------------------------------------\nThe Official Counter-Strike Bot V%d.%02d\nCreated by Michael S. Booth\nWeb: www.turtlerockstudios.com\\csbot\nE-mail: [email protected]\n--------------------------------------------------------------------------\n\n", CSBOT_VERSION_MAJOR, CSBOT_VERSION_MINOR);
		CONSOLE_ECHO(buffer);
		HintMessageToAllPlayers(buffer);
	}
	else if (FStrEq(pcmd, "bot_add"))
	{
		BotAddCommand(BOT_TEAM_ANY);
	}
	else if (FStrEq(pcmd, "bot_add_t"))
	{
		BotAddCommand(BOT_TEAM_T);
	}
	else if (FStrEq(pcmd, "bot_add_ct"))
	{
		BotAddCommand(BOT_TEAM_CT);
	}
	else if (FStrEq(pcmd, "bot_kill"))
	{
		bool killThemAll;
		if (CMD_ARGC() == 1 || FStrEq(msg, "all"))
			killThemAll = true;
		else
			killThemAll = false;

		for (int iIndex = 1; iIndex <= gpGlobals->maxClients; iIndex++)
		{
			CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex(iIndex);

			if (pPlayer == NULL)
				continue;

			if (FNullEnt(pPlayer->pev))
				continue;

			const char *name = STRING(pPlayer->pev->netname);

			if (FStrEq(name, ""))
				continue;

			if (pPlayer->IsBot())
			{
				if (killThemAll || FStrEq(name, msg))
				{
					pPlayer->TakeDamage(pPlayer->pev, pPlayer->pev, 9999.9f, DMG_CRUSH);
				}
			}
		}
	}
	else if (FStrEq(pcmd, "bot_kick"))
	{
		bool kickThemAll;
		if (CMD_ARGC() == 1 || FStrEq(msg, "all"))
			kickThemAll = true;
		else
			kickThemAll = false;

		for (int iIndex = 1; iIndex <= gpGlobals->maxClients; iIndex++)
		{
			CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex(iIndex);

			if (pPlayer == NULL)
				continue;

			if (FNullEnt(pPlayer->pev))
				continue;

			const char *name = STRING(pPlayer->pev->netname);

			if (FStrEq(name, ""))
				continue;

			if (pPlayer->IsBot())
			{
				if (kickThemAll || FStrEq(name, msg))
				{
					SERVER_COMMAND(UTIL_VarArgs("kick \"%s\"\n", name));
					CVAR_SET_FLOAT("bot_quota", cv_bot_quota.value - 1);
				}
			}
		}

		if (kickThemAll || cv_bot_quota.value < 0.0f)
		{
			CVAR_SET_FLOAT("bot_quota", 0);
		}
	}
	else if (FStrEq(pcmd, "bot_knives_only"))
	{
		CVAR_SET_FLOAT("bot_allow_pistols", 0);
		CVAR_SET_FLOAT("bot_allow_shotguns", 0);
		CVAR_SET_FLOAT("bot_allow_sub_machine_guns", 0);
		CVAR_SET_FLOAT("bot_allow_rifles", 0);
		CVAR_SET_FLOAT("bot_allow_machine_guns", 0);
		CVAR_SET_FLOAT("bot_allow_grenades", 0);
		CVAR_SET_FLOAT("bot_allow_snipers", 0);
		CVAR_SET_FLOAT("bot_allow_shield", 0);
	}
	else if (FStrEq(pcmd, "bot_pistols_only"))
	{
		CVAR_SET_FLOAT("bot_allow_pistols", 1);
		CVAR_SET_FLOAT("bot_allow_shotguns", 0);
		CVAR_SET_FLOAT("bot_allow_sub_machine_guns", 0);
		CVAR_SET_FLOAT("bot_allow_rifles", 0);
		CVAR_SET_FLOAT("bot_allow_machine_guns", 0);
		CVAR_SET_FLOAT("bot_allow_grenades", 0);
		CVAR_SET_FLOAT("bot_allow_snipers", 0);
		CVAR_SET_FLOAT("bot_allow_shield", 0);
	}
	else if (FStrEq(pcmd, "bot_snipers_only"))
	{
		CVAR_SET_FLOAT("bot_allow_pistols", 1);
		CVAR_SET_FLOAT("bot_allow_shotguns", 0);
		CVAR_SET_FLOAT("bot_allow_sub_machine_guns", 0);
		CVAR_SET_FLOAT("bot_allow_rifles", 0);
		CVAR_SET_FLOAT("bot_allow_machine_guns", 0);
		CVAR_SET_FLOAT("bot_allow_grenades", 0);
		CVAR_SET_FLOAT("bot_allow_snipers", 1);
		CVAR_SET_FLOAT("bot_allow_shield", 0);
	}
	else if (FStrEq(pcmd, "bot_all_weapons"))
	{
		CVAR_SET_FLOAT("bot_allow_pistols", 1);
		CVAR_SET_FLOAT("bot_allow_shotguns", 1);
		CVAR_SET_FLOAT("bot_allow_sub_machine_guns", 1);
		CVAR_SET_FLOAT("bot_allow_rifles", 1);
		CVAR_SET_FLOAT("bot_allow_machine_guns", 1);
		CVAR_SET_FLOAT("bot_allow_grenades", 1);
		CVAR_SET_FLOAT("bot_allow_snipers", 1);
		CVAR_SET_FLOAT("bot_allow_shield", 1);
	}
	else if (FStrEq(pcmd, "entity_dump"))
	{
		PrintAllEntities();
	}
	else if (FStrEq(pcmd, "bot_nav_delete"))
	{
		IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_DELETE;
	}
	else if (FStrEq(pcmd, "bot_nav_split"))
	{
		IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_SPLIT;
	}
	else if (FStrEq(pcmd, "bot_nav_merge"))
	{
		IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_MERGE;
	}
	else if (FStrEq(pcmd, "bot_nav_mark"))
	{
		IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_MARK;
	}
	else if (FStrEq(pcmd, "bot_nav_begin_area"))
	{
		IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_BEGIN_AREA;
	}
	else if (FStrEq(pcmd, "bot_nav_end_area"))
	{
		IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_END_AREA;
	}
	else if (FStrEq(pcmd, "bot_nav_connect"))
	{
		IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_CONNECT;
	}
	else if (FStrEq(pcmd, "bot_nav_disconnect"))
	{
		IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_DISCONNECT;
	}
	else if (FStrEq(pcmd, "bot_nav_splice"))
	{
		IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_SPLICE;
	}
	else if (FStrEq(pcmd, "bot_nav_crouch"))
	{
		IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_ATTRIB_CROUCH;
	}
	else if (FStrEq(pcmd, "bot_nav_jump"))
	{
		IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_ATTRIB_JUMP;
	}
	else if (FStrEq(pcmd, "bot_nav_precise"))
	{
		IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_ATTRIB_PRECISE;
	}
	else if (FStrEq(pcmd, "bot_nav_no_jump"))
	{
		IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_ATTRIB_NO_JUMP;
	}
	else if (FStrEq(pcmd, "bot_nav_analyze"))
	{
		IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_isAnalysisRequested) = true;
	}
	else if (FStrEq(pcmd, "bot_nav_strip"))
	{
		StripNavigationAreas();// TODO: reverse me
	}
	else if (FStrEq(pcmd, "bot_nav_save"))
	{
		GET_GAME_DIR(buffer);
		buffer[ Q_strlen(buffer) ] = '\\';

		Q_strcat(buffer, CBotManager::GetNavMapFilename());

		if (SaveNavigationMap(buffer))// TODO: reverse me
			CONSOLE_ECHO("Navigation map '%s' saved.\n", buffer);
		else
			CONSOLE_ECHO("ERROR: Cannot save navigation map '%s'.\n", buffer);
	}
	else if (FStrEq(pcmd, "bot_nav_load"))
	{
		ValidateMapData();
	}
	else if (FStrEq(pcmd, "bot_nav_use_place"))
	{
		if (CMD_ARGC() == 1)
		{
			int i = 0;
			const BotPhraseList *placeList = TheBotPhrases->GetPlaceList();

			for (BotPhraseList::const_iterator iter = placeList->begin(); iter != placeList->end(); ++iter, i++)
			{
				if ((*iter)->GetID() == GetNavPlace())
					CONSOLE_ECHO("--> %-26s", (*iter)->GetName());
				else
					CONSOLE_ECHO("%-30s", (*iter)->GetName());

				if (!(i % 3))
					CONSOLE_ECHO("\n");
			}
			CONSOLE_ECHO("\n");
		}
		else
		{
			const BotPhraseList *placeList = TheBotPhrases->GetPlaceList();
			const BotPhrase *found = NULL;
			bool isAmbiguous = false;

			for (BotPhraseList::const_iterator iter = placeList->begin(); iter != placeList->end(); ++iter)
			{
				if (!Q_strnicmp((*iter)->GetName(), msg, Q_strlen(msg)))
				{
					if (!Q_strcmp((*iter)->GetName(), msg))
					{
						found = (*iter);
						break;
					}

					if (found != NULL)
						isAmbiguous = true;
					else
						found = (*iter);
				}
			}

			if (isAmbiguous)
			{
				CONSOLE_ECHO("Ambiguous\n");
				return;
			}

			if (found != NULL)
			{
				CONSOLE_ECHO("Current place set to '%s'\n", found->GetName());
				m_navPlace = found->GetID();
			}
		}
	}
	else if (FStrEq(pcmd, "bot_nav_toggle_place_mode"))
	{
		IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_TOGGLE_PLACE_MODE;
	}
	else if (FStrEq(pcmd, "bot_nav_place_floodfill"))
	{
		IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_PLACE_FLOODFILL;
	}
	else if (FStrEq(pcmd, "bot_nav_place_pick"))
	{
		IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_PLACE_PICK;
	}
	else if (FStrEq(pcmd, "bot_nav_toggle_place_painting"))
	{
		IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_TOGGLE_PLACE_PAINTING;
	}
	else if (FStrEq(pcmd, "bot_goto_mark"))
	{
		// tell the first bot we find to go to our marked area
		CNavArea *area = GetMarkedArea();// TODO: reverse me
		if (area != NULL)
		{
			CBaseEntity *pEntity = NULL;
			while ((pEntity = UTIL_FindEntityByClassname(pEntity, "player")) != NULL)
			{
				if (!pEntity->IsPlayer())
					continue;

				if ((pEntity->pev->flags & FL_DORMANT) == FL_DORMANT)
					continue;

				CBasePlayer *playerOrBot = GetClassPtr((CBasePlayer *)pEntity->pev);

				if (playerOrBot->IsBot())
				{
					CCSBot *bot = reinterpret_cast<CCSBot *>(playerOrBot);
					bot->MoveTo(&area->m_center, FASTEST_ROUTE);// TODO: reverse me
					return;
				}
			}
		}
	}
	else if (FStrEq(pcmd, "bot_memory_usage"))
	{
		CONSOLE_ECHO("Memory usage:\n");
		CONSOLE_ECHO("  %d bytes per bot\b", sizeof(CCSBot));
		CONSOLE_ECHO("  %d Navigation Areas @ %d bytes each = %d bytes\n",
			TheNavAreaGrid.GetNavAreaCount(),
			sizeof(CNavArea),
			TheNavAreaGrid.GetNavAreaCount() * sizeof(CNavArea));
		CONSOLE_ECHO("  %d Hiding Spots @ %d bytes each = %d bytes\n",
			TheHidingSpotList.size(),
			sizeof(HidingSpot),
			sizeof(HidingSpot) * TheHidingSpotList.size());

		unsigned int encounterMem = 0;
		for (NavAreaList::iterator iter = TheNavAreaList.begin(); iter != TheNavAreaList.end(); ++iter)
		{
			CNavArea *area = (*iter);

			for (SpotEncounterList::iterator siter = area->m_spotEncounterList.begin(); siter != area->m_spotEncounterList.end(); ++siter)
			{
				// TODO: Fix me, this is crashed in HOOK_GAMEDLL
				SpotEncounter se = (*siter);

				encounterMem += sizeof(SpotEncounter);
				encounterMem += sizeof(SpotOrder) * se.spotList.size();
			}
		}

		CONSOLE_ECHO("  Encounter Spot data = %d bytes\n", encounterMem);
	}
	else if (FStrEq(pcmd, "bot_nav_mark_unnamed"))
	{
		IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_MARK_UNNAMED;
	}
	else if (FStrEq(pcmd, "bot_nav_warp"))
	{
		IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_WARP_TO_MARK;
	}
	else if (FStrEq(pcmd, "bot_nav_corner_select"))
	{
		IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_SELECT_CORNER;
	}
	else if (FStrEq(pcmd, "bot_nav_corner_raise"))
	{
		IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_RAISE_CORNER;
	}
	else if (FStrEq(pcmd, "bot_nav_corner_lower"))
	{
		IMPLEMENT_ARRAY_CLASS(CCSBotManager, m_editCmd) = EDIT_LOWER_CORNER;
	}
	else if (FStrEq(pcmd, "bot_nav_check_consistency"))
	{
		if (CMD_ARGC() != 2)
		{
			CONSOLE_ECHO("usage: bot_nav_check_consistency <filename>\n");
			return;
		}

		SanityCheckNavigationMap(msg);// TODO: reverse me
	}
}
Пример #5
0
CBasePlayer *CCSBot::FindMostDangerousThreat()
{
	// maximum number of simulataneously attendable threats
	enum { MAX_THREATS = 16 };
	struct CloseInfo
	{
		CBasePlayer *enemy;
		float range;
	}
	threat[ MAX_THREATS ];
	int threatCount = 0;

	m_bomber = NULL;

	m_closestVisibleFriend = NULL;
	float closeFriendRange = 99999999999.9f;

	m_closestVisibleHumanFriend = NULL;
	float closeHumanFriendRange = 99999999999.9f;

	int i;

	{
		for (i = 1; i <= gpGlobals->maxClients; ++i)
		{
			CBasePlayer *player = UTIL_PlayerByIndex(i);

			if (player == NULL)
				continue;

			if (FNullEnt(player->pev))
				continue;

			// is it a player?
			if (!player->IsPlayer())
				continue;

			// ignore self
			if (player->entindex() == entindex())
				continue;

			// is it alive?
			if (!player->IsAlive())
				continue;

			// is it an enemy?
			if (player->m_iTeam == m_iTeam)
			{
				TraceResult result;
				UTIL_TraceLine(GetEyePosition(), player->pev->origin, ignore_monsters, ignore_glass, edict(), &result);
				if (result.flFraction == 1.0f)
				{
					// update watch timestamp
					int idx = player->entindex() - 1;
					m_watchInfo[idx].timestamp = gpGlobals->time;
					m_watchInfo[idx].isEnemy = false;

					// keep track of our closest friend
					Vector to = pev->origin - player->pev->origin;
					float rangeSq = to.LengthSquared();
					if (rangeSq < closeFriendRange)
					{
						m_closestVisibleFriend = player;
						closeFriendRange = rangeSq;
					}

					// keep track of our closest human friend
					if (!player->IsBot() && rangeSq < closeHumanFriendRange)
					{
						m_closestVisibleHumanFriend = player;
						closeHumanFriendRange = rangeSq;
					}
				}

				continue;
			}

			// check if this enemy is fully
			if (!IsVisible(player, CHECK_FOV))
				continue;

			// update watch timestamp
			int idx = player->entindex() - 1;
			m_watchInfo[idx].timestamp = gpGlobals->time;
			m_watchInfo[idx].isEnemy = true;

			// note if we see the bomber
			if (player->IsBombGuy())
			{
				m_bomber = player;
			}

			// keep track of all visible threats
			Vector d = pev->origin - player->pev->origin;
			float distSq = d.LengthSquared();

			// maintain set of visible threats, sorted by increasing distance
			if (threatCount == 0)
			{
				threat[0].enemy = player;
				threat[0].range = distSq;
				threatCount = 1;
			}
			else
			{
				// find insertion point
				int j;
				for (j = 0; j < threatCount; ++j)
				{
					if (distSq < threat[j].range)
						break;
				}


				// shift lower half down a notch
				for (int k = threatCount - 1; k >= j; --k)
					threat[k + 1] = threat[k];

				// insert threat into sorted list
				threat[j].enemy = player;
				threat[j].range = distSq;

				if (threatCount < MAX_THREATS)
					++threatCount;
			}
		}
	}
	{
		// track the maximum enemy and friend counts we've seen recently
		int prevEnemies = m_nearbyEnemyCount;
		int prevFriends = m_nearbyFriendCount;
		m_nearbyEnemyCount = 0;
		m_nearbyFriendCount = 0;

		for (i = 0; i < MAX_CLIENTS; ++i)
		{
			if (m_watchInfo[i].timestamp <= 0.0f)
				continue;

			const float recentTime = 3.0f;
			if (gpGlobals->time - m_watchInfo[i].timestamp < recentTime)
			{
				if (m_watchInfo[i].isEnemy)
					++m_nearbyEnemyCount;
				else
					++m_nearbyFriendCount;
			}
		}

		// note when we saw this batch of enemies
		if (prevEnemies == 0 && m_nearbyEnemyCount > 0)
		{
			m_firstSawEnemyTimestamp = gpGlobals->time;
		}

		if (prevEnemies != m_nearbyEnemyCount || prevFriends != m_nearbyFriendCount)
		{
			PrintIfWatched("Nearby friends = %d, enemies = %d\n", m_nearbyFriendCount, m_nearbyEnemyCount);
		}
	}
	{
		// Track the place where we saw most of our enemies
		struct PlaceRank
		{
			unsigned int place;
			int count;
		};
		static PlaceRank placeRank[ MAX_PLACES_PER_MAP ];
		int locCount = 0;

		PlaceRank common;
		common.place = 0;
		common.count = 0;

		for (i = 0; i < threatCount; ++i)
		{
			// find the area the player/bot is standing on
			CNavArea *area;
			CCSBot *bot = dynamic_cast<CCSBot *>(threat[i].enemy);
			if (bot != NULL && bot->IsBot())
			{
				area = bot->GetLastKnownArea();
			}
			else
			{
				area = TheNavAreaGrid.GetNearestNavArea(&threat[i].enemy->pev->origin);
			}

			if (area == NULL)
				continue;

			unsigned int threatLoc = area->GetPlace();
			if (!threatLoc)
				continue;

			// if place is already in set, increment count
			int j;
			for (j = 0; j < locCount; ++j)
			{
				if (placeRank[j].place == threatLoc)
					break;
			}

			if (j == locCount)
			{
				// new place
				if (locCount < MAX_PLACES_PER_MAP)
				{
					placeRank[ locCount ].place = threatLoc;
					placeRank[ locCount ].count = 1;

					if (common.count == 0)
						common = placeRank[locCount];

					++locCount;
				}
			}
			else
			{
				// others are in that place, increment
				++placeRank[j].count;

				// keep track of the most common place
				if (placeRank[j].count > common.count)
					common = placeRank[j];
			}
		}

		// remember most common place
		m_enemyPlace = common.place;
	}

	{
		if (threatCount == 0)
			return NULL;

		// otherwise, find the closest threat that without using shield
		int t;
		for (t = 0; t < threatCount; ++t)
		{
			if (!threat[t].enemy->IsProtectedByShield())
			{
				return threat[t].enemy;
			}
		}
	}

	// return closest threat
	return threat[0].enemy;
}