C4Team *C4TeamList::GetGenerateTeamByID(int32_t iID) { // only if enabled if (!IsMultiTeams()) return NULL; // new team? if (iID == TEAMID_New) iID = GetLargestTeamID()+1; // find in list C4Team *pTeam = GetTeamByID(iID); if (pTeam) return pTeam; // not found: Generate GenerateDefaultTeams(iID); return GetTeamByID(iID); }
bool C4TeamList::IsJoin2TeamAllowed(int32_t idTeam) { // join to new team: Only if new teams can be created if (idTeam == TEAMID_New) return IsAutoGenerateTeams(); // team number must be valid C4Team *pTeam = GetTeamByID(idTeam); if (!pTeam) return false; // team player count must not exceed the limit return !pTeam->IsFull(); }
bool C4TeamList::IsJoin2TeamAllowed(int32_t idTeam, C4PlayerType plrType) { // join to new team: Only if new teams can be created if (idTeam == TEAMID_New) return IsAutoGenerateTeams(); // team number must be valid C4Team *pTeam = GetTeamByID(idTeam); if (!pTeam) return false; // team player count must not exceed the limit, unless it is a script player return !pTeam->IsFull() || plrType == C4PT_Script; }
bool C4TeamList::RecheckPlayerInfoTeams(C4PlayerInfo &rNewJoin, bool fByHost) { // only if enabled assert(IsMultiTeams()); if (!IsMultiTeams()) return false; // check whether a new team is to be assigned first C4Team *pCurrentTeam = GetTeamByPlayerID(rNewJoin.GetID()); int32_t idCurrentTeam = pCurrentTeam ? pCurrentTeam->GetID() : 0; if (rNewJoin.GetTeam()) { // was that team a change to the current team? // no change anyway: OK, skip this info if (idCurrentTeam == rNewJoin.GetTeam()) return true; // the player had a different team assigned: Check if changes are allowed at all if (eTeamDist == TEAMDIST_Free || (eTeamDist == TEAMDIST_Host && fByHost)) // also make sure that selecting this team is allowed, e.g. doesn't break the team limit // this also checks whether the team number is a valid team - but it would accept TEAMID_New, which shouldn't be used in player infos! if (rNewJoin.GetTeam() != TEAMID_New && IsJoin2TeamAllowed(rNewJoin.GetTeam())) // okay; accept change return true; // Reject change by reassigning the current team rNewJoin.SetTeam(idCurrentTeam); // and determine a new team, if none has been assigned yet if (idCurrentTeam) return true; } // new team assignment // teams are always needed in the lobby, so there's a team preset to change // for runtime joins, teams are needed if specified by teams.txt or if any teams have been created before (to avoid mixed team-noteam-scenarios) // but only assign teams in runtime join if the player won't pick it himself bool fWillHaveLobby = ::Network.isEnabled() && !::Network.Status.isPastLobby() && Game.fLobby; bool fHasOrWillHaveLobby = ::Network.isLobbyActive() || fWillHaveLobby; bool fCanPickTeamAtRuntime = !IsRandomTeam() && (rNewJoin.GetType() == C4PT_User) && IsRuntimeJoinTeamChoice(); bool fIsTeamNeeded = IsRuntimeJoinTeamChoice() || GetTeamCount(); if (!fHasOrWillHaveLobby && (!fIsTeamNeeded || fCanPickTeamAtRuntime)) return false; // get least-used team C4Team *pAssignTeam=NULL; C4Team *pLowestTeam = GetRandomSmallestTeam(); // melee mode if (IsAutoGenerateTeams() && !IsRandomTeam()) { // reuse old team only if it's empty if (pLowestTeam && !pLowestTeam->GetPlayerCount()) pAssignTeam = pLowestTeam; else { // no empty team: generate new GenerateDefaultTeams(iLastTeamID+1); pAssignTeam = GetTeamByID(iLastTeamID); } } else { if (!pLowestTeam) { // not enough teams defined in teamwork mode? // then create two teams as default if (!GetTeamByIndex(1)) GenerateDefaultTeams(2); else // otherwise, all defined teams are full. This is a scenario error, because MaxPlayer should have been adjusted return false; pLowestTeam = GetTeamByIndex(0); } pAssignTeam = pLowestTeam; } // assign it if (!pAssignTeam) return false; pAssignTeam->AddPlayer(rNewJoin, true); return true; }