Exemplo n.º 1
0
 public GameDialog(Game.Result readyResult)
 {
     _resultsViewMode = true;
     DataContext      = new ViewModel();
     InitializeComponent();
     OnResult(readyResult, null);
 }
Exemplo n.º 2
0
 public string AttackFaceUpOpponent(MonsterCard attackingCard, MonsterCard defendingCard)
 {
     Game.Result r = myCurrentGame.RequestAttack(id, attackingCard, defendingCard);
     if (r.Equals(Game.Result.Success))
     {
         return("");
     }
     else
     {
         return(r.ToString());
     }
 }
Exemplo n.º 3
0
 public string AttackLifePoints(MonsterCard attackingCard)
 {
     Game.Result r = myCurrentGame.RequestAttackLifePoints(id, attackingCard);
     if (r.Equals(Game.Result.Success))
     {
         return("");
     }
     else
     {
         return(r.ToString());
     }
 }
Exemplo n.º 4
0
 /// <summary>
 /// Asks the game to change the mode of the card (to attack mode or defense mode).
 /// </summary>
 /// <param name="toChangeModeOf">to change to attack mode or defense mode</param>
 /// <returns>"" if successful. Error message if Error</returns>
 public string ChangeModeOfCard(MonsterCard toChangeModeOf)
 {
     Game.Result r = myCurrentGame.RequestChangeModeOfCard(id, toChangeModeOf);
     if (r.Equals(Game.Result.Success))
     {
         return("");
     }
     else
     {
         return(r.ToString());
     }
 }
Exemplo n.º 5
0
        public string TryEquip(Object EquipableCard, string nameOfCardToEquipTo)
        {
            bool found = false;

            if (hand.Contains(EquipableCard))
            {
                for (int i = 0; i < faceDownCardsInMonsterZone.Count && !found; i++)
                {
                    if (faceDownCardsInMonsterZone[i].getName().Equals(nameOfCardToEquipTo))
                    {
                        MonsterCard equippingTo = faceDownCardsInMonsterZone[i];
                        found = true;
                        Game.Result r = myCurrentGame.RequestEquip(id, EquipableCard, ref equippingTo);
                        if (r == Game.Result.Success)
                        {
                            faceDownCardsInMonsterZone[i] = equippingTo;
                            SendToGraveYard(EquipableCard, Zone.Hand);
                            return("");
                        }
                        else
                        {
                            return(r.ToString());
                        }
                    }
                }
                IList <MonsterCard> faceUpMonsters = m_meReadOnly.getFaceUpMonstersInMonsterZone();
                for (int i = 0; i < faceUpMonsters.Count && !found; i++)
                {
                    if (faceUpMonsters[i].getName().Equals(nameOfCardToEquipTo))
                    {
                        found = true;
                        MonsterCard equippingTo = faceUpMonsters[i];
                        Game.Result r           = myCurrentGame.RequestEquip(id, EquipableCard, ref equippingTo);
                        if (r == Game.Result.Success)
                        {
                            faceUpMonsters[i] = equippingTo;
                            m_meReadOnly.setFaceUpMonstersInMonsterZone(faceUpMonsters);
                            SendToGraveYard(EquipableCard, Zone.Hand);
                            return("");
                        }
                        else
                        {
                            return(r.ToString());
                        }
                    }
                }
                return("Failed to find card");
            }
            else
            {
                return("Equipable Card not in hand anymore.");
            }
        }
Exemplo n.º 6
0
 /// <summary>
 /// Tell the game and opponent you are done for this turn. Should be called after you attack, summon, etc.
 /// </summary>
 /// <returns>"" if successfully ended turn. Error string if failed.</returns>
 public string EndTurn()
 {
     Game.Result r = myCurrentGame.RequestEndTurn(id);
     if (r == Game.Result.Success)
     {
         return("");
     }
     else
     {
         return(r.ToString());
     }
 }
Exemplo n.º 7
0
        internal ReplayHelper(Game.StartProperties startProperties, Game.Result result)
        {
            OriginalFilename = Path.Combine(FileUtils.GetReplaysDirectory(), ReplayObject.PreviousReplayName);
            RenamedFilename  = FileUtils.EnsureUnique(OriginalFilename);
            Name             = GetReplayName(startProperties, result);

            IsAvailable = File.Exists(OriginalFilename);
            if (IsAvailable && SettingsHolder.Drive.AutoSaveReplays)
            {
                IsRenamed = true;
            }
        }
