From 87580d0aab65f9f88670c0910677e1735d00b729 Mon Sep 17 00:00:00 2001 From: abcdefg30 Date: Sat, 22 Aug 2015 21:36:30 +0200 Subject: [PATCH] Add a GpsRemoveFrozenActor trait --- OpenRA.Game/Traits/Player/FrozenActorLayer.cs | 18 +++++- OpenRA.Game/Traits/TraitsInterfaces.cs | 5 ++ OpenRA.Mods.RA/OpenRA.Mods.RA.csproj | 1 + OpenRA.Mods.RA/Traits/GpsRemoveFrozenActor.cs | 55 +++++++++++++++++++ .../Traits/SupportPowers/GpsPower.cs | 14 ++--- mods/ra/rules/defaults.yaml | 2 + 6 files changed, 86 insertions(+), 9 deletions(-) create mode 100644 OpenRA.Mods.RA/Traits/GpsRemoveFrozenActor.cs diff --git a/OpenRA.Game/Traits/Player/FrozenActorLayer.cs b/OpenRA.Game/Traits/Player/FrozenActorLayer.cs index d68bcb0d33..384de66273 100644 --- a/OpenRA.Game/Traits/Player/FrozenActorLayer.cs +++ b/OpenRA.Game/Traits/Player/FrozenActorLayer.cs @@ -27,6 +27,7 @@ namespace OpenRA.Traits public readonly PPos[] Footprint; public readonly WPos CenterPosition; public readonly Rectangle Bounds; + readonly IRemoveFrozenActor[] removeFrozenActors; readonly Actor actor; readonly Shroud shroud; @@ -46,6 +47,7 @@ namespace OpenRA.Traits { actor = self; this.shroud = shroud; + removeFrozenActors = self.TraitsImplementing().ToArray(); // Consider all cells inside the map area (ignoring the current map bounds) Footprint = footprint @@ -127,6 +129,16 @@ namespace OpenRA.Traits public bool HasRenderables { get { return renderables.Any(); } } + public bool ShouldBeRemoved(Player owner) + { + // We use a loop here for performance reasons + foreach (var rfa in removeFrozenActors) + if (rfa.RemoveActor(actor, owner)) + return true; + + return false; + } + public override string ToString() { return "{0} {1}{2}".F(Info.Name, ID, IsValid ? "" : " (invalid)"); @@ -140,7 +152,7 @@ namespace OpenRA.Traits readonly World world; readonly Player owner; - Dictionary frozen; + readonly Dictionary frozen; public FrozenActorLayer(Actor self) { @@ -169,7 +181,9 @@ namespace OpenRA.Traits var frozenActor = kvp.Value; frozenActor.Tick(); - if (frozenActor.Visible) + if (frozenActor.ShouldBeRemoved(owner)) + remove.Add(kvp.Key); + else if (frozenActor.Visible) VisibilityHash += hash; else if (frozenActor.Actor == null) remove.Add(kvp.Key); diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 0fb00d6296..a02380d078 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -369,4 +369,9 @@ namespace OpenRA.Traits bool IsValidAgainst(FrozenActor victim, Actor firedBy); void DoImpact(Target target, Actor firedBy, IEnumerable damageModifiers); } + + public interface IRemoveFrozenActor + { + bool RemoveActor(Actor self, Player owner); + } } diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 61290d4564..37f7fb9e3f 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -92,6 +92,7 @@ + diff --git a/OpenRA.Mods.RA/Traits/GpsRemoveFrozenActor.cs b/OpenRA.Mods.RA/Traits/GpsRemoveFrozenActor.cs new file mode 100644 index 0000000000..3b432096ff --- /dev/null +++ b/OpenRA.Mods.RA/Traits/GpsRemoveFrozenActor.cs @@ -0,0 +1,55 @@ +#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.Traits; + +namespace OpenRA.Mods.RA.Traits +{ + [Desc("Removes frozen actors of actors that are dead or sold," + + " when having an active GPS power.")] + public class GpsRemoveFrozenActorInfo : ITraitInfo + { + [Desc("Should this trait also affect allied players?")] + public bool GrantAllies = true; + + public object Create(ActorInitializer init) { return new GpsRemoveFrozenActor(init.Self, this); } + } + + public class GpsRemoveFrozenActor : IRemoveFrozenActor + { + readonly GpsWatcher[] watchers; + readonly GpsRemoveFrozenActorInfo info; + + public GpsRemoveFrozenActor(Actor self, GpsRemoveFrozenActorInfo info) + { + this.info = info; + watchers = self.World.ActorsWithTrait().Select(w => w.Trait).ToArray(); + } + + public bool RemoveActor(Actor self, Player owner) + { + if (!self.IsDead) + return false; + + foreach (var w in watchers) + { + if (w.Owner != owner && !(info.GrantAllies && w.Owner.IsAlliedWith(owner))) + continue; + + if (w.Launched) + return true; + } + + return false; + } + } +} diff --git a/OpenRA.Mods.RA/Traits/SupportPowers/GpsPower.cs b/OpenRA.Mods.RA/Traits/SupportPowers/GpsPower.cs index 8ef924c0c9..aae043ce91 100644 --- a/OpenRA.Mods.RA/Traits/SupportPowers/GpsPower.cs +++ b/OpenRA.Mods.RA/Traits/SupportPowers/GpsPower.cs @@ -25,14 +25,14 @@ namespace OpenRA.Mods.RA.Traits class GpsWatcher : ISync, IFogVisibilityModifier { - [Sync] bool launched = false; + [Sync] public bool Launched = false; [Sync] public bool GrantedAllies = false; [Sync] public bool Granted = false; - Player owner; + public Player Owner; List actors = new List { }; - public GpsWatcher(Player owner) { this.owner = owner; } + public GpsWatcher(Player owner) { Owner = owner; } public void GpsRem(Actor atek) { @@ -51,7 +51,7 @@ namespace OpenRA.Mods.RA.Traits atek.World.Add(new DelayedAction(((GpsPowerInfo)info).RevealDelay * 25, () => { - launched = true; + Launched = true; RefreshGps(atek); })); } @@ -69,11 +69,11 @@ namespace OpenRA.Mods.RA.Traits void RefreshGranted() { - Granted = actors.Count > 0 && launched; - GrantedAllies = owner.World.ActorsWithTrait().Any(p => p.Actor.Owner.IsAlliedWith(owner) && p.Trait.Granted); + Granted = actors.Count > 0 && Launched; + GrantedAllies = Owner.World.ActorsWithTrait().Any(p => p.Actor.Owner.IsAlliedWith(Owner) && p.Trait.Granted); if (Granted || GrantedAllies) - owner.Shroud.ExploreAll(owner.World); + Owner.Shroud.ExploreAll(Owner.World); } public bool HasFogVisibility(Player byPlayer) diff --git a/mods/ra/rules/defaults.yaml b/mods/ra/rules/defaults.yaml index 674d507b06..268d1ebe2f 100644 --- a/mods/ra/rules/defaults.yaml +++ b/mods/ra/rules/defaults.yaml @@ -400,6 +400,7 @@ Guardable: Range: 3 FrozenUnderFog: + GpsRemoveFrozenActor: Tooltip: GenericName: Structure Demolishable: @@ -461,6 +462,7 @@ Guardable: BodyOrientation: FrozenUnderFog: + GpsRemoveFrozenActor: ScriptTriggers: ^TechBuilding: