diff --git a/OpenRA.Mods.Common/Effects/RevealShroudEffect.cs b/OpenRA.Mods.Common/Effects/RevealShroudEffect.cs new file mode 100644 index 0000000000..116bffd7a2 --- /dev/null +++ b/OpenRA.Mods.Common/Effects/RevealShroudEffect.cs @@ -0,0 +1,81 @@ +#region Copyright & License Information +/* + * Copyright 2007-2016 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, either version 3 of + * the License, or (at your option) any later version. For more + * information, see COPYING. + */ +#endregion + +using System.Collections.Generic; +using System.Linq; +using OpenRA.Effects; +using OpenRA.Graphics; +using OpenRA.Traits; + +namespace OpenRA.Mods.Common.Effects +{ + public class RevealShroudEffect : IEffect + { + static readonly PPos[] NoCells = { }; + + readonly WPos pos; + readonly Player player; + readonly Shroud.SourceType sourceType; + readonly WDist revealRadius; + readonly Stance validStances; + readonly int duration; + + int ticks; + + public RevealShroudEffect(WPos pos, WDist radius, Shroud.SourceType type, Player forPlayer, Stance stances, int delay = 0, int duration = 50) + { + this.pos = pos; + player = forPlayer; + revealRadius = radius; + validStances = stances; + sourceType = type; + this.duration = duration; + ticks = -delay; + } + + void AddCellsToPlayerShroud(Player p, PPos[] uv) { if (!validStances.HasStance(p.Stances[player])) return; p.Shroud.AddSource(this, sourceType, uv); } + + void RemoveCellsFromPlayerShroud(Player p) { p.Shroud.RemoveSource(this); } + + PPos[] ProjectedCells(World world) + { + var map = world.Map; + var range = revealRadius; + if (range == WDist.Zero) + return NoCells; + + return Shroud.ProjectedCellsInRange(map, pos, range) + .ToArray(); + } + + public void Tick(World world) + { + if (ticks == 0) + { + var cells = ProjectedCells(world); + foreach (var p in world.Players) + AddCellsToPlayerShroud(p, cells); + } + + if (ticks == duration) + { + foreach (var p in world.Players) + RemoveCellsFromPlayerShroud(p); + + world.AddFrameEndTask(w => w.Remove(this)); + } + + ticks++; + } + + public IEnumerable Render(WorldRenderer wr) { return SpriteRenderable.None; } + } +} diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index 93aaa12c61..51e210ca26 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -138,6 +138,7 @@ +