From 7e6f7c51e1a308e1882c03909c573107e2fb7071 Mon Sep 17 00:00:00 2001 From: ScottNZ Date: Sat, 7 Jun 2014 02:05:10 +1200 Subject: [PATCH] Refactor AutoTarget scan and GPS interaction, and cache trait lookup for a slight performance boost --- OpenRA.Game/Traits/TraitsInterfaces.cs | 2 ++ OpenRA.Game/Traits/World/Shroud.cs | 14 ++++++++++- OpenRA.Mods.RA/Activities/Attack.cs | 2 +- OpenRA.Mods.RA/AutoTarget.cs | 23 +++++-------------- OpenRA.Mods.RA/Crates/HideMapCrateAction.cs | 10 ++++---- OpenRA.Mods.RA/InfiltrateForExploration.cs | 4 ++-- OpenRA.Mods.RA/OpenRA.Mods.RA.csproj | 7 ------ OpenRA.Mods.RA/PlayerExts.cs | 22 ------------------ .../SupportPowers/ChronoshiftPower.cs | 8 +++---- OpenRA.Mods.RA/SupportPowers/GpsPower.cs | 7 +++++- 10 files changed, 39 insertions(+), 60 deletions(-) delete mode 100644 OpenRA.Mods.RA/PlayerExts.cs diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index cfa990b7e0..2f1b8f730e 100755 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -112,6 +112,8 @@ namespace OpenRA.Traits } public interface IVisibilityModifier { bool IsVisible(Actor self, Player byPlayer); } + public interface IFogVisibilityModifier { bool HasFogVisibility(Player byPlayer); } + public interface IRadarColorModifier { Color RadarColorOverride(Actor self); } public interface IOccupySpaceInfo { } diff --git a/OpenRA.Game/Traits/World/Shroud.cs b/OpenRA.Game/Traits/World/Shroud.cs index 8c8665a15e..c4804e535e 100644 --- a/OpenRA.Game/Traits/World/Shroud.cs +++ b/OpenRA.Game/Traits/World/Shroud.cs @@ -31,6 +31,8 @@ namespace OpenRA.Traits int[,] generatedShroudCount; bool[,] explored; + readonly Lazy fogVisibilities; + // Cache of visibility that was added, so no matter what crazy trait code does, it // can't make us invalid. Dictionary visibility = new Dictionary(); @@ -57,6 +59,8 @@ namespace OpenRA.Traits if (!self.World.LobbyInfo.GlobalSettings.Shroud) ExploredBounds = map.Bounds; + + fogVisibilities = Exts.Lazy(() => self.TraitsImplementing().ToArray()); } void Invalidate() @@ -278,10 +282,18 @@ namespace OpenRA.Traits public bool IsTargetable(Actor a) { + if (HasFogVisibility()) + return true; + if (a.TraitsImplementing().Any(t => !t.IsVisible(a, self.Owner))) return false; - return GetVisOrigins(a).Any(o => IsVisible(o)); + return GetVisOrigins(a).Any(IsVisible); + } + + public bool HasFogVisibility() + { + return fogVisibilities.Value.Any(f => f.HasFogVisibility(self.Owner)); } } } diff --git a/OpenRA.Mods.RA/Activities/Attack.cs b/OpenRA.Mods.RA/Activities/Attack.cs index 90efafca78..cf2958cc86 100755 --- a/OpenRA.Mods.RA/Activities/Attack.cs +++ b/OpenRA.Mods.RA/Activities/Attack.cs @@ -53,7 +53,7 @@ namespace OpenRA.Mods.RA.Activities return NextActivity; // TODO: This is horrible, and probably wrong. Work out what it is trying to solve, then redo it properly. - if (type == TargetType.Actor && !self.Owner.HasFogVisibility() && Target.Actor.HasTrait() && !self.Owner.Shroud.IsTargetable(Target.Actor)) + if (type == TargetType.Actor && Target.Actor.HasTrait() && !self.Owner.Shroud.IsTargetable(Target.Actor)) return NextActivity; if (!Target.IsInRange(self.CenterPosition, Range)) diff --git a/OpenRA.Mods.RA/AutoTarget.cs b/OpenRA.Mods.RA/AutoTarget.cs index 90634ee032..15d9bfed4b 100644 --- a/OpenRA.Mods.RA/AutoTarget.cs +++ b/OpenRA.Mods.RA/AutoTarget.cs @@ -147,23 +147,12 @@ namespace OpenRA.Mods.RA nextScanTime = self.World.SharedRandom.Next(info.MinimumScanTimeInterval, info.MaximumScanTimeInterval); var inRange = self.World.FindActorsInCircle(self.CenterPosition, range); - if (self.Owner.HasFogVisibility()) - { - return inRange - .Where(a => a.AppearsHostileTo(self)) - .Where(a => !a.HasTrait()) - .Where(a => attack.HasAnyValidWeapons(Target.FromActor(a))) - .ClosestTo(self); - } - else - { - return inRange - .Where(a => a.AppearsHostileTo(self)) - .Where(a => !a.HasTrait()) - .Where(a => attack.HasAnyValidWeapons(Target.FromActor(a))) - .Where(a => self.Owner.Shroud.IsTargetable(a)) - .ClosestTo(self); - } + return inRange + .Where(a => a.AppearsHostileTo(self)) + .Where(a => !a.HasTrait()) + .Where(a => attack.HasAnyValidWeapons(Target.FromActor(a))) + .Where(a => self.Owner.Shroud.IsTargetable(a)) + .ClosestTo(self); } } diff --git a/OpenRA.Mods.RA/Crates/HideMapCrateAction.cs b/OpenRA.Mods.RA/Crates/HideMapCrateAction.cs index 4f2f6a7587..70574406e9 100644 --- a/OpenRA.Mods.RA/Crates/HideMapCrateAction.cs +++ b/OpenRA.Mods.RA/Crates/HideMapCrateAction.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * 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, @@ -18,15 +18,15 @@ namespace OpenRA.Mods.RA class HideMapCrateAction : CrateAction { public HideMapCrateAction(Actor self, HideMapCrateActionInfo info) - : base(self, info) {} + : base(self, info) { } - public override int GetSelectionShares (Actor collector) + public override int GetSelectionShares(Actor collector) { // don't ever hide the map for people who have GPS. - if (collector.Owner.HasFogVisibility()) + if (collector.Owner.Shroud.HasFogVisibility()) return 0; - return base.GetSelectionShares (collector); + return base.GetSelectionShares(collector); } public override void Activate(Actor collector) diff --git a/OpenRA.Mods.RA/InfiltrateForExploration.cs b/OpenRA.Mods.RA/InfiltrateForExploration.cs index 42d8a0443f..ca35243319 100644 --- a/OpenRA.Mods.RA/InfiltrateForExploration.cs +++ b/OpenRA.Mods.RA/InfiltrateForExploration.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * 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, @@ -20,7 +20,7 @@ namespace OpenRA.Mods.RA { // Steal and reset the owners exploration infiltrator.Owner.Shroud.Explore(self.Owner.Shroud); - if (!self.Owner.HasFogVisibility()) + if (!self.Owner.Shroud.HasFogVisibility()) self.Owner.Shroud.ResetExploration(); } } diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index ec9d881bfa..fba7ca004f 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -304,7 +304,6 @@ - @@ -572,10 +571,4 @@ cd "$(SolutionDir)thirdparty/" copy "FuzzyLogicLibrary.dll" "$(SolutionDir)" cd "$(SolutionDir)" - - - - - - \ No newline at end of file diff --git a/OpenRA.Mods.RA/PlayerExts.cs b/OpenRA.Mods.RA/PlayerExts.cs deleted file mode 100644 index 84d2248d28..0000000000 --- a/OpenRA.Mods.RA/PlayerExts.cs +++ /dev/null @@ -1,22 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2011 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 - -namespace OpenRA.Mods.RA -{ - public static class PlayerExts - { - public static bool HasFogVisibility( this Player a ) - { - var gpsWatcher = a.PlayerActor.TraitOrDefault(); - return gpsWatcher != null && (gpsWatcher.Granted || gpsWatcher.GrantedAllies); - } - - } -} \ No newline at end of file diff --git a/OpenRA.Mods.RA/SupportPowers/ChronoshiftPower.cs b/OpenRA.Mods.RA/SupportPowers/ChronoshiftPower.cs index f672495fe4..1221d8e1cf 100644 --- a/OpenRA.Mods.RA/SupportPowers/ChronoshiftPower.cs +++ b/OpenRA.Mods.RA/SupportPowers/ChronoshiftPower.cs @@ -145,7 +145,7 @@ namespace OpenRA.Mods.RA var xy = wr.Position(wr.Viewport.ViewToWorldPx(Viewport.LastMousePos)).ToCPos(); var targetUnits = power.UnitsInRange(xy); foreach (var unit in targetUnits) - if (manager.self.Owner.Shroud.IsTargetable(unit) || manager.self.Owner.HasFogVisibility()) + if (manager.self.Owner.Shroud.IsTargetable(unit)) wr.DrawSelectionBox(unit, Color.Red); } @@ -224,7 +224,7 @@ namespace OpenRA.Mods.RA public void RenderAfterWorld(WorldRenderer wr, World world) { foreach (var unit in power.UnitsInRange(sourceLocation)) - if (manager.self.Owner.Shroud.IsTargetable(unit) || manager.self.Owner.HasFogVisibility()) + if (manager.self.Owner.Shroud.IsTargetable(unit)) wr.DrawSelectionBox(unit, Color.Red); } @@ -256,8 +256,8 @@ namespace OpenRA.Mods.RA if (manager.self.Owner.Shroud.IsTargetable(unit)) { var targetCell = unit.Location + (xy - sourceLocation); - var canEnter = ((manager.self.Owner.Shroud.IsExplored(targetCell) || manager.self.Owner.HasFogVisibility()) && - unit.Trait().CanChronoshiftTo(unit,targetCell)); + var canEnter = manager.self.Owner.Shroud.IsExplored(targetCell) && + unit.Trait().CanChronoshiftTo(unit, targetCell); var tile = canEnter ? validTile : invalidTile; yield return new SpriteRenderable(tile, targetCell.CenterPosition, WVec.Zero, -511, pal, 1f, true); } diff --git a/OpenRA.Mods.RA/SupportPowers/GpsPower.cs b/OpenRA.Mods.RA/SupportPowers/GpsPower.cs index 3fba6985f6..9fbc2f3ea3 100755 --- a/OpenRA.Mods.RA/SupportPowers/GpsPower.cs +++ b/OpenRA.Mods.RA/SupportPowers/GpsPower.cs @@ -21,7 +21,7 @@ namespace OpenRA.Mods.RA public object Create (ActorInitializer init) { return new GpsWatcher(init.self.Owner); } } - class GpsWatcher : ISync + class GpsWatcher : ISync, IFogVisibilityModifier { [Sync] bool Launched = false; [Sync] public bool GrantedAllies = false; @@ -73,6 +73,11 @@ namespace OpenRA.Mods.RA if (Granted || GrantedAllies) owner.Shroud.ExploreAll(owner.World); } + + public bool HasFogVisibility(Player byPlayer) + { + return Granted || GrantedAllies; + } } class GpsPowerInfo : SupportPowerInfo