diff --git a/OpenRA.Game/GameRules/RulesetCache.cs b/OpenRA.Game/GameRules/RulesetCache.cs index fe3c3ec673..b7cc7bd044 100755 --- a/OpenRA.Game/GameRules/RulesetCache.cs +++ b/OpenRA.Game/GameRules/RulesetCache.cs @@ -19,6 +19,8 @@ namespace OpenRA { public sealed class RulesetCache : IDisposable { + static readonly List NoMapRules = new List(); + readonly ModData modData; readonly Dictionary actorCache = new Dictionary(); @@ -41,12 +43,11 @@ namespace OpenRA this.modData = modData; } - public Ruleset LoadDefaultRules() - { - return LoadMapRules(new Map()); - } - - public Ruleset LoadMapRules(Map map) + /// + /// Cache and return the Ruleset for a given map. + /// If a map isn't specified then return the default mod Ruleset. + /// + public Ruleset Load(Map map = null) { var m = modData.Manifest; @@ -58,20 +59,34 @@ namespace OpenRA Dictionary tileSets; using (new PerfTimer("Actors")) - actors = LoadYamlRules(actorCache, m.Rules, map.RuleDefinitions, (k, y) => new ActorInfo(k.Key.ToLowerInvariant(), k.Value, y)); + actors = LoadYamlRules(actorCache, m.Rules, + map != null ? map.RuleDefinitions : NoMapRules, + (k, y) => new ActorInfo(k.Key.ToLowerInvariant(), k.Value, y)); + using (new PerfTimer("Weapons")) - weapons = LoadYamlRules(weaponCache, m.Weapons, map.WeaponDefinitions, (k, _) => new WeaponInfo(k.Key.ToLowerInvariant(), k.Value)); + weapons = LoadYamlRules(weaponCache, m.Weapons, + map != null ? map.WeaponDefinitions : NoMapRules, + (k, _) => new WeaponInfo(k.Key.ToLowerInvariant(), k.Value)); + using (new PerfTimer("Voices")) - voices = LoadYamlRules(voiceCache, m.Voices, map.VoiceDefinitions, (k, _) => new SoundInfo(k.Value)); + voices = LoadYamlRules(voiceCache, m.Voices, + map != null ? map.VoiceDefinitions : NoMapRules, + (k, _) => new SoundInfo(k.Value)); + using (new PerfTimer("Notifications")) - notifications = LoadYamlRules(notificationCache, m.Notifications, map.NotificationDefinitions, (k, _) => new SoundInfo(k.Value)); + notifications = LoadYamlRules(notificationCache, m.Notifications, + map != null ? map.NotificationDefinitions : NoMapRules, + (k, _) => new SoundInfo(k.Value)); + using (new PerfTimer("Music")) - music = LoadYamlRules(musicCache, m.Music, new List(), (k, _) => new MusicInfo(k.Key, k.Value)); + music = LoadYamlRules(musicCache, m.Music, + NoMapRules, + (k, _) => new MusicInfo(k.Key, k.Value)); + using (new PerfTimer("TileSets")) tileSets = LoadTileSets(tileSetCache, sequenceCaches, m.TileSets); var sequences = sequenceCaches.ToDictionary(kvp => kvp.Key, kvp => new SequenceProvider(kvp.Value, map)); - return new Ruleset(actors, weapons, voices, notifications, music, tileSets, sequences); } diff --git a/OpenRA.Game/Graphics/SequenceProvider.cs b/OpenRA.Game/Graphics/SequenceProvider.cs index 1c021c7447..198f9ffbc5 100644 --- a/OpenRA.Game/Graphics/SequenceProvider.cs +++ b/OpenRA.Game/Graphics/SequenceProvider.cs @@ -120,7 +120,7 @@ namespace OpenRA.Graphics public Sequences LoadSequences(Map map) { using (new Support.PerfTimer("LoadSequences")) - return Load(map.SequenceDefinitions); + return Load(map != null ? map.SequenceDefinitions : new List()); } Sequences Load(List sequenceNodes) diff --git a/OpenRA.Game/Graphics/Viewport.cs b/OpenRA.Game/Graphics/Viewport.cs index 911ea6ede4..130edcf178 100644 --- a/OpenRA.Game/Graphics/Viewport.cs +++ b/OpenRA.Game/Graphics/Viewport.cs @@ -45,7 +45,7 @@ namespace OpenRA.Graphics // Viewport geometry (world-px) public int2 CenterLocation { get; private set; } - public WPos CenterPosition { get { return worldRenderer.Position(CenterLocation); } } + public WPos CenterPosition { get { return worldRenderer.ProjectedPosition(CenterLocation); } } public int2 TopLeft { get { return CenterLocation - viewportSize / 2; } } public int2 BottomRight { get { return CenterLocation + viewportSize / 2; } } @@ -158,14 +158,14 @@ namespace OpenRA.Graphics } // Something is very wrong, but lets return something that isn't completely bogus and hope the caller can recover - return worldRenderer.World.Map.CellContaining(worldRenderer.Position(ViewToWorldPx(view))); + return worldRenderer.World.Map.CellContaining(worldRenderer.ProjectedPosition(ViewToWorldPx(view))); } /// Returns an unfiltered list of all cells that could potentially contain the mouse cursor IEnumerable CandidateMouseoverCells(int2 world) { var map = worldRenderer.World.Map; - var minPos = worldRenderer.Position(world); + var minPos = worldRenderer.ProjectedPosition(world); // Find all the cells that could potentially have been clicked var a = map.CellContaining(minPos - new WVec(1024, 0, 0)).ToMPos(map.TileShape); @@ -230,8 +230,8 @@ namespace OpenRA.Graphics // Calculate the viewport corners in "projected wpos" (at ground level), and // this to an equivalent projected cell for the two corners - var tl = map.CellContaining(worldRenderer.Position(TopLeft)).ToMPos(map); - var br = map.CellContaining(worldRenderer.Position(BottomRight)).ToMPos(map); + var tl = map.CellContaining(worldRenderer.ProjectedPosition(TopLeft)).ToMPos(map); + var br = map.CellContaining(worldRenderer.ProjectedPosition(BottomRight)).ToMPos(map); // Diamond tile shapes don't have straight edges, and so we need // an additional cell margin to include the cells that are half diff --git a/OpenRA.Game/Graphics/WorldRenderer.cs b/OpenRA.Game/Graphics/WorldRenderer.cs index 3a3668f918..4b256be4da 100644 --- a/OpenRA.Game/Graphics/WorldRenderer.cs +++ b/OpenRA.Game/Graphics/WorldRenderer.cs @@ -264,7 +264,11 @@ namespace OpenRA.Graphics return pos.Y + pos.Z + offset; } - public WPos Position(int2 screenPx) + /// + /// Returns a position in the world that is projected to the given screen position. + /// There are many possible world positions, and the returned value chooses the value with no elevation. + /// + public WPos ProjectedPosition(int2 screenPx) { var ts = Game.ModData.Manifest.TileSize; return new WPos(1024 * screenPx.X / ts.Width, 1024 * screenPx.Y / ts.Height, 0); diff --git a/OpenRA.Game/Map/Map.cs b/OpenRA.Game/Map/Map.cs index 4ebee4554a..499cc3c85e 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 @@ -242,47 +254,6 @@ namespace OpenRA [FieldLoader.Ignore] public CellRegion CellsInsideBounds; [FieldLoader.Ignore] public CellRegion AllCells; - public static Map FromTileset(TileSet tileset) - { - var size = new Size(1, 1); - var tileShape = Game.ModData.Manifest.TileShape; - var tileRef = new TerrainTile(tileset.Templates.First().Key, (byte)0); - - var makeMapTiles = Exts.Lazy(() => - { - var ret = new CellLayer(tileShape, size); - ret.Clear(tileRef); - return ret; - }); - - var makeMapHeight = Exts.Lazy(() => - { - var ret = new CellLayer(tileShape, size); - ret.Clear(0); - return ret; - }); - - var map = new Map() - { - Title = "Name your map here", - Description = "Describe your map here", - Author = "Your name here", - MapSize = new int2(size), - Tileset = tileset.Id, - Videos = new MapVideos(), - Options = new MapOptions(), - MapResources = Exts.Lazy(() => new CellLayer(tileShape, size)), - MapTiles = makeMapTiles, - MapHeight = makeMapHeight, - - SpawnPoints = Exts.Lazy(() => new CPos[0]) - }; - - map.PostInit(); - - return map; - } - void AssertExists(string filename) { using (var s = Container.GetContent(filename)) @@ -290,11 +261,47 @@ namespace OpenRA throw new InvalidOperationException("Required file {0} not present in this map".F(filename)); } - // Stub constructor that doesn't produce a valid map, but is - // sufficient for loading a mod to the content-install panel - public Map() { } + /// + /// Initializes a new map created by the editor or importer. + /// The map will not recieve a valid UID until after it has been saved and reloaded. + /// + public Map(TileSet tileset, int width, int height) + { + var size = new Size(width, height); + var tileShape = Game.ModData.Manifest.TileShape; + var tileRef = new TerrainTile(tileset.Templates.First().Key, (byte)0); - // The standard constructor for most purposes + Title = "Name your map here"; + Description = "Describe your map here"; + Author = "Your name here"; + + MapSize = new int2(size); + Tileset = tileset.Id; + Videos = new MapVideos(); + Options = new MapOptions(); + + MapResources = Exts.Lazy(() => new CellLayer(tileShape, size)); + + MapTiles = Exts.Lazy(() => + { + var ret = new CellLayer(tileShape, size); + ret.Clear(tileRef); + return ret; + }); + + MapHeight = Exts.Lazy(() => + { + var ret = new CellLayer(tileShape, size); + ret.Clear(0); + return ret; + }); + + SpawnPoints = Exts.Lazy(() => new CPos[0]); + + PostInit(); + } + + /// Initializes a map loaded from disk. public Map(string path) { Path = path; @@ -380,7 +387,7 @@ namespace OpenRA { try { - return Game.ModData.RulesetCache.LoadMapRules(this); + return Game.ModData.RulesetCache.Load(this); } catch (Exception e) { @@ -397,9 +404,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) @@ -657,7 +664,7 @@ namespace OpenRA // (b) Therefore: // - ax + by adds (a - b) * 512 + 512 to u // - ax + by adds (a + b) * 512 + 512 to v - var z = Contains(cell) ? 512 * MapHeight.Value[cell] : 0; + var z = MapHeight.Value.Contains(cell) ? 512 * MapHeight.Value[cell] : 0; return new WPos(512 * (cell.X - cell.Y), 512 * (cell.X + cell.Y + 1), z); } @@ -706,13 +713,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.Game/ModData.cs b/OpenRA.Game/ModData.cs index d0a2b037d6..4042318503 100644 --- a/OpenRA.Game/ModData.cs +++ b/OpenRA.Game/ModData.cs @@ -79,7 +79,7 @@ namespace OpenRA foreach (var dir in Manifest.Folders) GlobalFileSystem.Mount(dir); - defaultRules = Exts.Lazy(() => RulesetCache.LoadDefaultRules()); + defaultRules = Exts.Lazy(() => RulesetCache.Load()); initialThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId; } diff --git a/OpenRA.Mods.Common/Lint/CheckMapRules.cs b/OpenRA.Mods.Common/Lint/CheckMapRules.cs index b75e37ae03..563992dddf 100644 --- a/OpenRA.Mods.Common/Lint/CheckMapRules.cs +++ b/OpenRA.Mods.Common/Lint/CheckMapRules.cs @@ -19,7 +19,7 @@ namespace OpenRA.Mods.Common.Lint { try { - Game.ModData.RulesetCache.LoadMapRules(map); + Game.ModData.RulesetCache.Load(map); } catch (Exception e) { 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/Traits/Render/RenderNameTag.cs b/OpenRA.Mods.Common/Traits/Render/RenderNameTag.cs index 6c87e936f7..2683c5744c 100644 --- a/OpenRA.Mods.Common/Traits/Render/RenderNameTag.cs +++ b/OpenRA.Mods.Common/Traits/Render/RenderNameTag.cs @@ -49,7 +49,7 @@ namespace OpenRA.Mods.Common.Traits var bounds = self.Bounds; bounds.Offset(pos.X, pos.Y); var spaceBuffer = (int)(10 / wr.Viewport.Zoom); - var effectPos = wr.Position(new int2(pos.X, bounds.Y - spaceBuffer)); + var effectPos = wr.ProjectedPosition(new int2(pos.X, bounds.Y - spaceBuffer)); yield return new TextRenderable(font, effectPos, 0, color, name); } diff --git a/OpenRA.Mods.Common/Traits/Render/WithDecoration.cs b/OpenRA.Mods.Common/Traits/Render/WithDecoration.cs index e6531c008f..850ac087c1 100644 --- a/OpenRA.Mods.Common/Traits/Render/WithDecoration.cs +++ b/OpenRA.Mods.Common/Traits/Render/WithDecoration.cs @@ -145,7 +145,7 @@ namespace OpenRA.Mods.Common.Traits pxPos += info.Offset; // HACK: Because WorldRenderer.Position() does not care about terrain height at the location - var renderPos = wr.Position(pxPos); + var renderPos = wr.ProjectedPosition(pxPos); renderPos = new WPos(renderPos.X, renderPos.Y + self.CenterPosition.Z, self.CenterPosition.Z); anim.Tick(); diff --git a/OpenRA.Mods.Common/Traits/World/BridgeLayer.cs b/OpenRA.Mods.Common/Traits/World/BridgeLayer.cs index 6f5fc6d4d2..85579f6c36 100644 --- a/OpenRA.Mods.Common/Traits/World/BridgeLayer.cs +++ b/OpenRA.Mods.Common/Traits/World/BridgeLayer.cs @@ -50,15 +50,9 @@ namespace OpenRA.Mods.Common.Traits } // Loop through the map looking for templates to overlay - for (var i = w.Map.Bounds.Left; i < w.Map.Bounds.Right; i++) - { - for (var j = w.Map.Bounds.Top; j < w.Map.Bounds.Bottom; j++) - { - var cell = new CPos(i, j); - if (bridgeTypes.ContainsKey(w.Map.MapTiles.Value[cell].Type)) - ConvertBridgeToActor(w, cell); - } - } + foreach (var cell in w.Map.AllCells) + if (bridgeTypes.ContainsKey(w.Map.MapTiles.Value[cell].Type)) + ConvertBridgeToActor(w, cell); // Link adjacent (long)-bridges so that artwork is updated correctly foreach (var b in w.Actors.SelectMany(a => a.TraitsImplementing())) diff --git a/OpenRA.Mods.Common/Traits/World/DomainIndex.cs b/OpenRA.Mods.Common/Traits/World/DomainIndex.cs index b2db3f00ec..d716461489 100644 --- a/OpenRA.Mods.Common/Traits/World/DomainIndex.cs +++ b/OpenRA.Mods.Common/Traits/World/DomainIndex.cs @@ -159,6 +159,9 @@ namespace OpenRA.Mods.Common.Traits bool CanTraverseTile(World world, CPos p) { + if (!map.Contains(p)) + return false; + var terrainOffset = world.Map.GetTerrainIndex(p); return (movementClass & (1 << terrainOffset)) > 0; } @@ -172,7 +175,7 @@ namespace OpenRA.Mods.Common.Traits var visited = new CellLayer(map); var toProcess = new Queue(); - toProcess.Enqueue(new CPos(map.Bounds.Left, map.Bounds.Top)); + toProcess.Enqueue(MPos.Zero.ToCPos(map)); // Flood-fill over each domain while (toProcess.Count != 0) @@ -209,7 +212,7 @@ namespace OpenRA.Mods.Common.Traits // Don't crawl off the map, or add already-visited cells var neighbors = CVec.Directions.Select(d => n + d) - .Where(p => map.Contains(p) && !visited[p]); + .Where(p => visited.Contains(p) && !visited[p]); foreach (var neighbor in neighbors) domainQueue.Enqueue(neighbor); diff --git a/OpenRA.Mods.Common/UtilityCommands/ActorStatsExport.cs b/OpenRA.Mods.Common/UtilityCommands/ActorStatsExport.cs index 883d103ed3..9ae4a9510d 100644 --- a/OpenRA.Mods.Common/UtilityCommands/ActorStatsExport.cs +++ b/OpenRA.Mods.Common/UtilityCommands/ActorStatsExport.cs @@ -22,7 +22,7 @@ namespace OpenRA.Mods.Common.UtilityCommands { public static DataTable GenerateTable() { - var rules = Game.ModData.RulesetCache.LoadDefaultRules(); + var rules = Game.ModData.RulesetCache.Load(); var table = new DataTable(); table.Columns.Add("Name", typeof(string)); diff --git a/OpenRA.Mods.Common/UtilityCommands/ExtractLanguageStringsCommand.cs b/OpenRA.Mods.Common/UtilityCommands/ExtractLanguageStringsCommand.cs index 2f24eafd47..551bc0a0c8 100644 --- a/OpenRA.Mods.Common/UtilityCommands/ExtractLanguageStringsCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/ExtractLanguageStringsCommand.cs @@ -25,7 +25,7 @@ namespace OpenRA.Mods.Common.UtilityCommands { // HACK: The engine code assumes that Game.modData is set. Game.ModData = modData; - Game.ModData.RulesetCache.LoadDefaultRules(); + Game.ModData.RulesetCache.Load(); var types = Game.ModData.ObjectCreator.GetTypes(); var translatableFields = types.SelectMany(t => t.GetFields()) diff --git a/OpenRA.Mods.Common/UtilityCommands/ImportLegacyMapCommand.cs b/OpenRA.Mods.Common/UtilityCommands/ImportLegacyMapCommand.cs index 10b33452cf..31529006c5 100644 --- a/OpenRA.Mods.Common/UtilityCommands/ImportLegacyMapCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/ImportLegacyMapCommand.cs @@ -23,7 +23,7 @@ namespace OpenRA.Mods.Common.UtilityCommands // HACK: The engine code assumes that Game.modData is set. Game.ModData = modData; - var rules = Game.ModData.RulesetCache.LoadDefaultRules(); + var rules = Game.ModData.RulesetCache.Load(); var map = LegacyMapImporter.Import(args[1], modData.Manifest.Mod.Id, rules, Console.WriteLine); var fileName = Path.GetFileNameWithoutExtension(args[1]); diff --git a/OpenRA.Mods.Common/UtilityCommands/LegacyMapImporter.cs b/OpenRA.Mods.Common/UtilityCommands/LegacyMapImporter.cs index 06fd2f583d..e7d1f24007 100644 --- a/OpenRA.Mods.Common/UtilityCommands/LegacyMapImporter.cs +++ b/OpenRA.Mods.Common/UtilityCommands/LegacyMapImporter.cs @@ -143,21 +143,17 @@ namespace OpenRA.Mods.Common.UtilityCommands var width = Exts.ParseIntegerInvariant(mapSection.GetValue("Width", "0")); var height = Exts.ParseIntegerInvariant(mapSection.GetValue("Height", "0")); mapSize = (legacyMapFormat == IniMapFormat.RedAlert) ? 128 : 64; - var size = new Size(mapSize, mapSize); var tileset = Truncate(mapSection.GetValue("Theater", "TEMPERAT"), 8); - map = Map.FromTileset(rules.TileSets[tileset]); - map.Title = basic.GetValue("Name", Path.GetFileNameWithoutExtension(iniFile)); - map.Author = "Westwood Studios"; - map.MapSize = new int2(mapSize, mapSize); - map.Bounds = Rectangle.FromLTRB(offsetX, offsetY, offsetX + width, offsetY + height); + map = new Map(rules.TileSets[tileset], mapSize, mapSize) + { + Title = basic.GetValue("Name", Path.GetFileNameWithoutExtension(iniFile)), + Author = "Westwood Studios" + }; - map.MapResources = Exts.Lazy(() => new CellLayer(TileShape.Rectangle, size)); - map.MapTiles = Exts.Lazy(() => new CellLayer(TileShape.Rectangle, size)); - - map.Videos = new MapVideos(); - - map.Options = new MapOptions(); + var tl = new MPos(offsetX, offsetY); + var br = new MPos(offsetX + width - 1, offsetY + height - 1); + map.SetBounds(tl, br); if (legacyMapFormat == IniMapFormat.RedAlert) { diff --git a/OpenRA.Mods.Common/UtilityCommands/RemapShpCommand.cs b/OpenRA.Mods.Common/UtilityCommands/RemapShpCommand.cs index 2f44c4db18..ebde509782 100644 --- a/OpenRA.Mods.Common/UtilityCommands/RemapShpCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/RemapShpCommand.cs @@ -39,14 +39,14 @@ namespace OpenRA.Mods.Common.UtilityCommands Game.ModData = new ModData(srcMod); GlobalFileSystem.LoadFromManifest(Game.ModData.Manifest); - var srcRules = Game.ModData.RulesetCache.LoadDefaultRules(); + var srcRules = Game.ModData.RulesetCache.Load(); var srcPaletteInfo = srcRules.Actors["player"].Traits.Get(); var srcRemapIndex = srcPaletteInfo.RemapIndex; var destMod = args[2].Split(':')[0]; Game.ModData = new ModData(destMod); GlobalFileSystem.LoadFromManifest(Game.ModData.Manifest); - var destRules = Game.ModData.RulesetCache.LoadDefaultRules(); + var destRules = Game.ModData.RulesetCache.Load(); var destPaletteInfo = destRules.Actors["player"].Traits.Get(); var destRemapIndex = destPaletteInfo.RemapIndex; var shadowIndex = new int[] { }; diff --git a/OpenRA.Mods.Common/Widgets/Logic/Editor/NewMapLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Editor/NewMapLogic.cs index 8448322063..ea9c7a2045 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Editor/NewMapLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Editor/NewMapLogic.cs @@ -51,9 +51,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic panel.Get("CREATE_BUTTON").OnClick = () => { - var tileset = modRules.TileSets[tilesetDropDown.Text]; - var map = Map.FromTileset(tileset); - int width, height; int.TryParse(widthTextField.Text, out width); int.TryParse(heightTextField.Text, out height); @@ -63,8 +60,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic width = Math.Max(2, width); height = Math.Max(2, height); - map.Resize(width + 2, height + tileset.MaxGroundHeight + 2); - map.ResizeCordon(1, 1, width + 1, height + tileset.MaxGroundHeight + 1); + var tileset = modRules.TileSets[tilesetDropDown.Text]; + var map = new Map(tileset, width + 2, height + tileset.MaxGroundHeight + 2); + + 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); diff --git a/OpenRA.Mods.Common/Widgets/RadarWidget.cs b/OpenRA.Mods.Common/Widgets/RadarWidget.cs index d2a77b1d76..615eda1977 100644 --- a/OpenRA.Mods.Common/Widgets/RadarWidget.cs +++ b/OpenRA.Mods.Common/Widgets/RadarWidget.cs @@ -237,8 +237,8 @@ namespace OpenRA.Mods.Common.Widgets // Draw viewport rect if (hasRadar) { - var tl = CellToMinimapPixel(world.Map.CellContaining(worldRenderer.Position(worldRenderer.Viewport.TopLeft))); - var br = CellToMinimapPixel(world.Map.CellContaining(worldRenderer.Position(worldRenderer.Viewport.BottomRight))); + var tl = CellToMinimapPixel(world.Map.CellContaining(worldRenderer.ProjectedPosition(worldRenderer.Viewport.TopLeft))); + var br = CellToMinimapPixel(world.Map.CellContaining(worldRenderer.ProjectedPosition(worldRenderer.Viewport.BottomRight))); Game.Renderer.EnableScissor(mapRect); DrawRadarPings(); diff --git a/OpenRA.Mods.D2k/UtilityCommands/D2kMapImporter.cs b/OpenRA.Mods.D2k/UtilityCommands/D2kMapImporter.cs index a8a90b5cbc..2ca753a292 100644 --- a/OpenRA.Mods.D2k/UtilityCommands/D2kMapImporter.cs +++ b/OpenRA.Mods.D2k/UtilityCommands/D2kMapImporter.cs @@ -308,16 +308,16 @@ namespace OpenRA.Mods.D2k.UtilityCommands mapSize = new Size(stream.ReadUInt16(), stream.ReadUInt16()); tileSet = rules.TileSets["ARRAKIS"]; - map = Map.FromTileset(tileSet); - map.Title = Path.GetFileNameWithoutExtension(mapFile); - map.Author = "Westwood Studios"; - map.MapSize = new int2(mapSize.Width + 2 * MapCordonWidth, mapSize.Height + 2 * MapCordonWidth); - map.Bounds = new Rectangle(MapCordonWidth, MapCordonWidth, mapSize.Width, mapSize.Height); - map.MapResources = Exts.Lazy(() => new CellLayer(TileShape.Rectangle, new Size(map.MapSize.X, map.MapSize.Y))); - map.MapTiles = Exts.Lazy(() => new CellLayer(TileShape.Rectangle, new Size(map.MapSize.X, map.MapSize.Y))); + map = new Map(tileSet, mapSize.Width + 2 * MapCordonWidth, mapSize.Height + 2 * MapCordonWidth) + { + Title = Path.GetFileNameWithoutExtension(mapFile), + Author = "Westwood Studios" + }; - map.Options = new MapOptions(); + var tl = new MPos(MapCordonWidth, MapCordonWidth); + var br = new MPos(MapCordonWidth + mapSize.Width - 1, MapCordonWidth + mapSize.Height - 1); + map.SetBounds(tl, br); // Get all templates from the tileset YAML file that have at least one frame and an Image property corresponding to the requested tileset // Each frame is a tile from the Dune 2000 tileset files, with the Frame ID being the index of the tile in the original file diff --git a/OpenRA.Mods.D2k/UtilityCommands/ImportD2kMapCommand.cs b/OpenRA.Mods.D2k/UtilityCommands/ImportD2kMapCommand.cs index fb3b752177..840be72081 100644 --- a/OpenRA.Mods.D2k/UtilityCommands/ImportD2kMapCommand.cs +++ b/OpenRA.Mods.D2k/UtilityCommands/ImportD2kMapCommand.cs @@ -23,7 +23,7 @@ namespace OpenRA.Mods.D2k.UtilityCommands // HACK: The engine code assumes that Game.modData is set. Game.ModData = modData; - var rules = Game.ModData.RulesetCache.LoadDefaultRules(); + var rules = Game.ModData.RulesetCache.Load(); var map = D2kMapImporter.Import(args[1], modData.Manifest.Mod.Id, args[2], rules); diff --git a/OpenRA.Mods.RA/Graphics/TeslaZapRenderable.cs b/OpenRA.Mods.RA/Graphics/TeslaZapRenderable.cs index 06baa89c90..5c4155f696 100644 --- a/OpenRA.Mods.RA/Graphics/TeslaZapRenderable.cs +++ b/OpenRA.Mods.RA/Graphics/TeslaZapRenderable.cs @@ -139,7 +139,7 @@ namespace OpenRA.Mods.RA.Graphics var step = steps.Where(t => (to - (z + new float2(t[0], t[1]))).LengthSquared < (to - z).LengthSquared) .MinBy(t => Math.Abs(float2.Dot(z + new float2(t[0], t[1]), q) + c)); - var pos = wr.Position((z + new float2(step[2], step[3])).ToInt2()); + var pos = wr.ProjectedPosition((z + new float2(step[2], step[3])).ToInt2()); rs.Add(new SpriteRenderable(s.GetSprite(step[4]), pos, WVec.Zero, 0, pal, 1f, true).PrepareRender(wr)); z += new float2(step[0], step[1]);