Exemplo n.º 8
0
 public string Sacrifice(MonsterCard toSacrifice)
 {
     Game.Result r = myCurrentGame.RequestSacrifice(id, toSacrifice);
     if (r.Equals(Game.Result.Success))
     {
         return("");
     }
     else
     {
         return(r.ToString());
     }
 }
Exemplo n.º 9
0
 public string AttackFaceDownOpponent(MonsterCard attackingCard, Mode faceDownCardsMode)
 {
     Game.Result r = myCurrentGame.RequestAttackOnFaceDownCard(id, attackingCard, faceDownCardsMode);
     if (r.Equals(Game.Result.Success))
     {
         return("");
     }
     else
     {
         return(r.ToString());
     }
 }
Exemplo n.º 10
0
        public void AddNewResult([NotNull] Game.StartProperties startProperties, [NotNull] Game.Result result)
        {
            var directory = SessionsDirectory;

            FileUtils.EnsureDirectoryExists(directory);

            var fileName = DateTime.Now.ToString("yyMMdd-HHmmss") + ".json";
            var raceOut  = AcPaths.GetResultJsonFilename();

            JObject data = null;

            if (File.Exists(raceOut))
            {
                try {
                    // Let’s try to save original data instead in case we missed something during parsing.
                    // But let’s remove formatting just in case.
                    data = JObject.Parse(File.ReadAllText(raceOut));
                } catch (Exception e) {
                    Logging.Warning(e);
                }
            }

            if (data == null)
            {
                data = JObject.FromObject(result);
            }

            // Trying to keep race params as well…
            // TODO: Do it the other way around, from start params?

            var raceIni = AcPaths.GetRaceIniFilename();

            if (File.Exists(raceIni))
            {
                data[KeyRaceIni] = File.ReadAllText(raceIni);
            }

            var quickDrive = startProperties.GetAdditional <QuickDrivePresetProperty>();

            if (quickDrive?.SerializedData != null)
            {
                data[KeyQuickDrive] = quickDrive.SerializedData;
            }

            File.WriteAllText(FileUtils.EnsureUnique(Path.Combine(directory, fileName)), data.ToString(Formatting.None));
        }
