diff --git a/OpenRA.Game/Map/Map.cs b/OpenRA.Game/Map/Map.cs index 4ebee4554a..114b656702 100644 --- a/OpenRA.Game/Map/Map.cs +++ b/OpenRA.Game/Map/Map.cs @@ -207,6 +207,18 @@ namespace OpenRA public Rectangle Bounds; + /// + /// The top-left of the playable area in projected world coordinates + /// This is a hacky workaround for legacy functionality. Do not use for new code. + /// + public WPos ProjectedTopLeft; + + /// + /// The bottom-right of the playable area in projected world coordinates + /// This is a hacky workaround for legacy functionality. Do not use for new code. + /// + public WPos ProjectedBottomRight; + public Lazy SpawnPoints; // Yaml map data @@ -397,9 +409,9 @@ namespace OpenRA var br = new MPos(MapSize.X - 1, MapSize.Y - 1).ToCPos(this); AllCells = new CellRegion(TileShape, tl, br); - var btl = new MPos(Bounds.Left, Bounds.Top).ToCPos(this); - var bbr = new MPos(Bounds.Right - 1, Bounds.Bottom - 1).ToCPos(this); - CellsInsideBounds = new CellRegion(TileShape, btl, bbr); + var btl = new MPos(Bounds.Left, Bounds.Top); + var bbr = new MPos(Bounds.Right - 1, Bounds.Bottom - 1); + SetBounds(btl, bbr); CustomTerrain = new CellLayer(this); foreach (var uv in AllCells.MapCoords) @@ -706,13 +718,27 @@ namespace OpenRA AllCells = new CellRegion(TileShape, tl, br); } - public void ResizeCordon(int left, int top, int right, int bottom) + public void SetBounds(MPos tl, MPos br) { - Bounds = Rectangle.FromLTRB(left, top, right, bottom); + // The tl and br coordinates are inclusive, but the Rectangle + // is exclusive. Pad the right and bottom edges to match. + Bounds = Rectangle.FromLTRB(tl.U, tl.V, br.U + 1, br.V + 1); + CellsInsideBounds = new CellRegion(TileShape, tl.ToCPos(this), br.ToCPos(this)); - var tl = new MPos(Bounds.Left, Bounds.Top).ToCPos(this); - var br = new MPos(Bounds.Right - 1, Bounds.Bottom - 1).ToCPos(this); - CellsInsideBounds = new CellRegion(TileShape, tl, br); + // Directly calculate the projected map corners in world units avoiding unnecessary + // conversions. This abuses the definition that the width of the cell is always + // 1024 units, and that the height of two rows is 2048 for classic cells and 1024 + // for diamond cells. + var wtop = tl.V * 1024; + var wbottom = (br.V + 1) * 1024; + if (TileShape == TileShape.Diamond) + { + wtop /= 2; + wbottom /= 2; + } + + ProjectedTopLeft = new WPos(tl.U * 1024, wtop, 0); + ProjectedBottomRight = new WPos(br.U * 1024 - 1, wbottom - 1, 0); } string ComputeHash() diff --git a/OpenRA.Mods.Common/Scripting/Global/MapGlobal.cs b/OpenRA.Mods.Common/Scripting/Global/MapGlobal.cs index 8fc7794f37..3fcf1d0336 100644 --- a/OpenRA.Mods.Common/Scripting/Global/MapGlobal.cs +++ b/OpenRA.Mods.Common/Scripting/Global/MapGlobal.cs @@ -64,16 +64,26 @@ namespace OpenRA.Mods.Common.Scripting return actors.ToArray(); } - [Desc("Returns the location of the top-left corner of the map.")] + [Desc("Returns the location of the top-left corner of the map (assuming zero terrain height).")] public WPos TopLeft { - get { return new WPos(Context.World.Map.Bounds.Left * 1024, Context.World.Map.Bounds.Top * 1024, 0); } + get + { + // HACK: This api method abuses the coordinate system, and should be removed + // in favour of proper actor queries. See #8549. + return Context.World.Map.ProjectedTopLeft; + } } - [Desc("Returns the location of the bottom-right corner of the map.")] + [Desc("Returns the location of the bottom-right corner of the map (assuming zero terrain height).")] public WPos BottomRight { - get { return new WPos(Context.World.Map.Bounds.Right * 1024, Context.World.Map.Bounds.Bottom * 1024, 0); } + get + { + // HACK: This api method abuses the coordinate system, and should be removed + // in favour of proper actor queries. See #8549. + return Context.World.Map.ProjectedBottomRight; + } } [Desc("Returns a random cell inside the visible region of the map.")] diff --git a/OpenRA.Mods.Common/Widgets/Logic/Editor/NewMapLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Editor/NewMapLogic.cs index 8448322063..30bebf1718 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Editor/NewMapLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Editor/NewMapLogic.cs @@ -64,7 +64,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic height = Math.Max(2, height); map.Resize(width + 2, height + tileset.MaxGroundHeight + 2); - map.ResizeCordon(1, 1, width + 1, height + tileset.MaxGroundHeight + 1); + + var tl = new MPos(1, 1); + var br = new MPos(width, height + tileset.MaxGroundHeight); + map.SetBounds(tl, br); + map.PlayerDefinitions = new MapPlayers(map.Rules, map.SpawnPoints.Value.Length).ToMiniYaml(); map.FixOpenAreas(modRules);