diff --git a/OpenRA.Mods.Common/Traits/World/ClearMapGenerator.cs b/OpenRA.Mods.Common/Traits/World/ClearMapGenerator.cs index d2381a4f0b..38319a1208 100644 --- a/OpenRA.Mods.Common/Traits/World/ClearMapGenerator.cs +++ b/OpenRA.Mods.Common/Traits/World/ClearMapGenerator.cs @@ -19,7 +19,7 @@ namespace OpenRA.Mods.Common.Traits { [TraitLocation(SystemActors.EditorWorld)] [Desc("A map generator that clears a map.")] - public sealed class ClearMapGeneratorInfo : TraitInfo, IEditorMapGeneratorInfo, IEditorToolInfo + public sealed class ClearMapGeneratorInfo : TraitInfo, IEditorMapGeneratorInfo { [FieldLoader.Require] [Desc("Human-readable name this generator uses.")] @@ -93,10 +93,26 @@ namespace OpenRA.Mods.Common.Traits return map; } - string IEditorToolInfo.Label => Name; - string IEditorToolInfo.PanelWidget => PanelWidget; + public override object Create(ActorInitializer init) + { + return new ClearMapGenerator(this); + } + string[] IEditorMapGeneratorInfo.Tilesets => Tilesets; } - public class ClearMapGenerator { /* we're only interested in the Info */ } + public class ClearMapGenerator : IEditorTool + { + public string Label { get; } + public string PanelWidget { get; } + public TraitInfo TraitInfo { get; } + public bool IsEnabled => true; + + public ClearMapGenerator(ClearMapGeneratorInfo info) + { + Label = info.Name; + PanelWidget = info.PanelWidget; + TraitInfo = info; + } + } } diff --git a/OpenRA.Mods.Common/Traits/World/ExperimentalMapGenerator.cs b/OpenRA.Mods.Common/Traits/World/ExperimentalMapGenerator.cs index 1871e4ceeb..de7b3879a9 100644 --- a/OpenRA.Mods.Common/Traits/World/ExperimentalMapGenerator.cs +++ b/OpenRA.Mods.Common/Traits/World/ExperimentalMapGenerator.cs @@ -22,7 +22,7 @@ using static OpenRA.Mods.Common.Traits.ResourceLayerInfo; namespace OpenRA.Mods.Common.Traits { [TraitLocation(SystemActors.EditorWorld)] - public sealed class ExperimentalMapGeneratorInfo : TraitInfo, IEditorMapGeneratorInfo, IEditorToolInfo + public sealed class ExperimentalMapGeneratorInfo : TraitInfo, IEditorMapGeneratorInfo { [FieldLoader.Require] public readonly string Type = null; @@ -899,9 +899,25 @@ namespace OpenRA.Mods.Common.Traits return map; } - string IEditorToolInfo.Label => Name; - string IEditorToolInfo.PanelWidget => PanelWidget; + public override object Create(ActorInitializer init) + { + return new ExperimentalMapGenerator(init, this); + } } - public class ExperimentalMapGenerator { /* we're only interested in the Info */ } + public class ExperimentalMapGenerator : IEditorTool + { + public string Label { get; } + public string PanelWidget { get; } + public TraitInfo TraitInfo { get; } + public bool IsEnabled { get; } + + public ExperimentalMapGenerator(ActorInitializer init, ExperimentalMapGeneratorInfo info) + { + Label = info.Name; + PanelWidget = info.PanelWidget; + TraitInfo = info; + IsEnabled = info.Tilesets.Contains(init.Self.World.Map.Tileset); + } + } } diff --git a/OpenRA.Mods.Common/Traits/World/MarkerLayerOverlay.cs b/OpenRA.Mods.Common/Traits/World/MarkerLayerOverlay.cs index 2d28da5db5..77220296d6 100644 --- a/OpenRA.Mods.Common/Traits/World/MarkerLayerOverlay.cs +++ b/OpenRA.Mods.Common/Traits/World/MarkerLayerOverlay.cs @@ -21,7 +21,7 @@ using Color = OpenRA.Primitives.Color; namespace OpenRA.Mods.Common.Traits { [TraitLocation(SystemActors.EditorWorld)] - public class MarkerLayerOverlayInfo : TraitInfo, IEditorToolInfo + public class MarkerLayerOverlayInfo : TraitInfo { [FluentReference] [Desc("The label to show in the tools menu.")] @@ -53,13 +53,15 @@ namespace OpenRA.Mods.Common.Traits { return new MarkerLayerOverlay(init.Self, this); } - - string IEditorToolInfo.Label => Label; - string IEditorToolInfo.PanelWidget => PanelWidget; } - public class MarkerLayerOverlay : IRenderAnnotations, INotifyActorDisposing, IWorldLoaded + public class MarkerLayerOverlay : IEditorTool, IRenderAnnotations, INotifyActorDisposing, IWorldLoaded { + public string Label { get; } + public string PanelWidget { get; } + public TraitInfo TraitInfo { get; } + public bool IsEnabled => true; + public class MarkerLayer { public readonly Dictionary Tiles; @@ -132,6 +134,8 @@ namespace OpenRA.Mods.Common.Traits Info = info; world = self.World; var map = self.World.Map; + Label = info.Label; + PanelWidget = info.PanelWidget; tileAlpha = info.Alpha; alphaBlendColors = new Color[info.Colors.Length]; diff --git a/OpenRA.Mods.Common/Traits/World/TilingPathTool.cs b/OpenRA.Mods.Common/Traits/World/TilingPathTool.cs index 9506abfb2d..af11ca06a0 100644 --- a/OpenRA.Mods.Common/Traits/World/TilingPathTool.cs +++ b/OpenRA.Mods.Common/Traits/World/TilingPathTool.cs @@ -23,14 +23,9 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { [TraitLocation(SystemActors.EditorWorld)] - public sealed class TilingPathToolInfo : TraitInfo, IEditorToolInfo + [IncludeStaticFluentReferences(typeof(TilingPathTool))] + public sealed class TilingPathToolInfo : TraitInfo { - [FluentReference] - const string Label = "label-tool-tiling-path"; - - [Desc("The widget tree to open when the tool is selected.")] - const string PanelWidget = "TILING_PATH_TOOL_PANEL"; - [Desc("The preferred defaults for the start type.")] public readonly string[] DefaultStart = []; [Desc("The preferred defaults for the inner type.")] @@ -42,13 +37,22 @@ namespace OpenRA.Mods.Common.Traits { return new TilingPathTool(init.Self, this); } - - string IEditorToolInfo.Label => Label; - string IEditorToolInfo.PanelWidget => PanelWidget; } - public sealed class TilingPathTool : IRenderAnnotations, INotifyActorDisposing, IWorldLoaded + public sealed class TilingPathTool : IEditorTool, IRenderAnnotations, INotifyActorDisposing, IWorldLoaded { + [FluentReference] + const string Label = "label-tool-tiling-path"; + + [Desc("The widget tree to open when the tool is selected.")] + const string PanelWidget = "TILING_PATH_TOOL_PANEL"; + + public bool IsEnabled { get; } + + string IEditorTool.Label => Label; + string IEditorTool.PanelWidget => PanelWidget; + public TraitInfo TraitInfo { get; } + /// /// Holds the shape of a path being planned out in the map editor. /// @@ -312,9 +316,6 @@ namespace OpenRA.Mods.Common.Traits } } - /// Whether the TilingPathTool can be used. - public readonly bool Available; - public readonly World World; public WorldRenderer WorldRenderer = null; public readonly ImmutableArray SegmentedBrushes; @@ -338,6 +339,7 @@ namespace OpenRA.Mods.Common.Traits public TilingPathTool(Actor self, TilingPathToolInfo info) { World = self.World; + TraitInfo = info; var templatedTerrainInfo = World.Map.Rules.TerrainInfo as ITemplatedTerrainInfo; SegmentedBrushes = @@ -347,9 +349,8 @@ namespace OpenRA.Mods.Common.Traits .Where(multiBrush => multiBrush.Segment != null) .ToImmutableArray(); - Available = SegmentedBrushes.Length > 0; - - if (!Available) + IsEnabled = SegmentedBrushes.Length > 0; + if (!IsEnabled) return; InnerTypes = SegmentedBrushes diff --git a/OpenRA.Mods.Common/TraitsInterfaces.cs b/OpenRA.Mods.Common/TraitsInterfaces.cs index cb9ebf2556..7770791256 100644 --- a/OpenRA.Mods.Common/TraitsInterfaces.cs +++ b/OpenRA.Mods.Common/TraitsInterfaces.cs @@ -977,10 +977,12 @@ namespace OpenRA.Mods.Common.Traits bool PathMightExistForLocomotorBlockedByImmovable(Locomotor locomotor, CPos source, CPos target); } - public interface IEditorToolInfo : ITraitInfoInterface + public interface IEditorTool { string Label { get; } string PanelWidget { get; } + bool IsEnabled { get; } + TraitInfo TraitInfo { get; } } public class MapGenerationException : Exception diff --git a/OpenRA.Mods.Common/Widgets/Logic/Editor/MapEditorTabsLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Editor/MapEditorTabsLogic.cs index 30b7a9fb5c..1b5fdcec54 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Editor/MapEditorTabsLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Editor/MapEditorTabsLogic.cs @@ -9,6 +9,7 @@ */ #endregion +using System.Linq; using OpenRA.Mods.Common.Traits; using OpenRA.Widgets; @@ -72,7 +73,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (tabType == MenuType.Tools) { - var toolsAvailable = world.Map.Rules.Actors[SystemActors.EditorWorld].HasTraitInfo(); + var toolsAvailable = world.WorldActor.TraitsImplementing().Any(); tab.IsDisabled = () => !toolsAvailable; } diff --git a/OpenRA.Mods.Common/Widgets/Logic/Editor/MapGeneratorToolLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Editor/MapGeneratorToolLogic.cs index 7d5e30358e..1497c84817 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Editor/MapGeneratorToolLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Editor/MapGeneratorToolLogic.cs @@ -44,15 +44,14 @@ namespace OpenRA.Mods.Common.Widgets.Logic readonly Widget dropDownSettingTemplate; [ObjectCreator.UseCtor] - public MapGeneratorToolLogic(Widget widget, World world, WorldRenderer worldRenderer, ModData modData, - IEditorMapGeneratorInfo tool) + public MapGeneratorToolLogic(Widget widget, World world, WorldRenderer worldRenderer, ModData modData, IEditorTool tool) { editorActionManager = world.WorldActor.Trait(); this.world = world; this.worldRenderer = worldRenderer; this.modData = modData; - generator = tool; + generator = tool.TraitInfo as IEditorMapGeneratorInfo; settings = generator.GetSettings(); settingsPanel = widget.Get("SETTINGS_PANEL"); diff --git a/OpenRA.Mods.Common/Widgets/Logic/Editor/MapToolsLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Editor/MapToolsLogic.cs index 763ccf78c3..4946454957 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Editor/MapToolsLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Editor/MapToolsLogic.cs @@ -26,10 +26,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic public MapToolsLogic(Widget widget, World world) { var toolDropdownWidget = widget.Get("TOOLS_DROPDOWN"); - var tools = world.Map.Rules.Actors[SystemActors.EditorWorld].TraitInfos(); + var tools = world.WorldActor.TraitsImplementing(); foreach (var tool in tools) { - if (tool is IEditorMapGeneratorInfo gi && !gi.Tilesets.Contains(world.Map.Tileset)) + if (!tool.IsEnabled) continue; var panel = Game.LoadWidget(world, tool.PanelWidget, widget, new WidgetArgs() { { "tool", tool } }); diff --git a/OpenRA.Mods.Common/Widgets/Logic/Editor/TilingPathToolLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Editor/TilingPathToolLogic.cs index 3ecdc7920b..dfefaf7158 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Editor/TilingPathToolLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Editor/TilingPathToolLogic.cs @@ -40,10 +40,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic ((ScrollPanelWidget)widget).Layout.AdjustChildren(); var editCheckbox = widget.Get("EDIT"); - editCheckbox.Disabled = !tool.Available; - if (!tool.Available) - return; - editCheckbox.IsChecked = () => editorWidget.CurrentBrush is EditorTilingPathBrush; editCheckbox.OnClick = () => editorWidget.SetBrush( diff --git a/OpenRA.Mods.D2k/Traits/World/D2kMapGenerator.cs b/OpenRA.Mods.D2k/Traits/World/D2kMapGenerator.cs index a42eaadf6c..65222c7fd4 100644 --- a/OpenRA.Mods.D2k/Traits/World/D2kMapGenerator.cs +++ b/OpenRA.Mods.D2k/Traits/World/D2kMapGenerator.cs @@ -23,7 +23,7 @@ using static OpenRA.Mods.Common.Traits.ResourceLayerInfo; namespace OpenRA.Mods.D2k.Traits { [TraitLocation(SystemActors.EditorWorld)] - public sealed class D2kMapGeneratorInfo : TraitInfo, IEditorMapGeneratorInfo, IEditorToolInfo + public sealed class D2kMapGeneratorInfo : TraitInfo, IEditorMapGeneratorInfo { [FieldLoader.Require] public readonly string Type = null; @@ -614,9 +614,24 @@ namespace OpenRA.Mods.D2k.Traits return map; } - string IEditorToolInfo.Label => Name; - string IEditorToolInfo.PanelWidget => PanelWidget; + public override object Create(ActorInitializer init) + { + return new D2kMapGenerator(this); + } } - public class D2kMapGenerator { /* we're only interested in the Info */ } + public class D2kMapGenerator : IEditorTool + { + public string Label { get; } + public string PanelWidget { get; } + public TraitInfo TraitInfo { get; } + public bool IsEnabled => true; + + public D2kMapGenerator(D2kMapGeneratorInfo info) + { + Label = info.Name; + PanelWidget = info.PanelWidget; + TraitInfo = info; + } + } }