diff --git a/OpenRA.Game/FieldLoader.cs b/OpenRA.Game/FieldLoader.cs index 9b2dcb920c..616bc1af34 100644 --- a/OpenRA.Game/FieldLoader.cs +++ b/OpenRA.Game/FieldLoader.cs @@ -188,6 +188,27 @@ namespace OpenRA return InvalidValueAction(value, fieldType, fieldName); } + else if (fieldType == typeof(Color[])) + { + var parts = value.Split(','); + + if (parts.Length % 4 != 0) + return InvalidValueAction(value, fieldType, fieldName); + + var colors = new Color[parts.Length / 4]; + + for (var i = 0; i < colors.Length; i++) + { + colors[i] = Color.FromArgb( + Exts.ParseIntegerInvariant(parts[4 * i]).Clamp(0, 255), + Exts.ParseIntegerInvariant(parts[4 * i + 1]).Clamp(0, 255), + Exts.ParseIntegerInvariant(parts[4 * i + 2]).Clamp(0, 255), + Exts.ParseIntegerInvariant(parts[4 * i + 3]).Clamp(0, 255)); + } + + return colors; + } + else if (fieldType == typeof(HSLColor)) { var parts = value.Split(','); diff --git a/OpenRA.Game/Graphics/Viewport.cs b/OpenRA.Game/Graphics/Viewport.cs index efa1a53b8b..d9a8513a88 100644 --- a/OpenRA.Game/Graphics/Viewport.cs +++ b/OpenRA.Game/Graphics/Viewport.cs @@ -39,6 +39,8 @@ namespace OpenRA.Graphics // Map bounds (world-px) readonly Rectangle mapBounds; + readonly int maxGroundHeight; + // Viewport geometry (world-px) public int2 CenterLocation { get; private set; } @@ -96,6 +98,7 @@ namespace OpenRA.Graphics var br = wr.ScreenPxPosition(map.CenterOfCell(Map.MapToCell(map.TileShape, new CPos(b.Right, b.Bottom))) + new WVec(511, 511, 0)); mapBounds = Rectangle.FromLTRB(tl.X, tl.Y, br.X, br.Y); + maxGroundHeight = wr.world.TileSet.MaxGroundHeight; CenterLocation = (tl + br) / 2; Zoom = Game.Settings.Graphics.PixelDouble ? 2 : 1; } @@ -144,8 +147,8 @@ namespace OpenRA.Graphics var cbr = map.CenterOfCell(VisibleCells.BottomRight) + new WVec(512, 512, 0); // Convert to screen coordinates - var tl = WorldToViewPx(worldRenderer.ScreenPxPosition(ctl)).Clamp(ScreenClip); - var br = WorldToViewPx(worldRenderer.ScreenPxPosition(cbr)).Clamp(ScreenClip); + var tl = WorldToViewPx(worldRenderer.ScreenPxPosition(ctl - new WVec(0, 0, ctl.Z))).Clamp(ScreenClip); + var br = WorldToViewPx(worldRenderer.ScreenPxPosition(cbr - new WVec(0, 0, cbr.Z))).Clamp(ScreenClip); return Rectangle.FromLTRB(tl.X, tl.Y, br.X, br.Y); } } @@ -156,14 +159,20 @@ namespace OpenRA.Graphics { if (cellsDirty) { - // Visible rectangle in map coordinates var map = worldRenderer.world.Map; - var ctl = Map.CellToMap(map.TileShape, map.CellContaining(worldRenderer.Position(TopLeft))); - var cbr = Map.CellToMap(map.TileShape, map.CellContaining(worldRenderer.Position(BottomRight))); + var wtl = worldRenderer.Position(TopLeft); + var wbr = worldRenderer.Position(BottomRight); - // Add a 2 cell cordon to prevent holes, then convert back to cell coordinates - var tl = map.Clamp(Map.MapToCell(map.TileShape, ctl - new CVec(2, 2))); - var br = map.Clamp(Map.MapToCell(map.TileShape, cbr + new CVec(2, 2))); + // Visible rectangle in map coordinates + var ctl = new CPos(wtl.X / 1024, wtl.Y / 1024); + var dy = map.TileShape == TileShape.Diamond ? 512 : 1024; + var cbr = new CPos((wbr.X + 1023) / 1024, (wbr.Y + dy - 1) / dy); + + // Add a 1 cell cordon to prevent holes, then convert back to cell coordinates + var tl = map.Clamp(Map.MapToCell(map.TileShape, ctl - new CVec(1, 1))); + + // Also need to account for height of cells in rows below the bottom + var br = map.Clamp(Map.MapToCell(map.TileShape, cbr + new CVec(1, 2 + maxGroundHeight / 2))); cells = new CellRegion(map.TileShape, tl, br); cellsDirty = false; diff --git a/OpenRA.Game/Map/Map.cs b/OpenRA.Game/Map/Map.cs index 24089e2ff0..d2ac405aaa 100644 --- a/OpenRA.Game/Map/Map.cs +++ b/OpenRA.Game/Map/Map.cs @@ -24,6 +24,38 @@ using OpenRA.Traits; namespace OpenRA { + struct BinaryDataHeader + { + public readonly byte Format; + public readonly uint TilesOffset; + public readonly uint HeightsOffset; + public readonly uint ResourcesOffset; + + public BinaryDataHeader(Stream s, int2 expectedSize) + { + Format = s.ReadUInt8(); + var width = s.ReadUInt16(); + var height = s.ReadUInt16(); + if (width != expectedSize.X || height != expectedSize.Y) + throw new InvalidDataException("Invalid tile data"); + + if (Format == 1) + { + TilesOffset = 5; + HeightsOffset = 0; + ResourcesOffset = (uint)(3 * width * height + 5); + } + else if (Format == 2) + { + TilesOffset = s.ReadUInt32(); + HeightsOffset = s.ReadUInt32(); + ResourcesOffset = s.ReadUInt32(); + } + else + throw new InvalidDataException("Unknown binary map format '{0}'".F(Format)); + } + } + public class MapOptions { public bool? Cheats; @@ -118,11 +150,14 @@ namespace OpenRA [FieldLoader.Ignore] public List TranslationDefinitions = new List(); // Binary map data - [FieldLoader.Ignore] public byte TileFormat = 1; + [FieldLoader.Ignore] public byte TileFormat = 2; + public int2 MapSize; [FieldLoader.Ignore] public Lazy> MapTiles; [FieldLoader.Ignore] public Lazy> MapResources; + [FieldLoader.Ignore] public Lazy> MapHeight; + [FieldLoader.Ignore] public CellLayer CustomTerrain; [FieldLoader.Ignore] Lazy cachedTileSet; @@ -145,6 +180,13 @@ namespace OpenRA 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", @@ -155,6 +197,7 @@ namespace OpenRA Options = new MapOptions(), MapResources = Exts.Lazy(() => new CellLayer(tileShape, size)), MapTiles = makeMapTiles, + MapHeight = makeMapHeight, Actors = Exts.Lazy(() => new Dictionary()), Smudges = Exts.Lazy(() => new List()) }; @@ -253,6 +296,8 @@ namespace OpenRA MapTiles = Exts.Lazy(() => LoadMapTiles()); MapResources = Exts.Lazy(() => LoadResourceTiles()); + MapHeight = Exts.Lazy(() => LoadMapHeight()); + TileShape = Game.modData.Manifest.TileShape; SubCellOffsets = Game.modData.Manifest.SubCellOffsets; LastSubCell = (SubCell)(SubCellOffsets.Length - 1); @@ -395,33 +440,25 @@ namespace OpenRA public CellLayer LoadMapTiles() { var tiles = new CellLayer(this); - using (var dataStream = Container.GetContent("map.bin")) + using (var s = Container.GetContent("map.bin")) { - if (dataStream.ReadUInt8() != 1) - throw new InvalidDataException("Unknown binary map format"); - - // Load header info - var width = dataStream.ReadUInt16(); - var height = dataStream.ReadUInt16(); - - if (width != MapSize.X || height != MapSize.Y) - throw new InvalidDataException("Invalid tile data"); - - // Load tile data - var data = dataStream.ReadBytes(MapSize.X * MapSize.Y * 3); - var d = 0; - for (var i = 0; i < MapSize.X; i++) + var header = new BinaryDataHeader(s, MapSize); + if (header.TilesOffset > 0) { - for (var j = 0; j < MapSize.Y; j++) + s.Position = header.TilesOffset; + for (var i = 0; i < MapSize.X; i++) { - var tile = BitConverter.ToUInt16(data, d); - d += 2; + for (var j = 0; j < MapSize.Y; j++) + { + var tile = s.ReadUInt16(); + var index = s.ReadUInt8(); - var index = data[d++]; - if (index == byte.MaxValue) - index = (byte)(i % 4 + (j % 4) * 4); + // TODO: Remember to remove this when rewriting tile variants / PickAny + if (index == byte.MaxValue) + index = (byte)(i % 4 + (j % 4) * 4); - tiles[i, j] = new TerrainTile(tile, index); + tiles[i, j] = new TerrainTile(tile, index); + } } } } @@ -429,32 +466,45 @@ namespace OpenRA return tiles; } + public CellLayer LoadMapHeight() + { + var maxHeight = cachedTileSet.Value.MaxGroundHeight; + var tiles = new CellLayer(this); + using (var s = Container.GetContent("map.bin")) + { + var header = new BinaryDataHeader(s, MapSize); + if (header.HeightsOffset > 0) + { + s.Position = header.HeightsOffset; + for (var i = 0; i < MapSize.X; i++) + for (var j = 0; j < MapSize.Y; j++) + tiles[i, j] = s.ReadUInt8().Clamp((byte)0, maxHeight); + } + } + + return tiles; + } + public CellLayer LoadResourceTiles() { var resources = new CellLayer(this); - using (var dataStream = Container.GetContent("map.bin")) + using (var s = Container.GetContent("map.bin")) { - if (dataStream.ReadUInt8() != 1) - throw new InvalidDataException("Unknown binary map format"); - - // Load header info - var width = dataStream.ReadUInt16(); - var height = dataStream.ReadUInt16(); - - if (width != MapSize.X || height != MapSize.Y) - throw new InvalidDataException("Invalid tile data"); - - // Skip past tile data - dataStream.Seek(3 * MapSize.X * MapSize.Y, SeekOrigin.Current); - - var data = dataStream.ReadBytes(MapSize.X * MapSize.Y * 2); - var d = 0; - - // Load resource data - for (var i = 0; i < MapSize.X; i++) - for (var j = 0; j < MapSize.Y; j++) - resources[i, j] = new ResourceTile(data[d++], data[d++]); + var header = new BinaryDataHeader(s, MapSize); + if (header.ResourcesOffset > 0) + { + s.Position = header.ResourcesOffset; + for (var i = 0; i < MapSize.X; i++) + { + for (var j = 0; j < MapSize.Y; j++) + { + var type = s.ReadUInt8(); + var density = s.ReadUInt8(); + resources[i, j] = new ResourceTile(type, density); + } + } + } } return resources; @@ -465,28 +515,53 @@ namespace OpenRA var dataStream = new MemoryStream(); using (var writer = new BinaryWriter(dataStream)) { - // File header consists of a version byte, followed by 2 ushorts for width and height + // Binary data version writer.Write(TileFormat); + + // Size writer.Write((ushort)MapSize.X); writer.Write((ushort)MapSize.Y); + // Data offsets + var tilesOffset = 17; + var heightsOffset = cachedTileSet.Value.MaxGroundHeight > 0 ? 3 * MapSize.X * MapSize.Y + 17 : 0; + var resourcesOffset = (cachedTileSet.Value.MaxGroundHeight > 0 ? 4 : 3) * MapSize.X * MapSize.Y + 17; + + writer.Write((uint)tilesOffset); + writer.Write((uint)heightsOffset); + writer.Write((uint)resourcesOffset); + // Tile data - for (var i = 0; i < MapSize.X; i++) - for (var j = 0; j < MapSize.Y; j++) + if (tilesOffset != 0) + { + for (var i = 0; i < MapSize.X; i++) { - var tile = MapTiles.Value[i, j]; - writer.Write(tile.Type); - writer.Write(tile.Index); + for (var j = 0; j < MapSize.Y; j++) + { + var tile = MapTiles.Value[i, j]; + writer.Write(tile.Type); + writer.Write(tile.Index); + } } + } + + // Height data + if (heightsOffset != 0) + for (var i = 0; i < MapSize.X; i++) + for (var j = 0; j < MapSize.Y; j++) + writer.Write(MapHeight.Value[i, j]); // Resource data - for (var i = 0; i < MapSize.X; i++) + if (resourcesOffset != 0) { - for (var j = 0; j < MapSize.Y; j++) + for (var i = 0; i < MapSize.X; i++) { - var tile = MapResources.Value[i, j]; - writer.Write(tile.Type); - writer.Write(tile.Index); + for (var j = 0; j < MapSize.Y; j++) + { + var tile = MapResources.Value[i, j]; + writer.Write(tile.Type); + writer.Write(tile.Index); + } } } } @@ -513,7 +588,9 @@ namespace OpenRA // (b) Therefore: // - ax + by adds (a - b) * 512 + 512 to u // - ax + by adds (a + b) * 512 + 512 to v - return new WPos(512 * (cell.X - cell.Y + 1), 512 * (cell.X + cell.Y + 1), 0); + + var z = Contains(cell) ? 512 * MapHeight.Value[cell] : 0; + return new WPos(512 * (cell.X - cell.Y + 1), 512 * (cell.X + cell.Y + 1), z); } public WPos CenterOfSubCell(CPos cell, SubCell subCell) @@ -588,10 +665,12 @@ namespace OpenRA { var oldMapTiles = MapTiles.Value; var oldMapResources = MapResources.Value; + var oldMapHeight = MapHeight.Value; var newSize = new Size(width, height); MapTiles = Exts.Lazy(() => CellLayer.Resize(oldMapTiles, newSize, oldMapTiles[0, 0])); MapResources = Exts.Lazy(() => CellLayer.Resize(oldMapResources, newSize, oldMapResources[0, 0])); + MapHeight = Exts.Lazy(() => CellLayer.Resize(oldMapHeight, newSize, oldMapHeight[0, 0])); MapSize = new int2(newSize); } diff --git a/OpenRA.Game/Map/TileSet.cs b/OpenRA.Game/Map/TileSet.cs index f26da12774..2c1769808f 100644 --- a/OpenRA.Game/Map/TileSet.cs +++ b/OpenRA.Game/Map/TileSet.cs @@ -148,7 +148,7 @@ namespace OpenRA public class TileSet { - static readonly string[] Fields = { "Name", "Id", "SheetSize", "Palette", "PlayerPalette", "Extensions", "WaterPaletteRotationBase", "EditorTemplateOrder", "IgnoreTileSpriteOffsets" }; + static readonly string[] Fields = { "Name", "Id", "SheetSize", "Palette", "PlayerPalette", "Extensions", "WaterPaletteRotationBase", "EditorTemplateOrder", "IgnoreTileSpriteOffsets", "MaximumHeight" }; public readonly string Name; public readonly string Id; @@ -156,11 +156,14 @@ namespace OpenRA public readonly string Palette; public readonly string PlayerPalette; public readonly string[] Extensions; - public readonly int WaterPaletteRotationBase = 0x60; - public readonly Dictionary Templates = new Dictionary(); + public readonly int WaterPaletteRotationBase = 0x60; + public readonly byte MaxGroundHeight = 0; + public readonly Color[] HeightDebugColors = new[] { Color.Red }; public readonly string[] EditorTemplateOrder; public readonly bool IgnoreTileSpriteOffsets; + public readonly Dictionary Templates = new Dictionary(); + public readonly TerrainTypeInfo[] TerrainInfo; readonly Dictionary terrainIndexByType = new Dictionary(); readonly byte defaultWalkableTerrainIndex; diff --git a/OpenRA.Game/Traits/Player/DeveloperMode.cs b/OpenRA.Game/Traits/Player/DeveloperMode.cs index 66b9656ca7..af18664c41 100644 --- a/OpenRA.Game/Traits/Player/DeveloperMode.cs +++ b/OpenRA.Game/Traits/Player/DeveloperMode.cs @@ -23,6 +23,7 @@ namespace OpenRA.Traits public bool BuildAnywhere; public bool ShowCombatGeometry; public bool ShowDebugGeometry; + public bool ShowTerrainGeometry; public object Create(ActorInitializer init) { return new DeveloperMode(this); } } @@ -41,6 +42,7 @@ namespace OpenRA.Traits // Client side only public bool ShowCombatGeometry; public bool ShowDebugGeometry; + public bool ShowTerrainGeometry; public DeveloperMode(DeveloperModeInfo info) { @@ -53,6 +55,7 @@ namespace OpenRA.Traits BuildAnywhere = info.BuildAnywhere; ShowCombatGeometry = info.ShowCombatGeometry; ShowDebugGeometry = info.ShowDebugGeometry; + ShowTerrainGeometry = info.ShowTerrainGeometry; } public void ResolveOrder(Actor self, Order order) diff --git a/OpenRA.Mods.Common/Graphics/VoxelRenderable.cs b/OpenRA.Mods.Common/Graphics/VoxelRenderable.cs index 24c0b76655..259fb1c4d3 100644 --- a/OpenRA.Mods.Common/Graphics/VoxelRenderable.cs +++ b/OpenRA.Mods.Common/Graphics/VoxelRenderable.cs @@ -100,8 +100,13 @@ namespace OpenRA.Mods.Common.Graphics public void Render(WorldRenderer wr) { + // TODO: This is a temporary workaround until we have a proper ramp-aware height calculation + var groundPos = wr.world.Map.CenterOfCell(wr.world.Map.CellContaining(pos)); + + var ts = Game.modData.Manifest.TileSize; + var groundZ = ts.Height * (groundPos.Z - pos.Z) / 1024f; + var pxOrigin = wr.ScreenPosition(pos); - var groundZ = 0.5f*(pxOrigin.Y - wr.ScreenZPosition(pos, 0)); var shadowOrigin = pxOrigin - groundZ*(new float2(renderProxy.ShadowDirection, 1)); var psb = renderProxy.ProjectedShadowBounds; diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index e2943e07b9..dac0a791ce 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -152,6 +152,7 @@ + diff --git a/OpenRA.Mods.Common/World/TerrainGeometryOverlay.cs b/OpenRA.Mods.Common/World/TerrainGeometryOverlay.cs new file mode 100644 index 0000000000..f68b7d22c3 --- /dev/null +++ b/OpenRA.Mods.Common/World/TerrainGeometryOverlay.cs @@ -0,0 +1,127 @@ +#region Copyright & License Information + /* + * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ + #endregion + +using System; +using System.Drawing; +using System.Collections.Generic; +using System.Linq; +using OpenRA.Traits; +using OpenRA.Graphics; + +namespace OpenRA.Mods.Common +{ + [Desc("Renders a debug overlay showing the terrain cells. Attach this to the world actor.")] + public class TerrainGeometryOverlayInfo : ITraitInfo + { + public object Create(ActorInitializer init) { return new TerrainGeometryOverlay(init.self); } + } + + public class TerrainGeometryOverlay : IRenderOverlay + { + readonly int[][] vertices = new int[][] + { + // Flat + new[] { 0, 0, 0, 0 }, + + // Slopes (two corners high) + new[] { 0, 0, 1, 1 }, + new[] { 1, 0, 0, 1 }, + new[] { 1, 1, 0, 0 }, + new[] { 0, 1, 1, 0 }, + + // Slopes (one corner high) + new[] { 0, 0, 0, 1 }, + new[] { 1, 0, 0, 0 }, + new[] { 0, 1, 0, 0 }, + new[] { 0, 0, 1, 0 }, + + // Slopes (three corners high) + new[] { 1, 0, 1, 1 }, + new[] { 1, 1, 0, 1 }, + new[] { 1, 1, 1, 0 }, + new[] { 0, 1, 1, 1 }, + + // Slopes (two corners high, one corner double high) + new[] { 1, 0, 1, 2 }, + new[] { 2, 1, 0, 1 }, + new[] { 1, 2, 1, 0 }, + new[] { 0, 1, 2, 1 }, + + // Slopes (two corners high, alternating) + new[] { 1, 0, 1, 0 }, + new[] { 0, 1, 0, 1 }, + new[] { 1, 0, 1, 0 }, + new[] { 0, 1, 0, 1 } + }; + + readonly Lazy devMode; + + public TerrainGeometryOverlay(Actor self) + { + devMode = Exts.Lazy(() => self.World.LocalPlayer != null ? self.World.LocalPlayer.PlayerActor.Trait() : null); + } + + public void Render(WorldRenderer wr) + { + if (devMode.Value == null || !devMode.Value.ShowTerrainGeometry) + return; + + var ts = wr.world.Map.TileShape; + var colors = wr.world.TileSet.HeightDebugColors; + + var leftDelta = ts == TileShape.Diamond ? new WVec(-512, 0, 0) : new WVec(-512, -512, 0); + var topDelta = ts == TileShape.Diamond ? new WVec(0, -512, 0) : new WVec(512, -512, 0); + var rightDelta = ts == TileShape.Diamond ? new WVec(512, 0, 0) : new WVec(512, 512, 0); + var bottomDelta = ts == TileShape.Diamond ? new WVec(0, 512, 0) : new WVec(-512, 512, 0); + + foreach (var cell in wr.Viewport.VisibleCells) + { + var lr = Game.Renderer.WorldLineRenderer; + var pos = wr.world.Map.CenterOfCell(cell); + + var height = (int)wr.world.Map.MapHeight.Value[cell]; + var tile = wr.world.Map.MapTiles.Value[cell]; + + TerrainTileInfo tileInfo = null; + + // TODO: This is a temporary workaround for our sloppy tileset definitions + // (ra/td templates omit Clear tiles from templates) + try + { + tileInfo = wr.world.TileSet.Templates[tile.Type][tile.Index]; + } + catch (Exception) { } + + if (tileInfo == null) + continue; + + var leftHeight = vertices[tileInfo.RampType][0]; + var topHeight = vertices[tileInfo.RampType][1]; + var rightHeight = vertices[tileInfo.RampType][2]; + var bottomHeight = vertices[tileInfo.RampType][3]; + + var leftColor = colors[height + leftHeight]; + var topColor = colors[height + topHeight]; + var rightColor = colors[height + rightHeight]; + var bottomColor = colors[height + bottomHeight]; + + var left = wr.ScreenPxPosition(pos + leftDelta + new WVec(0, 0, 512 * leftHeight)).ToFloat2(); + var top = wr.ScreenPxPosition(pos + topDelta + new WVec(0, 0, 512 * topHeight)).ToFloat2(); + var right = wr.ScreenPxPosition(pos + rightDelta + new WVec(0, 0, 512 * rightHeight)).ToFloat2(); + var bottom = wr.ScreenPxPosition(pos + bottomDelta + new WVec(0, 0, 512 * bottomHeight)).ToFloat2(); + + lr.DrawLine(left, top, leftColor, topColor); + lr.DrawLine(top, right, topColor, rightColor); + lr.DrawLine(right, bottom, rightColor, bottomColor); + lr.DrawLine(bottom, left, bottomColor, leftColor); + } + } + } +} diff --git a/OpenRA.Mods.RA/Widgets/Logic/DebugMenuLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/DebugMenuLogic.cs index 1011d75816..2e6cd763ff 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/DebugMenuLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/DebugMenuLogic.cs @@ -74,6 +74,13 @@ namespace OpenRA.Mods.RA.Widgets.Logic showGeometryCheckbox.OnClick = () => devTrait.ShowDebugGeometry ^= true; } + var showTerrainGeometryCheckbox = widget.GetOrNull("SHOW_TERRAIN_OVERLAY"); + if (showTerrainGeometryCheckbox != null) + { + showTerrainGeometryCheckbox.IsChecked = () => devTrait.ShowTerrainGeometry; + showTerrainGeometryCheckbox.OnClick = () => devTrait.ShowTerrainGeometry ^= true; + } + var allTechCheckbox = widget.GetOrNull("ENABLE_TECH"); if (allTechCheckbox != null) { diff --git a/mods/cnc/chrome/ingame-debug.yaml b/mods/cnc/chrome/ingame-debug.yaml index 148e0ec559..9e1dc992bc 100644 --- a/mods/cnc/chrome/ingame-debug.yaml +++ b/mods/cnc/chrome/ingame-debug.yaml @@ -83,30 +83,36 @@ Container@DEBUG_PANEL: Width: PARENT_RIGHT Checkbox@SHOW_UNIT_PATHS: X: 45 - Y: 285 + Y: 275 Width: 200 Height: 20 Font: Regular Text: Show Unit Paths Checkbox@SHOW_ASTAR: X: 45 - Y: 315 + Y: 305 Height: 20 Width: 200 Font: Regular Text: Show A* Cost Checkbox@SHOW_COMBATOVERLAY: X: 290 - Y: 285 + Y: 275 Height: 20 Width: 200 Font: Regular Text: Show Combat Geometry Checkbox@SHOW_GEOMETRY: X: 290 - Y: 315 + Y: 305 Height: 20 Width: 200 Font: Regular Text: Show Render Geometry - + Checkbox@SHOW_TERRAIN_OVERLAY: + X: 290 + Y: 335 + Height: 20 + Width: 200 + Font: Regular + Text: Show Terrain Geometry diff --git a/mods/cnc/rules/world.yaml b/mods/cnc/rules/world.yaml index 9410aca729..a26240673b 100644 --- a/mods/cnc/rules/world.yaml +++ b/mods/cnc/rules/world.yaml @@ -125,6 +125,7 @@ World: AllowedTerrainTypes: Clear,Road AllowUnderActors: false PathfinderDebugOverlay: + TerrainGeometryOverlay: SpawnMapActors: MPStartLocations: CreateMPPlayers: diff --git a/mods/d2k/rules/world.yaml b/mods/d2k/rules/world.yaml index e3d091e8b1..26dd5e7d75 100644 --- a/mods/d2k/rules/world.yaml +++ b/mods/d2k/rules/world.yaml @@ -104,6 +104,7 @@ World: Race: ordos DomainIndex: PathfinderDebugOverlay: + TerrainGeometryOverlay: BuildableTerrainLayer: D2kResourceLayer: ResourceClaimLayer: diff --git a/mods/ra/chrome/ingame-debug.yaml b/mods/ra/chrome/ingame-debug.yaml index b2e20db205..e6cf64c0ae 100644 --- a/mods/ra/chrome/ingame-debug.yaml +++ b/mods/ra/chrome/ingame-debug.yaml @@ -1,6 +1,6 @@ Container@DEBUG_PANEL: Logic: DebugMenuLogic - Y: 20 + Y: 10 Width: PARENT_RIGHT Height: PARENT_BOTTOM Children: @@ -88,30 +88,36 @@ Container@DEBUG_PANEL: Width: PARENT_RIGHT Checkbox@SHOW_UNIT_PATHS: X: 45 - Y: 285 + Y: 275 Width: 200 Height: 20 Font: Regular Text: Show Unit Paths Checkbox@SHOW_ASTAR: X: 45 - Y: 315 + Y: 305 Height: 20 Width: 200 Font: Regular Text: Show A* Cost Checkbox@SHOW_COMBATOVERLAY: X: 290 - Y: 285 + Y: 275 Height: 20 Width: 200 Font: Regular Text: Show Combat Geometry Checkbox@SHOW_GEOMETRY: X: 290 - Y: 315 + Y: 305 Height: 20 Width: 200 Font: Regular Text: Show Render Geometry - + Checkbox@SHOW_TERRAIN_OVERLAY: + X: 290 + Y: 335 + Height: 20 + Width: 200 + Font: Regular + Text: Show Terrain Geometry diff --git a/mods/ra/rules/world.yaml b/mods/ra/rules/world.yaml index 7e6fda39aa..a5094986a2 100644 --- a/mods/ra/rules/world.yaml +++ b/mods/ra/rules/world.yaml @@ -133,6 +133,7 @@ World: AllowUnderActors: false TerrainType: Gems PathfinderDebugOverlay: + TerrainGeometryOverlay: SpawnMapActors: CreateMPPlayers: MPStartUnits@mcvonly: diff --git a/mods/ts/maps/arivruns/map.bin b/mods/ts/maps/arivruns/map.bin new file mode 100644 index 0000000000..3ba4a80df1 Binary files /dev/null and b/mods/ts/maps/arivruns/map.bin differ diff --git a/mods/ts/maps/arivruns/map.yaml b/mods/ts/maps/arivruns/map.yaml new file mode 100644 index 0000000000..f35730f8ab --- /dev/null +++ b/mods/ts/maps/arivruns/map.yaml @@ -0,0 +1,188 @@ +Selectable: True + +MapFormat: 6 + +RequiresMod: ts + +Title: A River Runs Near It + +Description: Describe your map here + +Author: Westwood Studios + +Tileset: TEMPERAT + +MapSize: 134,256 + +Bounds: 2,4,130,234 + +UseAsShellmap: False + +Type: Conquest + +Options: + +Players: + PlayerReference@Neutral: + Name: Neutral + OwnsWorld: True + NonCombatant: True + Race: gdi + PlayerReference@Multi0: + Name: Multi0 + Playable: True + Race: Random + Enemies: Creeps + PlayerReference@Multi1: + Name: Multi1 + Playable: True + Race: Random + Enemies: Creeps + PlayerReference@Multi2: + Name: Multi2 + Playable: True + Race: Random + Enemies: Creeps + PlayerReference@Multi3: + Name: Multi3 + Playable: True + Race: Random + Enemies: Creeps + PlayerReference@Multi4: + Name: Multi4 + Playable: True + Race: Random + Enemies: Creeps + PlayerReference@Multi5: + Name: Multi5 + Playable: True + Race: Random + Enemies: Creeps + PlayerReference@Creeps: + Name: Creeps + NonCombatant: True + Race: gdi + Enemies: Multi0, Multi1, Multi2, Multi3, Multi4, Multi5 + +Actors: + Actor0: tibtre01 + Location: 133,-102 + Owner: Neutral + Actor1: tibtre02 + Location: 74,-39 + Owner: Neutral + Actor2: tibtre03 + Location: 52,21 + Owner: Neutral + Actor3: tibtre02 + Location: 110,88 + Owner: Neutral + Actor4: tibtre03 + Location: 177,39 + Owner: Neutral + Actor5: tibtre01 + Location: 208,-37 + Owner: Neutral + Actor6: tibtre02 + Location: 91,62 + Owner: Neutral + Actor7: tibtre03 + Location: 84,76 + Owner: Neutral + Actor8: tibtre03 + Location: 62,-7 + Owner: Neutral + Actor9: tibtre03 + Location: 179,-73 + Owner: Neutral + Actor10: tibtre02 + Location: 169,-63 + Owner: Neutral + Actor11: tibtre01 + Location: 111,-77 + Owner: Neutral + Actor12: tibtre02 + Location: 87,-66 + Owner: Neutral + Actor13: tibtre03 + Location: 99,-6 + Owner: Neutral + Actor14: tibtre01 + Location: 81,40 + Owner: Neutral + Actor15: tibtre01 + Location: 125,114 + Owner: Neutral + Actor16: tibtre01 + Location: 150,71 + Owner: Neutral + Actor17: tibtre03 + Location: 164,56 + Owner: Neutral + Actor18: tibtre03 + Location: 190,5 + Owner: Neutral + Actor19: tibtre02 + Location: 138,-66 + Owner: Neutral + Actor20: tibtre01 + Location: 181,-41 + Owner: Neutral + Actor21: tibtre01 + Location: 115,23 + Owner: Neutral + Actor22: tibtre02 + Location: 144,23 + Owner: Neutral + Actor23: tibtre01 + Location: 115,-24 + Owner: Neutral + Actor24: tibtre01 + Location: 150,-25 + Owner: Neutral + Actor25: tibtre01 + Location: 23,10 + Owner: Neutral + Actor26: tibtre01 + Location: 223,-1 + Owner: Neutral + Actor27: mpspawn + Location: 59,26 + Owner: Neutral + Actor28: mpspawn + Location: 207,-31 + Owner: Neutral + Actor29: mpspawn + Location: 82,-35 + Owner: Neutral + Actor30: mpspawn + Location: 178,34 + Owner: Neutral + Actor31: mpspawn + Location: 137,-94 + Owner: Neutral + Actor32: mpspawn + Location: 115,85 + Owner: Neutral + Actor33: waypoint + Location: 132,-4 + Owner: Neutral + Actor34: waypoint + Location: 132,-4 + Owner: Neutral + +Smudges: + +Rules: + +Sequences: + +VoxelSequences: + +Weapons: + +Voices: + +Notifications: + +Translations: diff --git a/mods/ts/rules/world.yaml b/mods/ts/rules/world.yaml index 4c7f48d9cf..4badd21f11 100644 --- a/mods/ts/rules/world.yaml +++ b/mods/ts/rules/world.yaml @@ -148,6 +148,7 @@ World: AllowUnderActors: false TerrainType: BlueTiberium PathfinderDebugOverlay: + TerrainGeometryOverlay: SpawnMapActors: CreateMPPlayers: MPStartUnits@MCV: diff --git a/mods/ts/tilesets/temperat.yaml b/mods/ts/tilesets/temperat.yaml index b82a5c1e99..024ce8afc4 100644 --- a/mods/ts/tilesets/temperat.yaml +++ b/mods/ts/tilesets/temperat.yaml @@ -3,6 +3,8 @@ General: Id: TEMPERAT Extensions: .tem, .shp Palette: isotem.pal + MaxGroundHeight: 16 + HeightDebugColors: 128,0,0,0, 128,0,0,68, 128,0,0,136, 128,0,0,204, 128,0,0,255, 128,68,0,204, 128,136,0,136, 128,204,0,68, 128,255,17,0, 128,255,85,0, 128,255,153,0, 128,255,221,0, 128,221,255,0, 128,153,255,0, 128,85,255,0, 128,17,255,0 EditorTemplateOrder: Misc Buildings, Clear, Cliff Pieces, Ice Flow, House, Blank, Ice Ramps, Cliff Set, Civilian Buildings, Shore Pieces, Rough LAT tile, Clear/Rough LAT, Cliff/Water pieces, Bendy Dirt Roads, Dirt Road Junctions, Straight Dirt Roads, Bridges, Paved Roads, Water, Dirt Road Slopes, Slope Set Pieces, Dead Oil Tanker, Ruins, Waterfalls, Ground 01, Ground 02, Sand, Sand/Clear LAT, Rough ground, Paved Road Ends, TrainBridges, Pavement, Pavement/Clear LAT, Paved road bits, Green, Green/Clear LAT, Ramp edge fixup, Water slopes, Pavement (Use for LAT), Paved Road Slopes, Monorail Slopes, Waterfalls-B, Waterfalls-C, Waterfalls-D, Tunnel Floor, Tunnel Side, TrackTunnel Floor, Destroyable Cliffs, Water Caves, Scrin Wreckage, DirtTrackTunnel Floor, DirtTunnel Floor SheetSize: 2048