Merge pull request #11974 from abc013/SecondWeaponAnimation

Add support for multiple fire animations in WithInfantryBody
This commit is contained in:
abcdefg30
2016-10-15 12:49:41 +02:00
committed by GitHub
14 changed files with 81 additions and 51 deletions

View File

@@ -24,10 +24,24 @@ namespace OpenRA.Mods.Common.Traits.Render
public readonly int MaxIdleDelay = 110; public readonly int MaxIdleDelay = 110;
[SequenceReference] public readonly string MoveSequence = "run"; [SequenceReference] public readonly string MoveSequence = "run";
[SequenceReference] public readonly string AttackSequence = null; [SequenceReference] public readonly string DefaultAttackSequence = null;
// TODO: [SequenceReference] isn't smart enough to use Dictionaries.
[Desc("Attack sequence to use for each armament.")]
[FieldLoader.LoadUsing("LoadWeaponSequences")]
public readonly Dictionary<string, string> AttackSequences = new Dictionary<string, string>();
[SequenceReference] public readonly string[] IdleSequences = { }; [SequenceReference] public readonly string[] IdleSequences = { };
[SequenceReference] public readonly string[] StandSequences = { "stand" }; [SequenceReference] public readonly string[] StandSequences = { "stand" };
public static object LoadWeaponSequences(MiniYaml yaml)
{
var md = yaml.ToDictionary();
return md.ContainsKey("AttackSequences")
? md["AttackSequences"].ToDictionary(my => FieldLoader.GetValue<string>("(value)", my.Value))
: new Dictionary<string, string>();
}
public override object Create(ActorInitializer init) { return new WithInfantryBody(init, this); } public override object Create(ActorInitializer init) { return new WithInfantryBody(init, this); }
public IEnumerable<IActorPreview> RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p) public IEnumerable<IActorPreview> RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p)
@@ -96,18 +110,22 @@ namespace OpenRA.Mods.Common.Traits.Render
return !IsModifyingSequence; return !IsModifyingSequence;
} }
public void Attacking(Actor self, Target target) public void Attacking(Actor self, Target target, Armament a)
{ {
if (!string.IsNullOrEmpty(Info.AttackSequence) && DefaultAnimation.HasSequence(NormalizeInfantrySequence(self, Info.AttackSequence))) string sequence;
if (!Info.AttackSequences.TryGetValue(a.Info.Name, out sequence))
sequence = Info.DefaultAttackSequence;
if (!string.IsNullOrEmpty(sequence) && DefaultAnimation.HasSequence(NormalizeInfantrySequence(self, sequence)))
{ {
state = AnimationState.Attacking; state = AnimationState.Attacking;
DefaultAnimation.PlayThen(NormalizeInfantrySequence(self, Info.AttackSequence), () => state = AnimationState.Idle); DefaultAnimation.PlayThen(NormalizeInfantrySequence(self, sequence), () => state = AnimationState.Idle);
} }
} }
void INotifyAttack.PreparingAttack(Actor self, Target target, Armament a, Barrel barrel) void INotifyAttack.PreparingAttack(Actor self, Target target, Armament a, Barrel barrel)
{ {
Attacking(self, target); Attacking(self, target, a);
} }
void INotifyAttack.Attacking(Actor self, Target target, Armament a, Barrel barrel) { } void INotifyAttack.Attacking(Actor self, Target target, Armament a, Barrel barrel) { }

View File

@@ -386,6 +386,17 @@ namespace OpenRA.Mods.Common.UtilityCommands
} }
} }
// Renamed AttackSequence to DefaultAttackSequence in WithInfantryBody.
if (engineVersion < 20161014)
{
if (node.Key == "WithInfantryBody")
{
var attackSequence = node.Value.Nodes.FirstOrDefault(n => n.Key == "AttackSequence");
if (attackSequence != null)
attackSequence.Key = "DefaultAttackSequence";
}
}
UpgradeActorRules(modData, engineVersion, ref node.Value.Nodes, node, depth + 1); UpgradeActorRules(modData, engineVersion, ref node.Value.Nodes, node, depth + 1);
} }

View File

