using System.Linq; using Content.Server.Arcade.Components; using Content.Server.UserInterface; using Content.Shared.Arcade; using Robust.Shared.Utility; using Robust.Server.GameObjects; namespace Content.Server.Arcade { // ReSharper disable once ClassNeverInstantiated.Global public sealed partial class ArcadeSystem : EntitySystem { private readonly List _roundHighscores = new(); private readonly List _globalHighscores = new(); public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnAfterUIOpen); SubscribeLocalEvent(OnAfterUIOpenSV); InitializeBlockGame(); InitializeSpaceVillain(); } private void OnAfterUIOpen(EntityUid uid, BlockGameArcadeComponent component, AfterActivatableUIOpenEvent args) { var actor = Comp(args.User); if (component.UserInterface?.SessionHasOpen(actor.PlayerSession) == true) { component.RegisterPlayerSession(actor.PlayerSession); } } private void OnAfterUIOpenSV(EntityUid uid, SpaceVillainArcadeComponent component, AfterActivatableUIOpenEvent args) { component.Game ??= new SpaceVillainArcadeComponent.SpaceVillainGame(component); } public HighScorePlacement RegisterHighScore(string name, int score) { var entry = new BlockGameMessages.HighScoreEntry(name, score); return new HighScorePlacement(TryInsertIntoList(_roundHighscores, entry), TryInsertIntoList(_globalHighscores, entry)); } public List GetLocalHighscores() => GetSortedHighscores(_roundHighscores); public List GetGlobalHighscores() => GetSortedHighscores(_globalHighscores); private List GetSortedHighscores(List highScoreEntries) { var result = highScoreEntries.ShallowClone(); result.Sort((p1, p2) => p2.Score.CompareTo(p1.Score)); return result; } private int? TryInsertIntoList(List highScoreEntries, BlockGameMessages.HighScoreEntry entry) { if (highScoreEntries.Count < 5) { highScoreEntries.Add(entry); return GetPlacement(highScoreEntries, entry); } if (highScoreEntries.Min(e => e.Score) >= entry.Score) return null; var lowestHighscore = highScoreEntries.Min(); if (lowestHighscore == null) return null; highScoreEntries.Remove(lowestHighscore); highScoreEntries.Add(entry); return GetPlacement(highScoreEntries, entry); } private int? GetPlacement(List highScoreEntries, BlockGameMessages.HighScoreEntry entry) { int? placement = null; if (highScoreEntries.Contains(entry)) { highScoreEntries.Sort((p1,p2) => p2.Score.CompareTo(p1.Score)); placement = 1 + highScoreEntries.IndexOf(entry); } return placement; } public override void Update(float frameTime) { foreach (var comp in EntityManager.EntityQuery()) { comp.DoGameTick(frameTime); } } public readonly struct HighScorePlacement { public readonly int? GlobalPlacement; public readonly int? LocalPlacement; public HighScorePlacement(int? globalPlacement, int? localPlacement) { GlobalPlacement = globalPlacement; LocalPlacement = localPlacement; } } } }