Knowledge UI (#779)
* knowledge button in HUD * ui controller * bugfixes * finish * all-knowing ghosts * Create knowledge-ui.ftl
This commit is contained in:
@@ -123,6 +123,10 @@ namespace Content.Client.Input
|
||||
common.AddFunction(ContentKeyFunctions.OpenDecalSpawnWindow);
|
||||
common.AddFunction(ContentKeyFunctions.OpenAdminMenu);
|
||||
common.AddFunction(ContentKeyFunctions.OpenGuidebook);
|
||||
|
||||
//CP14 Keys
|
||||
human.AddFunction(ContentKeyFunctions.CP14OpenKnowledgeMenu);
|
||||
//CP14 Keys end
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,6 +265,11 @@ namespace Content.Client.Options.UI.Tabs
|
||||
AddButton(EngineKeyFunctions.HideUI);
|
||||
AddButton(ContentKeyFunctions.InspectEntity);
|
||||
|
||||
//CP14
|
||||
AddHeader("ui-options-header-cp14");
|
||||
AddButton(ContentKeyFunctions.CP14OpenKnowledgeMenu);
|
||||
//CP14 end
|
||||
|
||||
foreach (var control in _keyControls.Values)
|
||||
{
|
||||
UpdateKeyControl(control);
|
||||
|
||||
@@ -24,6 +24,7 @@ public sealed class GameTopMenuBarUIController : UIController
|
||||
[Dependency] private readonly SandboxUIController _sandbox = default!;
|
||||
[Dependency] private readonly GuidebookUIController _guidebook = default!;
|
||||
[Dependency] private readonly EmotesUIController _emotes = default!;
|
||||
[Dependency] private readonly CP14KnowledgeUIController _knowledge = default!; //CP14
|
||||
|
||||
private GameTopMenuBar? GameTopMenuBar => UIManager.GetActiveUIWidgetOrNull<GameTopMenuBar>();
|
||||
|
||||
@@ -47,6 +48,7 @@ public sealed class GameTopMenuBarUIController : UIController
|
||||
_action.UnloadButton();
|
||||
_sandbox.UnloadButton();
|
||||
_emotes.UnloadButton();
|
||||
_knowledge.UnloadButton(); //CP14
|
||||
}
|
||||
|
||||
public void LoadButtons()
|
||||
@@ -60,5 +62,6 @@ public sealed class GameTopMenuBarUIController : UIController
|
||||
_action.LoadButton();
|
||||
_sandbox.LoadButton();
|
||||
_emotes.LoadButton();
|
||||
_knowledge.LoadButton(); //CP14
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,18 @@
|
||||
HorizontalExpand="True"
|
||||
AppendStyleClass="{x:Static style:StyleBase.ButtonSquare}"
|
||||
/>
|
||||
<!-- CP14 UI part -->
|
||||
<ui:MenuButton
|
||||
Name="CP14KnowledgeButton"
|
||||
Access="Internal"
|
||||
Icon="{xe:Tex '/Textures/Interface/students-cap.svg.192dpi.png'}"
|
||||
ToolTip="{Loc 'cp14-game-hud-open-knowledge-menu-button-tooltip'}"
|
||||
BoundKey = "{x:Static is:ContentKeyFunctions.CP14OpenKnowledgeMenu}"
|
||||
MinSize="42 64"
|
||||
HorizontalExpand="True"
|
||||
AppendStyleClass="{x:Static style:StyleBase.ButtonSquare}"
|
||||
/>
|
||||
<!-- CP14 UI part end -->
|
||||
<ui:MenuButton
|
||||
Name="CharacterButton"
|
||||
Access="Internal"
|
||||
|
||||
@@ -1,7 +1,42 @@
|
||||
using Content.Shared._CP14.Knowledge;
|
||||
using Content.Shared._CP14.Knowledge.Prototypes;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client._CP14.Knowledge;
|
||||
|
||||
public sealed partial class ClientCP14KnowledgeSystem : SharedCP14KnowledgeSystem
|
||||
{
|
||||
[Dependency] private readonly IPlayerManager _players = default!;
|
||||
|
||||
public event Action<KnowledgeData>? OnKnowledgeUpdate;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeNetworkEvent<CP14KnowledgeInfoEvent>(OnCharacterKnowledgeEvent);
|
||||
}
|
||||
|
||||
public void RequestKnowledgeInfo()
|
||||
{
|
||||
var entity = _players.LocalEntity;
|
||||
if (entity is null)
|
||||
return;
|
||||
|
||||
RaiseNetworkEvent(new RequestKnowledgeInfoEvent(GetNetEntity(entity.Value)));
|
||||
}
|
||||
|
||||
private void OnCharacterKnowledgeEvent(CP14KnowledgeInfoEvent msg, EntitySessionEventArgs args)
|
||||
{
|
||||
var entity = GetEntity(msg.NetEntity);
|
||||
var data = new KnowledgeData(entity, msg.AllKnowledge);
|
||||
|
||||
OnKnowledgeUpdate?.Invoke(data);
|
||||
}
|
||||
|
||||
public readonly record struct KnowledgeData(
|
||||
EntityUid Entity,
|
||||
HashSet<ProtoId<CP14KnowledgePrototype>> AllKnowledges
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
using Content.Client._CP14.Knowledge;
|
||||
using Content.Client._CP14.UserInterface.Systems.Knowledge.Windows;
|
||||
using Content.Client.Gameplay;
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Shared.Input;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controllers;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Shared.Input.Binding;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client.UserInterface.Systems.Character;
|
||||
|
||||
[UsedImplicitly]
|
||||
public sealed class CP14KnowledgeUIController : UIController, IOnStateEntered<GameplayState>, IOnStateExited<GameplayState>,
|
||||
IOnSystemChanged<ClientCP14KnowledgeSystem>
|
||||
{
|
||||
[Dependency] private readonly IPlayerManager _player = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
[UISystemDependency] private readonly ClientCP14KnowledgeSystem _knowledge = default!;
|
||||
|
||||
private CP14KnowledgeWindow? _window;
|
||||
|
||||
private MenuButton? KnowledgeButton => UIManager.GetActiveUIWidgetOrNull<MenuBar.Widgets.GameTopMenuBar>()?.CP14KnowledgeButton;
|
||||
|
||||
public void OnStateEntered(GameplayState state)
|
||||
{
|
||||
DebugTools.Assert(_window == null);
|
||||
|
||||
_window = UIManager.CreateWindow<CP14KnowledgeWindow>();
|
||||
LayoutContainer.SetAnchorPreset(_window, LayoutContainer.LayoutPreset.CenterTop);
|
||||
|
||||
CommandBinds.Builder
|
||||
.Bind(ContentKeyFunctions.CP14OpenKnowledgeMenu,
|
||||
InputCmdHandler.FromDelegate(_ => ToggleWindow()))
|
||||
.Register<CP14KnowledgeUIController>();
|
||||
}
|
||||
|
||||
public void OnStateExited(GameplayState state)
|
||||
{
|
||||
if (_window != null)
|
||||
{
|
||||
_window.Dispose();
|
||||
_window = null;
|
||||
}
|
||||
|
||||
CommandBinds.Unregister<CP14KnowledgeUIController>();
|
||||
}
|
||||
|
||||
public void OnSystemLoaded(ClientCP14KnowledgeSystem system)
|
||||
{
|
||||
system.OnKnowledgeUpdate += KnowledgeUpdated;
|
||||
_player.LocalPlayerDetached += CharacterDetached;
|
||||
}
|
||||
|
||||
public void OnSystemUnloaded(ClientCP14KnowledgeSystem system)
|
||||
{
|
||||
system.OnKnowledgeUpdate -= KnowledgeUpdated;
|
||||
_player.LocalPlayerDetached -= CharacterDetached;
|
||||
}
|
||||
|
||||
public void UnloadButton()
|
||||
{
|
||||
if (KnowledgeButton is null)
|
||||
return;
|
||||
|
||||
KnowledgeButton.OnPressed -= KnowledgeButtonPressed;
|
||||
}
|
||||
|
||||
public void LoadButton()
|
||||
{
|
||||
if (KnowledgeButton is null)
|
||||
return;
|
||||
|
||||
KnowledgeButton.OnPressed += KnowledgeButtonPressed;
|
||||
|
||||
if (_window is null)
|
||||
return;
|
||||
|
||||
_window.OnClose += DeactivateButton;
|
||||
_window.OnOpen += ActivateButton;
|
||||
}
|
||||
|
||||
private void DeactivateButton()
|
||||
{
|
||||
KnowledgeButton!.Pressed = false;
|
||||
}
|
||||
|
||||
private void ActivateButton()
|
||||
{
|
||||
KnowledgeButton!.Pressed = true;
|
||||
}
|
||||
|
||||
private void KnowledgeUpdated(ClientCP14KnowledgeSystem.KnowledgeData data)
|
||||
{
|
||||
if (_window is null)
|
||||
return;
|
||||
|
||||
_window.KnowledgeContent.RemoveAllChildren();
|
||||
|
||||
var (entity, allKnowledge) = data;
|
||||
|
||||
foreach (var knowledge in allKnowledge)
|
||||
{
|
||||
if (!_proto.TryIndex(knowledge, out var indexedKnowledge))
|
||||
continue;
|
||||
|
||||
var knowledgeButton = new Button()
|
||||
{
|
||||
Access = AccessLevel.Public,
|
||||
Text = Loc.GetString(indexedKnowledge.Name),
|
||||
ToolTip = Loc.GetString(indexedKnowledge.Desc),
|
||||
TextAlign = Label.AlignMode.Center,
|
||||
};
|
||||
|
||||
_window.KnowledgeContent.AddChild(knowledgeButton);
|
||||
}
|
||||
}
|
||||
|
||||
private void CharacterDetached(EntityUid uid)
|
||||
{
|
||||
CloseWindow();
|
||||
}
|
||||
|
||||
private void KnowledgeButtonPressed(BaseButton.ButtonEventArgs args)
|
||||
{
|
||||
ToggleWindow();
|
||||
}
|
||||
|
||||
private void CloseWindow()
|
||||
{
|
||||
_window?.Close();
|
||||
}
|
||||
|
||||
private void ToggleWindow()
|
||||
{
|
||||
if (_window == null)
|
||||
return;
|
||||
|
||||
if (KnowledgeButton != null)
|
||||
{
|
||||
KnowledgeButton.SetClickPressed(!_window.IsOpen);
|
||||
}
|
||||
|
||||
if (_window.IsOpen)
|
||||
{
|
||||
CloseWindow();
|
||||
}
|
||||
else
|
||||
{
|
||||
_knowledge.RequestKnowledgeInfo();
|
||||
_window.Open();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<windows:CP14KnowledgeWindow
|
||||
xmlns="https://spacestation14.io"
|
||||
xmlns:cc="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
xmlns:windows="clr-namespace:Content.Client._CP14.UserInterface.Systems.Knowledge.Windows"
|
||||
Title="{Loc 'cp14-knowledge-info-title'}"
|
||||
MinWidth="400"
|
||||
MinHeight="200">
|
||||
<ScrollContainer>
|
||||
<BoxContainer Name="KnowledgeContent" Margin="5" Access="Public" Orientation="Vertical">
|
||||
|
||||
</BoxContainer>
|
||||
</ScrollContainer>
|
||||
</windows:CP14KnowledgeWindow>
|
||||
@@ -0,0 +1,14 @@
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
|
||||
namespace Content.Client._CP14.UserInterface.Systems.Knowledge.Windows;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class CP14KnowledgeWindow : DefaultWindow
|
||||
{
|
||||
public CP14KnowledgeWindow()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,8 @@ public sealed partial class CP14KnowledgeSystem : SharedCP14KnowledgeSystem
|
||||
SubscribeLocalEvent<CP14KnowledgeStorageComponent, GetVerbsEvent<Verb>>(AddKnowledgeAdminVerb);
|
||||
SubscribeLocalEvent<CP14KnowledgeLearningSourceComponent, GetVerbsEvent<Verb>>(AddKnowledgeLearningVerb);
|
||||
SubscribeLocalEvent<CP14KnowledgeStorageComponent, CP14KnowledgeLearnDoAfterEvent>(KnowledgeLearnedEvent);
|
||||
|
||||
SubscribeNetworkEvent<RequestKnowledgeInfoEvent>(OnRequestKnowledgeInfoEvent);
|
||||
}
|
||||
|
||||
private void KnowledgeLearnedEvent(Entity<CP14KnowledgeStorageComponent> ent, ref CP14KnowledgeLearnDoAfterEvent args)
|
||||
@@ -120,7 +122,7 @@ public sealed partial class CP14KnowledgeSystem : SharedCP14KnowledgeSystem
|
||||
Category = VerbCategory.CP14KnowledgeAdd,
|
||||
Act = () =>
|
||||
{
|
||||
TryLearnKnowledge(ent, knowledge, false);
|
||||
TryLearnKnowledge(ent, knowledge, true);
|
||||
},
|
||||
Impact = LogImpact.High,
|
||||
});
|
||||
@@ -251,4 +253,17 @@ public sealed partial class CP14KnowledgeSystem : SharedCP14KnowledgeSystem
|
||||
$"{EntityManager.ToPrettyString(uid):player} forgot knowledge: {Loc.GetString(indexedKnowledge.Name)}");
|
||||
return true;
|
||||
}
|
||||
|
||||
private void OnRequestKnowledgeInfoEvent(RequestKnowledgeInfoEvent msg, EntitySessionEventArgs args)
|
||||
{
|
||||
if (!args.SenderSession.AttachedEntity.HasValue || args.SenderSession.AttachedEntity != GetEntity(msg.NetEntity))
|
||||
return;
|
||||
|
||||
var entity = args.SenderSession.AttachedEntity.Value;
|
||||
|
||||
if (!TryComp<CP14KnowledgeStorageComponent>(entity, out var knowledgeComp))
|
||||
return;
|
||||
|
||||
RaiseNetworkEvent(new CP14KnowledgeInfoEvent(GetNetEntity(entity),knowledgeComp.Knowledges), args.SenderSession);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,5 +116,9 @@ namespace Content.Shared.Input
|
||||
public static readonly BoundKeyFunction MappingRemoveDecal = "MappingRemoveDecal";
|
||||
public static readonly BoundKeyFunction MappingCancelEraseDecal = "MappingCancelEraseDecal";
|
||||
public static readonly BoundKeyFunction MappingOpenContextMenu = "MappingOpenContextMenu";
|
||||
|
||||
//CP14 keys
|
||||
public static readonly BoundKeyFunction CP14OpenKnowledgeMenu = "CP14OpenKnowledgeMenu";
|
||||
//CP14 keys end
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ using System.Text;
|
||||
using Content.Shared._CP14.Knowledge.Components;
|
||||
using Content.Shared._CP14.Knowledge.Prototypes;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Ghost;
|
||||
using Content.Shared.MagicMirror;
|
||||
using Content.Shared.Paper;
|
||||
using Robust.Shared.Prototypes;
|
||||
@@ -65,6 +66,9 @@ public abstract partial class SharedCP14KnowledgeSystem : EntitySystem
|
||||
ProtoId<CP14KnowledgePrototype> knowledge,
|
||||
CP14KnowledgeStorageComponent? knowledgeStorage = null)
|
||||
{
|
||||
if (HasComp<GhostComponent>(uid)) //All-knowing ghosts
|
||||
return true;
|
||||
|
||||
if (!Resolve(uid, ref knowledgeStorage, false))
|
||||
return false;
|
||||
|
||||
@@ -92,3 +96,27 @@ public sealed partial class CP14KnowledgeLearnDoAfterEvent : DoAfterEvent
|
||||
public ProtoId<CP14KnowledgePrototype> Knowledge;
|
||||
public override DoAfterEvent Clone() => this;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class CP14KnowledgeInfoEvent : EntityEventArgs
|
||||
{
|
||||
public readonly NetEntity NetEntity;
|
||||
public readonly HashSet<ProtoId<CP14KnowledgePrototype>> AllKnowledge;
|
||||
|
||||
public CP14KnowledgeInfoEvent(NetEntity netEntity, HashSet<ProtoId<CP14KnowledgePrototype>> allKnowledge)
|
||||
{
|
||||
NetEntity = netEntity;
|
||||
AllKnowledge = allKnowledge;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class RequestKnowledgeInfoEvent : EntityEventArgs
|
||||
{
|
||||
public readonly NetEntity NetEntity;
|
||||
|
||||
public RequestKnowledgeInfoEvent(NetEntity netEntity)
|
||||
{
|
||||
NetEntity = netEntity;
|
||||
}
|
||||
}
|
||||
|
||||
1
Resources/Locale/en-US/_CP14/HUD/game-hud.ftl
Normal file
1
Resources/Locale/en-US/_CP14/HUD/game-hud.ftl
Normal file
@@ -0,0 +1 @@
|
||||
cp14-game-hud-open-knowledge-menu-button-tooltip = Open character knowledge menu.
|
||||
@@ -14,3 +14,9 @@ cp14-ui-options-postprocess-tooltip =
|
||||
additive lighting will be present. This does not control
|
||||
post-process effects that affect the game or otherwise
|
||||
carry some form of gameplay-related meaning.
|
||||
|
||||
|
||||
## Controls menu
|
||||
|
||||
ui-options-header-cp14 = CrystallEdge
|
||||
ui-options-function-cp14-open-knowledge-menu = Open character knowledge menu.
|
||||
1
Resources/Locale/en-US/_CP14/knowledge/knowledge-ui.ftl
Normal file
1
Resources/Locale/en-US/_CP14/knowledge/knowledge-ui.ftl
Normal file
@@ -0,0 +1 @@
|
||||
cp14-knowledge-info-title = Character knowledge
|
||||
1
Resources/Locale/ru-RU/_CP14/HUD/game-hud.ftl
Normal file
1
Resources/Locale/ru-RU/_CP14/HUD/game-hud.ftl
Normal file
@@ -0,0 +1 @@
|
||||
cp14-game-hud-open-knowledge-menu-button-tooltip = Открыть меню знаний персонажа.
|
||||
@@ -14,3 +14,9 @@ cp14-ui-options-postprocess-tooltip =
|
||||
такие как аддитивное освещение. Это не управляет эффеками постобработки, которые
|
||||
влияют на игру или иным образом не контролирует эффекты постобработки, которые
|
||||
влияют на игру или имеют какое-то значение для игрового процесса.
|
||||
|
||||
|
||||
## Controls menu
|
||||
|
||||
ui-options-header-cp14 = CrystallEdge
|
||||
ui-options-function-cp14-open-knowledge-menu = Открыть меню знаний персонажа
|
||||
|
||||
1
Resources/Locale/ru-RU/_CP14/knowledge/knowledge-ui.ftl
Normal file
1
Resources/Locale/ru-RU/_CP14/knowledge/knowledge-ui.ftl
Normal file
@@ -0,0 +1 @@
|
||||
cp14-knowledge-info-title = Знания персонажа
|
||||
Reference in New Issue
Block a user