diff --git a/OpenRA.Game/Actor.cs b/OpenRA.Game/Actor.cs index 2abb53100f..d9c89d8bf2 100755 --- a/OpenRA.Game/Actor.cs +++ b/OpenRA.Game/Actor.cs @@ -68,7 +68,7 @@ namespace OpenRA public void Tick() { - if (currentActivity == null) + if (currentActivity == null || currentActivity is Idle) foreach (var ni in TraitsImplementing()) ni.TickIdle(this); diff --git a/OpenRA.Mods.RA/Activities/IdleAnimation.cs b/OpenRA.Mods.RA/Activities/IdleAnimation.cs deleted file mode 100644 index 5bb54a2192..0000000000 --- a/OpenRA.Mods.RA/Activities/IdleAnimation.cs +++ /dev/null @@ -1,47 +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.Collections.Generic; -using OpenRA.Mods.RA.Render; -using OpenRA.Traits; -using OpenRA.Traits.Activities; - -namespace OpenRA.Mods.RA.Activities -{ - public class IdleAnimation : Idle - { - string sequence; - int delay; - - public IdleAnimation(string sequence, int delay) - { - this.sequence = sequence; - this.delay = delay; - } - - bool active = true; - public override IActivity Tick(Actor self) - { - if (!active) return NextActivity; - - if (delay > 0 && --delay == 0) - self.Trait().anim.PlayThen(sequence, () => active = false); - - return this; - } - - protected override bool OnCancel( Actor self ) - { - active = false; - return true; - } - - } -} diff --git a/OpenRA.Mods.RA/AutoHeal.cs b/OpenRA.Mods.RA/AutoHeal.cs index ed09029b0c..0d3a1d56b9 100644 --- a/OpenRA.Mods.RA/AutoHeal.cs +++ b/OpenRA.Mods.RA/AutoHeal.cs @@ -18,71 +18,47 @@ namespace OpenRA.Mods.RA class AutoHeal : INotifyIdle { - public void TickIdle( Actor self ) + bool NeedsNewTarget(Actor self) { - self.QueueActivity( new IdleHealActivity() ); + var attack = self.Trait(); + var range = attack.GetMaximumRange(); + + if (currentTarget == null || !currentTarget.IsInWorld) + return true; // he's dead. + if( !Combat.IsInRange( self.CenterLocation, range, currentTarget ) ) + return true; // wandered off faster than we could follow + + if (currentTarget.GetDamageState() == DamageState.Undamaged) + return true; // fully healed + + return false; } - class IdleHealActivity : Idle + Actor ChooseTarget(Actor self, float range) { - Actor currentTarget; - IActivity inner; + var inRange = self.World.FindUnitsInCircle(self.CenterLocation, Game.CellSize * range); + var attack = self.Trait(); - public override IActivity Tick( Actor self ) + return inRange + .Where(a => a != self && self.Owner.Stances[a.Owner] == Stance.Ally) + .Where(a => a.IsInWorld && !a.IsDead()) + .Where(a => a.HasTrait() && a.GetDamageState() > DamageState.Undamaged) + .Where(a => attack.HasAnyValidWeapons(Target.FromActor(a))) + .OrderBy(a => (a.CenterLocation - self.CenterLocation).LengthSquared) + .FirstOrDefault(); + } + + Actor currentTarget; + public void TickIdle( Actor self ) + { + var attack = self.Trait(); + var range = attack.GetMaximumRange(); + + if (NeedsNewTarget(self)) { - if( inner == null ) - { - if( NextActivity != null ) - return NextActivity; - - var attack = self.Trait(); - var range = attack.GetMaximumRange(); - - if (NeedsNewTarget(self)) - { - currentTarget = ChooseTarget(self, range); - if( currentTarget != null ) - inner = self.Trait().GetAttackActivity(self, Target.FromActor( currentTarget ), false ); - } - } - if( inner != null ) - { - if( NeedsNewTarget(self) ) - inner.Cancel( self ); - inner = Util.RunActivity( self, inner ); - } - - return this; - } - - bool NeedsNewTarget(Actor self) - { - var attack = self.Trait(); - var range = attack.GetMaximumRange(); - - if (currentTarget == null || !currentTarget.IsInWorld) - return true; // he's dead. - if( !Combat.IsInRange( self.CenterLocation, range, currentTarget ) ) - return true; // wandered off faster than we could follow - - if (currentTarget.GetDamageState() == DamageState.Undamaged) - return true; // fully healed - - return false; - } - - Actor ChooseTarget(Actor self, float range) - { - var inRange = self.World.FindUnitsInCircle(self.CenterLocation, Game.CellSize * range); - var attack = self.Trait(); - - return inRange - .Where(a => a != self && self.Owner.Stances[a.Owner] == Stance.Ally) - .Where(a => a.IsInWorld && !a.IsDead()) - .Where(a => a.HasTrait() && a.GetDamageState() > DamageState.Undamaged) - .Where(a => attack.HasAnyValidWeapons(Target.FromActor(a))) - .OrderBy(a => (a.CenterLocation - self.CenterLocation).LengthSquared) - .FirstOrDefault(); + var currentTarget = ChooseTarget(self, range); + if( currentTarget != null ) + self.QueueActivity(self.Trait().GetAttackActivity(self, Target.FromActor( currentTarget ), false )); } } } diff --git a/OpenRA.Mods.RA/AutoTarget.cs b/OpenRA.Mods.RA/AutoTarget.cs index a2eb29746e..12f743a5fa 100644 --- a/OpenRA.Mods.RA/AutoTarget.cs +++ b/OpenRA.Mods.RA/AutoTarget.cs @@ -39,33 +39,13 @@ namespace OpenRA.Mods.RA public void TickIdle( Actor self ) { - self.QueueActivity( new IdleAttackActivity() ); - } - - class IdleAttackActivity : Idle - { - Actor currentTarget; - IActivity inner; - - public override IActivity Tick( Actor self ) - { - if( NextActivity != null && inner != null ) - inner.Cancel( self ); - if( inner == null ) - { - if( NextActivity != null ) - return NextActivity; - - var attack = self.Trait(); - currentTarget = attack.ScanForTarget(self, null); - if( currentTarget != null ) - inner = attack.GetAttackActivity( self, Target.FromActor(currentTarget), self.Info.Traits.Get().AllowMovement ); - } - if( inner != null ) - inner = Util.RunActivity( self, inner ); - - return this; - } + var attack = self.Trait(); + var currentTarget = attack.ScanForTarget(self, null); + if( currentTarget != null ) + self.QueueActivity(attack.GetAttackActivity( self, + Target.FromActor(currentTarget), + self.Info.Traits.Get().AllowMovement + )); } } } diff --git a/OpenRA.Mods.RA/IdleAnimation.cs b/OpenRA.Mods.RA/IdleAnimation.cs index d17c8227e6..bea9a164c2 100644 --- a/OpenRA.Mods.RA/IdleAnimation.cs +++ b/OpenRA.Mods.RA/IdleAnimation.cs @@ -9,6 +9,7 @@ #endregion using OpenRA.Traits; +using OpenRA.Mods.RA.Render; namespace OpenRA.Mods.RA { @@ -20,24 +21,61 @@ namespace OpenRA.Mods.RA } // infantry prone behavior - class IdleAnimation : INotifyDamage, INotifyIdle + class IdleAnimation : ITick, INotifyIdle { IdleAnimationInfo Info; + string sequence; + int delay; + bool active, waiting; + public IdleAnimation(IdleAnimationInfo info) { Info = info; } - - public void Damaged(Actor self, AttackInfo e) - { - if (self.GetCurrentActivity() is Activities.IdleAnimation) - self.CancelActivity(); - } + public void Tick(Actor self) + { + if (active) + { + //System.Console.WriteLine("active: {0} ({1})", self.Info.Name, self.ActorID); + return; + } + if (!self.IsIdle) + { + //System.Console.WriteLine("notidle: {0} ({1}) ",self.Info.Name, self.ActorID); + active = false; + waiting = false; + return; + } + + if (delay > 0 && --delay == 0) + { + System.Console.WriteLine("activate: {0} ({1})",self.Info.Name, self.ActorID); + active = true; + waiting = false; + self.Trait().anim.PlayThen(sequence, () => + { + //System.Console.WriteLine("finished: {0} ({1}) ",self.Info.Name, self.ActorID); + active = false; + }); + } + } + public void TickIdle(Actor self) { - self.QueueActivity(new Activities.IdleAnimation(Info.Animations.Random(self.World.SharedRandom), - Info.IdleWaitTicks)); + //if (active) + // System.Console.WriteLine("idleactive: {0} ({1}) ",self.Info.Name, self.ActorID); + + //if (waiting) + // System.Console.WriteLine("idlewaiting: {0} ({1}) ",self.Info.Name, self.ActorID); + if (active || waiting) + return; + + waiting = true; + sequence = Info.Animations.Random(self.World.SharedRandom); + delay = Info.IdleWaitTicks; + //System.Console.WriteLine("TickIdle: {2} ({3}) set {0} {1}",sequence,delay, self.Info.Name, self.ActorID); + } } } diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 7478c5b857..f8bef4d330 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -299,7 +299,6 @@ - diff --git a/OpenRA.Mods.RA/Render/RenderInfantry.cs b/OpenRA.Mods.RA/Render/RenderInfantry.cs index 935796c202..60eaf3a802 100644 --- a/OpenRA.Mods.RA/Render/RenderInfantry.cs +++ b/OpenRA.Mods.RA/Render/RenderInfantry.cs @@ -67,14 +67,16 @@ namespace OpenRA.Mods.RA.Render { base.Tick(self); if (inAttack) return; - if (self.GetCurrentActivity() is Activities.IdleAnimation) return; + if (self.IsIdle) return; if (ChooseMoveAnim(self)) return; - if (IsProne(self)) - anim.PlayFetchIndex("crawl", () => 0); /* what a hack. */ - else - anim.Play("stand"); + // TODO: Pick new animation only on damage or idle notifications + //if (IsProne(self)) + // anim.PlayFetchIndex("crawl", () => 0); /* what a hack. */ + //else + // anim.Play("stand"); } + public void Damaged(Actor self, AttackInfo e) {