#nullable enable using System.Collections.Generic; using Content.Server.GameObjects.Components.Stack; using Content.Shared.Audio; using Content.Shared.GameObjects.EntitySystems; using Content.Shared.Utility; using Robust.Server.GameObjects.EntitySystems; using Robust.Shared.GameObjects.Systems; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.Random; using Robust.Shared.Interfaces.Serialization; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; namespace Content.Server.GameObjects.Components.Destructible { public class Threshold : IExposeData { /// /// Entities spawned on reaching this threshold, from a min to a max. /// [ViewVariables] public Dictionary? Spawn; /// /// Sound played upon destruction. /// [ViewVariables] public string Sound = string.Empty; /// /// Used instead of if specified. /// [ViewVariables] public string SoundCollection = string.Empty; /// /// What acts this threshold should trigger upon activation. /// See . /// [ViewVariables] public int Acts; /// /// Whether or not this threshold has already been triggered. /// [ViewVariables] public bool Triggered; /// /// Whether or not this threshold only triggers once. /// If false, it will trigger again once the entity is healed /// and then damaged to reach this threshold once again. /// It will not repeatedly trigger as damage rises beyond that. /// [ViewVariables] public bool TriggersOnce; public void ExposeData(ObjectSerializer serializer) { serializer.DataField(ref Spawn, "Spawn", null); serializer.DataField(ref Sound, "Sound", string.Empty); serializer.DataField(ref SoundCollection, "SoundCollection", string.Empty); serializer.DataField(ref Acts, "Acts", 0, WithFormat.Flags()); serializer.DataField(ref Triggered, "Triggered", false); serializer.DataField(ref TriggersOnce, "TriggersOnce", false); } /// /// Triggers this threshold. /// /// The entity that owns this threshold. /// /// An instance of to get randomness from, if relevant. /// /// /// An instance of to call acts on, if relevant. /// public void Trigger(IEntity owner, IRobustRandom random, ActSystem actSystem) { Triggered = true; PlaySound(owner); DoSpawn(owner, random); DoActs(owner, actSystem); } private void PlaySound(IEntity owner) { var pos = owner.Transform.Coordinates; var actualSound = string.Empty; if (SoundCollection != string.Empty) { actualSound = AudioHelpers.GetRandomFileFromSoundCollection(SoundCollection); } else if (Sound != string.Empty) { actualSound = Sound; } if (actualSound != string.Empty) { EntitySystem.Get().PlayAtCoords(actualSound, pos, AudioHelpers.WithVariation(0.125f)); } } private void DoSpawn(IEntity owner, IRobustRandom random) { if (Spawn == null) { return; } foreach (var (key, value) in Spawn) { var count = value.Min >= value.Max ? value.Min : random.Next(value.Min, value.Max + 1); if (count == 0) continue; if (EntityPrototypeHelpers.HasComponent(key)) { var spawned = owner.EntityManager.SpawnEntity(key, owner.Transform.Coordinates); var stack = spawned.GetComponent(); stack.Count = count; spawned.RandomOffset(0.5f); } else { for (var i = 0; i < count; i++) { var spawned = owner.EntityManager.SpawnEntity(key, owner.Transform.Coordinates); spawned.RandomOffset(0.5f); } } } } private void DoActs(IEntity owner, ActSystem acts) { if ((Acts & (int) ThresholdActs.Breakage) != 0) { acts.HandleBreakage(owner); } if ((Acts & (int) ThresholdActs.Destruction) != 0) { acts.HandleDestruction(owner); } } } }