diff --git a/OpenRA.Mods.Common/EditorBrushes/EditorDefaultBrush.cs b/OpenRA.Mods.Common/EditorBrushes/EditorDefaultBrush.cs index bd7f865235..a82faca76d 100644 --- a/OpenRA.Mods.Common/EditorBrushes/EditorDefaultBrush.cs +++ b/OpenRA.Mods.Common/EditorBrushes/EditorDefaultBrush.cs @@ -11,7 +11,9 @@ using System; using System.Collections.Generic; +using System.Linq; using OpenRA.Graphics; +using OpenRA.Mods.Common.EditorBrushes; using OpenRA.Mods.Common.Graphics; using OpenRA.Mods.Common.Traits; using OpenRA.Widgets; @@ -87,6 +89,12 @@ namespace OpenRA.Mods.Common.Widgets return ((long)pixelDistance << 32) + worldZPosition; } + public void DeleteSelection(MapBlitFilters filters) + { + if (Selection.Area != null) + editorActionManager.Add(new DeleteAreaAction(world.Map, filters, Selection.Area, resourceLayer, actorLayer)); + } + public void ClearSelection(bool updateSelectedTab = false) { if (Selection.HasSelection) @@ -335,6 +343,114 @@ namespace OpenRA.Mods.Common.Widgets } } + sealed class DeleteAreaAction : IEditorAction + { + [FluentReference("x", "y", "width", "height")] + const string RemovedArea = "notification-removed-area"; + + public string Text { get; } + + readonly EditorBlitSource editorBlitSource; + readonly MapBlitFilters blitFilters; + readonly IResourceLayer resourceLayer; + readonly EditorActorLayer editorActorLayer; + readonly CellRegion area; + readonly Map map; + + public DeleteAreaAction(Map map, MapBlitFilters blitFilters, CellRegion area, IResourceLayer resourceLayer, EditorActorLayer editorActorLayer) + { + this.map = map; + this.blitFilters = blitFilters; + this.resourceLayer = resourceLayer; + this.editorActorLayer = editorActorLayer; + this.area = area; + + editorBlitSource = EditorBlit.CopyRegionContents(map, editorActorLayer, resourceLayer, area, blitFilters); + + Text = FluentProvider.GetMessage(RemovedArea, + "x", area.TopLeft.X, + "y", area.TopLeft.Y, + "width", area.BottomRight.X - area.TopLeft.X, + "height", area.BottomRight.Y - area.TopLeft.Y); + } + + public void Execute() + { + Do(); + } + + public void Do() + { + if (blitFilters.HasFlag(MapBlitFilters.Actors)) + { + // Clear any existing actors in the paste cells. + foreach (var regionActor in editorActorLayer.PreviewsInCellRegion(area.CellCoords).ToList()) + editorActorLayer.Remove(regionActor); + } + + foreach (var tileKeyValuePair in editorBlitSource.Tiles) + { + var position = tileKeyValuePair.Key; + if (!map.Tiles.Contains(position)) + continue; + + // Clear any existing resources. + if (resourceLayer != null && blitFilters.HasFlag(MapBlitFilters.Resources)) + resourceLayer.ClearResources(position); + + if (blitFilters.HasFlag(MapBlitFilters.Terrain)) + { + map.Tiles[position] = map.Rules.TerrainInfo.DefaultTerrainTile; + map.Height[position] = 0; + } + } + } + + public void Undo() + { + foreach (var tileKeyValuePair in editorBlitSource.Tiles) + { + var position = tileKeyValuePair.Key; + if (!map.Tiles.Contains(position)) + continue; + + var tile = tileKeyValuePair.Value; + var resourceLayerContents = tile.ResourceLayerContents; + + if (blitFilters.HasFlag(MapBlitFilters.Terrain)) + { + map.Tiles[position] = tile.TerrainTile; + map.Height[position] = tile.Height; + } + + if (blitFilters.HasFlag(MapBlitFilters.Resources) && + resourceLayerContents.HasValue && + !string.IsNullOrWhiteSpace(resourceLayerContents.Value.Type)) + resourceLayer.AddResource(resourceLayerContents.Value.Type, position, resourceLayerContents.Value.Density); + } + + if (blitFilters.HasFlag(MapBlitFilters.Actors)) + { + // Create copies of the original actors, update their locations, and place. + foreach (var actorKeyValuePair in editorBlitSource.Actors) + { + var copy = actorKeyValuePair.Value.Export(); + var locationInit = copy.GetOrDefault(); + if (locationInit != null) + { + if (!map.Tiles.Contains(locationInit.Value)) + continue; + + copy.RemoveAll(); + copy.Add(new LocationInit(locationInit.Value)); + } + + editorActorLayer.Add(copy); + } + } + } + } + sealed class RemoveSelectedActorAction : IEditorAction { [FluentReference("name", "id")] diff --git a/OpenRA.Mods.Common/Widgets/Logic/Editor/MapEditorSelectionLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Editor/MapEditorSelectionLogic.cs index bb73f139e3..238749b584 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Editor/MapEditorSelectionLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Editor/MapEditorSelectionLogic.cs @@ -33,7 +33,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic public LabelWidget DiagonalLabel; public LabelWidget ResourceCounterLabel; - MapBlitFilters copyFilters = MapBlitFilters.All; + MapBlitFilters selectionFilters = MapBlitFilters.All; EditorBlitSource? clipboard; [ObjectCreator.UseCtor] @@ -81,12 +81,15 @@ namespace OpenRA.Mods.Common.Widgets.Logic worldRenderer, clipboard.Value, resourceLayer, - () => copyFilters)); + () => selectionFilters)); }; pasteButton.IsDisabled = () => clipboard == null; pasteButton.IsHighlighted = () => editor.CurrentBrush is EditorCopyPasteBrush; + var deleteAreaSelectionButton = areaEditPanel.Get("SELECTION_DELETE_BUTTON"); + deleteAreaSelectionButton.OnClick = () => editor.DefaultBrush.DeleteSelection(selectionFilters); + var closeAreaSelectionButton = areaEditPanel.Get("SELECTION_CANCEL_BUTTON"); closeAreaSelectionButton.OnClick = () => editor.DefaultBrush.ClearSelection(updateSelectedTab: true); @@ -102,15 +105,15 @@ namespace OpenRA.Mods.Common.Widgets.Logic editorActorLayer, resourceLayer, editor.DefaultBrush.Selection.Area, - copyFilters); + selectionFilters); } void CreateCategoryPanel(MapBlitFilters copyFilter, CheckboxWidget checkbox) { checkbox.GetText = () => copyFilter.ToString(); - checkbox.IsChecked = () => copyFilters.HasFlag(copyFilter); + checkbox.IsChecked = () => selectionFilters.HasFlag(copyFilter); checkbox.IsVisible = () => true; - checkbox.OnClick = () => copyFilters ^= copyFilter; + checkbox.OnClick = () => selectionFilters ^= copyFilter; } protected override void Dispose(bool disposing) diff --git a/mods/cnc/chrome/editor.yaml b/mods/cnc/chrome/editor.yaml index f2bb48c2ae..02cccd1651 100644 --- a/mods/cnc/chrome/editor.yaml +++ b/mods/cnc/chrome/editor.yaml @@ -634,7 +634,7 @@ Container@EDITOR_WORLD_ROOT: Height: 25 Font: Bold Align: Left - Text: label-copy-filters + Text: label-selection-filters Checkbox@COPY_FILTER_TERRAIN_CHECKBOX: X: 7 Y: 70 @@ -688,6 +688,13 @@ Container@EDITOR_WORLD_ROOT: Width: 55 Height: 22 Align: Left + Button@SELECTION_DELETE_BUTTON: + X: 7 + Y: 222 + Width: 75 + Height: 25 + Text: button-delete-area.label + Font: Bold Button@SELECTION_CANCEL_BUTTON: X: 208 Y: 222 diff --git a/mods/cnc/fluent/chrome.ftl b/mods/cnc/fluent/chrome.ftl index d9a3f7cf2c..dc6de9ccbf 100644 --- a/mods/cnc/fluent/chrome.ftl +++ b/mods/cnc/fluent/chrome.ftl @@ -66,7 +66,7 @@ label-area-selection = Area Selection label-area-info = Area Info label-selected-area-diagonal = Diagonal: label-selected-area-resources = Resources: -label-copy-filters = Copy Filters +label-selection-filters = Filters label-filter-terrain = Terrain label-filter-resources = Resources label-filter-actors = Actors @@ -85,6 +85,9 @@ button-map-editor-tab-container-actors-tooltip = Actors button-map-editor-tab-container-tools-tooltip = Tools button-map-editor-tab-container-history-tooltip = History +button-delete-area = + .label = Delete + button-editor-world-root-copy = .label = Copy .tooltip = Copy the selected area diff --git a/mods/common/chrome/editor.yaml b/mods/common/chrome/editor.yaml index 190c32a9e1..a302ed3c03 100644 --- a/mods/common/chrome/editor.yaml +++ b/mods/common/chrome/editor.yaml @@ -600,7 +600,7 @@ Container@EDITOR_WORLD_ROOT: Height: 25 Font: Bold Align: Left - Text: label-copy-filters + Text: label-selection-filters Checkbox@COPY_FILTER_TERRAIN_CHECKBOX: X: 5 Y: 70 @@ -654,6 +654,13 @@ Container@EDITOR_WORLD_ROOT: Width: 55 Height: 22 Align: Left + Button@SELECTION_DELETE_BUTTON: + X: 5 + Y: 222 + Width: 75 + Height: 25 + Text: button-delete-area.label + Font: Bold Button@SELECTION_CANCEL_BUTTON: X: 208 Y: 222 diff --git a/mods/common/fluent/chrome.ftl b/mods/common/fluent/chrome.ftl index 735d687878..76b9b922bb 100644 --- a/mods/common/fluent/chrome.ftl +++ b/mods/common/fluent/chrome.ftl @@ -62,7 +62,7 @@ label-area-selection = Area Selection label-area-info = Area Info label-selected-area-diagonal = Diagonal: label-selected-area-resources = Resources: -label-copy-filters = Copy Filters +label-selection-filters = Filters label-filter-terrain = Terrain label-filter-resources = Resources label-filter-actors = Actors @@ -81,6 +81,9 @@ button-map-editor-tab-container-actors-tooltip = Actors button-map-editor-tab-container-tools-tooltip = Tools button-map-editor-tab-container-history-tooltip = History +button-delete-area = + .label = Delete + button-editor-world-root-options = .label = Menu .tooltip = Menu diff --git a/mods/common/fluent/common.ftl b/mods/common/fluent/common.ftl index d457497fef..7ddb13959f 100644 --- a/mods/common/fluent/common.ftl +++ b/mods/common/fluent/common.ftl @@ -804,6 +804,7 @@ notification-copied-tiles = ## EditorDefaultBrush notification-selected-area = Selected area { $x },{ $y } ({ $width },{ $height }) +notification-removed-area = Removed area { $x },{ $y } ({ $width },{ $height }) notification-selected-actor = Selected actor { $id } notification-cleared-selection = Cleared selection notification-removed-actor = Removed { $name } ({ $id })