diff --git a/Robust.Client/Placement/IPlacementManager.cs b/Robust.Client/Placement/IPlacementManager.cs index c9f6c291b9..b04bd32a8f 100644 --- a/Robust.Client/Placement/IPlacementManager.cs +++ b/Robust.Client/Placement/IPlacementManager.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using Robust.Shared.Enums; using Robust.Shared.Maths; using Robust.Shared.Timing; @@ -49,9 +50,9 @@ namespace Robust.Client.Placement void ToggleEraserHijacked(PlacementHijack hijack); /// - /// Returns an array containing the names of all placement modes that can be used. + /// Returns a collection containing all placement mode Types that can be used. /// - string[] GetAllPlacementModes(); + IEnumerable GetAllPlacementModes(); void FrameUpdate(FrameEventArgs e); } diff --git a/Robust.Client/Placement/Modes/AlignSimilar.cs b/Robust.Client/Placement/Modes/AlignSimilar.cs index 78cab2388a..57d7499b29 100644 --- a/Robust.Client/Placement/Modes/AlignSimilar.cs +++ b/Robust.Client/Placement/Modes/AlignSimilar.cs @@ -9,7 +9,7 @@ using Robust.Shared.Prototypes; namespace Robust.Client.Placement.Modes { - [PlacementMode] + [PlacementMode(priority: (int)EnginePlacementMode.AlignSimilar)] public sealed class AlignSimilar : PlacementMode { private const uint SnapToRange = 50; diff --git a/Robust.Client/Placement/Modes/AlignSnapgridBorder.cs b/Robust.Client/Placement/Modes/AlignSnapgridBorder.cs index 7a2e68fe88..fd0d8d11f0 100644 --- a/Robust.Client/Placement/Modes/AlignSnapgridBorder.cs +++ b/Robust.Client/Placement/Modes/AlignSnapgridBorder.cs @@ -7,7 +7,7 @@ using Robust.Shared.Maths; namespace Robust.Client.Placement.Modes { - [PlacementMode] + [PlacementMode(priority: (int)EnginePlacementMode.SnapgridBorder)] public sealed class SnapgridBorder : SnapgridCenter { public override bool HasLineMode => true; diff --git a/Robust.Client/Placement/Modes/AlignSnapgridCenter.cs b/Robust.Client/Placement/Modes/AlignSnapgridCenter.cs index 1d22bfa4cc..e2b211549b 100644 --- a/Robust.Client/Placement/Modes/AlignSnapgridCenter.cs +++ b/Robust.Client/Placement/Modes/AlignSnapgridCenter.cs @@ -9,7 +9,7 @@ using Robust.Shared.Maths; namespace Robust.Client.Placement.Modes { [Virtual] - [PlacementMode] + [PlacementMode(priority: (int)EnginePlacementMode.SnapgridCenter)] public class SnapgridCenter : PlacementMode { protected MapGridComponent? Grid; diff --git a/Robust.Client/Placement/Modes/AlignTileAny.cs b/Robust.Client/Placement/Modes/AlignTileAny.cs index f7a8309720..059f476bea 100644 --- a/Robust.Client/Placement/Modes/AlignTileAny.cs +++ b/Robust.Client/Placement/Modes/AlignTileAny.cs @@ -5,7 +5,7 @@ using Robust.Shared.Map.Components; namespace Robust.Client.Placement.Modes { - [PlacementMode] + [PlacementMode(priority: (int)EnginePlacementMode.AlignTileAny)] public sealed class AlignTileAny : PlacementMode { public override bool HasLineMode => true; diff --git a/Robust.Client/Placement/Modes/AlignTileDense.cs b/Robust.Client/Placement/Modes/AlignTileDense.cs index 871df6993c..32629778b0 100644 --- a/Robust.Client/Placement/Modes/AlignTileDense.cs +++ b/Robust.Client/Placement/Modes/AlignTileDense.cs @@ -5,7 +5,7 @@ using Robust.Shared.Map.Components; namespace Robust.Client.Placement.Modes { - [PlacementMode] + [PlacementMode(priority: (int)EnginePlacementMode.AlignTileDense)] public sealed class AlignTileDense : PlacementMode { public override bool HasLineMode => true; diff --git a/Robust.Client/Placement/Modes/AlignTileEmpty.cs b/Robust.Client/Placement/Modes/AlignTileEmpty.cs index 50c662db0f..bdc2714efb 100644 --- a/Robust.Client/Placement/Modes/AlignTileEmpty.cs +++ b/Robust.Client/Placement/Modes/AlignTileEmpty.cs @@ -6,7 +6,7 @@ using Robust.Shared.Maths; namespace Robust.Client.Placement.Modes { - [PlacementMode] + [PlacementMode(priority: (int)EnginePlacementMode.AlignTileEmpty)] public sealed class AlignTileEmpty : PlacementMode { public override bool HasLineMode => true; diff --git a/Robust.Client/Placement/Modes/AlignTileNonDense.cs b/Robust.Client/Placement/Modes/AlignTileNonDense.cs index 117bb8a4ae..01a1e8cedd 100644 --- a/Robust.Client/Placement/Modes/AlignTileNonDense.cs +++ b/Robust.Client/Placement/Modes/AlignTileNonDense.cs @@ -5,7 +5,7 @@ using Robust.Shared.Map.Components; namespace Robust.Client.Placement.Modes { - [PlacementMode] + [PlacementMode(priority: (int)EnginePlacementMode.AlignTileNonDense)] public sealed class AlignTileNonDense : PlacementMode { public override bool HasLineMode => true; diff --git a/Robust.Client/Placement/Modes/AlignWall.cs b/Robust.Client/Placement/Modes/AlignWall.cs index d04361cff5..c7f06dd604 100644 --- a/Robust.Client/Placement/Modes/AlignWall.cs +++ b/Robust.Client/Placement/Modes/AlignWall.cs @@ -5,7 +5,7 @@ using Vector2 = System.Numerics.Vector2; namespace Robust.Client.Placement.Modes { - [PlacementMode] + [PlacementMode(priority: (int)EnginePlacementMode.AlignWall)] public sealed class AlignWall : PlacementMode { public AlignWall(PlacementManager pMan) : base(pMan) { } diff --git a/Robust.Client/Placement/Modes/AlignWallProper.cs b/Robust.Client/Placement/Modes/AlignWallProper.cs index 7eba3c722e..e3fe3ab203 100644 --- a/Robust.Client/Placement/Modes/AlignWallProper.cs +++ b/Robust.Client/Placement/Modes/AlignWallProper.cs @@ -7,7 +7,7 @@ namespace Robust.Client.Placement.Modes /// /// Snaps in edge on one axis, center in the other. /// - [PlacementMode] + [PlacementMode(priority: (int)EnginePlacementMode.AlignWallProper)] public sealed class AlignWallProper : PlacementMode { public AlignWallProper(PlacementManager pMan) : base(pMan) diff --git a/Robust.Client/Placement/Modes/PlaceFree.cs b/Robust.Client/Placement/Modes/PlaceFree.cs index 6bfdecab01..8d0f512f5f 100644 --- a/Robust.Client/Placement/Modes/PlaceFree.cs +++ b/Robust.Client/Placement/Modes/PlaceFree.cs @@ -2,7 +2,7 @@ namespace Robust.Client.Placement.Modes { - [PlacementMode] + [PlacementMode(priority: (int)EnginePlacementMode.PlaceFree)] public sealed class PlaceFree : PlacementMode { public PlaceFree(PlacementManager pMan) : base(pMan) { } diff --git a/Robust.Client/Placement/Modes/PlaceNearby.cs b/Robust.Client/Placement/Modes/PlaceNearby.cs index 2cc86b8c6d..4d060dbfcd 100644 --- a/Robust.Client/Placement/Modes/PlaceNearby.cs +++ b/Robust.Client/Placement/Modes/PlaceNearby.cs @@ -2,7 +2,7 @@ namespace Robust.Client.Placement.Modes { - [PlacementMode] + [PlacementMode(priority: (int)EnginePlacementMode.PlaceNearby)] public sealed class PlaceNearby : PlacementMode { public PlaceNearby(PlacementManager pMan) : base(pMan) { } diff --git a/Robust.Client/Placement/Modes/PlacementModeAttribute.cs b/Robust.Client/Placement/Modes/PlacementModeAttribute.cs index 71f3740690..56847b6e3a 100644 --- a/Robust.Client/Placement/Modes/PlacementModeAttribute.cs +++ b/Robust.Client/Placement/Modes/PlacementModeAttribute.cs @@ -6,10 +6,30 @@ namespace Robust.Client.Placement.Modes; [AttributeUsage(AttributeTargets.Class)] [BaseTypeRequired(typeof(PlacementMode))] [MeansImplicitUse] -public sealed class PlacementModeAttribute(string? name = null) : Attribute +public sealed class PlacementModeAttribute(string? name = null, int priority = 0) : Attribute { /// /// The display name of this placement mode. /// public string? Name { get; } = name; + + /// + /// Controls ordering of modes in the selector. Higher priority modes are listed first. + /// + public int Priority { get; } = priority; +} + +public enum EnginePlacementMode +{ + PlaceFree = 1000, + PlaceNearby = 999, + SnapgridCenter = 998, + SnapgridBorder = 997, + AlignSimilar = 996, + AlignTileAny = 995, + AlignTileEmpty = 994, + AlignTileNonDense = 993, + AlignTileDense = 992, + AlignWall = 991, + AlignWallProper = 990, } diff --git a/Robust.Client/Placement/PlacementManager.cs b/Robust.Client/Placement/PlacementManager.cs index bc3c026995..65c418e026 100644 --- a/Robust.Client/Placement/PlacementManager.cs +++ b/Robust.Client/Placement/PlacementManager.cs @@ -499,19 +499,9 @@ namespace Robust.Client.Placement else Clear(); } - public string[] GetAllPlacementModes() + public IEnumerable GetAllPlacementModes() { - List names = []; - var modes = _reflectionManager.FindTypesWithAttribute(); - foreach (var type in modes) - { - if (Attribute.GetCustomAttribute(type, typeof(PlacementModeAttribute)) is not PlacementModeAttribute attribute) - throw new InvalidImplementationException(type, typeof(PlacementMode), $"No {nameof(PlacementModeAttribute)}!"); - - // Use the override if specified, falling back to the Type name - names.Add(attribute.Name ?? type.Name); - } - return names.ToArray(); + return _reflectionManager.FindTypesWithAttribute(); } public void BeginPlacing(PlacementInformation info, PlacementHijack? hijack = null) diff --git a/Robust.Client/UserInterface/CustomControls/EntitySpawnWindow.xaml.cs b/Robust.Client/UserInterface/CustomControls/EntitySpawnWindow.xaml.cs index 86bd3f615f..8947d00985 100644 --- a/Robust.Client/UserInterface/CustomControls/EntitySpawnWindow.xaml.cs +++ b/Robust.Client/UserInterface/CustomControls/EntitySpawnWindow.xaml.cs @@ -1,11 +1,15 @@ +using System; using System.Collections.Generic; +using System.Linq; using System.Numerics; using Robust.Client.AutoGenerated; using Robust.Client.Graphics; using Robust.Client.Placement; +using Robust.Client.Placement.Modes; using Robust.Client.UserInterface.XAML; using Robust.Shared.Graphics; using Robust.Shared.IoC; +using Robust.Shared.IoC.Exceptions; using Robust.Shared.Maths; using Robust.Shared.Prototypes; @@ -28,9 +32,16 @@ namespace Robust.Client.UserInterface.CustomControls MeasureButton.Measure(Vector2Helpers.Infinity); - List modes = ["Default"]; - modes.AddRange(_placementManager.GetAllPlacementModes()); - InitOpts = modes.ToArray(); + List<(string Name, int Priority)> modes = [("Default", int.MaxValue)]; + foreach (var type in _placementManager.GetAllPlacementModes()) + { + if (Attribute.GetCustomAttribute(type, typeof(PlacementModeAttribute)) is not PlacementModeAttribute attribute) + throw new InvalidImplementationException(type, typeof(PlacementMode), $"No {nameof(PlacementModeAttribute)}!"); + + // Use the override if specified, falling back to the Type name + modes.Add((attribute.Name ?? type.Name, attribute.Priority)); + } + InitOpts = modes.OrderByDescending(m => m.Priority).Select(m => m.Name).ToArray(); for (var i = 0; i < InitOpts.Length; i++) { OverrideMenu.AddItem(InitOpts[i], i);