Skip to content

Commit

Permalink
port Parkstation random announcers
Browse files Browse the repository at this point in the history
  • Loading branch information
DEATHB4DEFEAT committed May 19, 2024
1 parent c62f777 commit bed753a
Show file tree
Hide file tree
Showing 190 changed files with 1,980 additions and 211 deletions.
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();
}
}
6 changes: 5 additions & 1 deletion Content.Server/Administration/UI/AdminAnnounceEui.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
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!;
[Dependency] private readonly AnnouncerSystem _announcer = default!;
private readonly ChatSystem _chatSystem;

public AdminAnnounceEui()
Expand Down Expand Up @@ -50,7 +53,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
22 changes: 5 additions & 17 deletions Content.Server/AlertLevel/AlertLevelSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Robust.Shared.Audio.Systems;
using Robust.Shared.Configuration;
using Robust.Shared.Prototypes;
using Content.Server.Announcements.Systems;

namespace Content.Server.AlertLevel;

Expand All @@ -16,6 +17,7 @@ public sealed class AlertLevelSystem : EntitySystem
[Dependency] private readonly ChatSystem _chatSystem = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly StationSystem _stationSystem = default!;
[Dependency] private readonly AnnouncerSystem _announcer = default!;

// Until stations are a prototype, this is how it's going to have to be.
public const string DefaultAlertLevelSet = "stationAlerts";
Expand Down Expand Up @@ -162,25 +164,11 @@ public void SetLevel(EntityUid station, string level, bool playSound, bool annou
// The full announcement to be spat out into chat.
var announcementFull = Loc.GetString("alert-level-announcement", ("name", name), ("announcement", announcement));

var playDefault = false;
var alert = _announcer.GetAnnouncementId($"Alert{level}");
if (playSound)
{
if (detail.Sound != null)
{
var filter = _stationSystem.GetInOwningStation(station);
_audio.PlayGlobal(detail.Sound, filter, true, detail.Sound.Params);
}
else
{
playDefault = true;
}
}

_announcer.SendAnnouncementAudio(alert, _stationSystem.GetInOwningStation(station));
if (announce)
{
_chatSystem.DispatchStationAnnouncement(station, announcementFull, playDefaultSound: playDefault,
colorOverride: detail.Color, sender: stationName);
}
_announcer.SendAnnouncementMessage(alert, announcementFull, colorOverride: detail.Color);

RaiseLocalEvent(new AlertLevelChangedEvent(station, level));
}
Expand Down
Loading

0 comments on commit bed753a

Please sign in to comment.