public void Restore(GameBackupModel backup) { if (GameStatus != GameStatusType.Created) { throw new Exception("Нельзя восстановить игру, так как она уже была запущена."); } StoredEvents.AddRange(backup.StoredEvents); GameStatus = backup.GameStatus; LaunchTime = backup.LaunchTime; EndTime = backup.EndTime; foreach (var td in backup.TeamProgress) { LocalTeam team = Teams.Single(x => x.Id == td.Key); team.Progress = new TeamGameProgress( Config.Grid[Teams.IndexOf(team)], td.Value.LastHintTime, td.Value.LastTaskCompleteTime, td.Value.CurrentTaskIndex ); } NewEvents.Add(new GameRestored(DateTime.Now)); SendBroadcastMessage("Игра была восстановлена после перезапуска"); }
public override void Run(GameManager gm) { LocalTeam team = gm.Teams.First(x => x.Id == TeamId); team.Progress = new TeamGameProgress(gm.Config.Grid[gm.Teams.IndexOf(team)], AddDate); team.SendMessage(gm.Noticer, $"Ваше первое задание: {team.Progress.GetCurrentTask().Task}"); }
public override void Run(GameManager gm) { LocalTeam team = gm.Teams.First(x => x.Id == TeamId); team.Progress.LastHintTime = AddDate; GameTask task = team.Progress.GetCurrentTask(); team.SendMessage(gm.Noticer, $"Слив адреса: {task.Hint2} ({task.Address})"); }
public override void Run(GameManager gm) { LocalTeam team = gm.Teams.First(x => x.Id == TeamId); team.Progress.CompleteTask(AddDate, TaskIndex); if (team.Progress.IsAllTaskCompleted()) { team.SendMessage(gm.Noticer, $"Задание слито!\r\nВсе задания выполнены, возвращайтесь на место сбора."); } else { team.SendMessage(gm.Noticer, $"Задание слито!\r\nВаше следующее задание:\r\n{team.Progress.GetCurrentTask().Task}"); } }
/// <summary> /// Обрабатывает один фрейм игры, на текущий момент времени. /// </summary> public void Iterate() { if (GameStatus != GameStatusType.InProgress && GameStatus != GameStatusType.Stopped) { return; } lock (_locker) { // Запоминаем время начала итерации DateTime curTime = DateTime.Now; int eventsCount = NewEvents.Count; // STEP 1: Обрабатываем все ивенты (если они есть) if (eventsCount > 0) { // Получаем список ивентов, обрабатываемый на текущей итерации List <GameEvent> processedEvents = NewEvents.GetRange(0, eventsCount).OrderBy(x => x.AddDate).ToList(); NewEvents.RemoveRange(0, eventsCount); // Выполняем каждый ивент foreach (GameEvent currentEvent in processedEvents) { currentEvent.Run(this); } // Добавляем все обработанные ивенты в список StoredEvents.AddRange(processedEvents); } // STEP 2: Добавляем новые ивенты, если прошло необходимое время (подсказка, слив адреса, слив задания) if (GameStatus != GameStatusType.Stopped) { foreach (LocalTeam t in Teams) { // Получение первого задания, если прошло достаточно времени и команда еще не начала играть. if (t.Progress == null) { if (curTime > ((DateTime)LaunchTime).AddSeconds(Setting.SecondsDelayStart * Teams.IndexOf(t))) { NewEvents.Add(new TeamStartsPlay(curTime, t.Id)); } continue; } if (t.Progress.IsAllTaskCompleted()) { continue; } // Кол-во секунд, прошедшее со сдачи последнего задания double lastCompleteTaskSec = curTime.Subtract(t.Progress.LastTaskCompleteTime).TotalSeconds; // Кол-во секунд, прошедшее с получения последней подсказки double lastHintSec = curTime.Subtract(t.Progress.LastHintTime).TotalSeconds; // ... сливаем задание if (lastCompleteTaskSec > (Setting.TaskDropDelaySec + Setting.Hint2DelaySec + Setting.Hint1DelaySec)) { NewEvents.Add(new TeamDropTask(curTime, t.Id, t.Progress.CurrentTaskIndex)); } // ... сливаем адрес else if (lastCompleteTaskSec > (Setting.Hint2DelaySec + Setting.Hint1DelaySec) && lastHintSec > Setting.Hint2DelaySec) { NewEvents.Add(new TeamGetAddress(curTime, t.Id, t.Progress.CurrentTaskIndex)); } // ... сливаем подсказку else if (lastCompleteTaskSec > (Setting.Hint1DelaySec) && lastHintSec > Setting.Hint1DelaySec) { NewEvents.Add(new TeamGetHint(curTime, t.Id, t.Progress.CurrentTaskIndex)); } } } // STEP 3: Анализируем пришедшие сообщения от пользователей и добавляем новые ивенты List <Message> inputMessages = Noticer.PullInput(); foreach (Message m in inputMessages) { LocalTeam playerTeam = Teams.First(x => x.Id == m.Player.TeamId); if (playerTeam.Progress == null) { m.Player.SendMessage(Noticer, $"Ваша команда еще не получила первое задание."); continue; } if (playerTeam.Progress.GetCurrentTask() == null) { m.Player.SendMessage(Noticer, $"Ваша команда уже выполнила все задания."); continue; } switch (m.Text) { case "задание": m.Player.SendMessage(Noticer, $"Какая-то подсказка."); continue; } if (playerTeam.Progress.GetCurrentTask().Code == m.Text) { NewEvents.Add(new PlayerCompletedTask(curTime, playerTeam.Id, m.Player.Id, playerTeam.Progress.CurrentTaskIndex)); } else { NewEvents.Add(new PlayerFailedTask(curTime, playerTeam.Id, m.Player.Id, playerTeam.Progress.CurrentTaskIndex)); } } // STEP 4: Завершение игры // Переводим игру в статус "останавливается", если пришло время конца игры. if (GameStatus == GameStatusType.InProgress && curTime.Subtract((DateTime)LaunchTime).TotalMinutes > Setting.GameDurationMin) { NewEvents.Add(new GameStopped(DateTime.Now)); } // Если после остановки игры прошло необходимое кол-во минут - завершаем игру. if (GameStatus == GameStatusType.Stopped && EndTime != null && curTime > EndTime?.AddMinutes(Setting.GameClosingDurationMin)) { GameStatus = GameStatusType.Ended; SendBroadcastMessage("Приём кодов завершён."); } } }