_window = this.CreateWindow<VoiceMaskNameChangeWindow>();
_window.ReloadVerbs(_protomanager);
+ _window.AddVerbs();
_window.OnNameChange += OnNameSelected;
_window.OnVerbChange += verb => SendMessage(new VoiceMaskChangeVerbMessage(verb));
OnVerbChange?.Invoke((string?) args.Button.GetItemMetadata(args.Id));
SpeechVerbSelector.SelectId(args.Id);
};
-
- AddVerbs();
}
public void ReloadVerbs(IPrototypeManager proto)
_verbs.Sort((a, b) => a.Item1.CompareTo(b.Item1));
}
- private void AddVerbs()
+ public void AddVerbs()
{
SpeechVerbSelector.Clear();
using Content.Server.Administration.Logs;
using Content.Server.Administration.Managers;
using Content.Server.Chat.Managers;
-using Content.Server.Examine;
using Content.Server.GameTicking;
using Content.Server.Players.RateLimiting;
using Content.Server.Speech.Components;
using Content.Shared.Database;
using Content.Shared.Examine;
using Content.Shared.Ghost;
-using Content.Shared.Humanoid;
using Content.Shared.IdentityManagement;
-using Content.Shared.Interaction;
using Content.Shared.Mobs.Systems;
using Content.Shared.Players;
using Content.Shared.Radio;
-using Content.Shared.Speech;
using Content.Shared.Whitelist;
using Robust.Server.Player;
using Robust.Shared.Audio;
{
var nameEv = new TransformSpeakerNameEvent(source, Name(source));
RaiseLocalEvent(source, nameEv);
- name = nameEv.Name;
+ name = nameEv.VoiceName;
// Check for a speech verb override
- if (nameEv.SpeechVerb != null && _prototypeManager.TryIndex<SpeechVerbPrototype>(nameEv.SpeechVerb, out var proto))
+ if (nameEv.SpeechVerb != null && _prototypeManager.TryIndex(nameEv.SpeechVerb, out var proto))
speech = proto;
}
{
var nameEv = new TransformSpeakerNameEvent(source, Name(source));
RaiseLocalEvent(source, nameEv);
- name = nameEv.Name;
+ name = nameEv.VoiceName;
}
name = FormattedMessage.EscapeText(name);
{
}
-public sealed class TransformSpeakerNameEvent : EntityEventArgs
-{
- public EntityUid Sender;
- public string Name;
- public string? SpeechVerb;
-
- public TransformSpeakerNameEvent(EntityUid sender, string name, string? speechVerb = null)
- {
- Sender = sender;
- Name = name;
- SpeechVerb = speechVerb;
- }
-}
-
/// <summary>
/// Raised broadcast in order to transform speech.transmit
/// </summary>
using Content.Shared.Interaction;
using Content.Shared.Power;
using Content.Shared.Radio;
+using Content.Shared.Chat;
using Content.Shared.Radio.Components;
using Robust.Shared.Prototypes;
var name = Loc.GetString("speech-name-relay",
("speaker", Name(uid)),
- ("originalName", nameEv.Name));
+ ("originalName", nameEv.VoiceName));
// log to chat so people can identity the speaker/source, but avoid clogging ghost chat if there are many radios
_chat.TrySendInGameICMessage(uid, args.Message, InGameICChatType.Whisper, ChatTransmitRange.GhostRangeLimit, nameOverride: name, checkRadioPrefix: false);
using Content.Server.Chat.Systems;
using Content.Server.Power.Components;
using Content.Server.Radio.Components;
-using Content.Server.VoiceMask;
using Content.Shared.Chat;
using Content.Shared.Database;
using Content.Shared.Radio;
if (!_messages.Add(message))
return;
- var name = TryComp(messageSource, out VoiceMaskComponent? mask) && mask.Enabled
- ? mask.VoiceName
- : MetaData(messageSource).EntityName;
+ var evt = new TransformSpeakerNameEvent(messageSource, MetaData(messageSource).EntityName);
+ RaiseLocalEvent(messageSource, evt);
+ var name = evt.VoiceName;
name = FormattedMessage.EscapeText(name);
SpeechVerbPrototype speech;
- if (mask != null
- && mask.Enabled
- && mask.SpeechVerb != null
- && _prototype.TryIndex<SpeechVerbPrototype>(mask.SpeechVerb, out var proto))
- {
- speech = proto;
- }
+ if (evt.SpeechVerb != null && _prototype.TryIndex(evt.SpeechVerb, out var evntProto))
+ speech = evntProto;
else
speech = _chat.GetSpeechVerb(messageSource, message);
-using Content.Server.Speech.Components;
using Content.Server.Chat.Systems;
-using Content.Server.VoiceMask;
+using Content.Shared.Radio;
+using Content.Server.Radio.Components;
+using Content.Server.Radio.EntitySystems;
+using Content.Server.Speech.Components;
using Content.Server.Wires;
-using Content.Shared.Speech;
using Content.Shared.Wires;
+using Content.Shared.Speech;
+using Robust.Shared.Prototypes;
namespace Content.Server.Speech;
{
private WiresSystem _wires = default!;
private ChatSystem _chat = default!;
+ private RadioSystem _radio = default!;
+ private IPrototypeManager _protoMan = default!;
/// <summary>
/// Length of the gibberish string sent when pulsing the wire
/// </summary>
private const int NoiseLength = 16;
-
- /// <summary>
- /// Identifier of the SpeechVerbPrototype to use when pulsing the wire
- /// </summary>
- [ValidatePrototypeId<SpeechVerbPrototype>]
- private const string SpeechVerb = "Electricity";
public override Color Color { get; set; } = Color.Green;
public override string Name { get; set; } = "wire-name-listen";
_wires = EntityManager.System<WiresSystem>();
_chat = EntityManager.System<ChatSystem>();
+ _radio = EntityManager.System<RadioSystem>();
+ _protoMan = IoCManager.Resolve<IPrototypeManager>();
}
public override StatusLightState? GetLightState(Wire wire)
{
if (!GetValue(wire.Owner) || !IsPowered(wire.Owner))
return;
- // We have to use a valid euid in the ListenEvent. The user seems
- // like a sensible choice, but we need to mask their name.
-
- // Save the user's existing voicemask if they have one
- var oldEnabled = true;
- var oldVoiceName = Loc.GetString("wire-listen-pulse-error-name");
- string? oldSpeechVerb = null;
- if (EntityManager.TryGetComponent<VoiceMaskComponent>(user, out var oldMask))
- {
- oldEnabled = oldMask.Enabled;
- oldVoiceName = oldMask.VoiceName;
- oldSpeechVerb = oldMask.SpeechVerb;
- }
-
- // Give the user a temporary voicemask component
- var mask = EntityManager.EnsureComponent<VoiceMaskComponent>(user);
- mask.Enabled = true;
- mask.VoiceName = Loc.GetString("wire-listen-pulse-identifier");
- mask.SpeechVerb = SpeechVerb;
-
var chars = Loc.GetString("wire-listen-pulse-characters").ToCharArray();
var noiseMsg = _chat.BuildGibberishString(chars, NoiseLength);
- var attemptEv = new ListenAttemptEvent(wire.Owner);
- EntityManager.EventBus.RaiseLocalEvent(wire.Owner, attemptEv);
- if (!attemptEv.Cancelled)
- {
- var ev = new ListenEvent(noiseMsg, user);
- EntityManager.EventBus.RaiseLocalEvent(wire.Owner, ev);
- }
+ if (!EntityManager.TryGetComponent<RadioMicrophoneComponent>(wire.Owner, out var radioMicroPhoneComp))
+ return;
- // Remove the voicemask component, or set it back to what it was before
- if (oldMask == null)
- EntityManager.RemoveComponent(user, mask);
- else
- {
- mask.Enabled = oldEnabled;
- mask.VoiceName = oldVoiceName;
- mask.SpeechVerb = oldSpeechVerb;
- }
+ if (!EntityManager.TryGetComponent<VoiceOverrideComponent>(wire.Owner, out var voiceOverrideComp))
+ return;
+
+ // The reason for the override is to make the voice sound like its coming from electrity rather than the intercom.
+ voiceOverrideComp.NameOverride = Loc.GetString("wire-listen-pulse-identifier");
+ voiceOverrideComp.Enabled = true;
+ _radio.SendRadioMessage(wire.Owner, noiseMsg, _protoMan.Index<RadioChannelPrototype>(radioMicroPhoneComp.BroadcastChannel), wire.Owner);
+ voiceOverrideComp.Enabled = false;
base.Pulse(user, wire);
}
--- /dev/null
+using Content.Shared.Speech;
+using Robust.Shared.Prototypes;
+
+namespace Content.Server.Speech.Components;
+
+/// <summary>
+/// Will change the voice of the entity that has the component (e.g radio and speech).
+/// </summary>
+/// <remarks>
+/// Before using this component, please take a look at the the TransformSpeakerNameEvent (and the inventory relay version).
+/// Depending on what you're doing, it could be a better choice!
+/// </remarks>
+[RegisterComponent]
+public sealed partial class VoiceOverrideComponent : Component
+{
+ /// <summary>
+ /// The name that will be used instead of an entities default one.
+ /// Uses the localized version of the string and if null wont do anything.
+ /// </summary>
+ [DataField]
+ public string? NameOverride = null;
+
+ /// <summary>
+ /// The verb that will be used insteand of an entities default one.
+ /// If null, the defaut will be used.
+ /// </summary>
+ [DataField]
+ public ProtoId<SpeechVerbPrototype>? SpeechVerbOverride = null;
+
+ /// <summary>
+ /// If true, the override values (if they are not null) will be applied.
+ /// </summary>
+ [DataField]
+ public bool Enabled = true;
+}
--- /dev/null
+using Content.Shared.Chat;
+using Content.Server.Speech.Components;
+
+namespace Content.Server.Speech.EntitySystems;
+
+public sealed partial class VoiceOverrideSystem : EntitySystem
+{
+ public override void Initialize()
+ {
+ base.Initialize();
+ SubscribeLocalEvent<VoiceOverrideComponent, TransformSpeakerNameEvent>(OnTransformSpeakerName);
+ }
+
+ private void OnTransformSpeakerName(Entity<VoiceOverrideComponent> entity, ref TransformSpeakerNameEvent args)
+ {
+ if (!entity.Comp.Enabled)
+ return;
+
+ args.VoiceName = entity.Comp.NameOverride ?? args.VoiceName;
+ args.SpeechVerb = entity.Comp.SpeechVerbOverride ?? args.SpeechVerb;
+ }
+}
using Content.Server.Chat.Systems;
using Content.Server.Speech;
using Content.Shared.Speech;
+using Content.Shared.Chat;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Timing;
RaiseLocalEvent(args.Speaker, nameEv);
var name = Loc.GetString("speech-name-relay", ("speaker", Name(uid)),
- ("originalName", nameEv.Name));
+ ("originalName", nameEv.VoiceName));
// log to chat so people can identity the speaker/source, but avoid clogging ghost chat if there are many radios
_chatSystem.TrySendInGameICMessage(uid, args.Message, InGameICChatType.Speak, ChatTransmitRange.GhostRangeLimit, nameOverride: name);
namespace Content.Server.VoiceMask;
+/// <summary>
+/// This component is for voice mask items! Adding this component to clothing will give the the voice mask UI
+/// and allow the wearer to change their voice and verb at will.
+/// </summary>
+/// <remarks>
+/// DO NOT use this if you do not want the interface.
+/// The VoiceOverrideSystem is probably what your looking for (Or you might have to make something similar)!
+/// </remarks>
[RegisterComponent]
public sealed partial class VoiceMaskComponent : Component
{
+ /// <summary>
+ /// The name that will override an entities default name. If null, it will use the default override.
+ /// </summary>
+ [DataField]
+ public string? VoiceMaskName = null;
+
+ /// <summary>
+ /// The speech verb that will override an entities default one. If null, it will use the entities default verb.
+ /// </summary>
[DataField]
- [ViewVariables(VVAccess.ReadWrite)]
- public bool Enabled = true;
+ public ProtoId<SpeechVerbPrototype>? VoiceMaskSpeechVerb;
+ /// <summary>
+ /// The action that gets displayed when the voice mask is equipped.
+ /// </summary>
[DataField]
- [ViewVariables(VVAccess.ReadWrite)]
- public string VoiceName = "Unknown";
+ public EntProtoId Action = "ActionChangeVoiceMask";
/// <summary>
- /// If EnableSpeechVerbModification is true, overrides the speech verb used when this entity speaks.
+ /// Reference to the action.
/// </summary>
[DataField]
- [ViewVariables(VVAccess.ReadWrite)]
- public ProtoId<SpeechVerbPrototype>? SpeechVerb;
+ public EntityUid? ActionEntity;
}
+++ /dev/null
-using Content.Server.Actions;
-using Content.Shared.Clothing;
-using Content.Shared.Inventory;
-
-namespace Content.Server.VoiceMask;
-
-// This partial deals with equipment, i.e., the syndicate voice mask.
-public sealed partial class VoiceMaskSystem
-{
- [Dependency] private readonly InventorySystem _inventory = default!;
- [Dependency] private readonly ActionsSystem _actions = default!;
-
- private const string MaskSlot = "mask";
-
- private void OnEquip(EntityUid uid, VoiceMaskerComponent component, ClothingGotEquippedEvent args)
- {
- var user = args.Wearer;
- var comp = EnsureComp<VoiceMaskComponent>(user);
- comp.VoiceName = component.LastSetName;
- comp.SpeechVerb = component.LastSpeechVerb;
-
- _actions.AddAction(user, ref component.ActionEntity, component.Action, uid);
- }
-
- private void OnUnequip(EntityUid uid, VoiceMaskerComponent compnent, ClothingGotUnequippedEvent args)
- {
- RemComp<VoiceMaskComponent>(args.Wearer);
- }
-
- private VoiceMaskerComponent? TryGetMask(EntityUid user)
- {
- if (!HasComp<VoiceMaskComponent>(user) || !_inventory.TryGetSlotEntity(user, MaskSlot, out var maskEntity))
- return null;
-
- return CompOrNull<VoiceMaskerComponent>(maskEntity);
- }
-
- private void TrySetLastKnownName(EntityUid user, string name)
- {
- if (TryGetMask(user) is {} comp)
- comp.LastSetName = name;
- }
-
- private void TrySetLastSpeechVerb(EntityUid user, string? verb)
- {
- if (TryGetMask(user) is {} comp)
- comp.LastSpeechVerb = verb;
- }
-}
-using Content.Server.Administration.Logs;
-using Content.Server.Chat.Systems;
-using Content.Server.Popups;
+using Content.Shared.Actions;
+using Content.Shared.Administration.Logs;
+using Content.Shared.Chat;
using Content.Shared.Clothing;
using Content.Shared.Database;
+using Content.Shared.Inventory;
using Content.Shared.Popups;
using Content.Shared.Preferences;
using Content.Shared.Speech;
using Content.Shared.VoiceMask;
-using Robust.Server.GameObjects;
-using Robust.Shared.Player;
using Robust.Shared.Prototypes;
namespace Content.Server.VoiceMask;
public sealed partial class VoiceMaskSystem : EntitySystem
{
- [Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
- [Dependency] private readonly PopupSystem _popupSystem = default!;
- [Dependency] private readonly IAdminLogManager _adminLogger = default!;
+ [Dependency] private readonly SharedUserInterfaceSystem _uiSystem = default!;
+ [Dependency] private readonly SharedPopupSystem _popupSystem = default!;
+ [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;
+ [Dependency] private readonly SharedActionsSystem _actions = default!;
public override void Initialize()
{
- SubscribeLocalEvent<VoiceMaskComponent, TransformSpeakerNameEvent>(OnSpeakerNameTransform);
+ base.Initialize();
+ SubscribeLocalEvent<VoiceMaskComponent, InventoryRelayedEvent<TransformSpeakerNameEvent>>(OnTransformSpeakerName);
SubscribeLocalEvent<VoiceMaskComponent, VoiceMaskChangeNameMessage>(OnChangeName);
SubscribeLocalEvent<VoiceMaskComponent, VoiceMaskChangeVerbMessage>(OnChangeVerb);
- SubscribeLocalEvent<VoiceMaskComponent, WearerMaskToggledEvent>(OnMaskToggled);
- SubscribeLocalEvent<VoiceMaskerComponent, ClothingGotEquippedEvent>(OnEquip);
- SubscribeLocalEvent<VoiceMaskerComponent, ClothingGotUnequippedEvent>(OnUnequip);
- SubscribeLocalEvent<VoiceMaskSetNameEvent>(OnSetName);
- // SubscribeLocalEvent<VoiceMaskerComponent, GetVerbsEvent<AlternativeVerb>>(GetVerbs);
+ SubscribeLocalEvent<VoiceMaskComponent, ClothingGotEquippedEvent>(OnEquip);
+ SubscribeLocalEvent<VoiceMaskSetNameEvent>(OpenUI);
}
- private void OnSetName(VoiceMaskSetNameEvent ev)
+ private void OnTransformSpeakerName(Entity<VoiceMaskComponent> entity, ref InventoryRelayedEvent<TransformSpeakerNameEvent> args)
{
- OpenUI(ev.Performer);
+ args.Args.VoiceName = GetCurrentVoiceName(entity);
+ args.Args.SpeechVerb = entity.Comp.VoiceMaskSpeechVerb ?? args.Args.SpeechVerb;
}
- private void OnChangeName(EntityUid uid, VoiceMaskComponent component, VoiceMaskChangeNameMessage message)
+ #region User inputs from UI
+ private void OnChangeVerb(Entity<VoiceMaskComponent> entity, ref VoiceMaskChangeVerbMessage msg)
{
- if (message.Name.Length > HumanoidCharacterProfile.MaxNameLength || message.Name.Length <= 0)
- {
- _popupSystem.PopupEntity(Loc.GetString("voice-mask-popup-failure"), uid, message.Actor, PopupType.SmallCaution);
+ if (msg.Verb is { } id && !_proto.HasIndex<SpeechVerbPrototype>(id))
return;
- }
- component.VoiceName = message.Name;
- _adminLogger.Add(LogType.Action, LogImpact.Medium, $"{ToPrettyString(message.Actor):player} set voice of {ToPrettyString(uid):mask}: {component.VoiceName}");
-
- _popupSystem.PopupEntity(Loc.GetString("voice-mask-popup-success"), uid, message.Actor);
+ entity.Comp.VoiceMaskSpeechVerb = msg.Verb;
+ // verb is only important to metagamers so no need to log as opposed to name
- TrySetLastKnownName(uid, message.Name);
+ _popupSystem.PopupEntity(Loc.GetString("voice-mask-popup-success"), entity, msg.Actor);
- UpdateUI(uid, component);
+ UpdateUI(entity);
}
- private void OnChangeVerb(Entity<VoiceMaskComponent> ent, ref VoiceMaskChangeVerbMessage msg)
+ private void OnChangeName(Entity<VoiceMaskComponent> entity, ref VoiceMaskChangeNameMessage message)
{
- if (msg.Verb is {} id && !_proto.HasIndex<SpeechVerbPrototype>(id))
+ if (message.Name.Length > HumanoidCharacterProfile.MaxNameLength || message.Name.Length <= 0)
+ {
+ _popupSystem.PopupEntity(Loc.GetString("voice-mask-popup-failure"), entity, message.Actor, PopupType.SmallCaution);
return;
+ }
- ent.Comp.SpeechVerb = msg.Verb;
- // verb is only important to metagamers so no need to log as opposed to name
-
- _popupSystem.PopupEntity(Loc.GetString("voice-mask-popup-success"), ent, msg.Actor);
+ entity.Comp.VoiceMaskName = message.Name;
+ _adminLogger.Add(LogType.Action, LogImpact.Medium, $"{ToPrettyString(message.Actor):player} set voice of {ToPrettyString(entity):mask}: {entity.Comp.VoiceMaskName}");
- TrySetLastSpeechVerb(ent, msg.Verb);
+ _popupSystem.PopupEntity(Loc.GetString("voice-mask-popup-success"), entity, message.Actor);
- UpdateUI(ent, ent.Comp);
+ UpdateUI(entity);
}
+ #endregion
- private void OnSpeakerNameTransform(EntityUid uid, VoiceMaskComponent component, TransformSpeakerNameEvent args)
+ #region UI
+ private void OnEquip(EntityUid uid, VoiceMaskComponent component, ClothingGotEquippedEvent args)
{
- if (component.Enabled)
- {
- /*
- args.Name = _idCard.TryGetIdCard(uid, out var card) && !string.IsNullOrEmpty(card.FullName)
- ? card.FullName
- : Loc.GetString("voice-mask-unknown");
- */
-
- args.Name = component.VoiceName;
- if (component.SpeechVerb != null)
- args.SpeechVerb = component.SpeechVerb;
- }
+ _actions.AddAction(args.Wearer, ref component.ActionEntity, component.Action, uid);
}
- private void OnMaskToggled(Entity<VoiceMaskComponent> ent, ref WearerMaskToggledEvent args)
+ private void OpenUI(VoiceMaskSetNameEvent ev)
{
- ent.Comp.Enabled = !args.IsToggled;
- }
+ var maskEntity = ev.Action.Comp.Container;
- private void OpenUI(EntityUid player)
- {
- if (!_uiSystem.HasUi(player, VoiceMaskUIKey.Key))
+ if (!TryComp<VoiceMaskComponent>(maskEntity, out var voiceMaskComp))
+ return;
+
+ if (!_uiSystem.HasUi(maskEntity.Value, VoiceMaskUIKey.Key))
return;
- _uiSystem.OpenUi(player, VoiceMaskUIKey.Key, player);
- UpdateUI(player);
+ _uiSystem.OpenUi(maskEntity.Value, VoiceMaskUIKey.Key, ev.Performer);
+ UpdateUI((maskEntity.Value, voiceMaskComp));
}
- private void UpdateUI(EntityUid owner, VoiceMaskComponent? component = null)
+ private void UpdateUI(Entity<VoiceMaskComponent> entity)
{
- if (!Resolve(owner, ref component))
- {
- return;
- }
+ if (_uiSystem.HasUi(entity, VoiceMaskUIKey.Key))
+ _uiSystem.SetUiState(entity.Owner, VoiceMaskUIKey.Key, new VoiceMaskBuiState(GetCurrentVoiceName(entity), entity.Comp.VoiceMaskSpeechVerb));
+ }
+ #endregion
- if (_uiSystem.HasUi(owner, VoiceMaskUIKey.Key))
- _uiSystem.SetUiState(owner, VoiceMaskUIKey.Key, new VoiceMaskBuiState(component.VoiceName, component.SpeechVerb));
+ #region Helper functions
+ private string GetCurrentVoiceName(Entity<VoiceMaskComponent> entity)
+ {
+ return entity.Comp.VoiceMaskName ?? Loc.GetString("voice-mask-default-name-override");
}
+ #endregion
}
+++ /dev/null
-using Content.Shared.Speech;
-using Robust.Shared.Prototypes;
-
-namespace Content.Server.VoiceMask;
-
-[RegisterComponent]
-public sealed partial class VoiceMaskerComponent : Component
-{
- [DataField]
- public string LastSetName = "Unknown";
-
- [DataField]
- public ProtoId<SpeechVerbPrototype>? LastSpeechVerb;
-
- [DataField]
- public EntProtoId Action = "ActionChangeVoiceMask";
-
- [DataField]
- public EntityUid? ActionEntity;
-}
--- /dev/null
+using Content.Shared.Speech;
+using Robust.Shared.Prototypes;
+using Content.Shared.Inventory;
+
+namespace Content.Shared.Chat;
+
+/// <summary>
+/// This event should be sent everytime an entity talks (Radio, local chat, etc...).
+/// The event is sent to both the entity itself, and all clothing (For stuff like voice masks).
+/// </summary>
+public sealed class TransformSpeakerNameEvent : EntityEventArgs, IInventoryRelayEvent
+{
+ public SlotFlags TargetSlots { get; } = SlotFlags.WITHOUT_POCKET;
+ public EntityUid Sender;
+ public string VoiceName;
+ public ProtoId<SpeechVerbPrototype>? SpeechVerb;
+
+ public TransformSpeakerNameEvent(EntityUid sender, string name)
+ {
+ Sender = sender;
+ VoiceName = name;
+ SpeechVerb = null;
+ }
+}
using Content.Shared.Strip.Components;
using Content.Shared.Temperature;
using Content.Shared.Verbs;
+using Content.Shared.Chat;
namespace Content.Shared.Inventory;
SubscribeLocalEvent<InventoryComponent, ModifyChangedTemperatureEvent>(RelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, GetDefaultRadioChannelEvent>(RelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, RefreshNameModifiersEvent>(RelayInventoryEvent);
+ SubscribeLocalEvent<InventoryComponent, TransformSpeakerNameEvent>(RelayInventoryEvent);
// by-ref events
SubscribeLocalEvent<InventoryComponent, GetExplosionResistanceEvent>(RefRelayInventoryEvent);
+voice-mask-default-name-override = Unknown
+
voice-mask-name-change-window = Voice Mask Name Change
voice-mask-name-change-info = Type in the name you want to mimic.
voice-mask-name-change-speech-style = Speech style
id: ClothingMaskGasVoiceChameleon
suffix: Voice Mask, Chameleon
components:
- - type: VoiceMasker
+ - type: VoiceMask
- type: HideLayerClothing
slots:
- Snout
+ - type: UserInterface
+ interfaces:
+ enum.VoiceMaskUIKey.Key:
+ type: VoiceMaskBoundUserInterface
- type: entity
parent: ClothingMaskBase
- type: Stripping
- type: UserInterface
interfaces:
- enum.VoiceMaskUIKey.Key:
- type: VoiceMaskBoundUserInterface
enum.HumanoidMarkingModifierKey.Key:
type: HumanoidMarkingModifierBoundUserInterface
enum.StrippingUiKey.Key:
interfaces:
enum.StorageUiKey.Key:
type: StorageBoundUserInterface
- enum.VoiceMaskUIKey.Key:
- type: VoiceMaskBoundUserInterface
enum.HumanoidMarkingModifierKey.Key:
type: HumanoidMarkingModifierBoundUserInterface
enum.StrippingUiKey.Key:
- type: Intercom
- type: Speech
speechVerb: Robotic
+ - type: VoiceOverride # This is for the wire that makes an electricity zapping noise.
+ speechVerbOverride: Electricity
+ enabled: false
- type: ExtensionCableReceiver
- type: Clickable
- type: InteractionOutline