Exemplo n.º 1
0
        private int balanceTeams(DateTime now) {


            pluginState = PluginState.balance;
            setStartTime(pluginState, now.AddSeconds(1));
            DebugWrite("^b" + pluginState + "_live^n state started " + getStartTime(pluginState).ToString() + "^n^0", 1);

            bool keep_clans = getBooleanVarValue("keep_clans_live");
            Dictionary<int, int> player_count = getPlayerCount();

            if (player_count[1] == player_count[2])
                return 0;

            int team_sz = serverInfo.MaxPlayerCount / 2;
            int neutral_team = 0;
            int bigger_team = (player_count[1] > player_count[2]) ? 1 : 2;
            int smaller_team = (player_count[1] > player_count[2]) ? 2 : 1;
            int total = player_count[1] + player_count[2];
            int difference = Math.Abs(player_count[1] - player_count[2]);
            int needed = difference / 2;


            DebugWrite("Total of ^b" + total + "^n player/s in server^0", 3);
            for (int i = 1; i < 3; i++) {
                DebugWrite("^bTeam(" + TN(i) + ")^n has ^b" + player_count[i] + "^n player/s^0", 3);
            }

            DebugWrite("Teams differ by ^b" + difference + "^n player/s,  ^b" + needed + "^n player/s are needed on ^bTeam(" + TN(smaller_team) + ")^n^0", 3);

            int candidates = needed;

            //?????? jstmx - Wrong logic, some fixes
            if (getBooleanVarValue("wait_death")) {
                candidates = getIntegerVarValue("wait_death_count");

                int tsz = player_count[bigger_team];

                // check that the candidate list does not exceed the team size
                if (candidates > tsz) {
                    DebugWrite("cannot use candidate list size of ^b" + candidates + "^n, Team(" + TN(bigger_team) + ") has only ^b" + tsz + "^n player" + ((tsz > 1) ? "s" : ""), 3);
                    candidates = tsz;
                }

                // check that the candidates list size is bigger than needed 
                if (candidates > needed) {
                    needed = candidates;
                    DebugWrite("^bwait_death^n is on, will flag " + needed + " candidate" + ((needed > 1) ? "s" : "") + " for moving", 3);
                }
            }
            //??????

            DebugWrite("Building no-squad pool from ^bTeam(" + TN(bigger_team) + ")^n^0", 3);
            List<PlayerProfile> nosquad_pool = getNoSquadPlayers(bigger_team);
            DebugWrite("No-squad pool has ^b" + nosquad_pool.Count + "^n player/s^0", 3);

            DebugWrite("Building squad pool from ^bTeam(" + TN(bigger_team) + ")^n^0", 3);
            List<PlayerSquad> squad_pool = getNonEmptySquads(bigger_team);
            DebugWrite("Squad pool has ^b" + squad_pool.Count + "^n squads^0", 3);


            Dictionary<string, int>[] clan_stats = new Dictionary<string, int>[3];
            clan_stats[smaller_team] = new Dictionary<string, int>();
            clan_stats[bigger_team] = new Dictionary<string, int>();
            clan_stats[neutral_team] = new Dictionary<string, int>();

            if (keep_clans) {
                DebugWrite("Keeping clans in same team", 3);

                List<PlayerProfile> players_list = getPlayersProfile("");
                /* collect statistics about clans */
                DebugWrite("Collecting clan statistics", 3);
                getClanStatsByTeam(players_list, clan_stats);


                List<string> clanlist = new List<string>();
                clanlist.AddRange(clan_stats[1].Keys);

                DebugWrite("^b" + clanlist.Count + "^n clans in server: [^b" + String.Join("^n], [^b", clanlist.ToArray()) + "^n]", 3);
            }

            if (!getBooleanVarValue("keep_squads_live")) {
                DebugWrite("^bkeep_squads_live^n is off, moving players to no-squad pool before balancing", 3);
                foreach (PlayerSquad squad in squad_pool)
                    foreach (PlayerProfile player in squad.getMembers())
                        nosquad_pool.Add(player);

                squad_pool.Clear();
            }

            /* sort the no-squad pool */
            DebugWrite("Sorting the no-squad pool by ^b" + getStringVarValue("live_sort") + "^n^0", 3);
            nosquad_pool.Sort(new Comparison<PlayerProfile>(getPlayerSort("live_sort")));

            for (int i = 0; i < nosquad_pool.Count; i++)
                DebugWrite("      " + i + ". " + nosquad_pool[i] + "(" + getSortFieldValueStr(nosquad_pool[i], "live_sort") + ")", 3);


            DebugWrite("Moving ^b" + needed + "^n players from sorted no-squad pool to ^bTeam(" + TN(smaller_team) + ")^n^0", 3);
            while (needed > 0 && nosquad_pool.Count > 0) {
                PlayerProfile player = nosquad_pool[0];
                nosquad_pool.RemoveAt(0);
                string tag = player.getClanTag();

                /* if keeping clans together, and there are more than two players in the clan in the sever */
                if (keep_clans && shouldSkipClanPlayer(player, smaller_team, bigger_team, clan_stats))
                    continue;

                DebugWrite("Moving ^b" + player.ToString() + "^n to ^bTeam(^n" + TN(smaller_team) + ")^n^0", 3);
                if (movePlayer(player, smaller_team, 0, true))
                    needed--;
            }

            /* if teams are balanced, we are done */
            if (needed == 0) {
                DebugWrite("Teams should now be balanced!", 3);
                return needed;
            }

            /* teams are not balanced, proceed on squad balancing */

            DebugWrite("Teams are still unbalanced, " + needed + " more player/s needed", 3);

            /* sort the squad pool */
            DebugWrite("Sorting the squad pool by ^b" + getStringVarValue("live_sort") + "^n^0", 3);
            squad_pool.Sort(new Comparison<PlayerSquad>(getSquadSort("live_sort")));

            for (int i = 0; i < squad_pool.Count; i++) {
                DebugWrite("      " + i + ". " + squad_pool[i].ToString() + "(" + getSortFieldValueStr(squad_pool[i], "live_sort") + ")", 3);
            }

            DebugWrite("Moving squads from sorted squad pool to ^bTeam(" + TN(smaller_team) + ")^n^0", 3);
            while (needed > 0 && squad_pool.Count > 0) {
                PlayerSquad squad = squad_pool[0];
                squad_pool.RemoveAt(0);


                int squad_sz = squad.getCount();
                string squad_uid = squad.ToString();
                string smaller_team_uid = "^bTeam(" + TN(smaller_team) + ")^n";

                DebugWrite("^b" + needed + "^n players are needed on " + smaller_team_uid + "^0", 3);
                DebugWrite(squad_uid + " has ^b" + squad_sz + "^n player/s^0", 2);

                if (needed >= squad_sz) {
                    if (keep_clans && shouldSkipClanSquad(squad, smaller_team, bigger_team, clan_stats))
                        continue;


                    /* we can move the entrie squad */
                    DebugWrite("Moving entire " + squad_uid + " to " + smaller_team_uid + "^0", 3);
                    squad_sz = moveSquad(squad, smaller_team, team_sz);
                    needed -= squad_sz;
                } else {
                    /* we have to break up a squad */
                    PlayerSquad temp_squad = new PlayerSquad(squad.getTeamId(), squad.getSquadId());

                    DebugWrite("Breaking up " + squad_uid + " to get ^b" + needed + "^n player/s^0", 3);
                    DebugWrite("But, first I will sort the members of " + squad_uid, 3);
                    squad.sortMembers(getPlayerSort("live_sort"));
                    for (int i = 0; i < squad.getCount(); i++)
                        DebugWrite("      " + i + ". " + squad.getMembers()[i] + "(" + getSortFieldValueStr(squad.getMembers()[i], "live_sort") + ")", 3);

                    /* get as many players as needed */
                    while (needed > 0 && squad.getCount() > 0) {
                        PlayerProfile player = squad.getMembers()[0];
                        squad.dropPlayer(player);

                        if (keep_clans && shouldSkipClanPlayer(player, smaller_team, bigger_team, clan_stats))
                            continue;

                        if (isInMoveWhiteList(player))
                            continue;

                        temp_squad.addPlayer(player);
                        DebugWrite("Player " + player + " selected to move to " + smaller_team_uid + "^0", 3);
                        needed--;
                    }

                    /* move the temporary squad */
                    moveSquad(temp_squad, smaller_team, team_sz);
                }
            }


            if (needed == 0)
                DebugWrite("Teams should now be balanced!", 3);
            else
                DebugWrite("Teams are still ubalanced!", 3);

            return needed;
        }