private void Scrambler(List<TeamScore> teamScores)
{
// Clear the debug lists
try {
fDebugScramblerBefore[0].Clear();
fDebugScramblerBefore[1].Clear();
fDebugScramblerAfter[0].Clear();
fDebugScramblerAfter[1].Clear();
fDebugScramblerStartRound[0].Clear();
fDebugScramblerStartRound[1].Clear();
lock (fExtrasLock) {
fDebugScramblerSuspects.Clear();
}
} catch (Exception e) {
ConsoleException(e);
}
// Check all the reasons not to scramble
if (fServerInfo == null) {
ConsoleDebug("Scrambler: fServerInfo is null!");
return;
}
PerModeSettings perMode = GetPerModeSettings();
if (!perMode.EnableScrambler) {
DebugScrambler("Enable Scrambler is False, no scramble this round");
return;
}
if (OnlyByCommand && !fScrambleByCommand) {
DebugScrambler("Only By Command is True and no command was issued, no scramble this round");
return;
}
int current = fServerInfo.CurrentRound + 1; // zero based index
if (!fScrambleByCommand && OnlyOnNewMaps && current < fServerInfo.TotalRounds) {
DebugScrambler("Only scrambling new maps and this is only round " + current + " of " + fServerInfo.TotalRounds);
return;
}
if (IsSQDM()) {
DebugScrambler("SQDM can't be scrambled");
return;
}
int totalPlayers = TotalPlayerCount();
int minNeeded = (perMode.EnableLowPopulationAdjustments) ? 6 : 16;
if (!KeepSquadsTogether && !KeepClanTagsInSameTeam && !KeepFriendsInSameTeam) {
DebugScrambler("All Keep settings are False, relaxing min needed requirement!");
minNeeded = 6;
}
if (!fScrambleByCommand && totalPlayers < minNeeded) {
DebugScrambler("Not enough players to scramble, at least " + minNeeded + " required: " + totalPlayers);
return;
}
if (!IsCTF() && !IsCarrierAssault() && !IsObliteration() && !fScrambleByCommand && OnlyOnFinalTicketPercentage > 100) {
if (teamScores == null || teamScores.Count < 2) {
DebugScrambler("DEBUG: no final team scores");
return;
}
bool countDown = true;
if (fMaxTickets == -1) return;
double goal = fMaxTickets;
double a = (teamScores[0].Score == 1) ? 0 : teamScores[0].Score;
double b = (teamScores[1].Score == 1) ? 0 : teamScores[1].Score;
/*
if (IsRush()) {
// normalize Rush ticket ratio
b = fMaxTickets - (fRushMaxTickets - b);
b = Math.Max(b, 1);
}
*/
if (IsCountUp()) {
countDown = false;
goal = teamScores[0].WinningScore;
}
/*
double ratio = 0;
if (countDown) {
// ratio of difference from max
if (a < b) {
ratio = (goal - a) / Math.Max(1, (goal - b));
DebugScrambler("Ratio T1/T2: " + a + " vs " + b + " <- [" + goal + "]: " + (goal-a) + "/" + Math.Max(1, (goal-b)) + " = " + ratio.ToString("F2"));
} else {
ratio = (goal - b) / Math.Max(1, (goal - a));
DebugScrambler("Ratio T2/T1: " + a + " vs " + b + " <- [" + goal + "]: " + (goal-b) + "/" + Math.Max(1, (goal-a)) + " = " + ratio.ToString("F2"));
}
} else {
// direct ratio
if (a > b) {
ratio = a / Math.Max(1, b);
DebugScrambler("Ratio T1/T2: " + a + " vs " + b + " -> [" + goal + "]: " + a + "/" + Math.Max(1, b) + " = " + ratio.ToString("F2"));
} else {
ratio = b / Math.Max(1, a);
DebugScrambler("Ratio T2/T2: " + a + " vs " + b + " -> [" + goal + "]: " + b + "/" + Math.Max(1, a) + " = " + ratio.ToString("F2"));
}
}
*/
String smsg = String.Empty;
double ratio = ComputeTicketRatio(a, b, goal, countDown, out smsg);
DebugScrambler(smsg);
if ((ratio * 100) < OnlyOnFinalTicketPercentage) {
DebugScrambler("Only On Final Ticket Percentage >= " + OnlyOnFinalTicketPercentage.ToString("F0") + "%, but ratio is only " + (ratio * 100).ToString("F0") + "%, no scramble this round");
return;
} else {
DebugScrambler("Only On Final Ticket Percentage >= " + OnlyOnFinalTicketPercentage.ToString("F0") + "% and ratio is " + (ratio * 100).ToString("F0") + "%");
}
}
DebugScrambler("Scrambling teams by " + ScrambleBy + " in " + DelaySeconds.ToString("F0") + " seconds");
Chat("all", TeamsWillBeScrambled, false);
// Activate the scrambler thread
lock (fScramblerLock) {
fScramblerLock.MaxDelay = DelaySeconds;
fScramblerLock.LastUpdate = DateTime.Now;
Monitor.Pulse(fScramblerLock);
}
}