Allows AAC phrases to be combined (#3461)

* Allows AAC phrases to be combined

* Uses Index instead of TryIndex when ID guaranteed valid

* Removes unnecessary braces

* Reduces List reallocations

* Renames the backspace button to be less silly

---------

Co-authored-by: Oxdeception <9624-oxdeception@users.noreply.gitgud.io>
This commit is contained in:
Oxdeception 2025-04-16 11:55:23 -04:00 committed by GitHub
parent 7a17c7ba05
commit 55b889a4c9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 75 additions and 14 deletions

View File

@ -22,7 +22,7 @@ public sealed class AACBoundUserInterface : BoundUserInterface
_window.PhraseButtonPressed += OnPhraseButtonPressed;
}
private void OnPhraseButtonPressed(ProtoId<QuickPhrasePrototype> phraseId)
private void OnPhraseButtonPressed(List<ProtoId<QuickPhrasePrototype>> phraseId)
{
SendMessage(new AACTabletSendPhraseMessage(phraseId));
}

View File

@ -4,12 +4,20 @@
Resizable="True"
SetSize="540 300"
MinSize="540 300">
<TabContainer Name="WindowBody" TabTitle="Search" VerticalExpand="True" MouseFilter="Pass">
<BoxContainer Orientation="Vertical" Name="Search" MinSize="540 200">
<LineEdit Name="SearchBar" PlaceHolder="Search" HorizontalExpand="True" Margin="4 4" />
<ScrollContainer HorizontalExpand="True" VerticalExpand="True">
<BoxContainer Name="SearchResults" Orientation="Vertical" HorizontalExpand="True" />
</ScrollContainer>
<BoxContainer Orientation="Vertical">
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
<CheckBox Name="ShouldBuffer" Text="Combine"/>
<LineEdit Name="BufferedString" Editable="False" HorizontalExpand="True"/>
<Button Name="ClearButton" Text="Backspace" TextAlign="Center"/>
<Button Name="SendButton" Text="Send" TextAlign="Center"/>
</BoxContainer>
</TabContainer>
<TabContainer Name="WindowBody" TabTitle="Search" VerticalExpand="True" MouseFilter="Pass">
<BoxContainer Orientation="Vertical" Name="Search" MinSize="540 200">
<LineEdit Name="SearchBar" PlaceHolder="Search" HorizontalExpand="True" Margin="4 4" />
<ScrollContainer HorizontalExpand="True" VerticalExpand="True">
<BoxContainer Name="SearchResults" Orientation="Vertical" HorizontalExpand="True" />
</ScrollContainer>
</BoxContainer>
</TabContainer>
</BoxContainer>
</controls:FancyWindow>

View File

@ -16,7 +16,7 @@ public sealed partial class AACWindow : FancyWindow
[Dependency] private readonly IPrototypeManager _prototype = default!;
private readonly List<QuickPhrasePrototype> _phrases;
private readonly Dictionary<string, List<QuickPhrasePrototype>> _filteredPhrases = new();
public event Action<ProtoId<QuickPhrasePrototype>>? PhraseButtonPressed;
public event Action<List<ProtoId<QuickPhrasePrototype>>>? PhraseButtonPressed;
private const float SpaceWidth = 10f;
private const float ParentWidth = 540f;
@ -25,6 +25,9 @@ public sealed partial class AACWindow : FancyWindow
private const int ButtonWidth =
(int)((ParentWidth - SpaceWidth * 2) / ColumnCount - SpaceWidth * ((ColumnCount - 1f) / ColumnCount));
private readonly List<ProtoId<QuickPhrasePrototype>> _phraseBuffer = [];
private readonly List<ProtoId<QuickPhrasePrototype>> _phraseSingle = [];
public AACWindow()
{
RobustXamlLoader.Load(this);
@ -32,10 +35,38 @@ public sealed partial class AACWindow : FancyWindow
_phrases = _prototype.EnumeratePrototypes<QuickPhrasePrototype>().ToList();
_phrases.Sort((a, b) => string.CompareOrdinal(a.Group, b.Group));
SearchBar.OnTextChanged += FilterSearch;
SendButton.OnPressed += SendBuffer;
ClearButton.OnPressed += BackspaceBuffer;
PopulateGui();
FilterSearch(null);
}
private void BackspaceBuffer(BaseButton.ButtonEventArgs obj)
{
if (_phraseBuffer.Count == 0)
return;
_phraseBuffer.RemoveAt(_phraseBuffer.Count - 1);
UpdateBufferText();
}
private void UpdateBufferText()
{
BufferedString.Text = string.Empty;
foreach (var phraseId in _phraseBuffer)
{
var phrase = _prototype.Index(phraseId);
BufferedString.Text += Loc.GetString(phrase.Text) + " ";
}
}
private void SendBuffer(BaseButton.ButtonEventArgs obj)
{
PhraseButtonPressed?.Invoke(_phraseBuffer);
_phraseBuffer.Clear();
BufferedString.Text = string.Empty;
}
private void FilterSearch(LineEdit.LineEditEventArgs? obj)
{
SearchResults.DisposeAllChildren();
@ -184,6 +215,16 @@ public sealed partial class AACWindow : FancyWindow
private void OnPhraseButtonPressed(ProtoId<QuickPhrasePrototype> phraseId)
{
PhraseButtonPressed?.Invoke(phraseId);
if (ShouldBuffer.Pressed)
{
_phraseBuffer.Add(phraseId);
UpdateBufferText();
}
else
{
_phraseSingle.Clear();
_phraseSingle.Add(phraseId);
PhraseButtonPressed?.Invoke(_phraseSingle);
}
}
}

View File

@ -13,6 +13,8 @@ public sealed class AACTabletSystem : EntitySystem
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly IPrototypeManager _prototype = default!;
private readonly List<string> _localisedPhrases = [];
public override void Initialize()
{
base.Initialize();
@ -29,13 +31,23 @@ public sealed class AACTabletSystem : EntitySystem
("speaker", Name(ent)),
("originalName", senderName));
if (!_prototype.TryIndex(message.PhraseId, out var phrase))
_localisedPhrases.Clear();
foreach (var phraseProto in message.PhraseIds)
{
if (_prototype.TryIndex(phraseProto, out var phrase))
{
// Ensures each phrase is capitalised to maintain common AAC styling
_localisedPhrases.Add(_chat.SanitizeMessageCapital(Loc.GetString(phrase.Text)));
}
}
if (_localisedPhrases.Count <= 0)
return;
EnsureComp<VoiceOverrideComponent>(ent).NameOverride = speakerName;
_chat.TrySendInGameICMessage(ent,
Loc.GetString(phrase.Text),
string.Join(" ", _localisedPhrases),
InGameICChatType.Speak,
hideChat: false,
nameOverride: speakerName);

View File

@ -11,7 +11,7 @@ public enum AACTabletKey : byte
}
[Serializable, NetSerializable]
public sealed class AACTabletSendPhraseMessage(ProtoId<QuickPhrasePrototype> phraseId) : BoundUserInterfaceMessage
public sealed class AACTabletSendPhraseMessage(List<ProtoId<QuickPhrasePrototype>> phraseIds) : BoundUserInterfaceMessage
{
public ProtoId<QuickPhrasePrototype> PhraseId = phraseId;
public List<ProtoId<QuickPhrasePrototype>> PhraseIds = phraseIds;
}