#region Copyright & License Information /* * Copyright 2007-2015 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.Collections.Generic; using System.Drawing; using System.Linq; using OpenRA.Graphics; using OpenRA.Mods.Common.Commands; using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { [Desc("Renders a debug overlay showing the terrain cells. Attach this to the world actor.")] public class TerrainGeometryOverlayInfo : TraitInfo { } public class TerrainGeometryOverlay : IPostRender, IWorldLoaded, IChatCommand { const string CommandName = "terrainoverlay"; const string CommandDesc = "Toggles the terrain geometry overlay"; public bool Enabled; public void WorldLoaded(World w, WorldRenderer wr) { var console = w.WorldActor.TraitOrDefault(); var help = w.WorldActor.TraitOrDefault(); if (console == null || help == null) return; console.RegisterCommand(CommandName, this); help.RegisterHelp(CommandName, CommandDesc); } public void InvokeCommand(string name, string arg) { if (name == CommandName) Enabled ^= true; } public void RenderAfterWorld(WorldRenderer wr, Actor self) { if (!Enabled) return; var map = wr.World.Map; var tileSet = wr.World.TileSet; var lr = Game.Renderer.WorldLineRenderer; var colors = wr.World.TileSet.HeightDebugColors; var mouseCell = wr.Viewport.ViewToWorld(Viewport.LastMousePos).ToMPos(wr.World.Map); foreach (var uv in wr.Viewport.AllVisibleCells.CandidateMapCoords) { if (!map.MapHeight.Value.Contains(uv)) continue; var height = (int)map.MapHeight.Value[uv]; var tile = map.MapTiles.Value[uv]; var ti = tileSet.GetTileInfo(tile); var ramp = ti != null ? (int)ti.RampType : 0; var corners = map.CellCorners[ramp]; var color = corners.Select(c => colors[height + c.Z / 512]).ToArray(); var pos = map.CenterOfCell(uv.ToCPos(map)); var screen = corners.Select(c => wr.ScreenPxPosition(pos + c).ToFloat2()).ToArray(); if (uv == mouseCell) lr.LineWidth = 3; for (var i = 0; i < 4; i++) { var j = (i + 1) % 4; lr.DrawLine(screen[i], screen[j], color[i], color[j]); } lr.LineWidth = 1; } // Projected cell coordinates for the current cell var projectedCorners = map.CellCorners[0]; lr.LineWidth = 3; foreach (var puv in map.ProjectedCellsCovering(mouseCell)) { var pos = map.CenterOfCell(((MPos)puv).ToCPos(map)); var screen = projectedCorners.Select(c => wr.ScreenPxPosition(pos + c - new WVec(0, 0, pos.Z)).ToFloat2()).ToArray(); for (var i = 0; i < 4; i++) { var j = (i + 1) % 4; lr.DrawLine(screen[i], screen[j], Color.Navy); } } lr.LineWidth = 1; } } }