Add start delay functionality to attack animation traits

This commit is contained in:
reaperrr
2016-07-01 17:13:48 +02:00
parent 75c49620d1
commit 3b43544e2d
3 changed files with 73 additions and 7 deletions

View File

@@ -28,6 +28,12 @@ namespace OpenRA.Mods.Common.Traits.Render
[Desc("Shown while reloading.")] [Desc("Shown while reloading.")]
[SequenceReference(null, true)] public readonly string ReloadPrefix = null; [SequenceReference(null, true)] public readonly string ReloadPrefix = null;
[Desc("Delay in ticks before animation starts, either relative to attack preparation or attack.")]
public readonly int Delay = 0;
[Desc("Should the animation be delayed relative to preparation or actual attack?")]
public readonly AttackDelayType DelayRelativeTo = AttackDelayType.Preparation;
public object Create(ActorInitializer init) { return new WithAttackAnimation(init, this); } public object Create(ActorInitializer init) { return new WithAttackAnimation(init, this); }
} }
@@ -38,6 +44,8 @@ namespace OpenRA.Mods.Common.Traits.Render
readonly Armament armament; readonly Armament armament;
readonly WithSpriteBody wsb; readonly WithSpriteBody wsb;
int tick;
public WithAttackAnimation(ActorInitializer init, WithAttackAnimationInfo info) public WithAttackAnimation(ActorInitializer init, WithAttackAnimationInfo info)
{ {
this.info = info; this.info = info;
@@ -47,16 +55,39 @@ namespace OpenRA.Mods.Common.Traits.Render
wsb = init.Self.Trait<WithSpriteBody>(); wsb = init.Self.Trait<WithSpriteBody>();
} }
void INotifyAttack.Attacking(Actor self, Target target, Armament a, Barrel barrel) { } void PlayAttackAnimation(Actor self)
void INotifyAttack.PreparingAttack(Actor self, Target target, Armament a, Barrel barrel)
{ {
if (!string.IsNullOrEmpty(info.AttackSequence)) if (!string.IsNullOrEmpty(info.AttackSequence))
wsb.PlayCustomAnimation(self, info.AttackSequence, () => wsb.CancelCustomAnimation(self)); wsb.PlayCustomAnimation(self, info.AttackSequence, () => wsb.CancelCustomAnimation(self));
} }
void INotifyAttack.Attacking(Actor self, Target target, Armament a, Barrel barrel)
{
if (info.DelayRelativeTo == AttackDelayType.Attack)
{
if (info.Delay > 0)
tick = info.Delay;
else
PlayAttackAnimation(self);
}
}
void INotifyAttack.PreparingAttack(Actor self, Target target, Armament a, Barrel barrel)
{
if (info.DelayRelativeTo == AttackDelayType.Preparation)
{
if (info.Delay > 0)
tick = info.Delay;
else
PlayAttackAnimation(self);
}
}
void ITick.Tick(Actor self) void ITick.Tick(Actor self)
{ {
if (info.Delay > 0 && --tick == 0)
PlayAttackAnimation(self);
if (string.IsNullOrEmpty(info.AimSequence) && string.IsNullOrEmpty(info.ReloadPrefix)) if (string.IsNullOrEmpty(info.AimSequence) && string.IsNullOrEmpty(info.ReloadPrefix))
return; return;

View File

@@ -27,16 +27,23 @@ namespace OpenRA.Mods.Common.Traits.Render
[Desc("Custom palette is a player palette BaseName")] [Desc("Custom palette is a player palette BaseName")]
public readonly bool IsPlayerPalette = false; public readonly bool IsPlayerPalette = false;
[Desc("Delay in ticks before overlay starts, either relative to attack preparation or attack.")]
public readonly int Delay = 0;
[Desc("Should the overlay be delayed relative to preparation or actual attack?")]
public readonly AttackDelayType DelayRelativeTo = AttackDelayType.Preparation;
public object Create(ActorInitializer init) { return new WithAttackOverlay(init, this); } public object Create(ActorInitializer init) { return new WithAttackOverlay(init, this); }
} }
public class WithAttackOverlay : INotifyAttack public class WithAttackOverlay : INotifyAttack, ITick
{ {
readonly Animation overlay; readonly Animation overlay;
readonly RenderSprites renderSprites; readonly RenderSprites renderSprites;
readonly WithAttackOverlayInfo info; readonly WithAttackOverlayInfo info;
bool attacking; bool attacking;
int tick;
public WithAttackOverlay(ActorInitializer init, WithAttackOverlayInfo info) public WithAttackOverlay(ActorInitializer init, WithAttackOverlayInfo info)
{ {
@@ -50,12 +57,38 @@ namespace OpenRA.Mods.Common.Traits.Render
info.Palette, info.IsPlayerPalette); info.Palette, info.IsPlayerPalette);
} }
void INotifyAttack.Attacking(Actor self, Target target, Armament a, Barrel barrel) { } void PlayOverlay(Actor self)
void INotifyAttack.PreparingAttack(Actor self, Target target, Armament a, Barrel barrel)
{ {
attacking = true; attacking = true;
overlay.PlayThen(info.Sequence, () => attacking = false); overlay.PlayThen(info.Sequence, () => attacking = false);
} }
void INotifyAttack.Attacking(Actor self, Target target, Armament a, Barrel barrel)
{
if (info.DelayRelativeTo == AttackDelayType.Attack)
{
if (info.Delay > 0)
tick = info.Delay;
else
PlayOverlay(self);
}
}
void INotifyAttack.PreparingAttack(Actor self, Target target, Armament a, Barrel barrel)
{
if (info.DelayRelativeTo == AttackDelayType.Preparation)
{
if (info.Delay > 0)
tick = info.Delay;
else
PlayOverlay(self);
}
}
void ITick.Tick(Actor self)
{
if (info.Delay > 0 && --tick == 0)
PlayOverlay(self);
}
} }
} }

View File

@@ -19,6 +19,8 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits namespace OpenRA.Mods.Common.Traits
{ {
public enum AttackDelayType { Preparation, Attack }
public interface IQuantizeBodyOrientationInfo : ITraitInfo public interface IQuantizeBodyOrientationInfo : ITraitInfo
{ {
int QuantizedBodyFacings(ActorInfo ai, SequenceProvider sequenceProvider, string race); int QuantizedBodyFacings(ActorInfo ai, SequenceProvider sequenceProvider, string race);