diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 1f7c1f0e4a..c6f8769867 100755 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -242,6 +242,7 @@ namespace OpenRA.Traits { string[] TargetTypes { get; } IEnumerable TargetableCells( Actor self ); + bool TargetableBy(Actor self, Actor byActor); } public interface INotifyKeyPress { bool KeyPressed(Actor self, KeyInput e); } diff --git a/OpenRA.Mods.RA/Activities/Attack.cs b/OpenRA.Mods.RA/Activities/Attack.cs index 260398684c..6d67f75f7c 100755 --- a/OpenRA.Mods.RA/Activities/Attack.cs +++ b/OpenRA.Mods.RA/Activities/Attack.cs @@ -19,12 +19,16 @@ namespace OpenRA.Mods.RA.Activities public class Attack : CancelableActivity { Target Target; + ITargetable targetable; int Range; bool AllowMovement; public Attack(Target target, int range, bool allowMovement) { Target = target; + if (target.IsActor) + targetable = target.Actor.TraitOrDefault(); + Range = range; AllowMovement = allowMovement; } @@ -50,6 +54,9 @@ namespace OpenRA.Mods.RA.Activities if (!Target.IsValid) return NextActivity; + if (targetable != null && !targetable.TargetableBy(Target.Actor, self)) + return NextActivity; + if (!Combat.IsInRange(self.CenterLocation, Range, Target)) return (AllowMovement) ? Util.SequenceActivities(self.Trait().MoveWithinRange(Target, Range), this) : NextActivity; diff --git a/OpenRA.Mods.RA/Air/TargetableAircraft.cs b/OpenRA.Mods.RA/Air/TargetableAircraft.cs index 197e38a1a0..28d8d3211e 100755 --- a/OpenRA.Mods.RA/Air/TargetableAircraft.cs +++ b/OpenRA.Mods.RA/Air/TargetableAircraft.cs @@ -25,7 +25,7 @@ namespace OpenRA.Mods.RA.Air { Aircraft Aircraft; public TargetableAircraft(Actor self, TargetableAircraftInfo info) - : base(info) + : base(self, info) { Aircraft = self.Trait(); } diff --git a/OpenRA.Mods.RA/AttackBase.cs b/OpenRA.Mods.RA/AttackBase.cs index 86d3200acf..7e3774805f 100644 --- a/OpenRA.Mods.RA/AttackBase.cs +++ b/OpenRA.Mods.RA/AttackBase.cs @@ -76,7 +76,11 @@ namespace OpenRA.Mods.RA if (!target.IsValid) return false; if (Weapons.All(w => w.IsReloading)) return false; if (self.TraitsImplementing().Any(d => d.Disabled)) return false; - + + if (target.IsActor && target.Actor.HasTrait() && + !target.Actor.Trait().TargetableBy(target.Actor,self)) + return false; + return true; } diff --git a/OpenRA.Mods.RA/Cloak.cs b/OpenRA.Mods.RA/Cloak.cs index d1be3a0f53..28bc698463 100644 --- a/OpenRA.Mods.RA/Cloak.cs +++ b/OpenRA.Mods.RA/Cloak.cs @@ -103,7 +103,10 @@ namespace OpenRA.Mods.RA public bool IsVisible(Actor self) { - return !Cloaked || self.Owner == self.World.LocalPlayer; + if (!Cloaked || self.Owner == self.World.LocalPlayer || self.Owner.Stances[self.World.LocalPlayer] == Stance.Ally) + return true; + + return self.World.Queries.WithTrait().Any(a => (self.Location - a.Actor.Location).Length < a.Actor.Info.Traits.Get().Range); } public Color RadarColorOverride(Actor self) diff --git a/OpenRA.Mods.RA/Crates/CloakCrateAction.cs b/OpenRA.Mods.RA/Crates/CloakCrateAction.cs index c295578b83..550d8e34b8 100644 --- a/OpenRA.Mods.RA/Crates/CloakCrateAction.cs +++ b/OpenRA.Mods.RA/Crates/CloakCrateAction.cs @@ -9,6 +9,7 @@ #endregion using OpenRA.FileFormats; +using OpenRA.Mods.RA; namespace OpenRA.Mods.RA.Crates { @@ -44,7 +45,11 @@ namespace OpenRA.Mods.RA.Crates collector.World.AddFrameEndTask(w => { w.Remove(collector); + collector.AddTrait(cloak); + if (collector.HasTrait>()) + collector.Trait>().RecievedCloak(collector); + w.Add(collector); }); diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 5d4a96e53b..3cead6e810 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -294,7 +294,6 @@ - @@ -324,6 +323,7 @@ + diff --git a/OpenRA.Mods.RA/TargetableBuilding.cs b/OpenRA.Mods.RA/TargetableBuilding.cs index 5b217587bc..e27801bd8d 100755 --- a/OpenRA.Mods.RA/TargetableBuilding.cs +++ b/OpenRA.Mods.RA/TargetableBuilding.cs @@ -29,7 +29,7 @@ namespace OpenRA.Mods.RA } public string[] TargetTypes { get { return info.TargetTypes; } } - + public bool TargetableBy(Actor self, Actor byActor) { return true; } public IEnumerable TargetableCells( Actor self ) { return self.Trait().OccupiedCells(); diff --git a/OpenRA.Mods.RA/TargetableCloaked.cs b/OpenRA.Mods.RA/TargetableCloaked.cs deleted file mode 100644 index 6bc162c62a..0000000000 --- a/OpenRA.Mods.RA/TargetableCloaked.cs +++ /dev/null @@ -1,46 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2010 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 LICENSE. - */ -#endregion - -using System.Linq; -using OpenRA.Traits; - -namespace OpenRA.Mods.RA -{ - public class TargetableCloakedInfo : TargetableUnitInfo, ITraitPrerequisite - { - public readonly string[] CloakedTargetTypes = {}; - public override object Create( ActorInitializer init ) { return new TargetableCloaked(init.self, this); } - } - - public class TargetableCloaked : TargetableUnit - { - Cloak Cloak; - public TargetableCloaked(Actor self, TargetableCloakedInfo info) - : base(info) - { - Cloak = self.Trait(); - } - - public override string[] TargetTypes - { - get { return (Cloak.Cloaked) ? info.CloakedTargetTypes - : info.TargetTypes;} - } - - // Todo: Finish me - public bool TargetableBy(Actor self, Actor byActor) - { - if (!Cloak.Cloaked || self.Owner == byActor.Owner || self.Owner.Stances[byActor.Owner] == Stance.Ally) - return true; - - return self.World.Queries.WithTrait().Any(a => (self.Location - a.Actor.Location).Length < a.Actor.Info.Traits.Get().Range); - } - } -} diff --git a/OpenRA.Mods.RA/TargetableSubmarine.cs b/OpenRA.Mods.RA/TargetableSubmarine.cs new file mode 100644 index 0000000000..80491ff7d3 --- /dev/null +++ b/OpenRA.Mods.RA/TargetableSubmarine.cs @@ -0,0 +1,33 @@ +#region Copyright & License Information +/* + * Copyright 2007-2010 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 LICENSE. + */ +#endregion + +using System.Linq; +using OpenRA.Traits; + +namespace OpenRA.Mods.RA +{ + public class TargetableSubmarineInfo : TargetableUnitInfo, ITraitPrerequisite + { + public readonly string[] CloakedTargetTypes = {}; + public override object Create( ActorInitializer init ) { return new TargetableSubmarine(init.self, this); } + } + + public class TargetableSubmarine : TargetableUnit + { + public TargetableSubmarine(Actor self, TargetableSubmarineInfo info) + : base(self, info) {} + + public override string[] TargetTypes + { + get { return (Cloak.Cloaked) ? info.CloakedTargetTypes + : info.TargetTypes;} + } + } +} diff --git a/OpenRA.Mods.RA/TargetableUnit.cs b/OpenRA.Mods.RA/TargetableUnit.cs index 0b736bcfc5..708ed4253e 100755 --- a/OpenRA.Mods.RA/TargetableUnit.cs +++ b/OpenRA.Mods.RA/TargetableUnit.cs @@ -19,16 +19,36 @@ namespace OpenRA.Mods.RA public class TargetableUnitInfo : ITraitInfo { public readonly string[] TargetTypes = { }; - public virtual object Create( ActorInitializer init ) { return new TargetableUnit( this ); } + public virtual object Create( ActorInitializer init ) { return new TargetableUnit( init.self, this ); } } public class TargetableUnit : ITargetable where Info : TargetableUnitInfo { protected readonly Info info; - public TargetableUnit( Info info ) + protected Cloak Cloak; + + public TargetableUnit( Actor self, Info info ) { this.info = info; + RecievedCloak(self); + } + + // Arbitrary units can recieve cloak via a crate during gameplay + public void RecievedCloak(Actor self) + { + Cloak = self.TraitOrDefault(); + } + + public virtual bool TargetableBy(Actor self, Actor byActor) + { + if (Cloak == null) + return true; + + if (!Cloak.Cloaked || self.Owner == byActor.Owner || self.Owner.Stances[byActor.Owner] == Stance.Ally) + return true; + + return self.World.Queries.WithTrait().Any(a => (self.Location - a.Actor.Location).Length < a.Actor.Info.Traits.Get().Range); } public virtual string[] TargetTypes { get { return info.TargetTypes; } } diff --git a/mods/cnc/rules/structures.yaml b/mods/cnc/rules/structures.yaml index 75372668e2..7e3730abb6 100644 --- a/mods/cnc/rules/structures.yaml +++ b/mods/cnc/rules/structures.yaml @@ -300,6 +300,7 @@ HQ: Range: 10 Bib: ProvidesRadar: + RenderDetectionCircle: DetectCloaked: Range: 8 @@ -414,6 +415,9 @@ EYE: Range: 10 Bib: ProvidesRadar: + RenderDetectionCircle: + DetectCloaked: + Range: 8 IonControl: TMPL: @@ -480,6 +484,9 @@ OBLI: -RenderBuilding: RenderRangeCircle: -EmitInfantryOnSell: + RenderDetectionCircle: + DetectCloaked: + Range: 6 CYCL: Inherits: ^Wall @@ -574,7 +581,9 @@ GUN: -RenderBuilding: -DeadBuildingState: RenderRangeCircle: - + RenderDetectionCircle: + DetectCloaked: + Range: 3 SAM: Inherits: ^Building Valued: @@ -633,6 +642,7 @@ GTWR: AutoTarget: DetectCloaked: Range: 3 + RenderDetectionCircle: RenderRangeCircle: ATWR: @@ -660,6 +670,7 @@ ATWR: PrimaryWeapon: Tomahawk SecondaryWeapon: Tomahawk AutoTarget: + RenderDetectionCircle: DetectCloaked: Range: 6 RenderRangeCircle: diff --git a/mods/cnc/rules/system.yaml b/mods/cnc/rules/system.yaml index 102f5b6c3e..4b358a5659 100644 --- a/mods/cnc/rules/system.yaml +++ b/mods/cnc/rules/system.yaml @@ -211,8 +211,8 @@ CRATE: SelectionShares: 5 CloakCrateAction: SelectionShares: 5 - InitialDelay: .4 - CloakDelay: 2.0 + InitialDelay: 5 + CloakDelay: 5 CloakSound: appear1.aud UncloakSound: appear1.aud Effect: stealth diff --git a/mods/cnc/rules/vehicles.yaml b/mods/cnc/rules/vehicles.yaml index 638d1d3cf7..52a7b6bb9b 100644 --- a/mods/cnc/rules/vehicles.yaml +++ b/mods/cnc/rules/vehicles.yaml @@ -438,17 +438,15 @@ STNK: RevealsShroud: Range: 4 Cloak: - InitialDelay: 0 - CloakDelay: 2.0 + InitialDelay: 5 + CloakDelay: 5 CloakSound: appear1.aud UncloakSound: appear1.aud AttackFrontal: PrimaryWeapon: 227mm RenderUnit: AutoTarget: - -TargetableUnit: - TargetableCloaked: - CloakedTargetTypes: cloaked + TargetableUnit: TRAN: Inherits: ^Helicopter diff --git a/mods/ra/rules/vehicles.yaml b/mods/ra/rules/vehicles.yaml index 07132c9255..2a7fef56d6 100644 --- a/mods/ra/rules/vehicles.yaml +++ b/mods/ra/rules/vehicles.yaml @@ -495,7 +495,7 @@ SS: RevealsShroud: Range: 6 -TargetableUnit: - TargetableCloaked: + TargetableSubmarine: TargetTypes: Ground, Water CloakedTargetTypes: Underwater RenderUnit: @@ -538,7 +538,7 @@ MSUB: Range: 6 RenderUnit: -TargetableUnit: - TargetableCloaked: + TargetableSubmarine: TargetTypes: Ground, Water CloakedTargetTypes: Underwater Cloak: