using System.Linq; using Content.Client.CharacterInfo; using Content.Client.Gameplay; using Content.Client.UserInterface.Controls; using Content.Client.UserInterface.Systems.Character.Controls; using Content.Client.UserInterface.Systems.Character.Windows; using Content.Client.UserInterface.Systems.Objectives.Controls; using Content.Shared.Input; using JetBrains.Annotations; using Robust.Client.GameObjects; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controllers; using Robust.Client.UserInterface.Controls; using Robust.Shared.Input.Binding; using Robust.Shared.Utility; using static Content.Client.CharacterInfo.CharacterInfoSystem; using static Robust.Client.UserInterface.Controls.BaseButton; namespace Content.Client.UserInterface.Systems.Character; [UsedImplicitly] public sealed class CharacterUIController : UIController, IOnStateEntered, IOnStateExited, IOnSystemChanged { [UISystemDependency] private readonly CharacterInfoSystem _characterInfo = default!; [UISystemDependency] private readonly SpriteSystem _sprite = default!; private CharacterWindow? _window; private MenuButton? CharacterButton => UIManager.GetActiveUIWidgetOrNull()?.CharacterButton; public void OnStateEntered(GameplayState state) { DebugTools.Assert(_window == null); _window = UIManager.CreateWindow(); LayoutContainer.SetAnchorPreset(_window, LayoutContainer.LayoutPreset.CenterTop); CommandBinds.Builder .Bind(ContentKeyFunctions.OpenCharacterMenu, InputCmdHandler.FromDelegate(_ => ToggleWindow())) .Register(); } public void OnStateExited(GameplayState state) { if (_window != null) { _window.Dispose(); _window = null; } CommandBinds.Unregister(); } public void OnSystemLoaded(CharacterInfoSystem system) { system.OnCharacterUpdate += CharacterUpdated; system.OnCharacterDetached += CharacterDetached; } public void OnSystemUnloaded(CharacterInfoSystem system) { system.OnCharacterUpdate -= CharacterUpdated; system.OnCharacterDetached -= CharacterDetached; } public void UnloadButton() { if (CharacterButton == null) { return; } CharacterButton.OnPressed -= CharacterButtonPressed; } public void LoadButton() { if (CharacterButton == null) { return; } CharacterButton.OnPressed += CharacterButtonPressed; if (_window == null) { return; } _window.OnClose += DeactivateButton; _window.OnOpen += ActivateButton; } private void DeactivateButton() => CharacterButton!.Pressed = false; private void ActivateButton() => CharacterButton!.Pressed = true; private void CharacterUpdated(CharacterData data) { if (_window == null) { return; } var (entity, job, objectives, briefing, entityName) = data; _window.SpriteView.SetEntity(entity); _window.NameLabel.Text = entityName; _window.SubText.Text = job; _window.Objectives.RemoveAllChildren(); _window.ObjectivesLabel.Visible = objectives.Any(); foreach (var (groupId, conditions) in objectives) { var objectiveControl = new CharacterObjectiveControl { Orientation = BoxContainer.LayoutOrientation.Vertical, Modulate = Color.Gray }; objectiveControl.AddChild(new Label { Text = groupId, Modulate = Color.LightSkyBlue }); foreach (var condition in conditions) { var conditionControl = new ObjectiveConditionsControl(); conditionControl.ProgressTexture.Texture = _sprite.Frame0(condition.Icon); conditionControl.ProgressTexture.Progress = condition.Progress; var titleMessage = new FormattedMessage(); var descriptionMessage = new FormattedMessage(); titleMessage.AddText(condition.Title); descriptionMessage.AddText(condition.Description); conditionControl.Title.SetMessage(titleMessage); conditionControl.Description.SetMessage(descriptionMessage); objectiveControl.AddChild(conditionControl); } _window.Objectives.AddChild(objectiveControl); } if (briefing != null) { var briefingControl = new ObjectiveBriefingControl(); briefingControl.Label.Text = briefing; _window.Objectives.AddChild(briefingControl); } var controls = _characterInfo.GetCharacterInfoControls(entity); foreach (var control in controls) { _window.Objectives.AddChild(control); } _window.RolePlaceholder.Visible = briefing == null && !controls.Any() && !objectives.Any(); } private void CharacterDetached() { CloseWindow(); } private void CharacterButtonPressed(ButtonEventArgs args) { ToggleWindow(); } private void CloseWindow() { _window?.Close(); } private void ToggleWindow() { if (_window == null) return; if (CharacterButton != null) { CharacterButton.Pressed = !_window.IsOpen; } if (_window.IsOpen) { CloseWindow(); } else { _characterInfo.RequestCharacterInfo(); _window.Open(); } } }