Fix idle animations / prone.

This commit is contained in:
Paul Chote
2010-11-30 12:51:25 +13:00
parent 5070a81db4
commit 2d224a207c
5 changed files with 72 additions and 88 deletions

View File

@@ -51,7 +51,6 @@ namespace OpenRA.Mods.RA
Actor currentTarget; Actor currentTarget;
public void TickIdle( Actor self ) public void TickIdle( Actor self )
{ {
System.Console.WriteLine("AutoHeal:TickIdle");
var attack = self.Trait<AttackBase>(); var attack = self.Trait<AttackBase>();
var range = attack.GetMaximumRange(); var range = attack.GetMaximumRange();
@@ -59,10 +58,7 @@ namespace OpenRA.Mods.RA
{ {
var currentTarget = ChooseTarget(self, range); var currentTarget = ChooseTarget(self, range);
if( currentTarget != null ) if( currentTarget != null )
{
System.Console.WriteLine("AutoHeal: Queing heal activity");
self.QueueActivity(self.Trait<AttackBase>().GetAttackActivity(self, Target.FromActor( currentTarget ), false )); self.QueueActivity(self.Trait<AttackBase>().GetAttackActivity(self, Target.FromActor( currentTarget ), false ));
}
} }
} }
} }

View File

@@ -39,17 +39,13 @@ namespace OpenRA.Mods.RA
public void TickIdle( Actor self ) public void TickIdle( Actor self )
{ {
System.Console.WriteLine("AutoTarget:TickIdle");
var attack = self.Trait<AttackBase>(); var attack = self.Trait<AttackBase>();
var currentTarget = attack.ScanForTarget(self, null); var currentTarget = attack.ScanForTarget(self, null);
if( currentTarget != null ) if( currentTarget != null )
{
System.Console.WriteLine("AutoTarget: Queing attack activity");
self.QueueActivity(attack.GetAttackActivity( self, self.QueueActivity(attack.GetAttackActivity( self,
Target.FromActor(currentTarget), Target.FromActor(currentTarget),
self.Info.Traits.Get<AutoTargetInfo>().AllowMovement self.Info.Traits.Get<AutoTargetInfo>().AllowMovement
)); ));
}
} }
} }
} }

View File

@@ -23,11 +23,18 @@ namespace OpenRA.Mods.RA
// infantry prone behavior // infantry prone behavior
class IdleAnimation : ITick, INotifyIdle class IdleAnimation : ITick, INotifyIdle
{ {
enum IdleState
{
None,
Waiting,
Active
};
IdleAnimationInfo Info; IdleAnimationInfo Info;
string sequence; string sequence;
int delay; int delay;
bool active, waiting; IdleState state;
public IdleAnimation(IdleAnimationInfo info) public IdleAnimation(IdleAnimationInfo info)
{ {
Info = info; Info = info;
@@ -35,49 +42,30 @@ namespace OpenRA.Mods.RA
public void Tick(Actor self) public void Tick(Actor self)
{ {
if (active)
{
//System.Console.WriteLine("active: {0} ({1})", self.Info.Name, self.ActorID);
return;
}
if (!self.IsIdle) if (!self.IsIdle)
{ {
//System.Console.WriteLine("notidle: {0} ({1}) ",self.Info.Name, self.ActorID); state = IdleState.None;
active = false;
waiting = false;
return; return;
} }
if (delay > 0 && --delay == 0) if (state == IdleState.Active)
return;
else if (delay > 0 && --delay == 0)
{ {
System.Console.WriteLine("activate: {0} ({1})",self.Info.Name, self.ActorID); state = IdleState.Active;
active = true; self.Trait<RenderInfantry>().anim.PlayThen(sequence, () => state = IdleState.None);
waiting = false;
self.Trait<RenderInfantry>().anim.PlayThen(sequence, () =>
{
//System.Console.WriteLine("finished: {0} ({1}) ",self.Info.Name, self.ActorID);
active = false;
});
} }
} }
public void TickIdle(Actor self) public void TickIdle(Actor self)
{ {
System.Console.WriteLine("IdleAnimation:TickIdle"); if (state != IdleState.None)
//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; return;
waiting = true; state = IdleState.Waiting;
sequence = Info.Animations.Random(self.World.SharedRandom); sequence = Info.Animations.Random(self.World.SharedRandom);
delay = Info.IdleWaitTicks; delay = Info.IdleWaitTicks;
System.Console.WriteLine("IdleAnimation: setting anim to {0} delay {1}", sequence, delay);
} }
} }
} }

View File

