From d70c30763b06d6f191e59ff560fbdc90a32ca892 Mon Sep 17 00:00:00 2001 From: Gustas <37534529+PunkPun@users.noreply.github.com> Date: Sun, 30 Mar 2025 13:53:19 +0300 Subject: [PATCH] Add a backup for unloaded bots --- OpenRA.Game/Map/MapPreview.cs | 21 +++++++++++++--- .../Widgets/Logic/Lobby/LobbyUtils.cs | 25 +++++++++++++++++-- .../Widgets/Logic/ServerListLogic.cs | 24 +++++++++++++----- mods/common/fluent/common.ftl | 3 +++ 4 files changed, 62 insertions(+), 11 deletions(-) diff --git a/OpenRA.Game/Map/MapPreview.cs b/OpenRA.Game/Map/MapPreview.cs index 26882d2ef8..2e7c59a1d6 100644 --- a/OpenRA.Game/Map/MapPreview.cs +++ b/OpenRA.Game/Map/MapPreview.cs @@ -249,11 +249,26 @@ namespace OpenRA /// public string GetMessage(string key, object[] args = null) { - // PERF: instead of loading mod level strings per each MapPreview, reuse the already loaded one in FluentProvider. - if (FluentProvider.TryGetModMessage(key, out var message, args)) + if (TryGetMessage(key, out var message, args)) return message; - return innerData.FluentBundle?.GetMessage(key, args) ?? key; + return key; + } + + /// + /// Functionality mirrors , except instead of using + /// loaded 's fluent bundle as backup, we use this 's. + /// + public bool TryGetMessage(string key, out string message, object[] args = null) + { + // PERF: instead of loading mod level strings per each MapPreview, reuse the already loaded one in FluentProvider. + if (FluentProvider.TryGetModMessage(key, out message, args)) + return true; + + if (innerData.FluentBundle == null) + return false; + + return innerData.FluentBundle.TryGetMessage(key, out message, args); } Sprite minimap; diff --git a/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyUtils.cs b/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyUtils.cs index a1213d08d2..9d894b1785 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyUtils.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyUtils.cs @@ -33,6 +33,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic [FluentReference] const string Bots = "options-lobby-slot.bots"; + [FluentReference] + const string BotPlayer = "label-bot-player"; + [FluentReference] const string BotsDisabled = "options-lobby-slot.bots-disabled"; @@ -432,7 +435,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic var font = Game.Renderer.Fonts[label.Font]; var clientName = new CachedTransform(s => - WidgetUtils.TruncateText(c.IsBot ? map.GetMessage(c.Name) : c.Name, label.Bounds.Width, font)); + { + var name = c.Name; + if (c.IsBot && !map.TryGetMessage(c.Name, out name)) + name = FluentProvider.GetMessage(BotPlayer); + + return WidgetUtils.TruncateText(name, label.Bounds.Width, font); + }); label.GetText = () => clientName.Update(map.Status); @@ -453,7 +462,19 @@ namespace OpenRA.Mods.Common.Widgets.Logic var closed = FluentProvider.GetMessage(Closed); var open = FluentProvider.GetMessage(Open); - var clientName = new CachedTransform(s => c.IsBot ? map.GetMessage(c.Name) : c.Name); + var clientName = new CachedTransform(s => + { + if (c.IsBot) + { + if (map.TryGetMessage(c.Name, out var message)) + return message; + else + return FluentProvider.GetMessage(BotPlayer); + } + + return c.Name; + }); + slot.GetText = () => truncated.Update(c != null ? clientName.Update(map.Status) : s.Closed ? closed : open); diff --git a/OpenRA.Mods.Common/Widgets/Logic/ServerListLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/ServerListLogic.cs index ad5f5a355c..24e3ba6b55 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/ServerListLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/ServerListLogic.cs @@ -14,6 +14,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using BeaconLib; +using OpenRA.Graphics; using OpenRA.Network; using OpenRA.Primitives; using OpenRA.Server; @@ -49,6 +50,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic [FluentReference("bots")] const string BotsLabel = "label-bots-count"; + [FluentReference] + const string BotPlayer = "label-bot-player"; + [FluentReference("spectators")] const string SpectatorsLabel = "label-spectators-count"; @@ -604,15 +608,21 @@ namespace OpenRA.Mods.Common.Widgets.Logic foreach (var option in kv.Value) { var o = option; - var playerName = o.IsBot ? currentMap.GetMessage(o.Name) : o.Name; + var playerName = new CachedTransform<(MapStatus, int, SpriteFont), string>(s => + { + var name = o.IsBot + ? currentMap.TryGetMessage(o.Name, out var msg) ? msg : FluentProvider.GetMessage(BotPlayer) + : o.Name; + + return WidgetUtils.TruncateText(name, s.Item2, s.Item3); + }); var item = ScrollItemWidget.Setup(clientTemplate, () => false, () => { }); if (!o.IsSpectator && server.Mod == modData.Manifest.Id) { var label = item.Get("LABEL"); var font = Game.Renderer.Fonts[label.Font]; - var name = WidgetUtils.TruncateText(playerName, label.Bounds.Width, font); - label.GetText = () => name; + label.GetText = () => playerName.Update((currentMap.Status, label.Bounds.Width, font)); label.GetColor = () => o.Color; var flag = item.Get("FLAG"); @@ -624,11 +634,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic { var label = item.Get("NOFLAG_LABEL"); var font = Game.Renderer.Fonts[label.Font]; - var name = WidgetUtils.TruncateText(playerName, label.Bounds.Width, font); // Force spectator color to prevent spoofing by the server var color = o.IsSpectator ? Color.White : o.Color; - label.GetText = () => name; + label.GetText = () => playerName.Update((currentMap.Status, label.Bounds.Width, font)); label.GetColor = () => color; } @@ -765,7 +774,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic var preview = modData.MapCache[game.Map]; var tooltip = new CachedTransform(s => { - var displayClients = game.Clients.Select(c => c.IsBot ? preview.GetMessage(c.Name) : c.Name); + var displayClients = game.Clients.Select(c => c.IsBot + ? preview.TryGetMessage(c.Name, out var msg) ? msg : FluentProvider.GetMessage(BotPlayer) + : c.Name); + if (game.Clients.Length > 10) displayClients = displayClients .Take(9) diff --git a/mods/common/fluent/common.ftl b/mods/common/fluent/common.ftl index 5ffd699e6a..6f9d6616ba 100644 --- a/mods/common/fluent/common.ftl +++ b/mods/common/fluent/common.ftl @@ -205,6 +205,9 @@ label-chat-availability = *[other] Chat available in { $seconds } seconds... } +## LobbyLogic, ServerListLogic +label-bot-player = AI Player + ## IngameMenuLogic menu-ingame = .leave = Leave