Damage rework (#2525)
* Make damage work through messages and events, make destructible not inherit ruinable or reference damageable * Copy sound logic to destructible component for now * Fix typo * Fix prototype error * Remove breakable component damageable reference * Remove breakable construction reference * Remove ruinable component * Move thresholds to individual components and away from damageable * Add threshold property to damageable component code * Add thresholds to destructible component, add states to damageable, remove damage container, fix up mob states * Being alive isn't normal * Fix not reading the id * Merge fixes * YAML fixes * Grammar moment * Remove unnecessary dependency * Update thresholds doc * Change naming of thresholds to states in MobStateComponent * Being alive is once again normal * Make DamageState a byte * Bring out classes structs and enums from DestructibleComponent * Add test for destructible thresholds * Merge fixes * More merge fixes and fix rejuvenate test * Remove IMobState.IsConscious * More merge fixes someone please god review this shit already * Fix rejuvenate test * Update outdated destructible in YAML * Fix repeatedly entering the current state * Fix repeatedly entering the current state, add Threshold.TriggersOnce and expand test * Update saltern
This commit is contained in:
148
Content.Server/GameObjects/Components/Destructible/Threshold.cs
Normal file
148
Content.Server/GameObjects/Components/Destructible/Threshold.cs
Normal file
@@ -0,0 +1,148 @@
|
||||
#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
|
||||
{
|
||||
/// <summary>
|
||||
/// Entities spawned on reaching this threshold, from a min to a max.
|
||||
/// </summary>
|
||||
[ViewVariables] public Dictionary<string, MinMax>? Spawn;
|
||||
|
||||
/// <summary>
|
||||
/// Sound played upon destruction.
|
||||
/// </summary>
|
||||
[ViewVariables] public string Sound = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Used instead of <see cref="Sound"/> if specified.
|
||||
/// </summary>
|
||||
[ViewVariables] public string SoundCollection = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// What acts this threshold should trigger upon activation.
|
||||
/// See <see cref="ActSystem"/>.
|
||||
/// </summary>
|
||||
[ViewVariables] public int Acts;
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not this threshold has already been triggered.
|
||||
/// </summary>
|
||||
[ViewVariables] public bool Triggered;
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
[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<ActsFlags>());
|
||||
serializer.DataField(ref Triggered, "Triggered", false);
|
||||
serializer.DataField(ref TriggersOnce, "TriggersOnce", false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggers this threshold.
|
||||
/// </summary>
|
||||
/// <param name="owner">The entity that owns this threshold.</param>
|
||||
/// <param name="random">
|
||||
/// An instance of <see cref="IRobustRandom"/> to get randomness from, if relevant.
|
||||
/// </param>
|
||||
/// <param name="actSystem">
|
||||
/// An instance of <see cref="ActSystem"/> to call acts on, if relevant.
|
||||
/// </param>
|
||||
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<AudioSystem>().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<StackComponent>(key))
|
||||
{
|
||||
var spawned = owner.EntityManager.SpawnEntity(key, owner.Transform.Coordinates);
|
||||
var stack = spawned.GetComponent<StackComponent>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user