@@ -23,58 +23,53 @@ namespace OpenRA.Mods.RA.Render
public class RenderInfantry : RenderSimple, INotifyAttack, INotifyDamage, INotifyIdle public class RenderInfantry : RenderSimple, INotifyAttack, INotifyDamage, INotifyIdle
{ {
public enum AnimationState
{
Idle,
Attacking,
Moving
};
public AnimationState State { get; private set; }
Mobile mobile = self.Trait<Mobile>();
public RenderInfantry(Actor self) public RenderInfantry(Actor self)
: base(self, () => self.Trait<IFacing>().Facing) : base(self, () => self.Trait<IFacing>().Facing)
{ {
anim.Play("stand"); anim.Play("stand");
} State = AnimationState.Idle;
bool ChooseMoveAnim(Actor self)
{
var mobile = self.Trait<Mobile>();
if( !mobile.IsMoving ) return false;
if (float2.WithinEpsilon(self.CenterLocation, Util.CenterOfCell(mobile.toCell), 2)) return false;
var seq = IsProne(self) ? "crawl" : "run";
if (anim.CurrentSequence.Name != seq)
anim.PlayRepeating(seq);
return true;
}
bool inAttack = false;
bool IsProne(Actor self)
{
var takeCover = self.TraitOrDefault<TakeCover>();
return takeCover != null && takeCover.IsProne;
} }
public void Attacking(Actor self, Target target) public void Attacking(Actor self, Target target)
{ {
inAttack = true; State = AnimationState.Attacking;
if (anim.HasSequence("shoot"))
var seq = IsProne(self) ? "prone-shoot" : "shoot"; anim.PlayThen("shoot", () => State = AnimationState.Idle);
if (anim.HasSequence(seq))
anim.PlayThen(seq, () => inAttack = false);
else if (anim.HasSequence("heal")) else if (anim.HasSequence("heal"))
anim.PlayThen("heal", () => inAttack = false); anim.PlayThen("heal", () => State = AnimationState.Idle);
} }
public override void Tick(Actor self) public override void Tick(Actor self)
{ {
base.Tick(self); base.Tick(self);
if (self.IsIdle || inAttack) return;
ChooseMoveAnim(self); if (State == AnimationState.Attacking || self.IsIdle || !mobile.IsMoving)
return;
// Set move animation
if (State != AnimationState.Moving)
{
State = AnimationState.Moving;
anim.PlayRepeating("run");
}
} }
public void TickIdle(Actor self) public void TickIdle(Actor self)
{ {
System.Console.WriteLine("RenderInfantry:TickIdle"); if (State != AnimationState.Idle)
System.Console.WriteLine("RenderInfantry: setting anim to stand"); {
anim.Play("stand"); anim.Play("stand");
State = AnimationState.Idle;
}
} }

View File

@@ -10,13 +10,14 @@
using OpenRA.GameRules; using OpenRA.GameRules;
using OpenRA.Traits; using OpenRA.Traits;
using OpenRA.Mods.RA.Render;
namespace OpenRA.Mods.RA namespace OpenRA.Mods.RA
{ {
class TakeCoverInfo : TraitInfo<TakeCover> { } class TakeCoverInfo : TraitInfo<TakeCover>, ITraitPrerequisite<RenderInfantryInfo> { }
// infantry prone behavior // infantry prone behavior
class TakeCover : ITick, INotifyDamage, IDamageModifier, ISpeedModifier, INotifyIdle class TakeCover : ITick, INotifyDamage, IDamageModifier, ISpeedModifier
{ {
const int defaultProneTime = 100; /* ticks, =4s */ const int defaultProneTime = 100; /* ticks, =4s */
const float proneDamage = .5f; const float proneDamage = .5f;
@@ -29,30 +30,38 @@ namespace OpenRA.Mods.RA
public void Damaged(Actor self, AttackInfo e) public void Damaged(Actor self, AttackInfo e)
{ {
if (e.Damage > 0) /* fix to allow healing via `damage` */ if (e.Damage > 0) /* Don't go prone when healed */
{ {
if (e.Warhead == null || !e.Warhead.PreventProne) if (e.Warhead == null || !e.Warhead.PreventProne)
remainingProneTime = defaultProneTime; remainingProneTime = defaultProneTime;
} }
} }
public void Tick(Actor self) public void Tick(Actor self)
{ {
if (IsProne) if (!IsProne)
--remainingProneTime; return;
remainingProneTime--;
var ri = self.Trait<RenderInfantry>();
if (ri.State == RenderInfantry.AnimationState.Idle)
if (IsProne)
ri.anim.PlayFetchIndex("crawl", () => 0);
else
ri.anim.Play("stand");
if (ri.anim.CurrentSequence.Name == "run" && IsProne)
ri.anim.ReplaceAnim("crawl");
else if (ri.anim.CurrentSequence.Name == "crawl" && !IsProne)
ri.anim.ReplaceAnim("run");
if (ri.anim.CurrentSequence.Name == "shoot" && IsProne)
ri.anim.ReplaceAnim("prone-shoot");
else if (ri.anim.CurrentSequence.Name == "prone-shoot" && !IsProne)
ri.anim.ReplaceAnim("shoot");
} }
public void TickIdle(Actor self)
{
System.Console.WriteLine("TakeCover:TickIdle");
if (remainingProneTime > 0)
{
System.Console.WriteLine("TakeCover: set anim to crawl");
self.Trait<RenderSimple>().anim.PlayFetchIndex("crawl", () => 0);
}
}
public float GetDamageModifier(Actor attacker, WarheadInfo warhead ) public float GetDamageModifier(Actor attacker, WarheadInfo warhead )
{ {
return IsProne ? proneDamage : 1f; return IsProne ? proneDamage : 1f;