Muted StatusEffects (#43668)

* MutedStatusEffects

* Update species_base.yml

* System

* refactor

* yml fix

* fix component

* review

* fix yml

* Update disabilities.yml

* StatusEffectMuted -> TraitStatusEffectMuted

* Update misc.yml

* merge

* RemoveStatusEffect

* more review

* cleanup

* merge

* oops

* Send it

---------

Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
Co-authored-by: AJCM-git <ajcm_mail@disroot.org>
This commit is contained in:
Pok 2026-07-30 06:52:56 +03:00 • committed by GitHub
parent 5781283a9c
commit b38e363d41
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 230 additions and 132 deletions

View file

@ -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<MutedComponent>(uid))
if (_statusEffects.HasEffectComp<MutedStatusEffectComponent>(uid))
{
_popupSystem.PopupEntity(Loc.GetString("fake-death-muted"), uid, uid);
return;

View file

@ -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<DeathgaspComponent> ent, ref MobStateChangedEvent args)
@ -30,7 +32,7 @@ public sealed partial class DeathgaspSystem : EntitySystem
if (!Resolve(uid, ref component, false))
return false;
if (HasComp<MutedComponent>(uid))
if (_statusEffects.HasEffectComp<MutedStatusEffectComponent>(uid))
return false;
_chat.TryEmoteWithChat(uid, component.Prototype, ignoreActionBlocker: true);

View file

@ -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;
/// </summary>
public sealed partial class VentriloquistPuppetSystem : SharedVentriloquistPuppetSystem
{
[Dependency] private PopupSystem _popupSystem = default!;
public static readonly EntProtoId MutedEffect = "StatusEffectVentriloquistPuppetMuted";
[Dependency] private EntityQuery<MutedComponent> _mutedQuery;
[Dependency] private PopupSystem _popupSystem = default!;
[Dependency] private StatusEffectsSystem _statusEffects = default!;
/// <summary>
/// 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<MutedComponent>(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<VentriloquistPuppetComponent> 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<VentriloquistPuppetComponent> 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<VentriloquistPuppetComponent> ent)
{
_popupSystem.PopupEntity(Loc.GetString("ventriloquist-puppet-removed-hand"), ent, ent);
EnsureComp<MutedComponent>(ent);
_statusEffects.TrySetStatusEffectDuration(ent, MutedEffect);
RemComp<CombatModeComponent>(ent);
RemComp<GhostTakeoverAvailableComponent>(ent);
}

View file

@ -54,9 +54,6 @@ public sealed partial class MimePowersComponent : Component
[DataField, AutoNetworkedField]
public TimeSpan VowCooldown = TimeSpan.FromMinutes(5);
[DataField]
public ProtoId<AlertPrototype> VowAlert = "VowOfSilence";
[DataField]
public ProtoId<AlertPrototype> VowBrokenAlert = "VowBroken";

View file

@ -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<MimePowersComponent, ComponentInit>(OnComponentInit);
SubscribeLocalEvent<MimePowersComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<MimePowersComponent, ComponentShutdown>(OnComponentShutdown);
SubscribeLocalEvent<MimePowersComponent, InvisibleWallActionEvent>(OnInvisibleWall);
@ -55,9 +59,10 @@ public sealed partial class MimePowersSystem : EntitySystem
}
}
private void OnComponentInit(Entity<MimePowersComponent> ent, ref ComponentInit args)
private void OnMapInit(Entity<MimePowersComponent> ent, ref MapInitEvent args)
{
EnsureComp<MutedComponent>(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<MimePowersComponent> 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<MutedComponent>(uid);
_statusEffects.TryRemoveStatusEffect(uid, MutedEffect);
if (mimePowers.PreventWriting)
RemComp<BlockWritingComponent>(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<MutedComponent>(uid);
_statusEffects.TrySetStatusEffectDuration(uid, MutedEffect);
if (mimePowers.PreventWriting)
{
EnsureComp<BlockWritingComponent>(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);
}
}

View file

@ -141,6 +141,11 @@ namespace Content.Shared.ActionBlocker
return !itemEv.Cancelled;
}
/// <summary>
/// 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.
/// </summary>
/// <param name="uid">The mob to check.</param>
public bool CanSpeak(EntityUid uid)
{
// This one is used as broadcast

View file

@ -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<MutedComponent>(args.Performer))
if (comp.RequiresSpeech && !_actionBlocker.CanSpeak(args.Performer))
hasReqs = false;
if (hasReqs)

View file

@ -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<SpeechComponent>(user) || HasComp<MutedComponent>(user))
if (!HasComp<SpeechComponent>(user) || !_actionBlocker.CanSpeak(user))
return;
if (string.IsNullOrWhiteSpace(ent.Comp.Sentence))

