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

RenameStart #2343

Merged
merged 5 commits into from
Dec 15, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
22 changes: 22 additions & 0 deletions Content.Client/SS220/DialogWindowDescUI/DialogWindowDesc.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!--© SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt-->
<controls:FancyWindow
xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
MinSize="200 200">
<BoxContainer Orientation="Vertical" Margin="8">
<BoxContainer Name="Prompts" Orientation="Vertical"/>
<BoxContainer Orientation="Vertical"
HorizontalExpand="True"
VerticalExpand="True">
<BoxContainer MinHeight="20"></BoxContainer>
<Button Name="OkButton"
Text="{Loc 'quick-dialog-ui-confirm'}"
StyleClasses="OpenBoth"
MaxWidth="120"
HorizontalAlignment="Center"
VerticalExpand="False"
HorizontalExpand="False">
</Button>
</BoxContainer>
</BoxContainer>
</controls:FancyWindow>
84 changes: 84 additions & 0 deletions Content.Client/SS220/DialogWindowDescUI/DialogWindowDesc.xaml.cs
stalengd marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
using Content.Shared.Administration;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Content.Client.UserInterface.Controls;

namespace Content.Client.SS220.DialogWindowDescUI;

/// <summary>
/// A modified <see cref="DialogWindow"/> window in which you can send an additional description to explain a particular action being performed
/// </summary>
[GenerateTypedNameReferences]
public sealed partial class DialogWindowDesc : FancyWindow
{
private List<(string, LineEdit)> _promptLines;

private bool _finished;

public Action<Dictionary<string, string>>? OnConfirmed;

public Action? OnCancelled;

public DialogWindowDesc(string title, string dsscEntty, List<QuickDialogEntry> entries, bool ok = true)
{
RobustXamlLoader.Load(this);

Title = title;

OkButton.Visible = ok;

_promptLines = new(entries.Count);

for (int i = 0; i < entries.Count; i++)
{
var entry = entries[i];

var box = new BoxContainer();
box.AddChild(new Label() { Text = entry.Prompt, Align = Label.AlignMode.Center, HorizontalExpand = true});
Prompts.AddChild(box);

var boxDesc = new BoxContainer();
boxDesc.AddChild(new Label() { Text = dsscEntty, Align = Label.AlignMode.Center, FontColorOverride = Color.Gray, HorizontalExpand = true });
Prompts.AddChild(boxDesc);

var boxEmpty = new BoxContainer();
boxEmpty.AddChild(new BoxContainer() {MinHeight=20});
Prompts.AddChild(boxEmpty);

var boxEdit = new BoxContainer();
var edit = new LineEdit() { HorizontalExpand = true };
boxEdit.AddChild(edit);

_promptLines.Add((entry.FieldId, edit));
Prompts.AddChild(boxEdit);
}

OkButton.OnPressed += _ => Confirm();

OnClose += () =>
{
if (!_finished)
OnCancelled?.Invoke();
};

_promptLines[0].Item2.GrabKeyboardFocus();

OpenCentered();
}

private void Confirm()
{
var results = new Dictionary<string, string>();
foreach (var (field, edit) in _promptLines)
{
results[field] = edit.Text;
}

_finished = true;
OnConfirmed?.Invoke(results);
Close();
}
}

35 changes: 35 additions & 0 deletions Content.Client/SS220/QuickDialog/QuickDialogSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
using Content.Client.SS220.DialogWindowDescUI;
using Content.Shared.Administration;

namespace Content.Client.SS220.QuickDialog;

public sealed class QuickDialogSystem : EntitySystem
{
/// <inheritdoc/>
public override void Initialize()
{
SubscribeNetworkEvent<QuickDialogDescOpenEvent>(OpenDialog);
}

private void OpenDialog(QuickDialogDescOpenEvent ev)
{
var ok = (ev.Buttons & QuickDialogButtonFlag.OkButton) != 0;
var window = new DialogWindowDesc(ev.Title, ev.Description, ev.Prompts, ok: ok);

window.OnConfirmed += responses =>
{
RaiseNetworkEvent(new QuickDialogResponseEvent(ev.DialogId,
responses,
QuickDialogButtonFlag.OkButton));
};

window.OnCancelled += () =>
{
RaiseNetworkEvent(new QuickDialogResponseEvent(ev.DialogId,
new(),
QuickDialogButtonFlag.CancelButton));
};
}
}

