diff --git a/Content.Server/Mobs/CritMobActionsSystem.cs b/Content.Server/Mobs/CritMobActionsSystem.cs index 1d0086c81e..e07ba82f66 100644 --- a/Content.Server/Mobs/CritMobActionsSystem.cs +++ b/Content.Server/Mobs/CritMobActionsSystem.cs @@ -5,9 +5,10 @@ using Content.Shared.Chat; using Content.Shared.Mobs; using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; +using Content.Shared.Speech.Muting; +using Content.Shared.StatusEffectNew; using Robust.Server.Console; using Robust.Shared.Player; -using Content.Shared.Speech.Muting; namespace Content.Server.Mobs; @@ -22,6 +23,7 @@ public sealed partial class CritMobActionsSystem : EntitySystem [Dependency] private MobStateSystem _mobState = default!; [Dependency] private PopupSystem _popupSystem = default!; [Dependency] private QuickDialogSystem _quickDialog = default!; + [Dependency] private StatusEffectsSystem _statusEffects = default!; private const int MaxLastWordsLength = 30; @@ -48,7 +50,7 @@ public sealed partial class CritMobActionsSystem : EntitySystem if (!_mobState.IsCritical(uid)) return; - if (HasComp(uid)) + if (_statusEffects.HasEffectComp(uid)) { _popupSystem.PopupEntity(Loc.GetString("fake-death-muted"), uid, uid); return; diff --git a/Content.Server/Mobs/DeathgaspSystem.cs b/Content.Server/Mobs/DeathgaspSystem.cs index 63e50acbcf..d3dffb6bac 100644 --- a/Content.Server/Mobs/DeathgaspSystem.cs +++ b/Content.Server/Mobs/DeathgaspSystem.cs @@ -1,6 +1,7 @@ -using Content.Server.Chat.Systems; +using Content.Server.Chat.Systems; using Content.Shared.Mobs; using Content.Shared.Speech.Muting; +using Content.Shared.StatusEffectNew; namespace Content.Server.Mobs; @@ -11,6 +12,7 @@ namespace Content.Server.Mobs; public sealed partial class DeathgaspSystem : EntitySystem { [Dependency] private ChatSystem _chat = default!; + [Dependency] private StatusEffectsSystem _statusEffects = default!; [SubscribeLocalEvent] private void OnMobStateChanged(Entity ent, ref MobStateChangedEvent args) @@ -30,7 +32,7 @@ public sealed partial class DeathgaspSystem : EntitySystem if (!Resolve(uid, ref component, false)) return false; - if (HasComp(uid)) + if (_statusEffects.HasEffectComp(uid)) return false; _chat.TryEmoteWithChat(uid, component.Prototype, ignoreActionBlocker: true); diff --git a/Content.Server/Puppet/VentriloquistPuppetSystem.cs b/Content.Server/Puppet/VentriloquistPuppetSystem.cs index 027449d431..1f2907d592 100644 --- a/Content.Server/Puppet/VentriloquistPuppetSystem.cs +++ b/Content.Server/Puppet/VentriloquistPuppetSystem.cs @@ -4,7 +4,8 @@ using Content.Shared.CombatMode; using Content.Shared.Hands; using Content.Shared.Interaction.Events; using Content.Shared.Puppet; -using Content.Shared.Speech.Muting; +using Content.Shared.StatusEffectNew; +using Robust.Shared.Prototypes; namespace Content.Server.Puppet; @@ -13,9 +14,10 @@ namespace Content.Server.Puppet; /// public sealed partial class VentriloquistPuppetSystem : SharedVentriloquistPuppetSystem { - [Dependency] private PopupSystem _popupSystem = default!; + public static readonly EntProtoId MutedEffect = "StatusEffectVentriloquistPuppetMuted"; - [Dependency] private EntityQuery _mutedQuery; + [Dependency] private PopupSystem _popupSystem = default!; + [Dependency] private StatusEffectsSystem _statusEffects = default!; /// /// When used user inserts hand into dummy and the dummy can speak, when used again the user removes hand @@ -31,7 +33,7 @@ public sealed partial class VentriloquistPuppetSystem : SharedVentriloquistPuppe // TODO disable dummy when the user dies or cannot interact. // Then again, this is all quite cursed code, so maybe its a cursed ventriloquist puppet. - if (!RemComp(ent)) + if (!_statusEffects.TryRemoveStatusEffect(ent, MutedEffect)) { _popupSystem.PopupEntity(Loc.GetString("ventriloquist-puppet-remove-hand"), ent, args.User); MuteDummy(ent); @@ -60,7 +62,7 @@ public sealed partial class VentriloquistPuppetSystem : SharedVentriloquistPuppe [SubscribeLocalEvent] private void OnDropped(Entity ent, ref DroppedEvent args) { - if (_mutedQuery.HasComp(ent)) + if (_statusEffects.HasStatusEffect(ent, MutedEffect)) return; _popupSystem.PopupEntity(Loc.GetString("ventriloquist-puppet-remove-hand"), ent, args.User); @@ -73,7 +75,7 @@ public sealed partial class VentriloquistPuppetSystem : SharedVentriloquistPuppe [SubscribeLocalEvent] private void OnUnequippedHand(Entity ent, ref GotUnequippedHandEvent args) { - if (_mutedQuery.HasComp(ent)) + if (_statusEffects.HasStatusEffect(ent, MutedEffect)) return; _popupSystem.PopupEntity(Loc.GetString("ventriloquist-puppet-remove-hand"), ent, args.User); @@ -86,7 +88,7 @@ public sealed partial class VentriloquistPuppetSystem : SharedVentriloquistPuppe private void MuteDummy(Entity ent) { _popupSystem.PopupEntity(Loc.GetString("ventriloquist-puppet-removed-hand"), ent, ent); - EnsureComp(ent); + _statusEffects.TrySetStatusEffectDuration(ent, MutedEffect); RemComp(ent); RemComp(ent); } diff --git a/Content.Shared/Abilities/Mime/MimePowersComponent.cs b/Content.Shared/Abilities/Mime/MimePowersComponent.cs index 8414dd7a0d..4486bc6ada 100644 --- a/Content.Shared/Abilities/Mime/MimePowersComponent.cs +++ b/Content.Shared/Abilities/Mime/MimePowersComponent.cs @@ -54,9 +54,6 @@ public sealed partial class MimePowersComponent : Component [DataField, AutoNetworkedField] public TimeSpan VowCooldown = TimeSpan.FromMinutes(5); - [DataField] - public ProtoId VowAlert = "VowOfSilence"; - [DataField] public ProtoId VowBrokenAlert = "VowBroken"; diff --git a/Content.Shared/Abilities/Mime/MimePowersSystem.cs b/Content.Shared/Abilities/Mime/MimePowersSystem.cs index 1eb107b426..6b10f47f59 100644 --- a/Content.Shared/Abilities/Mime/MimePowersSystem.cs +++ b/Content.Shared/Abilities/Mime/MimePowersSystem.cs @@ -7,18 +7,22 @@ using Content.Shared.IdentityManagement; using Content.Shared.Maps; using Content.Shared.Paper; using Content.Shared.Physics; -using Content.Shared.Speech.Muting; +using Content.Shared.StatusEffectNew; using Robust.Shared.Containers; using Robust.Shared.Map; +using Robust.Shared.Prototypes; using Robust.Shared.Timing; namespace Content.Shared.Abilities.Mime; public sealed partial class MimePowersSystem : EntitySystem { + public static readonly EntProtoId MutedEffect = "StatusEffectMimeMuted"; + [Dependency] private SharedPopupSystem _popupSystem = default!; [Dependency] private SharedActionsSystem _actionsSystem = default!; [Dependency] private AlertsSystem _alertsSystem = default!; + [Dependency] private StatusEffectsSystem _statusEffects = default!; [Dependency] private TurfSystem _turf = default!; [Dependency] private SharedContainerSystem _container = default!; [Dependency] private IGameTiming _timing = default!; @@ -27,7 +31,7 @@ public sealed partial class MimePowersSystem : EntitySystem { base.Initialize(); - SubscribeLocalEvent(OnComponentInit); + SubscribeLocalEvent(OnMapInit); SubscribeLocalEvent(OnComponentShutdown); SubscribeLocalEvent(OnInvisibleWall); @@ -55,9 +59,10 @@ public sealed partial class MimePowersSystem : EntitySystem } } - private void OnComponentInit(Entity ent, ref ComponentInit args) + private void OnMapInit(Entity ent, ref MapInitEvent args) { - EnsureComp(ent); + if (!ent.Comp.VowBroken) + _statusEffects.TrySetStatusEffectDuration(ent, MutedEffect); if (ent.Comp.PreventWriting) { @@ -66,12 +71,12 @@ public sealed partial class MimePowersSystem : EntitySystem Dirty(ent, illiterateComponent); } - _alertsSystem.ShowAlert(ent.Owner, ent.Comp.VowAlert); _actionsSystem.AddAction(ent, ref ent.Comp.InvisibleWallActionEntity, ent.Comp.InvisibleWallAction); } private void OnComponentShutdown(Entity ent, ref ComponentShutdown args) { + _statusEffects.TryRemoveStatusEffect(ent, MutedEffect); _actionsSystem.RemoveAction(ent.Owner, ent.Comp.InvisibleWallActionEntity); } @@ -144,11 +149,10 @@ public sealed partial class MimePowersSystem : EntitySystem mimePowers.VowBroken = true; mimePowers.VowRepentTime = _timing.CurTime + mimePowers.VowCooldown; Dirty(uid, mimePowers); - RemComp(uid); + _statusEffects.TryRemoveStatusEffect(uid, MutedEffect); if (mimePowers.PreventWriting) RemComp(uid); - _alertsSystem.ClearAlert(uid, mimePowers.VowAlert); _alertsSystem.ShowAlert(uid, mimePowers.VowBrokenAlert); _actionsSystem.RemoveAction(uid, mimePowers.InvisibleWallActionEntity); } @@ -171,7 +175,7 @@ public sealed partial class MimePowersSystem : EntitySystem mimePowers.ReadyToRepent = false; mimePowers.VowBroken = false; Dirty(uid, mimePowers); - AddComp(uid); + _statusEffects.TrySetStatusEffectDuration(uid, MutedEffect); if (mimePowers.PreventWriting) { EnsureComp(uid, out var illiterateComponent); @@ -180,7 +184,6 @@ public sealed partial class MimePowersSystem : EntitySystem } _alertsSystem.ClearAlert(uid, mimePowers.VowBrokenAlert); - _alertsSystem.ShowAlert(uid, mimePowers.VowAlert); _actionsSystem.AddAction(uid, ref mimePowers.InvisibleWallActionEntity, mimePowers.InvisibleWallAction, uid); } } diff --git a/Content.Shared/ActionBlocker/ActionBlockerSystem.cs b/Content.Shared/ActionBlocker/ActionBlockerSystem.cs index 578cb14803..46ca5ffcb0 100644 --- a/Content.Shared/ActionBlocker/ActionBlockerSystem.cs +++ b/Content.Shared/ActionBlocker/ActionBlockerSystem.cs @@ -141,6 +141,11 @@ namespace Content.Shared.ActionBlocker return !itemEv.Cancelled; } + /// + /// Whether a player is able to speak. + /// This only checks if something blocks them from speaking, not if they had the ability to do so in the first place. + /// + /// The mob to check. public bool CanSpeak(EntityUid uid) { // This one is used as broadcast diff --git a/Content.Shared/Magic/SharedMagicSystem.cs b/Content.Shared/Magic/SharedMagicSystem.cs index 17d366985b..4b7e4bd7e5 100644 --- a/Content.Shared/Magic/SharedMagicSystem.cs +++ b/Content.Shared/Magic/SharedMagicSystem.cs @@ -1,4 +1,5 @@ using System.Numerics; +using Content.Shared.ActionBlocker; using Content.Shared.Charges.Components; using Content.Shared.Charges.Systems; using Content.Shared.Coordinates.Helpers; @@ -48,6 +49,7 @@ public abstract partial class SharedMagicSystem : EntitySystem [Dependency] private ISerializationManager _seriMan = default!; [Dependency] private SharedMapSystem _mapSystem = default!; [Dependency] private IRobustRandom _random = default!; + [Dependency] private ActionBlockerSystem _actionBlocker = default!; [Dependency] private SharedGunSystem _gunSystem = default!; [Dependency] private SharedPhysicsSystem _physics = default!; [Dependency] private SharedTransformSystem _transform = default!; @@ -109,7 +111,7 @@ public abstract partial class SharedMagicSystem : EntitySystem } } - if (comp.RequiresSpeech && HasComp(args.Performer)) + if (comp.RequiresSpeech && !_actionBlocker.CanSpeak(args.Performer)) hasReqs = false; if (hasReqs) diff --git a/Content.Shared/Speech/EntitySystems/SpeakOnActionSystem.cs b/Content.Shared/Speech/EntitySystems/SpeakOnActionSystem.cs index 6880ef9edf..2df4b269b8 100644 --- a/Content.Shared/Speech/EntitySystems/SpeakOnActionSystem.cs +++ b/Content.Shared/Speech/EntitySystems/SpeakOnActionSystem.cs @@ -1,12 +1,13 @@ using Content.Shared.Speech.Components; using Content.Shared.Actions.Events; +using Content.Shared.ActionBlocker; using Content.Shared.Chat; -using Content.Shared.Speech.Muting; namespace Content.Shared.Speech.EntitySystems; public sealed partial class SpeakOnActionSystem : EntitySystem { + [Dependency] private ActionBlockerSystem _actionBlocker = default!; [Dependency] private SharedChatSystem _chat = default!; [SubscribeLocalEvent] @@ -15,7 +16,7 @@ public sealed partial class SpeakOnActionSystem : EntitySystem var user = args.Performer; // If we can't speak, we can't speak. - if (!HasComp(user) || HasComp(user)) + if (!HasComp(user) || !_actionBlocker.CanSpeak(user)) return; if (string.IsNullOrWhiteSpace(ent.Comp.Sentence)) diff --git a/Content.Shared/Speech/Muting/MutedComponent.cs b/Content.Shared/Speech/Muting/MutedComponent.cs deleted file mode 100644 index 46e5f2cbd8..0000000000 --- a/Content.Shared/Speech/Muting/MutedComponent.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Robust.Shared.GameStates; - -namespace Content.Shared.Speech.Muting -{ - [RegisterComponent, NetworkedComponent] - public sealed partial class MutedComponent : Component - { - - } -} diff --git a/Content.Shared/Speech/Muting/MutedStatusEffectComponent.cs b/Content.Shared/Speech/Muting/MutedStatusEffectComponent.cs new file mode 100644 index 0000000000..8acc1cc357 --- /dev/null +++ b/Content.Shared/Speech/Muting/MutedStatusEffectComponent.cs @@ -0,0 +1,22 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Speech.Muting; + +/// +/// Marks a status effect that prevents speaking, screaming, and vocal emotes. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class MutedStatusEffectComponent : Component +{ + /// + /// Popup shown when speech is blocked. + /// + [DataField, AutoNetworkedField] + public LocId SpeakPopup = "speech-muted"; + + /// + /// Popup shown when screaming is blocked. + /// + [DataField, AutoNetworkedField] + public LocId ActionPopup = "speech-muted"; +} diff --git a/Content.Shared/Speech/Muting/MutedStatusEffectSystem.cs b/Content.Shared/Speech/Muting/MutedStatusEffectSystem.cs new file mode 100644 index 0000000000..775c16e42f --- /dev/null +++ b/Content.Shared/Speech/Muting/MutedStatusEffectSystem.cs @@ -0,0 +1,62 @@ +using Content.Shared.Chat; +using Content.Shared.Chat.Prototypes; +using Content.Shared.Popups; +using Content.Shared.StatusEffectNew; +using Content.Shared.StatusEffectNew.Components; + +namespace Content.Shared.Speech.Muting; + +/// +/// Handles the speech restrictions imposed by . +/// +public sealed partial class MutedStatusEffectSystem : EntitySystem +{ + [Dependency] private SharedPopupSystem _popup = default!; + + /// + public override void Initialize() + { + SubscribeLocalEvent>(OnSpeakAttempt); + SubscribeLocalEvent>(OnEmote); + SubscribeLocalEvent>(OnEmoteAction); + } + + private void OnEmote(Entity ent, ref StatusEffectRelayedEvent args) + { + if (args.Args.Handled) + return; + + // Still leaves the text so it looks like they are pantomiming a laugh. + if (args.Args.Emote.Category.HasFlag(EmoteCategory.Vocal)) + { + args.Args = args.Args with { Handled = true }; + } + } + + private void OnEmoteAction(Entity ent, ref StatusEffectRelayedEvent args) + { + if (args.Args.Handled) + return; + + if (!TryComp(ent, out var statusEffect)) + return; + + if (statusEffect.AppliedTo is not { } target) + return; + + _popup.PopupEntity(Loc.GetString(ent.Comp.ActionPopup), target, target); + args.Args.Handled = true; + } + + private void OnSpeakAttempt(Entity ent, ref StatusEffectRelayedEvent args) + { + if (args.Args.Cancelled) + return; + + var target = args.Args.Uid; + + _popup.PopupEntity(Loc.GetString(ent.Comp.SpeakPopup), target, target); + + args.Args.Cancel(); + } +} diff --git a/Content.Shared/Speech/Muting/MutingSystem.cs b/Content.Shared/Speech/Muting/MutingSystem.cs deleted file mode 100644 index 2b54e5c332..0000000000 --- a/Content.Shared/Speech/Muting/MutingSystem.cs +++ /dev/null @@ -1,72 +0,0 @@ -using Content.Shared.Abilities.Mime; -using Content.Shared.Chat; -using Content.Shared.Chat.Prototypes; -using Content.Shared.Popups; -using Content.Shared.Puppet; -using Content.Shared.Speech.EntitySystems; - -namespace Content.Shared.Speech.Muting; - -/// -/// A system to prevent muted characters from talking. -/// -/// -public sealed partial class MutingSystem : EntitySystem -{ - [Dependency] private SharedPopupSystem _popup = default!; - - [Dependency] private EntityQuery _mimePowersQuery; - [Dependency] private EntityQuery _puppetQuery; - - /// - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent(OnEmote, before: new[] { typeof(VocalSystem), typeof(MumbleAccentSystem) }); - SubscribeLocalEvent(OnEmoteAction, before: new[] { typeof(VocalSystem) }); - } - - private void OnEmote(Entity ent, ref EmoteEvent args) - { - if (args.Handled) - return; - - //still leaves the text so it looks like they are pantomiming a laugh - if (args.Emote.Category.HasFlag(EmoteCategory.Vocal)) - args.Handled = true; - } - - private void OnEmoteAction(Entity ent, ref EmoteActionEvent args) - { - if (args.Handled) - return; - - if (!ProtoMan.Resolve(args.Emote, out var emote)) - return; - - if (!emote.Category.HasFlag(EmoteCategory.Vocal)) - return; - - if (_mimePowersQuery.HasComp(ent)) - _popup.PopupEntity(Loc.GetString("mime-cant-speak"), ent, ent); - else - _popup.PopupEntity(Loc.GetString("speech-muted"), ent, ent); - - args.Handled = true; - } - - [SubscribeLocalEvent] - private void OnSpeakAttempt(Entity ent, ref SpeakAttemptEvent args) - { - // TODO something better than this. - if (_mimePowersQuery.HasComp(ent)) - _popup.PopupEntity(Loc.GetString("mime-cant-speak"), ent, ent); - else if (_puppetQuery.HasComp(ent)) - _popup.PopupEntity(Loc.GetString("ventriloquist-puppet-cant-speak"), ent, ent); - else - _popup.PopupEntity(Loc.GetString("speech-muted"), ent, ent); - - args.Cancel(); - } -} diff --git a/Content.Shared/StatusEffectNew/Components/PermanentStatusEffectsComponent.cs b/Content.Shared/StatusEffectNew/Components/PermanentStatusEffectsComponent.cs new file mode 100644 index 0000000000..1ded016cdb --- /dev/null +++ b/Content.Shared/StatusEffectNew/Components/PermanentStatusEffectsComponent.cs @@ -0,0 +1,17 @@ +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.StatusEffectNew.Components; + +/// +/// Applies a set of permanent status effects while this component exists. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class PermanentStatusEffectsComponent : Component +{ + /// + /// The status effects to apply. + /// + [DataField(required: true)] + public HashSet StatusEffects = new(); +} diff --git a/Content.Shared/StatusEffectNew/PermanentStatusEffectsSystem.cs b/Content.Shared/StatusEffectNew/PermanentStatusEffectsSystem.cs new file mode 100644 index 0000000000..a6d28899d3 --- /dev/null +++ b/Content.Shared/StatusEffectNew/PermanentStatusEffectsSystem.cs @@ -0,0 +1,30 @@ +using Content.Shared.StatusEffectNew.Components; + +namespace Content.Shared.StatusEffectNew; + +/// +/// Keeps permanent status effects from applied +/// for as long as the owning component exists. +/// +public sealed partial class PermanentStatusEffectsSystem : EntitySystem +{ + [Dependency] private StatusEffectsSystem _statusEffects = default!; + + [SubscribeLocalEvent] + private void OnMapInit(Entity ent, ref MapInitEvent args) + { + foreach (var effect in ent.Comp.StatusEffects) + { + _statusEffects.TrySetStatusEffectDuration(ent, effect); + } + } + + [SubscribeLocalEvent] + private void OnRemove(Entity ent, ref ComponentRemove args) + { + foreach (var effect in ent.Comp.StatusEffects) + { + _statusEffects.TryRemoveStatusEffect(ent, effect); + } + } +} diff --git a/Content.Shared/StatusEffectNew/StatusEffectSystem.Relay.cs b/Content.Shared/StatusEffectNew/StatusEffectSystem.Relay.cs index 4ae1562c8e..e7b009ac69 100644 --- a/Content.Shared/StatusEffectNew/StatusEffectSystem.Relay.cs +++ b/Content.Shared/StatusEffectNew/StatusEffectSystem.Relay.cs @@ -1,14 +1,16 @@ using Content.Shared.Body.Events; +using Content.Shared.Chat; using Content.Shared.Damage.Events; using Content.Shared.Damage.Systems; using Content.Shared.Eye.Blinding.Systems; using Content.Shared.Flash; -using Content.Shared.Mobs.Events; using Content.Shared.Mobs; +using Content.Shared.Mobs.Events; using Content.Shared.Movement.Events; using Content.Shared.Movement.Systems; using Content.Shared.Rejuvenate; using Content.Shared.Speech; +using Content.Shared.Speech.EntitySystems; using Content.Shared.StatusEffectNew.Components; using Content.Shared.Stunnable; using Robust.Shared.Player; @@ -40,8 +42,11 @@ public sealed partial class StatusEffectsSystem SubscribeLocalEvent(RelayStatusEffectEvent); SubscribeLocalEvent(RelayStatusEffectEvent); + SubscribeLocalEvent(RelayStatusEffectEvent); + SubscribeLocalEvent(RelayStatusEffectEvent, before: new[] { typeof(VocalSystem) }); SubscribeLocalEvent(RefRelayStatusEffectEvent); + SubscribeLocalEvent(RefRelayStatusEffectEvent, before: new[] { typeof(VocalSystem), typeof(MumbleAccentSystem) }); SubscribeLocalEvent(RefRelayStatusEffectEvent); SubscribeLocalEvent(RelayStatusEffectEvent); diff --git a/Resources/Locale/en-US/guidebook/entity-effects/statuseffects.ftl b/Resources/Locale/en-US/guidebook/entity-effects/statuseffects.ftl index c99d8d3d07..ea0706fea1 100644 --- a/Resources/Locale/en-US/guidebook/entity-effects/statuseffects.ftl +++ b/Resources/Locale/en-US/guidebook/entity-effects/statuseffects.ftl @@ -2,7 +2,6 @@ entity-effect-status-effect-KnockedDown = knockdown entity-effect-status-effect-Jitter = jittering entity-effect-status-effect-SeeingRainbows = hallucinations -entity-effect-status-effect-Muted = inability to speak entity-effect-status-effect-Stutter = stuttering entity-effect-status-effect-ForcedSleep = unconsciousness entity-effect-status-effect-Drunk = drunkenness diff --git a/Resources/Prototypes/Body/species_base.yml b/Resources/Prototypes/Body/species_base.yml index 6428ddb87e..fead1ffeca 100644 --- a/Resources/Prototypes/Body/species_base.yml +++ b/Resources/Prototypes/Body/species_base.yml @@ -73,7 +73,6 @@ allowed: - Electrocution - PressureImmunity - - Muted - Pacified - Flashed - Adrenaline diff --git a/Resources/Prototypes/Entities/Mobs/Player/clone.yml b/Resources/Prototypes/Entities/Mobs/Player/clone.yml index 8e26fe9cdb..1a7170cb7b 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/clone.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/clone.yml @@ -21,7 +21,6 @@ - Narcolepsy - ImpairedMobility # - LegsParalyzed (you get healed) - - Muted - PermanentBlindness - Snoring - Unrevivable diff --git a/Resources/Prototypes/Entities/Objects/Devices/pda.yml b/Resources/Prototypes/Entities/Objects/Devices/pda.yml index b84efe64c3..9d04ecf468 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/pda.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/pda.yml @@ -431,13 +431,15 @@ accentHColor: "#333333" - type: Icon state: pda-mime - - type: Muted # for random sentience event - type: EntityTableContainerFill containers: preinstalled-program-container: !type:AllSelector children: - id: CrewManifestCartridge - id: NewsReaderCartridge + - type: PermanentStatusEffects # for random sentience event + statusEffects: + - TraitStatusEffectMuted - type: entity name: chaplain PDA diff --git a/Resources/Prototypes/Entities/Objects/Fun/toys.yml b/Resources/Prototypes/Entities/Objects/Fun/toys.yml index ce3eaa20aa..2f49bea864 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/toys.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/toys.yml @@ -167,7 +167,9 @@ - type: VentriloquistPuppet - type: Item size: Normal - - type: Muted + - type: PermanentStatusEffects + statusEffects: + - StatusEffectVentriloquistPuppetMuted - type: TypingIndicator proto: robot - type: Actions diff --git a/Resources/Prototypes/Entities/StatusEffects/misc.yml b/Resources/Prototypes/Entities/StatusEffects/misc.yml index 536b4910dc..1451c2a2e8 100644 --- a/Resources/Prototypes/Entities/StatusEffects/misc.yml +++ b/Resources/Prototypes/Entities/StatusEffects/misc.yml @@ -63,6 +63,38 @@ - type: StunnedStatusEffect - type: KnockdownStatusEffect +# Prevents speaking and vocal emotes. +- type: entity + abstract: true + parent: MobStatusEffectBase + id: MutedStatusEffectBase + name: muted + components: + - type: StatusEffectAlert + alert: Muted + - type: MutedStatusEffect + +- type: entity + parent: [ MutedStatusEffectBase, MobStatusEffectDebuff ] + id: StatusEffectMuted + +- type: entity + parent: MutedStatusEffectBase + id: StatusEffectMimeMuted + components: + - type: StatusEffectAlert + alert: VowOfSilence + - type: MutedStatusEffect + speakPopup: mime-cant-speak + actionPopup: mime-cant-speak + +- type: entity + parent: MutedStatusEffectBase + id: StatusEffectVentriloquistPuppetMuted + components: + - type: MutedStatusEffect + speakPopup: ventriloquist-puppet-cant-speak + # Blurs your vision and makes you randomly fall asleep - type: entity parent: MobStatusEffectDebuff diff --git a/Resources/Prototypes/Entities/StatusEffects/traits.yml b/Resources/Prototypes/Entities/StatusEffects/traits.yml index c65933a26b..9ccf41e286 100644 --- a/Resources/Prototypes/Entities/StatusEffects/traits.yml +++ b/Resources/Prototypes/Entities/StatusEffects/traits.yml @@ -22,3 +22,6 @@ id: TraitStatusEffectPainNumbness name: pain numbness +- type: entity + parent: [ MutedStatusEffectBase, TraitStatusEffectBase ] + id: TraitStatusEffectMuted diff --git a/Resources/Prototypes/Reagents/Consumable/Drink/alcohol.yml b/Resources/Prototypes/Reagents/Consumable/Drink/alcohol.yml index 7dbdbafcdd..5535c3c9bf 100644 --- a/Resources/Prototypes/Reagents/Consumable/Drink/alcohol.yml +++ b/Resources/Prototypes/Reagents/Consumable/Drink/alcohol.yml @@ -1540,9 +1540,8 @@ metabolisms: Digestion: effects: - - !type:GenericStatusEffect - key: Muted - component: Muted + - !type:ModifyStatusEffect + effectProto: StatusEffectMuted - !type:SatiateThirst factor: 2 @@ -2051,9 +2050,8 @@ metabolites: Ethanol: 0.14 effects: - - !type:GenericStatusEffect - key: Muted - component: Muted + - !type:ModifyStatusEffect + effectProto: StatusEffectMuted - !type:SatiateThirst factor: 2 diff --git a/Resources/Prototypes/Reagents/cleaning.yml b/Resources/Prototypes/Reagents/cleaning.yml index 51d3d5a6a1..0ac63ee0a6 100644 --- a/Resources/Prototypes/Reagents/cleaning.yml +++ b/Resources/Prototypes/Reagents/cleaning.yml @@ -123,9 +123,8 @@ type: Add Digestion: effects: - - !type:GenericStatusEffect - key: Muted - component: Muted + - !type:ModifyStatusEffect + effectProto: StatusEffectMuted time: 5 footstepSound: collection: FootstepSlime diff --git a/Resources/Prototypes/Reagents/narcotics.yml b/Resources/Prototypes/Reagents/narcotics.yml index 87828bc000..66c26c425f 100644 --- a/Resources/Prototypes/Reagents/narcotics.yml +++ b/Resources/Prototypes/Reagents/narcotics.yml @@ -343,9 +343,8 @@ metabolisms: Bloodstream: effects: - - !type:GenericStatusEffect - key: Muted - component: Muted + - !type:ModifyStatusEffect + effectProto: StatusEffectMuted type: Add time: 10 diff --git a/Resources/Prototypes/Traits/disabilities.yml b/Resources/Prototypes/Traits/disabilities.yml index de3e93223b..7909a50b54 100644 --- a/Resources/Prototypes/Traits/disabilities.yml +++ b/Resources/Prototypes/Traits/disabilities.yml @@ -62,8 +62,10 @@ blacklist: components: - BorgChassis - components: - - type: Muted + specials: + - !type:ApplyStatusEffectSpecial + statusEffects: + - TraitStatusEffectMuted - type: trait id: Paracusia diff --git a/Resources/Prototypes/status_effects.yml b/Resources/Prototypes/status_effects.yml index e8eaf67c64..e23a83912c 100644 --- a/Resources/Prototypes/status_effects.yml +++ b/Resources/Prototypes/status_effects.yml @@ -30,10 +30,6 @@ - type: statusEffect id: PressureImmunity -- type: statusEffect - id: Muted - alert: Muted - - type: statusEffect id: Corporeal alert: Corporeal