mirror of
https://github.com/WWhiteDreamProject/wwdpublic.git
synced 2026-04-16 21:17:39 +03:00
* - tweak: update StyleSheetify * - add: flexbox * - fix: size of flexbox in launchergui * - tweak: Profile editor: start. * - add: categories * - tweak: help me please with this shi... loadouts * - fix: container path think * - tweak: thinks for optimisation * - add: group selection for loadoutpicker * - tweak: change position of preview * - add: reason text * - fix: Кролькины фиксы * - fix: кролькины фиксы ч.2 * - fix: кролькины фиксы ч.3 * - кролькины фиксы - финал * - fix: Ворчливого дедушкины фиксы, удаление старого барахла и пометка wwdp * - tweak: some ui change for LoadoutCategories and LoadoutEntry * - ворчливый дед фиксы ч.2 * - fix: очередные кролькины фиксы * - add: loadout prototype validation * - fix: description read from edit field
329 lines
13 KiB
C#
329 lines
13 KiB
C#
using System.Linq;
|
|
using System.Numerics;
|
|
using System.Text;
|
|
using Content.Client.Guidebook;
|
|
using Content.Client.Paint;
|
|
using Content.Client.Players.PlayTimeTracking;
|
|
using Content.Client.Stylesheets;
|
|
using Content.Client.UserInterface.Systems.Guidebook;
|
|
using Content.Shared.Clothing.Loadouts.Prototypes;
|
|
using Content.Shared.Clothing.Loadouts.Systems;
|
|
using Content.Shared.Customization.Systems;
|
|
using Content.Shared.Guidebook;
|
|
using Content.Shared.Labels.Components;
|
|
using Content.Shared.Paint;
|
|
using Content.Shared.Preferences;
|
|
using Content.Shared.Roles;
|
|
using Robust.Client.AutoGenerated;
|
|
using Robust.Client.Graphics;
|
|
using Robust.Client.UserInterface;
|
|
using Robust.Client.UserInterface.Controls;
|
|
using Robust.Client.UserInterface.CustomControls;
|
|
using Robust.Client.UserInterface.XAML;
|
|
using Robust.Shared.Configuration;
|
|
using Robust.Shared.Map;
|
|
using Robust.Shared.Prototypes;
|
|
using Robust.Shared.Timing;
|
|
using Robust.Shared.Utility;
|
|
|
|
namespace Content.Client.Lobby.UI;
|
|
|
|
|
|
[GenerateTypedNameReferences]
|
|
public sealed partial class LoadoutPreferenceSelector : Control
|
|
{
|
|
public const string DefaultLoadoutInfoGuidebook = "LoadoutInfo";
|
|
|
|
public EntityUid DummyEntityUid;
|
|
private readonly IEntityManager _entityManager;
|
|
|
|
public LoadoutPrototype Loadout { get; }
|
|
|
|
private Loadout _preference = null!;
|
|
public Loadout Preference
|
|
{
|
|
get => _preference;
|
|
set
|
|
{
|
|
_preference = value;
|
|
NameEdit.Text = value.CustomName ?? "";
|
|
DescriptionEdit.TextRope = new Rope.Leaf(value.CustomDescription ?? "");
|
|
BookTextEdit.TextRope = new Rope.Leaf(value.CustomContent ?? ""); // WD EDIT
|
|
ColorEdit.Color = Color.FromHex(value.CustomColorTint, Color.White);
|
|
if (value.CustomColorTint != null)
|
|
UpdatePaint(new(DummyEntityUid, _entityManager.GetComponent<PaintedComponent>(DummyEntityUid)), _entityManager);
|
|
HeirloomButton.Pressed = value.CustomHeirloom ?? false;
|
|
}
|
|
}
|
|
|
|
public bool Valid;
|
|
private bool _showUnusable;
|
|
public bool ShowUnusable
|
|
{
|
|
get => _showUnusable;
|
|
set
|
|
{
|
|
_showUnusable = value;
|
|
Visible = Valid && _wearable || _showUnusable;
|
|
PreferenceButton.RemoveStyleClass(StyleBase.ButtonDanger);
|
|
PreferenceButton.AddStyleClass(Valid ? "" : StyleBase.ButtonDanger);
|
|
}
|
|
}
|
|
|
|
private bool _wearable;
|
|
public bool Wearable
|
|
{
|
|
get => _wearable;
|
|
set
|
|
{
|
|
_wearable = value;
|
|
Visible = Valid && _wearable || _showUnusable;
|
|
PreferenceButton.RemoveStyleClass(StyleBase.ButtonCaution);
|
|
PreferenceButton.AddStyleClass(_wearable ? "" : StyleBase.ButtonCaution);
|
|
}
|
|
}
|
|
|
|
public event Action<Loadout>? PreferenceChanged;
|
|
|
|
public LoadoutPreferenceSelector(LoadoutPrototype loadout, JobPrototype highJob,
|
|
HumanoidCharacterProfile profile, ref Dictionary<string, EntityUid> entities,
|
|
IEntityManager entityManager, IPrototypeManager prototypeManager, IConfigurationManager configManager,
|
|
CharacterRequirementsSystem characterRequirementsSystem, JobRequirementsManager jobRequirementsManager)
|
|
{
|
|
RobustXamlLoader.Load(this);
|
|
|
|
_entityManager = entityManager;
|
|
Loadout = loadout;
|
|
|
|
// Show/hide the special menu and items depending on what's allowed
|
|
HeirloomButton.Visible = loadout.CanBeHeirloom;
|
|
SpecialMenu.Visible = Loadout.CustomName || Loadout.CustomDescription || Loadout.CustomContent || Loadout.CustomColorTint; // WD EDIT
|
|
SpecialName.Visible = Loadout.CustomName;
|
|
SpecialDescription.Visible = Loadout.CustomDescription;
|
|
SpecialBookText.Visible = Loadout.CustomContent; // WD EDIT
|
|
SpecialColorTintToggle.Visible = Loadout.CustomColorTint;
|
|
|
|
|
|
SpriteView previewLoadout;
|
|
if (!entities.TryGetValue(loadout.ID + 0, out var dummyLoadoutItem))
|
|
{
|
|
// Get the first item in the loadout to be the preview
|
|
dummyLoadoutItem = entityManager.SpawnEntity(loadout.Items.First(), MapCoordinates.Nullspace);
|
|
entities.Add(loadout.ID + 0, dummyLoadoutItem);
|
|
|
|
// Create a sprite preview of the loadout item
|
|
previewLoadout = new SpriteView
|
|
{
|
|
Scale = new Vector2(1, 1),
|
|
OverrideDirection = Direction.South,
|
|
VerticalAlignment = VAlignment.Center,
|
|
SizeFlagsStretchRatio = 1,
|
|
};
|
|
previewLoadout.SetEntity(dummyLoadoutItem);
|
|
}
|
|
else
|
|
{
|
|
// Create a sprite preview of the loadout item
|
|
previewLoadout = new SpriteView
|
|
{
|
|
Scale = new Vector2(1, 1),
|
|
OverrideDirection = Direction.South,
|
|
VerticalAlignment = VAlignment.Center,
|
|
SizeFlagsStretchRatio = 1,
|
|
};
|
|
previewLoadout.SetEntity(dummyLoadoutItem);
|
|
}
|
|
DummyEntityUid = dummyLoadoutItem;
|
|
|
|
entityManager.EnsureComponent<AppearanceComponent>(dummyLoadoutItem);
|
|
entityManager.EnsureComponent<PaintedComponent>(dummyLoadoutItem, out var paint);
|
|
|
|
var loadoutName =
|
|
Loc.GetString($"loadout-name-{loadout.ID}") == $"loadout-name-{loadout.ID}"
|
|
? entityManager.GetComponent<MetaDataComponent>(dummyLoadoutItem).EntityName
|
|
: Loc.GetString($"loadout-name-{loadout.ID}");
|
|
|
|
// Display the item's label if it's present
|
|
if (entityManager.TryGetComponent(dummyLoadoutItem, out LabelComponent? labelComponent))
|
|
{
|
|
var itemLabel = labelComponent.CurrentLabel;
|
|
if (!string.IsNullOrEmpty(itemLabel))
|
|
loadoutName += $" ({Loc.GetString(itemLabel)})";
|
|
}
|
|
|
|
var loadoutDesc =
|
|
!Loc.TryGetString($"loadout-description-{loadout.ID}", out var description)
|
|
? entityManager.GetComponent<MetaDataComponent>(dummyLoadoutItem).EntityDescription
|
|
: description;
|
|
|
|
|
|
// Manage the info button
|
|
void UpdateGuidebook() => GuidebookButton.Visible =
|
|
prototypeManager.HasIndex<GuideEntryPrototype>(loadout.GuideEntry);
|
|
UpdateGuidebook();
|
|
prototypeManager.PrototypesReloaded += _ => UpdateGuidebook();
|
|
|
|
GuidebookButton.OnPressed += _ =>
|
|
{
|
|
if (!prototypeManager.TryIndex<GuideEntryPrototype>(loadout.GuideEntry, out var guideRoot))
|
|
return;
|
|
|
|
var guidebookController = UserInterfaceManager.GetUIController<GuidebookUIController>();
|
|
//TODO: Don't close the guidebook if its already open, just go to the correct page
|
|
guidebookController.OpenGuidebook(
|
|
new Dictionary<ProtoId<GuideEntryPrototype>, GuideEntry> { { loadout.GuideEntry, guideRoot } },
|
|
includeChildren: true,
|
|
selected: loadout.GuideEntry);
|
|
};
|
|
|
|
// Create a checkbox to get the loadout
|
|
PreferenceButton.AddChild(new BoxContainer
|
|
{
|
|
Children =
|
|
{
|
|
new Label
|
|
{
|
|
Text = loadout.Cost.ToString(),
|
|
StyleClasses = { StyleBase.StyleClassLabelHeading },
|
|
MinWidth = 32,
|
|
MaxWidth = 32,
|
|
ClipText = true,
|
|
Margin = new(0, 0, 8, 0),
|
|
},
|
|
new PanelContainer
|
|
{
|
|
PanelOverride = new StyleBoxFlat { BackgroundColor = Color.FromHex("#2f2f2f") },
|
|
Children =
|
|
{
|
|
previewLoadout,
|
|
},
|
|
},
|
|
new Label
|
|
{
|
|
Text = loadoutName,
|
|
Margin = new(8, 0, 0, 0),
|
|
},
|
|
},
|
|
});
|
|
|
|
// Update prefs cache when something changes
|
|
NameEdit.OnTextChanged += _ =>
|
|
_preference.CustomName = string.IsNullOrEmpty(NameEdit.Text) ? null : NameEdit.Text;
|
|
DescriptionEdit.OnTextChanged += _ =>
|
|
_preference.CustomDescription = string.IsNullOrEmpty(Rope.Collapse(DescriptionEdit.TextRope)) ? null : Rope.Collapse(DescriptionEdit.TextRope);
|
|
// WD EDIT START
|
|
BookTextEdit.OnTextChanged += _ =>
|
|
_preference.CustomContent = string.IsNullOrEmpty(Rope.Collapse(BookTextEdit.TextRope)) ? null : Rope.Collapse(BookTextEdit.TextRope);
|
|
// WD EDIT END
|
|
SpecialColorTintToggle.OnToggled += args =>
|
|
ColorEdit.Visible = args.Pressed;
|
|
ColorEdit.OnColorChanged += _ =>
|
|
{
|
|
_preference.CustomColorTint = SpecialColorTintToggle.Pressed ? ColorEdit.Color.ToHex() : null;
|
|
UpdatePaint(new(dummyLoadoutItem, paint), entityManager);
|
|
};
|
|
|
|
var desc = Loc.GetString(loadoutDesc);
|
|
NameEdit.PlaceHolder = loadoutName;
|
|
DescriptionEdit.Placeholder = new Rope.Leaf(desc);
|
|
BookTextEdit.Placeholder = new Rope.Leaf(Loc.GetString("humanoid-profile-editor-loadouts-customize-book-text-placeholder")); // WD EDIT
|
|
|
|
|
|
var tooltip = new Tooltip();
|
|
PreferenceButton.TooltipSupplier = _ => tooltip;
|
|
var toolBox = (BoxContainer) tooltip.Children.First();
|
|
|
|
if (!string.IsNullOrEmpty(desc))
|
|
tooltip.SetMessage(FormattedMessage.FromMarkupPermissive(desc));
|
|
if (loadout.Requirements.Any())
|
|
{
|
|
toolBox.AddChild(
|
|
new Label
|
|
{
|
|
Text = Loc.GetString("character-requirement-desc"),
|
|
StyleClasses = { StyleBase.StyleClassLabelHeading, },
|
|
Margin = new(0, 8, 0, 4),
|
|
});
|
|
|
|
MakeTooltipTree(toolBox, loadout.Requirements);
|
|
toolBox.AddChild(new() { Margin = new(0, 2), });
|
|
}
|
|
|
|
return;
|
|
|
|
void MakeTooltipTree(BoxContainer box, List<CharacterRequirement> requirements)
|
|
{
|
|
foreach (var requirement in requirements)
|
|
{
|
|
if (requirement is CharacterLogicRequirement logicRequirement)
|
|
{
|
|
requirement.IsValid(
|
|
highJob, profile, new Dictionary<string, TimeSpan>(), jobRequirementsManager.IsWhitelisted(), loadout,
|
|
entityManager, prototypeManager, configManager, out var reason);
|
|
box.AddChild(new RichTextLabel { Text = reason?.Split("\n")[0], Margin = new(8, 2), });
|
|
var newBox = new BoxContainer { Orientation = BoxContainer.LayoutOrientation.Vertical, };
|
|
box.AddChild(new PanelContainer
|
|
{
|
|
PanelOverride = new StyleBoxFlat
|
|
{
|
|
BackgroundColor = Color.FromHex("#1B1B1C"),
|
|
BorderColor = Color.FromHex("#3A3A3D"),
|
|
BorderThickness = new(1),
|
|
},
|
|
Margin = new(8, 2),
|
|
Children = { newBox, },
|
|
});
|
|
MakeTooltipTree(newBox, logicRequirement.Requirements);
|
|
}
|
|
else
|
|
{
|
|
requirement.IsValid(
|
|
highJob, profile, new Dictionary<string, TimeSpan>(), jobRequirementsManager.IsWhitelisted(), loadout,
|
|
entityManager, prototypeManager, configManager, out var reason);
|
|
box.AddChild(new RichTextLabel
|
|
{
|
|
Text = reason,
|
|
Margin = new(8, 2),
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private bool _initialized;
|
|
protected override void FrameUpdate(FrameEventArgs args)
|
|
{
|
|
if (_initialized || SpecialMenu.Heading == null)
|
|
return;
|
|
|
|
// Move the special editor
|
|
var heading = SpecialMenu.Heading;
|
|
heading.Orphan();
|
|
ButtonGroup.AddChild(heading);
|
|
GuidebookButton.Orphan();
|
|
ButtonGroup.AddChild(GuidebookButton);
|
|
|
|
// These guys are here too for reasons
|
|
HeadingButton.SetHeight = HeirloomButton.SetHeight = GuidebookButton.SetHeight = PreferenceButton.Size.Y;
|
|
SpecialColorTintToggle.Pressed = ColorEdit.Visible = _preference.CustomColorTint != null;
|
|
|
|
_initialized = true;
|
|
}
|
|
|
|
|
|
private void UpdatePaint(Entity<PaintedComponent> entity, IEntityManager entityManager)
|
|
{
|
|
if (_preference.CustomColorTint != null)
|
|
{
|
|
entity.Comp.Color = Color.FromHex(_preference.CustomColorTint);
|
|
entity.Comp.Enabled = true;
|
|
}
|
|
else
|
|
entity.Comp.Enabled = false;
|
|
|
|
var app = entityManager.System<SharedAppearanceSystem>();
|
|
app.TryGetData(entity, PaintVisuals.Painted, out bool value);
|
|
app.SetData(entity, PaintVisuals.Painted, !value);
|
|
}
|
|
}
|