diff --git a/Content.Server/Dice/DiceComponent.cs b/Content.Server/Dice/DiceComponent.cs index 94cb65945b..99bdf36eaa 100644 --- a/Content.Server/Dice/DiceComponent.cs +++ b/Content.Server/Dice/DiceComponent.cs @@ -1,6 +1,7 @@ using Content.Shared.Audio; using Content.Shared.Examine; using Content.Shared.Interaction; +using Content.Shared.Sound; using Content.Shared.Throwing; using Robust.Server.GameObjects; using Robust.Shared.Audio; @@ -24,15 +25,16 @@ namespace Content.Server.Dice public override string Name => "Dice"; - [DataField("step")] - private int _step = 1; private int _sides = 20; - private int _currentSide = 20; + [ViewVariables] - [DataField("diceSoundCollection")] - public string _soundCollectionName = "dice"; + [DataField("sound")] + private readonly SoundSpecifier _sound = new SoundCollectionSpecifier("Dice"); + [ViewVariables] - public int Step => _step; + [DataField("step")] + public int Step { get; } = 1; + [ViewVariables] [DataField("sides")] public int Sides @@ -41,29 +43,28 @@ namespace Content.Server.Dice set { _sides = value; - _currentSide = value; + CurrentSide = value; } } [ViewVariables] - public int CurrentSide => _currentSide; + public int CurrentSide { get; private set; } = 20; public void Roll() { - _currentSide = _random.Next(1, (_sides/_step)+1) * _step; - if (!Owner.TryGetComponent(out SpriteComponent? sprite)) return; - sprite.LayerSetState(0, $"d{_sides}{_currentSide}"); + CurrentSide = _random.Next(1, (_sides/Step)+1) * Step; + PlayDiceEffect(); + + if (!Owner.TryGetComponent(out SpriteComponent? sprite)) + return; + + sprite.LayerSetState(0, $"d{_sides}{CurrentSide}"); } public void PlayDiceEffect() { - if (!string.IsNullOrWhiteSpace(_soundCollectionName)) - { - var soundCollection = _prototypeManager.Index(_soundCollectionName); - var file = _random.Pick(soundCollection.PickFiles); - SoundSystem.Play(Filter.Pvs(Owner), file, Owner, AudioParams.Default); - } + SoundSystem.Play(Filter.Pvs(Owner), _sound.GetSound(), Owner, AudioParams.Default); } void IActivate.Activate(ActivateEventArgs eventArgs) @@ -89,7 +90,7 @@ namespace Content.Server.Dice ("sidesAmount", _sides)) + "\n" + Loc.GetString("dice-component-on-examine-message-part-2", - ("currentSide", _currentSide))); + ("currentSide", CurrentSide))); } } } diff --git a/Content.Shared/Sound/SoundSpecifier.cs b/Content.Shared/Sound/SoundSpecifier.cs new file mode 100644 index 0000000000..616ccf9551 --- /dev/null +++ b/Content.Shared/Sound/SoundSpecifier.cs @@ -0,0 +1,67 @@ +using System; +using Content.Shared.Audio; +using Robust.Shared; +using Robust.Shared.Serialization.Manager.Attributes; +using Robust.Shared.Serialization.TypeSerializers.Implementations; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; +using Robust.Shared.Utility; + +namespace Content.Shared.Sound +{ + [DataDefinition] + public abstract class SoundSpecifier + { + public abstract string GetSound(); + } + + [DataDefinition] + public sealed class SoundPathSpecifier : SoundSpecifier + { + public const string Node = "path"; + + [DataField(Node, customTypeSerializer:typeof(ResourcePathSerializer), required:true)] + public ResourcePath? Path { get; } + + public SoundPathSpecifier() + { + } + + public SoundPathSpecifier(string path) + { + Path = new ResourcePath(path); + } + + public SoundPathSpecifier(ResourcePath path) + { + Path = path; + } + + public override string GetSound() + { + return Path == null ? string.Empty : Path.ToString(); + } + } + + [DataDefinition] + public sealed class SoundCollectionSpecifier : SoundSpecifier + { + public const string Node = "collection"; + + [DataField(Node, customTypeSerializer:typeof(PrototypeIdSerializer), required:true)] + public string? Collection { get; } + + public SoundCollectionSpecifier() + { + } + + public SoundCollectionSpecifier(string collection) + { + Collection = collection; + } + + public override string GetSound() + { + return Collection == null ? string.Empty : AudioHelpers.GetRandomFileFromSoundCollection(Collection); + } + } +} diff --git a/Content.Shared/Sound/SoundSpecifierTypeSerializer.cs b/Content.Shared/Sound/SoundSpecifierTypeSerializer.cs new file mode 100644 index 0000000000..26596961c5 --- /dev/null +++ b/Content.Shared/Sound/SoundSpecifierTypeSerializer.cs @@ -0,0 +1,48 @@ +using System; +using Robust.Shared.IoC; +using Robust.Shared.Serialization.Manager; +using Robust.Shared.Serialization.Manager.Attributes; +using Robust.Shared.Serialization.Manager.Result; +using Robust.Shared.Serialization.Markdown.Mapping; +using Robust.Shared.Serialization.Markdown.Validation; +using Robust.Shared.Serialization.TypeSerializers.Interfaces; + +namespace Content.Shared.Sound +{ + [TypeSerializer] + public class SoundSpecifierTypeSerializer : ITypeReader + { + private Type GetType(MappingDataNode node) + { + var hasPath = node.Has(SoundPathSpecifier.Node); + var hasCollection = node.Has(SoundCollectionSpecifier.Node); + + if (hasPath || !(hasPath ^ hasCollection)) + return typeof(SoundPathSpecifier); + + if (hasCollection) + return typeof(SoundCollectionSpecifier); + + return typeof(SoundPathSpecifier); + } + + public DeserializationResult Read(ISerializationManager serializationManager, MappingDataNode node, + IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null) + { + var type = GetType(node); + return serializationManager.Read(type, node, context, skipHook); + } + + public ValidationNode Validate(ISerializationManager serializationManager, MappingDataNode node, + IDependencyCollection dependencies, ISerializationContext? context = null) + { + if (node.Has(SoundPathSpecifier.Node) && node.Has(SoundCollectionSpecifier.Node)) + return new ErrorNode(node, "You can only specify either a sound path or a sound collection!"); + + if (!node.Has(SoundPathSpecifier.Node) && !node.Has(SoundCollectionSpecifier.Node)) + return new ErrorNode(node, "You need to specify either a sound path or a sound collection!"); + + return serializationManager.ValidateNode(GetType(node), node, context); + } + } +} diff --git a/Resources/Prototypes/Entities/Objects/Fun/dice.yml b/Resources/Prototypes/Entities/Objects/Fun/dice.yml index 90005db59b..93ae58dd7c 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/dice.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/dice.yml @@ -4,7 +4,6 @@ id: BaseDice components: - type: Dice - - type: LoopingSound - type: Sprite sprite: Objects/Fun/dice.rsi diff --git a/Resources/Prototypes/SoundCollections/dice.yml b/Resources/Prototypes/SoundCollections/dice.yml index 6ae970bc91..2683441098 100644 --- a/Resources/Prototypes/SoundCollections/dice.yml +++ b/Resources/Prototypes/SoundCollections/dice.yml @@ -1,5 +1,5 @@ - type: soundCollection - id: dice + id: Dice files: - /Audio/Items/Dice/dice1.ogg - /Audio/Items/Dice/dice2.ogg