Skip to content
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
587 changes: 443 additions & 144 deletions Content.Client/Audio/ContentAudioSystem.AmbientMusic.cs

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion Content.Client/Audio/ContentAudioSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public sealed partial class ContentAudioSystem : SharedContentAudioSystem
public const float TtsMultiplier = 3f; // Corvax-TTS

public const float SalvageMultiplier = 1f; // Frontier
public const float CombatMultiplier = 3f; //Mono

public override void Initialize()
{
Expand Down Expand Up @@ -84,7 +85,7 @@ public override void Update(float frameTime)
if (!_timing.IsFirstTimePredicted)
return;

UpdateAmbientMusic();
UpdateAmbientMusic(frameTime);
UpdateLobbyMusic();
UpdateFades(frameTime);
}
Expand Down
3 changes: 3 additions & 0 deletions Content.Client/Options/UI/Tabs/AudioTab.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
<ui:OptionSlider Name="SliderVolumeTts" Title="{Loc 'ui-options-tts-volume'}"/>
<ui:OptionSlider Name="SliderVolumeTtsRadio" Title="{Loc 'ui-options-tts-radio-volume'}"
Margin="0 0 0 8" />
<ui:OptionSlider Name="SliderVolumeCombatMusic" Title="{Loc 'ui-options-combat-music-volume'}" />
<ui:OptionSlider Name="SliderWindUpCombatMusic" Title="{Loc 'ui-options-combat-music-windup'}" />
<ui:OptionSlider Name="SliderWindDownCombatMusic" Title="{Loc 'ui-options-combat-music-winddown'}" />
<CheckBox Name="CombatMusicCheckBox" Text="{Loc 'ui-options-combat-music'}" />
<CheckBox Name="LobbyMusicCheckBox" Text="{Loc 'ui-options-lobby-music'}" />
<CheckBox Name="RestartSoundsCheckBox" Text="{Loc 'ui-options-restart-sounds'}" />
Expand Down
22 changes: 22 additions & 0 deletions Content.Client/Options/UI/Tabs/AudioTab.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,28 @@ public AudioTab()
SliderVolumeTtsRadio,
scale: ContentAudioSystem.TtsMultiplier);

// Mono begin
Control.AddOptionPercentSlider(
MonoCVars.CombatMusicVolume,
SliderVolumeCombatMusic,
scale: ContentAudioSystem.CombatMultiplier);

Control.AddOptionSlider(
MonoCVars.CombatMusicWindUpTime,
SliderWindUpCombatMusic,
1,
10,
(_, value) => Loc.GetString("ui-options-combat-music-sec-format", ("value", value))); // i dont think anyone is ghonna want more than 10 seconds of constant combatmode being the trigger. the actions already over

Control.AddOptionSlider(
MonoCVars.CombatMusicWindDownTime,
SliderWindDownCombatMusic,
1,
120,
(_, value) => Loc.GetString("ui-options-combat-music-sec-format", ("value", value))); // and also i think 2 minutes is enough of an upper limit since it refreshes anytime you turn it back on even for a second

Control.AddOptionCheckBox(MonoCVars.CombatMusicEnabled, CombatMusicCheckBox);
// Mono end
Control.AddOptionCheckBox(CCVars.LobbyMusicEnabled, LobbyMusicCheckBox);
Control.AddOptionCheckBox(CCVars.RestartSoundsEnabled, RestartSoundsCheckBox);
Control.AddOptionCheckBox(CCVars.EventMusicEnabled, EventMusicCheckBox);
Expand Down
9 changes: 6 additions & 3 deletions Content.Client/Salvage/SalvageExpeditionComponent.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
using Content.Shared._Crescent.SpaceBiomes;
using Content.Shared.Salvage.Expeditions;
using Robust.Shared.Prototypes;

namespace Content.Client.Salvage;

