From 3d597c788050152310d122db26325470dda12db2 Mon Sep 17 00:00:00 2001 From: teees Date: Sat, 28 Nov 2015 21:34:12 +0100 Subject: [PATCH] Add IBlocksProjectiles interface to avoid using BlocksProjectiles directly --- .../Traits/BlocksProjectiles.cs | 20 ++++++++++++++----- .../Traits/CombatDebugOverlay.cs | 17 +++++++++++----- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/OpenRA.Mods.Common/Traits/BlocksProjectiles.cs b/OpenRA.Mods.Common/Traits/BlocksProjectiles.cs index 6ca63a390a..e03e53b246 100644 --- a/OpenRA.Mods.Common/Traits/BlocksProjectiles.cs +++ b/OpenRA.Mods.Common/Traits/BlocksProjectiles.cs @@ -9,9 +9,16 @@ #endregion using System.Linq; +using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { + [RequireExplicitImplementation] + public interface IBlocksProjectiles + { + WDist BlockingHeight { get; } + } + [Desc("This actor blocks bullets and missiles with 'Blockable' property.")] public class BlocksProjectilesInfo : UpgradableTraitInfo { @@ -20,17 +27,20 @@ namespace OpenRA.Mods.Common.Traits public override object Create(ActorInitializer init) { return new BlocksProjectiles(init.Self, this); } } - public class BlocksProjectiles : UpgradableTrait + public class BlocksProjectiles : UpgradableTrait, IBlocksProjectiles { public BlocksProjectiles(Actor self, BlocksProjectilesInfo info) : base(info) { } + WDist IBlocksProjectiles.BlockingHeight { get { return Info.Height; } } + public static bool AnyBlockingActorAt(World world, WPos pos) { var dat = world.Map.DistanceAboveTerrain(pos); + return world.ActorMap.GetActorsAt(world.Map.CellContaining(pos)) - .Any(a => a.TraitsImplementing() - .Where(t => t.Info.Height.Length >= dat.Length) + .Any(a => a.TraitsImplementing() + .Where(t => t.BlockingHeight >= dat) .Any(Exts.IsTraitEnabled)); } @@ -41,7 +51,7 @@ namespace OpenRA.Mods.Common.Traits foreach (var a in actors) { - var blockers = a.TraitsImplementing() + var blockers = a.TraitsImplementing() .Where(Exts.IsTraitEnabled).ToList(); if (!blockers.Any()) @@ -49,7 +59,7 @@ namespace OpenRA.Mods.Common.Traits var hitPos = WorldExtensions.MinimumPointLineProjection(start, end, a.CenterPosition); var dat = world.Map.DistanceAboveTerrain(hitPos); - if ((hitPos - start).Length < length && blockers.Any(t => t.Info.Height.Length >= dat.Length)) + if ((hitPos - start).Length < length && blockers.Any(t => t.BlockingHeight >= dat)) { hit = hitPos; return true; diff --git a/OpenRA.Mods.Common/Traits/CombatDebugOverlay.cs b/OpenRA.Mods.Common/Traits/CombatDebugOverlay.cs index e016bf9620..72d30fdbea 100644 --- a/OpenRA.Mods.Common/Traits/CombatDebugOverlay.cs +++ b/OpenRA.Mods.Common/Traits/CombatDebugOverlay.cs @@ -9,7 +9,9 @@ #endregion using System; +using System.Collections.Generic; using System.Drawing; +using System.Linq; using OpenRA.Graphics; using OpenRA.Mods.Common.Effects; using OpenRA.Traits; @@ -22,19 +24,18 @@ namespace OpenRA.Mods.Common.Traits public object Create(ActorInitializer init) { return new CombatDebugOverlay(init.Self); } } - public class CombatDebugOverlay : IPostRender, INotifyDamage + public class CombatDebugOverlay : IPostRender, INotifyDamage, INotifyCreated { readonly DeveloperMode devMode; readonly HealthInfo healthInfo; - readonly BlocksProjectilesInfo blockInfo; + IBlocksProjectiles[] allBlockers; Lazy attack; Lazy coords; public CombatDebugOverlay(Actor self) { healthInfo = self.Info.TraitInfoOrDefault(); - blockInfo = self.Info.TraitInfoOrDefault(); attack = Exts.Lazy(() => self.TraitOrDefault()); coords = Exts.Lazy(() => self.Trait()); @@ -42,6 +43,11 @@ namespace OpenRA.Mods.Common.Traits devMode = localPlayer != null ? localPlayer.PlayerActor.Trait() : null; } + public void Created(Actor self) + { + allBlockers = self.TraitsImplementing().ToArray(); + } + public void RenderAfterWorld(WorldRenderer wr, Actor self) { if (devMode == null || !devMode.ShowCombatGeometry) @@ -53,10 +59,11 @@ namespace OpenRA.Mods.Common.Traits if (healthInfo != null) healthInfo.Shape.DrawCombatOverlay(wr, wcr, self); - if (blockInfo != null) + var blockers = allBlockers.Where(Exts.IsTraitEnabled).ToList(); + if (blockers.Count > 0) { var hc = Color.Orange; - var height = new WVec(0, 0, blockInfo.Height.Length); + var height = new WVec(0, 0, blockers.Max(b => b.BlockingHeight.Length)); var ha = wr.ScreenPosition(self.CenterPosition); var hb = wr.ScreenPosition(self.CenterPosition + height); wcr.DrawLine(ha, hb, iz, hc);