diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
index 44ee1075e0..2f46b7ce84 100644
--- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
+++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
@@ -528,6 +528,7 @@
+
diff --git a/OpenRA.Mods.Common/Traits/World/WarheadDebugOverlay.cs b/OpenRA.Mods.Common/Traits/World/WarheadDebugOverlay.cs
new file mode 100644
index 0000000000..ab1204c021
--- /dev/null
+++ b/OpenRA.Mods.Common/Traits/World/WarheadDebugOverlay.cs
@@ -0,0 +1,87 @@
+#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.Collections.Generic;
+using System.Drawing;
+using OpenRA.Graphics;
+using OpenRA.Traits;
+
+namespace OpenRA.Mods.Common.Traits
+{
+ [Desc("Part of the combat overlay from DeveloperMode. Attach this to the world actor.")]
+ public class WarheadDebugOverlayInfo : ITraitInfo
+ {
+ public readonly int DisplayDuration = 25;
+
+ public object Create(ActorInitializer init) { return new WarheadDebugOverlay(this); }
+ }
+
+ public class WarheadDebugOverlay : IPostRender
+ {
+ class WHImpact
+ {
+ public readonly WPos CenterPosition;
+ public readonly WDist[] Range;
+ public int Time;
+
+ public WDist OuterRange
+ {
+ get { return Range[Range.Length - 1]; }
+ }
+
+ public WHImpact(WPos pos, WDist[] range, int time)
+ {
+ CenterPosition = pos;
+ Range = range;
+ Time = time;
+ }
+ }
+
+ readonly WarheadDebugOverlayInfo info;
+ readonly List impacts = new List();
+
+ public WarheadDebugOverlay(WarheadDebugOverlayInfo info)
+ {
+ this.info = info;
+ }
+
+ public void AddImpact(WPos pos, WDist[] range)
+ {
+ impacts.Add(new WHImpact(pos, range, info.DisplayDuration));
+ }
+
+ public void RenderAfterWorld(WorldRenderer wr, Actor self)
+ {
+ foreach (var i in impacts)
+ {
+ var alpha = 255.0f * i.Time / info.DisplayDuration;
+ var rangeStep = alpha / i.Range.Length;
+
+ wr.DrawRangeCircle(i.CenterPosition, i.OuterRange, Color.FromArgb((int)alpha, Color.Red));
+
+ foreach (var r in i.Range)
+ {
+ var tl = wr.ScreenPosition(i.CenterPosition - new WVec(r.Length, r.Length, 0));
+ var br = wr.ScreenPosition(i.CenterPosition + new WVec(r.Length, r.Length, 0));
+ var rect = RectangleF.FromLTRB(tl.X, tl.Y, br.X, br.Y);
+
+ Game.Renderer.WorldLineRenderer.FillEllipse(rect, Color.FromArgb((int)alpha, Color.Red));
+
+ alpha -= rangeStep;
+ }
+
+ if (!wr.World.Paused)
+ i.Time--;
+ }
+
+ impacts.RemoveAll(i => i.Time == 0);
+ }
+ }
+}
diff --git a/OpenRA.Mods.Common/Warheads/HealthPercentageDamageWarhead.cs b/OpenRA.Mods.Common/Warheads/HealthPercentageDamageWarhead.cs
index 92bba3a1db..e01e0a6c5e 100644
--- a/OpenRA.Mods.Common/Warheads/HealthPercentageDamageWarhead.cs
+++ b/OpenRA.Mods.Common/Warheads/HealthPercentageDamageWarhead.cs
@@ -10,6 +10,7 @@
using System.Collections.Generic;
using System.Linq;
+using OpenRA.Mods.Common.Traits;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Warheads
@@ -22,6 +23,14 @@ namespace OpenRA.Mods.Common.Warheads
public override void DoImpact(WPos pos, Actor firedBy, IEnumerable damageModifiers)
{
var world = firedBy.World;
+
+ if (world.LocalPlayer != null)
+ {
+ var devMode = world.LocalPlayer.PlayerActor.TraitOrDefault();
+ if (devMode != null && devMode.ShowCombatGeometry)
+ world.WorldActor.Trait().AddImpact(pos, Spread);
+ }
+
var range = Spread[0];
var hitActors = world.FindActorsInCircle(pos, range);
if (Spread.Length > 1 && Spread[1].Length > 0)
diff --git a/OpenRA.Mods.Common/Warheads/SpreadDamageWarhead.cs b/OpenRA.Mods.Common/Warheads/SpreadDamageWarhead.cs
index 6a0e11255e..c63077583b 100644
--- a/OpenRA.Mods.Common/Warheads/SpreadDamageWarhead.cs
+++ b/OpenRA.Mods.Common/Warheads/SpreadDamageWarhead.cs
@@ -10,6 +10,7 @@
using System;
using System.Collections.Generic;
+using OpenRA.Mods.Common.Traits;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Warheads
@@ -50,6 +51,13 @@ namespace OpenRA.Mods.Common.Warheads
var world = firedBy.World;
+ if (world.LocalPlayer != null)
+ {
+ var devMode = world.LocalPlayer.PlayerActor.TraitOrDefault();
+ if (devMode != null && devMode.ShowCombatGeometry)
+ world.WorldActor.Trait().AddImpact(pos, Range);
+ }
+
// This only finds actors where the center is within the search radius,
// so we need to search beyond the maximum spread to account for actors with large health radius
var hitActors = world.FindActorsInCircle(pos, Range[Range.Length - 1] + TargetExtraSearchRadius);
diff --git a/mods/cnc/rules/world.yaml b/mods/cnc/rules/world.yaml
index f8832d807a..36cefb68fb 100644
--- a/mods/cnc/rules/world.yaml
+++ b/mods/cnc/rules/world.yaml
@@ -73,6 +73,7 @@ World:
ResourceLayer:
ResourceClaimLayer:
PathfinderDebugOverlay:
+ WarheadDebugOverlay:
SpawnMapActors:
MPStartLocations:
CreateMPPlayers:
@@ -152,4 +153,3 @@ EditorWorld:
Inherits: ^BaseWorld
EditorActorLayer:
EditorResourceLayer:
-
diff --git a/mods/d2k/rules/world.yaml b/mods/d2k/rules/world.yaml
index 35c448c614..acc693d261 100644
--- a/mods/d2k/rules/world.yaml
+++ b/mods/d2k/rules/world.yaml
@@ -67,6 +67,7 @@ World:
ValidGround: Sand, Dune, Rock
DomainIndex:
PathfinderDebugOverlay:
+ WarheadDebugOverlay:
BuildableTerrainLayer:
D2kResourceLayer:
ResourceClaimLayer:
@@ -146,4 +147,3 @@ EditorWorld:
Inherits: ^BaseWorld
EditorActorLayer:
D2kEditorResourceLayer:
-
diff --git a/mods/ra/rules/world.yaml b/mods/ra/rules/world.yaml
index ae2d4193fc..0e49d5848f 100644
--- a/mods/ra/rules/world.yaml
+++ b/mods/ra/rules/world.yaml
@@ -118,6 +118,7 @@ World:
ResourceLayer:
ResourceClaimLayer:
PathfinderDebugOverlay:
+ WarheadDebugOverlay:
SpawnMapActors:
CreateMPPlayers:
MPStartUnits@mcvonly:
@@ -171,4 +172,3 @@ EditorWorld:
Inherits: ^BaseWorld
EditorActorLayer:
EditorResourceLayer:
-
diff --git a/mods/ts/rules/world.yaml b/mods/ts/rules/world.yaml
index 07a385eaa9..90d349c0a4 100644
--- a/mods/ts/rules/world.yaml
+++ b/mods/ts/rules/world.yaml
@@ -97,6 +97,7 @@ World:
ResourceLayer:
ResourceClaimLayer:
PathfinderDebugOverlay:
+ WarheadDebugOverlay:
SpawnMapActors:
CreateMPPlayers:
MPStartUnits@MCV:
@@ -173,4 +174,3 @@ EditorWorld:
Inherits: ^BaseWorld
EditorActorLayer:
EditorResourceLayer:
-