diff --git a/Content.Server/Nutrition/EntitySystems/SmokingSystem.cs b/Content.Server/Nutrition/EntitySystems/SmokingSystem.cs index d2074a3d82..b3ef8bff69 100644 --- a/Content.Server/Nutrition/EntitySystems/SmokingSystem.cs +++ b/Content.Server/Nutrition/EntitySystems/SmokingSystem.cs @@ -15,6 +15,7 @@ using Content.Shared.Nutrition.Components; using Content.Shared.Smoking; using Content.Shared.Temperature; using Robust.Server.GameObjects; +using Robust.Shared.Audio.Systems; using Robust.Shared.Containers; using System.Linq; using Content.Shared.Atmos; @@ -30,6 +31,7 @@ namespace Content.Server.Nutrition.EntitySystems [Dependency] private readonly TransformSystem _transformSystem = default!; [Dependency] private readonly InventorySystem _inventorySystem = default!; [Dependency] private readonly ClothingSystem _clothing = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedItemSystem _items = default!; [Dependency] private readonly SharedContainerSystem _container = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!; @@ -39,11 +41,6 @@ namespace Content.Server.Nutrition.EntitySystems private float _timer; - /// - /// We keep a list of active smokables, because iterating all existing smokables would be dumb. - /// - private readonly HashSet _active = new(); - public override void Initialize() { SubscribeLocalEvent(OnSmokableIsHotEvent); @@ -65,7 +62,7 @@ namespace Content.Server.Nutrition.EntitySystems public void SetSmokableState(EntityUid uid, SmokableState state, SmokableComponent? smokable = null, AppearanceComponent? appearance = null, ClothingComponent? clothing = null) { - if (!Resolve(uid, ref smokable, ref appearance, ref clothing)) + if (!Resolve(uid, ref smokable, ref appearance, ref clothing) || smokable.State == state) return; smokable.State = state; @@ -83,17 +80,17 @@ namespace Content.Server.Nutrition.EntitySystems if (state == SmokableState.Lit) { + EnsureComp(uid); + _audio.PlayPvs(smokable.LightSound, uid); var igniteEvent = new IgnitedEvent(); RaiseLocalEvent(uid, ref igniteEvent); - - _active.Add(uid); } else { - var igniteEvent = new ExtinguishedEvent(); - RaiseLocalEvent(uid, ref igniteEvent); - - _active.Remove(uid); + RemComp(uid); + _audio.PlayPvs(smokable.SnuffSound, uid); + var extinguishEvent = new ExtinguishedEvent(); + RaiseLocalEvent(uid, ref extinguishEvent); } } @@ -104,7 +101,7 @@ namespace Content.Server.Nutrition.EntitySystems private void OnSmokableShutdownEvent(Entity entity, ref ComponentShutdown args) { - _active.Remove(entity); + RemComp(entity); } private void OnSmokeableEquipEvent(Entity entity, ref GotEquippedEvent args) @@ -122,18 +119,12 @@ namespace Content.Server.Nutrition.EntitySystems if (_timer < UpdateTimer) return; - // TODO Use an "active smoke" component instead, EntityQuery over that. - foreach (var uid in _active.ToArray()) + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out _, out var smokable)) { - if (!TryComp(uid, out SmokableComponent? smokable)) - { - _active.Remove(uid); - continue; - } - if (!_solutionContainerSystem.TryGetSolution(uid, smokable.Solution, out var soln, out var solution)) { - _active.Remove(uid); + SetSmokableState(uid, SmokableState.Unlit, smokable); continue; } diff --git a/Content.Shared/Nutrition/Components/SmokableComponent.cs b/Content.Shared/Nutrition/Components/SmokableComponent.cs index e5cbd27242..28e84dc190 100644 --- a/Content.Shared/Nutrition/Components/SmokableComponent.cs +++ b/Content.Shared/Nutrition/Components/SmokableComponent.cs @@ -1,5 +1,6 @@ using Content.Shared.FixedPoint; using Content.Shared.Smoking; +using Robust.Shared.Audio; using Robust.Shared.GameStates; namespace Content.Shared.Nutrition.Components @@ -32,5 +33,17 @@ namespace Content.Shared.Nutrition.Components public string LitPrefix = "lit"; [DataField("unlitPrefix")] public string UnlitPrefix = "unlit"; + + /// + /// Sound played when lighting this smokable. + /// + [DataField] + public SoundSpecifier? LightSound = new SoundPathSpecifier("/Audio/Effects/cig_light.ogg"); + + /// + /// Sound played when this smokable is extinguished or runs out. + /// + [DataField] + public SoundSpecifier? SnuffSound = new SoundPathSpecifier("/Audio/Effects/cig_snuff.ogg"); } } diff --git a/Content.Shared/Smoking/BurningComponent.cs b/Content.Shared/Smoking/BurningComponent.cs new file mode 100644 index 0000000000..bbb9765174 --- /dev/null +++ b/Content.Shared/Smoking/BurningComponent.cs @@ -0,0 +1,12 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Smoking; + +/// +/// Marker component used to track active burning objects. +/// +/// +/// Right now only smoking uses this, but flammable could use it as well in the future. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class BurningComponent : Component; diff --git a/Resources/Audio/Effects/attributions.yml b/Resources/Audio/Effects/attributions.yml index add8884a7d..9cfaa54122 100644 --- a/Resources/Audio/Effects/attributions.yml +++ b/Resources/Audio/Effects/attributions.yml @@ -241,3 +241,8 @@ copyright: 'created by Vrymaa on Freesound and modified by Chaboricks' license: "CC0-1.0" source: https://freesound.org/people/Vrymaa/sounds/785128/ + +- files: ["cig_light.ogg", "cig_snuff.ogg"] + license: "CC-BY-SA-3.0" + copyright: "Created by mattroks101 for Bee Station. cig_snuff converted to mono" + source: "https://github.com/BeeStation/BeeStation-Hornet/pull/29" diff --git a/Resources/Audio/Effects/cig_light.ogg b/Resources/Audio/Effects/cig_light.ogg new file mode 100644 index 0000000000..48aef9c344 Binary files /dev/null and b/Resources/Audio/Effects/cig_light.ogg differ diff --git a/Resources/Audio/Effects/cig_snuff.ogg b/Resources/Audio/Effects/cig_snuff.ogg new file mode 100644 index 0000000000..b97cd5c426 Binary files /dev/null and b/Resources/Audio/Effects/cig_snuff.ogg differ