Transition blits to CellCoordsRegion

This commit is contained in:
Gustas
2025-08-06 17:30:33 +03:00
committed by Paul Chote
parent 032f20b622
commit dcd4c41d81
9 changed files with 58 additions and 65 deletions

View File

@@ -21,7 +21,7 @@ namespace OpenRA.Mods.Common.EditorBrushes
{ {
public readonly record struct BlitTile(TerrainTile TerrainTile, ResourceTile ResourceTile, ResourceLayerContents? ResourceLayerContents, byte Height); public readonly record struct BlitTile(TerrainTile TerrainTile, ResourceTile ResourceTile, ResourceLayerContents? ResourceLayerContents, byte Height);
public readonly record struct EditorBlitSource(CellRegion CellRegion, Dictionary<string, EditorActorPreview> Actors, Dictionary<CPos, BlitTile> Tiles); public readonly record struct EditorBlitSource(CellCoordsRegion CellCoords, Dictionary<string, EditorActorPreview> Actors, Dictionary<CPos, BlitTile> Tiles);
[Flags] [Flags]
public enum MapBlitFilters public enum MapBlitFilters
@@ -64,18 +64,18 @@ namespace OpenRA.Mods.Common.EditorBrushes
this.map = map; this.map = map;
this.respectBounds = respectBounds; this.respectBounds = respectBounds;
var blitSize = blitSource.CellRegion.BottomRight - blitSource.CellRegion.TopLeft; var blitSize = blitSource.CellCoords.BottomRight - blitSource.CellCoords.TopLeft;
// Only include into the revert blit stuff which would be modified by the main blit. // Only include into the revert blit stuff which would be modified by the main blit.
var mask = GetBlitSourceMask( var mask = GetBlitSourceMask(
blitSource, blitPosition - blitSource.CellRegion.TopLeft); blitSource, blitPosition - blitSource.CellCoords.TopLeft);
commitBlitSource = blitSource; commitBlitSource = blitSource;
revertBlitSource = CopyRegionContents( revertBlitSource = CopyRegionContents(
map, map,
editorActorLayer, editorActorLayer,
resourceLayer, resourceLayer,
new CellRegion(map.Grid.Type, blitPosition, blitPosition + blitSize), new CellCoordsRegion(blitPosition, blitPosition + blitSize),
blitFilters, blitFilters,
mask); mask);
} }
@@ -89,7 +89,7 @@ namespace OpenRA.Mods.Common.EditorBrushes
Map map, Map map,
EditorActorLayer editorActorLayer, EditorActorLayer editorActorLayer,
IResourceLayer resourceLayer, IResourceLayer resourceLayer,
CellRegion region, CellCoordsRegion region,
MapBlitFilters blitFilters, MapBlitFilters blitFilters,
IReadOnlySet<CPos> mask = null) IReadOnlySet<CPos> mask = null)
{ {
@@ -102,7 +102,7 @@ namespace OpenRA.Mods.Common.EditorBrushes
if (blitFilters.HasFlag(MapBlitFilters.Terrain) || blitFilters.HasFlag(MapBlitFilters.Resources)) if (blitFilters.HasFlag(MapBlitFilters.Terrain) || blitFilters.HasFlag(MapBlitFilters.Resources))
{ {
foreach (var cell in region.CellCoords) foreach (var cell in region)
{ {
if (!mapTiles.Contains(cell) || (mask != null && !mask.Contains(cell))) if (!mapTiles.Contains(cell) || (mask != null && !mask.Contains(cell)))
continue; continue;
@@ -117,7 +117,7 @@ namespace OpenRA.Mods.Common.EditorBrushes
} }
if (blitFilters.HasFlag(MapBlitFilters.Actors)) if (blitFilters.HasFlag(MapBlitFilters.Actors))
foreach (var preview in editorActorLayer.PreviewsInCellRegion(region.CellCoords)) foreach (var preview in editorActorLayer.PreviewsInCellRegion(region))
if (mask == null || preview.Footprint.Keys.Any(mask.Contains)) if (mask == null || preview.Footprint.Keys.Any(mask.Contains))
previews.TryAdd(preview.ID, preview); previews.TryAdd(preview.ID, preview);
@@ -127,10 +127,10 @@ namespace OpenRA.Mods.Common.EditorBrushes
void Blit(bool isRevert) void Blit(bool isRevert)
{ {
var source = isRevert ? revertBlitSource : commitBlitSource; var source = isRevert ? revertBlitSource : commitBlitSource;
var blitPos = isRevert ? source.CellRegion.TopLeft : blitPosition; var blitPos = isRevert ? source.CellCoords.TopLeft : blitPosition;
var blitVec = blitPos - source.CellRegion.TopLeft; var blitVec = blitPos - source.CellCoords.TopLeft;
var blitSize = source.CellRegion.BottomRight - source.CellRegion.TopLeft; var blitSize = source.CellCoords.BottomRight - source.CellCoords.TopLeft;
var blitRegion = new CellRegion(map.Grid.Type, blitPos, blitPos + blitSize); var blitRegion = new CellCoordsRegion(blitPos, blitPos + blitSize);
if (blitFilters.HasFlag(MapBlitFilters.Actors)) if (blitFilters.HasFlag(MapBlitFilters.Actors))
{ {
@@ -148,10 +148,10 @@ namespace OpenRA.Mods.Common.EditorBrushes
// - revertBlitSource's mask will overlap all revert actors BUT MAY OVERLAP MORE! // - revertBlitSource's mask will overlap all revert actors BUT MAY OVERLAP MORE!
// //
// This means we use the commit mask, not the revert one. // This means we use the commit mask, not the revert one.
var commitBlitVec = blitPosition - commitBlitSource.CellRegion.TopLeft; var commitBlitVec = blitPosition - commitBlitSource.CellCoords.TopLeft;
var mask = GetBlitSourceMask(commitBlitSource, commitBlitVec); var mask = GetBlitSourceMask(commitBlitSource, commitBlitVec);
using (new PerfTimer("RemoveActors", 1)) using (new PerfTimer("RemoveActors", 1))
editorActorLayer.RemoveRegion(blitRegion.CellCoords, mask); editorActorLayer.RemoveRegion(blitRegion, mask);
} }
foreach (var tileKeyValuePair in source.Tiles) foreach (var tileKeyValuePair in source.Tiles)
@@ -290,7 +290,7 @@ namespace OpenRA.Mods.Common.EditorBrushes
{ {
var mask = new HashSet<CPos>(); var mask = new HashSet<CPos>();
var sourceCellCoords = blitSource.CellRegion.CellCoords; var sourceCellCoords = blitSource.CellCoords;
foreach (var (cpos, _) in blitSource.Tiles) foreach (var (cpos, _) in blitSource.Tiles)
{ {

View File

@@ -28,9 +28,9 @@ namespace OpenRA.Mods.Common.Widgets
readonly IResourceLayer resourceLayer; readonly IResourceLayer resourceLayer;
readonly Func<MapBlitFilters> getCopyFilters; readonly Func<MapBlitFilters> getCopyFilters;
public CPos? PastePreviewPosition { get; private set; } public CPos PastePreviewPosition { get; private set; }
public CellRegion Region => clipboard.CellRegion; public CellCoordsRegion Region => clipboard.CellCoords;
public EditorCopyPasteBrush( public EditorCopyPasteBrush(
EditorViewportControllerWidget editorWidget, EditorViewportControllerWidget editorWidget,
@@ -47,6 +47,7 @@ namespace OpenRA.Mods.Common.Widgets
editorActionManager = wr.World.WorldActor.Trait<EditorActionManager>(); editorActionManager = wr.World.WorldActor.Trait<EditorActionManager>();
editorActorLayer = wr.World.WorldActor.Trait<EditorActorLayer>(); editorActorLayer = wr.World.WorldActor.Trait<EditorActorLayer>();
PastePreviewPosition = worldRenderer.Viewport.ViewToWorld(Viewport.LastMousePos);
} }
public bool HandleMouseInput(MouseInput mi) public bool HandleMouseInput(MouseInput mi)
@@ -89,25 +90,19 @@ namespace OpenRA.Mods.Common.Widgets
void IEditorBrush.TickRender(WorldRenderer wr, Actor self) { } void IEditorBrush.TickRender(WorldRenderer wr, Actor self) { }
IEnumerable<IRenderable> IEditorBrush.RenderAboveShroud(Actor self, WorldRenderer wr) IEnumerable<IRenderable> IEditorBrush.RenderAboveShroud(Actor self, WorldRenderer wr)
{ {
if (PastePreviewPosition != null) var preview = EditorBlit.PreviewBlitSource(
{ clipboard,
var preview = EditorBlit.PreviewBlitSource( getCopyFilters(),
clipboard, PastePreviewPosition - Region.TopLeft,
getCopyFilters(), wr);
PastePreviewPosition.Value - Region.TopLeft, foreach (var renderable in preview)
wr); yield return renderable;
foreach (var renderable in preview)
yield return renderable;
}
} }
IEnumerable<IRenderable> IEditorBrush.RenderAnnotations(Actor self, WorldRenderer wr) IEnumerable<IRenderable> IEditorBrush.RenderAnnotations(Actor self, WorldRenderer wr)
{ {
if (PastePreviewPosition != null) yield return new EditorSelectionAnnotationRenderable(Region, editorWidget.SelectionAltColor, editorWidget.SelectionAltOffset, PastePreviewPosition);
{ yield return new EditorSelectionAnnotationRenderable(Region, editorWidget.PasteColor, int2.Zero, PastePreviewPosition);
yield return new EditorSelectionAnnotationRenderable(Region, editorWidget.SelectionAltColor, editorWidget.SelectionAltOffset, PastePreviewPosition);
yield return new EditorSelectionAnnotationRenderable(Region, editorWidget.PasteColor, int2.Zero, PastePreviewPosition);
}
} }
public void Tick() public void Tick()

View File

@@ -33,10 +33,10 @@ namespace OpenRA.Mods.Common.Widgets
public class EditorSelection public class EditorSelection
{ {
public CellRegion Area; public CellCoordsRegion? Area;
public EditorActorPreview Actor; public EditorActorPreview Actor;
public bool HasSelection => Area != null || Actor != null; public bool HasSelection => Area.HasValue || Actor != null;
} }
public sealed class EditorDefaultBrush : IEditorBrush public sealed class EditorDefaultBrush : IEditorBrush
@@ -54,12 +54,12 @@ namespace OpenRA.Mods.Common.Widgets
readonly IResourceLayer resourceLayer; readonly IResourceLayer resourceLayer;
readonly EditorActorLayer actorLayer; readonly EditorActorLayer actorLayer;
public CellRegion CurrentDragBounds => selectionBounds ?? Selection.Area; public CellCoordsRegion? CurrentDragBounds => selectionBounds ?? Selection.Area;
public EditorSelection Selection { get; private set; } = new(); public EditorSelection Selection { get; private set; } = new();
EditorSelection previousSelection; EditorSelection previousSelection;
CellRegion selectionBounds; CellCoordsRegion? selectionBounds;
int2? selectionStartLocation; int2? selectionStartLocation;
CPos? selectionStartCell; CPos? selectionStartCell;
int2 worldPixel; int2 worldPixel;
@@ -95,8 +95,8 @@ namespace OpenRA.Mods.Common.Widgets
public void DeleteSelection(MapBlitFilters filters) public void DeleteSelection(MapBlitFilters filters)
{ {
if (Selection.Area != null) if (Selection.Area.HasValue)
editorActionManager.Add(new DeleteAreaAction(world.Map, filters, Selection.Area, resourceLayer, actorLayer)); editorActionManager.Add(new DeleteAreaAction(world.Map, filters, Selection.Area.Value, resourceLayer, actorLayer));
} }
public void ClearSelection(bool updateSelectedTab = false) public void ClearSelection(bool updateSelectedTab = false)
@@ -193,7 +193,7 @@ namespace OpenRA.Mods.Common.Widgets
// We've dragged enough to capture more than one cell, make a selection box. // We've dragged enough to capture more than one cell, make a selection box.
if (selectionBounds == null) if (selectionBounds == null)
{ {
selectionBounds = new CellRegion(gridType, topLeft, bottomRight); selectionBounds = new CellCoordsRegion(topLeft, bottomRight);
// Lose focus on any search boxes so we can always copy/paste. // Lose focus on any search boxes so we can always copy/paste.
Ui.KeyboardFocusWidget = null; Ui.KeyboardFocusWidget = null;
@@ -201,7 +201,7 @@ namespace OpenRA.Mods.Common.Widgets
else else
{ {
// We already have a drag box; resize it // We already have a drag box; resize it
selectionBounds = new CellRegion(gridType, topLeft, bottomRight); selectionBounds = new CellCoordsRegion(topLeft, bottomRight);
} }
} }
@@ -281,8 +281,8 @@ namespace OpenRA.Mods.Common.Widgets
{ {
if (CurrentDragBounds != null) if (CurrentDragBounds != null)
{ {
yield return new EditorSelectionAnnotationRenderable(CurrentDragBounds, editorWidget.SelectionAltColor, editorWidget.SelectionAltOffset, null); yield return new EditorSelectionAnnotationRenderable(CurrentDragBounds.Value, editorWidget.SelectionAltColor, editorWidget.SelectionAltOffset, null);
yield return new EditorSelectionAnnotationRenderable(CurrentDragBounds, editorWidget.SelectionMainColor, int2.Zero, null); yield return new EditorSelectionAnnotationRenderable(CurrentDragBounds.Value, editorWidget.SelectionMainColor, int2.Zero, null);
} }
} }
@@ -321,12 +321,12 @@ namespace OpenRA.Mods.Common.Widgets
Area = previousSelection.Area Area = previousSelection.Area
}; };
if (selection.Area != null) if (selection.Area.HasValue)
Text = FluentProvider.GetMessage(SelectedArea, Text = FluentProvider.GetMessage(SelectedArea,
"x", selection.Area.TopLeft.X, "x", selection.Area.Value.TopLeft.X,
"y", selection.Area.TopLeft.Y, "y", selection.Area.Value.TopLeft.Y,
"width", selection.Area.BottomRight.X - selection.Area.TopLeft.X, "width", selection.Area.Value.BottomRight.X - selection.Area.Value.TopLeft.X,
"height", selection.Area.BottomRight.Y - selection.Area.TopLeft.Y); "height", selection.Area.Value.BottomRight.Y - selection.Area.Value.TopLeft.Y);
else if (selection.Actor != null) else if (selection.Actor != null)
Text = FluentProvider.GetMessage(SelectedActor, "id", selection.Actor.ID); Text = FluentProvider.GetMessage(SelectedActor, "id", selection.Actor.ID);
else else
@@ -360,10 +360,10 @@ namespace OpenRA.Mods.Common.Widgets
readonly MapBlitFilters blitFilters; readonly MapBlitFilters blitFilters;
readonly IResourceLayer resourceLayer; readonly IResourceLayer resourceLayer;
readonly EditorActorLayer editorActorLayer; readonly EditorActorLayer editorActorLayer;
readonly CellRegion area; readonly CellCoordsRegion area;
readonly Map map; readonly Map map;
public DeleteAreaAction(Map map, MapBlitFilters blitFilters, CellRegion area, IResourceLayer resourceLayer, EditorActorLayer editorActorLayer) public DeleteAreaAction(Map map, MapBlitFilters blitFilters, CellCoordsRegion area, IResourceLayer resourceLayer, EditorActorLayer editorActorLayer)
{ {
this.map = map; this.map = map;
this.blitFilters = blitFilters; this.blitFilters = blitFilters;
@@ -391,7 +391,7 @@ namespace OpenRA.Mods.Common.Widgets
{ {
// Clear any existing actors in the paste cells. // Clear any existing actors in the paste cells.
using (new PerfTimer("RemoveActors", 1)) using (new PerfTimer("RemoveActors", 1))
editorActorLayer.RemoveRegion(area.CellCoords); editorActorLayer.RemoveRegion(area);
} }
foreach (var tileKeyValuePair in editorBlitSource.Tiles) foreach (var tileKeyValuePair in editorBlitSource.Tiles)

View File

@@ -347,7 +347,7 @@ namespace OpenRA.Mods.Common.Widgets
editorBlit = new EditorBlit( editorBlit = new EditorBlit(
MapBlitFilters.Terrain | MapBlitFilters.Actors, MapBlitFilters.Terrain | MapBlitFilters.Actors,
null, null,
blitSource.CellRegion.TopLeft, blitSource.CellCoords.TopLeft,
world.Map, world.Map,
blitSource, blitSource,
editorActorLayer, editorActorLayer,

View File

@@ -20,11 +20,11 @@ namespace OpenRA.Mods.Common.Graphics
public class EditorSelectionAnnotationRenderable : IRenderable, IFinalizedRenderable public class EditorSelectionAnnotationRenderable : IRenderable, IFinalizedRenderable
{ {
readonly Color color; readonly Color color;
readonly CellRegion bounds; readonly CellCoordsRegion bounds;
readonly int2 altPixelOffset; readonly int2 altPixelOffset;
readonly CPos? offset; readonly CPos? offset;
public EditorSelectionAnnotationRenderable(CellRegion bounds, Color color, int2 altPixelOffset, CPos? offset) public EditorSelectionAnnotationRenderable(CellCoordsRegion bounds, Color color, int2 altPixelOffset, CPos? offset)
{ {
this.bounds = bounds; this.bounds = bounds;
this.color = color; this.color = color;
@@ -44,15 +44,12 @@ namespace OpenRA.Mods.Common.Graphics
public IFinalizedRenderable PrepareRender(WorldRenderer wr) { return this; } public IFinalizedRenderable PrepareRender(WorldRenderer wr) { return this; }
public void Render(WorldRenderer wr) public void Render(WorldRenderer wr)
{ {
if (bounds == null)
return;
const int Width = 1; const int Width = 1;
var map = wr.World.Map; var map = wr.World.Map;
var originalWPos = map.CenterOfCell(bounds.TopLeft); var originalWPos = map.CenterOfCell(bounds.TopLeft);
var wposOffset = offset.HasValue ? map.CenterOfCell(offset.Value) - originalWPos : WVec.Zero; var wposOffset = offset.HasValue ? map.CenterOfCell(offset.Value) - originalWPos : WVec.Zero;
foreach (var cellPos in bounds.CellCoords) foreach (var cellPos in bounds)
{ {
var uv = cellPos.ToMPos(map); var uv = cellPos.ToMPos(map);
if (!map.Height.Contains(uv)) if (!map.Height.Contains(uv))

View File

@@ -843,7 +843,7 @@ namespace OpenRA.Mods.Common.MapGenerator
var bottomRight = new CPos( var bottomRight = new CPos(
Shape.Max(cvec => cvec.X), Shape.Max(cvec => cvec.X),
Shape.Max(cvec => cvec.Y)); Shape.Max(cvec => cvec.Y));
var cellRegion = new CellRegion(map.Grid.Type, topLeft, bottomRight); var cellRegion = new CellCoordsRegion(topLeft, bottomRight);
var actorPreviews = new Dictionary<string, EditorActorPreview>(); var actorPreviews = new Dictionary<string, EditorActorPreview>();
for (var i = 0; i < actorPlans.Count; i++) for (var i = 0; i < actorPlans.Count; i++)

View File

@@ -176,10 +176,10 @@ namespace OpenRA.Mods.Common.Traits
NetWorth += newDensity * newResourceValue; NetWorth += newDensity * newResourceValue;
} }
public int CalculateRegionValue(CellRegion sourceRegion) public int CalculateRegionValue(CellCoordsRegion sourceRegion)
{ {
var resourceValueInRegion = 0; var resourceValueInRegion = 0;
foreach (var cell in sourceRegion.CellCoords) foreach (var cell in sourceRegion)
{ {
var mcell = cell.ToMPos(Map); var mcell = cell.ToMPos(Map);
if (!Map.Resources.Contains(mcell)) if (!Map.Resources.Contains(mcell))

View File

@@ -53,7 +53,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var areaEditPanel = selectTabContainer.Get("AREA_EDIT_PANEL"); var areaEditPanel = selectTabContainer.Get("AREA_EDIT_PANEL");
actorEditPanel.IsVisible = () => editor.DefaultBrush.Selection.Actor != null; actorEditPanel.IsVisible = () => editor.DefaultBrush.Selection.Actor != null;
areaEditPanel.IsVisible = () => editor.DefaultBrush.Selection.Area != null; areaEditPanel.IsVisible = () => editor.DefaultBrush.Selection.Area.HasValue;
var copyTerrainCheckbox = areaEditPanel.Get<CheckboxWidget>("COPY_FILTER_TERRAIN_CHECKBOX"); var copyTerrainCheckbox = areaEditPanel.Get<CheckboxWidget>("COPY_FILTER_TERRAIN_CHECKBOX");
var copyResourcesCheckbox = areaEditPanel.Get<CheckboxWidget>("COPY_FILTER_RESOURCES_CHECKBOX"); var copyResourcesCheckbox = areaEditPanel.Get<CheckboxWidget>("COPY_FILTER_RESOURCES_CHECKBOX");
@@ -65,7 +65,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var copyButton = widget.Get<ButtonWidget>("COPY_BUTTON"); var copyButton = widget.Get<ButtonWidget>("COPY_BUTTON");
copyButton.OnClick = () => clipboard = CopySelectionContents(); copyButton.OnClick = () => clipboard = CopySelectionContents();
copyButton.IsDisabled = () => editor.DefaultBrush.Selection.Area == null; copyButton.IsDisabled = () => !editor.DefaultBrush.Selection.Area.HasValue;
AreaEditTitle = areaEditPanel.Get<LabelWidget>("AREA_EDIT_TITLE"); AreaEditTitle = areaEditPanel.Get<LabelWidget>("AREA_EDIT_TITLE");
DiagonalLabel = areaEditPanel.Get<LabelWidget>("DIAGONAL_COUNTER_LABEL"); DiagonalLabel = areaEditPanel.Get<LabelWidget>("DIAGONAL_COUNTER_LABEL");
@@ -105,7 +105,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
map, map,
editorActorLayer, editorActorLayer,
resourceLayer, resourceLayer,
editor.DefaultBrush.Selection.Area, editor.DefaultBrush.Selection.Area.Value,
selectionFilters); selectionFilters);
} }
@@ -125,10 +125,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
void HandleSelectionChanged() void HandleSelectionChanged()
{ {
var selectedRegion = editor.DefaultBrush.Selection.Area; if (!editor.DefaultBrush.Selection.Area.HasValue)
if (selectedRegion == null)
return; return;
var selectedRegion = editor.DefaultBrush.Selection.Area.Value;
if (editorResourceLayer == null) if (editorResourceLayer == null)
return; return;

View File

@@ -307,7 +307,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var cellBounds = CellLayerUtils.CellBounds(map); var cellBounds = CellLayerUtils.CellBounds(map);
var topLeft = new CPos(cellBounds.TopLeft.X, cellBounds.TopLeft.Y); var topLeft = new CPos(cellBounds.TopLeft.X, cellBounds.TopLeft.Y);
var bottomRight = new CPos(cellBounds.BottomRight.X, cellBounds.BottomRight.Y); var bottomRight = new CPos(cellBounds.BottomRight.X, cellBounds.BottomRight.Y);
var cellRegion = new CellRegion(map.Grid.Type, topLeft, bottomRight); var cellRegion = new CellCoordsRegion(topLeft, bottomRight);
var blitSource = new EditorBlitSource(cellRegion, previews, tiles); var blitSource = new EditorBlitSource(cellRegion, previews, tiles);
var editorBlit = new EditorBlit( var editorBlit = new EditorBlit(
MapBlitFilters.All, MapBlitFilters.All,