Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upstream merge 7/15/2024 #47

Merged
merged 20 commits into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
69 changes: 69 additions & 0 deletions Content.Client/Announcements/Systems/AnnouncerSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using Content.Client.Audio;
using Content.Shared.Announcements.Events;
using Content.Shared.Announcements.Systems;
using Content.Shared.CCVar;
using Robust.Client.Audio;
using Robust.Client.Player;
using Robust.Client.ResourceManagement;
using Robust.Shared.Audio.Sources;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Configuration;

namespace Content.Client.Announcements.Systems;

public sealed class AnnouncerSystem : SharedAnnouncerSystem
{
[Dependency] private readonly IPlayerManager _player = default!;
[Dependency] private readonly IConfigurationManager _config = default!;
[Dependency] private readonly IResourceCache _cache = default!;
[Dependency] private readonly IAudioManager _audioManager = default!;

private IAudioSource? AnnouncerSource { get; set; }
private float AnnouncerVolume { get; set; }


public override void Initialize()
{
base.Initialize();

AnnouncerVolume = _config.GetCVar(CCVars.AnnouncerVolume) * 100f / ContentAudioSystem.AnnouncerMultiplier;

SubscribeNetworkEvent<AnnouncementSendEvent>(OnAnnouncementReceived);
_config.OnValueChanged(CCVars.AnnouncerVolume, OnAnnouncerVolumeChanged);
}

public override void Shutdown()
{
base.Shutdown();

_config.UnsubValueChanged(CCVars.AnnouncerVolume, OnAnnouncerVolumeChanged);
}


private void OnAnnouncerVolumeChanged(float value)
{
AnnouncerVolume = value;

if (AnnouncerSource != null)
AnnouncerSource.Gain = AnnouncerVolume;
}

private void OnAnnouncementReceived(AnnouncementSendEvent ev)
{
if (!ev.Recipients.Contains(_player.LocalSession!.UserId)
|| !_cache.TryGetResource<AudioResource>(GetAnnouncementPath(ev.AnnouncementId, ev.AnnouncerId),
out var resource))
return;

var source = _audioManager.CreateAudioSource(resource);
if (source != null)
{
source.Gain = AnnouncerVolume * SharedAudioSystem.VolumeToGain(ev.AudioParams.Volume);
source.Global = true;
}

AnnouncerSource?.Dispose();
AnnouncerSource = source;
AnnouncerSource?.StartPlaying();
}
}
3 changes: 2 additions & 1 deletion Content.Client/Audio/ContentAudioSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ public sealed partial class ContentAudioSystem : SharedContentAudioSystem
public const float AmbientMusicMultiplier = 3f;
public const float LobbyMultiplier = 3f;
public const float InterfaceMultiplier = 2f;

public const float AnnouncerMultiplier = 3f;

public override void Initialize()
{
base.Initialize();
Expand Down
13 changes: 13 additions & 0 deletions Content.Client/Options/UI/Tabs/AudioTab.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,19 @@
<Label Name="AmbienceSoundsLabel" MinSize="48 0" Align="Right" />
<Control MinSize="4 0"/>
</BoxContainer>
<BoxContainer Orientation="Horizontal" Margin="5 0 0 0">
<Label Text="{Loc 'ui-options-announcer-volume'}" HorizontalExpand="True" />
<Control MinSize="8 0" />
<Slider Name="AnnouncerVolumeSlider"
MinValue="0"
MaxValue="100"
HorizontalExpand="True"
MinSize="80 0"
Rounded="True" />
<Control MinSize="8 0" />
<Label Name="AnnouncerVolumeLabel" MinSize="48 0" Align="Right" />
<Control MinSize="4 0"/>
</BoxContainer>
<Control MinSize="0 8" />
<CheckBox Name="LobbyMusicCheckBox" Text="{Loc 'ui-options-lobby-music'}" />
<CheckBox Name="RestartSoundsCheckBox" Text="{Loc 'ui-options-restart-sounds'}" />
Expand Down
18 changes: 16 additions & 2 deletions Content.Client/Options/UI/Tabs/AudioTab.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public AudioTab()
AmbienceSoundsSlider.OnValueChanged += OnAmbienceSoundsSliderChanged;
LobbyVolumeSlider.OnValueChanged += OnLobbyVolumeSliderChanged;
InterfaceVolumeSlider.OnValueChanged += OnInterfaceVolumeSliderChanged;
AnnouncerVolumeSlider.OnValueChanged += OnAnnouncerVolumeSliderChanged;
LobbyMusicCheckBox.OnToggled += OnLobbyMusicCheckToggled;
RestartSoundsCheckBox.OnToggled += OnRestartSoundsCheckToggled;
EventMusicCheckBox.OnToggled += OnEventMusicCheckToggled;
Expand All @@ -58,6 +59,7 @@ protected override void Dispose(bool disposing)
AmbienceVolumeSlider.OnValueChanged -= OnAmbienceVolumeSliderChanged;
LobbyVolumeSlider.OnValueChanged -= OnLobbyVolumeSliderChanged;
InterfaceVolumeSlider.OnValueChanged -= OnInterfaceVolumeSliderChanged;
AnnouncerVolumeSlider.OnValueChanged -= OnAnnouncerVolumeSliderChanged;
base.Dispose(disposing);
}