View file

@ -1,10 +0,0 @@
using Robust.Shared.GameStates;
namespace Content.Shared.Speech.Muting
{
[RegisterComponent, NetworkedComponent]
public sealed partial class MutedComponent : Component
{
}
}

View file

@ -0,0 +1,22 @@
using Robust.Shared.GameStates;
namespace Content.Shared.Speech.Muting;
/// <summary>
/// Marks a status effect that prevents speaking, screaming, and vocal emotes.
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class MutedStatusEffectComponent : Component
{
/// <summary>
/// Popup shown when speech is blocked.
/// </summary>
[DataField, AutoNetworkedField]
public LocId SpeakPopup = "speech-muted";
/// <summary>
/// Popup shown when screaming is blocked.
/// </summary>
[DataField, AutoNetworkedField]
public LocId ActionPopup = "speech-muted";
}

View file

@ -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;
/// <summary>
/// Handles the speech restrictions imposed by <see cref="MutedStatusEffectComponent"/>.
/// </summary>
public sealed partial class MutedStatusEffectSystem : EntitySystem
{
[Dependency] private SharedPopupSystem _popup = default!;
/// <inheritdoc />
public override void Initialize()
{
SubscribeLocalEvent<MutedStatusEffectComponent, StatusEffectRelayedEvent<SpeakAttemptEvent>>(OnSpeakAttempt);
SubscribeLocalEvent<MutedStatusEffectComponent, StatusEffectRelayedEvent<EmoteEvent>>(OnEmote);
SubscribeLocalEvent<MutedStatusEffectComponent, StatusEffectRelayedEvent<EmoteActionEvent>>(OnEmoteAction);
}
private void OnEmote(Entity<MutedStatusEffectComponent> ent, ref StatusEffectRelayedEvent<EmoteEvent> 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<MutedStatusEffectComponent> ent, ref StatusEffectRelayedEvent<EmoteActionEvent> args)
{
if (args.Args.Handled)
return;
if (!TryComp<StatusEffectComponent>(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<MutedStatusEffectComponent> ent, ref StatusEffectRelayedEvent<SpeakAttemptEvent> args)
{
if (args.Args.Cancelled)
return;
var target = args.Args.Uid;
_popup.PopupEntity(Loc.GetString(ent.Comp.SpeakPopup), target, target);
args.Args.Cancel();
}
}

View file

@ -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;
/// <summary>
/// A system to prevent muted characters from talking.
/// </summary>
/// <seealso cref="MutedComponent"/>
public sealed partial class MutingSystem : EntitySystem
{
[Dependency] private SharedPopupSystem _popup = default!;
[Dependency] private EntityQuery<MimePowersComponent> _mimePowersQuery;
[Dependency] private EntityQuery<VentriloquistPuppetComponent> _puppetQuery;
/// <inheritdoc />
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<MutedComponent, EmoteEvent>(OnEmote, before: new[] { typeof(VocalSystem), typeof(MumbleAccentSystem) });
SubscribeLocalEvent<MutedComponent, EmoteActionEvent>(OnEmoteAction, before: new[] { typeof(VocalSystem) });
}
private void OnEmote(Entity<MutedComponent> 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<MutedComponent> 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<MutedComponent> 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();
}
}

View file

@ -0,0 +1,17 @@
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
namespace Content.Shared.StatusEffectNew.Components;
/// <summary>
/// Applies a set of permanent status effects while this component exists.
/// </summary>
[RegisterComponent, NetworkedComponent]
public sealed partial class PermanentStatusEffectsComponent : Component
{
/// <summary>
/// The status effects to apply.
/// </summary>
[DataField(required: true)]
public HashSet<EntProtoId> StatusEffects = new();
}

View file

@ -0,0 +1,30 @@
using Content.Shared.StatusEffectNew.Components;
namespace Content.Shared.StatusEffectNew;
/// <summary>
/// Keeps permanent status effects from <see cref="PermanentStatusEffectsComponent"/> applied
/// for as long as the owning component exists.
/// </summary>
public sealed partial class PermanentStatusEffectsSystem : EntitySystem
{
[Dependency] private StatusEffectsSystem _statusEffects = default!;
[SubscribeLocalEvent]
private void OnMapInit(Entity<PermanentStatusEffectsComponent> ent, ref MapInitEvent args)
{
foreach (var effect in ent.Comp.StatusEffects)
{
_statusEffects.TrySetStatusEffectDuration(ent, effect);
}
}
[SubscribeLocalEvent]
private void OnRemove(Entity<PermanentStatusEffectsComponent> ent, ref ComponentRemove args)
{
foreach (var effect in ent.Comp.StatusEffects)
{
_statusEffects.TryRemoveStatusEffect(ent, effect);
}
}
}

View file

@ -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<StatusEffectContainerComponent, BeforeForceSayEvent>(RelayStatusEffectEvent);
SubscribeLocalEvent<StatusEffectContainerComponent, BeforeAlertSeverityCheckEvent>(RelayStatusEffectEvent);
SubscribeLocalEvent<StatusEffectContainerComponent, SpeakAttemptEvent>(RelayStatusEffectEvent);
SubscribeLocalEvent<StatusEffectContainerComponent, EmoteActionEvent>(RelayStatusEffectEvent, before: new[] { typeof(VocalSystem) });
SubscribeLocalEvent<StatusEffectContainerComponent, AccentGetEvent>(RefRelayStatusEffectEvent);
SubscribeLocalEvent<StatusEffectContainerComponent, EmoteEvent>(RefRelayStatusEffectEvent, before: new[] { typeof(VocalSystem), typeof(MumbleAccentSystem) });
SubscribeLocalEvent<StatusEffectContainerComponent, BleedModifierEvent>(RefRelayStatusEffectEvent);
SubscribeLocalEvent<StatusEffectContainerComponent, DamageModifyEvent>(RelayStatusEffectEvent);

View file

@ -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

View file

@ -73,7 +73,6 @@
allowed:
- Electrocution
- PressureImmunity
- Muted
- Pacified
- Flashed
- Adrenaline

View file

@ -21,7 +21,6 @@
- Narcolepsy
- ImpairedMobility
# - LegsParalyzed (you get healed)
- Muted
- PermanentBlindness
- Snoring
- Unrevivable

View file

@ -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

View file

@ -167,7 +167,9 @@
- type: VentriloquistPuppet
- type: Item
size: Normal
- type: Muted
- type: PermanentStatusEffects
statusEffects:
- StatusEffectVentriloquistPuppetMuted
- type: TypingIndicator
proto: robot
- type: Actions

View file

@ -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

View file

@ -22,3 +22,6 @@
id: TraitStatusEffectPainNumbness
name: pain numbness
- type: entity
parent: [ MutedStatusEffectBase, TraitStatusEffectBase ]
id: TraitStatusEffectMuted

View file

@ -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

View file

@ -123,9 +123,8 @@
type: Add
Digestion:
effects:
- !type:GenericStatusEffect
key: Muted
component: Muted
- !type:ModifyStatusEffect
effectProto: StatusEffectMuted
time: 5
footstepSound:
collection: FootstepSlime

View file

@ -343,9 +343,8 @@
metabolisms:
Bloodstream:
effects:
- !type:GenericStatusEffect
key: Muted
component: Muted
- !type:ModifyStatusEffect
effectProto: StatusEffectMuted
type: Add
time: 10

View file

@ -62,8 +62,10 @@
blacklist:
components:
- BorgChassis
components:
- type: Muted
specials:
- !type:ApplyStatusEffectSpecial
statusEffects:
- TraitStatusEffectMuted
- type: trait
id: Paracusia

View file

@ -30,10 +30,6 @@
- type: statusEffect
id: PressureImmunity
- type: statusEffect
id: Muted
alert: Muted
- type: statusEffect
id: Corporeal
alert: Corporeal