@@ -30,13 +30,13 @@ namespace OpenRA.Mods.RA.Activities
int ticks; int ticks;
WAngle angle; WAngle angle;
public Leap(Actor self, Actor target, WeaponInfo weapon, WDist speed, WAngle angle) public Leap(Actor self, Actor target, Armament a, WDist speed, WAngle angle)
{ {
var targetMobile = target.TraitOrDefault<Mobile>(); var targetMobile = target.TraitOrDefault<Mobile>();
if (targetMobile == null) if (targetMobile == null)
throw new InvalidOperationException("Leap requires a target actor with the Mobile trait"); throw new InvalidOperationException("Leap requires a target actor with the Mobile trait");
this.weapon = weapon; this.weapon = a.Weapon;
this.angle = angle; this.angle = angle;
mobile = self.Trait<Mobile>(); mobile = self.Trait<Mobile>();
mobile.SetLocation(mobile.FromCell, mobile.FromSubCell, targetMobile.FromCell, targetMobile.FromSubCell); mobile.SetLocation(mobile.FromCell, mobile.FromSubCell, targetMobile.FromCell, targetMobile.FromSubCell);
@@ -47,7 +47,7 @@ namespace OpenRA.Mods.RA.Activities
length = Math.Max((to - from).Length / speed.Length, 1); length = Math.Max((to - from).Length / speed.Length, 1);
// HACK: why isn't this using the interface? // HACK: why isn't this using the interface?
self.Trait<WithInfantryBody>().Attacking(self, Target.FromActor(target)); self.Trait<WithInfantryBody>().Attacking(self, Target.FromActor(target), a);
if (weapon.Report != null && weapon.Report.Any()) if (weapon.Report != null && weapon.Report.Any())
Game.Sound.Play(weapon.Report.Random(self.World.SharedRandom), self.CenterPosition); Game.Sound.Play(weapon.Report.Random(self.World.SharedRandom), self.CenterPosition);

View File

@@ -51,7 +51,7 @@ namespace OpenRA.Mods.RA.Traits
return; return;
self.CancelActivity(); self.CancelActivity();
self.QueueActivity(new Leap(self, target.Actor, a.Weapon, info.Speed, info.Angle)); self.QueueActivity(new Leap(self, target.Actor, a, info.Speed, info.Angle));
} }
} }
} }

View File

@@ -320,7 +320,7 @@
Weapon: Pistol Weapon: Pistol
AttackFrontal: AttackFrontal:
WithInfantryBody: WithInfantryBody:
AttackSequence: shoot DefaultAttackSequence: shoot
^DINO: ^DINO:
Inherits@1: ^ExistsInWorld Inherits@1: ^ExistsInWorld
@@ -365,7 +365,7 @@
QuantizeFacingsFromSequence: QuantizeFacingsFromSequence:
Sequence: stand Sequence: stand
WithInfantryBody: WithInfantryBody:
AttackSequence: attack DefaultAttackSequence: attack
WithDeathAnimation: WithDeathAnimation:
UseDeathTypeSuffix: false UseDeathTypeSuffix: false
AutoTarget: AutoTarget:

View File

@@ -17,7 +17,7 @@ E1:
AttackFrontal: AttackFrontal:
WithInfantryBody: WithInfantryBody:
IdleSequences: idle1,idle2,idle3,idle4 IdleSequences: idle1,idle2,idle3,idle4
AttackSequence: shoot DefaultAttackSequence: shoot
E2: E2:
Inherits: ^Soldier Inherits: ^Soldier
@@ -40,7 +40,7 @@ E2:
FireDelay: 15 FireDelay: 15
AttackFrontal: AttackFrontal:
WithInfantryBody: WithInfantryBody:
AttackSequence: throw DefaultAttackSequence: throw
Explodes: Explodes:
Weapon: GrenadierExplode Weapon: GrenadierExplode
EmptyWeapon: GrenadierExplode EmptyWeapon: GrenadierExplode
@@ -68,7 +68,7 @@ E3:
FireDelay: 5 FireDelay: 5
AttackFrontal: AttackFrontal:
WithInfantryBody: WithInfantryBody:
AttackSequence: shoot DefaultAttackSequence: shoot
E4: E4:
Inherits: ^Soldier Inherits: ^Soldier
@@ -93,7 +93,7 @@ E4:
AttackFrontal: AttackFrontal:
WithMuzzleOverlay: WithMuzzleOverlay:
WithInfantryBody: WithInfantryBody:
AttackSequence: shoot DefaultAttackSequence: shoot
E5: E5:
Inherits: ^Soldier Inherits: ^Soldier
@@ -124,7 +124,7 @@ E5:
WithMuzzleOverlay: WithMuzzleOverlay:
-DamagedByTerrain: -DamagedByTerrain:
WithInfantryBody: WithInfantryBody:
AttackSequence: shoot DefaultAttackSequence: shoot
E6: E6:
Inherits: ^Soldier Inherits: ^Soldier
@@ -185,7 +185,7 @@ RMBO:
AttackMove: AttackMove:
Voice: Attack Voice: Attack
WithInfantryBody: WithInfantryBody:
AttackSequence: shoot DefaultAttackSequence: shoot
IdleSequences: idle1,idle2,idle3 IdleSequences: idle1,idle2,idle3
AnnounceOnBuild: AnnounceOnBuild:
AnnounceOnKill: AnnounceOnKill:

