From 440cd377ca9ae914be4b89b96490a5a43a1c1c3f Mon Sep 17 00:00:00 2001 From: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> Date: Sun, 5 Feb 2023 14:52:30 -0500 Subject: [PATCH] Anomaly Vessel visuals + audio (#13927) --- .../Anomaly/AnomalySystem.Vessel.cs | 71 +++++++++++++++++- Content.Server/Anomaly/AnomalySystem.cs | 7 ++ .../Components/AnomalyVesselComponent.cs | 26 +++++++ Content.Shared/Anomaly/SharedAnomaly.cs | 3 +- Resources/Audio/Machines/attributions.yml | 5 ++ Resources/Audio/Machines/vessel_warning.ogg | Bin 0 -> 4523 bytes .../Structures/Machines/anomaly_equipment.yml | 14 +++- .../{anomaly.png => anomaly-1.png} | Bin .../Anomaly/anomaly_vessel.rsi/anomaly-2.png | Bin 0 -> 262 bytes .../Anomaly/anomaly_vessel.rsi/anomaly-3.png | Bin 0 -> 259 bytes .../Anomaly/anomaly_vessel.rsi/meta.json | 18 ++++- .../{powered.png => powered-1.png} | Bin .../Anomaly/anomaly_vessel.rsi/powered-2.png | Bin 0 -> 143 bytes .../Anomaly/anomaly_vessel.rsi/powered-3.png | Bin 0 -> 143 bytes 14 files changed, 137 insertions(+), 7 deletions(-) create mode 100644 Resources/Audio/Machines/vessel_warning.ogg rename Resources/Textures/Structures/Machines/Anomaly/anomaly_vessel.rsi/{anomaly.png => anomaly-1.png} (100%) create mode 100644 Resources/Textures/Structures/Machines/Anomaly/anomaly_vessel.rsi/anomaly-2.png create mode 100644 Resources/Textures/Structures/Machines/Anomaly/anomaly_vessel.rsi/anomaly-3.png rename Resources/Textures/Structures/Machines/Anomaly/anomaly_vessel.rsi/{powered.png => powered-1.png} (100%) create mode 100644 Resources/Textures/Structures/Machines/Anomaly/anomaly_vessel.rsi/powered-2.png create mode 100644 Resources/Textures/Structures/Machines/Anomaly/anomaly_vessel.rsi/powered-3.png diff --git a/Content.Server/Anomaly/AnomalySystem.Vessel.cs b/Content.Server/Anomaly/AnomalySystem.Vessel.cs index ce71cf4715..4809a613fd 100644 --- a/Content.Server/Anomaly/AnomalySystem.Vessel.cs +++ b/Content.Server/Anomaly/AnomalySystem.Vessel.cs @@ -25,7 +25,9 @@ public sealed partial class AnomalySystem SubscribeLocalEvent(OnVesselInteractUsing); SubscribeLocalEvent(OnExamined); SubscribeLocalEvent(OnVesselGetPointsPerSecond); + SubscribeLocalEvent(OnUnpaused); SubscribeLocalEvent(OnVesselAnomalyShutdown); + SubscribeLocalEvent(OnVesselAnomalyStabilityChanged); } private void OnExamined(EntityUid uid, AnomalyVesselComponent component, ExaminedEvent args) @@ -94,6 +96,11 @@ public sealed partial class AnomalySystem args.Points += (int) (GetAnomalyPointValue(anomaly) * component.PointMultiplier); } + private void OnUnpaused(EntityUid uid, AnomalyVesselComponent component, ref EntityUnpausedEvent args) + { + component.NextBeep += args.PausedTime; + } + private void OnVesselAnomalyShutdown(ref AnomalyShutdownEvent args) { foreach (var component in EntityQuery()) @@ -112,6 +119,18 @@ public sealed partial class AnomalySystem } } + private void OnVesselAnomalyStabilityChanged(ref AnomalyStabilityChangedEvent args) + { + foreach (var component in EntityQuery()) + { + var ent = component.Owner; + if (args.Anomaly != component.Anomaly) + continue; + + UpdateVesselAppearance(ent, component); + } + } + /// /// Updates the appearance of an anomaly vessel /// based on whether or not it has an anomaly @@ -125,11 +144,61 @@ public sealed partial class AnomalySystem var on = component.Anomaly != null; - Appearance.SetData(uid, AnomalyVesselVisuals.HasAnomaly, on); + if (!TryComp(uid, out var appearanceComponent)) + return; + + Appearance.SetData(uid, AnomalyVesselVisuals.HasAnomaly, on, appearanceComponent); if (TryComp(uid, out var pointLightComponent)) { pointLightComponent.Enabled = on; } + + // arbitrary value for the generic visualizer to use. + // i didn't feel like making an enum for this. + var value = 1; + if (TryComp(component.Anomaly, out var anomalyComp)) + { + if (anomalyComp.Stability <= anomalyComp.DecayThreshold) + { + value = 2; + } + else if (anomalyComp.Stability >= anomalyComp.GrowthThreshold) + { + value = 3; + } + } + Appearance.SetData(uid, AnomalyVesselVisuals.AnomalyState, value, appearanceComponent); + _ambient.SetAmbience(uid, on); } + + private void UpdateVessels() + { + foreach (var vessel in EntityQuery()) + { + var vesselEnt = vessel.Owner; + if (vessel.Anomaly is not { } anomUid) + continue; + + if (!TryComp(anomUid, out var anomaly)) + continue; + + if (Timing.CurTime < vessel.NextBeep) + continue; + + // a lerp between the max and min values for each threshold. + // longer beeps that get shorter as the anomaly gets more extreme + float timerPercentage; + if (anomaly.Stability <= anomaly.DecayThreshold) + timerPercentage = (anomaly.DecayThreshold - anomaly.Stability) / anomaly.DecayThreshold; + else if (anomaly.Stability >= anomaly.GrowthThreshold) + timerPercentage = (anomaly.Stability - anomaly.GrowthThreshold) / (1 - anomaly.GrowthThreshold); + else //it's not unstable + continue; + + Audio.PlayPvs(vessel.BeepSound, vesselEnt); + var beepInterval = (vessel.MaxBeepInterval - vessel.MinBeepInterval) * (1 - timerPercentage) + vessel.MinBeepInterval; + vessel.NextBeep = beepInterval + Timing.CurTime; + } + } } diff --git a/Content.Server/Anomaly/AnomalySystem.cs b/Content.Server/Anomaly/AnomalySystem.cs index f85ddbe990..8dce08c406 100644 --- a/Content.Server/Anomaly/AnomalySystem.cs +++ b/Content.Server/Anomaly/AnomalySystem.cs @@ -124,4 +124,11 @@ public sealed partial class AnomalySystem : SharedAnomalySystem _ => throw new ArgumentOutOfRangeException() }; } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + UpdateVessels(); + } } diff --git a/Content.Server/Anomaly/Components/AnomalyVesselComponent.cs b/Content.Server/Anomaly/Components/AnomalyVesselComponent.cs index c833cf636b..2d502f0ea3 100644 --- a/Content.Server/Anomaly/Components/AnomalyVesselComponent.cs +++ b/Content.Server/Anomaly/Components/AnomalyVesselComponent.cs @@ -1,4 +1,6 @@ using Content.Shared.Construction.Prototypes; +using Robust.Shared.Audio; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; namespace Content.Server.Anomaly.Components; @@ -37,4 +39,28 @@ public sealed class AnomalyVesselComponent : Component /// [DataField("partRatingPointModifier")] public float PartRatingPointModifier = 1.5f; + + /// + /// The maximum time between each beep + /// + [DataField("maxBeepInterval")] + public TimeSpan MaxBeepInterval = TimeSpan.FromSeconds(2f); + + /// + /// The minimum time between each beep + /// + [DataField("minBeepInterval")] + public TimeSpan MinBeepInterval = TimeSpan.FromSeconds(0.75f); + + /// + /// When the next beep sound will play + /// + [DataField("nextBeep", customTypeSerializer:typeof(TimeOffsetSerializer))] + public TimeSpan NextBeep = TimeSpan.Zero; + + /// + /// The sound that is played repeatedly when the anomaly is destabilizing/decaying + /// + [DataField("beepSound")] + public SoundSpecifier BeepSound = new SoundPathSpecifier("/Audio/Machines/vessel_warning.ogg"); } diff --git a/Content.Shared/Anomaly/SharedAnomaly.cs b/Content.Shared/Anomaly/SharedAnomaly.cs index fe93cff117..9ee1f847a9 100644 --- a/Content.Shared/Anomaly/SharedAnomaly.cs +++ b/Content.Shared/Anomaly/SharedAnomaly.cs @@ -38,7 +38,8 @@ public enum AnomalousParticleType : byte [Serializable, NetSerializable] public enum AnomalyVesselVisuals : byte { - HasAnomaly + HasAnomaly, + AnomalyState } [Serializable, NetSerializable] diff --git a/Resources/Audio/Machines/attributions.yml b/Resources/Audio/Machines/attributions.yml index 64bb2793db..4ac0ac9cfb 100644 --- a/Resources/Audio/Machines/attributions.yml +++ b/Resources/Audio/Machines/attributions.yml @@ -12,3 +12,8 @@ license: "CC0-1.0" copyright: "receipt printing.wav by 13F_Panska_Tlolkova_Matilda. This version is cleaned up, shortened, and converted to OGG." source: "https://freesound.org/people/13F_Panska_Tlolkova_Matilda/sounds/378331" + +- files: ["vessel_warning.ogg"] + license: "CC-BY-4.0" + copyright: "Created by AUDACITIER (freesound), converted to MONO and .ogg and edited by EmoGarbage404 (github)." + source: "https://freesound.org/people/AUDACITIER/sounds/629196/" \ No newline at end of file diff --git a/Resources/Audio/Machines/vessel_warning.ogg b/Resources/Audio/Machines/vessel_warning.ogg new file mode 100644 index 0000000000000000000000000000000000000000..63431034c036992d89948da3646a2672713cfcf9 GIT binary patch literal 4523 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 MPoH>rVwaZmFT$-RLjV8( literal 0 HcmV?d00001 diff --git a/Resources/Prototypes/Entities/Structures/Machines/anomaly_equipment.yml b/Resources/Prototypes/Entities/Structures/Machines/anomaly_equipment.yml index 581e15e5f8..cfce5ca910 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/anomaly_equipment.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/anomaly_equipment.yml @@ -9,10 +9,11 @@ sprite: Structures/Machines/Anomaly/anomaly_vessel.rsi layers: - state: base - - state: powered + - state: powered-1 shader: unshaded map: ["enum.PowerDeviceVisualLayers.Powered"] - - state: anomaly + - state: anomaly-1 + visible: false shader: unshaded map: ["enum.AnomalyVesselVisualLayers.Base"] - state: panel @@ -54,6 +55,15 @@ enum.AnomalyVesselVisualLayers.Base: True: { visible: true } False: { visible: false } + enum.AnomalyVesselVisuals.AnomalyState: + enum.PowerDeviceVisualLayers.Powered: + 1: { state: powered-1 } + 2: { state: powered-2 } + 3: { state: powered-3 } + enum.AnomalyVesselVisualLayers.Base: + 1: { state: anomaly-1 } + 2: { state: anomaly-2 } + 3: { state: anomaly-3 } enum.WiresVisuals.MaintenancePanelState: enum.WiresVisualLayers.MaintenancePanel: True: { visible: false } diff --git a/Resources/Textures/Structures/Machines/Anomaly/anomaly_vessel.rsi/anomaly.png b/Resources/Textures/Structures/Machines/Anomaly/anomaly_vessel.rsi/anomaly-1.png similarity index 100% rename from Resources/Textures/Structures/Machines/Anomaly/anomaly_vessel.rsi/anomaly.png rename to Resources/Textures/Structures/Machines/Anomaly/anomaly_vessel.rsi/anomaly-1.png diff --git a/Resources/Textures/Structures/Machines/Anomaly/anomaly_vessel.rsi/anomaly-2.png b/Resources/Textures/Structures/Machines/Anomaly/anomaly_vessel.rsi/anomaly-2.png new file mode 100644 index 0000000000000000000000000000000000000000..2e4aebe536a2672f43201e0aef6f14c2bc2506b7 GIT binary patch literal 262 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}2RvOILn2y} z6C_v{Cy4Yk1sZU<9rR%D`JwWEPi*Sp0|yqcKh-ieF!0#FPx0;@i{R0b80V~%WTjzuPd#;DUpZap=v@$ci+r@pkEj~UHx3v IIVCg!07e;O&;S4c literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Machines/Anomaly/anomaly_vessel.rsi/anomaly-3.png b/Resources/Textures/Structures/Machines/Anomaly/anomaly_vessel.rsi/anomaly-3.png new file mode 100644 index 0000000000000000000000000000000000000000..da20f911821341879b32cbdf48eb743142fce462 GIT binary patch literal 259 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}dp%toLn2z= zPT9zH$Uva2-c`nbqJZGS==-km2YT#gC)X&ln>!u}Xi6)&s5-@AYp-hQitoCf9!1}u z@-Z3k95&$j{GR8P+4=JX99pA&CVUTEXw@b$x=n)1_S3j3^ HP6KZ3WQ_bNYQEypvzQf}4>_i8y^^#~N#ohgn<W$<+Mb6Mw<&;$Tsg*5p9 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Machines/Anomaly/anomaly_vessel.rsi/powered-3.png b/Resources/Textures/Structures/Machines/Anomaly/anomaly_vessel.rsi/powered-3.png new file mode 100644 index 0000000000000000000000000000000000000000..59af1c9a3319c2655f458154074bb3758df110b1 GIT binary patch literal 143 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}o}Mm_ArY-_ z&o1O`a1da<$XIAPAz_=9)}p1}>w4Bc=7~6?)s!@E?);hwDxQ;;?2le`Vf*8*j1)g5 qsoxf--%4kT&U-%db9X*xgY>#}yexq$P1gYpW$<+Mb6Mw<&;$Vaelh?6 literal 0 HcmV?d00001 -- 2.52.0