diff --git a/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs index 203b27ca15..da9757196a 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyLogic.cs @@ -62,6 +62,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic bool disableTeamChat; bool teamChat; bool updateDiscordStatus = true; + Dictionary spawnOccupants = new Dictionary(); readonly string chatLineSound = ChromeMetrics.Get("ChatLineSound"); @@ -118,6 +119,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic Game.LobbyInfoChanged += UpdateCurrentMap; Game.LobbyInfoChanged += UpdatePlayerList; Game.LobbyInfoChanged += UpdateDiscordStatus; + Game.LobbyInfoChanged += UpdateSpawnOccupants; Game.BeforeGameStart += OnGameStart; Game.ConnectionStateChanged += ConnectionStateChanged; @@ -133,10 +135,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic "onMouseDown", (Action)((preview, mapPreview, mi) => LobbyUtils.SelectSpawnPoint(orderManager, preview, mapPreview, mi)) }, - { - "getSpawnOccupants", (Func>)(mapPreview => - LobbyUtils.GetSpawnOccupants(orderManager.LobbyInfo, mapPreview)) - }, + { "getSpawnOccupants", (Func>)(() => spawnOccupants) }, { "showUnoccupiedSpawnpoints", true }, }); @@ -464,6 +463,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic Game.LobbyInfoChanged -= UpdateCurrentMap; Game.LobbyInfoChanged -= UpdatePlayerList; Game.LobbyInfoChanged -= UpdateDiscordStatus; + Game.LobbyInfoChanged -= UpdateSpawnOccupants; Game.BeforeGameStart -= OnGameStart; Game.ConnectionStateChanged -= ConnectionStateChanged; } @@ -789,6 +789,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic } } + void UpdateSpawnOccupants() + { + spawnOccupants = orderManager.LobbyInfo.Clients + .Where(c => c.SpawnPoint != 0) + .ToDictionary(c => c.SpawnPoint, c => new SpawnOccupant(c)); + } + void OnGameStart() { Ui.CloseWindow(); diff --git a/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyUtils.cs b/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyUtils.cs index a0c817d6ed..d3b004415b 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyUtils.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyUtils.cs @@ -227,22 +227,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic color.AttachPanel(colorChooser, onExit); } - public static Dictionary GetSpawnOccupants(Session lobbyInfo, MapPreview preview) - { - var spawns = preview.SpawnPoints; - return lobbyInfo.Clients - .Where(c => (c.SpawnPoint - 1 >= 0) && (c.SpawnPoint - 1 < spawns.Length)) - .ToDictionary(c => spawns[c.SpawnPoint - 1], c => new SpawnOccupant(c)); - } - - public static Dictionary GetSpawnOccupants(IEnumerable players, MapPreview preview) - { - var spawns = preview.SpawnPoints; - return players - .Where(c => (c.SpawnPoint - 1 >= 0) && (c.SpawnPoint - 1 < spawns.Length)) - .ToDictionary(c => spawns[c.SpawnPoint - 1], c => new SpawnOccupant(c)); - } - public static void SelectSpawnPoint(OrderManager orderManager, MapPreviewWidget mapPreview, MapPreview preview, MouseInput mi) { if (mi.Button != MouseButton.Left) diff --git a/OpenRA.Mods.Common/Widgets/Logic/Lobby/MapPreviewLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Lobby/MapPreviewLogic.cs index 4c4c820067..06e0ec1b1c 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Lobby/MapPreviewLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Lobby/MapPreviewLogic.cs @@ -25,7 +25,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic [ObjectCreator.UseCtor] internal MapPreviewLogic(Widget widget, ModData modData, OrderManager orderManager, Func getMap, - Action onMouseDown, Func> getSpawnOccupants, bool showUnoccupiedSpawnpoints) + Action onMouseDown, Func> getSpawnOccupants, bool showUnoccupiedSpawnpoints) { var mapRepository = modData.Manifest.Get().MapRepository; @@ -172,12 +172,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic } void SetupWidgets(Widget parent, Func getMap, - Action onMouseDown, Func> getSpawnOccupants, bool showUnoccupiedSpawnpoints) + Action onMouseDown, Func> getSpawnOccupants, bool showUnoccupiedSpawnpoints) { var preview = parent.Get("MAP_PREVIEW"); preview.Preview = () => getMap(); preview.OnMouseDown = mi => onMouseDown(preview, getMap(), mi); - preview.SpawnOccupants = () => getSpawnOccupants(getMap()); + preview.SpawnOccupants = getSpawnOccupants; preview.ShowUnoccupiedSpawnpoints = showUnoccupiedSpawnpoints; var titleLabel = parent.GetOrNull("MAP_TITLE"); diff --git a/OpenRA.Mods.Common/Widgets/Logic/Lobby/SpawnSelectorTooltipLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Lobby/SpawnSelectorTooltipLogic.cs index a805749b73..f9f17c8e98 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Lobby/SpawnSelectorTooltipLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Lobby/SpawnSelectorTooltipLogic.cs @@ -40,10 +40,17 @@ namespace OpenRA.Mods.Common.Widgets.Logic tooltipContainer.BeforeRender = () => { showTooltip = true; - var occupant = preview.SpawnOccupants().Values.FirstOrDefault(c => c.SpawnPoint == preview.TooltipSpawnIndex); var teamWidth = 0; - if (occupant == null) + if (preview.SpawnOccupants().TryGetValue(preview.TooltipSpawnIndex, out var occupant)) + { + labelText = occupant.PlayerName; + playerFaction = occupant.Faction; + playerTeam = occupant.Team; + widget.Bounds.Height = playerTeam > 0 ? doubleHeight : singleHeight; + teamWidth = teamFont.Measure(team.GetText()).X; + } + else { if (!showUnoccupiedSpawnpoints) { @@ -56,14 +63,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic playerTeam = 0; widget.Bounds.Height = singleHeight; } - else - { - labelText = occupant.PlayerName; - playerFaction = occupant.Faction; - playerTeam = occupant.Team; - widget.Bounds.Height = playerTeam > 0 ? doubleHeight : singleHeight; - teamWidth = teamFont.Measure(team.GetText()).X; - } label.Bounds.X = playerFaction != null ? flag.Bounds.Right + labelMargin : labelMargin; label.Bounds.Width = ownerFont.Measure(labelText).X; diff --git a/OpenRA.Mods.Common/Widgets/Logic/ReplayBrowserLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/ReplayBrowserLogic.cs index 9ac0df263e..60d416ec11 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/ReplayBrowserLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/ReplayBrowserLogic.cs @@ -76,15 +76,15 @@ namespace OpenRA.Mods.Common.Widgets.Logic mapPreviewRoot.IsVisible = () => selectedReplay != null; panel.Get("REPLAY_INFO").IsVisible = () => selectedReplay != null; + var spawnOccupants = new CachedTransform>(r => + r.GameInfo.Players.ToDictionary(c => c.SpawnPoint, c => new SpawnOccupant(c))); + Ui.LoadWidget("MAP_PREVIEW", mapPreviewRoot, new WidgetArgs { { "orderManager", null }, { "getMap", (Func)(() => map) }, { "onMouseDown", (Action)((preview, mapPreview, mi) => { }) }, - { - "getSpawnOccupants", (Func>)(mapPreview => - LobbyUtils.GetSpawnOccupants(selectedReplay.GameInfo.Players, mapPreview)) - }, + { "getSpawnOccupants", (Func>)(() => spawnOccupants.Update(selectedReplay)) }, { "showUnoccupiedSpawnpoints", false }, }); diff --git a/OpenRA.Mods.Common/Widgets/Logic/ServerListLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/ServerListLogic.cs index 2ff583be37..369bbae2d0 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/ServerListLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/ServerListLogic.cs @@ -424,7 +424,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic var spawns = currentMap.SpawnPoints; var occupants = server.Clients .Where(c => (c.SpawnPoint - 1 >= 0) && (c.SpawnPoint - 1 < spawns.Length)) - .ToDictionary(c => spawns[c.SpawnPoint - 1], c => new SpawnOccupant(c, server.Mod != modData.Manifest.Id)); + .ToDictionary(c => c.SpawnPoint, c => new SpawnOccupant(c, server.Mod != modData.Manifest.Id)); mapPreview.SpawnOccupants = () => occupants; } diff --git a/OpenRA.Mods.Common/Widgets/MapPreviewWidget.cs b/OpenRA.Mods.Common/Widgets/MapPreviewWidget.cs index 9fa24764d6..b44ff03cc2 100644 --- a/OpenRA.Mods.Common/Widgets/MapPreviewWidget.cs +++ b/OpenRA.Mods.Common/Widgets/MapPreviewWidget.cs @@ -70,7 +70,7 @@ namespace OpenRA.Mods.Common.Widgets readonly int2 spawnLabelOffset; public Func Preview = () => null; - public Func> SpawnOccupants = () => new Dictionary(); + public Func> SpawnOccupants = () => new Dictionary(); public Action OnMouseDown = _ => { }; public int TooltipSpawnIndex = -1; public bool ShowUnoccupiedSpawnpoints = true; @@ -182,19 +182,21 @@ namespace OpenRA.Mods.Common.Widgets TooltipSpawnIndex = -1; if (ShowSpawnPoints) { - var colors = SpawnOccupants().ToDictionary(c => c.Key, c => c.Value.Color); - var spawnPoints = preview.SpawnPoints; + var occupants = SpawnOccupants(); var gridType = preview.GridType; - foreach (var p in spawnPoints) + for (var i = 0; i < spawnPoints.Length; i++) { - var owned = colors.ContainsKey(p); + var p = spawnPoints[i]; + + // Spawn numbers are 1 indexed with 0 meaning "random spawn". + var occupied = occupants.TryGetValue(i + 1, out var occupant); var pos = ConvertToPreview(p, gridType); - var sprite = owned ? spawnClaimed : spawnUnclaimed; + var sprite = occupied ? spawnClaimed : spawnUnclaimed; var offset = sprite.Size.XY.ToInt2() / 2; - if (owned) - WidgetUtils.FillEllipseWithColor(new Rectangle(pos.X - offset.X + 1, pos.Y - offset.Y + 1, (int)sprite.Size.X - 2, (int)sprite.Size.Y - 2), colors[p]); + if (occupied) + WidgetUtils.FillEllipseWithColor(new Rectangle(pos.X - offset.X + 1, pos.Y - offset.Y + 1, (int)sprite.Size.X - 2, (int)sprite.Size.Y - 2), occupant.Color); Game.Renderer.RgbaSpriteRenderer.DrawSprite(sprite, pos - offset); var number = Convert.ToChar('A' + spawnPoints.IndexOf(p)).ToString();