diff --git a/OpenRA.Game/Actor.cs b/OpenRA.Game/Actor.cs index f52554891a..20c0dd0fe5 100755 --- a/OpenRA.Game/Actor.cs +++ b/OpenRA.Game/Actor.cs @@ -131,7 +131,14 @@ namespace OpenRA return new RectangleF(loc.X, loc.Y, size.X, size.Y); } - public bool IsInWorld { get; internal set; } + public bool IsInWorld { get; internal set; } + + public void QueueActivity( bool queued, IActivity nextActivity ) + { + if( !queued ) + CancelActivity(); + QueueActivity( nextActivity ); + } public void QueueActivity( IActivity nextActivity ) { diff --git a/OpenRA.Mods.RA/Air/AttackHeli.cs b/OpenRA.Mods.RA/Air/AttackHeli.cs index 8cb7d1c5d2..540523af0f 100755 --- a/OpenRA.Mods.RA/Air/AttackHeli.cs +++ b/OpenRA.Mods.RA/Air/AttackHeli.cs @@ -22,10 +22,10 @@ namespace OpenRA.Mods.RA.Air { public AttackHeli(Actor self, AttackHeliInfo info) : base(self, info) { } - protected override void QueueAttack(Actor self, Target newTarget) + protected override void QueueAttack(Actor self, bool queued, Target newTarget) { target = newTarget; - self.QueueActivity(new HeliAttack(newTarget)); + self.QueueActivity(queued, new HeliAttack(newTarget)); } } } diff --git a/OpenRA.Mods.RA/Air/AttackPlane.cs b/OpenRA.Mods.RA/Air/AttackPlane.cs index 966a54e645..ab5304b252 100755 --- a/OpenRA.Mods.RA/Air/AttackPlane.cs +++ b/OpenRA.Mods.RA/Air/AttackPlane.cs @@ -22,10 +22,10 @@ namespace OpenRA.Mods.RA.Air { public AttackPlane(Actor self, AttackPlaneInfo info) : base(self, info) { } - protected override void QueueAttack(Actor self, Target newTarget) + protected override void QueueAttack(Actor self, bool queued, Target newTarget) { target = newTarget; - self.QueueActivity(new FlyAttack(newTarget)); + self.QueueActivity(queued, new FlyAttack(newTarget)); } protected override bool CanAttack(Actor self) diff --git a/OpenRA.Mods.RA/AttackBase.cs b/OpenRA.Mods.RA/AttackBase.cs index c8f3ca6612..2b3eef7ab6 100644 --- a/OpenRA.Mods.RA/AttackBase.cs +++ b/OpenRA.Mods.RA/AttackBase.cs @@ -149,8 +149,7 @@ namespace OpenRA.Mods.RA { if (order.OrderString == "Attack") { - self.CancelActivity(); - QueueAttack(self, Target.FromOrder(order)); + QueueAttack(self, order.Queued, Target.FromOrder(order)); if (self.Owner == self.World.LocalPlayer) self.World.AddFrameEndTask(w => @@ -181,7 +180,7 @@ namespace OpenRA.Mods.RA return (order.OrderString == "Attack") ? "Attack" : null; } - protected abstract void QueueAttack(Actor self, Target newTarget); + protected abstract void QueueAttack(Actor self, bool queued, Target newTarget); public bool HasAnyValidWeapons(Target t) { return Weapons.Any(w => w.IsValidAgainst(self.World, t)); } public float GetMaximumRange() { return Weapons.Max(w => w.Info.Range); } diff --git a/OpenRA.Mods.RA/AttackFrontal.cs b/OpenRA.Mods.RA/AttackFrontal.cs index 62ea298c09..d648b2813f 100644 --- a/OpenRA.Mods.RA/AttackFrontal.cs +++ b/OpenRA.Mods.RA/AttackFrontal.cs @@ -40,12 +40,12 @@ namespace OpenRA.Mods.RA return true; } - protected override void QueueAttack(Actor self, Target newTarget) + protected override void QueueAttack(Actor self, bool queued, Target newTarget) { var weapon = ChooseWeaponForTarget(newTarget); if (weapon != null) - self.QueueActivity( + self.QueueActivity( queued, new Activities.Attack( newTarget, Math.Max(0, (int)weapon.Info.Range))); diff --git a/OpenRA.Mods.RA/AttackLeap.cs b/OpenRA.Mods.RA/AttackLeap.cs index c206f79929..9808ef1cba 100644 --- a/OpenRA.Mods.RA/AttackLeap.cs +++ b/OpenRA.Mods.RA/AttackLeap.cs @@ -40,12 +40,12 @@ namespace OpenRA.Mods.RA self.QueueActivity(new Leap(self, target)); } - protected override void QueueAttack(Actor self, Target newTarget) + protected override void QueueAttack(Actor self, bool queued, Target newTarget) { var weapon = ChooseWeaponForTarget(newTarget); if (weapon != null) - self.QueueActivity( + self.QueueActivity( queued, new Activities.Attack( newTarget, Math.Max(0, (int)weapon.Info.Range))); diff --git a/OpenRA.Mods.RA/AttackOmni.cs b/OpenRA.Mods.RA/AttackOmni.cs index 24fc908918..d8d3ade121 100644 --- a/OpenRA.Mods.RA/AttackOmni.cs +++ b/OpenRA.Mods.RA/AttackOmni.cs @@ -10,6 +10,7 @@ using OpenRA.Mods.RA.Buildings; using OpenRA.Traits; +using OpenRA.Mods.RA.Activities; namespace OpenRA.Mods.RA { @@ -37,9 +38,22 @@ namespace OpenRA.Mods.RA DoAttack(self, target); } - protected override void QueueAttack(Actor self, Target newTarget) + protected override void QueueAttack(Actor self, bool queued, Target newTarget) { - target = newTarget; + self.QueueActivity( queued, new SetTarget( newTarget ) ); + } + + class SetTarget : CancelableActivity + { + readonly Target target; + public SetTarget( Target target ) { this.target = target; } + + public override IActivity Tick( Actor self ) + { + if( !IsCanceled ) + self.Trait().target = target; + return NextActivity; + } } } } diff --git a/OpenRA.Mods.RA/AttackTurreted.cs b/OpenRA.Mods.RA/AttackTurreted.cs index 005b8ddb92..e1f66904d7 100644 --- a/OpenRA.Mods.RA/AttackTurreted.cs +++ b/OpenRA.Mods.RA/AttackTurreted.cs @@ -46,24 +46,39 @@ namespace OpenRA.Mods.RA DoAttack( self, target ); } - protected override void QueueAttack( Actor self, Target newTarget ) + protected override void QueueAttack( Actor self, bool queued, Target newTarget ) { if (self.TraitsImplementing().Any(d => d.Disabled)) return; - - const int RangeTolerance = 1; /* how far inside our maximum range we should try to sit */ - var weapon = ChooseWeaponForTarget(newTarget); - if (weapon == null) - return; - target = newTarget; - - if (self.HasTrait() && !self.Info.Traits.Get().OnRails) - self.QueueActivity( new Follow( newTarget, - Math.Max( 0, (int)weapon.Info.Range - RangeTolerance ) ) ); + self.QueueActivity( queued, new AttackActivity( newTarget ) ); } bool buildComplete = false; public void BuildingComplete(Actor self) { buildComplete = true; } + + class AttackActivity : CancelableActivity + { + readonly Target newTarget; + public AttackActivity( Target newTarget ) { this.newTarget = newTarget; } + + public override IActivity Tick( Actor self ) + { + if( IsCanceled ) return NextActivity; + + var attack = self.Trait(); + const int RangeTolerance = 1; /* how far inside our maximum range we should try to sit */ + var weapon = attack.ChooseWeaponForTarget(newTarget); + if (weapon != null) + { + attack.target = newTarget; + + if (self.HasTrait() && !self.Info.Traits.Get().OnRails) + self.QueueActivity( new Follow( newTarget, + Math.Max( 0, (int)weapon.Info.Range - RangeTolerance ) ) ); + } + return NextActivity; + } + } } } diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 3c51fb220a..d78da20152 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -1,4 +1,4 @@ - + Debug @@ -321,7 +321,4 @@ copy "$(TargetPath)" "$(SolutionDir)mods/ra/" cd "$(SolutionDir)" - - - \ No newline at end of file