#if defined _smlib_teams_included #endinput #endif #define _smlib_teams_included #include #include #include #define MAX_TEAMS 32 // Max number of teams in a game #define MAX_TEAM_NAME_LENGTH 32 // Max length of a team's name // Team Defines #define TEAM_INVALID -1 #define TEAM_UNASSIGNED 0 #define TEAM_SPECTATOR 1 #define TEAM_ONE 2 #define TEAM_TWO 3 #define TEAM_THREE 4 #define TEAM_FOUR 5 /* * If one team is empty its assumed single team mode is enabled and the game won't start. * * @noparam * @return True if one team is empty, false otherwise. */ stock bool Team_HaveAllPlayers(bool countFakeClients=true) { int teamCount = GetTeamCount(); for (int i=2; i < teamCount; i++) { if (Team_GetClientCount(i, ((countFakeClients) ? CLIENTFILTER_ALL : CLIENTFILTER_NOBOTS)) == 0) { return false; } } return true; } /* * Returns the client count of the players in a team. * * @param team Team Index. * @param flags Client Filter Flags (Use the CLIENTFILTER_ constants). * @return Client count in the server. */ stock int Team_GetClientCount(int team, int flags=0) { flags |= CLIENTFILTER_INGAME; int numClients = 0; for (int client=1; client <= MaxClients; client++) { if (!Client_MatchesFilter(client, flags)) { continue; } if (GetClientTeam(client) == team) { numClients++; } } return numClients; } /* * Returns the client counts of the first two teams (eg.: Terrorists - Counter). * Use this function for optimization if you have to get the counts of both teams, * otherwise use Team_GetClientCount(). * * @param team1 Pass an integer variable by reference * @param team2 Pass an integer variable by reference * @param flags Client Filter Flags (Use the CLIENTFILTER_ constants). */ stock void Team_GetClientCounts(int &team1=0, int &team2=0, int flags=0) { flags |= CLIENTFILTER_INGAME; for (int client=1; client <= MaxClients; client++) { if (!Client_MatchesFilter(client, flags)) { continue; } if (GetClientTeam(client) == TEAM_ONE) { team1++; } else if (GetClientTeam(client) == TEAM_TWO) { team2++; } } } /* * Gets the name of a team. * Don't call this before OnMapStart() * * @param index Team Index. * @param str String buffer * @param size String Buffer Size * @return True on success, false otherwise */ stock bool Team_GetName(int index, char[] str, int size) { int edict = Team_GetEdict(index); if (edict == -1) { str[0] = '\0'; return false; } GetEntPropString(edict, Prop_Send, "m_szTeamname", str, size); return true; } /* * Changes a team's name. * Use this carefully ! * Only set the teamname OnMapStart() or OnEntityCreated() * when no players are ingame, otherwise it can crash the server. * * @param index Team Index. * @param name New Name String * @return True on success, false otherwise */ stock bool Team_SetName(int index, const char[] name) { int edict = Team_GetEdict(index); if (edict == -1) { return false; } SetEntPropString(edict, Prop_Send, "m_szTeamname", name); ChangeEdictState(edict, GetEntSendPropOffs(edict, "m_szTeamname", true)); return true; } /* * Changes a team's score. * Don't use this before OnMapStart(). * * @param index Team Index. * @return Team Score or -1 if the team is not valid. */ stock int Team_GetScore(int index) { int edict = Team_GetEdict(index); if (edict == -1) { return -1; } return GetEntProp(edict, Prop_Send, "m_iScore"); } /* * Changes a team's score. * Don't use this before OnMapStart(). * * @param index Team Index. * @param score Score value. * @return True on success, false otherwise */ stock bool Team_SetScore(int index, int score) { int edict = Team_GetEdict(index); if (edict == -1) { return false; } SetEntProp(edict, Prop_Send, "m_iScore", score); ChangeEdictState(edict, GetEntSendPropOffs(edict, "m_iScore", true)); return true; } /* * Gets a team's edict (*team_manager) Team Index. * Don't call this before OnMapStart() * * @param edict Edict * @return Team Index */ stock int Team_EdictGetNum(int edict) { return GetEntProp(edict, Prop_Send, "m_iTeamNum"); } /* * Check's whether the index is a valid team index or not. * Don't call this before OnMapStart() * * @param index Index. * @return True if the Index is a valid team, false otherwise. */ stock bool Team_IsValid(int index) { return (Team_GetEdict(index) != -1); } /* * Gets a team's edict (team_manager) Team Index. * Don't call this before OnMapStart() * * @param index Edict * @return Team Index */ stock int Team_EdictIsValid(int edict) { return GetEntProp(edict, Prop_Send, "m_iTeamNum"); } /* * Gets a team's edict (team_manager). * This function caches found team edicts. * Don't call this before OnMapStart() * * @param index Team Index. * @return Team edict or -1 if not found */ stock int Team_GetEdict(int index) { static int teams[MAX_TEAMS] = { INVALID_ENT_REFERENCE, ... }; if (index < 0 || index > MAX_TEAMS) { return -1; } int edict = teams[index]; if (Entity_IsValid(edict)) { return edict; } bool foundTeamManager = false; int maxEntities = GetMaxEntities(); for (int entity=MaxClients+1; entity < maxEntities; entity++) { if (!IsValidEntity(entity)) { continue; } if (Entity_ClassNameMatches(entity, "team_manager", true)) { foundTeamManager = true; } // Do not continue when no team managers are found anymore (for optimization) else if (foundTeamManager) { return -1; } else { continue; } int num = Team_EdictGetNum(entity); if (num >= 0 && num <= MAX_TEAMS) { teams[num] = EntIndexToEntRef(entity); } if (num == index) { return entity; } } return -1; } /* * Trys to find a client in the specified team. * This function is NOT random, it returns the first * or the cached player (Use Client_GetRandom() instead). * * @param index Team Index. * @return Client Index or -1 if no client was found in the specified team. */ stock int Team_GetAnyClient(int index) { static int client_cache[MAX_TEAMS] = {-1, ...}; int client; if (index > 0) { client = client_cache[index]; if (client > 0 && client <= MaxClients) { if (IsClientInGame(client) && GetClientTeam(client) == index) { return client; } } else { client = -1; } } for (client=1; client <= MaxClients; client++) { if (!IsClientInGame(client)) { continue; } if (GetClientTeam(client) != index) { continue; } client_cache[index] = client; return client; } return -1; }