Main menu art credit system (#41328)

* Main menu art credit system

* change to center align in one box

* left align

* Update Resources/Prototypes/lobbyscreens.yml

Co-authored-by: Hannah Giovanna Dawson <karakkaraz@gmail.com>

* add margin

* Update Resources/Prototypes/lobbyscreens.yml

Co-authored-by: Hannah Giovanna Dawson <karakkaraz@gmail.com>

* fix formatting

* change to locale

* FTL file

* locid

* handle null list properly

* remove unneeded using

* push

* One more push

---------

Co-authored-by: Hannah Giovanna Dawson <karakkaraz@gmail.com>
Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com>
This commit is contained in:
Matthew Herber
2025-11-23 08:00:58 -05:00
committed by GitHub
parent cc27b6f027
commit 11a6f57d69
11 changed files with 142 additions and 41 deletions

View File

@@ -112,7 +112,6 @@ namespace Content.Client.Entry
_prototypeManager.RegisterIgnore("htnPrimitive"); _prototypeManager.RegisterIgnore("htnPrimitive");
_prototypeManager.RegisterIgnore("gameMap"); _prototypeManager.RegisterIgnore("gameMap");
_prototypeManager.RegisterIgnore("gameMapPool"); _prototypeManager.RegisterIgnore("gameMapPool");
_prototypeManager.RegisterIgnore("lobbyBackground");
_prototypeManager.RegisterIgnore("gamePreset"); _prototypeManager.RegisterIgnore("gamePreset");
_prototypeManager.RegisterIgnore("noiseChannel"); _prototypeManager.RegisterIgnore("noiseChannel");
_prototypeManager.RegisterIgnore("playerConnectionWhitelist"); _prototypeManager.RegisterIgnore("playerConnectionWhitelist");

View File

@@ -11,6 +11,7 @@ using Robust.Client.State;
using Robust.Client.UserInterface; using Robust.Client.UserInterface;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Content.Shared.GameTicking.Prototypes;
namespace Content.Client.GameTicking.Managers namespace Content.Client.GameTicking.Managers
{ {
@@ -28,7 +29,7 @@ namespace Content.Client.GameTicking.Managers
[ViewVariables] public bool AreWeReady { get; private set; } [ViewVariables] public bool AreWeReady { get; private set; }
[ViewVariables] public bool IsGameStarted { get; private set; } [ViewVariables] public bool IsGameStarted { get; private set; }
[ViewVariables] public ResolvedSoundSpecifier? RestartSound { get; private set; } [ViewVariables] public ResolvedSoundSpecifier? RestartSound { get; private set; }
[ViewVariables] public string? LobbyBackground { get; private set; } [ViewVariables] public ProtoId<LobbyBackgroundPrototype>? LobbyBackground { get; private set; }
[ViewVariables] public bool DisallowedLateJoin { get; private set; } [ViewVariables] public bool DisallowedLateJoin { get; private set; }
[ViewVariables] public string? ServerInfoBlob { get; private set; } [ViewVariables] public string? ServerInfoBlob { get; private set; }
[ViewVariables] public TimeSpan StartTime { get; private set; } [ViewVariables] public TimeSpan StartTime { get; private set; }

View File

@@ -13,6 +13,7 @@ using Robust.Client.ResourceManagement;
using Robust.Client.UserInterface; using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.Controls;
using Robust.Shared.Configuration; using Robust.Shared.Configuration;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing; using Robust.Shared.Timing;
namespace Content.Client.Lobby namespace Content.Client.Lobby
@@ -28,6 +29,7 @@ namespace Content.Client.Lobby
[Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly IVoteManager _voteManager = default!; [Dependency] private readonly IVoteManager _voteManager = default!;
[Dependency] private readonly ClientsidePlaytimeTrackingManager _playtimeTracking = default!; [Dependency] private readonly ClientsidePlaytimeTrackingManager _playtimeTracking = default!;
[Dependency] private readonly IPrototypeManager _protoMan = default!;
private ClientGameTicker _gameTicker = default!; private ClientGameTicker _gameTicker = default!;
private ContentAudioSystem _contentAudioSystem = default!; private ContentAudioSystem _contentAudioSystem = default!;
@@ -250,15 +252,22 @@ namespace Content.Client.Lobby
private void UpdateLobbyBackground() private void UpdateLobbyBackground()
{ {
if (_gameTicker.LobbyBackground != null) if (_protoMan.TryIndex(_gameTicker.LobbyBackground, out var proto))
{ {
Lobby!.Background.Texture = _resourceCache.GetResource<TextureResource>(_gameTicker.LobbyBackground ); Lobby!.Background.Texture = _resourceCache.GetResource<TextureResource>(proto.Background);
var markup = Loc.GetString("lobby-state-background-text",
("backgroundTitle", Loc.GetString(proto.Title)),
("backgroundArtist", Loc.GetString(proto.Artist)));
Lobby!.LobbyBackground.SetMarkup(markup);
} }
else else
{ {
Lobby!.Background.Texture = null; Lobby!.Background.Texture = null;
}
Lobby!.LobbyBackground.SetMarkup(Loc.GetString("lobby-state-background-no-background-text"));
}
} }
private void SetReady(bool newReady) private void SetReady(bool newReady)

View File

@@ -51,10 +51,13 @@
<!-- Vertical Padding--> <!-- Vertical Padding-->
<Control VerticalExpand="True" /> <Control VerticalExpand="True" />
<!-- Left Bot Panel --> <!-- Left Bot Panel -->
<BoxContainer Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Bottom"> <BoxContainer Orientation="Vertical" HorizontalAlignment="Left" VerticalAlignment="Bottom">
<info:DevInfoBanner Name="DevInfoBanner" VerticalExpand="false" Margin="3 3 3 3" /> <info:DevInfoBanner Name="DevInfoBanner" VerticalExpand="false" Margin="3 3 3 3" />
<PanelContainer StyleClasses="BackgroundPanel"> <PanelContainer StyleClasses="BackgroundPanel" Margin="3 3 3 3">
<RichTextLabel Name="LobbySong" Access="Public" HorizontalAlignment="Center" /> <BoxContainer Orientation="Vertical" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="3 3 3 3">
<RichTextLabel Name="LobbySong" Access="Public" HorizontalAlignment="Left" />
<RichTextLabel Name="LobbyBackground" Access="Public" HorizontalAlignment="Left" />
</BoxContainer>
</PanelContainer> </PanelContainer>
</BoxContainer> </BoxContainer>
</Control> </Control>

View File

@@ -1,4 +1,5 @@
using Content.Server.GameTicking.Prototypes; using Content.Shared.GameTicking.Prototypes;
using Robust.Shared.Prototypes;
using Robust.Shared.Random; using Robust.Shared.Random;
using Robust.Shared.Utility; using Robust.Shared.Utility;
using System.Linq; using System.Linq;
@@ -8,24 +9,37 @@ namespace Content.Server.GameTicking;
public sealed partial class GameTicker public sealed partial class GameTicker
{ {
[ViewVariables] [ViewVariables]
public string? LobbyBackground { get; private set; } public ProtoId<LobbyBackgroundPrototype>? LobbyBackground { get; private set; }
[ViewVariables] [ViewVariables]
private List<ResPath>? _lobbyBackgrounds; private List<ProtoId<LobbyBackgroundPrototype>>? _lobbyBackgrounds;
private static readonly string[] WhitelistedBackgroundExtensions = new string[] {"png", "jpg", "jpeg", "webp"}; private static readonly string[] WhitelistedBackgroundExtensions = new string[] {"png", "jpg", "jpeg", "webp"};
private void InitializeLobbyBackground() private void InitializeLobbyBackground()
{ {
_lobbyBackgrounds = _prototypeManager.EnumeratePrototypes<LobbyBackgroundPrototype>() var allprotos = _prototypeManager.EnumeratePrototypes<LobbyBackgroundPrototype>().ToList();
.Select(x => x.Background) _lobbyBackgrounds ??= new List<ProtoId<LobbyBackgroundPrototype>>();
.Where(x => WhitelistedBackgroundExtensions.Contains(x.Extension))
.ToList(); //create protoids from them
foreach (var proto in allprotos)
{
var ext = proto.Background.Extension;
if (!WhitelistedBackgroundExtensions.Contains(ext))
continue;
//create a protoid and add it to the list
_lobbyBackgrounds.Add(new ProtoId<LobbyBackgroundPrototype>(proto.ID));
}
RandomizeLobbyBackground(); RandomizeLobbyBackground();
} }
private void RandomizeLobbyBackground() { private void RandomizeLobbyBackground()
LobbyBackground = _lobbyBackgrounds!.Any() ? _robustRandom.Pick(_lobbyBackgrounds!).ToString() : null; {
if (_lobbyBackgrounds != null && _lobbyBackgrounds.Count != 0)
LobbyBackground = _robustRandom.Pick(_lobbyBackgrounds);
else
LobbyBackground = null;
} }
} }

View File

@@ -1,21 +0,0 @@
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Server.GameTicking.Prototypes;
/// <summary>
/// Prototype for a lobby background the game can choose.
/// </summary>
[Prototype]
public sealed partial class LobbyBackgroundPrototype : IPrototype
{
/// <inheritdoc/>
[IdDataField]
public string ID { get; set; } = default!;
/// <summary>
/// The sprite to use as the background. This should ideally be 1920x1080.
/// </summary>
[DataField("background", required: true)]
public ResPath Background = default!;
}

View File

@@ -0,0 +1,33 @@
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Shared.GameTicking.Prototypes;
/// <summary>
/// Prototype for a lobby background the game can choose.
/// </summary>
[Prototype]
public sealed partial class LobbyBackgroundPrototype : IPrototype
{
/// <inheritdoc/>
[IdDataField]
public string ID { get; set; } = default!;
/// <summary>
/// The sprite to use as the background. This should ideally be 1920x1080.
/// </summary>
[DataField(required: true)]
public ResPath Background = default!;
/// <summary>
/// The title of the background to be displayed in the lobby.
/// </summary>
[DataField]
public LocId Title = "lobby-state-background-unknown-title";
/// <summary>
/// The artist who made the art for the background.
/// </summary>
[DataField]
public LocId Artist = "lobby-state-background-unknown-artist";
}

View File

@@ -7,6 +7,7 @@ using Robust.Shared.Serialization.Markdown.Mapping;
using Robust.Shared.Serialization.Markdown.Value; using Robust.Shared.Serialization.Markdown.Value;
using Robust.Shared.Timing; using Robust.Shared.Timing;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Content.Shared.GameTicking.Prototypes;
namespace Content.Shared.GameTicking namespace Content.Shared.GameTicking
{ {
@@ -95,14 +96,14 @@ namespace Content.Shared.GameTicking
public sealed class TickerLobbyStatusEvent : EntityEventArgs public sealed class TickerLobbyStatusEvent : EntityEventArgs
{ {
public bool IsRoundStarted { get; } public bool IsRoundStarted { get; }
public string? LobbyBackground { get; } public ProtoId<LobbyBackgroundPrototype>? LobbyBackground { get; }
public bool YouAreReady { get; } public bool YouAreReady { get; }
// UTC. // UTC.
public TimeSpan StartTime { get; } public TimeSpan StartTime { get; }
public TimeSpan RoundStartTimeSpan { get; } public TimeSpan RoundStartTimeSpan { get; }
public bool Paused { get; } public bool Paused { get; }
public TickerLobbyStatusEvent(bool isRoundStarted, string? lobbyBackground, bool youAreReady, TimeSpan startTime, TimeSpan preloadTime, TimeSpan roundStartTimeSpan, bool paused) public TickerLobbyStatusEvent(bool isRoundStarted, ProtoId<LobbyBackgroundPrototype>? lobbyBackground, bool youAreReady, TimeSpan startTime, TimeSpan preloadTime, TimeSpan roundStartTimeSpan, bool paused)
{ {
IsRoundStarted = isRoundStarted; IsRoundStarted = isRoundStarted;
LobbyBackground = lobbyBackground; LobbyBackground = lobbyBackground;

View File

@@ -0,0 +1,35 @@
lobby-state-background-warden-title = Warden
lobby-state-background-warden-artist = Solbusaur
lobby-state-background-pharmacy-title = Pharmacy
lobby-state-background-pharmacy-artist = Solbusaur
lobby-state-background-SSXIV-title = SSXIV
lobby-state-background-SSXIV-artist = Abyssal
lobby-state-background-susstation-title = Susstation
lobby-state-background-susstation-artist = Alekshhh
lobby-state-background-skellyvstherev-title = Skelly Versus The Rev
lobby-state-background-skellyvstherev-artist = Hannah 'FairlySadPanda' Dawson
lobby-state-background-doomed-title = Doomed
lobby-state-background-doomed-artist = brainfood1183
lobby-state-background-blueprint-title = Blueprint
lobby-state-background-blueprint-artist = data_redacted
lobby-state-background-behonker-title = Behonker
lobby-state-background-behonker-artist = InCrah
lobby-state-background-terminalstation-title = Terminal Station
lobby-state-background-terminalstation-artist = aserovich
lobby-state-background-justaweekaway-title = Just a Week Away
lobby-state-background-justaweekaway-artist = plantyfern
lobby-state-background-janishootout-title = Jani Shootout
lobby-state-background-janishootout-artist = psychpsyo
lobby-state-background-reclaimernuke-title = Reclaimer Nuke
lobby-state-background-reclaimernuke-artist = GetOutMarutak

View File

@@ -21,6 +21,10 @@ lobby-state-song-text = Playing: [color=white]{$songTitle}[/color] by [color=whi
lobby-state-song-no-song-text = No lobby song playing. lobby-state-song-no-song-text = No lobby song playing.
lobby-state-song-unknown-title = [color=dimgray]Unknown title[/color] lobby-state-song-unknown-title = [color=dimgray]Unknown title[/color]
lobby-state-song-unknown-artist = [color=dimgray]Unknown artist[/color] lobby-state-song-unknown-artist = [color=dimgray]Unknown artist[/color]
lobby-state-background-text = Menu art: [color=white]{$backgroundTitle}[/color] by [color=white]{$backgroundArtist}[/color]
lobby-state-background-no-background-text = No menu art loaded.
lobby-state-background-unknown-title = [color=dimgray]Unknown title[/color]
lobby-state-background-unknown-artist = [color=dimgray]Unknown artist[/color]
lobby-state-playtime-comment-normal = lobby-state-playtime-comment-normal =
You've spent {$hours} {$hours -> You've spent {$hours} {$hours ->
[1]hour [1]hour

View File

@@ -1,48 +1,71 @@
- type: lobbyBackground - type: lobbyBackground
id: Warden id: Warden
background: /Textures/LobbyScreens/warden.webp background: /Textures/LobbyScreens/warden.webp
title: lobby-state-background-warden-title
artist: lobby-state-background-warden-artist
- type: lobbyBackground - type: lobbyBackground
id: Pharmacy id: Pharmacy
background: /Textures/LobbyScreens/pharmacy.webp background: /Textures/LobbyScreens/pharmacy.webp
title: lobby-state-background-pharmacy-title
artist: lobby-state-background-pharmacy-artist
- type: lobbyBackground - type: lobbyBackground
id: SSXIV id: SSXIV
background: /Textures/LobbyScreens/ssxiv.webp background: /Textures/LobbyScreens/ssxiv.webp
title: lobby-state-background-SSXIV-title
artist: lobby-state-background-SSXIV-artist
- type: lobbyBackground - type: lobbyBackground
id: Susstation id: Susstation
background: /Textures/LobbyScreens/susstation.webp background: /Textures/LobbyScreens/susstation.webp
title: lobby-state-background-susstation-title
artist: lobby-state-background-susstation-artist
- type: lobbyBackground - type: lobbyBackground
id: SkellyVsTheRev id: SkellyVsTheRev
background: /Textures/LobbyScreens/skellyvstherev.webp background: /Textures/LobbyScreens/skellyvstherev.webp
title: lobby-state-background-skellyvstherev-title
artist: lobby-state-background-skellyvstherev-artist
- type: lobbyBackground - type: lobbyBackground
id: Doomed id: Doomed
background: /Textures/LobbyScreens/doomed.webp background: /Textures/LobbyScreens/doomed.webp
title: lobby-state-background-doomed-title
artist: lobby-state-background-doomed-artist
- type: lobbyBackground - type: lobbyBackground
id: Blueprint id: Blueprint
background: /Textures/LobbyScreens/blueprint.webp background: /Textures/LobbyScreens/blueprint.webp
title: lobby-state-background-blueprint-title
artist: lobby-state-background-blueprint-artist
- type: lobbyBackground - type: lobbyBackground
id: Behonker id: Behonker
background: /Textures/LobbyScreens/behonker.webp background: /Textures/LobbyScreens/behonker.webp
title: lobby-state-background-behonker-title
artist: lobby-state-background-behonker-artist
- type: lobbyBackground - type: lobbyBackground
id: TerminalStation id: TerminalStation
background: /Textures/LobbyScreens/terminalstation.webp background: /Textures/LobbyScreens/terminalstation.webp
title: lobby-state-background-terminalstation-title
artist: lobby-state-background-terminalstation-artist
- type: lobbyBackground - type: lobbyBackground
id: JustAWeekAway id: JustAWeekAway
background: /Textures/LobbyScreens/justaweekaway.webp background: /Textures/LobbyScreens/justaweekaway.webp
title: lobby-state-background-justaweekaway-title
artist: lobby-state-background-justaweekaway-artist
- type: lobbyBackground - type: lobbyBackground
id: JaniShootout id: JaniShootout
background: /Textures/LobbyScreens/janishootout.webp background: /Textures/LobbyScreens/janishootout.webp
title: lobby-state-background-janishootout-title
artist: lobby-state-background-janishootout-artist
- type: lobbyBackground - type: lobbyBackground
id: ReclaimerNuke id: ReclaimerNuke
background: /Textures/LobbyScreens/reclaimer-nuke.webp background: /Textures/LobbyScreens/reclaimer-nuke.webp
title: lobby-state-background-reclaimernuke-title
artist: lobby-state-background-reclaimernuke-artist