Exosuit: Ripley (#12668)
* mechs * interaction relay * atmos handling * fuck around with interaction events SPAGHETTI CODE OH MY GOD * more sprites and whatever the hell * more mech shit * more shit for equipment * starting equipment (for nukie mechs and such) * equipment cycling * starting with some of the ui * a fat chunk of ui prototyping * done tinkering with ui * a bunch of ui stuff and what have yous * cleaning up grabber and state handling * make the ui actually functional + watch me port a million icons I swear i'll prune the sprites later blease * start on construction * construction yo mamma * remove some unused files * fix a silly * make the graph sane * make it actually constructible. * print the boards as well, bozo * rebalance part prices * eject action also i appease the russians by remembering to localize * Punch Shit * make mech integrity and repairs work * Make the UI more based STOMP STOMP STOMP STOMP * make equipment even more based * batteries and other such delights * make the ui look pimpin af * make the construction mega based * UI but so epic * equipment * some sweat tweaks * damage rebalancing * restructure tech * fix some shit * mechs inherit access * make icons actually use sprite specifiers * TRAILING COMMAA!!!!! * fix a mild indentation sin * undo this change because it isn't needed * actually fix this * secret webeditting shhhh * place this tech here * comments * foo
This commit is contained in:
24
Content.Client/Mech/MechAssemblyVisualizerSystem.cs
Normal file
24
Content.Client/Mech/MechAssemblyVisualizerSystem.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using Content.Shared.Mech;
|
||||
using Robust.Client.GameObjects;
|
||||
|
||||
namespace Content.Client.Mech;
|
||||
|
||||
/// <summary>
|
||||
/// Handles the sprite state changes while
|
||||
/// constructing mech assemblies.
|
||||
/// </summary>
|
||||
public sealed class MechAssemblyVisualizerSystem : VisualizerSystem<MechAssemblyVisualsComponent>
|
||||
{
|
||||
protected override void OnAppearanceChange(EntityUid uid, MechAssemblyVisualsComponent component,
|
||||
ref AppearanceChangeEvent args)
|
||||
{
|
||||
base.OnAppearanceChange(uid, component, ref args);
|
||||
|
||||
if (!args.Component.TryGetData(MechAssemblyVisuals.State, out int stage))
|
||||
return;
|
||||
|
||||
var state = component.StatePrefix + stage;
|
||||
|
||||
args.Sprite?.LayerSetState(0, state);
|
||||
}
|
||||
}
|
||||
15
Content.Client/Mech/MechAssemblyVisualsComponent.cs
Normal file
15
Content.Client/Mech/MechAssemblyVisualsComponent.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
namespace Content.Client.Mech;
|
||||
|
||||
/// <summary>
|
||||
/// This is used for visualizing mech constructions
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed class MechAssemblyVisualsComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The prefix that is followed by the number which
|
||||
/// denotes the current state to use.
|
||||
/// </summary>
|
||||
[DataField("statePrefix", required: true)]
|
||||
public string StatePrefix = string.Empty;
|
||||
}
|
||||
12
Content.Client/Mech/MechComponent.cs
Normal file
12
Content.Client/Mech/MechComponent.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using Content.Shared.Mech.Components;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Client.Mech;
|
||||
|
||||
/// <inheritdoc/>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
[ComponentReference(typeof(SharedMechComponent))]
|
||||
public sealed class MechComponent : SharedMechComponent
|
||||
{
|
||||
|
||||
}
|
||||
43
Content.Client/Mech/MechSystem.cs
Normal file
43
Content.Client/Mech/MechSystem.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using Content.Shared.Mech;
|
||||
using Content.Shared.Mech.EntitySystems;
|
||||
using Robust.Client.GameObjects;
|
||||
using DrawDepth = Content.Shared.DrawDepth.DrawDepth;
|
||||
|
||||
namespace Content.Client.Mech;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public sealed class MechSystem : SharedMechSystem
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<MechComponent, AppearanceChangeEvent>(OnAppearanceChanged);
|
||||
}
|
||||
|
||||
private void OnAppearanceChanged(EntityUid uid, MechComponent component, ref AppearanceChangeEvent args)
|
||||
{
|
||||
if (args.Sprite == null)
|
||||
return;
|
||||
|
||||
if (!args.Sprite.TryGetLayer((int) MechVisualLayers.Base, out var layer))
|
||||
return;
|
||||
|
||||
var state = component.BaseState;
|
||||
var drawDepth = DrawDepth.Mobs;
|
||||
if (component.BrokenState != null && args.Component.TryGetData(MechVisuals.Broken, out bool broken) && broken)
|
||||
{
|
||||
state = component.BrokenState;
|
||||
drawDepth = DrawDepth.SmallMobs;
|
||||
}
|
||||
else if (component.OpenState != null && args.Component.TryGetData(MechVisuals.Open, out bool open) && open)
|
||||
{
|
||||
state = component.OpenState;
|
||||
drawDepth = DrawDepth.SmallMobs;
|
||||
}
|
||||
|
||||
layer.SetState(state);
|
||||
args.Sprite.DrawDepth = (int) drawDepth;
|
||||
}
|
||||
}
|
||||
36
Content.Client/Mech/Ui/Equipment/MechGrabberUi.cs
Normal file
36
Content.Client/Mech/Ui/Equipment/MechGrabberUi.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using Content.Client.UserInterface.Fragments;
|
||||
using Content.Shared.Mech;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.UserInterface;
|
||||
|
||||
namespace Content.Client.Mech.Ui.Equipment;
|
||||
|
||||
public sealed class MechGrabberUi : UIFragment
|
||||
{
|
||||
private MechGrabberUiFragment? _fragment;
|
||||
|
||||
public override Control GetUIFragmentRoot()
|
||||
{
|
||||
return _fragment!;
|
||||
}
|
||||
|
||||
public override void Setup(BoundUserInterface userInterface, EntityUid? fragmentOwner)
|
||||
{
|
||||
if (fragmentOwner == null)
|
||||
return;
|
||||
|
||||
_fragment = new MechGrabberUiFragment();
|
||||
_fragment.OnEjectAction += e =>
|
||||
{
|
||||
userInterface.SendMessage(new MechGrabberEjectMessage(fragmentOwner.Value, e));
|
||||
};
|
||||
}
|
||||
|
||||
public override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
if (state is not MechGrabberUiState grabberState)
|
||||
return;
|
||||
|
||||
_fragment?.UpdateContents(grabberState);
|
||||
}
|
||||
}
|
||||
15
Content.Client/Mech/Ui/Equipment/MechGrabberUiFragment.xaml
Normal file
15
Content.Client/Mech/Ui/Equipment/MechGrabberUiFragment.xaml
Normal file
@@ -0,0 +1,15 @@
|
||||
<equipment:MechGrabberUiFragment
|
||||
xmlns:equipment="clr-namespace:Content.Client.Mech.Ui.Equipment"
|
||||
xmlns="https://spacestation14.io" Margin="1 0 2 0" HorizontalExpand="True" VerticalExpand="True">
|
||||
<BoxContainer Orientation="Vertical"
|
||||
HorizontalExpand="True"
|
||||
VerticalExpand="True">
|
||||
<ItemList Name="ItemList"
|
||||
VerticalExpand="True"
|
||||
MinHeight="120"
|
||||
HorizontalExpand="True"
|
||||
SelectMode="Button">
|
||||
</ItemList>
|
||||
<Label Name="SpaceLabel" HorizontalAlignment="Right" StyleClasses="LabelSubText"></Label>
|
||||
</BoxContainer>
|
||||
</equipment:MechGrabberUiFragment>
|
||||
@@ -0,0 +1,35 @@
|
||||
using Content.Shared.Mech;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
|
||||
namespace Content.Client.Mech.Ui.Equipment;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class MechGrabberUiFragment : BoxContainer
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entity = default!;
|
||||
|
||||
public event Action<EntityUid>? OnEjectAction;
|
||||
|
||||
public MechGrabberUiFragment()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
}
|
||||
|
||||
public void UpdateContents(MechGrabberUiState state)
|
||||
{
|
||||
SpaceLabel.Text = $"{state.Contents.Count}/{state.MaxContents}";
|
||||
for (var i = 0; i < state.Contents.Count; i++)
|
||||
{
|
||||
var ent = state.Contents[i];
|
||||
|
||||
if (!_entity.TryGetComponent<MetaDataComponent>(ent, out var meta))
|
||||
continue;
|
||||
|
||||
ItemList.AddItem(meta.EntityName);
|
||||
ItemList[i].OnSelected += _ => OnEjectAction?.Invoke(ent);
|
||||
}
|
||||
}
|
||||
}
|
||||
84
Content.Client/Mech/Ui/MechBoundUserInterface.cs
Normal file
84
Content.Client/Mech/Ui/MechBoundUserInterface.cs
Normal file
@@ -0,0 +1,84 @@
|
||||
using Content.Client.UserInterface.Fragments;
|
||||
using Content.Shared.Mech;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
|
||||
namespace Content.Client.Mech.Ui;
|
||||
|
||||
[UsedImplicitly]
|
||||
public sealed class MechBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _ent = default!;
|
||||
|
||||
private readonly EntityUid _mech;
|
||||
|
||||
private MechMenu? _menu;
|
||||
|
||||
public MechBoundUserInterface(ClientUserInterfaceComponent owner, Enum uiKey) : base(owner, uiKey)
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
_mech = owner.Owner;
|
||||
}
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
_menu = new(_mech);
|
||||
|
||||
_menu.OnClose += Close;
|
||||
_menu.OpenCenteredLeft();
|
||||
|
||||
_menu.OnRemoveButtonPressed += uid =>
|
||||
{
|
||||
SendMessage(new MechEquipmentRemoveMessage(uid));
|
||||
};
|
||||
}
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
base.UpdateState(state);
|
||||
|
||||
if (state is not MechBoundUiState msg)
|
||||
return;
|
||||
UpdateEquipmentControls(msg);
|
||||
_menu?.UpdateMechStats();
|
||||
_menu?.UpdateEquipmentView();
|
||||
}
|
||||
|
||||
public void UpdateEquipmentControls(MechBoundUiState state)
|
||||
{
|
||||
if (!_ent.TryGetComponent<MechComponent>(_mech, out var mechComp))
|
||||
return;
|
||||
|
||||
foreach (var ent in mechComp.EquipmentContainer.ContainedEntities)
|
||||
{
|
||||
var ui = GetEquipmentUi(ent);
|
||||
if (ui == null)
|
||||
continue;
|
||||
foreach (var (attached, estate) in state.EquipmentStates)
|
||||
{
|
||||
if (ent == attached)
|
||||
ui.UpdateState(estate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
|
||||
if (!disposing)
|
||||
return;
|
||||
|
||||
_menu?.Close();
|
||||
}
|
||||
|
||||
public UIFragment? GetEquipmentUi(EntityUid? uid)
|
||||
{
|
||||
var component = _ent.GetComponentOrNull<UIFragmentComponent>(uid);
|
||||
component?.Ui?.Setup(this, uid);
|
||||
return component?.Ui;
|
||||
}
|
||||
}
|
||||
|
||||
26
Content.Client/Mech/Ui/MechEquipmentControl.xaml
Normal file
26
Content.Client/Mech/Ui/MechEquipmentControl.xaml
Normal file
@@ -0,0 +1,26 @@
|
||||
<Control xmlns="https://spacestation14.io"
|
||||
xmlns:customControls="clr-namespace:Content.Client.Administration.UI.CustomControls">
|
||||
<Button Disabled="True"
|
||||
Margin="0 0 0 0"
|
||||
HorizontalExpand="True"
|
||||
VerticalExpand="True"
|
||||
StyleClasses="ButtonSquare">
|
||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True" VerticalAlignment="Top">
|
||||
<BoxContainer HorizontalExpand="True" VerticalExpand="True" Orientation="Horizontal">
|
||||
<SpriteView
|
||||
Name="EquipmentView"
|
||||
OverrideDirection="South"
|
||||
MinSize="32 32"
|
||||
SetSize="32 32"
|
||||
Scale="1 1"
|
||||
RectClipContent="True"/>
|
||||
<RichTextLabel Name="EquipmentName" VerticalAlignment="Center"/>
|
||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True" HorizontalAlignment="Right" VerticalAlignment="Center">
|
||||
<TextureButton Name="RemoveButton" Scale="0.5 0.5"></TextureButton>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
<customControls:HSeparator Name="Separator" StyleClasses="LowDivider" Visible="False"/>
|
||||
<BoxContainer Name="CustomControlContainer" Margin="0 10 0 0" HorizontalExpand="True" VerticalExpand="True"></BoxContainer>
|
||||
</BoxContainer>
|
||||
</Button>
|
||||
</Control>
|
||||
28
Content.Client/Mech/Ui/MechEquipmentControl.xaml.cs
Normal file
28
Content.Client/Mech/Ui/MechEquipmentControl.xaml.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
|
||||
namespace Content.Client.Mech.Ui;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class MechEquipmentControl : Control
|
||||
{
|
||||
public event Action? OnRemoveButtonPressed;
|
||||
|
||||
public MechEquipmentControl(string itemName, SpriteComponent? sprite, Control? fragment)
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
EquipmentName.SetMessage(itemName);
|
||||
EquipmentView.Sprite = sprite;
|
||||
RemoveButton.TexturePath = "/Textures/Interface/Nano/cross.svg.png";
|
||||
|
||||
if (fragment != null)
|
||||
{
|
||||
Separator.Visible = true;
|
||||
CustomControlContainer.AddChild(fragment);
|
||||
}
|
||||
|
||||
RemoveButton.OnPressed += _ => OnRemoveButtonPressed?.Invoke();
|
||||
}
|
||||
}
|
||||
71
Content.Client/Mech/Ui/MechMenu.xaml
Normal file
71
Content.Client/Mech/Ui/MechMenu.xaml
Normal file
@@ -0,0 +1,71 @@
|
||||
<controls:FancyWindow xmlns="https://spacestation14.io"
|
||||
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
Title="{Loc 'mech-menu-title'}"
|
||||
MinSize="350 440"
|
||||
SetSize="350 440">
|
||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True">
|
||||
<BoxContainer Margin="10 10 10 10" Orientation="Horizontal" HorizontalExpand="True">
|
||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True">
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||
<ProgressBar Name="IntegrityDisplayBar"
|
||||
HorizontalExpand="True"
|
||||
SetHeight="25"
|
||||
MaxValue="1"
|
||||
Value="0">
|
||||
<Label Name="IntegrityDisplay"
|
||||
HorizontalAlignment="Left"
|
||||
Margin="5 0 0 0"
|
||||
VerticalAlignment="Center" />
|
||||
</ProgressBar>
|
||||
</BoxContainer>
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" Margin="0 5 0 0">
|
||||
<ProgressBar Name="EnergyDisplayBar"
|
||||
HorizontalExpand="True"
|
||||
SetHeight="25"
|
||||
MaxValue="1"
|
||||
Value="0">
|
||||
<Label Name="EnergyDisplay"
|
||||
Margin="5 0 0 0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"></Label>
|
||||
</ProgressBar>
|
||||
</BoxContainer>
|
||||
<Label Name="SlotDisplay"
|
||||
HorizontalAlignment="Left"
|
||||
Access="Public"
|
||||
HorizontalExpand="True" />
|
||||
</BoxContainer>
|
||||
<SpriteView Name="MechView"
|
||||
Margin="10 0 0 0"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Right"
|
||||
OverrideDirection="South"
|
||||
SetSize="64 64"
|
||||
MaxSize="64 64"
|
||||
Scale="2 2">
|
||||
</SpriteView>
|
||||
</BoxContainer>
|
||||
<BoxContainer VerticalExpand="True" Margin="10 0 10 10" Orientation="Vertical">
|
||||
<PanelContainer VerticalExpand="True" MinSize="0 200">
|
||||
<PanelContainer.PanelOverride>
|
||||
<gfx:StyleBoxFlat BackgroundColor="#1B1B1E" />
|
||||
</PanelContainer.PanelOverride>
|
||||
<ScrollContainer
|
||||
HScrollEnabled="False"
|
||||
HorizontalExpand="True"
|
||||
MinSize="100 256"
|
||||
SizeFlagsStretchRatio="2"
|
||||
VerticalExpand="True">
|
||||
<BoxContainer
|
||||
Name="EquipmentControlContainer"
|
||||
MinSize="100 256"
|
||||
Orientation="Vertical"
|
||||
SizeFlagsStretchRatio="2"
|
||||
VerticalExpand="True">
|
||||
</BoxContainer>
|
||||
</ScrollContainer>
|
||||
</PanelContainer>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</controls:FancyWindow>
|
||||
72
Content.Client/Mech/Ui/MechMenu.xaml.cs
Normal file
72
Content.Client/Mech/Ui/MechMenu.xaml.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Client.UserInterface.Fragments;
|
||||
using Content.Shared.Mech.Components;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
|
||||
namespace Content.Client.Mech.Ui;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class MechMenu : FancyWindow
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _ent = default!;
|
||||
|
||||
private readonly EntityUid _mech;
|
||||
|
||||
public event Action<EntityUid>? OnRemoveButtonPressed;
|
||||
|
||||
public MechMenu(EntityUid mech)
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
_mech = mech;
|
||||
|
||||
if (!_ent.TryGetComponent<SpriteComponent>(mech, out var sprite))
|
||||
return;
|
||||
|
||||
MechView.Sprite = sprite;
|
||||
}
|
||||
|
||||
public void UpdateMechStats()
|
||||
{
|
||||
if (!_ent.TryGetComponent<SharedMechComponent>(_mech, out var mechComp))
|
||||
return;
|
||||
|
||||
var integrityPercent = mechComp.Integrity / mechComp.MaxIntegrity;
|
||||
IntegrityDisplayBar.Value = integrityPercent.Float();
|
||||
IntegrityDisplay.Text = Loc.GetString("mech-integrity-display", ("amount", (integrityPercent*100).Int()));
|
||||
|
||||
var energyPercent = mechComp.Energy / mechComp.MaxEnergy;
|
||||
EnergyDisplayBar.Value = energyPercent.Float();
|
||||
EnergyDisplay.Text = Loc.GetString("mech-energy-display", ("amount", (energyPercent*100).Int()));
|
||||
|
||||
SlotDisplay.Text = Loc.GetString("mech-slot-display",
|
||||
("amount", mechComp.MaxEquipmentAmount - mechComp.EquipmentContainer.ContainedEntities.Count));
|
||||
}
|
||||
|
||||
public void UpdateEquipmentView()
|
||||
{
|
||||
if (!_ent.TryGetComponent<MechComponent>(_mech, out var mechComp))
|
||||
return;
|
||||
|
||||
EquipmentControlContainer.Children.Clear();
|
||||
foreach (var ent in mechComp.EquipmentContainer.ContainedEntities)
|
||||
{
|
||||
if (!_ent.TryGetComponent<SpriteComponent>(ent, out var sprite) ||
|
||||
!_ent.TryGetComponent<MetaDataComponent>(ent, out var metaData))
|
||||
continue;
|
||||
|
||||
var uicomp = _ent.GetComponentOrNull<UIFragmentComponent>(ent);
|
||||
var ui = uicomp?.Ui?.GetUIFragmentRoot();
|
||||
|
||||
var control = new MechEquipmentControl(metaData.EntityName, sprite, ui);
|
||||
|
||||
control.OnRemoveButtonPressed += () => OnRemoveButtonPressed?.Invoke(ent);
|
||||
|
||||
EquipmentControlContainer.AddChild(control);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user