View File

@@ -18,7 +18,7 @@ light_inf:
Weapon: LMG Weapon: LMG
AttackFrontal: AttackFrontal:
WithInfantryBody: WithInfantryBody:
AttackSequence: shoot DefaultAttackSequence: shoot
engineer: engineer:
Inherits: ^Infantry Inherits: ^Infantry
@@ -73,7 +73,7 @@ trooper:
LocalOffset: 128,0,256 LocalOffset: 128,0,256
AttackFrontal: AttackFrontal:
WithInfantryBody: WithInfantryBody:
AttackSequence: shoot DefaultAttackSequence: shoot
thumper: thumper:
Inherits: ^Infantry Inherits: ^Infantry
@@ -154,7 +154,7 @@ fremen:
Weapon: Fremen_L Weapon: Fremen_L
AttackFrontal: AttackFrontal:
WithInfantryBody: WithInfantryBody:
AttackSequence: shoot DefaultAttackSequence: shoot
Cloak: Cloak:
InitialDelay: 85 InitialDelay: 85
CloakDelay: 85 CloakDelay: 85
@@ -188,7 +188,7 @@ grenadier:
FireDelay: 3 FireDelay: 3
AttackFrontal: AttackFrontal:
WithInfantryBody: WithInfantryBody:
AttackSequence: throw DefaultAttackSequence: throw
Explodes: Explodes:
Weapon: GrenDeath Weapon: GrenDeath
EmptyWeapon: GrenDeath EmptyWeapon: GrenDeath
@@ -213,7 +213,7 @@ sardaukar:
RevealsShroud: RevealsShroud:
Range: 4c768 Range: 4c768
WithInfantryBody: WithInfantryBody:
AttackSequence: shoot DefaultAttackSequence: shoot
Armament@PRIMARY: Armament@PRIMARY:
Weapon: M_LMG Weapon: M_LMG
Armament@SECONDARY: Armament@SECONDARY:

View File

@@ -303,7 +303,7 @@
Weapon: Pistol Weapon: Pistol
AttackFrontal: AttackFrontal:
WithInfantryBody: WithInfantryBody:
AttackSequence: shoot DefaultAttackSequence: shoot
^Ship: ^Ship:
Inherits@1: ^ExistsInWorld Inherits@1: ^ExistsInWorld

View File

