Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

voicemask can select speech verb #25768

Merged
merged 9 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions Content.Client/VoiceMask/VoiceMaskBoundUserInterface.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
using Content.Shared.VoiceMask;
using Robust.Client.GameObjects;
using Robust.Shared.Prototypes;

namespace Content.Client.VoiceMask;

public sealed class VoiceMaskBoundUserInterface : BoundUserInterface
{
[Dependency] private readonly IPrototypeManager _proto = default!;

[ViewVariables]
private VoiceMaskNameChangeWindow? _window;

Expand All @@ -16,10 +19,11 @@ protected override void Open()
{
base.Open();

_window = new();
_window = new(_proto);

_window.OpenCentered();
_window.OnNameChange += OnNameSelected;
_window.OnVerbChange += verb => SendMessage(new VoiceMaskChangeVerbMessage(verb));
_window.OnClose += Close;
}

Expand All @@ -35,7 +39,7 @@ protected override void UpdateState(BoundUserInterfaceState state)
return;
}

_window.UpdateState(cast.Name);
_window.UpdateState(cast.Name, cast.Verb);
}

protected override void Dispose(bool disposing)
Expand Down
15 changes: 10 additions & 5 deletions Content.Client/VoiceMask/VoiceMaskNameChangeWindow.xaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
<DefaultWindow xmlns="https://spacestation14.io"
<controls:FancyWindow xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
Title="{Loc 'voice-mask-name-change-window'}"
MinSize="5 20">
<BoxContainer Orientation="Vertical">
MinSize="5 30">
<BoxContainer Orientation="Vertical" Margin="5">
<Label Text="{Loc 'voice-mask-name-change-info'}" />
<BoxContainer Orientation="Horizontal">
<BoxContainer Orientation="Horizontal" Margin="5">
<LineEdit Name="NameSelector" HorizontalExpand="True" />
<Button Name="NameSelectorSet" Text="{Loc 'voice-mask-name-change-set'}" />
</BoxContainer>
<BoxContainer Orientation="Horizontal" Margin="5">
<Label Text="{Loc 'voice-mask-name-change-speech-style'}" />
<OptionButton Name="SpeechVerbSelector" /> <!-- Populated in LoadVerbs -->
</BoxContainer>
</BoxContainer>
</DefaultWindow>
</controls:FancyWindow>
67 changes: 63 additions & 4 deletions Content.Client/VoiceMask/VoiceMaskNameChangeWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,26 +1,85 @@
using Content.Client.UserInterface.Controls;
using Content.Shared.Speech;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;

namespace Content.Client.VoiceMask;

[GenerateTypedNameReferences]
public sealed partial class VoiceMaskNameChangeWindow : DefaultWindow
public sealed partial class VoiceMaskNameChangeWindow : FancyWindow
{
public Action<string>? OnNameChange;
public Action<string?>? OnVerbChange;

public VoiceMaskNameChangeWindow()
private List<(string, string)> _verbs = new();

private string? _verb;

public VoiceMaskNameChangeWindow(IPrototypeManager proto)
{
RobustXamlLoader.Load(this);

NameSelectorSet.OnPressed += _ =>
{
OnNameChange!(NameSelector.Text);
OnNameChange?.Invoke(NameSelector.Text);
};

SpeechVerbSelector.OnItemSelected += args =>
{
OnVerbChange?.Invoke((string?) args.Button.GetItemMetadata(args.Id));
SpeechVerbSelector.SelectId(args.Id);
};

ReloadVerbs(proto);

AddVerbs();
}

private void ReloadVerbs(IPrototypeManager proto)
{
foreach (var verb in proto.EnumeratePrototypes<SpeechVerbPrototype>())
{
_verbs.Add((Loc.GetString(verb.Name), verb.ID));
}
_verbs.Sort((a, b) => a.Item1.CompareTo(b.Item1));
}

public void UpdateState(string name)
private void AddVerbs()
{
SpeechVerbSelector.Clear();

AddVerb(Loc.GetString("chat-speech-verb-name-none"), null);
foreach (var (name, id) in _verbs)
{
AddVerb(name, id);
}
}

private void AddVerb(string name, string? verb)
{
var id = SpeechVerbSelector.ItemCount;
SpeechVerbSelector.AddItem(name);
if (verb is {} metadata)
SpeechVerbSelector.SetItemMetadata(id, metadata);

if (verb == _verb)
SpeechVerbSelector.SelectId(id);
}

public void UpdateState(string name, string? verb)
{
NameSelector.Text = name;
_verb = verb;

for (int id = 0; id < SpeechVerbSelector.ItemCount; id++)
{
if (string.Equals(verb, SpeechVerbSelector.GetItemMetadata(id)))
{
SpeechVerbSelector.SelectId(id);
break;
}
}
}
}
25 changes: 17 additions & 8 deletions Content.Server/VoiceMask/VoiceMaskSystem.Equip.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ private void OnEquip(EntityUid uid, VoiceMaskerComponent component, GotEquippedE

var comp = EnsureComp<VoiceMaskComponent>(user);
comp.VoiceName = component.LastSetName;
comp.SpeechVerb = component.LastSpeechVerb;

_actions.AddAction(user, ref component.ActionEntity, component.Action, uid);
}
Expand All @@ -30,15 +31,23 @@ private void OnUnequip(EntityUid uid, VoiceMaskerComponent compnent, GotUnequipp
RemComp<VoiceMaskComponent>(args.Equipee);
}

