Chameleon controller implant (Clothing fast switch) (#33887)
* Add the chameleon controller implant * address the issues (Git please dont kill me) * Address the review and fix some merge conflicts! * Cleanup * Add use delay * Silly mistakes * Making a PR at 2 am: Gone wrong * Predict use delay and disable the buttons until you can choose another * First phase custom clothing * Better system, now relays to agent id and mindshield. Chameleon loadouts are a lot better to work with as well * Address the review! No more evil goto * Slams way is better I should have read more closely xD * Some of the jobs * Add to Cargo, CentComm, Service, Passenger, Ninja, Cluwne, Wizard + Minor changes to existing; Add chameleon to bandanas, medals, jugsuits and HUDs * Add everything else * Fix test * Job name * This looks better * Add department organization * Minor cleanup * Added some mindshields * Remove redudent comment and change funcion name to be clearer * Fix cluwne outfit * fix merge conflicts --------- Co-authored-by: SlamBamActionman <slambamactionman@gmail.com>
This commit is contained in:
157
Content.Client/Implants/UI/ChameleonControllerMenu.xaml.cs
Normal file
157
Content.Client/Implants/UI/ChameleonControllerMenu.xaml.cs
Normal file
@@ -0,0 +1,157 @@
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Content.Client.Roles;
|
||||
using Content.Client.Stylesheets;
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Shared.Implants;
|
||||
using Content.Shared.StatusIcon;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Client.Implants.UI;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class ChameleonControllerMenu : FancyWindow
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
private readonly SpriteSystem _sprite;
|
||||
private readonly JobSystem _job;
|
||||
|
||||
// List of all the job protos that you can select!
|
||||
private IEnumerable<ChameleonOutfitPrototype> _outfits;
|
||||
|
||||
// Lock the UI until this time
|
||||
public DateTime? _lockedUntil;
|
||||
|
||||
private static readonly ProtoId<JobIconPrototype> UnknownIcon = "JobIconUnknown";
|
||||
private static readonly LocId UnknownDepartment = "department-Unknown";
|
||||
|
||||
public event Action<ProtoId<ChameleonOutfitPrototype>>? OnJobSelected;
|
||||
|
||||
public ChameleonControllerMenu()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
_sprite = _entityManager.System<SpriteSystem>();
|
||||
_job = _entityManager.System<JobSystem>();
|
||||
|
||||
_outfits = _prototypeManager.EnumeratePrototypes<ChameleonOutfitPrototype>();
|
||||
|
||||
UpdateGrid();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fill the grid with the correct job icons and buttons.
|
||||
/// </summary>
|
||||
/// <param name="disabled">Set to true to disable all the buttons.</param>
|
||||
public void UpdateGrid(bool disabled = false)
|
||||
{
|
||||
Grid.RemoveAllChildren();
|
||||
|
||||
// Dictionary to easily put outfits in departments.
|
||||
// Department name -> UI element holding that department.
|
||||
var departments = new Dictionary<string, BoxContainer>();
|
||||
|
||||
departments.Add(UnknownDepartment, CreateDepartment(UnknownDepartment));
|
||||
|
||||
// Go through every outfit and add them to the correct department.
|
||||
foreach (var outfit in _outfits)
|
||||
{
|
||||
_prototypeManager.TryIndex(outfit.Job, out var jobProto);
|
||||
|
||||
var name = outfit.LoadoutName ?? outfit.Name ?? jobProto?.Name ?? "Prototype has no name or job.";
|
||||
|
||||
var jobIconId = outfit.Icon ?? jobProto?.Icon ?? UnknownIcon;
|
||||
var jobIconProto = _prototypeManager.Index(jobIconId);
|
||||
|
||||
var outfitButton = CreateOutfitButton(disabled, name, jobIconProto, outfit.ID);
|
||||
|
||||
if (outfit.Job != null && _job.TryGetLowestWeightDepartment(outfit.Job, out var departmentPrototype))
|
||||
{
|
||||
if (!departments.ContainsKey(departmentPrototype.Name))
|
||||
departments.Add(departmentPrototype.Name, CreateDepartment(departmentPrototype.Name));
|
||||
|
||||
departments[departmentPrototype.Name].AddChild(outfitButton);
|
||||
}
|
||||
else
|
||||
{
|
||||
departments[UnknownDepartment].AddChild(outfitButton);
|
||||
}
|
||||
}
|
||||
|
||||
// Sort the departments by their weight.
|
||||
var departmentList = departments.ToList();
|
||||
departmentList.Sort((a, b) => a.Value.ChildCount.CompareTo(b.Value.ChildCount));
|
||||
|
||||
// Actually add the departments to the window.
|
||||
foreach (var department in departmentList)
|
||||
{
|
||||
Grid.AddChild(department.Value);
|
||||
}
|
||||
}
|
||||
|
||||
private BoxContainer CreateDepartment(string name)
|
||||
{
|
||||
var departmentContainer = new BoxContainer
|
||||
{
|
||||
Orientation = BoxContainer.LayoutOrientation.Vertical,
|
||||
};
|
||||
departmentContainer.AddChild(new Label
|
||||
{
|
||||
Text = Loc.GetString(name),
|
||||
});
|
||||
|
||||
return departmentContainer;
|
||||
}
|
||||
|
||||
private BoxContainer CreateOutfitButton(bool disabled, string name, JobIconPrototype jobIconProto, ProtoId<ChameleonOutfitPrototype> outfitProto)
|
||||
{
|
||||
var outfitButton = new BoxContainer();
|
||||
|
||||
var button = new Button
|
||||
{
|
||||
HorizontalExpand = true,
|
||||
StyleClasses = {StyleBase.ButtonSquare},
|
||||
ToolTip = Loc.GetString(name),
|
||||
Text = Loc.GetString(name),
|
||||
Margin = new Thickness(0, 0, 15, 0),
|
||||
Disabled = disabled,
|
||||
};
|
||||
|
||||
var jobIconTexture = new TextureRect
|
||||
{
|
||||
Texture = _sprite.Frame0(jobIconProto.Icon),
|
||||
TextureScale = new Vector2(2.5f, 2.5f),
|
||||
Stretch = TextureRect.StretchMode.KeepCentered,
|
||||
Margin = new Thickness(0, 0, 5, 0),
|
||||
};
|
||||
|
||||
outfitButton.AddChild(jobIconTexture);
|
||||
outfitButton.AddChild(button);
|
||||
|
||||
button.OnPressed += _ => JobButtonPressed(outfitProto);
|
||||
|
||||
return outfitButton;
|
||||
}
|
||||
|
||||
private void JobButtonPressed(ProtoId<ChameleonOutfitPrototype> outfit)
|
||||
{
|
||||
OnJobSelected?.Invoke(outfit);
|
||||
}
|
||||
|
||||
protected override void FrameUpdate(FrameEventArgs args)
|
||||
{
|
||||
base.FrameUpdate(args);
|
||||
|
||||
if (_lockedUntil == null || DateTime.Now < _lockedUntil)
|
||||
return;
|
||||
|
||||
_lockedUntil = null;
|
||||
UpdateGrid();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user