@@ -37,7 +37,7 @@ DOG:
Targetable: Targetable:
TargetTypes: Ground, Infantry TargetTypes: Ground, Infantry
WithInfantryBody: WithInfantryBody:
AttackSequence: shoot DefaultAttackSequence: shoot
StandSequences: stand StandSequences: stand
IgnoresDisguise: IgnoresDisguise:
DetectCloaked: DetectCloaked:
@@ -68,7 +68,7 @@ E1:
MuzzleSequence: garrison-muzzle MuzzleSequence: garrison-muzzle
AttackFrontal: AttackFrontal:
WithInfantryBody: WithInfantryBody:
AttackSequence: shoot DefaultAttackSequence: shoot
ProducibleWithLevel: ProducibleWithLevel:
Prerequisites: barracks.upgraded Prerequisites: barracks.upgraded
@@ -98,7 +98,7 @@ E2:
FireDelay: 15 FireDelay: 15
AttackFrontal: AttackFrontal:
WithInfantryBody: WithInfantryBody:
AttackSequence: throw DefaultAttackSequence: throw
Explodes: Explodes:
Weapon: UnitExplodeSmall Weapon: UnitExplodeSmall
Chance: 50 Chance: 50
@@ -123,6 +123,7 @@ E3:
Weapon: RedEye Weapon: RedEye
LocalOffset: 0,0,555 LocalOffset: 0,0,555
Armament@SECONDARY: Armament@SECONDARY:
Name: secondary
Weapon: Dragon Weapon: Dragon
LocalOffset: 0,0,555 LocalOffset: 0,0,555
Armament@GARRISONED: Armament@GARRISONED:
@@ -130,7 +131,7 @@ E3:
Weapon: Dragon Weapon: Dragon
AttackFrontal: AttackFrontal:
WithInfantryBody: WithInfantryBody:
AttackSequence: shoot DefaultAttackSequence: shoot
ProducibleWithLevel: ProducibleWithLevel:
Prerequisites: barracks.upgraded Prerequisites: barracks.upgraded
@@ -157,7 +158,7 @@ E4:
Weapon: Flamer Weapon: Flamer
AttackFrontal: AttackFrontal:
WithInfantryBody: WithInfantryBody:
AttackSequence: shoot DefaultAttackSequence: shoot
ProducibleWithLevel: ProducibleWithLevel:
Prerequisites: barracks.upgraded Prerequisites: barracks.upgraded
@@ -287,7 +288,7 @@ E7:
MuzzleSequence: garrison-muzzle MuzzleSequence: garrison-muzzle
AttackFrontal: AttackFrontal:
WithInfantryBody: WithInfantryBody:
AttackSequence: shoot DefaultAttackSequence: shoot
StandSequences: stand StandSequences: stand
AnnounceOnBuild: AnnounceOnBuild:
AnnounceOnKill: AnnounceOnKill:
@@ -323,7 +324,7 @@ MEDI:
AttackFrontal: AttackFrontal:
WithInfantryBody: WithInfantryBody:
StandSequences: stand StandSequences: stand
AttackSequence: heal DefaultAttackSequence: heal
Voiced: Voiced:
VoiceSet: MedicVoice VoiceSet: MedicVoice
@@ -360,7 +361,7 @@ MECH:
CaptureTypes: husk CaptureTypes: husk
PlayerExperience: 25 PlayerExperience: 25
WithInfantryBody: WithInfantryBody:
AttackSequence: repair DefaultAttackSequence: repair
StandSequences: stand StandSequences: stand
Voiced: Voiced:
VoiceSet: MechanicVoice VoiceSet: MechanicVoice
@@ -509,7 +510,7 @@ SHOK:
Guard: Guard:
Voice: Move Voice: Move
WithInfantryBody: WithInfantryBody:
AttackSequence: shoot DefaultAttackSequence: shoot
Voiced: Voiced:
VoiceSet: ShokVoice VoiceSet: ShokVoice
ProducibleWithLevel: ProducibleWithLevel:
@@ -544,7 +545,7 @@ SNIPER:
MuzzleSequence: garrison-muzzle MuzzleSequence: garrison-muzzle
AttackFrontal: AttackFrontal:
WithInfantryBody: WithInfantryBody:
AttackSequence: shoot DefaultAttackSequence: shoot
Cloak: Cloak:
InitialDelay: 250 InitialDelay: 250
CloakDelay: 120 CloakDelay: 120
@@ -579,7 +580,7 @@ Zombie:
ScanRadius: 5 ScanRadius: 5
AttackFrontal: AttackFrontal:
WithInfantryBody: WithInfantryBody:
AttackSequence: bite DefaultAttackSequence: bite
IdleSequences: idle1 IdleSequences: idle1
Armament: Armament:
Weapon: claw Weapon: claw
@@ -617,7 +618,7 @@ Ant:
ScanRadius: 5 ScanRadius: 5
AttackFrontal: AttackFrontal:
WithInfantryBody: WithInfantryBody:
AttackSequence: bite DefaultAttackSequence: bite
Armament: Armament:
Weapon: mandible Weapon: mandible
Targetable: Targetable:

View File

