Split and refactor aim animation from WithAttackAnimation
Splitting it from the attack animation, triggering start and end of the aiming animation via interface, as well as removing ReloadPrefix (in favor of switching sprite bodies via condition when reloading) allows us to drop updating via ITick, which in turn will make it much easier to ultimately make this trait compatible with other animation traits, once the priority system lands.
This commit is contained in:
@@ -452,6 +452,7 @@
|
||||
<Compile Include="Traits\Render\TimedConditionBar.cs" />
|
||||
<Compile Include="Traits\Render\WithSpriteBarrel.cs" />
|
||||
<Compile Include="Traits\Render\WithAttackAnimation.cs" />
|
||||
<Compile Include="Traits\Render\WithAimAnimation.cs" />
|
||||
<Compile Include="Traits\Render\WithAttackOverlay.cs" />
|
||||
<Compile Include="Traits\Render\WithMoveAnimation.cs" />
|
||||
<Compile Include="Traits\Render\WithSiloAnimation.cs" />
|
||||
|
||||
64
OpenRA.Mods.Common/Traits/Render/WithAimAnimation.cs
Normal file
64
OpenRA.Mods.Common/Traits/Render/WithAimAnimation.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2018 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, either version 3 of
|
||||
* the License, or (at your option) any later version. For more
|
||||
* information, see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits.Render
|
||||
{
|
||||
public class WithAimAnimationInfo : ConditionalTraitInfo, Requires<WithSpriteBodyInfo>, Requires<AttackBaseInfo>
|
||||
{
|
||||
[Desc("Armament name")]
|
||||
public readonly string Armament = "primary";
|
||||
|
||||
[Desc("Displayed while targeting.")]
|
||||
[FieldLoader.Require]
|
||||
[SequenceReference] public readonly string Sequence = null;
|
||||
|
||||
[Desc("Which sprite body to modify.")]
|
||||
public readonly string Body = "body";
|
||||
|
||||
public override object Create(ActorInitializer init) { return new WithAimAnimation(init, this); }
|
||||
|
||||
public override void RulesetLoaded(Ruleset rules, ActorInfo ai)
|
||||
{
|
||||
var match = ai.TraitInfos<WithSpriteBodyInfo>().SingleOrDefault(w => w.Name == Body);
|
||||
if (match == null)
|
||||
throw new YamlException("WithAimAnimation needs exactly one sprite body with matching name.");
|
||||
|
||||
base.RulesetLoaded(rules, ai);
|
||||
}
|
||||
}
|
||||
|
||||
public class WithAimAnimation : ConditionalTrait<WithAimAnimationInfo>, INotifyAiming
|
||||
{
|
||||
readonly AttackBase attack;
|
||||
readonly WithSpriteBody wsb;
|
||||
|
||||
public WithAimAnimation(ActorInitializer init, WithAimAnimationInfo info)
|
||||
: base(info)
|
||||
{
|
||||
attack = init.Self.Trait<AttackBase>();
|
||||
wsb = init.Self.TraitsImplementing<WithSpriteBody>().First(w => w.Info.Name == Info.Body);
|
||||
}
|
||||
|
||||
protected void UpdateSequence()
|
||||
{
|
||||
var seq = !IsTraitDisabled && attack.IsAiming ? Info.Sequence : wsb.Info.Sequence;
|
||||
wsb.DefaultAnimation.ReplaceAnim(seq);
|
||||
}
|
||||
|
||||
void INotifyAiming.StartedAiming(Actor self, AttackBase ab) { UpdateSequence(); }
|
||||
void INotifyAiming.StoppedAiming(Actor self, AttackBase ab) { UpdateSequence(); }
|
||||
protected override void TraitEnabled(Actor self) { UpdateSequence(); }
|
||||
protected override void TraitDisabled(Actor self) { UpdateSequence(); }
|
||||
}
|
||||
}
|
||||
@@ -20,13 +20,7 @@ namespace OpenRA.Mods.Common.Traits.Render
|
||||
public readonly string Armament = "primary";
|
||||
|
||||
[Desc("Displayed while attacking.")]
|
||||
[SequenceReference] public readonly string AttackSequence = null;
|
||||
|
||||
[Desc("Displayed while targeting.")]
|
||||
[SequenceReference] public readonly string AimSequence = null;
|
||||
|
||||
[Desc("Shown while reloading.")]
|
||||
[SequenceReference(null, true)] public readonly string ReloadPrefix = null;
|
||||
[SequenceReference] public readonly string Sequence = null;
|
||||
|
||||
[Desc("Delay in ticks before animation starts, either relative to attack preparation or attack.")]
|
||||
public readonly int Delay = 0;
|
||||
@@ -51,37 +45,28 @@ namespace OpenRA.Mods.Common.Traits.Render
|
||||
|
||||
public class WithAttackAnimation : ConditionalTrait<WithAttackAnimationInfo>, ITick, INotifyAttack
|
||||
{
|
||||
readonly AttackBase attack;
|
||||
readonly Armament armament;
|
||||
readonly WithSpriteBody wsb;
|
||||
readonly bool noAimOrReloadAnim;
|
||||
|
||||
int tick;
|
||||
bool attackAnimPlaying;
|
||||
|
||||
public WithAttackAnimation(ActorInitializer init, WithAttackAnimationInfo info)
|
||||
: base(info)
|
||||
{
|
||||
attack = init.Self.Trait<AttackBase>();
|
||||
armament = init.Self.TraitsImplementing<Armament>()
|
||||
.Single(a => a.Info.Name == Info.Armament);
|
||||
wsb = init.Self.TraitsImplementing<WithSpriteBody>().First(w => w.Info.Name == Info.Body);
|
||||
|
||||
noAimOrReloadAnim = string.IsNullOrEmpty(Info.AimSequence) && string.IsNullOrEmpty(Info.ReloadPrefix);
|
||||
}
|
||||
|
||||
void PlayAttackAnimation(Actor self)
|
||||
{
|
||||
if (!IsTraitDisabled && !wsb.IsTraitDisabled && !string.IsNullOrEmpty(Info.AttackSequence))
|
||||
{
|
||||
attackAnimPlaying = true;
|
||||
wsb.PlayCustomAnimation(self, Info.AttackSequence, () => attackAnimPlaying = false);
|
||||
}
|
||||
if (!IsTraitDisabled && !wsb.IsTraitDisabled && !string.IsNullOrEmpty(Info.Sequence))
|
||||
wsb.PlayCustomAnimation(self, Info.Sequence);
|
||||
}
|
||||
|
||||
void INotifyAttack.Attacking(Actor self, Target target, Armament a, Barrel barrel)
|
||||
{
|
||||
if (Info.DelayRelativeTo == AttackDelayType.Attack)
|
||||
if (a == armament && Info.DelayRelativeTo == AttackDelayType.Attack)
|
||||
{
|
||||
if (Info.Delay > 0)
|
||||
tick = Info.Delay;
|
||||
@@ -92,7 +77,7 @@ namespace OpenRA.Mods.Common.Traits.Render
|
||||
|
||||
void INotifyAttack.PreparingAttack(Actor self, Target target, Armament a, Barrel barrel)
|
||||
{
|
||||
if (Info.DelayRelativeTo == AttackDelayType.Preparation)
|
||||
if (a == armament && Info.DelayRelativeTo == AttackDelayType.Preparation)
|
||||
{
|
||||
if (Info.Delay > 0)
|
||||
tick = Info.Delay;
|
||||
@@ -105,20 +90,6 @@ namespace OpenRA.Mods.Common.Traits.Render
|
||||
{
|
||||
if (Info.Delay > 0 && --tick == 0)
|
||||
PlayAttackAnimation(self);
|
||||
|
||||
if (IsTraitDisabled || noAimOrReloadAnim || attackAnimPlaying || wsb.IsTraitDisabled)
|
||||
return;
|
||||
|
||||
var sequence = wsb.Info.Sequence;
|
||||
if (!string.IsNullOrEmpty(Info.AimSequence) && attack.IsAiming)
|
||||
sequence = Info.AimSequence;
|
||||
|
||||
var prefix = (armament.IsReloading && !string.IsNullOrEmpty(Info.ReloadPrefix)) ? Info.ReloadPrefix : "";
|
||||
|
||||
if (!string.IsNullOrEmpty(prefix) && sequence != (prefix + sequence))
|
||||
sequence = prefix + sequence;
|
||||
|
||||
wsb.DefaultAnimation.ReplaceAnim(sequence);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user