diff --git a/Content.Shared/Trigger/Components/Triggers/TriggerOnVoiceComponent.cs b/Content.Shared/Trigger/Components/Triggers/TriggerOnVoiceComponent.cs index 974d5322e0..1f6c62f6b6 100644 --- a/Content.Shared/Trigger/Components/Triggers/TriggerOnVoiceComponent.cs +++ b/Content.Shared/Trigger/Components/Triggers/TriggerOnVoiceComponent.cs @@ -21,6 +21,12 @@ public sealed partial class TriggerOnVoiceComponent : BaseTriggerOnXComponent [DataField, AutoNetworkedField] public string? KeyPhrase; + /// + /// The default keyphrase that is used when the trigger's keyphrase is reset. + /// + [DataField, AutoNetworkedField] + public LocId? DefaultKeyPhrase; + /// /// Range in which we listen for the keyphrase. /// @@ -75,6 +81,12 @@ public sealed partial class TriggerOnVoiceComponent : BaseTriggerOnXComponent [DataField, AutoNetworkedField] public LocId? RecordingVerbMessage; + /// + /// The verb text that is shown when you can reset keyphrase to default. + /// + [DataField, AutoNetworkedField] + public LocId ResetRecordingVerb = "trigger-on-voice-default"; + /// /// The verb text that is shown when you can clear a recording. /// diff --git a/Content.Shared/Trigger/Systems/TriggerSystem.Voice.cs b/Content.Shared/Trigger/Systems/TriggerSystem.Voice.cs index c374369a7f..a312b6aa28 100644 --- a/Content.Shared/Trigger/Systems/TriggerSystem.Voice.cs +++ b/Content.Shared/Trigger/Systems/TriggerSystem.Voice.cs @@ -11,18 +11,21 @@ public sealed partial class TriggerSystem { private void InitializeVoice() { - SubscribeLocalEvent(OnVoiceInit); + SubscribeLocalEvent(OnMapInit); SubscribeLocalEvent(OnVoiceExamine); SubscribeLocalEvent(OnListen); SubscribeLocalEvent>(OnVoiceGetAltVerbs); } - private void OnVoiceInit(Entity ent, ref ComponentInit args) + private void OnMapInit(Entity ent, ref MapInitEvent args) { - if (ent.Comp.IsListening) - EnsureComp(ent).Range = ent.Comp.ListenRange; - else - RemCompDeferred(ent); + if (ent.Comp.DefaultKeyPhrase != null) + { + ent.Comp.KeyPhrase = Loc.GetString(ent.Comp.DefaultKeyPhrase); + Dirty(ent); + } + + UpdateListening(ent); } private void OnVoiceExamine(EntityUid uid, TriggerOnVoiceComponent component, ExaminedEvent args) @@ -94,6 +97,19 @@ public sealed partial class TriggerSystem Priority = 1 }); + if (ent.Comp.DefaultKeyPhrase != null + && ent.Comp.KeyPhrase != Loc.GetString(ent.Comp.DefaultKeyPhrase)) + { + args.Verbs.Add(new AlternativeVerb + { + Text = Loc.GetString(ent.Comp.ResetRecordingVerb), + Act = () => + { + SetToDefault(ent, user); + }, + }); + } + if (string.IsNullOrWhiteSpace(ent.Comp.KeyPhrase)) return; @@ -107,6 +123,17 @@ public sealed partial class TriggerSystem }); } + /// + /// Updates the presence/absence of the ActiveListenerComponent based on IsListening. + /// + private void UpdateListening(Entity ent) + { + if (ent.Comp.IsListening) + EnsureComp(ent).Range = ent.Comp.ListenRange; + else + RemCompDeferred(ent); + } + /// /// Start recording a new keyphrase. /// @@ -163,4 +190,23 @@ public sealed partial class TriggerSystem Dirty(ent); RemComp(ent); } + + /// + /// Resets the current key phrase to default. + /// + public void SetToDefault(Entity ent, EntityUid? user = null) + { + if (ent.Comp.DefaultKeyPhrase == null) + return; + + ent.Comp.KeyPhrase = Loc.GetString(ent.Comp.DefaultKeyPhrase); + ent.Comp.IsRecording = false; + Dirty(ent); + UpdateListening(ent); + + _adminLogger.Add(LogType.Trigger, LogImpact.Low, + $"A voice-trigger on {ToPrettyString(ent):entity} has been reset to default keyphrase: '{ent.Comp.KeyPhrase}'. User: {ToPrettyString(user):speaker}"); + + _popup.PopupPredicted(Loc.GetString("trigger-on-voice-set-default", ("keyphrase", ent.Comp.KeyPhrase)), ent, user); + } } diff --git a/Resources/Locale/en-US/speech/speech-triggers.ftl b/Resources/Locale/en-US/speech/speech-triggers.ftl new file mode 100644 index 0000000000..6b6652aa5a --- /dev/null +++ b/Resources/Locale/en-US/speech/speech-triggers.ftl @@ -0,0 +1 @@ +key-phrase-gadget = go go gadget diff --git a/Resources/Locale/en-US/triggers/trigger-on-voice.ftl b/Resources/Locale/en-US/triggers/trigger-on-voice.ftl index 7ace486657..c955cd5384 100644 --- a/Resources/Locale/en-US/triggers/trigger-on-voice.ftl +++ b/Resources/Locale/en-US/triggers/trigger-on-voice.ftl @@ -4,9 +4,11 @@ trigger-on-voice-uninitialized = The display reads: Uninitialized... trigger-on-voice-record = Record trigger-on-voice-stop = Stop trigger-on-voice-clear = Clear recording +trigger-on-voice-default = Reset to default trigger-on-voice-start-recording = Started recording. trigger-on-voice-stop-recording = Stopped recording. trigger-on-voice-record-failed-too-long = Message too long, try again. trigger-on-voice-record-failed-too-short = Message too short, try again. trigger-on-voice-recorded = Recorded successfully! +trigger-on-voice-set-default = Set to default keyphrase: "{$keyphrase}" diff --git a/Resources/Prototypes/Entities/Clothing/Head/specific.yml b/Resources/Prototypes/Entities/Clothing/Head/specific.yml index 4539e2fdf3..4528d8cabd 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/specific.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/specific.yml @@ -24,7 +24,7 @@ - type: Tag tags: [] # ignore "WhitelistChameleon" tag - type: TriggerOnVoice - keyPhrase: "go go gadget" + defaultKeyPhrase: key-phrase-gadget listenRange: 0 - type: ActiveListener range: 0