diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 10da51510c..954d81e524 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -108,6 +108,7 @@ + diff --git a/OpenRA.Mods.RA/Traits/GpsWatcher.cs b/OpenRA.Mods.RA/Traits/GpsWatcher.cs new file mode 100644 index 0000000000..e64fcc901b --- /dev/null +++ b/OpenRA.Mods.RA/Traits/GpsWatcher.cs @@ -0,0 +1,113 @@ +#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.Linq; +using OpenRA.Effects; +using OpenRA.Mods.Common.Traits; +using OpenRA.Mods.RA.Effects; +using OpenRA.Traits; + +namespace OpenRA.Mods.RA.Traits +{ + [Desc("Required for GpsPower. Attach this to the player actor.")] + class GpsWatcherInfo : ITraitInfo + { + public object Create(ActorInitializer init) { return new GpsWatcher(init.Self.Owner); } + } + + interface IOnGpsRefreshed { void OnGpsRefresh(Actor self, Player player); } + + class GpsWatcher : ISync, IFogVisibilityModifier + { + [Sync] public bool Launched { get; private set; } + [Sync] public bool GrantedAllies { get; private set; } + [Sync] public bool Granted { get; private set; } + public readonly Player Owner; + + readonly List actors = new List(); + readonly HashSet> notifyOnRefresh = new HashSet>(); + + public GpsWatcher(Player owner) { Owner = owner; } + + public void GpsRem(Actor atek) + { + actors.Remove(atek); + RefreshGps(atek); + } + + public void GpsAdd(Actor atek) + { + actors.Add(atek); + RefreshGps(atek); + } + + public void Launch(Actor atek, SupportPowerInfo info) + { + atek.World.Add(new DelayedAction(((GpsPowerInfo)info).RevealDelay * 25, + () => + { + Launched = true; + RefreshGps(atek); + })); + } + + public void RefreshGps(Actor atek) + { + RefreshGranted(); + + foreach (var i in atek.World.ActorsWithTrait()) + i.Trait.RefreshGranted(); + + if ((Granted || GrantedAllies) && atek.Owner.IsAlliedWith(Owner)) + atek.Owner.Shroud.ExploreAll(atek.World); + } + + void RefreshGranted() + { + var wasGranted = Granted; + var wasGrantedAllies = GrantedAllies; + + Granted = actors.Count > 0 && Launched; + GrantedAllies = Owner.World.ActorsHavingTrait(g => g.Granted).Any(p => p.Owner.IsAlliedWith(Owner)); + + if (Granted || GrantedAllies) + Owner.Shroud.ExploreAll(Owner.World); + + if (wasGranted != Granted || wasGrantedAllies != GrantedAllies) + foreach (var tp in notifyOnRefresh.ToList()) + tp.Trait.OnGpsRefresh(tp.Actor, Owner); + } + + public bool HasFogVisibility() + { + return Granted || GrantedAllies; + } + + public bool IsVisible(Actor actor) + { + var gpsDot = actor.TraitOrDefault(); + if (gpsDot == null) + return false; + + return gpsDot.IsDotVisible(Owner); + } + + public void RegisterForOnGpsRefreshed(Actor actor, IOnGpsRefreshed toBeNotified) + { + notifyOnRefresh.Add(new TraitPair(actor, toBeNotified)); + } + + public void UnregisterForOnGpsRefreshed(Actor actor, IOnGpsRefreshed toBeNotified) + { + notifyOnRefresh.Remove(new TraitPair(actor, toBeNotified)); + } + } +} diff --git a/OpenRA.Mods.RA/Traits/SupportPowers/GpsPower.cs b/OpenRA.Mods.RA/Traits/SupportPowers/GpsPower.cs index 8a5930dd1b..631ab2c928 100644 --- a/OpenRA.Mods.RA/Traits/SupportPowers/GpsPower.cs +++ b/OpenRA.Mods.RA/Traits/SupportPowers/GpsPower.cs @@ -17,100 +17,6 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Traits { - [Desc("Required for GpsPower. Attach this to the player actor.")] - class GpsWatcherInfo : ITraitInfo - { - public object Create(ActorInitializer init) { return new GpsWatcher(init.Self.Owner); } - } - - class GpsWatcher : ISync, IFogVisibilityModifier - { - [Sync] public bool Launched { get; private set; } - [Sync] public bool GrantedAllies { get; private set; } - [Sync] public bool Granted { get; private set; } - public readonly Player Owner; - - readonly List actors = new List(); - readonly HashSet> notifyOnRefresh = new HashSet>(); - - public GpsWatcher(Player owner) { Owner = owner; } - - public void GpsRem(Actor atek) - { - actors.Remove(atek); - RefreshGps(atek); - } - - public void GpsAdd(Actor atek) - { - actors.Add(atek); - RefreshGps(atek); - } - - public void Launch(Actor atek, SupportPowerInfo info) - { - atek.World.Add(new DelayedAction(((GpsPowerInfo)info).RevealDelay * 25, - () => - { - Launched = true; - RefreshGps(atek); - })); - } - - public void RefreshGps(Actor atek) - { - RefreshGranted(); - - foreach (var i in atek.World.ActorsWithTrait()) - i.Trait.RefreshGranted(); - - if ((Granted || GrantedAllies) && atek.Owner.IsAlliedWith(Owner)) - atek.Owner.Shroud.ExploreAll(atek.World); - } - - void RefreshGranted() - { - var wasGranted = Granted; - var wasGrantedAllies = GrantedAllies; - - Granted = actors.Count > 0 && Launched; - GrantedAllies = Owner.World.ActorsHavingTrait(g => g.Granted).Any(p => p.Owner.IsAlliedWith(Owner)); - - if (Granted || GrantedAllies) - Owner.Shroud.ExploreAll(Owner.World); - - if (wasGranted != Granted || wasGrantedAllies != GrantedAllies) - foreach (var tp in notifyOnRefresh.ToList()) - tp.Trait.OnGpsRefresh(tp.Actor, Owner); - } - - public bool HasFogVisibility() - { - return Granted || GrantedAllies; - } - - public bool IsVisible(Actor actor) - { - var gpsDot = actor.TraitOrDefault(); - if (gpsDot == null) - return false; - - return gpsDot.IsDotVisible(Owner); - } - - public void RegisterForOnGpsRefreshed(Actor actor, IOnGpsRefreshed toBeNotified) - { - notifyOnRefresh.Add(new TraitPair(actor, toBeNotified)); - } - - public void UnregisterForOnGpsRefreshed(Actor actor, IOnGpsRefreshed toBeNotified) - { - notifyOnRefresh.Remove(new TraitPair(actor, toBeNotified)); - } - } - - interface IOnGpsRefreshed { void OnGpsRefresh(Actor self, Player player); } - class GpsPowerInfo : SupportPowerInfo { public readonly int RevealDelay = 0;