#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);
}
}
}
}