@@ -44,7 +44,7 @@ UMAGON:
AttackFrontal: AttackFrontal:
Voice: Attack Voice: Attack
WithInfantryBody: WithInfantryBody:
AttackSequence: attack DefaultAttackSequence: attack
ProducibleWithLevel: ProducibleWithLevel:
Prerequisites: barracks.upgraded Prerequisites: barracks.upgraded
@@ -99,7 +99,7 @@ MUTANT:
AttackFrontal: AttackFrontal:
Voice: Attack Voice: Attack
WithInfantryBody: WithInfantryBody:
AttackSequence: attack DefaultAttackSequence: attack
ProducibleWithLevel: ProducibleWithLevel:
Prerequisites: barracks.upgraded Prerequisites: barracks.upgraded
@@ -123,7 +123,7 @@ MWMN:
AttackFrontal: AttackFrontal:
Voice: Attack Voice: Attack
WithInfantryBody: WithInfantryBody:
AttackSequence: attack DefaultAttackSequence: attack
ProducibleWithLevel: ProducibleWithLevel:
Prerequisites: barracks.upgraded Prerequisites: barracks.upgraded
@@ -147,7 +147,7 @@ MUTANT3:
AttackFrontal: AttackFrontal:
Voice: Attack Voice: Attack
WithInfantryBody: WithInfantryBody:
AttackSequence: attack DefaultAttackSequence: attack
ProducibleWithLevel: ProducibleWithLevel:
Prerequisites: barracks.upgraded Prerequisites: barracks.upgraded
@@ -168,7 +168,7 @@ TRATOS:
Range: 4c0 Range: 4c0
-AutoTarget: -AutoTarget:
WithInfantryBody: WithInfantryBody:
AttackSequence: attack DefaultAttackSequence: attack
OXANNA: OXANNA:
Inherits: ^Soldier Inherits: ^Soldier
@@ -186,7 +186,7 @@ OXANNA:
Range: 4c0 Range: 4c0
-AutoTarget: -AutoTarget:
WithInfantryBody: WithInfantryBody:
AttackSequence: attack DefaultAttackSequence: attack
SLAV: SLAV:
Inherits: ^Soldier Inherits: ^Soldier
@@ -204,7 +204,7 @@ SLAV:
Range: 4c0 Range: 4c0
-AutoTarget: -AutoTarget:
WithInfantryBody: WithInfantryBody:
AttackSequence: attack DefaultAttackSequence: attack
DOGGIE: DOGGIE:
Inherits@1: ^Infantry Inherits@1: ^Infantry
@@ -279,7 +279,7 @@ VISC_LRG:
CIV1: CIV1:
Inherits: ^CivilianInfantry Inherits: ^CivilianInfantry
WithInfantryBody: WithInfantryBody:
AttackSequence: attack DefaultAttackSequence: attack
Armament: Armament:
Weapon: Pistola Weapon: Pistola
AttackFrontal: AttackFrontal:
@@ -292,7 +292,7 @@ CIV2:
CIV3: CIV3:
Inherits: ^CivilianInfantry Inherits: ^CivilianInfantry
WithInfantryBody: WithInfantryBody:
AttackSequence: attack DefaultAttackSequence: attack
Armament: Armament:
Weapon: Pistola Weapon: Pistola
AttackFrontal: AttackFrontal:

View File

@@ -396,7 +396,7 @@
MustBeDestroyed: MustBeDestroyed:
WithPermanentInjury: WithPermanentInjury:
WithInfantryBody: WithInfantryBody:
AttackSequence: attack DefaultAttackSequence: attack
IdleSequences: idle1,idle2 IdleSequences: idle1,idle2
UpgradeOnDamageState@CRITICAL: UpgradeOnDamageState@CRITICAL:
Upgrades: criticalspeed Upgrades: criticalspeed

View File

@@ -20,7 +20,7 @@ E2:
AttackFrontal: AttackFrontal:
Voice: Attack Voice: Attack
WithInfantryBody: WithInfantryBody:
AttackSequence: attack DefaultAttackSequence: attack
ProducibleWithLevel: ProducibleWithLevel:
Prerequisites: barracks.upgraded Prerequisites: barracks.upgraded
@@ -53,7 +53,7 @@ MEDIC:
OutsideRangeCursor: heal OutsideRangeCursor: heal
AttackFrontal: AttackFrontal:
WithInfantryBody: WithInfantryBody:
AttackSequence: heal DefaultAttackSequence: heal
SelfHealing: SelfHealing:
Delay: 60 Delay: 60
Passenger: Passenger:
@@ -88,7 +88,7 @@ JUMPJET:
AttackFrontal: AttackFrontal:
Voice: Attack Voice: Attack
WithInfantryBody: WithInfantryBody:
AttackSequence: attack DefaultAttackSequence: attack
-TakeCover: -TakeCover:
ProducibleWithLevel: ProducibleWithLevel:
Prerequisites: barracks.upgraded Prerequisites: barracks.upgraded
@@ -128,6 +128,6 @@ GHOST:
DetonationDelay: 45 DetonationDelay: 45
Voice: Attack Voice: Attack
WithInfantryBody: WithInfantryBody:
AttackSequence: attack DefaultAttackSequence: attack
ProducibleWithLevel: ProducibleWithLevel:
Prerequisites: barracks.upgraded Prerequisites: barracks.upgraded

View File

@@ -21,7 +21,7 @@ E3:
AttackFrontal: AttackFrontal:
Voice: Attack Voice: Attack
WithInfantryBody: WithInfantryBody:
AttackSequence: attack DefaultAttackSequence: attack
ProducibleWithLevel: ProducibleWithLevel:
Prerequisites: barracks.upgraded Prerequisites: barracks.upgraded

View File

@@ -25,7 +25,7 @@ E1:
AttackFrontal: AttackFrontal:
Voice: Attack Voice: Attack
WithInfantryBody: WithInfantryBody:
AttackSequence: attack DefaultAttackSequence: attack
ProducibleWithLevel: ProducibleWithLevel:
Prerequisites: barracks.upgraded Prerequisites: barracks.upgraded
RenderSprites: RenderSprites: