Add "Reset to default" verb to TriggerOnVoice (#35636)

* Add "Reset to default" verb to `TriggerOnVoice`

* Forgor to remove these changes

* Apply requested changes

* Test fail is real

* Apply requested changes

* Update according to refactored trigger system

* cleanup

---------

Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
This commit is contained in:
MilenVolf
2025-10-16 21:36:16 +03:00
committed by GitHub
parent 5a277268b9
commit e362ee121f
5 changed files with 68 additions and 7 deletions

View File

@@ -21,6 +21,12 @@ public sealed partial class TriggerOnVoiceComponent : BaseTriggerOnXComponent
[DataField, AutoNetworkedField] [DataField, AutoNetworkedField]
public string? KeyPhrase; public string? KeyPhrase;
/// <summary>
/// The default keyphrase that is used when the trigger's keyphrase is reset.
/// </summary>
[DataField, AutoNetworkedField]
public LocId? DefaultKeyPhrase;
/// <summary> /// <summary>
/// Range in which we listen for the keyphrase. /// Range in which we listen for the keyphrase.
/// </summary> /// </summary>
@@ -75,6 +81,12 @@ public sealed partial class TriggerOnVoiceComponent : BaseTriggerOnXComponent
[DataField, AutoNetworkedField] [DataField, AutoNetworkedField]
public LocId? RecordingVerbMessage; public LocId? RecordingVerbMessage;
/// <summary>
/// The verb text that is shown when you can reset keyphrase to default.
/// </summary>
[DataField, AutoNetworkedField]
public LocId ResetRecordingVerb = "trigger-on-voice-default";
/// <summary> /// <summary>
/// The verb text that is shown when you can clear a recording. /// The verb text that is shown when you can clear a recording.
/// </summary> /// </summary>

View File

@@ -11,18 +11,21 @@ public sealed partial class TriggerSystem
{ {
private void InitializeVoice() private void InitializeVoice()
{ {
SubscribeLocalEvent<TriggerOnVoiceComponent, ComponentInit>(OnVoiceInit); SubscribeLocalEvent<TriggerOnVoiceComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<TriggerOnVoiceComponent, ExaminedEvent>(OnVoiceExamine); SubscribeLocalEvent<TriggerOnVoiceComponent, ExaminedEvent>(OnVoiceExamine);
SubscribeLocalEvent<TriggerOnVoiceComponent, ListenEvent>(OnListen); SubscribeLocalEvent<TriggerOnVoiceComponent, ListenEvent>(OnListen);
SubscribeLocalEvent<TriggerOnVoiceComponent, GetVerbsEvent<AlternativeVerb>>(OnVoiceGetAltVerbs); SubscribeLocalEvent<TriggerOnVoiceComponent, GetVerbsEvent<AlternativeVerb>>(OnVoiceGetAltVerbs);
} }
private void OnVoiceInit(Entity<TriggerOnVoiceComponent> ent, ref ComponentInit args) private void OnMapInit(Entity<TriggerOnVoiceComponent> ent, ref MapInitEvent args)
{ {
if (ent.Comp.IsListening) if (ent.Comp.DefaultKeyPhrase != null)
EnsureComp<ActiveListenerComponent>(ent).Range = ent.Comp.ListenRange; {
else ent.Comp.KeyPhrase = Loc.GetString(ent.Comp.DefaultKeyPhrase);
RemCompDeferred<ActiveListenerComponent>(ent); Dirty(ent);
}
UpdateListening(ent);
} }
private void OnVoiceExamine(EntityUid uid, TriggerOnVoiceComponent component, ExaminedEvent args) private void OnVoiceExamine(EntityUid uid, TriggerOnVoiceComponent component, ExaminedEvent args)
@@ -94,6 +97,19 @@ public sealed partial class TriggerSystem
Priority = 1 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)) if (string.IsNullOrWhiteSpace(ent.Comp.KeyPhrase))
return; return;
@@ -107,6 +123,17 @@ public sealed partial class TriggerSystem
}); });
} }
/// <summary>
/// Updates the presence/absence of the ActiveListenerComponent based on IsListening.
/// </summary>
private void UpdateListening(Entity<TriggerOnVoiceComponent> ent)
{
if (ent.Comp.IsListening)
EnsureComp<ActiveListenerComponent>(ent).Range = ent.Comp.ListenRange;
else
RemCompDeferred<ActiveListenerComponent>(ent);
}
/// <summary> /// <summary>
/// Start recording a new keyphrase. /// Start recording a new keyphrase.
/// </summary> /// </summary>
@@ -163,4 +190,23 @@ public sealed partial class TriggerSystem
Dirty(ent); Dirty(ent);
RemComp<ActiveListenerComponent>(ent); RemComp<ActiveListenerComponent>(ent);
} }
/// <summary>
/// Resets the current key phrase to default.
/// </summary>
public void SetToDefault(Entity<TriggerOnVoiceComponent> 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);
}
} }

View File

@@ -0,0 +1 @@
key-phrase-gadget = go go gadget

View File

@@ -4,9 +4,11 @@ trigger-on-voice-uninitialized = The display reads: Uninitialized...
trigger-on-voice-record = Record trigger-on-voice-record = Record
trigger-on-voice-stop = Stop trigger-on-voice-stop = Stop
trigger-on-voice-clear = Clear recording trigger-on-voice-clear = Clear recording
trigger-on-voice-default = Reset to default
trigger-on-voice-start-recording = Started recording. trigger-on-voice-start-recording = Started recording.
trigger-on-voice-stop-recording = Stopped 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-long = Message too long, try again.
trigger-on-voice-record-failed-too-short = Message too short, try again. trigger-on-voice-record-failed-too-short = Message too short, try again.
trigger-on-voice-recorded = Recorded successfully! trigger-on-voice-recorded = Recorded successfully!
trigger-on-voice-set-default = Set to default keyphrase: "{$keyphrase}"

View File

@@ -24,7 +24,7 @@
- type: Tag - type: Tag
tags: [] # ignore "WhitelistChameleon" tag tags: [] # ignore "WhitelistChameleon" tag
- type: TriggerOnVoice - type: TriggerOnVoice
keyPhrase: "go go gadget" defaultKeyPhrase: key-phrase-gadget
listenRange: 0 listenRange: 0
- type: ActiveListener - type: ActiveListener
range: 0 range: 0