29 changes: 29 additions & 0 deletions Content.Server/Administration/QuickDialogSystem.OpenDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,33 @@ public void OpenDialog<T1, T2, T3, T4>(ICommonSession session, string title, str
cancelAction ?? (() => { })
);
}

//SS220-RenameStart - start
[PublicAPI]
public void OpenDialog<T1>(ICommonSession session, string title, string description, string prompt, Action<T1> okAction,
Action? cancelAction = null)
{
OpenDialogInternal(
session,
title,
description,
new List<QuickDialogEntry>
{
new("1", TypeToEntryType(typeof(T1)), prompt)
},
QuickDialogButtonFlag.OkButton | QuickDialogButtonFlag.CancelButton,
(ev =>
{
if (TryParseQuickDialog<T1>(TypeToEntryType(typeof(T1)), ev.Responses["1"], out var v1))
okAction.Invoke(v1);
else
{
session.Channel.Disconnect("Replied with invalid quick dialog data.");
cancelAction?.Invoke();
}
}),
cancelAction ?? (() => { })
);
}
//SS220-RenameStart - end
}
22 changes: 22 additions & 0 deletions Content.Server/Administration/QuickDialogSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,28 @@ private void OpenDialogInternal(ICommonSession session, string title, List<Quick
_openDialogsByUser[session.UserId].Add(did);
}

//SS220-RenameStart - start
private void OpenDialogInternal(ICommonSession session, string title, string description, List<QuickDialogEntry> entries, QuickDialogButtonFlag buttons, Action<QuickDialogResponseEvent> okAction, Action cancelAction)
{
var did = GetDialogId();
RaiseNetworkEvent(
new QuickDialogDescOpenEvent(
title,
description,
entries,
did,
buttons),
session
);

_openDialogs.Add(did, (okAction, cancelAction));
if (!_openDialogsByUser.ContainsKey(session.UserId))
_openDialogsByUser.Add(session.UserId, new List<int>());

_openDialogsByUser[session.UserId].Add(did);
}
//SS220-RenameStart - end

private bool TryParseQuickDialog<T>(QuickDialogEntryType entryType, string input, [NotNullWhen(true)] out T? output)
{
switch (entryType)
Expand Down
17 changes: 17 additions & 0 deletions Content.Server/SS220/RenameStart/RenameStartComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
using Content.Shared.Preferences;

namespace Content.Server.SS220.RenameStart;

/// <summary>
/// This is used for change the entity name once the player starts controlling
/// </summary>
[RegisterComponent]
public sealed partial class RenameStartComponent : Component
{
[DataField]
public int MinChar = 2;

[DataField]
public int MaxChar = HumanoidCharacterProfile.MaxNameLength;
}
90 changes: 90 additions & 0 deletions Content.Server/SS220/RenameStart/RenameStartSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
using System.Text.RegularExpressions;
using Content.Server.Administration;
using Content.Server.Administration.Systems;
using Content.Shared.Administration;
using Content.Shared.Mind;
using Content.Shared.Mind.Components;
using Robust.Shared.Player;

namespace Content.Server.SS220.RenameStart;

/// <summary>
/// This handles opens the ui to change your name at the beginning of the game. Renaming is necessary for such roles as a clown with a “custom” name
/// </summary>
public sealed class RenameStartSystem : EntitySystem
{
[Dependency] private readonly QuickDialogSystem _quickDialog = default!;
[Dependency] private readonly MetaDataSystem _meta = default!;
[Dependency] private readonly AdminFrozenSystem _frozen = default!;
private static readonly Regex Expressions = new("[^А-Яа-яёЁ0-9' \\-?!,.]");
/// <inheritdoc/>
public override void Initialize()
{
SubscribeLocalEvent<RenameStartComponent, PlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<RenameStartComponent, ComponentShutdown>(OnRemoveComponent);
}

private void OnPlayerAttached(Entity<RenameStartComponent> ent, ref PlayerAttachedEvent args)
{
_frozen.FreezeAndMute(ent.Owner); //prevent players from changing their name after showing up with their initial name

ChangeName(ent.Owner);
}

private void ChangeName(EntityUid entOwner)
{
if(!TryComp<ActorComponent>(entOwner, out var actorComp))
{
RemComp<RenameStartComponent>(entOwner);
return;
}

if(!TryComp<RenameStartComponent>(entOwner, out var renameComp))
{
RemComp<RenameStartComponent>(entOwner);
return;
}

_quickDialog.OpenDialog(actorComp.PlayerSession,
Loc.GetString("rename-window-title"),
description: Loc.GetString("rename-window-desc"),
Loc.GetString("rename-window-promt"),
(LongString newName) =>
{
if (newName.String.Length < renameComp.MinChar ||
newName.String.Length > renameComp.MaxChar ||
Expressions.IsMatch(newName.String))
{
ChangeName(entOwner);
return;
}

if(!TryComp<MindContainerComponent>(entOwner, out var mindContComp))
{
RemComp<RenameStartComponent>(entOwner);
return;
}

if (!TryComp<MindComponent>(mindContComp.Mind, out var mindComp))
{
RemComp<RenameStartComponent>(entOwner);
return;
}

mindComp.CharacterName = newName.String;

_meta.SetEntityName(entOwner, newName);

RemComp<RenameStartComponent>(entOwner);
}, () =>
{
RemComp<RenameStartComponent>(entOwner);
});
}

private void OnRemoveComponent(Entity<RenameStartComponent> ent, ref ComponentShutdown args)
{
RemComp<AdminFrozenComponent>(ent.Owner);
}
}
40 changes: 40 additions & 0 deletions Content.Shared/Administration/QuickDialogOpenEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,46 @@ public QuickDialogOpenEvent(string title, List<QuickDialogEntry> prompts, int di
}
}

