Files
wwdpublic/Content.Client/ShortConstruction/UI/ShortConstructionMenuBUI.cs
gluesniffler 39ad4dbc24 More Quick Construction Recipes And Upgrades (#945)
# Description

This PR adds a few new recipes to Quick Construction (accessed by
pressing Z on commonly used construction materials/items, such as rods,
glass, steel, plasma, etc etc). Along with simple nesting for grouping
items up under categories, akin to how the RCD works. Which allows
engineers to massively speed up pipe laying work, disposal rebuilding,
setting up the supermatter, etc etc.

First time doing UI code, apologies for the shitcode in advance :godo:

---

<details><summary><h1>Media</h1></summary>
<p>

https://github.com/user-attachments/assets/9d540d7f-7e4f-4a43-874d-5ea069011a37

</p>
</details>

---

# Considerations

Is this powergamey? Probably. Is it fucking awesome? Hell yeah. Some
servers might question the fact that everyone can build stuff this fast
now that they dont have to deal too much with the construction menu for
the most common things... And might want to lock it behind traits or
given as a job freebie, like CPR for doctors.

Other servers might appreciate it if they are looking for more action to
happen over the round, and giving everyone the ability to deal with
breaches and repairs quicker is probably a step into that direction.
I'll be observing for feedback and adjust accordingly.

It also shouldn't invalidate any eventual RPDs, or other devices of the
kind since this is just a shortcut for construction, you still require
materials and a doafter for most of them.

---

# Changelog

🆑 Mocho
- add: Added a lot of recipes to the quick construction menus. Give it a
shot by pressing Z with different construction materials in your hand!

---------

Signed-off-by: gluesniffler <159397573+gluesniffler@users.noreply.github.com>
Co-authored-by: VMSolidus <evilexecutive@gmail.com>
# Conflicts:
#	Content.Client/ShortConstruction/UI/ShortConstructionMenuBUI.cs
2024-10-19 13:20:04 +07:00

138 lines
4.5 KiB
C#

using System.Numerics;
using Content.Client.Construction;
using Content.Client.UserInterface.Controls;
using Content.Shared.Construction.Prototypes;
using Content.Shared.ShortConstruction;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Input;
using Robust.Client.Placement;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Shared.Enums;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
// ReSharper disable InconsistentNaming
namespace Content.Client.ShortConstruction.UI;
[UsedImplicitly]
public sealed class ShortConstructionMenuBUI : BoundUserInterface
{
[Dependency] private readonly IClyde _displayManager = default!;
[Dependency] private readonly IInputManager _inputManager = default!;
[Dependency] private readonly EntityManager _entManager = default!;
[Dependency] private readonly IPrototypeManager _protoManager = default!;
[Dependency] private readonly IPlacementManager _placementManager = default!;
private readonly ConstructionSystem _construction;
private readonly SpriteSystem _spriteSystem;
private RadialMenu? _menu;
public ShortConstructionMenuBUI(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
_construction = _entManager.System<ConstructionSystem>();
_spriteSystem = _entManager.System<SpriteSystem>();
}
protected override void Open()
{
_menu = new RadialMenu
{
HorizontalExpand = true,
VerticalExpand = true,
BackButtonStyleClass = "RadialMenuBackButton",
CloseButtonStyleClass = "RadialMenuCloseButton"
};
if (_entManager.TryGetComponent<ShortConstructionComponent>(Owner, out var crafting))
CreateMenu(crafting.Entries);
_menu.OpenCenteredAt(_inputManager.MouseScreenPosition.Position / _displayManager.ScreenSize);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
_menu?.Dispose();
}
private void CreateMenu(List<ShortConstructionEntry> entries, string? parentCategory = null)
{
if (_menu == null)
return;
var container = new RadialContainer
{
Name = parentCategory ?? "Main",
Radius = 48f + 24f * MathF.Log(entries.Count),
};
_menu.AddChild(container);
foreach (var entry in entries)
{
if (entry.Category != null)
{
var button = CreateButton(entry.Category.Name, entry.Category.Icon);
button.TargetLayer = entry.Category.Name;
CreateMenu(entry.Category.Entries, entry.Category.Name);
container.AddChild(button);
}
else if (entry.Prototype != null
&& _protoManager.TryIndex(entry.Prototype, out var proto))
{
var button = CreateButton(proto.Name, proto.Icon);
button.OnButtonUp += _ => ConstructItem(proto);
container.AddChild(button);
}
}
}
private RadialMenuTextureButton CreateButton(string name, SpriteSpecifier icon)
{
var button = new RadialMenuTextureButton
{
ToolTip = Loc.GetString(name),
StyleClasses = { "RadialMenuButton" },
SetSize = new Vector2(64f, 64f),
};
var texture = new TextureRect
{
VerticalAlignment = Control.VAlignment.Center,
HorizontalAlignment = Control.HAlignment.Center,
Texture = _spriteSystem.Frame0(icon),
TextureScale = new Vector2(2f, 2f)
};
button.AddChild(texture);
return button;
}
/// <summary>
/// Makes an item or places a schematic based on the type of construction recipe.
/// </summary>
private void ConstructItem(ConstructionPrototype prototype)
{
if (prototype.Type == ConstructionType.Item)
{
_construction.TryStartItemConstruction(prototype.ID);
return;
}
_placementManager.BeginPlacing(new PlacementInformation
{
IsTile = false,
PlacementOption = prototype.PlacementMode
}, new ConstructionPlacementHijack(_construction, prototype));
// Should only close the menu if we're placing a construction hijack.
// Theres not much point to closing it though. _menu!.Close();
}
}