Expand Down Expand Up @@ -97,6 +99,11 @@ private void OnMidiVolumeSliderChanged(Range range)
UpdateChanges();
}

private void OnAnnouncerVolumeSliderChanged(Range range)
{
UpdateChanges();
}

private void OnLobbyMusicCheckToggled(BaseButton.ButtonEventArgs args)
{
UpdateChanges();
Expand Down Expand Up @@ -125,6 +132,7 @@ private void OnApplyButtonPressed(BaseButton.ButtonEventArgs args)
_cfg.SetCVar(CCVars.AmbientMusicVolume, AmbientMusicVolumeSlider.Value / 100f * ContentAudioSystem.AmbientMusicMultiplier);
_cfg.SetCVar(CCVars.LobbyMusicVolume, LobbyVolumeSlider.Value / 100f * ContentAudioSystem.LobbyMultiplier);
_cfg.SetCVar(CCVars.InterfaceVolume, InterfaceVolumeSlider.Value / 100f * ContentAudioSystem.InterfaceMultiplier);
_cfg.SetCVar(CCVars.AnnouncerVolume, AnnouncerVolumeSlider.Value / 100f * ContentAudioSystem.AnnouncerMultiplier);

_cfg.SetCVar(CCVars.MaxAmbientSources, (int)AmbienceSoundsSlider.Value);

Expand All @@ -149,6 +157,7 @@ private void Reset()
AmbientMusicVolumeSlider.Value = _cfg.GetCVar(CCVars.AmbientMusicVolume) * 100f / ContentAudioSystem.AmbientMusicMultiplier;
LobbyVolumeSlider.Value = _cfg.GetCVar(CCVars.LobbyMusicVolume) * 100f / ContentAudioSystem.LobbyMultiplier;
InterfaceVolumeSlider.Value = _cfg.GetCVar(CCVars.InterfaceVolume) * 100f / ContentAudioSystem.InterfaceMultiplier;
AnnouncerVolumeSlider.Value = _cfg.GetCVar(CCVars.AnnouncerVolume) * 100f / ContentAudioSystem.AnnouncerMultiplier;

AmbienceSoundsSlider.Value = _cfg.GetCVar(CCVars.MaxAmbientSources);

Expand All @@ -174,14 +183,17 @@ private void UpdateChanges()
Math.Abs(LobbyVolumeSlider.Value - _cfg.GetCVar(CCVars.LobbyMusicVolume) * 100f / ContentAudioSystem.LobbyMultiplier) < 0.01f;
var isInterfaceVolumeSame =
Math.Abs(InterfaceVolumeSlider.Value - _cfg.GetCVar(CCVars.InterfaceVolume) * 100f / ContentAudioSystem.InterfaceMultiplier) < 0.01f;
var isAnnouncerVolumeSame =
Math.Abs(AnnouncerVolumeSlider.Value - _cfg.GetCVar(CCVars.AnnouncerVolume) * 100f / ContentAudioSystem.AnnouncerMultiplier) < 0.01f;

var isAmbientSoundsSame = (int)AmbienceSoundsSlider.Value == _cfg.GetCVar(CCVars.MaxAmbientSources);
var isLobbySame = LobbyMusicCheckBox.Pressed == _cfg.GetCVar(CCVars.LobbyMusicEnabled);
var isRestartSoundsSame = RestartSoundsCheckBox.Pressed == _cfg.GetCVar(CCVars.RestartSoundsEnabled);
var isEventSame = EventMusicCheckBox.Pressed == _cfg.GetCVar(CCVars.EventMusicEnabled);
var isAdminSoundsSame = AdminSoundsCheckBox.Pressed == _cfg.GetCVar(CCVars.AdminSoundsEnabled);
var isEverythingSame = isMasterVolumeSame && isMidiVolumeSame && isAmbientVolumeSame && isAmbientMusicVolumeSame && isAmbientSoundsSame && isLobbySame && isRestartSoundsSame && isEventSame
&& isAdminSoundsSame && isLobbyVolumeSame && isInterfaceVolumeSame;
var isEverythingSame = isMasterVolumeSame && isMidiVolumeSame && isAmbientVolumeSame
&& isAmbientMusicVolumeSame && isAmbientSoundsSame && isLobbySame && isRestartSoundsSame && isEventSame
&& isAdminSoundsSame && isLobbyVolumeSame && isInterfaceVolumeSame && isAnnouncerVolumeSame;
ApplyButton.Disabled = isEverythingSame;
ResetButton.Disabled = isEverythingSame;
MasterVolumeLabel.Text =
Expand All @@ -196,6 +208,8 @@ private void UpdateChanges()
Loc.GetString("ui-options-volume-percent", ("volume", LobbyVolumeSlider.Value / 100));
InterfaceVolumeLabel.Text =
Loc.GetString("ui-options-volume-percent", ("volume", InterfaceVolumeSlider.Value / 100));
AnnouncerVolumeLabel.Text =
Loc.GetString("ui-options-volume-percent", ("volume", AnnouncerVolumeSlider.Value / 100));
AmbienceSoundsLabel.Text = ((int)AmbienceSoundsSlider.Value).ToString();
}
}
Expand Down
41 changes: 41 additions & 0 deletions Content.IntegrationTests/Tests/Announcers/AnnouncerFallbackTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System.Collections.Generic;
using System.Linq;
using Content.Shared.Announcements.Prototypes;
using Robust.Shared.Prototypes;

