Audible emotes (#12708)

Co-authored-by: Visne <39844191+Visne@users.noreply.github.com>
This commit is contained in:
Alex Evgrashin
2023-01-25 17:29:41 +01:00
committed by GitHub
parent 7ec896543f
commit ef452b38a9
45 changed files with 794 additions and 169 deletions

View File

@@ -0,0 +1,51 @@
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
namespace Content.Shared.Chat.Prototypes;
/// <summary>
/// IC emotes (scream, smile, clapping, etc).
/// Entities can activate emotes by chat input or code.
/// </summary>
[Prototype("emote")]
public sealed class EmotePrototype : IPrototype
{
[IdDataField]
public string ID { get; } = default!;
/// <summary>
/// Different emote categories may be handled by different systems.
/// Also may be used for filtering.
/// </summary>
[DataField("category")]
public EmoteCategory Category = EmoteCategory.General;
/// <summary>
/// Collection of words that will be sent to chat if emote activates.
/// Will be picked randomly from list.
/// </summary>
[DataField("chatMessages")]
public List<string> ChatMessages = new();
/// <summary>
/// Trigger words for emote. Case independent.
/// When typed into players chat they will activate emote event.
/// All words should be unique across all emote prototypes.
/// </summary>
[DataField("chatTriggers")]
public HashSet<string> ChatTriggers = new();
}
/// <summary>
/// IC emote category. Usually physical source of emote,
/// like hands, voice, face, etc.
/// </summary>
[Flags]
[Serializable, NetSerializable]
public enum EmoteCategory : byte
{
Invalid = 0,
Vocal = 1 << 0,
Hands = 1 << 1,
General = byte.MaxValue
}

View File

@@ -0,0 +1,36 @@
using Robust.Shared.Audio;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary;
namespace Content.Shared.Chat.Prototypes;
/// <summary>
/// Sounds collection for each <see cref="EmotePrototype"/>.
/// Different entities may use different sounds collections.
/// </summary>
[Prototype("emoteSounds")]
public sealed class EmoteSoundsPrototype : IPrototype
{
[IdDataField]
public string ID { get; } = default!;
/// <summary>
/// Optional fallback sound that will play if collection
/// doesn't have specific sound for this emote id.
/// </summary>
[DataField("sound")]
public SoundSpecifier? FallbackSound;
/// <summary>
/// Optional audio params that will be applied to ALL sounds.
/// This will overwrite any params that may be set in sound specifiers.
/// </summary>
[DataField("params")]
public AudioParams? GeneralParams;
/// <summary>
/// Collection of emote prototypes and their sounds.
/// </summary>
[DataField("sounds", customTypeSerializer: typeof(PrototypeIdDictionarySerializer<SoundSpecifier, EmotePrototype>))]
public Dictionary<string, SoundSpecifier> Sounds = new();
}

View File

@@ -1,3 +1,5 @@
namespace Content.Shared.Chat;
public abstract class SharedChatSystem : EntitySystem {}
public abstract class SharedChatSystem : EntitySystem
{
}

View File

@@ -12,4 +12,10 @@ namespace Content.Shared.Humanoid
Female,
Unsexed,
}
/// <summary>
/// Raised when entity has changed their sex.
/// This doesn't handle gender changes.
/// </summary>
public record struct SexChangedEvent(Sex OldSex, Sex NewSex);
}

View File

@@ -197,4 +197,26 @@ public abstract class SharedHumanoidAppearanceSystem : EntitySystem
if (sync)
Dirty(humanoid);
}
/// <summary>
/// Set a humanoid mob's sex. This will not change their gender.
/// </summary>
/// <param name="uid">The humanoid mob's UID.</param>
/// <param name="sex">The sex to set the mob to.</param>
/// <param name="sync">Whether to immediately synchronize this to the humanoid mob, or not.</param>
/// <param name="humanoid">Humanoid component of the entity</param>
public void SetSex(EntityUid uid, Sex sex, bool sync = true, HumanoidAppearanceComponent? humanoid = null)
{
if (!Resolve(uid, ref humanoid) || humanoid.Sex == sex)
return;
var oldSex = humanoid.Sex;
humanoid.Sex = sex;
RaiseLocalEvent(uid, new SexChangedEvent(oldSex, sex));
if (sync)
{
Dirty(humanoid);
}
}
}

View File

@@ -1,3 +1,4 @@
using Content.Shared.Chat.Prototypes;
using Content.Shared.Roles;
using Content.Shared.Humanoid;
using Robust.Shared.GameStates;
@@ -80,5 +81,10 @@ namespace Content.Shared.Zombies
/// </summary>
[DataField("beforeZombifiedSkinColor")]
public Color BeforeZombifiedSkinColor;
[DataField("emoteId", customTypeSerializer: typeof(PrototypeIdSerializer<EmoteSoundsPrototype>))]
public string? EmoteSoundsId = "Zombie";
public EmoteSoundsPrototype? EmoteSounds;
}
}