//SS220-RenameStart - start
[Serializable, NetSerializable]
public sealed class QuickDialogDescOpenEvent : EntityEventArgs
{
/// <summary>
/// The title of the dialog.
/// </summary>
public string Title;

/// <summary>
/// The title of the dialog.
/// </summary>
public string Description;

/// <summary>
/// The internal dialog ID.
/// </summary>
public int DialogId;

/// <summary>
/// The prompts to show the user.
/// </summary>
public List<QuickDialogEntry> Prompts;

/// <summary>
/// The buttons presented for the user.
/// </summary>
public QuickDialogButtonFlag Buttons = QuickDialogButtonFlag.OkButton | QuickDialogButtonFlag.CancelButton;

public QuickDialogDescOpenEvent(string title, string description, List<QuickDialogEntry> prompts, int dialogId, QuickDialogButtonFlag buttons)
{
Title = title;
Description = description;
Prompts = prompts;
Buttons = buttons;
DialogId = dialogId;
}
}
//SS220-RenameStart - end

/// <summary>
/// A networked event raised when the client replies to a quick dialog.
/// </summary>
Expand Down
1 change: 1 addition & 0 deletions Resources/Locale/ru-RU/ss220/quick-dialog/quick-dialog.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
quick-dialog-ui-confirm = Подтвердить
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
rename-window-title = Переименование
rename-window-promt = Выберите свое новое имя
rename-window-desc =
Ваше имя не должно нарушать 4 пункт правил:
Ваш персонаж - находится на передовой космической станции.
Клоуну и миму предоставляется более широкое поле для мемных имён
Имена синтетиков так же имеют свою специфику. Ознакомьтесь с ними на вики.
1 change: 1 addition & 0 deletions Resources/Prototypes/Roles/Jobs/Civilian/clown.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
special:
- !type:AddComponentSpecial
components:
- type: RenameStart #SS220-RenameStart
- type: Clumsy
clumsyDamage:
types: #literally just picked semi random valus. i tested this once and tweaked it.
Expand Down
1 change: 1 addition & 0 deletions Resources/Prototypes/Roles/Jobs/Civilian/mime.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
components:
- type: MimePowers
- type: FrenchAccent
- type: RenameStart #SS220-RenameStart

- type: startingGear
id: MimeGear
Expand Down
Loading
Loading