/// <summary> /// Converts an OnlineScoreboardScore to a local score. /// </summary> /// <param name="score"></param> /// <returns></returns> public static Score FromOnlineScoreboardScore(OnlineScoreboardScore score) { // Unix timestamp is seconds past epoch var dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); dtDateTime = dtDateTime.AddSeconds(score.Timestamp / 1000f).ToLocalTime(); var localScore = new Score() { IsOnline = true, Id = score.Id, SteamId = score.SteamId, MapMd5 = score.MapMd5, Name = score.Username, DateTime = dtDateTime.ToString(CultureInfo.InvariantCulture), Mode = score.Mode, TotalScore = score.TotalScore, PerformanceRating = score.PerformanceRating, Grade = GradeHelper.GetGradeFromAccuracy((float)score.Accuracy), Accuracy = score.Accuracy, MaxCombo = score.MaxCombo, CountMarv = score.CountMarv, CountPerf = score.CountPerf, CountGreat = score.CountGreat, CountGood = score.CountGood, CountOkay = score.CountOkay, CountMiss = score.CountMiss, Mods = score.Mods }; return(localScore); }
/// <summary> /// Creates a local score object from a score processor. /// </summary> /// <param name="processor"></param> /// <param name="md5"></param> /// <param name="name"></param> /// <param name="scrollSpeed"></param> /// <returns></returns> public static Score FromScoreProcessor(ScoreProcessor processor, string md5, string name, int scrollSpeed, int pauseCount) { var score = new Score() { MapMd5 = md5, Name = name, DateTime = $"{System.DateTime.Now.ToShortDateString()} {System.DateTime.Now.ToShortTimeString()}", Mode = processor.Map.Mode, TotalScore = processor.Score, Grade = processor.Failed ? Grade.F : GradeHelper.GetGradeFromAccuracy(processor.Accuracy), Accuracy = processor.Accuracy, MaxCombo = processor.MaxCombo, CountMarv = processor.CurrentJudgements[Judgement.Marv], CountPerf = processor.CurrentJudgements[Judgement.Perf], CountGreat = processor.CurrentJudgements[Judgement.Great], CountGood = processor.CurrentJudgements[Judgement.Good], CountOkay = processor.CurrentJudgements[Judgement.Okay], CountMiss = processor.CurrentJudgements[Judgement.Miss], Mods = processor.Mods, ScrollSpeed = scrollSpeed, PauseCount = pauseCount, JudgementBreakdown = GzipHelper.Compress(processor.GetJudgementBreakdown()), }; return(score); }
/// <summary> /// Creates the grade of the score /// </summary> private void CreateGrade() => Grade = new Sprite() { Parent = this, Alignment = Alignment.MidRight, X = -50, Size = new ScalableVector2(100, 100), Image = Screen.ScoreProcessor.Failed ? SkinManager.Skin.Grades[API.Enums.Grade.F] : SkinManager.Skin.Grades[GradeHelper.GetGradeFromAccuracy(Screen.ScoreProcessor.Accuracy)] };
/// <summary> /// Changes discord rich presence to show results. /// </summary> private void ChangeDiscordPresence() { DiscordHelper.Presence.EndTimestamp = 0; // Don't change if we're loading in from a replay file. if (ResultsType == ResultScreenType.Replay || Gameplay.InReplayMode) { DiscordHelper.Presence.Details = "Idle"; DiscordHelper.Presence.State = "In the Menus"; DiscordRpc.UpdatePresence(ref DiscordHelper.Presence); return; } var state = Gameplay.Failed ? "Fail" : "Pass"; var score = $"{ScoreProcessor.Score / 1000}k"; var acc = $"{StringHelper.AccuracyToString(ScoreProcessor.Accuracy)}"; var grade = Gameplay.Failed ? "F" : GradeHelper.GetGradeFromAccuracy(ScoreProcessor.Accuracy).ToString(); var combo = $"{ScoreProcessor.MaxCombo}x"; if (OnlineManager.CurrentGame == null) { DiscordHelper.Presence.State = $"{state}: {grade} {score} {acc} {combo}"; } else { if (OnlineManager.CurrentGame.Ruleset == MultiplayerGameRuleset.Team) { var redTeamAverage = GetTeamAverage(MultiplayerTeam.Red); var blueTeamAverage = GetTeamAverage(MultiplayerTeam.Blue); DiscordHelper.Presence.State = $"Red: {redTeamAverage:0.00} vs. Blue: {blueTeamAverage:0.00}"; } else { DiscordHelper.Presence.State = $"{StringHelper.AddOrdinal(MultiplayerScores.First().Rank)} " + $"Place: {MultiplayerScores.First().RatingProcessor.CalculateRating(ScoreProcessor):0.00} {acc} {grade}"; } } DiscordRpc.UpdatePresence(ref DiscordHelper.Presence); }
/// <summary> /// Changes discord rich presence to show results. /// </summary> private void ChangeDiscordPresence() { DiscordHelper.Presence.EndTimestamp = 0; // Don't change if we're loading in from a replay file. if (ResultsType == ResultScreenType.Replay || Gameplay.InReplayMode) { DiscordHelper.Presence.Details = "Idle"; DiscordHelper.Presence.State = "In the Menus"; DiscordRpc.UpdatePresence(ref DiscordHelper.Presence); return; } var state = Gameplay.Failed ? "Fail" : "Pass"; var score = $"{ScoreProcessor.Score / 1000}k"; var acc = $"{StringHelper.AccuracyToString(ScoreProcessor.Accuracy)}"; var grade = Gameplay.Failed ? "F" : GradeHelper.GetGradeFromAccuracy(ScoreProcessor.Accuracy).ToString(); var combo = $"{ScoreProcessor.MaxCombo}x"; DiscordHelper.Presence.State = $"{state}: {grade} {score} {acc} {combo}"; DiscordRpc.UpdatePresence(ref DiscordHelper.Presence); }
/// <summary> /// Creates the grade of the score /// </summary> private void CreateGrade() { Texture2D image; switch (Screen.ResultsType) { case ResultScreenType.Replay: case ResultScreenType.Gameplay: // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression if (Screen.ScoreProcessor.Failed) { image = SkinManager.Skin.Grades[API.Enums.Grade.F]; } else { image = SkinManager.Skin.Grades[GradeHelper.GetGradeFromAccuracy(Screen.ScoreProcessor.Accuracy)]; } break; case ResultScreenType.Score: image = SkinManager.Skin.Grades[Screen.Score.Grade]; break; default: throw new ArgumentOutOfRangeException(); } Grade = new Sprite() { Parent = this, Alignment = Alignment.MidRight, X = -50, Size = new ScalableVector2(66, 66), Image = image }; }
/// <summary> /// Adds data to the row /// <header name, value> /// </summary> /// <param name="data"></param> private void CreateData(Dictionary <string, string> data) { foreach (var pair in data) { var header = Header.Headers[pair.Key]; Sprite val; if (pair.Key == "Grade") { val = new Sprite() { Parent = this, Alignment = Alignment.MidRight, Size = new ScalableVector2(30, 30), Image = Item.Processor.Failed ? SkinManager.Skin.Grades[Grade.F] : SkinManager.Skin.Grades[GradeHelper.GetGradeFromAccuracy(Item.Processor.Accuracy)], UsePreviousSpriteBatchOptions = true }; } else { val = new SpriteTextBitmap(FontsBitmap.GothamRegular, pair.Value) { Parent = this, Alignment = Alignment.MidRight, FontSize = 16, UsePreviousSpriteBatchOptions = true }; } if (Item.Type == ScoreboardUserType.Self && val is SpriteTextBitmap t) { t.Tint = Colors.SecondaryAccent; } val.X = header.X - header.Width / 2f; val.X += val.Width / 2f; } }