[RegisterComponent]
public sealed partial class SalvageExpeditionComponent : SharedSalvageExpeditionComponent
{
// Frontier: add audio stream
/// <summary>
/// Mono: used for ContentAudioSystem.AmbientMusic.cs & SpaceBiomeSystem.cs to communicate biome on FTL
/// </summary>
[DataField]
public EntityUid? Stream;
// End Frontier
public ProtoId<SpaceBiomePrototype> Biome = "BiomeExpedition";
}
59 changes: 0 additions & 59 deletions Content.Client/Salvage/SalvageSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,19 @@
using Content.Shared.Salvage.Expeditions;
using Robust.Client.Player;
using Robust.Shared.GameStates;
using Content.Shared._NF.CCVar; // Frontier
using Robust.Client.Audio; // Frontier
using Robust.Shared.Audio; // Frontier
using Robust.Shared.Configuration; // Frontier
using Robust.Shared.Player; // Frontier

namespace Content.Client.Salvage;

public sealed class SalvageSystem : SharedSalvageSystem
{
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly ContentAudioSystem _audio = default!;
[Dependency] private readonly AudioSystem _audioSystem = default!; // Frontier
[Dependency] private readonly IConfigurationManager _cfg = default!; // Frontier

const float SalvageExpeditionMinMusicVolume = -30f; // Frontier: expedition volume range
const float SalvageExpeditionMaxMusicVolume = 3.0f; // Frontier: expedition volume range

public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<PlayAmbientMusicEvent>(OnPlayAmbientMusic);
SubscribeLocalEvent<SalvageExpeditionComponent, ComponentHandleState>(OnExpeditionHandleState);
SubscribeLocalEvent<SalvageExpeditionComponent, ComponentRemove>(OnRemove); // Frontier
Subs.CVar(_cfg, NFCCVars.SalvageExpeditionMusicVolume, SetMusicVolume); // Frontier
}

private void OnExpeditionHandleState(EntityUid uid, SalvageExpeditionComponent component, ref ComponentHandleState args)
Expand All @@ -36,27 +24,11 @@ private void OnExpeditionHandleState(EntityUid uid, SalvageExpeditionComponent c
return;

component.Stage = state.Stage;
if (state.SelectedSong != null) // Frontier
component.SelectedSong = state.SelectedSong; // Frontier

if (component.Stage >= ExpeditionStage.MusicCountdown)
{
_audio.DisableAmbientMusic();
}

// Frontier: add music (only on music countdown, no music on forced exit)
if (component.Stage == ExpeditionStage.MusicCountdown
&& component.SelectedSong != null
&& component.Stream == null)
{
var volume = ConvertSliderValueToVolume(_cfg.GetCVar(NFCCVars.SalvageExpeditionMusicVolume));
var audioParams = AudioParams.Default.WithVolume(volume);
var audio = _audioSystem.PlayEntity(component.SelectedSong, Filter.Local(), uid, false, audioParams);
_audioSystem.SetMapAudio(audio);

component.Stream = audio?.Entity;
}
// End Frontier
}

private void OnPlayAmbientMusic(ref PlayAmbientMusicEvent ev)
Expand All @@ -75,35 +47,4 @@ private void OnPlayAmbientMusic(ref PlayAmbientMusicEvent ev)

ev.Cancelled = true;
}

// Frontier: stop stream when destroying the expedition
private void OnRemove(EntityUid uid, SalvageExpeditionComponent component, ComponentRemove args)
{
// For whatever reason, this stream is considered a server-side entity, so the AudioSystem won't tear it down.
// Don't really understand why, but I don't think it is.

//component.Stream = _audioSystem.Stop(component.Stream);
QueueDel(component.Stream);
}

private void SetMusicVolume(float volume)
{
var expedQuery = EntityQueryEnumerator<SalvageExpeditionComponent>();
while (expedQuery.MoveNext(out _, out var comp))
{
if (comp.Stream != null)
_audioSystem.SetVolume(comp.Stream, ConvertSliderValueToVolume(volume));
}
}

private float ConvertSliderValueToVolume(float value)
{
var ret = AudioSystem.GainToVolume(value);
if (!float.IsFinite(ret)) // Explicitly handle any odd cases (chiefly NaN)
ret = SalvageExpeditionMinMusicVolume;
else
ret = Math.Clamp(ret, SalvageExpeditionMinMusicVolume, SalvageExpeditionMaxMusicVolume);
return ret;
}
// End Frontier: stop stream when destroying the expedition
}
26 changes: 26 additions & 0 deletions Content.Client/_Crescent/SpaceBiomes/SpaceBiomeMessages.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Content.Shared._Crescent.SpaceBiomes;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;

namespace Content.Client._Crescent.SpaceBiomes;

/// <summary>
/// used by space biome system to signal when the player has changed biomes, to check for biome music
/// </summary>
/// <param name="Id"></param>
[ByRefEvent]
public readonly record struct SpaceBiomeSwapMessage(ProtoId<SpaceBiomePrototype> Id);

/// <summary>
/// used by space biome system to signal when the player's parent is changed, to check for grid music
/// </summary>
/// <param name="Grid"></param>
[ByRefEvent]
public readonly record struct PlayerParentChangedMessage(EntityUid? Grid); //null = space

/// <summary>
/// used by space biome system to add biome components to dynamically-created maps, like FTLmap and expeditions
/// </summary>
/// <param name="Id"></param>
[ByRefEvent]
public record struct SpaceBiomeMapChangeMessage(ProtoId<SpaceBiomePrototype>? Biome);
115 changes: 115 additions & 0 deletions Content.Client/_Crescent/SpaceBiomes/SpaceBiomeSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
using Content.Shared._Crescent.SpaceBiomes;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using Robust.Client.Player;
using Robust.Client.GameObjects;
using Content.Shared.Shuttles.Components;
using Content.Client.Salvage;

namespace Content.Client._Crescent.SpaceBiomes;

public sealed class SpaceBiomeSystem : EntitySystem
{
[Dependency] private readonly IPlayerManager _playerMan = default!;
[Dependency] private readonly IPrototypeManager _protMan = default!;
[Dependency] private readonly TransformSystem _formSys = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly IEntityManager _entMan = default!;

private float _updTimer;
private const float UpdateInterval = 0.5f; // in seconds - how often the checks for this system run

private SpaceBiomeSourceComponent? _cachedSource;
private EntityUid? _cachedGrid;
private EntityUid? _cachedMap;


public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<FTLMapComponent, SpaceBiomeMapChangeMessage>(OnFTLMapChanged);
SubscribeLocalEvent<SalvageExpeditionComponent, SpaceBiomeMapChangeMessage>(OnSalvageMapChanged);
}

public override void Update(float frameTime)
{
base.Update(frameTime);

if (!_timing.IsFirstTimePredicted) //otherwise this will tick like 5x faster on client. thanks prediction
return;

//update timers
_updTimer += frameTime;
if (_updTimer < UpdateInterval)
return;
_updTimer -= UpdateInterval;

// 0. grab the local player ent
if (_playerMan.LocalEntity == null) //this should never be null i thinky
return;

var localPlayerUid = _playerMan.LocalEntity.Value;
var xform = Transform(localPlayerUid);
var ourCoord = xform.Coordinates;

// 1. grab the local grid, if any. if not, send msg signalling we entered space
var newGrid = xform.GridUid;

if (newGrid != _cachedGrid) //if true, we have changed grids since last update
{
_cachedGrid = newGrid;
var message = new PlayerParentChangedMessage(newGrid); //if this is null it notifies that we're in space
RaiseLocalEvent(localPlayerUid, ref message, true);

}
// 2. grab the biome & check if its different than the cached biome from last update
SpaceBiomeSourceComponent? newSource = null;
var query = EntityQueryEnumerator<SpaceBiomeSourceComponent>();
while (query.MoveNext(out var sourceUid, out var comp))
{
var otherCoord = Transform(sourceUid).Coordinates;
if (!ourCoord.TryDistance(EntityManager, otherCoord, out var distance) || distance > (comp.SwapDistance ?? float.MaxValue)) //we're too far from this source, move on
continue;

if (newSource == null || //this whole shebang picks the highest priority source from the EQE
comp.Priority > newSource.Priority ||
comp.Priority == newSource.Priority && comp == _cachedSource)
{
newSource = comp;
}
}
// 3. check the mapid and check if its different than the cached mapid from the last update
EntityUid? newMap = _formSys.GetMap(localPlayerUid);
// 4. this is the actual checking bit
// if the map changed then it cant be the same source from last update, so we do _cachedSource = newSource anyway.
if (_cachedMap != newMap || _cachedSource != newSource)
{
var mapSwapMsg = new SpaceBiomeMapChangeMessage();
if (newMap != null) //if the new map is null then :godo: we are borked anyway
{
RaiseLocalEvent((EntityUid)newMap, ref mapSwapMsg, true);
}
_cachedMap = newMap;
_cachedSource = newSource;
SpaceBiomePrototype biome;
if (mapSwapMsg.Biome != null)
biome = _protMan.Index<SpaceBiomePrototype>(mapSwapMsg.Biome);
else
biome = _protMan.Index<SpaceBiomePrototype>(newSource?.Id ?? "BiomeDefault");
//note: this is where the parallax should swap. eventually.
var biomeSwapMsg = new SpaceBiomeSwapMessage(biome);
RaiseLocalEvent(localPlayerUid, ref biomeSwapMsg, true);

}
}

