[fix] Бумбокс (#18)

* Отвал пизды

* Ебался

---------

Co-authored-by: Mona Hmiza <>
This commit is contained in:
RavMorgan
2023-05-05 12:53:34 +03:00
committed by Aviu00
parent b40f935571
commit ccbbc8820b
2 changed files with 113 additions and 72 deletions

View File

@@ -1,20 +1,16 @@
using System.Resources; using Content.Shared.GameTicking;
using Content.Shared.GameTicking; using Content.Shared.Physics;
using Content.Shared.Interaction.Events;
using Content.Shared.White; using Content.Shared.White;
using Content.Shared.White.Jukebox; using Content.Shared.White.Jukebox;
using Robust.Client.Audio; using Robust.Client.Audio;
using Robust.Client.GameObjects; using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Physics;
using Robust.Client.Player; using Robust.Client.Player;
using Robust.Client.ResourceManagement; using Robust.Client.ResourceManagement;
using Robust.Shared.Audio; using Robust.Shared.Audio.Sources;
using Robust.Shared.Audio.Components;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Configuration; using Robust.Shared.Configuration;
using Robust.Shared.ContentPack;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Systems;
using Robust.Shared.Utility; using Robust.Shared.Utility;
namespace Content.Client.White.Jukebox; namespace Content.Client.White.Jukebox;
@@ -22,13 +18,11 @@ namespace Content.Client.White.Jukebox;
public sealed class JukeboxSystem : EntitySystem public sealed class JukeboxSystem : EntitySystem
{ {
[Dependency] private readonly SharedAudioSystem _audioSystem = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!; [Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IResourceCache _resource = default!; [Dependency] private readonly IResourceCache _resource = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!; [Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly IAudioManager _clydeAudio = default!;
[Dependency] private readonly SharedPhysicsSystem _physicsSystem = default!;
private readonly Dictionary<JukeboxComponent, JukeboxAudio> _playingJukeboxes = new(); private readonly Dictionary<JukeboxComponent, JukeboxAudio> _playingJukeboxes = new();
@@ -40,7 +34,7 @@ public sealed class JukeboxSystem : EntitySystem
base.Initialize(); base.Initialize();
_cfg.OnValueChanged(WhiteCVars.MaxJukeboxSoundRange, range => _maxAudioRange = range, true); _cfg.OnValueChanged(WhiteCVars.MaxJukeboxSoundRange, range => _maxAudioRange = range, true);
_cfg.OnValueChanged(WhiteCVars.JukeboxVolume, volume => JukeboxVolumeChanged(volume), true); _cfg.OnValueChanged(WhiteCVars.JukeboxVolume, JukeboxVolumeChanged, true);
SubscribeLocalEvent<JukeboxComponent, ComponentHandleState>(OnStateChanged); SubscribeLocalEvent<JukeboxComponent, ComponentHandleState>(OnStateChanged);
SubscribeLocalEvent<JukeboxComponent, ComponentRemove>(OnComponentRemoved); SubscribeLocalEvent<JukeboxComponent, ComponentRemove>(OnComponentRemoved);
@@ -52,7 +46,6 @@ public sealed class JukeboxSystem : EntitySystem
private void JukeboxVolumeChanged(float volume) private void JukeboxVolumeChanged(float volume)
{ {
_jukeboxVolume = volume; _jukeboxVolume = volume;
CleanUp(); CleanUp();
} }
@@ -69,7 +62,7 @@ public sealed class JukeboxSystem : EntitySystem
private void OnComponentRemoved(EntityUid uid, JukeboxComponent component, ComponentRemove args) private void OnComponentRemoved(EntityUid uid, JukeboxComponent component, ComponentRemove args)
{ {
if (!_playingJukeboxes.TryGetValue(component, out var playingData)) return; if (!_playingJukeboxes.TryGetValue(component, out var playingData)) return;
_audioSystem.Stop(playingData.PlayingStream, playingData.Component); playingData.PlayingStream.StopPlaying();
_playingJukeboxes.Remove(component); _playingJukeboxes.Remove(component);
} }
@@ -80,7 +73,7 @@ public sealed class JukeboxSystem : EntitySystem
if(!_playingJukeboxes.TryGetValue(jukeboxComponent, out var jukeboxAudio)) return; if(!_playingJukeboxes.TryGetValue(jukeboxComponent, out var jukeboxAudio)) return;
_audioSystem.Stop(jukeboxAudio.PlayingStream, jukeboxAudio.Component); jukeboxAudio.PlayingStream.StopPlaying();
_playingJukeboxes.Remove(jukeboxComponent); _playingJukeboxes.Remove(jukeboxComponent);
} }
@@ -101,26 +94,20 @@ public sealed class JukeboxSystem : EntitySystem
} }
public override void Update(float frameTime) public override void FrameUpdate(float frameTime)
{ {
base.Update(frameTime); base.FrameUpdate(frameTime);
var localPlayerEntity = _playerManager.LocalPlayer!.ControlledEntity; var localPlayerEntity = _playerManager.LocalPlayer!.ControlledEntity;
if(!localPlayerEntity.HasValue) return; if (!localPlayerEntity.HasValue)
{
CleanUp();
return;
}
ProcessJukeboxes(); ProcessJukeboxes();
} }
private void OnStateChanged(EntityUid uid, JukeboxComponent component, ref ComponentHandleState args)
{
if (args.Current is JukeboxComponentState state)
{
component.Repeating = state.Playing;
component.Volume = state.Volume;
component.PlayingSongData = state.SongData;
}
}
private void ProcessJukeboxes() private void ProcessJukeboxes()
{ {
var jukeboxes = EntityQuery<JukeboxComponent, TransformComponent>(); var jukeboxes = EntityQuery<JukeboxComponent, TransformComponent>();
@@ -129,22 +116,35 @@ public sealed class JukeboxSystem : EntitySystem
foreach (var (jukeboxComponent, jukeboxXform) in jukeboxes) foreach (var (jukeboxComponent, jukeboxXform) in jukeboxes)
{ {
if(jukeboxXform.MapID != playerXform.MapID) continue; if (jukeboxXform.MapID != playerXform.MapID || (jukeboxXform.MapPosition.Position - playerXform.MapPosition.Position).Length() > _maxAudioRange)
if ((jukeboxXform.MapPosition.Position - playerXform.MapPosition.Position).Length() > _maxAudioRange) continue; {
if (_playingJukeboxes.TryGetValue(jukeboxComponent, out var stream))
{
_playingJukeboxes.Remove(jukeboxComponent);
stream.PlayingStream.StopPlaying();
stream.PlayingStream.Dispose();
}
continue;
}
if (_playingJukeboxes.TryGetValue(jukeboxComponent, out var jukeboxAudio)) if (_playingJukeboxes.TryGetValue(jukeboxComponent, out var jukeboxAudio))
{ {
if (!jukeboxAudio.Component.Playing) if (!jukeboxAudio.PlayingStream.Playing)
{ {
HandleDoneStream(jukeboxAudio, jukeboxComponent); HandleDoneStream(jukeboxAudio, jukeboxComponent, jukeboxXform, playerXform);
return; continue;
} }
if (jukeboxAudio.SongData.SongPath != jukeboxComponent.PlayingSongData?.SongPath) if (jukeboxAudio.SongData.SongPath != jukeboxComponent.PlayingSongData?.SongPath)
{ {
HandleSongChanged(jukeboxAudio, jukeboxComponent); HandleSongChanged(jukeboxAudio, jukeboxComponent, jukeboxXform, playerXform);
return; continue;
} }
SetOcclusion(playerXform, jukeboxXform, jukeboxAudio);
SetPosition(jukeboxXform, jukeboxAudio);
} }
else else
{ {
@@ -154,11 +154,11 @@ public sealed class JukeboxSystem : EntitySystem
continue; continue;
} }
var stream = TryCreateStream(jukeboxComponent); var stream = TryCreateStream(jukeboxComponent, jukeboxXform, playerXform);
if (stream == null) if (stream == null)
{ {
return; continue;
} }
_playingJukeboxes.Add(jukeboxComponent, stream); _playingJukeboxes.Add(jukeboxComponent, stream);
@@ -167,13 +167,34 @@ public sealed class JukeboxSystem : EntitySystem
} }
} }
private void HandleSongChanged(JukeboxAudio jukeboxAudio, JukeboxComponent jukeboxComponent) private void SetPosition(TransformComponent jukeboxXform, JukeboxAudio jukeboxAudio)
{ {
_audioSystem.Stop(jukeboxAudio.PlayingStream, jukeboxAudio.Component); jukeboxAudio.PlayingStream.Position = jukeboxXform.MapPosition.Position;
}
private void SetOcclusion(TransformComponent playerXform, TransformComponent jukeboxXform, JukeboxAudio jukeboxAudio)
{
var collisionMask = CollisionGroup.Impassable;
var sourceRelative = playerXform.MapPosition.Position - jukeboxXform.MapPosition.Position;
var occlusion = 0f;
if (sourceRelative.Length() > 0)
{
occlusion = _physicsSystem.IntersectRayPenetration(jukeboxXform.MapID,
new CollisionRay(jukeboxXform.MapPosition.Position, sourceRelative.Normalized(), (int)collisionMask),
sourceRelative.Length(), jukeboxXform.Owner) * 3f;
}
jukeboxAudio.PlayingStream.Occlusion = occlusion;
}
private void HandleSongChanged(JukeboxAudio jukeboxAudio, JukeboxComponent jukeboxComponent, TransformComponent jukeboxXform, TransformComponent playerXform)
{
jukeboxAudio.PlayingStream.StopPlaying();
if (jukeboxComponent.PlayingSongData != null && jukeboxComponent.PlayingSongData.SongPath == jukeboxAudio.SongData.SongPath) if (jukeboxComponent.PlayingSongData != null && jukeboxComponent.PlayingSongData.SongPath == jukeboxAudio.SongData.SongPath)
{ {
var newStream = TryCreateStream(jukeboxComponent); var newStream = TryCreateStream(jukeboxComponent, jukeboxXform, playerXform);
if(newStream == null) return; if(newStream == null) return;
_playingJukeboxes[jukeboxComponent] = newStream; _playingJukeboxes[jukeboxComponent] = newStream;
@@ -186,11 +207,11 @@ public sealed class JukeboxSystem : EntitySystem
} }
} }
private void HandleDoneStream(JukeboxAudio jukeboxAudio, JukeboxComponent jukeboxComponent) private void HandleDoneStream(JukeboxAudio jukeboxAudio, JukeboxComponent jukeboxComponent, TransformComponent jukeboxXform, TransformComponent playerXform)
{ {
if (!jukeboxComponent.Repeating) if (!jukeboxComponent.Repeating)
{ {
_audioSystem.Stop(jukeboxAudio.PlayingStream, jukeboxAudio.Component); jukeboxAudio.PlayingStream.StopPlaying();
_playingJukeboxes.Remove(jukeboxComponent); _playingJukeboxes.Remove(jukeboxComponent);
SetBarsLayerVisible(jukeboxComponent, false); SetBarsLayerVisible(jukeboxComponent, false);
return; return;
@@ -199,7 +220,7 @@ public sealed class JukeboxSystem : EntitySystem
if(jukeboxComponent.PlayingSongData == null) return; if(jukeboxComponent.PlayingSongData == null) return;
var newStream = TryCreateStream(jukeboxComponent); var newStream = TryCreateStream(jukeboxComponent, jukeboxXform, playerXform);
if (newStream == null) if (newStream == null)
{ {
@@ -214,47 +235,35 @@ public sealed class JukeboxSystem : EntitySystem
} }
} }
private JukeboxAudio? TryCreateStream(JukeboxComponent jukeboxComponent) private JukeboxAudio? TryCreateStream(JukeboxComponent jukeboxComponent, TransformComponent jukeboxXform, TransformComponent playerXform)
{ {
if (jukeboxComponent.PlayingSongData == null) return null; if (jukeboxComponent.PlayingSongData == null) return null;
var resourcePath = jukeboxComponent.PlayingSongData.SongPath!; var resourcePath = jukeboxComponent.PlayingSongData.SongPath!;
var localSession = _playerManager.LocalPlayer!.Session;
if(!_resource.TryGetResource<AudioResource>((ResPath) resourcePath, out var audio)) if(!_resource.TryGetResource<AudioResource>((ResPath) resourcePath, out var audio))
return null!; return null!;
if (audio!.AudioStream.Length.TotalSeconds < jukeboxComponent.PlayingSongData!.PlaybackPosition) if (audio.AudioStream.Length.TotalSeconds < jukeboxComponent.PlayingSongData!.PlaybackPosition)
{ {
return null!; return null!;
} }
var audioParams = new AudioParams var playingStream = _clydeAudio.CreateAudioSource(audio.AudioStream);
{ if (playingStream == null)
PlayOffsetSeconds = jukeboxComponent.PlayingSongData.PlaybackPosition, return null!;
Volume = _jukeboxVolume,
MaxDistance = _maxAudioRange
};
var playingStream = _audioSystem.PlayEntity(resourcePath.ToString()!, localSession, jukeboxComponent.Owner, audioParams); playingStream.Volume = _jukeboxVolume;
playingStream.RolloffFactor = 3.5f;
return new JukeboxAudio(playingStream.Value.Entity, playingStream.Value.Component, audio!, jukeboxComponent.PlayingSongData); playingStream.Position = jukeboxXform.MapPosition.Position;
}
private class JukeboxAudio var jukeboxAudio = new JukeboxAudio(playingStream!, audio, jukeboxComponent.PlayingSongData);
{
public PlayingSongData SongData { get; }
public EntityUid PlayingStream { get; }
public AudioComponent Component { get; }
public AudioResource AudioStream { get; }
public JukeboxAudio(EntityUid playingStream, AudioComponent component, AudioResource audioStream, PlayingSongData songData) SetOcclusion(playerXform, jukeboxXform, jukeboxAudio);
{ playingStream.StartPlaying();
PlayingStream = playingStream;
Component = component; return jukeboxAudio;
AudioStream = audioStream;
SongData = songData;
}
} }
private void SetBarsLayerVisible(JukeboxComponent jukeboxComponent, bool visible) private void SetBarsLayerVisible(JukeboxComponent jukeboxComponent, bool visible)
@@ -264,11 +273,36 @@ public sealed class JukeboxSystem : EntitySystem
spriteComponent.LayerSetVisible(layer, visible); spriteComponent.LayerSetVisible(layer, visible);
} }
private void OnStateChanged(EntityUid uid, JukeboxComponent component, ref ComponentHandleState args)
{
if (args.Current is JukeboxComponentState state)
{
component.Repeating = state.Playing;
component.Volume = state.Volume;
component.PlayingSongData = state.SongData;
}
}
private class JukeboxAudio
{
public PlayingSongData SongData { get; }
public IAudioSource PlayingStream { get; }
public AudioResource AudioStream { get; }
public JukeboxAudio(IAudioSource playingStream, AudioResource audioStream, PlayingSongData songData)
{
PlayingStream = playingStream;
AudioStream = audioStream;
SongData = songData;
}
}
private void CleanUp() private void CleanUp()
{ {
foreach (var playingJukebox in _playingJukeboxes.Values) foreach (var playingJukebox in _playingJukeboxes.Values)
{ {
_audioSystem.Stop(playingJukebox.PlayingStream, playingJukebox.Component); playingJukebox.PlayingStream.StopPlaying();
playingJukebox.PlayingStream.Dispose();
} }
_playingJukeboxes.Clear(); _playingJukeboxes.Clear();

View File

@@ -16,13 +16,17 @@
- type: Item - type: Item
sprite: White/Objects/Devices/jukebox.rsi sprite: White/Objects/Devices/jukebox.rsi
heldPrefix: boombox heldPrefix: boombox
size: 500 size: Ginormous
- type: UserInterface - type: UserInterface
interfaces: interfaces:
- key: enum.JukeboxUIKey.Key - key: enum.JukeboxUIKey.Key
type: JukeboxBUI type: JukeboxBUI
- type: ActivatableUI - type: ActivatableUI
key: enum.JukeboxUIKey.Key key: enum.JukeboxUIKey.Key
- type: ContainerContainer
containers:
jukebox_tapes: !type:Container
jukebox_default_tapes: !type:Container
- type: entity - type: entity
parent: BaseItem parent: BaseItem
@@ -50,3 +54,6 @@
type: TapeCreatorBUI type: TapeCreatorBUI
- type: ActivatableUI - type: ActivatableUI
key: enum.TapeCreatorUIKey.Key key: enum.TapeCreatorUIKey.Key
- type: ContainerContainer
containers:
tape_creator_container: !type:Container