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