diff --git a/OpenRA.Mods.RA/Cloak.cs b/OpenRA.Mods.RA/Cloak.cs index 53c98e142c..7e6aecd82e 100644 --- a/OpenRA.Mods.RA/Cloak.cs +++ b/OpenRA.Mods.RA/Cloak.cs @@ -22,6 +22,7 @@ namespace OpenRA.Mods.RA public readonly int InitialDelay = 10; // Ticks public readonly int CloakDelay = 30; // Ticks public readonly bool UncloakOnMove = false; + public readonly bool RequiresCrate = false; public readonly string CloakSound = "subshow1.aud"; public readonly string UncloakSound = "subshow1.aud"; @@ -33,7 +34,8 @@ namespace OpenRA.Mods.RA public class Cloak : IRenderModifier, INotifyDamageStateChanged, INotifyAttack, ITick, IVisibilityModifier, IRadarColorModifier, ISync { [Sync] int remainingTime; - [Sync] bool canCloak = true; + [Sync] bool damageDisabled; + [Sync] bool crateDisabled; Actor self; CloakInfo info; @@ -45,6 +47,7 @@ namespace OpenRA.Mods.RA this.self = self; remainingTime = info.InitialDelay; + crateDisabled = info.RequiresCrate; } public void Uncloak() { Uncloak(info.CloakDelay); } @@ -63,8 +66,8 @@ namespace OpenRA.Mods.RA public void DamageStateChanged(Actor self, AttackInfo e) { - canCloak = e.DamageState < DamageState.Critical; - if (!canCloak) + damageDisabled = e.DamageState >= DamageState.Critical; + if (damageDisabled) Uncloak(); } @@ -84,7 +87,7 @@ namespace OpenRA.Mods.RA public void Tick(Actor self) { - if (remainingTime > 0 && canCloak && --remainingTime <= 0) + if (remainingTime > 0 && !crateDisabled && !damageDisabled && --remainingTime <= 0) { self.Generation++; Sound.Play(info.CloakSound, self.CenterPosition); @@ -118,5 +121,12 @@ namespace OpenRA.Mods.RA c = Color.FromArgb(128, c); return c; } + + public bool AcceptsCloakCrate { get { return info.RequiresCrate && crateDisabled; } } + + public void ReceivedCloakCrate(Actor self) + { + crateDisabled = false; + } } } diff --git a/OpenRA.Mods.RA/Crates/CloakCrateAction.cs b/OpenRA.Mods.RA/Crates/CloakCrateAction.cs index e7b7498685..4095eda5a0 100644 --- a/OpenRA.Mods.RA/Crates/CloakCrateAction.cs +++ b/OpenRA.Mods.RA/Crates/CloakCrateAction.cs @@ -16,52 +16,27 @@ namespace OpenRA.Mods.RA.Crates { public class CloakCrateActionInfo : CrateActionInfo { - public readonly int InitialDelay = 10; - public readonly int CloakDelay = 30; - public readonly string CloakSound = "subshow1.aud"; - public readonly string UncloakSound = "subshow1.aud"; - public override object Create(ActorInitializer init) { return new CloakCrateAction(init.self, this); } } public class CloakCrateAction : CrateAction { - CloakCrateActionInfo Info; public CloakCrateAction(Actor self, CloakCrateActionInfo info) - : base(self, info) { Info = info; } + : base(self, info) { } public override int GetSelectionShares(Actor collector) { - return collector.HasTrait() && !collector.HasTrait() - ? base.GetSelectionShares(collector) : 0; + var cloak = collector.TraitOrDefault(); + if (cloak == null || !cloak.AcceptsCloakCrate) + return 0; + + return base.GetSelectionShares(collector); } public override void Activate(Actor collector) { - var cloakInfo = new CloakInfo() - { - InitialDelay = Info.InitialDelay, - CloakDelay = Info.CloakDelay, - CloakSound = Info.CloakSound, - UncloakSound = Info.UncloakSound - }; - var cloak = new Cloak(collector, cloakInfo); - - collector.World.AddFrameEndTask(w => - { - w.Remove(collector); - - collector.AddTrait(cloak); - var t = collector.TraitOrDefault(); - if (t != null) t.ReceivedCloak(collector); - - w.Add(collector); - }); - + collector.Trait().ReceivedCloakCrate(collector); base.Activate(collector); } } - - public class AcceptsCloakCrateInfo : TraitInfo {} - public class AcceptsCloakCrate {} } diff --git a/OpenRA.Mods.RA/Effects/GpsDot.cs b/OpenRA.Mods.RA/Effects/GpsDot.cs index d336e46b65..af225b5740 100644 --- a/OpenRA.Mods.RA/Effects/GpsDot.cs +++ b/OpenRA.Mods.RA/Effects/GpsDot.cs @@ -36,6 +36,7 @@ namespace OpenRA.Mods.RA.Effects Lazy huf; Lazy fuf; Lazy spy; + Lazy cloak; Cache watcher; Cache frozen; @@ -53,15 +54,15 @@ namespace OpenRA.Mods.RA.Effects huf = Lazy.New(() => self.TraitOrDefault()); fuf = Lazy.New(() => self.TraitOrDefault()); spy = Lazy.New(() => self.TraitOrDefault()); + cloak = Lazy.New(() => self.TraitOrDefault()); + watcher = new Cache(p => p.PlayerActor.Trait()); frozen = new Cache(p => p.PlayerActor.Trait()); } bool ShouldShowIndicator() { - // Can be granted at runtime via a crate, so can't cache - var cloak = self.TraitOrDefault(); - if (cloak != null && cloak.Cloaked) + if (cloak.Value != null && cloak.Value.Cloaked) return false; if (spy.Value != null && spy.Value.Disguised) diff --git a/OpenRA.Mods.RA/TargetableUnit.cs b/OpenRA.Mods.RA/TargetableUnit.cs index 195e8226c7..5797c19f92 100755 --- a/OpenRA.Mods.RA/TargetableUnit.cs +++ b/OpenRA.Mods.RA/TargetableUnit.cs @@ -30,12 +30,6 @@ namespace OpenRA.Mods.RA public TargetableUnit(Actor self, TargetableUnitInfo info) { this.info = info; - ReceivedCloak(self); - } - - // Arbitrary units can receive cloak via a crate during gameplay - public void ReceivedCloak(Actor self) - { cloak = self.TraitOrDefault(); } diff --git a/mods/cnc/rules/defaults.yaml b/mods/cnc/rules/defaults.yaml index f110faa08f..38686db5c4 100644 --- a/mods/cnc/rules/defaults.yaml +++ b/mods/cnc/rules/defaults.yaml @@ -28,13 +28,18 @@ DrawLineToTarget: ActorLostNotification: AttackMove: - AcceptsCloakCrate: WithSmoke: DebugMuzzlePositions: Guard: Guardable: BodyOrientation: UpdatesPlayerStatistics: + Cloak: + RequiresCrate: true + InitialDelay: 15 + CloakDelay: 90 + CloakSound: trans1.aud + UncloakSound: trans1.aud ^Tank: AppearsOnRadar: @@ -66,7 +71,6 @@ DrawLineToTarget: ActorLostNotification: AttackMove: - AcceptsCloakCrate: WithSmoke: Explodes: Weapon: UnitExplodeSmall @@ -76,6 +80,12 @@ Guardable: BodyOrientation: UpdatesPlayerStatistics: + Cloak: + RequiresCrate: true + InitialDelay: 15 + CloakDelay: 90 + CloakSound: trans1.aud + UncloakSound: trans1.aud ^Helicopter: AppearsOnRadar: diff --git a/mods/cnc/rules/system.yaml b/mods/cnc/rules/system.yaml index f3a5eabfbb..5bfd668932 100644 --- a/mods/cnc/rules/system.yaml +++ b/mods/cnc/rules/system.yaml @@ -393,10 +393,6 @@ CRATE: SelectionShares: 5 CloakCrateAction: SelectionShares: 5 - InitialDelay: 15 - CloakDelay: 90 - CloakSound: trans1.aud - UncloakSound: trans1.aud Effect: cloak GiveMcvCrateAction: SelectionShares: 0 diff --git a/mods/cnc/rules/vehicles.yaml b/mods/cnc/rules/vehicles.yaml index b0c4050320..b9ee9338e5 100644 --- a/mods/cnc/rules/vehicles.yaml +++ b/mods/cnc/rules/vehicles.yaml @@ -33,7 +33,7 @@ MCV: LeavesHusk: HuskActor: MCV.Husk -GainsExperience: - -AcceptsCloakCrate: + -Cloak: Explodes: Weapon: UnitExplodeSmall EmptyWeapon: UnitExplodeSmall @@ -519,6 +519,7 @@ STNK: RevealsShroud: Range: 7 Cloak: + RequiresCrate: false InitialDelay: 90 CloakDelay: 90 CloakSound: trans1.aud diff --git a/mods/d2k/rules/system.yaml b/mods/d2k/rules/system.yaml index 23c0048411..565c0a58c9 100644 --- a/mods/d2k/rules/system.yaml +++ b/mods/d2k/rules/system.yaml @@ -554,13 +554,6 @@ CRATE: SelectionShares: 0 NoBaseSelectionShares: 9001 Unit: mcvo - CloakCrateAction: - SelectionShares: 15 - InitialDelay: 15 - CloakDelay: 90 - CloakSound: STEALTH1.WAV - UncloakSound: STEALTH2.WAV - Effect: cloak RenderSimple: ProximityCaptor: Types:Crate