mirror of
https://github.com/corvax-team/ss14-wl.git
synced 2026-02-14 19:29:57 +01:00
Dynamic description (#246)
* Add Dynamic Text * add UI for entering a dynamic description * work UI * work DynamicText * fixed client * final bugfix * mini change * Okay... Again mini change * fix request DynamicText * add limit Dynamic text
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
<Control Name="CFlavorText" xmlns="https://spacestation14.io">
|
||||
<Control Name="CFlavorText" xmlns="https://spacestation14.io">
|
||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True">
|
||||
<!-- WL-OOCText-Start -->
|
||||
<Label Text="{Loc 'flavor-tab-flavor-text'}" Margin="5 5 0 0" />
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Linq;
|
||||
using Content.Client._WL.DynamicText.UI; // WL-Chages
|
||||
using Content.Client.CharacterInfo;
|
||||
using Content.Client.Gameplay;
|
||||
using Content.Client.Stylesheets;
|
||||
@@ -19,6 +19,7 @@ using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Shared.Input.Binding;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
using System.Linq;
|
||||
using static Content.Client.CharacterInfo.CharacterInfoSystem;
|
||||
using static Robust.Client.UserInterface.Controls.BaseButton;
|
||||
|
||||
@@ -31,6 +32,10 @@ public sealed class CharacterUIController : UIController, IOnStateEntered<Gamepl
|
||||
[Dependency] private readonly IPlayerManager _player = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
|
||||
//WL-Changes-Start
|
||||
[Dependency] private readonly DynamicTextUIController _dynamicText = default!;
|
||||
//WL-Changes-end
|
||||
|
||||
[UISystemDependency] private readonly CharacterInfoSystem _characterInfo = default!;
|
||||
[UISystemDependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
@@ -54,6 +59,13 @@ public sealed class CharacterUIController : UIController, IOnStateEntered<Gamepl
|
||||
_window.OnClose += DeactivateButton;
|
||||
_window.OnOpen += ActivateButton;
|
||||
|
||||
//WL-Changes-Start
|
||||
_window.DynamicTextButton.OnPressed += _ =>
|
||||
{
|
||||
_dynamicText.OpenWindow();
|
||||
};
|
||||
//WL-Changes-End
|
||||
|
||||
CommandBinds.Builder
|
||||
.Bind(ContentKeyFunctions.OpenCharacterMenu,
|
||||
InputCmdHandler.FromDelegate(_ => ToggleWindow()))
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
<BoxContainer Orientation="Vertical" VerticalAlignment="Top">
|
||||
<Label Name="NameLabel" Access="Public"/>
|
||||
<Label Name="SubText" VerticalAlignment="Top" StyleClasses="LabelSubText" Access="Public"/>
|
||||
<!--WL-Change-Start-->
|
||||
<Button Access="Public" Name="DynamicTextButton" Text="{Loc 'character-info-dynamic-text-button'}"/>
|
||||
<!--WL-Change-End-->
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
<Label Name="ObjectivesLabel" Access="Public" Text="{Loc 'character-info-objectives-label'}" HorizontalAlignment="Center"/>
|
||||
|
||||
@@ -32,5 +32,17 @@
|
||||
<RichTextLabel Name="OocText" HorizontalExpand="True" Margin="8" />
|
||||
</BoxContainer>
|
||||
</ScrollContainer>
|
||||
|
||||
<ScrollContainer HorizontalExpand="True" HScrollEnabled="False" MinWidth="400">
|
||||
<BoxContainer Orientation="Vertical">
|
||||
<Label
|
||||
Name="DynamicTextLabel"
|
||||
HorizontalExpand="True"
|
||||
Text="{Loc 'character-information-ui-dynamic-text'}"
|
||||
Margin="0 10 0 0"
|
||||
HorizontalAlignment="Center" />
|
||||
<RichTextLabel Name="DynamicText" HorizontalExpand="True" Margin="8" />
|
||||
</BoxContainer>
|
||||
</ScrollContainer>
|
||||
</TabContainer>
|
||||
</controls:FancyWindow>
|
||||
|
||||
@@ -23,6 +23,7 @@ public sealed partial class CharacterInformationWindow : FancyWindow
|
||||
Tabs.SetTabTitle(0, Loc.GetString("character-information-ui-sprite"));
|
||||
Tabs.SetTabTitle(1, Loc.GetString("character-information-ui-flavor-text"));
|
||||
Tabs.SetTabTitle(2, Loc.GetString("character-information-ui-ooc-text"));
|
||||
Tabs.SetTabTitle(3, Loc.GetString("character-information-ui-dynamic-text"));
|
||||
}
|
||||
|
||||
protected override void FrameUpdate(FrameEventArgs args)
|
||||
@@ -60,6 +61,17 @@ public sealed partial class CharacterInformationWindow : FancyWindow
|
||||
OocTextLabel.Text = Loc.GetString("character-information-ui-no-ooc-text");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(state.DynamicText))
|
||||
{
|
||||
DynamicText.SetMessage(state.DynamicText);
|
||||
DynamicTextLabel.Text = Loc.GetString("character-information-ui-dynamic-text") + ":";
|
||||
}
|
||||
else
|
||||
{
|
||||
DynamicText.SetMessage("");
|
||||
DynamicTextLabel.Text = Loc.GetString("character-information-ui-no-dynamic-text");
|
||||
}
|
||||
|
||||
SetWidth = Size.X + 0.1f;
|
||||
}
|
||||
}
|
||||
|
||||
47
Content.Client/_WL/DynamicText/DynamicTextSystem.cs
Normal file
47
Content.Client/_WL/DynamicText/DynamicTextSystem.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using Content.Client._WL.DynamicText.UI;
|
||||
using Content.Shared._WL.DynamicText;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Client.UserInterface;
|
||||
|
||||
namespace Content.Client._WL.DynamicText;
|
||||
public sealed partial class DynamicTextSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _ent = default!;
|
||||
[Dependency] private readonly IPlayerManager _player = default!;
|
||||
[Dependency] private readonly IUserInterfaceManager _userInterfaceManager = default!;
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeNetworkEvent<RequestedDynamicTextEvent>(OnDynamicTextReceived);
|
||||
}
|
||||
|
||||
public void SaveDynamicText(string text)
|
||||
{
|
||||
if (!_player.LocalEntity.HasValue)
|
||||
return;
|
||||
|
||||
if (!_ent.TryGetNetEntity(_player.LocalEntity.Value, out var netEntity))
|
||||
return;
|
||||
|
||||
if (text is null)
|
||||
return;
|
||||
|
||||
RaiseNetworkEvent(new SetDynamicTextEvent(netEntity.Value, text));
|
||||
}
|
||||
public void RequestDynamicText()
|
||||
{
|
||||
if (!_player.LocalEntity.HasValue)
|
||||
return;
|
||||
|
||||
if (!_ent.TryGetNetEntity(_player.LocalEntity.Value, out var netEntity))
|
||||
return;
|
||||
|
||||
RaiseNetworkEvent(new RequestDynamicTextEvent(netEntity.Value));
|
||||
}
|
||||
public void OnDynamicTextReceived(RequestedDynamicTextEvent ev, EntitySessionEventArgs args)
|
||||
{
|
||||
_userInterfaceManager.GetUIController<DynamicTextUIController>().SetDynamicText(ev.DynamicText);
|
||||
}
|
||||
|
||||
}
|
||||
33
Content.Client/_WL/DynamicText/UI/DynamicTextUIController.cs
Normal file
33
Content.Client/_WL/DynamicText/UI/DynamicTextUIController.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using Content.Shared._WL.DynamicText;
|
||||
using Robust.Client.UserInterface.Controllers;
|
||||
|
||||
namespace Content.Client._WL.DynamicText.UI;
|
||||
|
||||
public sealed class DynamicTextUIController : UIController
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entManager = default!;
|
||||
|
||||
private DynamicTextWindow? _dynamicTextWindow;
|
||||
|
||||
public void OpenWindow()
|
||||
{
|
||||
if (_dynamicTextWindow == null || _dynamicTextWindow.Disposed)
|
||||
_dynamicTextWindow = UIManager.CreateWindow<DynamicTextWindow>();
|
||||
|
||||
if (_dynamicTextWindow != null)
|
||||
{
|
||||
_dynamicTextWindow.OnDynamicTextSaveButtonPressed += OnSave;
|
||||
}
|
||||
_entManager.System<DynamicTextSystem>().RequestDynamicText();
|
||||
_dynamicTextWindow?.OpenCentered();
|
||||
}
|
||||
public void SetDynamicText(string text)
|
||||
{
|
||||
_dynamicTextWindow?.SetDynamicText(text);
|
||||
}
|
||||
|
||||
private void OnSave(string text)
|
||||
{
|
||||
_entManager.System<DynamicTextSystem>().SaveDynamicText(text);
|
||||
}
|
||||
}
|
||||
24
Content.Client/_WL/DynamicText/UI/DynamicTextWindow.xaml
Normal file
24
Content.Client/_WL/DynamicText/UI/DynamicTextWindow.xaml
Normal file
@@ -0,0 +1,24 @@
|
||||
<controls:FancyWindow xmlns="https://spacestation14.io"
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
Title="{Loc 'dynamic-text-title'}"
|
||||
MinSize="700 350"
|
||||
SetSize="700 350">
|
||||
<BoxContainer Orientation="Vertical"
|
||||
HorizontalExpand="True"
|
||||
VerticalExpand="True"
|
||||
Margin="5 0 5 0">
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" VerticalExpand="True">
|
||||
<TextEdit Name="CDynamicTextInput" Access="Public" MinSize="220 100" HorizontalExpand="True" Margin="5 5 0 0" VerticalExpand="True" />
|
||||
</BoxContainer>
|
||||
<Control MinHeight="10"/>
|
||||
<BoxContainer Orientation="Vertical">
|
||||
<PanelContainer StyleClasses="LowDivider" />
|
||||
<BoxContainer Orientation="Horizontal" Margin="10 2 5 0" VerticalAlignment="Bottom">
|
||||
<Label Text="" StyleClasses="WindowFooterText"
|
||||
HorizontalAlignment="Left" HorizontalExpand="True" Margin="0 0 5 0" />
|
||||
<Button Access="Public" Name="DynamicTextSaveButton" Text="{Loc 'dynamic-text-save-button'}" VerticalAlignment="Center" HorizontalAlignment="Right"/>
|
||||
<Button Access="Public" Name="DynamicTextCloseButton" Text="{Loc 'dynamic-text-close-button'}" VerticalAlignment="Center" HorizontalAlignment="Right"/>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</controls:FancyWindow>
|
||||
38
Content.Client/_WL/DynamicText/UI/DynamicTextWindow.xaml.cs
Normal file
38
Content.Client/_WL/DynamicText/UI/DynamicTextWindow.xaml.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
|
||||
namespace Content.Client._WL.DynamicText.UI;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class DynamicTextWindow : FancyWindow
|
||||
{
|
||||
public Action<string>? OnDynamicTextSaveButtonPressed;
|
||||
public DynamicTextWindow()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
var loc = IoCManager.Resolve<ILocalizationManager>();
|
||||
|
||||
CDynamicTextInput.Placeholder = new Rope.Leaf(loc.GetString("dynamic-text-placeholder"));
|
||||
DynamicTextSaveButton.OnPressed += OnDynamicTextSave;
|
||||
DynamicTextCloseButton.OnPressed += OnClose;
|
||||
}
|
||||
public void SetDynamicText(string text)
|
||||
{
|
||||
CDynamicTextInput.TextRope = new Rope.Leaf(text);
|
||||
}
|
||||
|
||||
private void OnDynamicTextSave(BaseButton.ButtonEventArgs obj)
|
||||
{
|
||||
OnDynamicTextSaveButtonPressed?.Invoke(Rope.Collapse(CDynamicTextInput.TextRope).Trim());
|
||||
}
|
||||
|
||||
private void OnClose(BaseButton.ButtonEventArgs obj)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Content.Server._WL.CharacterInformation;
|
||||
namespace Content.Server._WL.CharacterInformation;
|
||||
|
||||
/// <summary>
|
||||
/// Adds examine details verb and store information that can be accessed without mob actor
|
||||
@@ -13,4 +13,8 @@ public sealed partial class CharacterInformationComponent : Component
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("oocText")]
|
||||
public string OocText = string.Empty;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("dynamicText")]
|
||||
public string DynamicText = string.Empty;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public sealed class CharacterInformationSystem : EntitySystem
|
||||
return;
|
||||
|
||||
var charName = Identity.Name(targetUid, EntityManager);
|
||||
var state = new CharacterInformationBuiState(GetNetEntity(targetUid), charName, charInfo.FlavorText, charInfo.OocText);
|
||||
var state = new CharacterInformationBuiState(GetNetEntity(targetUid), charName, charInfo.FlavorText, charInfo.OocText, charInfo.DynamicText);
|
||||
_userInterfaceSystem.SetUiState(uid, CharacterInformationUiKey.Key, state);
|
||||
}
|
||||
}
|
||||
|
||||
52
Content.Server/_WL/DynamicText/DynamicTextSystem.cs
Normal file
52
Content.Server/_WL/DynamicText/DynamicTextSystem.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using Content.Server._WL.CharacterInformation;
|
||||
using Content.Shared._WL.CCVars;
|
||||
using Content.Shared._WL.DynamicText;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Server._WL.DynamicText;
|
||||
|
||||
public sealed class DynamicTextSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _ent = default!;
|
||||
[Dependency] private readonly IConfigurationManager _cfm = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeNetworkEvent<SetDynamicTextEvent>(SetDynamicText);
|
||||
SubscribeNetworkEvent<RequestDynamicTextEvent>(RequestDynamicText);
|
||||
}
|
||||
|
||||
private void SetDynamicText(SetDynamicTextEvent ev, EntitySessionEventArgs args)
|
||||
{
|
||||
if (!_ent.TryGetEntity(ev.Entity, out var ent))
|
||||
return;
|
||||
|
||||
if (!TryComp<CharacterInformationComponent>(ent, out var comp))
|
||||
return;
|
||||
|
||||
if (args.SenderSession.AttachedEntity != ent)
|
||||
return;
|
||||
|
||||
var maxDynamicTextLength = _cfm.GetCVar(WLCVars.MaxDynamicTextLength);
|
||||
|
||||
comp.DynamicText = ev.DynamicText.Length > maxDynamicTextLength ? FormattedMessage.RemoveMarkupOrThrow(ev.DynamicText)[..maxDynamicTextLength] : FormattedMessage.RemoveMarkupOrThrow(ev.DynamicText);
|
||||
}
|
||||
|
||||
private void RequestDynamicText(RequestDynamicTextEvent ev, EntitySessionEventArgs args)
|
||||
{
|
||||
if (!_ent.TryGetEntity(ev.Entity, out var ent))
|
||||
return;
|
||||
|
||||
if (args.SenderSession.AttachedEntity != ent)
|
||||
return;
|
||||
|
||||
if (!TryComp<CharacterInformationComponent>(ent, out var comp))
|
||||
return;
|
||||
|
||||
RaiseNetworkEvent(new RequestedDynamicTextEvent(comp.DynamicText ?? string.Empty), Filter.SinglePlayer(args.SenderSession));
|
||||
}
|
||||
}
|
||||
@@ -138,4 +138,11 @@ public sealed class WLCVars
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> VoteShuttleTimer =
|
||||
CVarDef.Create("vote.evacuation_shuttle_vote_time", 40, CVar.SERVERONLY);
|
||||
|
||||
/*
|
||||
* Ic
|
||||
*/
|
||||
|
||||
public static readonly CVarDef<int> MaxDynamicTextLength =
|
||||
CVarDef.Create("ic.dynamic_text_length", 1024, CVar.SERVER | CVar.REPLICATED);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._WL.CharacterInformation;
|
||||
|
||||
@@ -15,16 +15,19 @@ public sealed class CharacterInformationBuiState : BoundUserInterfaceState
|
||||
public string CharacterName;
|
||||
public string FlavorText;
|
||||
public string? OocText;
|
||||
public string? DynamicText;
|
||||
|
||||
public CharacterInformationBuiState(
|
||||
NetEntity uid,
|
||||
string characterName,
|
||||
string flavorText,
|
||||
string? oocText)
|
||||
string? oocText,
|
||||
string? dynamicText)
|
||||
{
|
||||
Uid = uid;
|
||||
CharacterName = characterName;
|
||||
FlavorText = flavorText;
|
||||
OocText = oocText;
|
||||
DynamicText = dynamicText;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._WL.DynamicText;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class RequestDynamicTextEvent(NetEntity entity) : EntityEventArgs
|
||||
{
|
||||
public NetEntity Entity { get; } = entity;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._WL.DynamicText;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class RequestedDynamicTextEvent(string dynamicText) : EntityEventArgs
|
||||
{
|
||||
public string DynamicText { get; } = dynamicText;
|
||||
}
|
||||
10
Content.Shared/_WL/DynamicText/SetDynamicTextEvent.cs
Normal file
10
Content.Shared/_WL/DynamicText/SetDynamicTextEvent.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._WL.DynamicText;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class SetDynamicTextEvent(NetEntity netEntity, string dynamicText) : EntityEventArgs
|
||||
{
|
||||
public NetEntity Entity { get; } = netEntity;
|
||||
public string DynamicText { get; } = dynamicText;
|
||||
}
|
||||
@@ -1,6 +1,10 @@
|
||||
character-information-ui-title = Информация о персонаже
|
||||
character-information-ui-flavor-text = Описание персонажа
|
||||
character-information-ui-ooc-text = OOC заметки
|
||||
character-information-ui-dynamic-text = Динамические заметки
|
||||
character-information-ui-sprite = Спрайт
|
||||
character-information-ui-no-flavor-text = Описания персонажа нет
|
||||
character-information-ui-no-ooc-text = ООС заметок нет
|
||||
character-information-ui-no-dynamic-text = Динамических заметок нет
|
||||
|
||||
character-info-dynamic-text-button = Динамическое описание
|
||||
|
||||
4
Resources/Locale/ru-RU/_WL/dynamic-text/dynamic-text.ftl
Normal file
4
Resources/Locale/ru-RU/_WL/dynamic-text/dynamic-text.ftl
Normal file
@@ -0,0 +1,4 @@
|
||||
dynamic-text-title = Динамическое описание
|
||||
dynamic-text-save-button = Сохранить
|
||||
dynamic-text-close-button = Закрыть
|
||||
dynamic-text-placeholder = Динамическое описание
|
||||
Reference in New Issue
Block a user