private void ResetRound() { _voteOptions.Clear(); _lastRoundSeed = _roundSeed; _roundSeed = 0; _roundPriority = 0; _roundStartTimestamp = 0; _localPlayerIndex = -1; _matchBuffer = null; }
private void UpdateRound(Terminal terminal) { var roundDuration = Stopwatch.GetTimestamp() - _roundStartTimestamp; if (roundDuration < Timestamps.VoteStart) { TournamentPhase = TournamentPhase.VoteCountdown; NextPhaseTimestamp = _roundStartTimestamp + Timestamps.VoteStart; LocalPlayer.VoteOption = 0; } else { if (roundDuration < Timestamps.MatchTransitionStart) { LocalPlayer.IsReady = false; if (_voteOptions.Count == 0) { LocalPlayer.TournamentScore = (int)(LocalPlayer.TournamentScore * _scoreDecay); _roundRandom = new Random(_roundSeed); _voteOptions = _roundRandom.Shuffle(DisciplineDirectory.Disciplines).Take(3).ToList(); _voteOptions.Insert(0, null); } TournamentPhase = TournamentPhase.Vote; NextPhaseTimestamp = _roundStartTimestamp + Timestamps.MatchTransitionStart; } else { if (LocalPlayer.VoteOption == 0) { /* Local player opted out of the match. */ ResetRound(); return; } if (roundDuration < Timestamps.MatchCountdownStart) { TournamentPhase = TournamentPhase.MatchTransition; NextPhaseTimestamp = _roundStartTimestamp + Timestamps.MatchCountdownStart; } else { if (_matchBuffer == null) { var activePlayers = _roundRandom.Shuffle(_players.Values.Where(p => p.VoteOption != 0).OrderBy(p => p.Id)); if (activePlayers.Count < 2) { ResetRound(); return; } _localPlayerIndex = activePlayers.IndexOf(LocalPlayer); var winningDiscipline = _voteOptions[activePlayers[_roundRandom.Next(activePlayers.Count)].VoteOption]; _voteOptions.Clear(); DiscipleName = winningDiscipline.Name; var newOutput = new Output(); var playerDescriptions = activePlayers.Select( p => new PlayerDescription { Color = p.PlayerColor, Name = p.Name, Output = p == LocalPlayer ? newOutput : NullOutput.Instance, }).ToList(); var matchDescription = new MatchDescription { Players = playerDescriptions, Random = _roundRandom, Output = newOutput, LocalPlayerIndex = _localPlayerIndex, }; var match = winningDiscipline.CreateMatch(matchDescription); _matchBuffer = new MatchBuffer(match); _lastUpdatedFrame = 0; } int currentFrame; if (roundDuration < Timestamps.MatchStart) { TournamentPhase = TournamentPhase.MatchCountdown; NextPhaseTimestamp = _roundStartTimestamp + Timestamps.MatchStart; currentFrame = 0; } else { TournamentPhase = TournamentPhase.Match; NextPhaseTimestamp = 0; currentFrame = (int)((roundDuration - Timestamps.MatchStart) / GameSpeed.FrameDuration); var input = terminal.Input; while (currentFrame > _lastUpdatedFrame) { ++_lastUpdatedFrame; _matchBuffer.SetInput(_lastUpdatedFrame, _localPlayerIndex, input); _inputEntries.Add(new InputEntry(_lastUpdatedFrame, input)); } } /* Render a 50ms old frame to hide a certain amount of lag. */ _matchBuffer.UpdateToFrame(currentFrame - _latencyFrames); var output = _matchBuffer.PredictedMatch.Output as Output; if (output != null) { double frame = (roundDuration - Timestamps.MatchStart) / (double)GameSpeed.FrameDuration - _latencyFrames; output.Render(frame, terminal); } if (_matchBuffer.IsCompleted) { var scores = _matchBuffer.KnownMatch.Players.Select(p => p.Score).ToList(); var localPlayerScore = scores[_localPlayerIndex]; int roundScore = scores.Sum(s => s < localPlayerScore ? _winScore : (s == localPlayerScore ? _tieScore : 0)); LocalPlayer.TournamentScore += roundScore; ResetRound(); } } } } }