private void OnFTLMapChanged(Entity<FTLMapComponent> ent, ref SpaceBiomeMapChangeMessage args)
{
args.Biome = ent.Comp.Biome;
}

private void OnSalvageMapChanged(Entity<SalvageExpeditionComponent> ent, ref SpaceBiomeMapChangeMessage args)
{
args.Biome = ent.Comp.Biome;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using Content.Shared._Crescent.SpaceBiomes;
using Robust.Shared.Prototypes;
using Content.Client.Audio;
using Robust.Client.Graphics;
using Robust.Shared.Timing;
using Content.Shared._Crescent.Vessel;

namespace Content.Client._Crescent.SpaceBiomes;

public sealed class SpaceTextDisplaySystem : EntitySystem
{
[Dependency] private readonly IPrototypeManager _protMan = default!;
[Dependency] private readonly IOverlayManager _overMan = default!;
[Dependency] private readonly ContentAudioSystem _audioSys = default!;

private SpaceBiomeTextOverlay _overlay = default!;

public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<SpaceBiomeSwapMessage>(OnSwap);
SubscribeLocalEvent<PlayerParentChangedMessage>(OnNewVesselEntered);
_overlay = new();
_overMan.AddOverlay(_overlay);
}

private void OnSwap(ref SpaceBiomeSwapMessage ev)
{
_audioSys.DisableAmbientMusic();
SpaceBiomePrototype biome = _protMan.Index<SpaceBiomePrototype>(ev.Id);
_overlay.Reset();
_overlay.ResetDescription();
_overlay.Text = biome.Name;
_overlay.TextDescription = biome.Description;
_overlay.CharInterval = TimeSpan.FromSeconds(2f / biome.Name.Length);
if (_overlay.TextDescription == "") //if we have a biome with no description, it's default is "" and that has length 0.
_overlay.CharIntervalDescription = TimeSpan.Zero; //we need to calculate it here because otherwise...
else
_overlay.CharIntervalDescription = TimeSpan.FromSeconds(2f / biome.Description.Length); //this would throw an exception
}

private void OnNewVesselEntered(ref PlayerParentChangedMessage ev)
{
if (ev.Grid == null) //player walked into space so we dont care
return;

var name = MetaData((EntityUid)ev.Grid).EntityName; //this should never be null. i hope
var description = ""; //fallback for description is nothin'
if (TryComp<VesselInfoComponent>((EntityUid)ev.Grid, out var vesselinfo))
description = vesselinfo.Description;


_overlay.Reset(); //these should be reset as well to match OnSwap
_overlay.ResetDescription();

if (_overlay.Text != null) //i dont know why this is here but im not touching it
return;

_overlay.Text = name;
_overlay.TextDescription = description; // fallback is "" if no description is found.
_overlay.CharInterval = TimeSpan.FromSeconds(2f / _overlay.Text.Length);

if (_overlay.TextDescription == "")
_overlay.CharIntervalDescription = TimeSpan.Zero; //if this is not done it tries dividing by 0 in the "else" clause
else
_overlay.CharIntervalDescription = TimeSpan.FromSeconds(2f / _overlay.TextDescription.Length);
}
}
Loading
Loading