namespace Content.IntegrationTests.Tests.Announcers;

[TestFixture]
[TestOf(typeof(AnnouncerPrototype))]
public sealed class AnnouncerPrototypeTests
{
[Test]
public async Task TestAnnouncerFallbacks()
{
// Checks if every announcer has a fallback announcement

await using var pair = await PoolManager.GetServerClient();
var server = pair.Server;

var prototype = server.ResolveDependency<IPrototypeManager>();

await server.WaitAssertion(() =>
{
var success = true;
var why = new List<string>();

foreach (var announcer in prototype.EnumeratePrototypes<AnnouncerPrototype>())
{
if (announcer.Announcements.All(a => a.ID.ToLower() != "fallback"))
{
success = false;
why.Add(announcer.ID);
}
}

Assert.That(success, Is.True, $"The following announcers do not have a fallback announcement:\n {string.Join("\n ", why)}");
});

await pair.CleanReturnAsync();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using System.Collections.Generic;
using Content.Server.Announcements.Systems;
using Content.Server.StationEvents;
using Content.Shared.Announcements.Prototypes;
using Robust.Shared.GameObjects;
using Robust.Shared.Localization;

namespace Content.IntegrationTests.Tests.Announcers;

[TestFixture]
[TestOf(typeof(AnnouncerPrototype))]
public sealed class AnnouncerLocalizationTest
{
[Test]
public async Task TestEventLocalization()
{
// Checks if every station event wanting the announcerSystem to send messages has a localization string
// If an event doesn't have startAnnouncement or endAnnouncement set to true
// it will be expected for that system to handle the announcements if it wants them

await using var pair = await PoolManager.GetServerClient();
var server = pair.Server;

var locale = server.ResolveDependency<ILocalizationManager>();
var entSysMan = server.ResolveDependency<IEntitySystemManager>();
var announcer = entSysMan.GetEntitySystem<AnnouncerSystem>();
var events = entSysMan.GetEntitySystem<EventManagerSystem>();

await server.WaitAssertion(() =>
{
var succeeded = true;
var why = new List<string>();

foreach (var ev in events.AllEvents())
{
if (ev.Value.StartAnnouncement)
{
var announcementId = announcer.GetAnnouncementId(ev.Key.ID);
var eventLocaleString = announcer.GetEventLocaleString(announcementId);

if (locale.GetString(eventLocaleString) == eventLocaleString)
{
succeeded = false;
why.Add($"\"{announcementId}\": \"{eventLocaleString}\"");
}
}

if (ev.Value.EndAnnouncement)
{
var announcementId = announcer.GetAnnouncementId(ev.Key.ID, true);
var eventLocaleString = announcer.GetEventLocaleString(announcementId);

if (locale.GetString(eventLocaleString) == eventLocaleString)
{
succeeded = false;
why.Add($"\"{announcementId}\": \"{eventLocaleString}\"");
}
}
}

Assert.That(succeeded, Is.True, $"The following announcements do not have a localization string:\n {string.Join("\n ", why)}");
});

await pair.CleanReturnAsync();
}
}
8 changes: 7 additions & 1 deletion Content.Server/Administration/UI/AdminAnnounceEui.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,23 @@
using Content.Server.EUI;
using Content.Shared.Administration;
using Content.Shared.Eui;
using Content.Server.Announcements.Systems;
using Robust.Shared.Player;

namespace Content.Server.Administration.UI
{
public sealed class AdminAnnounceEui : BaseEui
{
[Dependency] private readonly IAdminManager _adminManager = default!;
[Dependency] private readonly IChatManager _chatManager = default!;
private readonly AnnouncerSystem _announcer;
private readonly ChatSystem _chatSystem;

public AdminAnnounceEui()
{
IoCManager.InjectDependencies(this);

_announcer = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<AnnouncerSystem>();
_chatSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<ChatSystem>();
}

Expand Down Expand Up @@ -50,7 +55,8 @@ public override void HandleMessage(EuiMessageBase msg)
break;
// TODO: Per-station announcement support
case AdminAnnounceType.Station:
_chatSystem.DispatchGlobalAnnouncement(doAnnounce.Announcement, doAnnounce.Announcer, colorOverride: Color.Gold);
_announcer.SendAnnouncement(_announcer.GetAnnouncementId("Announce"), Filter.Broadcast(),
doAnnounce.Announcement, doAnnounce.Announcer, Color.Gold);
break;
}

Expand Down
Loading
Loading