* mindcomponent namespace * wip MindRole stuff * admin player tab * mindroletype comment * mindRolePrototype redesign * broken param * wip RoleType implementation * basic role type switching for antags * traitor fix * fix AdminPanel update * the renameningTM * cleanup * feature uncreeping * roletypes on mind roles * update MindComponent.RoleType when MindRoles change * ghostrole configuration * ghostrole config improvements * live update of roleType on the character window * logging stuff and notes * remove thing no one asked for * weh * Mind Role Entities wip * headrev count fix * silicon stuff, cleanup * exclusive antag config, cleanup * jobroleadd overwerite * logging stuff * MindHasRole cleanup, admin log stuff * last second cleanup * ocd * move roletypeprototype to its own file, minor note stuff * remove Roletype.Created * log stuff * roletype setup for ghostroles and autotraitor reinforcements * ghostrole type configs * adjustable admin overlay * cleanup * fix this in its own PR * silicon antagonist * borg stuff * mmi roletype handling * spawnable borg roletype handling * weh * ghost role cleanup * weh * RoleEvent update * polish * log stuff * admin overlay config * ghostrolecomponent cleanup * weh * admin overlay code cleanup * minor cleanup * Obsolete MindRoleAddedEvent * comment * minor code cleanup * MindOnDoGreeting fix * Role update message * fix duplicate job greeting for cyborgs * fix emag job message dupe * nicer-looking role type update * crew aligned * syndicate assault borg role fix * fix test fail * fix a merge mistake * fix LoneOp role type * Update Content.Client/Administration/AdminNameOverlay.cs Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * Update Content.Shared/Roles/SharedRoleSystem.cs Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * comment formatting Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * change logging category Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * fix a space Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * use MindAddRoles Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * get MindComponent from TryGetMind Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * move var declaration outside loop * remove TryComp * take RoleEnum behind the barn * don't use ensurecomp unnecessarily * cvar comments * toggleableghostrolecomponent documentation * skrek * use EntProtoId * mindrole config * merge baserolecomponent into basemindrolecomponent * ai and borg silicon role tweaks * formatting Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * I will end you (the color) Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * use LocId type for a locale id * update RoleEvent documentation * update RoleEvent documentation * remove obsolete MindRoleAddedEvent * refine MindRolesUpdate() * use dependency Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * inject dependency Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * roleType.Name no longer required * reformatted draw code logic * GhostRoleMarkerRoleComponent comment * minor SharedRoleSystem cleanup * StartingMindRoleComponent, unhardcode roundstart silicon * Update Content.Shared/Roles/SharedRoleSystem.cs * remove a whitespace --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
264 lines
7.8 KiB
C#
264 lines
7.8 KiB
C#
using System.Linq;
|
|
using Content.Client.CharacterInfo;
|
|
using Content.Client.Gameplay;
|
|
using Content.Client.Stylesheets;
|
|
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 Content.Shared.Mind;
|
|
using Content.Shared.Mind.Components;
|
|
using Content.Shared.Roles;
|
|
using JetBrains.Annotations;
|
|
using Robust.Client.GameObjects;
|
|
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;
|
|
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<GameplayState>, IOnStateExited<GameplayState>, IOnSystemChanged<CharacterInfoSystem>
|
|
{
|
|
[Dependency] private readonly IEntityManager _ent = default!;
|
|
[Dependency] private readonly ILogManager _logMan = default!;
|
|
[Dependency] private readonly IPlayerManager _player = default!;
|
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
|
|
|
[UISystemDependency] private readonly CharacterInfoSystem _characterInfo = default!;
|
|
[UISystemDependency] private readonly SpriteSystem _sprite = default!;
|
|
|
|
private ISawmill _sawmill = default!;
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
|
|
_sawmill = _logMan.GetSawmill("character");
|
|
|
|
SubscribeNetworkEvent<MindRoleTypeChangedEvent>(OnRoleTypeChanged);
|
|
}
|
|
|
|
private CharacterWindow? _window;
|
|
private MenuButton? CharacterButton => UIManager.GetActiveUIWidgetOrNull<MenuBar.Widgets.GameTopMenuBar>()?.CharacterButton;
|
|
|
|
public void OnStateEntered(GameplayState state)
|
|
{
|
|
DebugTools.Assert(_window == null);
|
|
|
|
_window = UIManager.CreateWindow<CharacterWindow>();
|
|
LayoutContainer.SetAnchorPreset(_window, LayoutContainer.LayoutPreset.CenterTop);
|
|
|
|
|
|
|
|
CommandBinds.Builder
|
|
.Bind(ContentKeyFunctions.OpenCharacterMenu,
|
|
InputCmdHandler.FromDelegate(_ => ToggleWindow()))
|
|
.Register<CharacterUIController>();
|
|
}
|
|
|
|
public void OnStateExited(GameplayState state)
|
|
{
|
|
if (_window != null)
|
|
{
|
|
_window.Dispose();
|
|
_window = null;
|
|
}
|
|
|
|
CommandBinds.Unregister<CharacterUIController>();
|
|
}
|
|
|
|
public void OnSystemLoaded(CharacterInfoSystem system)
|
|
{
|
|
system.OnCharacterUpdate += CharacterUpdated;
|
|
_player.LocalPlayerDetached += CharacterDetached;
|
|
}
|
|
|
|
public void OnSystemUnloaded(CharacterInfoSystem system)
|
|
{
|
|
system.OnCharacterUpdate -= CharacterUpdated;
|
|
_player.LocalPlayerDetached -= 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);
|
|
|
|
UpdateRoleType();
|
|
|
|
_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
|
|
};
|
|
|
|
|
|
var objectiveText = new FormattedMessage();
|
|
objectiveText.TryAddMarkup(groupId, out _);
|
|
|
|
var objectiveLabel = new RichTextLabel
|
|
{
|
|
StyleClasses = {StyleNano.StyleClassTooltipActionTitle}
|
|
};
|
|
objectiveLabel.SetMessage(objectiveText);
|
|
|
|
objectiveControl.AddChild(objectiveLabel);
|
|
|
|
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();
|
|
var text = new FormattedMessage();
|
|
text.PushColor(Color.Yellow);
|
|
text.AddText(briefing);
|
|
briefingControl.Label.SetMessage(text);
|
|
_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 OnRoleTypeChanged(MindRoleTypeChangedEvent ev, EntitySessionEventArgs _)
|
|
{
|
|
UpdateRoleType();
|
|
}
|
|
|
|
private void UpdateRoleType()
|
|
{
|
|
if (_window == null || !_window.IsOpen)
|
|
return;
|
|
|
|
if (!_ent.TryGetComponent<MindContainerComponent>(_player.LocalEntity, out var container)
|
|
|| container.Mind is null)
|
|
return;
|
|
|
|
if (!_ent.TryGetComponent<MindComponent>(container.Mind.Value, out var mind))
|
|
return;
|
|
|
|
var roleText = Loc.GetString("role-type-crew-aligned-name");
|
|
var color = Color.White;
|
|
if (_prototypeManager.TryIndex(mind.RoleType, out var proto))
|
|
{
|
|
roleText = Loc.GetString(proto.Name);
|
|
color = proto.Color;
|
|
}
|
|
else
|
|
_sawmill.Error($"{_player.LocalEntity} has invalid Role Type '{mind.RoleType}'. Displaying '{roleText}' instead");
|
|
|
|
_window.RoleType.Text = roleText;
|
|
_window.RoleType.FontColorOverride = color;
|
|
}
|
|
|
|
private void CharacterDetached(EntityUid uid)
|
|
{
|
|
CloseWindow();
|
|
}
|
|
|
|
private void CharacterButtonPressed(ButtonEventArgs args)
|
|
{
|
|
ToggleWindow();
|
|
}
|
|
|
|
private void CloseWindow()
|
|
{
|
|
_window?.Close();
|
|
}
|
|
|
|
private void ToggleWindow()
|
|
{
|
|
if (_window == null)
|
|
return;
|
|
|
|
if (CharacterButton != null)
|
|
{
|
|
CharacterButton.SetClickPressed(!_window.IsOpen);
|
|
}
|
|
|
|
if (_window.IsOpen)
|
|
{
|
|
CloseWindow();
|
|
}
|
|
else
|
|
{
|
|
_characterInfo.RequestCharacterInfo();
|
|
_window.Open();
|
|
}
|
|
}
|
|
}
|