From cac0438d48b6cf99bf6c5bc43192d6a3d2094a04 Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Fri, 14 Jun 2024 15:32:14 +0100 Subject: [PATCH] Fix map editor copy-paste for isometric maps. When dealing with isometric maps, the copy paste region needs to copy the CellCoords area covered by the CellRegion. This is equivalent to the selected rectangle on screen. Using the cell region itself invokes cell->map->cell conversion that doesn't roundtrip and thus some of the selected cells don't get copied. Also when pasting terrain + actors, we need to fix the sequencing to clear actors on the current terrain, before adjusting the height and pasting in new actors. The current sequencing means we are clearing actors after having adjusted the terrain height, and affects the wrong area. --- .../EditorBrushes/EditorCopyPasteBrush.cs | 28 +++++++++++-------- .../Traits/World/EditorResourceLayer.cs | 2 +- .../Logic/Editor/MapEditorSelectionLogic.cs | 2 +- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/OpenRA.Mods.Common/EditorBrushes/EditorCopyPasteBrush.cs b/OpenRA.Mods.Common/EditorBrushes/EditorCopyPasteBrush.cs index c0e0a0b4c0..1c5bc12052 100644 --- a/OpenRA.Mods.Common/EditorBrushes/EditorCopyPasteBrush.cs +++ b/OpenRA.Mods.Common/EditorBrushes/EditorCopyPasteBrush.cs @@ -165,7 +165,7 @@ namespace OpenRA.Mods.Common.Widgets tiles.Add(cell, new ClipboardTile(mapTiles[cell], mapResources[cell], resourceLayerContents, mapHeight[cell])); if (copyFilters.HasFlag(MapCopyFilters.Actors)) - foreach (var preview in selection.SelectMany(editorActorLayer.PreviewsAt).Distinct()) + foreach (var preview in selection.CellCoords.SelectMany(editorActorLayer.PreviewsAt).Distinct()) previews.TryAdd(preview.ID, preview); } @@ -182,6 +182,15 @@ namespace OpenRA.Mods.Common.Widgets var sourcePos = clipboard.CellRegion.TopLeft; var pasteVec = new CVec(pastePosition.X - sourcePos.X, pastePosition.Y - sourcePos.Y); + if (copyFilters.HasFlag(MapCopyFilters.Actors)) + { + // Clear any existing actors in the paste cells. + var selectionSize = clipboard.CellRegion.BottomRight - clipboard.CellRegion.TopLeft; + var pasteRegion = new CellRegion(map.Grid.Type, pastePosition, pastePosition + selectionSize); + foreach (var regionActor in pasteRegion.CellCoords.SelectMany(editorActorLayer.PreviewsAt).ToHashSet()) + editorActorLayer.Remove(regionActor); + } + foreach (var tileKeyValuePair in clipboard.Tiles) { var position = tileKeyValuePair.Key + pasteVec; @@ -209,12 +218,6 @@ namespace OpenRA.Mods.Common.Widgets if (copyFilters.HasFlag(MapCopyFilters.Actors)) { - // Clear any existing actors in the paste cells. - var selectionSize = clipboard.CellRegion.BottomRight - clipboard.CellRegion.TopLeft; - var pasteRegion = new CellRegion(map.Grid.Type, pastePosition, pastePosition + selectionSize); - foreach (var regionActor in pasteRegion.SelectMany(editorActorLayer.PreviewsAt).ToHashSet()) - editorActorLayer.Remove(regionActor); - // Now place actors. foreach (var actorKeyValuePair in clipboard.Actors) { @@ -238,6 +241,13 @@ namespace OpenRA.Mods.Common.Widgets public void Undo() { + if (copyFilters.HasFlag(MapCopyFilters.Actors)) + { + // Clear existing actors. + foreach (var regionActor in undoClipboard.CellRegion.CellCoords.SelectMany(editorActorLayer.PreviewsAt).Distinct().ToList()) + editorActorLayer.Remove(regionActor); + } + foreach (var tileKeyValuePair in undoClipboard.Tiles) { var position = tileKeyValuePair.Key; @@ -262,10 +272,6 @@ namespace OpenRA.Mods.Common.Widgets if (copyFilters.HasFlag(MapCopyFilters.Actors)) { - // Clear existing actors. - foreach (var regionActor in undoClipboard.CellRegion.SelectMany(editorActorLayer.PreviewsAt).Distinct().ToList()) - editorActorLayer.Remove(regionActor); - // Place actors back again. foreach (var actor in undoClipboard.Actors.Values) editorActorLayer.Add(actor); diff --git a/OpenRA.Mods.Common/Traits/World/EditorResourceLayer.cs b/OpenRA.Mods.Common/Traits/World/EditorResourceLayer.cs index b0b4d063c4..c327d1660d 100644 --- a/OpenRA.Mods.Common/Traits/World/EditorResourceLayer.cs +++ b/OpenRA.Mods.Common/Traits/World/EditorResourceLayer.cs @@ -185,7 +185,7 @@ namespace OpenRA.Mods.Common.Traits public int CalculateRegionValue(CellRegion sourceRegion) { var resourceValueInRegion = 0; - foreach (var cell in sourceRegion) + foreach (var cell in sourceRegion.CellCoords) { var mcell = cell.ToMPos(Map); if (Map.Resources.Contains(mcell) && Map.Resources[mcell].Type != 0) diff --git a/OpenRA.Mods.Common/Widgets/Logic/Editor/MapEditorSelectionLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Editor/MapEditorSelectionLogic.cs index 12b77d3897..2d7432201b 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Editor/MapEditorSelectionLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Editor/MapEditorSelectionLogic.cs @@ -123,7 +123,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic tiles.Add(cell, new ClipboardTile(mapTiles[cell], mapResources[cell], resourceLayer?.GetResource(cell), mapHeight[cell])); if (copyFilters.HasFlag(MapCopyFilters.Actors)) - foreach (var preview in selection.SelectMany(editorActorLayer.PreviewsAt).Distinct()) + foreach (var preview in selection.CellCoords.SelectMany(editorActorLayer.PreviewsAt).Distinct()) previews.TryAdd(preview.ID, preview); }