private Phase GetPhase(PerModeSettings perMode, bool verbose)
{
if (perMode == null) return Phase.Mid;
// earlyTickets relative to max for count down, 0 for count up
// lateTickets relative to 0 for count down, max for count up
double earlyTickets = perMode.DefinitionOfEarlyPhaseFromStart;
double lateTickets = perMode.DefinitionOfLatePhaseFromEnd;
Phase phase = Phase.Mid;
if (fServerInfo == null) return phase;
if (AdjustForMetro(perMode)) {
lateTickets = perMode.MetroAdjustedDefinitionOfLatePhase;
}
// Special handling for CTF & Carrier Assault modes
bool isCTF = IsCTF();
bool isCarrierAssault = IsCarrierAssault();
bool isObliteration = IsObliteration();
if (isCTF || isCarrierAssault || isObliteration) {
if (fRoundStartTimestamp == DateTime.MinValue) return Phase.Early;
double earlyMinutes = earlyTickets;
double lateMinutes = lateTickets;
// TBD - assume max round time is 20 minutes for CTF at 100%
// TBD - assume max round time is 30 minutes for CRL/CRS at 100%
double maxMinutes = ((isCTF) ? 20 : 30) * fRoundTimeLimit;
if (verbose && DebugLevel >= 8) ConsoleDebug("fRoundTimeLimit = " + (fRoundTimeLimit*100).ToString("F0") + ", maxMinutes = " + maxMinutes);
//double totalRoundMins = DateTime.Now.Subtract(fRoundStartTimestamp).TotalMinutes;
double totalRoundMins = GetTimeInRoundMinutes();
/* moved to ValidateSettings, keep here for reference
// Late is higher priority than early
if (lateMinutes > maxMinutes) {earlyMinutes = 0; lateMinutes = maxMinutes;}
if (earlyMinutes > (maxMinutes - lateMinutes)) {earlyMinutes = maxMinutes - lateMinutes;}
*/
if (totalRoundMins <= earlyMinutes) {
phase = Phase.Early;
} else if (totalRoundMins >= (maxMinutes - lateMinutes)) {
phase = Phase.Late;
} else {
phase = Phase.Mid;
}
if (verbose && DebugLevel >= 8) ConsoleDebug("Phase: " + phase + " (" + totalRoundMins.ToString("F0") + " mins [" + earlyMinutes.ToString("F0") + " - " + (maxMinutes - lateMinutes).ToString("F0") + "])");
return phase;
}
if (fServerInfo.TeamScores == null || fServerInfo.TeamScores.Count < 2) return Phase.Mid;
double tickets = -1;
double goal = 0;
bool countDown = true;
if (fMaxTickets == -1) return Phase.Early;
if (IsCountUp()) {
countDown = false;
foreach (TeamScore ts in fServerInfo.TeamScores) {
if (ts.TeamID == 1) {
goal = ts.WinningScore;
break;
}
}
}
// Find ticket count closest to end
foreach (TeamScore ts in fServerInfo.TeamScores) {
if (tickets == -1) {
tickets = ts.Score;
} else {
if (countDown) {
if (ts.Score < tickets) {
tickets = ts.Score;
}
} else {
if (ts.Score > tickets) {
tickets = ts.Score;
}
}
}
}
if (countDown) {
// Late takes priority over early
if (lateTickets > fMaxTickets) {earlyTickets = 0; lateTickets = fMaxTickets;}
if (lateTickets > (fMaxTickets - earlyTickets)) {earlyTickets = fMaxTickets - lateTickets;}
if (tickets <= lateTickets) {
phase = Phase.Late;
} else if (fIsFullRound && (earlyTickets < fMaxTickets) && tickets >= (fMaxTickets - earlyTickets)) {
phase = Phase.Early;
} else {
phase = Phase.Mid;
}
} else {
// count up
// Late takes priority over early
if (lateTickets > goal) {earlyTickets = 0; lateTickets = goal;}
if (earlyTickets > (goal - lateTickets)) {earlyTickets = goal - lateTickets;}
if (lateTickets < goal && tickets >= (goal - lateTickets)) {
phase = Phase.Late;
} else if (tickets <= earlyTickets) {
phase = Phase.Early;
} else {
phase = Phase.Mid;
}
}
if (verbose && DebugLevel >= 8) ConsoleDebug("Phase: " + phase + " (" + tickets + " of " + fMaxTickets + " to " + goal + ", " + RemainingTicketPercent(tickets, goal).ToString("F0") + "%)");
return phase;
}