Exemplo n.º 11
0
        public int GetTakenPlace(Game.Result result)
        {
            if (result == null)
            {
                return(UnremarkablePlace);
            }

            var drift = result.GetExtraByType <Game.ResultExtraDrift>();

            if (drift != null && Type == PlaceConditionsType.Points)
            {
                return(GetTakenPlace(drift.Points));
            }

            var timeAttack = result.GetExtraByType <Game.ResultExtraTimeAttack>();

            if (timeAttack != null && Type == PlaceConditionsType.Points)
            {
                return(GetTakenPlace(timeAttack.Points));
            }

            var drag = result.GetExtraByType <Game.ResultExtraDrag>();

            if (drag != null && Type == PlaceConditionsType.Wins)
            {
                return(GetTakenPlace(drag.Wins));
            }

            switch (Type)
            {
            case PlaceConditionsType.Points:
            case PlaceConditionsType.Wins:
                return(UnremarkablePlace);

            case PlaceConditionsType.Position:
                var place = result.Sessions?.LastOrDefault(x => x.BestLaps?.Any() == true)?.CarPerTakenPlace?.IndexOf(0);
                return(place.HasValue ? GetTakenPlace(place.Value + 1) : UnremarkablePlace);

            case PlaceConditionsType.Time:
                var time = result.Sessions?.LastOrDefault(x => x.BestLaps?.Any() == true)?.BestLaps?.FirstOrDefault(x => x.CarNumber == 0)?.Time;
                return(time.HasValue ? GetTakenPlace((int)time.Value.TotalMilliseconds) : UnremarkablePlace);

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Exemplo n.º 12
0
 /// <summary>
 /// A request to normal summon the monster is given to the game class. If allowable, it will be summoned.
 /// </summary>
 /// <param name="monsterToSummon">A MonsterCard to play.</param>
 /// <returns>"" if successful. Error string if failed.</returns>
 public string NormalSummon(Object monsterToSummon)
 {
     if (monsterToSummon is MonsterCard && hand.Contains(monsterToSummon))
     {
         Game.Result amIAllowedToSummon = myCurrentGame.RequestNormalSummon(id, monsterToSummon, faceDownCardsInMonsterZone.Count + m_meReadOnly.getFaceUpMonstersInMonsterZone().Count);
         if (amIAllowedToSummon.ToString().Equals("Success"))
         {
             return("");
         }
         else
         {
             return(amIAllowedToSummon.ToString());
         }
     }
     else
     {
         return("Either Card is not a monster or the card is not in your hand!");
     }
 }
Exemplo n.º 13
0
        public static string GetType(Game.StartProperties startProperties, [CanBeNull] Game.Result result)
        {
            // TODO: drag mode
            if (startProperties.ModeProperties is Game.DriftProperties)
            {
                return("Drift");
            }

            if (startProperties.ModeProperties is Game.TimeAttackProperties)
            {
                return("Time Attack");
            }

            if (startProperties.ModeProperties is Game.HotlapProperties)
            {
                return("Hotlap");
            }

            if (startProperties.ModeProperties is Game.OnlineProperties)
            {
                return("Online");
            }

            if (startProperties.ModeProperties is Game.PracticeProperties)
            {
                return("Practice");
            }

            if (result?.Sessions?.Length == 1)
            {
                return("Race");
            }

            if (result?.Sessions?.Length > 1)
            {
                return("Weekend");
            }

            return(startProperties.ModeProperties is Game.RaceProperties ? "Race" : "Something Unspeakable");
        }
Exemplo n.º 14
0
        private static string GetValue(Game.StartProperties startProperties, [CanBeNull] Game.Result result, string key)
        {
            if (startProperties.BasicProperties == null)
            {
                return(null);
            }

            switch (key)
            {
            case "type":
                return(GetType(startProperties, result));

            case "car":
                return(CarsManager.Instance.GetById(startProperties.BasicProperties.CarId)?.DisplayName);

            case "car.id":
                return(startProperties.BasicProperties.CarId);

            case "track":
                var track  = TracksManager.Instance.GetById(startProperties.BasicProperties.TrackId);
                var config = startProperties.BasicProperties.TrackConfigurationId != null
                            ? track?.GetLayoutByLayoutId(startProperties.BasicProperties.TrackConfigurationId) : track;

                return(config?.Name);

            case "track.id":
                return(startProperties.BasicProperties.TrackId);

            case "date":
                return(startProperties.StartTime.ToString(CultureInfo.CurrentCulture));

            case "date_ac":
                return(GetAcDate(startProperties.StartTime));

            default:
                return(null);
            }
        }
Exemplo n.º 15
0
        void IGameUi.OnResult(Game.Result result, ReplayHelper replayHelper)
        {
            EnableRenderer(false);
            ProgressBar.Visibility = Visibility.Collapsed;

            var time = result?.GetExtraByType <Game.ResultExtraBestLap>()?.Time;

            if (!time.HasValue || time.Value == TimeSpan.Zero)
            {
                _bestLapTime = null;
                RevertUi(true);
            }
            else
            {
                _resultShown               = true;
                _bestLapTime               = time;
                LoadingText.Visibility     = Visibility.Visible;
                LoadingText.FontSize       = 20d;
                LoadingText.Text           = "Best time: " + string.Format("{0:mm}:{0:ss}:{0:fff}", time.Value);
                GameResultOk.Visibility    = Visibility.Visible;
                PlayerNamePanel.Visibility = Visibility.Visible;
            }
        }
Exemplo n.º 16
0
        public static string Process([NotNull] string str, [NotNull] Game.StartProperties startProperties, [CanBeNull] Game.Result result)
        {
            if (startProperties == null)
            {
                throw new ArgumentNullException(nameof(startProperties));
            }
            if (str == null)
            {
                throw new ArgumentNullException(nameof(str));
            }

            return(ReplayNameRegex.Replace(str, match => {
                var value = GetValue(startProperties, result, match.Groups[1].Value)?.Trim();
                if (string.IsNullOrEmpty(value))
                {
                    return "-";
                }

                foreach (var c in match.Groups[2].Success ? match.Groups[2].Value.ToLowerInvariant() : string.Empty)
                {
                    switch (c)
                    {
                    case 'l':
                        value = value.ToLowerInvariant();
                        break;

                    case 'u':
                        value = value.ToUpperInvariant();
                        break;

                    case '0':
                        value = value.Substring(0, 1);
                        break;

                    default:
                        Logging.Warning("Unsupported modifier: " + c);
                        break;
                    }
                }

                return value;
            }));
        }
Exemplo n.º 17
0
 public GameFinishedArgs([NotNull] Game.StartProperties startProperties, Game.Result result)
 {
     StartProperties = startProperties;
     Result          = result;
 }
Exemplo n.º 18
0
        void IGameUi.OnResult(Game.Result result, ReplayHelper replayHelper)
        {
            if (result != null && result.NumberOfSessions == 1 && result.Sessions.Length == 1 &&
                result.Sessions[0].Type == Game.SessionType.Practice && SettingsHolder.Drive.SkipPracticeResults ||
                _properties?.ReplayProperties != null || _properties?.BenchmarkProperties != null)
            {
                Close();
                return;
            }

            /* save replay button * /
             * Func<string> buttonText = () => replayHelper?.IsReplayRenamed == true ?
             *      AppStrings.RaceResult_UnsaveReplay : AppStrings.RaceResult_SaveReplay;
             *
             * var saveReplayButton = CreateExtraDialogButton(buttonText(), () => {
             *  if (replayHelper == null) {
             *      Logging.Warning("ReplayHelper=<NULL>");
             *      return;
             *  }
             *
             *  replayHelper.IsReplayRenamed = !replayHelper.IsReplayRenamed;
             * });
             *
             * if (replayHelper == null) {
             *  saveReplayButton.IsEnabled = false;
             * } else {
             *  replayHelper.PropertyChanged += (sender, args) => {
             *      if (args.PropertyName == nameof(ReplayHelper.IsReplayRenamed)) {
             *          saveReplayButton.Content = buttonText();
             *      }
             *  };
             * }
             *
             * /* save replay alt button */
            ButtonWithComboBox saveReplayButton;

            if (replayHelper != null)
            {
                Func <string> buttonText = () => replayHelper.IsRenamed ?
                                           AppStrings.RaceResult_UnsaveReplay : AppStrings.RaceResult_SaveReplay;
                Func <string> saveAsText = () => string.Format(replayHelper.IsRenamed ? "Saved as “{0}”" : "Save as “{0}”",
                                                               replayHelper.Name);

                saveReplayButton = new ButtonWithComboBox {
                    Margin    = new Thickness(4, 0, 0, 0),
                    MinHeight = 21,
                    MinWidth  = 65,
                    Content   = ToolsStrings.Shared_Replay,
                    Command   = new AsyncCommand(replayHelper.Play),
                    MenuItems =
                    {
                        new MenuItem {
                            Header = saveAsText(), Command = new DelegateCommand(() =>{
                                var newName = Prompt.Show("Save replay as:", "Replay Name", replayHelper.Name, "?", required: true);
                                if (!string.IsNullOrWhiteSpace(newName))
                                {
                                    replayHelper.Name = newName;
                                }

                                replayHelper.IsRenamed = true;
                            })
                        },
                        new MenuItem {
                            Header = buttonText(), Command = new DelegateCommand(replayHelper.Rename)
                        },
                        new Separator(),
                        new MenuItem {
                            Header  = "Share Replay",
                            Command = new AsyncCommand(() =>{
                                var car = _properties?.BasicProperties?.CarId == null ? null :
                                          CarsManager.Instance.GetById(_properties.BasicProperties.CarId);
                                var track = _properties?.BasicProperties?.TrackId == null ? null :
                                            TracksManager.Instance.GetById(_properties.BasicProperties.TrackId);
                                return(SelectedReplayPage.ShareReplay(replayHelper.Name, replayHelper.Filename, car, track));
                            })
                        },
                    }
                };

                replayHelper.PropertyChanged += (sender, args) => {
                    if (args.PropertyName == nameof(ReplayHelper.IsRenamed))
                    {
                        ((MenuItem)saveReplayButton.MenuItems[0]).Header = saveAsText();
                        ((MenuItem)saveReplayButton.MenuItems[1]).Header = buttonText();
                    }
                };
            }
            else
            {
                saveReplayButton = null;
            }

            var tryAgainButton = CreateExtraDialogButton(AppStrings.RaceResult_TryAgain, () => {
                CloseWithResult(MessageBoxResult.None);
                GameWrapper.StartAsync(_properties).Forget();
            });

            Button fixButton = null;

            if (result == null || !result.IsNotCancelled)
            {
                Model.CurrentState = ViewModel.State.Cancelled;

                var whatsGoingOn = _properties?.GetAdditional <WhatsGoingOn>();
                fixButton          = this.CreateFixItButton(whatsGoingOn?.Solution);
                Model.ErrorMessage = whatsGoingOn?.GetDescription();
            }
            else
            {
                try {
                    Model.CurrentState = ViewModel.State.Finished;
                    Model.FinishedData = GetFinishedData(_properties, result);
                } catch (Exception e) {
                    Logging.Warning(e);

                    Model.CurrentState = ViewModel.State.Error;
                    Model.ErrorMessage = AppStrings.RaceResult_ResultProcessingError;
                    Buttons            = new[] { CloseButton };
                    return;
                }
            }

            Buttons = new[] {
                fixButton,
                fixButton == null ? saveReplayButton : null,
                fixButton == null ? tryAgainButton : null,
                CloseButton
            };
        }
Exemplo n.º 19
0
 public GameEndedArgs([NotNull] Game.StartProperties startProperties, [CanBeNull] Game.Result result) {
     StartProperties = startProperties;
     Result = result;
 }
Exemplo n.º 20
0
        private static string GetReplayName([CanBeNull] Game.StartProperties startProperties, [CanBeNull] Game.Result result)
        {
            if (startProperties == null)
            {
                return($"_autosave_{DateTime.Now.ToMillisecondsTimestamp()}.acreplay");
            }

            var s = SettingsHolder.Drive.ReplaysNameFormat;

            if (string.IsNullOrEmpty(s))
            {
                s = SettingsHolder.Drive.DefaultReplaysNameFormat;
            }

            return(FileUtils.EnsureFileNameIsValid(VariablesReplacement.Process(s, startProperties, result)));
        }
Exemplo n.º 21
0
        private static BaseFinishedData GetFinishedData(Game.StartProperties properties, Game.Result result)
        {
            var conditions = properties?.GetAdditional <PlaceConditions>();
            var takenPlace = conditions?.GetTakenPlace(result) ?? PlaceConditions.UnremarkablePlace;

            Logging.Debug($"Place conditions: {conditions?.GetDescription()}, result: {result.GetDescription()}");

            if (result.GetExtraByType <Game.ResultExtraDrift>(out var drift))
            {
                return(new DriftFinishedData {
                    Points = drift.Points,
                    MaxCombo = drift.MaxCombo,
                    MaxLevel = drift.MaxLevel,
                    TakenPlace = takenPlace
                });
            }

            if (result.GetExtraByType <Game.ResultExtraTimeAttack>(out var timeAttack))
            {
                var bestLapTime = result.Sessions?.SelectMany(x => from lap in x.BestLaps where lap.CarNumber == 0 select lap.Time).MinOrDefault();
                return(new TimeAttackFinishedData {
                    Points = timeAttack.Points,
                    Laps = result.Sessions?.Sum(x => x.LapsTotalPerCar?.FirstOrDefault() ?? 0) ?? 0,
                    BestLapTime = bestLapTime == TimeSpan.Zero ? null : bestLapTime,
                    TakenPlace = takenPlace
                });
            }

            if (result.GetExtraByType <Game.ResultExtraBestLap>(out var bestLap) && bestLap.IsNotCancelled && result.Sessions?.Length == 1 &&
                result.Players?.Length == 1)
            {
                var bestLapTime = result.Sessions.SelectMany(x => from lap in x.BestLaps where lap.CarNumber == 0 select lap.Time).MinOrDefault();

                var sectorsPerSections  = result.Sessions.SelectMany(x => from lap in x.Laps where lap.CarNumber == 0 select lap.SectorsTime).ToList();
                var theoreticallLapTime = sectorsPerSections.FirstOrDefault()?.Select((x, i) => sectorsPerSections.Select(y => y[i]).Min()).Sum();

                return(result.Sessions[0].Name == AppStrings.Rsr_SessionName ? new RsrFinishedData {
                    Laps = result.Sessions.Sum(x => x.LapsTotalPerCar?.FirstOrDefault() ?? 0),
                    BestLapTime = bestLapTime == TimeSpan.Zero ? (TimeSpan?)null : bestLapTime,
                    TheoreticallLapTime = theoreticallLapTime,
                    TakenPlace = takenPlace
                } : new HotlapFinishedData {
                    Laps = result.Sessions.Sum(x => x.LapsTotalPerCar?.FirstOrDefault() ?? 0),
                    BestLapTime = bestLapTime == TimeSpan.Zero ? (TimeSpan?)null : bestLapTime,
                    TheoreticallLapTime = theoreticallLapTime,
                    TakenPlace = takenPlace
                });
            }

            var isOnline   = properties?.ModeProperties is Game.OnlineProperties;
            var playerName = isOnline && SettingsHolder.Drive.DifferentPlayerNameOnline
                    ? SettingsHolder.Drive.PlayerNameOnline : SettingsHolder.Drive.PlayerName;

            if (result.Sessions?.Length == 1 && result.Sessions[0].Name == Game.TrackDaySessionName && result.Players?.Length > 1)
            {
                var session    = result.Sessions[0];
                var playerLaps = session.LapsTotalPerCar?[0] ?? 1;
                session.LapsTotalPerCar = session.LapsTotalPerCar?.Select(x => Math.Min(x, playerLaps)).ToArray();
                session.Laps            = session.Laps?.Where(x => x.LapId < playerLaps).ToArray();
                session.BestLaps        = session.BestLaps?.Select(x => {
                    if (x.LapId < playerLaps)
                    {
                        return(x);
                    }
                    var best = session.Laps?.Where(y => y.CarNumber == x.CarNumber).MinEntryOrDefault(y => y.Time);
                    if (best == null)
                    {
                        return(null);
                    }
                    return(new Game.ResultBestLap {
                        Time = best.Time,
                        LapId = best.LapId,
                        CarNumber = x.CarNumber
                    });
                }).NonNull().ToArray();
            }

            var dragExtra    = result.GetExtraByType <Game.ResultExtraDrag>();
            var sessionsData = result.Sessions?.Select(session => {
                int[] takenPlaces;
                SessionFinishedData data;

                if (dragExtra != null)
                {
                    data = new DragFinishedData {
                        BestReactionTime = dragExtra.ReactionTime,
                        Total            = dragExtra.Total,
                        Wins             = dragExtra.Wins,
                        Runs             = dragExtra.Runs,
                    };

                    var delta   = dragExtra.Wins * 2 - dragExtra.Runs;
                    takenPlaces = new[] {
                        delta >= 0 ? 0 : 1,
                        delta <= 0 ? 0 : 1
                    };
                }
                else
                {
                    data        = new SessionFinishedData(session.Name?.ApartFromLast(@" Session"));
                    takenPlaces = session.GetTakenPlacesPerCar();
                }

                var sessionBestLap = session.BestLaps?.MinEntryOrDefault(x => x.Time);
                var sessionBest    = sessionBestLap?.Time;

                data.PlayerEntries = (
                    from player in result.Players
                    let car = CarsManager.Instance.GetById(player.CarId ?? "")
                              let carSkin = car?.GetSkinById(player.CarSkinId ?? "")
                                            select new { Player = player, Car = car, CarSkin = carSkin }
                    ).Select((entry, i) => {
                    var bestLapTime = session.BestLaps?.Where(x => x.CarNumber == i).MinEntryOrDefault(x => x.Time)?.Time;
                    var laps        = session.Laps?.Where(x => x.CarNumber == i).Select(x => new SessionFinishedData.PlayerLapEntry {
                        LapNumber          = x.LapId + 1,
                        Sectors            = x.SectorsTime,
                        Cuts               = x.Cuts,
                        TyresShortName     = x.TyresShortName,
                        Total              = x.Time,
                        DeltaToBest        = bestLapTime.HasValue ? x.Time - bestLapTime.Value : (TimeSpan?)null,
                        DeltaToSessionBest = sessionBest.HasValue ? x.Time - sessionBest.Value : (TimeSpan?)null,
                    }).ToArray();

                    var lapTimes = laps?.Skip(1).Select(x => x.Total.TotalSeconds).Where(x => x > 10d).ToList();
                    double?progress, spread;
                    if (lapTimes == null || lapTimes.Count < 2)
                    {
                        progress = null;
                        spread   = null;
                    }
                    else
                    {
                        var firstHalf    = lapTimes.Count / 2;
                        var firstMedian  = lapTimes.Take(firstHalf).Median();
                        var secondMedian = lapTimes.Skip(firstHalf).Median();
                        progress         = 1d - secondMedian / firstMedian;
                        spread           = (lapTimes.Max() - lapTimes.Min()) / bestLapTime?.TotalSeconds;
                    }

                    return(new SessionFinishedData.PlayerEntry {
                        Name = i == 0 ? playerName : entry.Player.Name,
                        IsPlayer = i == 0,
                        Index = i,
                        Car = entry.Car,
                        CarSkin = entry.CarSkin,
                        TakenPlace = i < takenPlaces?.Length ? takenPlaces[i] + 1 : DefinitelyNonPrizePlace,
                        PrizePlace = takenPlaces?.Length > 1,
                        LapsCount = session.LapsTotalPerCar?.ArrayElementAtOrDefault(i) ?? 0,
                        BestLapTime = bestLapTime,
                        DeltaToSessionBest = sessionBestLap?.CarNumber == i ? null : bestLapTime - sessionBest,
                        TotalTime = session.Laps?.Where(x => x.CarNumber == i).Select(x => x.SectorsTime.Sum()).Sum(),
                        Laps = laps,
                        LapTimeProgress = progress,
                        LapTimeSpread = spread
                    });
                }).OrderBy(x => x.TakenPlace).ToList();

                if (data.PlayerEntries.Count > 0)
                {
                    var maxLaps       = data.PlayerEntries.Select(x => x.Laps.Length).Max();
                    var bestTotalTime = data.PlayerEntries.Where(x => x.Laps.Length == maxLaps).MinEntryOrDefault(x => x.TotalTime ?? TimeSpan.MaxValue);
                    foreach (var entry in data.PlayerEntries)
                    {
                        var lapsDelta = maxLaps - entry.Laps.Length;
                        if (bestTotalTime == entry)
                        {
                            entry.TotalTimeDelta = "-";
                        }
                        else if (lapsDelta > 0)
                        {
                            entry.TotalTimeDelta = $"+{lapsDelta} {PluralizingConverter.Pluralize(lapsDelta, "lap")}";
                        }
                        else
                        {
                            var t = entry.TotalTime - bestTotalTime?.TotalTime;
                            var v = t?.ToMillisecondsString();
                            entry.TotalTimeDelta = t == TimeSpan.Zero ? "" : v != null ? $"+{v}" : null;
                        }
                    }
                }

                var bestProgress = (from player in data.PlayerEntries
                                    where player.LapTimeProgress > 0.03
                                    orderby player.LapTimeProgress descending
                                    select player).FirstOrDefault();
                var bestConsistent = (from player in data.PlayerEntries
                                      where player.LapTimeSpread < 0.02
                                      orderby player.LapTimeSpread descending
                                      select player).FirstOrDefault();

                data.RemarkableNotes = new[] {
                    sessionBestLap == null ? null :
                    new SessionFinishedData.RemarkableNote("[b]Best lap[/b] made by ", data.PlayerEntries.GetByIdOrDefault(sessionBestLap.CarNumber),
                                                           null),
                    new SessionFinishedData.RemarkableNote("[b]The Best Off-roader Award[/b] goes to ", (from player in data.PlayerEntries
                                                                                                         let cuts =
                                                                                                             (double)player.Laps.Sum(x => x.Cuts)
                                                                                                             / player.Laps.Length
                                                                                                             where cuts > 1.5
                                                                                                             orderby cuts descending
                                                                                                             select player).FirstOrDefault(), null),
                    new SessionFinishedData.RemarkableNote("[b]Remarkable progress[/b] shown by ", bestProgress, null),
                    new SessionFinishedData.RemarkableNote("[b]The most consistent[/b] is ", bestConsistent, null),
                }.Where(x => x?.Player != null).ToList();
                return(data);
            }).ToList();

            return(sessionsData?.Count == 1 ? (BaseFinishedData)sessionsData.First() :
                   sessionsData?.Any() == true ? new SessionsFinishedData(sessionsData) : null);
        }
Exemplo n.º 22
0
        private static BaseFinishedData GetFinishedData(Game.StartProperties properties, Game.Result result)
        {
            var conditions = properties?.GetAdditional <PlaceConditions>();
            var takenPlace = conditions?.GetTakenPlace(result) ?? PlaceConditions.UnremarkablePlace;

            Logging.Debug($"Place conditions: {conditions?.GetDescription()}, result: {result.GetDescription()}");

            {
                var extra = result.GetExtraByType <Game.ResultExtraDrift>();
                if (extra != null)
                {
                    return(new DriftFinishedData {
                        Points = extra.Points,
                        MaxCombo = extra.MaxCombo,
                        MaxLevel = extra.MaxLevel,
                        TakenPlace = takenPlace
                    });
                }
            }

            {
                var extra = result.GetExtraByType <Game.ResultExtraTimeAttack>();
                if (extra != null)
                {
                    var bestLapTime = result.Sessions.SelectMany(x => from lap in x.BestLaps where lap.CarNumber == 0 select lap.Time).MinOrDefault();
                    return(new TimeAttackFinishedData {
                        Points = extra.Points,
                        Laps = result.Sessions.Sum(x => x.LapsTotalPerCar.FirstOrDefault()),
                        BestLapTime = bestLapTime == TimeSpan.Zero ? (TimeSpan?)null : bestLapTime,
                        TakenPlace = takenPlace
                    });
                }
            }

            {
                var extra = result.GetExtraByType <Game.ResultExtraBestLap>();
                if (extra != null && extra.IsNotCancelled && result.Sessions.Length == 1 && result.Players.Length == 1)
                {
                    var bestLapTime = result.Sessions.SelectMany(x => from lap in x.BestLaps where lap.CarNumber == 0 select lap.Time).MinOrDefault();

                    var sectorsPerSections  = result.Sessions.SelectMany(x => from lap in x.Laps where lap.CarNumber == 0 select lap.SectorsTime).ToList();
                    var theoreticallLapTime = sectorsPerSections.FirstOrDefault()?.Select((x, i) => sectorsPerSections.Select(y => y[i]).Min()).Sum();

                    return(new HotlapFinishedData {
                        Laps = result.Sessions.Sum(x => x.LapsTotalPerCar.FirstOrDefault()),
                        BestLapTime = bestLapTime == TimeSpan.Zero ? (TimeSpan?)null : bestLapTime,
                        TheoreticallLapTime = theoreticallLapTime,
                        TakenPlace = takenPlace
                    });
                }
            }

            var isOnline   = properties?.ModeProperties is Game.OnlineProperties;
            var playerName = isOnline && SettingsHolder.Drive.DifferentPlayerNameOnline ? SettingsHolder.Drive.PlayerNameOnline : SettingsHolder.Drive.PlayerName;

            var dragExtra    = result.GetExtraByType <Game.ResultExtraDrag>();
            var sessionsData = result.Sessions.Select(session => {
                int[] takenPlaces;
                SessionFinishedData data;

                if (dragExtra != null)
                {
                    data = new DragFinishedData {
                        BestReactionTime = dragExtra.ReactionTime,
                        Total            = dragExtra.Total,
                        Wins             = dragExtra.Wins,
                        Runs             = dragExtra.Runs,
                    };

                    var delta   = dragExtra.Wins * 2 - dragExtra.Runs;
                    takenPlaces = new[] {
                        delta >= 0 ? 0 : 1,
                        delta <= 0 ? 0 : 1
                    };
                }
                else
                {
                    data        = new SessionFinishedData(session.Name.ApartFromLast(@" Session"));
                    takenPlaces = session.GetTakenPlacesPerCar();
                }

                var sessionBestLap = session.BestLaps.MinEntryOrDefault(x => x.Time);
                var sessionBest    = sessionBestLap?.Time;

                data.PlayerEntries = (
                    from player in result.Players
                    let car = CarsManager.Instance.GetById(player.CarId)
                              let carSkin = car.GetSkinById(player.CarSkinId)
                                            select new { Player = player, Car = car, CarSkin = carSkin }
                    ).Select((entry, i) => {
                    var bestLapTime = session.BestLaps.Where(x => x.CarNumber == i).MinEntryOrDefault(x => x.Time)?.Time;
                    return(new SessionFinishedData.PlayerEntry {
                        Name = i == 0 ? playerName : entry.Player.Name,
                        IsPlayer = i == 0,
                        Car = entry.Car,
                        CarSkin = entry.CarSkin,
                        TakenPlace = i < takenPlaces.Length ? takenPlaces[i] + 1 : DefinitelyNonPrizePlace,
                        PrizePlace = takenPlaces.Length > 1,
                        LapsCount = session.LapsTotalPerCar.ElementAtOrDefault(i),
                        BestLapTime = bestLapTime,
                        DeltaToSessionBest = sessionBestLap?.CarNumber == i ? null : bestLapTime - sessionBest,
                        Total = session.Laps.Where(x => x.CarNumber == i).Select(x => x.Time).Sum(),
                        Laps = session.Laps.Where(x => x.CarNumber == i).Select(x => new SessionFinishedData.PlayerLapEntry {
                            LapNumber = x.LapId + 1,
                            Sectors = x.SectorsTime,
                            Total = x.Time,
                            DeltaToBest = bestLapTime.HasValue ? x.Time - bestLapTime.Value : (TimeSpan?)null,
                            DeltaToSessionBest = sessionBest.HasValue ? x.Time - sessionBest.Value : (TimeSpan?)null,
                        }).ToArray()
                    });
                }).OrderBy(x => x.TakenPlace).ToList();
                return(data);
            }).ToList();

            return(sessionsData.Count == 1 ? (BaseFinishedData)sessionsData.First() :
                   sessionsData.Any() ? new SessionsFinishedData(sessionsData) : null);
        }
Exemplo n.º 23
0
 public GameEndedArgs([NotNull] Game.StartProperties startProperties, [CanBeNull] Game.Result result)
 {
     StartProperties = startProperties;
     Result          = result;
 }
Exemplo n.º 24
0
 public GameFinishedArgs([NotNull] Game.StartProperties startProperties, Game.Result result) {
     StartProperties = startProperties;
     Result = result;
 }