[fix] Бумбокс (#18)
* Отвал пизды * Ебался --------- Co-authored-by: Mona Hmiza <>
This commit is contained in:
@@ -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();
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user