PRoConEvents.MULTIbalancer.ScrambleTeams C# (CSharp) Method

ScrambleTeams() private method

private ScrambleTeams ( List usOrig, List ruOrig, bool logOnly ) : ScrambleStatus
usOrig List
ruOrig List
logOnly bool
return ScrambleStatus
        private ScrambleStatus ScrambleTeams(List<PlayerModel> usOrig, List<PlayerModel> ruOrig, bool logOnly)
        {
            /*
            We have to check every move to make sure that we are not overfilling a team
            or a squad. We get the live player count for each team. We start with the live
            count in case a new player has joined that would overfill the team. Player's leaving
            are ignored, since they help make a team less filled. Therefore these counts might
            be overestimates, but are never less than the actual live count. We can't wait
            for full round-trip updates, so we "dead reckon" the updated team counts for each
            move we make.
            */

            bool first = true;
            PerModeSettings perMode = GetPerModeSettings();
            int maxTeam = perMode.MaxPlayers/2;
            int usCount = 0;
            int ruCount = 0;
            Dictionary<int,int> allocated = new Dictionary<int,int>(); // key is combined team + squad

            // Get live counts
            List<String> allCopy = new List<String>();
            lock (fAllPlayers) {
            allCopy.AddRange(fAllPlayers);
            }
            foreach (String name in allCopy) {
            PlayerModel m = GetPlayer(name);
            if (m == null || m.Role != ROLE_PLAYER)
            continue;
            if (m.Team == 1) { ++usCount; }
            else if (m.Team == 2) { ++ruCount; }
            }

            // Check for full server
            if (usCount >= maxTeam && ruCount >= maxTeam) {
            List<PlayerModel> allPlayers = new List<PlayerModel>();
            allPlayers.AddRange(usOrig);
            allPlayers.AddRange(ruOrig);
            RestoreSquads(allPlayers, null, logOnly);
            return ScrambleStatus.CompletelyFull; // can't scramble, server is full
            }

            List<PlayerModel> usClone = new List<PlayerModel>();
            List<PlayerModel> ruClone = new List<PlayerModel>();
            // Remove players from these lists as they are moved
            usClone.AddRange(usOrig);
            ruClone.AddRange(ruOrig);

            // Move one by one, sending to the smallest team
            while (usClone.Count + ruClone.Count > 0) {
            if (DebugLevel >= 7) DebugScrambler("Team counts: Max = " + maxTeam + ", " + GetTeamName(1) + "(" + usCount + "), " + GetTeamName(2) + "(" + ruCount + ")");

            // Pick next list to pull from, using the one that represents moving to the lowest live count
            int nextList = 0;
            if (usCount < maxTeam && usClone.Count > 0 && (usCount <= ruCount || ruClone.Count == 0)) {
            nextList = 1;
            } else if (ruCount < maxTeam && ruClone.Count > 0 && (ruCount <= usCount || usClone.Count == 0)) {
            nextList = 2;
            } else {
            List<PlayerModel> remaining = new List<PlayerModel>();
            remaining.AddRange(usClone);
            remaining.AddRange(ruClone);
            RestoreSquads(remaining, allocated, logOnly);
            if (first) return ScrambleStatus.Failure; // can't continue scramble, server is full
            return ScrambleStatus.PartialSuccess;
            }

            // Pull from list and do the move
            DebugScrambler("Remaining to be moved: To " + GetTeamName(1) + "(" + usClone.Count + "), To " + GetTeamName(2) + "(" + ruClone.Count + ")");
            List<PlayerModel> pullFrom = (nextList == 1) ? usClone : ruClone;
            PlayerModel clone = pullFrom[0];
            pullFrom.Remove(clone);
            PlayerModel actual = GetPlayer(clone.Name);
            int actualTeam = (actual != null) ? actual.Team : 0;
            first = false;
            try {
            ScrambleMove(clone, nextList, logOnly);
            int num = 0;
            int key = (nextList * 1000) + clone.ScrambledSquad;
            if (allocated.TryGetValue(key, out num)) {
                num = num + 1;
            }
            if (num > fMaxSquadSize) {
                DebugScrambler("WARNING: team " + nextList + ", squad " + clone.ScrambledSquad + " has more than " + fMaxSquadSize + " players!");
            } else {
                allocated[key] = num;
            }
            } catch (Exception e) { ConsoleException(e); }

            // Moving to a new team?
            if (actualTeam != clone.Team) {
            if (nextList == 1) {
                ++usCount;
                --ruCount;
            } else {
                ++ruCount;
                --usCount;
            }
            } // otherwise moved to same team, so no change in team counts
            }
            return ScrambleStatus.Success;
        }
MULTIbalancer