Fix TS copy paste

This commit is contained in:
Gustas
2025-08-06 19:44:10 +03:00
committed by Paul Chote
parent dcd4c41d81
commit 1300ecc18f
7 changed files with 114 additions and 38 deletions

View File

@@ -14,6 +14,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Mods.Common.MapGenerator;
using OpenRA.Mods.Common.Traits; using OpenRA.Mods.Common.Traits;
using OpenRA.Support; using OpenRA.Support;
@@ -110,9 +111,9 @@ namespace OpenRA.Mods.Common.EditorBrushes
tiles.Add( tiles.Add(
cell, cell,
new BlitTile(mapTiles[cell], new BlitTile(mapTiles[cell],
mapResources[cell], mapResources[cell],
resourceLayer?.GetResource(cell), resourceLayer?.GetResource(cell),
mapHeight[cell])); mapHeight[cell]));
} }
} }
@@ -221,23 +222,24 @@ namespace OpenRA.Mods.Common.EditorBrushes
EditorBlitSource blitSource, EditorBlitSource blitSource,
MapBlitFilters filters, MapBlitFilters filters,
CVec offset, CVec offset,
WorldRenderer wr) WorldRenderer wr,
bool stickToGround)
{ {
var world = wr.World; var world = wr.World;
var map = world.Map; var map = world.Map;
var mapHeight = map.Height;
var wOffset = map.CenterOfCell(CPos.Zero + offset) - map.CenterOfCell(CPos.Zero); var mapGrid = map.Grid;
if (filters.HasFlag(MapBlitFilters.Terrain)) if (filters.HasFlag(MapBlitFilters.Terrain))
{ {
var terrainRenderer = world.WorldActor.Trait<ITiledTerrainRenderer>(); var terrainRenderer = world.WorldActor.Trait<ITiledTerrainRenderer>();
foreach (var (cpos, tile) in blitSource.Tiles) foreach (var (pos, tile) in blitSource.Tiles)
{ {
var preview = var cPos = pos + offset;
terrainRenderer.RenderPreview( var height = stickToGround ? (mapHeight.TryGetValue(cPos, out var isoHeight) ? isoHeight : byte.MinValue) : tile.Height;
wr, var wPos = CellLayerUtils.CPosToWPos(cPos, height, mapGrid.Type);
tile.TerrainTile, var preview = terrainRenderer.RenderPreview(wr, tile.TerrainTile, wPos);
map.CenterOfCell(cpos + offset));
foreach (var renderable in preview) foreach (var renderable in preview)
yield return renderable; yield return renderable;
} }
@@ -256,11 +258,26 @@ namespace OpenRA.Mods.Common.EditorBrushes
if (!filters.HasFlag(MapBlitFilters.Terrain) && !resourceLayer.CanAddResource(tile.ResourceLayerContents.Value.Type, cPos)) if (!filters.HasFlag(MapBlitFilters.Terrain) && !resourceLayer.CanAddResource(tile.ResourceLayerContents.Value.Type, cPos))
continue; continue;
byte height;
if (filters.HasFlag(MapBlitFilters.Terrain) && !stickToGround)
{
// We won't change relative tile height, use the saved value.
height = tile.Height;
}
else
{
if (!mapHeight.TryGetValue(cPos, out height))
height = byte.MinValue;
// If a tile has inherent height, we know it will raise terrain.
if (filters.HasFlag(MapBlitFilters.Terrain) && stickToGround)
height += map.Rules.TerrainInfo.GetTerrainInfo(tile.TerrainTile).Height;
}
var wPos = CellLayerUtils.CPosToWPos(cPos, height, mapGrid.Type);
var preview = resourceRenderers var preview = resourceRenderers
.SelectMany(r => r.RenderPreview( .SelectMany(r => r.RenderPreview(wr, tile.ResourceLayerContents.Value.Type, wPos));
wr,
tile.ResourceLayerContents.Value.Type,
map.CenterOfCell(cPos)));
foreach (var renderable in preview) foreach (var renderable in preview)
yield return renderable; yield return renderable;
} }
@@ -270,8 +287,20 @@ namespace OpenRA.Mods.Common.EditorBrushes
{ {
foreach (var (_, editorActorPreview) in blitSource.Actors) foreach (var (_, editorActorPreview) in blitSource.Actors)
{ {
var useGround = stickToGround;
if (!filters.HasFlag(MapBlitFilters.Terrain) || !blitSource.Tiles.ContainsKey(editorActorPreview.Location))
useGround = true;
var wOffset = CellLayerUtils.CVecToWVec(offset, 0, mapGrid.Type);
if (useGround)
{
var actorPos = editorActorPreview.CenterPosition + wOffset;
wOffset -= new WVec(0, 0, map.DistanceAboveTerrain(actorPos).Length);
}
var preview = editorActorPreview.RenderWithOffset(wOffset) var preview = editorActorPreview.RenderWithOffset(wOffset)
.OrderBy(WorldRenderer.RenderableZPositionComparisonKey); .OrderBy(WorldRenderer.RenderableZPositionComparisonKey);
foreach (var renderable in preview) foreach (var renderable in preview)
yield return renderable; yield return renderable;
} }

View File

@@ -90,19 +90,32 @@ 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)
{ {
var filters = getCopyFilters();
var stickToGround = !filters.HasFlag(MapBlitFilters.Terrain)
;
var preview = EditorBlit.PreviewBlitSource( var preview = EditorBlit.PreviewBlitSource(
clipboard, clipboard,
getCopyFilters(), filters,
PastePreviewPosition - Region.TopLeft, PastePreviewPosition - Region.TopLeft,
wr); wr,
stickToGround);
foreach (var renderable in preview) foreach (var renderable in preview)
yield return renderable; yield return renderable;
} }
IEnumerable<IRenderable> IEditorBrush.RenderAnnotations(Actor self, WorldRenderer wr) IEnumerable<IRenderable> IEditorBrush.RenderAnnotations(Actor self, WorldRenderer wr)
{ {
yield return new EditorSelectionAnnotationRenderable(Region, editorWidget.SelectionAltColor, editorWidget.SelectionAltOffset, PastePreviewPosition); yield return new EditorSelectionAnnotationRenderable(
yield return new EditorSelectionAnnotationRenderable(Region, editorWidget.PasteColor, int2.Zero, PastePreviewPosition); Region,
editorWidget.SelectionAltColor,
editorWidget.SelectionAltOffset,
PastePreviewPosition - Region.TopLeft);
yield return new EditorSelectionAnnotationRenderable(
Region,
editorWidget.PasteColor,
int2.Zero,
PastePreviewPosition - Region.TopLeft);
} }
public void Tick() public void Tick()

View File

@@ -279,10 +279,10 @@ namespace OpenRA.Mods.Common.Widgets
IEnumerable<IRenderable> IEditorBrush.RenderAboveShroud(Actor self, WorldRenderer wr) { yield break; } IEnumerable<IRenderable> IEditorBrush.RenderAboveShroud(Actor self, WorldRenderer wr) { yield break; }
IEnumerable<IRenderable> IEditorBrush.RenderAnnotations(Actor self, WorldRenderer wr) IEnumerable<IRenderable> IEditorBrush.RenderAnnotations(Actor self, WorldRenderer wr)
{ {
if (CurrentDragBounds != null) if (CurrentDragBounds.HasValue)
{ {
yield return new EditorSelectionAnnotationRenderable(CurrentDragBounds.Value, editorWidget.SelectionAltColor, editorWidget.SelectionAltOffset, null); yield return new EditorSelectionAnnotationRenderable(CurrentDragBounds.Value, editorWidget.SelectionAltColor, editorWidget.SelectionAltOffset, CVec.Zero);
yield return new EditorSelectionAnnotationRenderable(CurrentDragBounds.Value, editorWidget.SelectionMainColor, int2.Zero, null); yield return new EditorSelectionAnnotationRenderable(CurrentDragBounds.Value, editorWidget.SelectionMainColor, int2.Zero, CVec.Zero);
} }
} }

View File

@@ -203,11 +203,13 @@ namespace OpenRA.Mods.Common.Widgets
if (tool.EditorBlitSource == null) if (tool.EditorBlitSource == null)
yield break; yield break;
var stickToGround = tool.EditorBlitSource.Value.Tiles.Count == 0;
var preview = EditorBlit.PreviewBlitSource( var preview = EditorBlit.PreviewBlitSource(
tool.EditorBlitSource.Value, tool.EditorBlitSource.Value,
MapBlitFilters.Terrain | MapBlitFilters.Actors, MapBlitFilters.Terrain | MapBlitFilters.Actors,
CVec.Zero, CVec.Zero,
wr); wr,
stickToGround);
foreach (var renderable in preview) foreach (var renderable in preview)
yield return renderable; yield return renderable;
} }

View File

@@ -22,9 +22,9 @@ namespace OpenRA.Mods.Common.Graphics
readonly Color color; readonly Color color;
readonly CellCoordsRegion bounds; readonly CellCoordsRegion bounds;
readonly int2 altPixelOffset; readonly int2 altPixelOffset;
readonly CPos? offset; readonly CVec offset;
public EditorSelectionAnnotationRenderable(CellCoordsRegion bounds, Color color, int2 altPixelOffset, CPos? offset) public EditorSelectionAnnotationRenderable(CellCoordsRegion bounds, Color color, int2 altPixelOffset, CVec offset)
{ {
this.bounds = bounds; this.bounds = bounds;
this.color = color; this.color = color;
@@ -38,7 +38,7 @@ namespace OpenRA.Mods.Common.Graphics
public bool IsDecoration => true; public bool IsDecoration => true;
public IRenderable WithZOffset(int newOffset) { return this; } public IRenderable WithZOffset(int newOffset) { return this; }
public IRenderable OffsetBy(in WVec vec) { return new EditorSelectionAnnotationRenderable(bounds, color, new int2(vec.X, vec.Y), offset); } public IRenderable OffsetBy(in WVec vec) { return this; }
public IRenderable AsDecoration() { return this; } public IRenderable AsDecoration() { return this; }
public IFinalizedRenderable PrepareRender(WorldRenderer wr) { return this; } public IFinalizedRenderable PrepareRender(WorldRenderer wr) { return this; }
@@ -46,29 +46,27 @@ namespace OpenRA.Mods.Common.Graphics
{ {
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 wposOffset = offset.HasValue ? map.CenterOfCell(offset.Value) - originalWPos : WVec.Zero;
foreach (var cellPos in bounds) foreach (var cellPos in bounds)
{ {
var uv = cellPos.ToMPos(map); var pos = cellPos + offset;
var uv = pos.ToMPos(map);
if (!map.Height.Contains(uv)) if (!map.Height.Contains(uv))
continue; continue;
var ramp = map.Grid.Ramps[map.Ramp[uv]]; var ramp = map.Grid.Ramps[map.Ramp[uv]];
var pos = map.CenterOfCell(cellPos) - new WVec(0, 0, ramp.CenterHeightOffset); var wPos = map.CenterOfCell(pos) - new WVec(0, 0, ramp.CenterHeightOffset);
foreach (var p in ramp.Polygons) foreach (var p in ramp.Polygons)
{ {
for (var i = 0; i < p.Length; i++) for (var i = 0; i < p.Length; i++)
{ {
var j = (i + 1) % p.Length; var j = (i + 1) % p.Length;
var start = pos + p[i]; var start = wPos + p[i];
var end = pos + p[j]; var end = wPos + p[j];
Game.Renderer.RgbaColorRenderer.DrawLine( Game.Renderer.RgbaColorRenderer.DrawLine(
wr.Viewport.WorldToViewPx(wr.ScreenPosition(start + wposOffset)) + altPixelOffset, wr.Viewport.WorldToViewPx(wr.ScreenPosition(start)) + altPixelOffset,
wr.Viewport.WorldToViewPx(wr.Screen3DPosition(end + wposOffset)) + altPixelOffset, wr.Viewport.WorldToViewPx(wr.Screen3DPosition(end)) + altPixelOffset,
Width, color, color); Width, color, color);
} }
} }

View File

@@ -139,6 +139,26 @@ namespace OpenRA.Mods.Common.MapGenerator
} }
} }
/// <summary>Get the WVec representing the same translation as the given CVec, with a height offset.</summary>
public static WVec CVecToWVec(CVec cvec, int dz, MapGridType gridType)
{
switch (gridType)
{
case MapGridType.Rectangular:
return new WVec(
cvec.X * 1024,
cvec.Y * 1024,
0);
case MapGridType.RectangularIsometric:
return new WVec(
(cvec.X - cvec.Y) * 724,
(cvec.X + cvec.Y) * 724,
724 * dz);
default:
throw new NotImplementedException();
}
}
/// <summary>Get the WPos center of a CPos cell.</summary> /// <summary>Get the WPos center of a CPos cell.</summary>
public static WPos CPosToWPos(CPos cpos, MapGridType gridType) public static WPos CPosToWPos(CPos cpos, MapGridType gridType)
{ {
@@ -154,6 +174,21 @@ namespace OpenRA.Mods.Common.MapGenerator
} }
} }
/// <summary>Get the WPos center of a CPos cell with a height offset.</summary>
public static WPos CPosToWPos(CPos cpos, int dz, MapGridType gridType)
{
var wvec = CVecToWVec(new CVec(cpos.X, cpos.Y), dz, gridType);
switch (gridType)
{
case MapGridType.Rectangular:
return new WPos(512, 512, 0) + wvec;
case MapGridType.RectangularIsometric:
return new WPos(724, 724, 0) + wvec;
default:
throw new NotImplementedException();
}
}
/// <summary> /// <summary>
/// Find the CPos cell in which a WPos position lies. WPos positions on /// Find the CPos cell in which a WPos position lies. WPos positions on
/// an edge or corner match the CPos with higher X and/or Y positions. /// an edge or corner match the CPos with higher X and/or Y positions.

View File

@@ -214,10 +214,9 @@ namespace OpenRA.Mods.Common.Traits
yield break; yield break;
var sprite = tileCache.TileSprite(tile, 0); var sprite = tileCache.TileSprite(tile, 0);
var offset = map.Offset(new CVec(0, 0), template[tile.Index].Height);
var palette = wr.Palette(((DefaultTerrainTemplateInfo)template)?.Palette ?? terrainInfo.Palette); var palette = wr.Palette(((DefaultTerrainTemplateInfo)template)?.Palette ?? terrainInfo.Palette);
yield return new SpriteRenderable(sprite, origin, offset, 0, palette, 1f, 1f, float3.Ones, TintModifiers.None, false); yield return new SpriteRenderable(sprite, origin, WVec.Zero, 0, palette, 1f, 1f, float3.Ones, TintModifiers.None, false);
} }
} }
} }