From 9e650adef8ad44213996e4cca70a487ab145c39b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Sun, 5 Oct 2014 17:04:04 +0200 Subject: [PATCH] implement Ordos nerve gas missiles as warheads closes #2838 --- OpenRA.Mods.D2k/ChangeOwnerWarhead.cs | 50 +++++++++++++++ OpenRA.Mods.D2k/OpenRA.Mods.D2k.csproj | 2 + OpenRA.Mods.D2k/TemporaryOwnerManager.cs | 82 ++++++++++++++++++++++++ OpenRA.Mods.RA/Attack/AttackLoyalty.cs | 45 ------------- OpenRA.Mods.RA/OpenRA.Mods.RA.csproj | 1 - mods/d2k/rules/defaults.yaml | 2 + mods/d2k/rules/ordos.yaml | 4 +- mods/d2k/weapons.yaml | 5 +- 8 files changed, 142 insertions(+), 49 deletions(-) create mode 100644 OpenRA.Mods.D2k/ChangeOwnerWarhead.cs create mode 100644 OpenRA.Mods.D2k/TemporaryOwnerManager.cs delete mode 100644 OpenRA.Mods.RA/Attack/AttackLoyalty.cs diff --git a/OpenRA.Mods.D2k/ChangeOwnerWarhead.cs b/OpenRA.Mods.D2k/ChangeOwnerWarhead.cs new file mode 100644 index 0000000000..b17fea5f5c --- /dev/null +++ b/OpenRA.Mods.D2k/ChangeOwnerWarhead.cs @@ -0,0 +1,50 @@ +#region Copyright & License Information +/* + * Copyright 2007-2014 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 OpenRA.GameRules; +using OpenRA.Traits; + +namespace OpenRA.Mods.D2k +{ + [Desc("Interacts with the DynamicOwnerChange trait.")] + public class ChangeOwnerWarhead : Warhead + { + [Desc("Duration of the owner change (in ticks). Set to 0 to make it permanent.")] + public readonly int Duration = 0; + + public readonly WRange Range = WRange.FromCells(1); + + public override void DoImpact(Target target, Actor firedBy, IEnumerable damageModifiers) + { + var actors = target.Type == TargetType.Actor ? new[] { target.Actor } : + firedBy.World.FindActorsInCircle(target.CenterPosition, Range); + + foreach (var a in actors) + { + if (a.Owner == firedBy.Owner) // don't do anything on friendly fire + continue; + + if (Duration == 0) + a.ChangeOwner(firedBy.Owner); // permanent + else + { + var tempOwnerManager = a.TraitOrDefault(); + if (tempOwnerManager == null) + continue; + + tempOwnerManager.ChangeOwner(a, firedBy.Owner, Duration); + } + + a.CancelActivity(); // stop shooting, you have got new enemies + } + } + } +} diff --git a/OpenRA.Mods.D2k/OpenRA.Mods.D2k.csproj b/OpenRA.Mods.D2k/OpenRA.Mods.D2k.csproj index 3edfdb132e..8889a12c7d 100644 --- a/OpenRA.Mods.D2k/OpenRA.Mods.D2k.csproj +++ b/OpenRA.Mods.D2k/OpenRA.Mods.D2k.csproj @@ -92,6 +92,8 @@ + + diff --git a/OpenRA.Mods.D2k/TemporaryOwnerManager.cs b/OpenRA.Mods.D2k/TemporaryOwnerManager.cs new file mode 100644 index 0000000000..725f21ca73 --- /dev/null +++ b/OpenRA.Mods.D2k/TemporaryOwnerManager.cs @@ -0,0 +1,82 @@ +#region Copyright & License Information +/* + * Copyright 2007-2014 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.Drawing; +using OpenRA.Traits; + +namespace OpenRA.Mods.D2k +{ + [Desc("Interacts with the ChangeOwner warhead.", + "Displays a bar how long this actor is affected and reverts back to the old owner on temporary changes.")] + public class TemporaryOwnerManagerInfo : ITraitInfo + { + public readonly Color BarColor = Color.Orange; + + public object Create(ActorInitializer init) { return new TemporaryOwnerManager(init.self, this); } + } + + public class TemporaryOwnerManager : ISelectionBar, ITick, ISync, INotifyOwnerChanged + { + readonly TemporaryOwnerManagerInfo info; + + Player originalOwner; + Player changingOwner; + + [Sync] int remaining = -1; + int duration; + + public TemporaryOwnerManager(Actor self, TemporaryOwnerManagerInfo info) + { + this.info = info; + originalOwner = self.Owner; + } + + public void ChangeOwner(Actor self, Player newOwner, int duration) + { + remaining = this.duration = duration; + changingOwner = newOwner; + self.ChangeOwner(newOwner); + } + + public void Tick(Actor self) + { + if (!self.IsInWorld) + return; + + if (--remaining == 0) + { + changingOwner = originalOwner; + self.ChangeOwner(originalOwner); + self.CancelActivity(); // Stop shooting, you have got new enemies + } + } + + public void OnOwnerChanged(Actor self, Player oldOwner, Player newOwner) + { + if (changingOwner == null || changingOwner != newOwner) + originalOwner = newOwner; // It wasn't a temporary change, so we need to update here + else + changingOwner = null; // It was triggered by this trait: reset + } + + public float GetValue() + { + if (remaining <= 0) + return 0; + + return (float)remaining / duration; + } + + public Color GetColor() + { + return info.BarColor; + } + } +} diff --git a/OpenRA.Mods.RA/Attack/AttackLoyalty.cs b/OpenRA.Mods.RA/Attack/AttackLoyalty.cs deleted file mode 100644 index b9695347e1..0000000000 --- a/OpenRA.Mods.RA/Attack/AttackLoyalty.cs +++ /dev/null @@ -1,45 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2014 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.Linq; -using OpenRA.Traits; - -namespace OpenRA.Mods.RA -{ - public class AttackLoyaltyInfo : AttackFrontalInfo - { - public override object Create(ActorInitializer init) { return new AttackLoyalty(init.self, this); } - } - - public class AttackLoyalty : AttackFrontal - { - public AttackLoyalty(Actor self, AttackLoyaltyInfo info) - : base(self, info) { } - - public override void DoAttack(Actor self, Target target) - { - if (!CanAttack(self, target)) - return; - - var arm = Armaments.FirstOrDefault(); - if (arm == null) - return; - - if (!target.IsInRange(self.CenterPosition, arm.Weapon.Range)) - return; - - foreach (var a in Armaments) - a.CheckFire(self, facing.Value, target); - - if (target.Actor != null) - target.Actor.ChangeOwner(self.Owner); - } - } -} diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index d07d6dd4f0..1fae66cc42 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -146,7 +146,6 @@ - diff --git a/mods/d2k/rules/defaults.yaml b/mods/d2k/rules/defaults.yaml index 0552cef2df..cdf36f445f 100644 --- a/mods/d2k/rules/defaults.yaml +++ b/mods/d2k/rules/defaults.yaml @@ -47,6 +47,7 @@ UpgradeTypes: selfheal UpgradeMinEnabledLevel: 1 UpgradeManager: + TemporaryOwnerManager: ^Tank: AppearsOnRadar: @@ -97,6 +98,7 @@ UpgradeTypes: selfheal UpgradeMinEnabledLevel: 1 UpgradeManager: + TemporaryOwnerManager: ^Husk: Health: diff --git a/mods/d2k/rules/ordos.yaml b/mods/d2k/rules/ordos.yaml index d5c95157aa..93b5c99ae5 100644 --- a/mods/d2k/rules/ordos.yaml +++ b/mods/d2k/rules/ordos.yaml @@ -234,9 +234,9 @@ DEVIATORTANK: Range: 5c0 RenderUnit: Armament: - Weapon: FakeMissile + Weapon: NerveGasMissile LocalOffset: -299,0,85 - AttackLoyalty: + AttackFrontal: AutoTarget: InitialStance: Defend Explodes: diff --git a/mods/d2k/weapons.yaml b/mods/d2k/weapons.yaml index 7c6da57130..bc126406ba 100644 --- a/mods/d2k/weapons.yaml +++ b/mods/d2k/weapons.yaml @@ -366,7 +366,7 @@ DevBullet: Explosion: mini_explosion ImpactSound: EXPLMD3.WAV -FakeMissile: +NerveGasMissile: ReloadDelay: 120 Range: 8c0 Burst: 1 @@ -392,6 +392,9 @@ FakeMissile: Warhead@3Eff: CreateEffect Explosion: deviator ImpactSound: EXPLSML2.WAV + Warhead@4OwnerChange: ChangeOwner + Range: 1c0 + Duration: 750 155mm: ReloadDelay: 75