diff --git a/OpenRa.Game/Actor.cs b/OpenRa.Game/Actor.cs index c35073408d..ef56cb64a3 100755 --- a/OpenRa.Game/Actor.cs +++ b/OpenRa.Game/Actor.cs @@ -73,7 +73,9 @@ namespace OpenRa.Game public IEnumerable> Render() { - return traits.WithInterface().SelectMany( x => x.Render( this ) ); + var mods = traits.WithInterface(); + var sprites = traits.WithInterface().SelectMany(x => x.Render(this)); + return mods.Aggregate(sprites, (m, p) => p.ModifyRender(this, m)); } public Order Order( int2 xy, MouseInput mi ) diff --git a/OpenRa.Game/Combat.cs b/OpenRa.Game/Combat.cs index 4f48f169bd..c5481ef6f4 100644 --- a/OpenRa.Game/Combat.cs +++ b/OpenRa.Game/Combat.cs @@ -56,7 +56,7 @@ namespace OpenRa.Game { var projectile = Rules.ProjectileInfo[weapon.Projectile]; - if (projectile.ASW && target.traits.Contains()) return true; + if (projectile.ASW && target.traits.Contains()) return true; if (projectile.AA && target.traits.Contains()) return true; if (projectile.UnderWater && !target.Info.WaterBound) return false; return projectile.AG; diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index 3ad7116d4a..bd1e25d090 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -175,7 +175,7 @@ - + diff --git a/OpenRa.Game/Traits/Cloak.cs b/OpenRa.Game/Traits/Cloak.cs new file mode 100644 index 0000000000..6d471512e9 --- /dev/null +++ b/OpenRa.Game/Traits/Cloak.cs @@ -0,0 +1,50 @@ +using System.Collections.Generic; +using System.Linq; +using OpenRa.Game.Graphics; + +namespace OpenRa.Game.Traits +{ + class Cloak : IRenderModifier, INotifyAttack, ITick + { + int remainingSurfaceTime = 2; /* setup for initial dive */ + + public Cloak(Actor self) {} + + public void Attacking(Actor self) + { + if (remainingSurfaceTime <= 0) + OnSurface(); + + remainingSurfaceTime = (int)(Rules.General.SubmergeDelay * 60 * 25); + } + + public IEnumerable> + ModifyRender(Actor self, IEnumerable> rs) + { + if (remainingSurfaceTime > 0) + return rs; + + if (self.Owner == Game.LocalPlayer) + return rs.Select(a => Tuple.New(a.a, a.b, 8)); + else + return new Tuple[] { }; + } + + public void Tick(Actor self) + { + if (remainingSurfaceTime > 0) + if (--remainingSurfaceTime <= 0) + OnDive(); + } + + void OnSurface() + { + Sound.Play("subshow1.aud"); + } + + void OnDive() + { + Sound.Play("subshow1.aud"); /* is this the right sound?? */ + } + } +} diff --git a/OpenRa.Game/Traits/RenderSubmarine.cs b/OpenRa.Game/Traits/RenderSubmarine.cs deleted file mode 100644 index 95804a4479..0000000000 --- a/OpenRa.Game/Traits/RenderSubmarine.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System.Collections.Generic; -using OpenRa.Game.Graphics; - -namespace OpenRa.Game.Traits -{ - class RenderSubmarine : RenderSimple, INotifyAttack, ITick - { - int remainingSurfaceTime = 2; /* setup for initial dive */ - - public RenderSubmarine(Actor self) - : base(self) - { - anim.PlayFacing("idle", () => self.traits.Get().Facing); - } - - public void Attacking(Actor self) - { - if (remainingSurfaceTime <= 0) - OnSurface(); - - remainingSurfaceTime = (int)(Rules.General.SubmergeDelay * 60 * 25); - } - - public override IEnumerable> Render(Actor self) - { - var s = Util.Centered(self, anim.Image, self.CenterLocation); - if (remainingSurfaceTime <= 0) - { - s.c = 8; /* shadow only palette */ - if (self.Owner != Game.LocalPlayer) - yield break; /* can't see someone else's submerged subs */ - } - yield return s; - } - - public override void Tick(Actor self) - { - base.Tick(self); - if (remainingSurfaceTime > 0) - if (--remainingSurfaceTime <= 0) - OnDive(); - } - - void OnSurface() - { - Sound.Play("subshow1.aud"); - } - - void OnDive() - { - Sound.Play("subshow1.aud"); /* is this the right sound?? */ - } - } -} diff --git a/OpenRa.Game/Traits/TraitsInterfaces.cs b/OpenRa.Game/Traits/TraitsInterfaces.cs index 3a9842104b..33fe7c7016 100644 --- a/OpenRa.Game/Traits/TraitsInterfaces.cs +++ b/OpenRa.Game/Traits/TraitsInterfaces.cs @@ -9,7 +9,7 @@ namespace OpenRa.Game.Traits interface ITick { void Tick(Actor self); } interface IRender { IEnumerable> Render(Actor self); } interface INotifyDamage { void Damaged(Actor self, DamageState ds); } - interface INotifyDamageEx : INotifyDamage { void Damaged(Actor self, int damage, WarheadInfo warhead); } + interface INotifyDamageEx { void Damaged(Actor self, int damage, WarheadInfo warhead); } interface INotifyBuildComplete { void BuildingComplete (Actor self); } interface IOrder { @@ -19,4 +19,6 @@ namespace OpenRa.Game.Traits interface IProducer { bool Produce( Actor self, UnitInfo producee ); } interface IOccupySpace { IEnumerable OccupiedCells(); } interface INotifyAttack { void Attacking(Actor self); } + interface IRenderModifier { IEnumerable> + ModifyRender( Actor self, IEnumerable> r ); } } diff --git a/units.ini b/units.ini index 269dfa8da3..139514dd04 100755 --- a/units.ini +++ b/units.ini @@ -94,7 +94,7 @@ PT Description=Submarine WaterBound=yes BuiltAt=spen -Traits=Unit, Mobile, RenderSubmarine, AttackBase +Traits=Unit, Mobile, RenderUnit, Cloak, AttackBase FireDelay=2 [DD] Description=Destroyer