Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
using Content.Client._CM14.Attachable.Components;
using Content.Shared._CM14.Attachable.Events;
using Robust.Client.GameObjects;
namespace Content.Client._CM14.Attachable;
public sealed class AttachableHolderVisualsSystem : EntitySystem
{
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<AttachableHolderVisualsComponent, AttachableHolderAttachablesAlteredEvent>(OnAttachablesAltered);
}
private void OnAttachablesAltered(Entity<AttachableHolderVisualsComponent> holder,
ref AttachableHolderAttachablesAlteredEvent args)
{
if (!TryComp(args.Attachable, out AttachableVisualsComponent? attachableComponent))
return;
var attachable = new Entity<AttachableVisualsComponent>(args.Attachable, attachableComponent);
switch (args.Alteration)
{
case AttachableAlteredType.Attached:
SetAttachableOverlay(holder, attachable, args.SlotId);
break;
case AttachableAlteredType.Detached:
RemoveAttachableOverlay(holder, args.SlotId);
break;
case AttachableAlteredType.Activated:
if (!attachableComponent.ShowActive)
break;
SetAttachableOverlay(holder, attachable, args.SlotId, "-on");
break;
case AttachableAlteredType.Deactivated:
if (!attachableComponent.ShowActive)
break;
SetAttachableOverlay(holder, attachable, args.SlotId);
break;
}
}
private void RemoveAttachableOverlay(Entity<AttachableHolderVisualsComponent> holder, string slotId)
{
if (!holder.Comp.Offsets.ContainsKey(slotId) || !TryComp(holder, out SpriteComponent? spriteComponent))
return;
if (!spriteComponent.LayerMapTryGet(slotId, out var index))
return;
spriteComponent.LayerMapRemove(slotId);
spriteComponent.RemoveLayer(index);
}
private void SetAttachableOverlay(Entity<AttachableHolderVisualsComponent> holder,
Entity<AttachableVisualsComponent> attachable,
string slotId,
string suffix = "")
{
if (!holder.Comp.Offsets.ContainsKey(slotId) ||
!TryComp(holder, out SpriteComponent? holderSprite))
{
return;
}
if (!TryComp(attachable, out SpriteComponent? attachableSprite))
return;
var rsi = attachableSprite.LayerGetActualRSI(attachable.Comp.Layer)?.Path;
var state = attachableSprite.LayerGetState(attachable.Comp.Layer).ToString();
if (attachable.Comp.Rsi is { } rsiPath)
{
rsi = rsiPath;
if (attachable.Comp.Prefix == null)
state = slotId;
}
if (!string.IsNullOrWhiteSpace(attachable.Comp.Prefix))
state = attachable.Comp.Prefix + state;
if (attachable.Comp.IncludeSlotName)
state += slotId;
if (!string.IsNullOrWhiteSpace(attachable.Comp.Suffix))
state += attachable.Comp.Suffix;
state += suffix;
var layerData = new PrototypeLayerData()
{
RsiPath = rsi.ToString(),
State = state,
Offset = holder.Comp.Offsets[slotId] + attachable.Comp.Offset,
Visible = true,
};
if (holderSprite.LayerMapTryGet(slotId, out var index))
{
holderSprite.LayerSetData(index, layerData);
return;
}
holderSprite.LayerMapSet(slotId, holderSprite.AddLayer(layerData));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Numerics;
namespace Content.Client._CM14.Attachable.Components;
[RegisterComponent, AutoGenerateComponentState]
[Access(typeof(AttachableHolderVisualsSystem))]
public sealed partial class AttachableHolderVisualsComponent : Component
{
/// <summary>
/// This dictionary contains a list of offsets for every slot that should display the attachable placed into it.
/// If a slot is not in this dictionary, the attachable inside will not be displayed.
/// The list of valid slot names can be found in AttachableHolderComponent.cs
/// </summary>
[DataField(required: true), AutoNetworkedField]
public Dictionary<string, Vector2> Offsets = new();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.Numerics;
using Robust.Shared.Utility;
namespace Content.Client._CM14.Attachable.Components;
[RegisterComponent, AutoGenerateComponentState]
[Access(typeof(AttachableHolderVisualsSystem))]
public sealed partial class AttachableVisualsComponent : Component
{
[DataField, AutoNetworkedField]
public ResPath? Rsi;
[DataField, AutoNetworkedField]
public string? Prefix;
[DataField, AutoNetworkedField]
public string? Suffix = "_a";
[DataField, AutoNetworkedField]
public bool IncludeSlotName;
[DataField, AutoNetworkedField]
public bool ShowActive;
[DataField, AutoNetworkedField]
public int Layer;
[DataField, AutoNetworkedField]
public Vector2 Offset;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<controls:FancyWindow
xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
Title="{Loc 'cm-attachable-holder-strip-ui-title'}"
MinSize="200 100"
SetSize="200 100">
<BoxContainer Name="SlotsContainer" Orientation="Vertical" VerticalExpand="True"
HorizontalExpand="True" Margin="8 8 8 8" />
</controls:FancyWindow>
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using Content.Client.UserInterface.Controls;
using Content.Shared._CM14.Attachable;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
namespace Content.Client._CM14.Attachable.Ui;
[GenerateTypedNameReferences]
public sealed partial class AttachableHolderChooseSlotMenu : FancyWindow
{
private readonly AttachmentChooseSlotBui _boundUI;
private readonly Dictionary<string, AttachableSlotControl> _attachableSlotControls;
public AttachableHolderChooseSlotMenu(AttachmentChooseSlotBui boundUI)
{
RobustXamlLoader.Load(this);
_boundUI = boundUI;
_attachableSlotControls = new Dictionary<string, AttachableSlotControl>();
OnClose += boundUI.Close;
}
public void UpdateMenu(List<string> attachableSlots)
{
foreach (var slotId in attachableSlots)
{
if (!_attachableSlotControls.ContainsKey(slotId))
AddSlotControl(slotId);
}
}
private void AddSlotControl(string slotId)
{
var slotControl = new AttachableSlotControl(this, _boundUI, slotId);
SlotsContainer.AddChild(slotControl);
_attachableSlotControls.Add(slotId, slotControl);
}
private sealed class AttachableSlotControl : Control
{
public AttachableSlotControl(AttachableHolderChooseSlotMenu slotMenu,
AttachmentChooseSlotBui boundUI,
string slotId)
{
var button = new Button { Text = Loc.GetString(slotId) };
button.OnPressed += _ =>
{
boundUI.SendMessage(new AttachableHolderAttachToSlotMessage(slotId));
slotMenu.Close();
};
AddChild(button);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<controls:FancyWindow
xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
Title="{Loc 'cm-attachable-holder-strip-ui-title'}"
MinSize="350 400"
SetSize="350 400">
<BoxContainer Name="AttachablesContainer" Orientation="Vertical" VerticalExpand="True"
Margin="8 8 8 8" />
</controls:FancyWindow>
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using System.Numerics;
using Content.Client.Stylesheets;
using Content.Client.UserInterface.Controls;
using Content.Shared._CM14.Attachable;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using static Robust.Client.UserInterface.Controls.BoxContainer;
namespace Content.Client._CM14.Attachable.Ui;
[GenerateTypedNameReferences]
public sealed partial class AttachableHolderStripMenu : FancyWindow
{
private readonly AttachmentStripBui _boundUI;
private readonly Dictionary<string, AttachableSlotControl> _attachableSlotControls;
public AttachableHolderStripMenu(AttachmentStripBui boundUI)
{
RobustXamlLoader.Load(this);
_boundUI = boundUI;
_attachableSlotControls = new Dictionary<string, AttachableSlotControl>();
OnClose += boundUI.Close;
}
public void UpdateMenu(Dictionary<string, string?> attachableSlots)
{
foreach (var slotId in attachableSlots.Keys)
{
if (!_attachableSlotControls.ContainsKey(slotId))
AddSlotControl(slotId);
_attachableSlotControls[slotId].Update(attachableSlots[slotId]);
}
}
private void AddSlotControl(string slotId, string? attachableName = null)
{
var slotControl = new AttachableSlotControl(_boundUI, slotId);
AttachablesContainer.AddChild(slotControl);
_attachableSlotControls.Add(slotId, slotControl);
}
private sealed class AttachableSlotControl : Control
{
private readonly Button AttachableButton;
public AttachableSlotControl(AttachmentStripBui boundUI, string slotId)
{
var slotLabel = new Label
{
Text = Loc.GetString(slotId) + ':',
HorizontalAlignment = HAlignment.Left
};
AttachableButton = new Button
{
Text = Loc.GetString("cm-attachable-holder-strip-ui-empty-slot"),
HorizontalExpand = true,
HorizontalAlignment = HAlignment.Right,
StyleClasses = { StyleClass.ButtonOpenRight }
};
var hBox = new BoxContainer
{
Orientation = LayoutOrientation.Horizontal,
Children =
{
new Control { MinSize = new Vector2(5, 0) },
slotLabel,
new Control { MinSize = new Vector2(5, 0) },
AttachableButton,
},
};
AttachableButton.OnPressed += _ => boundUI.SendMessage(new AttachableHolderDetachMessage(slotId));
AddChild(hBox);
}
public void Update(string? attachableName)
{
if (attachableName == null)
{
AttachableButton.Text = Loc.GetString("cm-attachable-holder-strip-ui-empty-slot");
AttachableButton.Disabled = true;
return;
}
AttachableButton.Text = attachableName;
AttachableButton.Disabled = false;
}
}
}
33 changes: 33 additions & 0 deletions Content.Client/_CM14/Attachable/Ui/AttachmentChooseSlotBui.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Content.Shared._CM14.Attachable;
namespace Content.Client._CM14.Attachable.Ui;
public sealed class AttachmentChooseSlotBui : BoundUserInterface
{
[ViewVariables]
private AttachableHolderChooseSlotMenu? _menu;
public AttachmentChooseSlotBui(EntityUid owner, Enum uiKey) : base(owner, uiKey) { }
protected override void Open()
{
base.Open();
_menu = new AttachableHolderChooseSlotMenu(this);
var metaQuery = EntMan.GetEntityQuery<MetaDataComponent>();
if (metaQuery.TryGetComponent(Owner, out var metadata))
_menu.Title = metadata.EntityName;
_menu.OpenCentered();
}
protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);
if (state is not AttachableHolderChooseSlotUserInterfaceState msg)
return;
if (_menu == null)
return;
_menu.UpdateMenu(msg.AttachableSlots);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
return;
_menu?.Dispose();
}
}
32 changes: 32 additions & 0 deletions Content.Client/_CM14/Attachable/Ui/AttachmentStripBui.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using Content.Shared._CM14.Attachable;
namespace Content.Client._CM14.Attachable.Ui;
public sealed class AttachmentStripBui : BoundUserInterface
{
private AttachableHolderStripMenu? _menu;
public AttachmentStripBui(EntityUid owner, Enum uiKey) : base(owner, uiKey) { }
protected override void Open()
{
base.Open();
_menu = new AttachableHolderStripMenu(this);
var metaQuery = EntMan.GetEntityQuery<MetaDataComponent>();
if (metaQuery.TryGetComponent(Owner, out var metadata))
_menu.Title = metadata.EntityName;
_menu.OpenCentered();
}
protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);
if (state is not AttachableHolderStripUserInterfaceState msg)
return;
if (_menu == null)
return;
_menu.UpdateMenu(msg.AttachableSlots);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
return;
_menu?.Dispose();
}
}
Loading
Loading