From 9d1526f4e71f6b558adf9789a827c450aa0f8092 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Mon, 17 Mar 2014 12:24:17 +1300 Subject: [PATCH] Clean up Attack*. --- OpenRA.Mods.RA/Attack/AttackBase.cs | 7 ++ OpenRA.Mods.RA/Attack/AttackCharge.cs | 33 +++--- OpenRA.Mods.RA/Attack/AttackFollow.cs | 103 +++++++++++++++++++ OpenRA.Mods.RA/Attack/AttackLoyalty.cs | 6 +- OpenRA.Mods.RA/Attack/AttackOmni.cs | 23 ++--- OpenRA.Mods.RA/Attack/AttackPopupTurreted.cs | 12 +-- OpenRA.Mods.RA/Attack/AttackTurreted.cs | 77 +------------- OpenRA.Mods.RA/OpenRA.Mods.RA.csproj | 1 + 8 files changed, 147 insertions(+), 115 deletions(-) create mode 100644 OpenRA.Mods.RA/Attack/AttackFollow.cs diff --git a/OpenRA.Mods.RA/Attack/AttackBase.cs b/OpenRA.Mods.RA/Attack/AttackBase.cs index 75d18ea141..ffe81448d9 100644 --- a/OpenRA.Mods.RA/Attack/AttackBase.cs +++ b/OpenRA.Mods.RA/Attack/AttackBase.cs @@ -13,6 +13,7 @@ using System.Collections.Generic; using System.Drawing; using System.Linq; using OpenRA.FileFormats; +using OpenRA.Mods.RA.Buildings; using OpenRA.Traits; namespace OpenRA.Mods.RA @@ -35,6 +36,7 @@ namespace OpenRA.Mods.RA protected Lazy facing; Lazy> armaments; protected IEnumerable Armaments { get { return armaments.Value; } } + protected Lazy building; public AttackBase(Actor self, AttackBaseInfo info) { @@ -43,6 +45,7 @@ namespace OpenRA.Mods.RA armaments = Lazy.New(() => self.TraitsImplementing()); facing = Lazy.New(() => self.TraitOrDefault()); + building = Lazy.New(() => self.TraitOrDefault()); } protected virtual bool CanAttack(Actor self, Target target) @@ -50,6 +53,10 @@ namespace OpenRA.Mods.RA if (!self.IsInWorld) return false; + // Building is under construction or is being sold + if (building.Value != null && !building.Value.BuildComplete) + return false; + if (!target.IsValidFor(self)) return false; diff --git a/OpenRA.Mods.RA/Attack/AttackCharge.cs b/OpenRA.Mods.RA/Attack/AttackCharge.cs index c69a4a4316..35fa06a31d 100644 --- a/OpenRA.Mods.RA/Attack/AttackCharge.cs +++ b/OpenRA.Mods.RA/Attack/AttackCharge.cs @@ -29,7 +29,7 @@ namespace OpenRA.Mods.RA class AttackCharge : AttackOmni, ITick, INotifyAttack, ISync { - readonly AttackChargeInfo aci; + readonly AttackChargeInfo info; [Sync] int charges; [Sync] int timeToRecharge; @@ -37,25 +37,25 @@ namespace OpenRA.Mods.RA public AttackCharge(Actor self, AttackChargeInfo info) : base(self, info) { - aci = self.Info.Traits.Get(); - charges = aci.MaxCharges; + this.info = info; + charges = info.MaxCharges; } public void Tick(Actor self) { if (--timeToRecharge <= 0) - charges = aci.MaxCharges; + charges = info.MaxCharges; } public void Attacking(Actor self, Target target, Armament a, Barrel barrel) { --charges; - timeToRecharge = aci.ReloadTime; + timeToRecharge = info.ReloadTime; } public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove) { - return new ChargeAttack(newTarget); + return new ChargeAttack(this, newTarget); } public override void ResolveOrder(Actor self, Order order) @@ -68,9 +68,12 @@ namespace OpenRA.Mods.RA class ChargeAttack : Activity { + readonly AttackCharge attack; readonly Target target; - public ChargeAttack(Target target) + + public ChargeAttack(AttackCharge attack, Target target) { + this.attack = attack; this.target = target; } @@ -78,23 +81,22 @@ namespace OpenRA.Mods.RA { if (IsCanceled || !target.IsValidFor(self)) return NextActivity; - - var initDelay = self.Info.Traits.Get().InitialChargeDelay; - - var attack = self.Trait(); + if (attack.charges == 0 || !attack.CanAttack(self, target)) return this; self.Trait().PlayCharge(self); - return Util.SequenceActivities(new Wait(initDelay), new ChargeFire(target), this); + return Util.SequenceActivities(new Wait(attack.info.InitialChargeDelay), new ChargeFire(attack, target), this); } } class ChargeFire : Activity { + readonly AttackCharge attack; readonly Target target; - public ChargeFire(Target target) + public ChargeFire(AttackCharge attack, Target target) { + this.attack = attack; this.target = target; } @@ -103,15 +105,12 @@ namespace OpenRA.Mods.RA if (IsCanceled || !target.IsValidFor(self)) return NextActivity; - var chargeDelay = self.Info.Traits.Get().ChargeDelay; - - var attack = self.Trait(); if (attack.charges == 0) return NextActivity; attack.DoAttack(self, target); - return Util.SequenceActivities(new Wait(chargeDelay), this); + return Util.SequenceActivities(new Wait(attack.info.ChargeDelay), this); } } } diff --git a/OpenRA.Mods.RA/Attack/AttackFollow.cs b/OpenRA.Mods.RA/Attack/AttackFollow.cs new file mode 100644 index 0000000000..8df68d4304 --- /dev/null +++ b/OpenRA.Mods.RA/Attack/AttackFollow.cs @@ -0,0 +1,103 @@ +#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; +using System.Collections.Generic; +using OpenRA.FileFormats; +using OpenRA.Mods.RA.Activities; +using OpenRA.Mods.RA.Move; +using OpenRA.Traits; + +namespace OpenRA.Mods.RA +{ + public class AttackFollowInfo : AttackBaseInfo + { + public override object Create(ActorInitializer init) { return new AttackFollow(init.self, this); } + } + + public class AttackFollow : AttackBase, ITick, ISync + { + public Target Target { get; protected set; } + + public AttackFollow(Actor self, AttackFollowInfo info) + : base(self, info) { } + + protected override bool CanAttack(Actor self, Target target) + { + if (!target.IsValidFor(self)) + return false; + + return base.CanAttack(self, target); + } + + public void Tick(Actor self) + { + DoAttack(self, Target); + IsAttacking = Target.IsValidFor(self); + } + + public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove) + { + return new AttackActivity(self, newTarget, allowMove); + } + + public override void ResolveOrder(Actor self, Order order) + { + base.ResolveOrder(self, order); + + if (order.OrderString == "Stop") + Target = Target.Invalid; + } + + class AttackActivity : Activity + { + readonly AttackFollow attack; + readonly IMove move; + readonly Target target; + + public AttackActivity(Actor self, Target target, bool allowMove) + { + attack = self.Trait(); + move = allowMove ? self.TraitOrDefault() : null; + + // HACK: Mobile.OnRails is horrible + var mobile = move as Mobile; + if (mobile != null && mobile.Info.OnRails) + move = null; + + this.target = target; + } + + public override Activity Tick(Actor self) + { + if (IsCanceled || !target.IsValidFor(self)) + return NextActivity; + + if (self.IsDisabled()) + return this; + + const int RangeTolerance = 1; /* how far inside our maximum range we should try to sit */ + var weapon = attack.ChooseArmamentForTarget(target); + + if (weapon != null) + { + var range = WRange.FromCells(Math.Max(0, weapon.Weapon.Range.Range / 1024 - RangeTolerance)); + + attack.Target = target; + + if (move != null) + return Util.SequenceActivities(move.MoveFollow(self, target, range), this); + } + + return NextActivity; + } + } + } +} diff --git a/OpenRA.Mods.RA/Attack/AttackLoyalty.cs b/OpenRA.Mods.RA/Attack/AttackLoyalty.cs index dcd56c5f93..b9695347e1 100644 --- a/OpenRA.Mods.RA/Attack/AttackLoyalty.cs +++ b/OpenRA.Mods.RA/Attack/AttackLoyalty.cs @@ -25,7 +25,8 @@ namespace OpenRA.Mods.RA public override void DoAttack(Actor self, Target target) { - if (!CanAttack(self, target)) return; + if (!CanAttack(self, target)) + return; var arm = Armaments.FirstOrDefault(); if (arm == null) @@ -34,9 +35,8 @@ namespace OpenRA.Mods.RA if (!target.IsInRange(self.CenterPosition, arm.Weapon.Range)) return; - var facing = self.TraitOrDefault(); foreach (var a in Armaments) - a.CheckFire(self, facing, target); + a.CheckFire(self, facing.Value, target); if (target.Actor != null) target.Actor.ChangeOwner(self.Owner); diff --git a/OpenRA.Mods.RA/Attack/AttackOmni.cs b/OpenRA.Mods.RA/Attack/AttackOmni.cs index 03ae111b4a..517527e5a3 100644 --- a/OpenRA.Mods.RA/Attack/AttackOmni.cs +++ b/OpenRA.Mods.RA/Attack/AttackOmni.cs @@ -8,7 +8,7 @@ */ #endregion -using OpenRA.Mods.RA.Buildings; +using OpenRA.FileFormats; using OpenRA.Traits; namespace OpenRA.Mods.RA @@ -18,34 +18,25 @@ namespace OpenRA.Mods.RA public override object Create(ActorInitializer init) { return new AttackOmni(init.self, this); } } - class AttackOmni : AttackBase, INotifyBuildComplete, ISync + class AttackOmni : AttackBase, ISync { - [Sync] bool buildComplete = false; - public void BuildingComplete(Actor self) { buildComplete = true; } - public AttackOmni(Actor self, AttackOmniInfo info) : base(self, info) { } - protected override bool CanAttack(Actor self, Target target) - { - var isBuilding = self.HasTrait() && !buildComplete; - return base.CanAttack(self, target) && !isBuilding; - } - public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove) { - return new SetTarget(newTarget, this); + return new SetTarget(this, newTarget); } class SetTarget : Activity { readonly Target target; - readonly AttackOmni ao; + readonly AttackOmni attack; - public SetTarget(Target target, AttackOmni ao) + public SetTarget(AttackOmni attack, Target target) { this.target = target; - this.ao = ao; + this.attack = attack; } public override Activity Tick(Actor self) @@ -53,7 +44,7 @@ namespace OpenRA.Mods.RA if (IsCanceled || !target.IsValidFor(self)) return NextActivity; - ao.DoAttack(self, target); + attack.DoAttack(self, target); return this; } } diff --git a/OpenRA.Mods.RA/Attack/AttackPopupTurreted.cs b/OpenRA.Mods.RA/Attack/AttackPopupTurreted.cs index 3cc3c05bb7..781a6b38f5 100644 --- a/OpenRA.Mods.RA/Attack/AttackPopupTurreted.cs +++ b/OpenRA.Mods.RA/Attack/AttackPopupTurreted.cs @@ -35,19 +35,20 @@ namespace OpenRA.Mods.RA int idleTicks = 0; PopupState state = PopupState.Open; Turreted turret; + bool skippedMakeAnimation; public AttackPopupTurreted(ActorInitializer init, AttackPopupTurretedInfo info) : base(init.self, info) { this.info = info; - buildComplete = init.Contains(); turret = turrets.FirstOrDefault(); rb = init.self.Trait(); + skippedMakeAnimation = init.Contains(); } protected override bool CanAttack(Actor self, Target target) { - if (state == PopupState.Transitioning || !buildComplete) + if (state == PopupState.Transitioning || !building.Value.BuildComplete) return false; if (!base.CanAttack(self, target)) @@ -90,17 +91,14 @@ namespace OpenRA.Mods.RA } } - public override void BuildingComplete(Actor self) + public void BuildingComplete(Actor self) { - // Set true for SkipMakeAnimsInit - if (buildComplete) + if (!skippedMakeAnimation) { state = PopupState.Closed; rb.PlayCustomAnimRepeating(self, "closed-idle"); turret.desiredFacing = null; } - - buildComplete = true; } public float GetDamageModifier(Actor attacker, WarheadInfo warhead) diff --git a/OpenRA.Mods.RA/Attack/AttackTurreted.cs b/OpenRA.Mods.RA/Attack/AttackTurreted.cs index 9f7ee484c4..dee42a5761 100644 --- a/OpenRA.Mods.RA/Attack/AttackTurreted.cs +++ b/OpenRA.Mods.RA/Attack/AttackTurreted.cs @@ -10,23 +10,21 @@ using System; using System.Collections.Generic; +using OpenRA.FileFormats; using OpenRA.Mods.RA.Activities; -using OpenRA.Mods.RA.Buildings; using OpenRA.Mods.RA.Move; using OpenRA.Traits; namespace OpenRA.Mods.RA { - class AttackTurretedInfo : AttackBaseInfo, Requires + class AttackTurretedInfo : AttackFollowInfo, Requires { public override object Create(ActorInitializer init) { return new AttackTurreted(init.self, this); } } - class AttackTurreted : AttackBase, ITick, INotifyBuildComplete, ISync + class AttackTurreted : AttackFollow, ITick, ISync { - public Target Target { get; protected set; } protected IEnumerable turrets; - [Sync] protected bool buildComplete; public AttackTurreted(Actor self, AttackTurretedInfo info) : base(self, info) @@ -36,10 +34,7 @@ namespace OpenRA.Mods.RA protected override bool CanAttack(Actor self, Target target) { - if (self.HasTrait() && !buildComplete) - return false; - - if (!target.IsValidFor(self)) + if (!base.CanAttack(self, target)) return false; var canAttack = false; @@ -47,69 +42,7 @@ namespace OpenRA.Mods.RA if (t.FaceTarget(self, target)) canAttack = true; - if (!canAttack) - return false; - - return base.CanAttack(self, target); - } - - public void Tick(Actor self) - { - DoAttack(self, Target); - IsAttacking = Target.IsValidFor(self); - } - - public override Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove) - { - return new AttackActivity(newTarget, allowMove); - } - - public override void ResolveOrder(Actor self, Order order) - { - base.ResolveOrder(self, order); - - if (order.OrderString == "Stop") - Target = Target.Invalid; - } - - public virtual void BuildingComplete(Actor self) { buildComplete = true; } - - class AttackActivity : Activity - { - readonly Target target; - readonly bool allowMove; - - public AttackActivity(Target newTarget, bool allowMove) - { - this.target = newTarget; - this.allowMove = allowMove; - } - - public override Activity Tick(Actor self) - { - if (IsCanceled || !target.IsValidFor(self)) - return NextActivity; - - if (self.IsDisabled()) - return this; - - var attack = self.Trait(); - const int RangeTolerance = 1; /* how far inside our maximum range we should try to sit */ - var weapon = attack.ChooseArmamentForTarget(target); - - if (weapon != null) - { - var range = WRange.FromCells(Math.Max(0, weapon.Weapon.Range.Range / 1024 - RangeTolerance)); - - attack.Target = target; - var mobile = self.TraitOrDefault(); - - if (allowMove && mobile != null && !mobile.Info.OnRails) - return Util.SequenceActivities(mobile.MoveFollow(self, target, range), this); - } - - return NextActivity; - } + return canAttack; } } } diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index c19a7a5305..e21363edca 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -485,6 +485,7 @@ +