private void TrySetLastKnownName(EntityUid maskWearer, string lastName)
private VoiceMaskerComponent? TryGetMask(EntityUid user)
{
if (!HasComp<VoiceMaskComponent>(maskWearer)
|| !_inventory.TryGetSlotEntity(maskWearer, MaskSlot, out var maskEntity)
|| !TryComp<VoiceMaskerComponent>(maskEntity, out var maskComp))
{
return;
}
if (!HasComp<VoiceMaskComponent>(user) || !_inventory.TryGetSlotEntity(user, MaskSlot, out var maskEntity))
return null;

return CompOrNull<VoiceMaskerComponent>(maskEntity);
}

maskComp.LastSetName = lastName;
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;
}
}
21 changes: 20 additions & 1 deletion Content.Server/VoiceMask/VoiceMaskSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
using Content.Shared.Inventory.Events;
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;

Expand All @@ -17,11 +19,13 @@ 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 IPrototypeManager _proto = default!;

public override void Initialize()
{
SubscribeLocalEvent<VoiceMaskComponent, TransformSpeakerNameEvent>(OnSpeakerNameTransform);
SubscribeLocalEvent<VoiceMaskComponent, VoiceMaskChangeNameMessage>(OnChangeName);
SubscribeLocalEvent<VoiceMaskComponent, VoiceMaskChangeVerbMessage>(OnChangeVerb);
SubscribeLocalEvent<VoiceMaskComponent, WearerMaskToggledEvent>(OnMaskToggled);
SubscribeLocalEvent<VoiceMaskerComponent, GotEquippedEvent>(OnEquip);
SubscribeLocalEvent<VoiceMaskerComponent, GotUnequippedEvent>(OnUnequip);
Expand Down Expand Up @@ -55,6 +59,21 @@ private void OnChangeName(EntityUid uid, VoiceMaskComponent component, VoiceMask
UpdateUI(uid, component);
}

private void OnChangeVerb(Entity<VoiceMaskComponent> ent, ref VoiceMaskChangeVerbMessage msg)
{
if (msg.Verb is {} id && !_proto.HasIndex<SpeechVerbPrototype>(id))
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.Session);

TrySetLastSpeechVerb(ent, msg.Verb);

UpdateUI(ent, ent.Comp);
}

private void OnSpeakerNameTransform(EntityUid uid, VoiceMaskComponent component, TransformSpeakerNameEvent args)
{
if (component.Enabled)
Expand Down Expand Up @@ -95,6 +114,6 @@ private void UpdateUI(EntityUid owner, VoiceMaskComponent? component = null)
}

if (_uiSystem.TryGetUi(owner, VoiceMaskUIKey.Key, out var bui))
_uiSystem.SetUiState(bui, new VoiceMaskBuiState(component.VoiceName));
_uiSystem.SetUiState(bui, new VoiceMaskBuiState(component.VoiceName, component.SpeechVerb));
}
}
15 changes: 10 additions & 5 deletions Content.Server/VoiceMask/VoiceMaskerComponent.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
using Content.Shared.Speech;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;

namespace Content.Server.VoiceMask;

[RegisterComponent]
public sealed partial class VoiceMaskerComponent : Component
{
[ViewVariables(VVAccess.ReadWrite)] public string LastSetName = "Unknown";
[DataField]
public string LastSetName = "Unknown";

[DataField("action", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
public string Action = "ActionChangeVoiceMask";
[DataField]
public ProtoId<SpeechVerbPrototype>? LastSpeechVerb;

[DataField("actionEntity")] public EntityUid? ActionEntity;
[DataField]
public EntProtoId Action = "ActionChangeVoiceMask";

[DataField]
public EntityUid? ActionEntity;
}
6 changes: 6 additions & 0 deletions Content.Shared/Speech/SpeechVerbPrototype.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,10 @@ public sealed partial class SpeechVerbPrototype : IPrototype
/// </summary>
[DataField("priority")]
public int Priority = 0;

/// <summary>
/// Name shown in the voicemask UI for this verb.
/// </summary>
[DataField(required: true)]
public LocId Name = string.Empty;
}
22 changes: 19 additions & 3 deletions Content.Shared/VoiceMask/SharedVoiceMaskSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,37 @@ public enum VoiceMaskUIKey : byte
[Serializable, NetSerializable]
public sealed class VoiceMaskBuiState : BoundUserInterfaceState
{
public string Name { get; }
public readonly string Name;
public readonly string? Verb;

public VoiceMaskBuiState(string name)
public VoiceMaskBuiState(string name, string? verb)
{
Name = name;
Verb = verb;
}
}

[Serializable, NetSerializable]
public sealed class VoiceMaskChangeNameMessage : BoundUserInterfaceMessage
{
public string Name { get; }
public readonly string Name;

public VoiceMaskChangeNameMessage(string name)
{
Name = name;
}
}

/// <summary>
/// Change the speech verb prototype to override, or null to use the user's verb.
/// </summary>
[Serializable, NetSerializable]
public sealed class VoiceMaskChangeVerbMessage : BoundUserInterfaceMessage
{
public readonly string? Verb;

public VoiceMaskChangeVerbMessage(string? verb)
{
Verb = verb;
}
}
Loading
Loading