diff --git a/Content.Client/Chat/UI/EmotesMenu.xaml.cs b/Content.Client/Chat/UI/EmotesMenu.xaml.cs index f3b7837f21a5..70a05316e841 100644 --- a/Content.Client/Chat/UI/EmotesMenu.xaml.cs +++ b/Content.Client/Chat/UI/EmotesMenu.xaml.cs @@ -43,7 +43,8 @@ public EmotesMenu() if (!emote.Available && _entManager.TryGetComponent(player.Value, out var speech) && - !speech.AllowedEmotes.Contains(emote.ID)) + !speech.AllowedEmotes.Contains(emote.ID) && + !speech.ClothingEmotes.Contains(emote.ID)) //SS220 Clothing special emotes continue; var parent = FindControl(emote.Category.ToString()); diff --git a/Content.Server/Chat/Systems/ChatSystem.Emote.cs b/Content.Server/Chat/Systems/ChatSystem.Emote.cs index ba89ae09ff00..c0faf5d0a82d 100644 --- a/Content.Server/Chat/Systems/ChatSystem.Emote.cs +++ b/Content.Server/Chat/Systems/ChatSystem.Emote.cs @@ -218,7 +218,8 @@ private bool AllowedToUseEmote(EntityUid source, EmotePrototype emote) if (!emote.Available && TryComp(source, out var speech) && - !speech.AllowedEmotes.Contains(emote.ID)) + !speech.AllowedEmotes.Contains(emote.ID) && + !speech.ClothingEmotes.Contains(emote.ID)) //SS220 Clothing special emotes return false; return true; diff --git a/Content.Server/SS220/Speech/Components/ClothingSpecialEmotesComponent.cs b/Content.Server/SS220/Speech/Components/ClothingSpecialEmotesComponent.cs new file mode 100644 index 000000000000..2afabaa713bb --- /dev/null +++ b/Content.Server/SS220/Speech/Components/ClothingSpecialEmotesComponent.cs @@ -0,0 +1,19 @@ +// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt +using Content.Shared.Chat.Prototypes; +using Robust.Shared.Prototypes; + +namespace Content.Server.SS220.Speech.Components; + +/// +/// Allows you to use some emotions when equipped clothing with this component. +/// Must be used with in order for emotions to be voiced. +/// +[RegisterComponent] +public sealed partial class ClothingSpecialEmotesComponent : Component +{ + /// + /// List of emotions that can be used with these clothing + /// + [DataField] + public List> Emotes = new(); +} diff --git a/Content.Server/SS220/Speech/EntitySystems/ClothingSpecialEmotesSystem.cs b/Content.Server/SS220/Speech/EntitySystems/ClothingSpecialEmotesSystem.cs new file mode 100644 index 000000000000..901e50480302 --- /dev/null +++ b/Content.Server/SS220/Speech/EntitySystems/ClothingSpecialEmotesSystem.cs @@ -0,0 +1,72 @@ +// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt +using Content.Server.SS220.Speech.Components; +using Content.Shared.Chat.Prototypes; +using Content.Shared.Inventory; +using Content.Shared.Inventory.Events; +using Content.Shared.Speech; +using Robust.Shared.Prototypes; +using Robust.Shared.Utility; + +namespace Content.Server.SS220.Speech.EntitySystems; + +public sealed partial class ClothingSpecialEmotesSystem : EntitySystem +{ + [Dependency] private readonly InventorySystem _inventory = default!; + + private Dictionary>> _temporaryEmotes = new(); + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnEquipped); + SubscribeLocalEvent(OnUnequipped); + } + + private void OnEquipped(Entity entity, ref GotEquippedEvent args) + { + if (entity.Comp.Emotes.Count <= 0 || + !TryComp(args.Equipee, out var speech)) + return; + + foreach (var newEmote in entity.Comp.Emotes) + { + if (speech.AllowedEmotes.Contains(newEmote)) + continue; + + _temporaryEmotes.GetOrNew(entity.Owner).Add(newEmote); + if (!speech.ClothingEmotes.Contains(newEmote)) + speech.ClothingEmotes.Add(newEmote); + } + Dirty(args.Equipee, speech); + } + + private void OnUnequipped(Entity entity, ref GotUnequippedEvent args) + { + if (!_temporaryEmotes.TryGetValue(entity.Owner, out var toRemove) || + !TryComp(args.Equipee, out var speech)) + return; + + //doesn't remove emotion if equipee has other clothes that give it + var slotEnumerator = _inventory.GetSlotEnumerator(args.Equipee); + while (slotEnumerator.NextItem(out var item)) + { + if (item == entity.Owner || + !_temporaryEmotes.TryGetValue(item, out var itemEmotes)) + continue; + + foreach (var itemEmote in itemEmotes) + { + toRemove.Remove(itemEmote); + } + } + + foreach (var emote in toRemove) + { + speech.ClothingEmotes.Remove(emote); + } + + _temporaryEmotes.Remove(entity.Owner); + Dirty(args.Equipee, speech); + } +} diff --git a/Content.Shared/Speech/SpeechComponent.cs b/Content.Shared/Speech/SpeechComponent.cs index e98fa3a2955f..87f0f385ea01 100644 --- a/Content.Shared/Speech/SpeechComponent.cs +++ b/Content.Shared/Speech/SpeechComponent.cs @@ -34,6 +34,15 @@ public sealed partial class SpeechComponent : Component [DataField] public List> AllowedEmotes = new(); + //SS220 Clothing special emotes begin + /// + /// What emotions allowed to use with special clothing + /// + [ViewVariables(VVAccess.ReadWrite)] + [DataField, AutoNetworkedField] + public List> ClothingEmotes = new(); + //SS220 Clothing special emotes end + /// /// A mapping from chat suffixes loc strings to speech verb prototypes that should be conditionally used. /// For things like '?' changing to 'asks' or '!!' making text bold and changing to 'yells'. Can be overridden if necessary. diff --git a/Resources/Prototypes/Entities/Clothing/Head/misc.yml b/Resources/Prototypes/Entities/Clothing/Head/misc.yml index 44c4eff5db18..54f7dfcf240c 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/misc.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/misc.yml @@ -196,6 +196,11 @@ Female: FemaleFelinid Unsexed: MaleFelinid #ss220 special_sounds end + #SS220 clothing special emotes begin + - type: ClothingSpecialEmotes + emotes: ['Meow', 'Mew', 'Growl', 'Purr', 'Hiss'] + #SS220 clothing special emotes end + - type: entity parent: [ClothingHeadHatCatEars, BaseToggleClothing] diff --git a/Resources/Prototypes/Entities/Clothing/Neck/cloaks.yml b/Resources/Prototypes/Entities/Clothing/Neck/cloaks.yml index 6368b9b7d9a1..3142787d3a68 100644 --- a/Resources/Prototypes/Entities/Clothing/Neck/cloaks.yml +++ b/Resources/Prototypes/Entities/Clothing/Neck/cloaks.yml @@ -205,6 +205,10 @@ Female: UnisexMoth Unsexed: UnisexMoth #ss220 special_sounds end + #SS220 clothing special emotes begin + - type: ClothingSpecialEmotes + emotes: ['Chitter', 'Squeak'] + #SS220 clothing special emotes end - type: entity parent: ClothingNeckBase