diff --git a/OpenRA.Game/Sound.cs b/OpenRA.Game/Sound.cs index f059789b33..e54fbf4611 100644 --- a/OpenRA.Game/Sound.cs +++ b/OpenRA.Game/Sound.cs @@ -367,6 +367,19 @@ namespace OpenRA var type = mi.Voice.ToLowerInvariant(); return PlayPredefined(null, voicedUnit, type, phrase, variant, true); } + + public static bool PlayVoiceLocal(string phrase, Actor voicedUnit, string variant, WPos pos) + { + if (voicedUnit == null || phrase == null) + return false; + + var mi = voicedUnit.Info.Traits.GetOrDefault(); + if (mi == null || mi.Voice == null) + return false; + + var type = mi.Voice.ToLowerInvariant(); + return PlayPredefined(null, voicedUnit, type, phrase, variant, true); + } public static bool PlayNotification(Player player, string type, string notification, string variant) { diff --git a/OpenRA.Mods.RA/DeathSounds.cs b/OpenRA.Mods.RA/DeathSounds.cs new file mode 100644 index 0000000000..2ab4cef0a2 --- /dev/null +++ b/OpenRA.Mods.RA/DeathSounds.cs @@ -0,0 +1,53 @@ +#region Copyright & License Information +/* + * Copyright 2007-2014 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 COPYING. + */ +#endregion + +using System.Linq; +using OpenRA.Mods.RA.Move; +using OpenRA.Primitives; +using OpenRA.Traits; + +namespace OpenRA.Mods.RA +{ + public class DeathSoundsInfo : ITraitInfo + { + public readonly string DeathVoice = "Die"; + public readonly string Burned = null; + public readonly string Zapped = null; + + public object Create(ActorInitializer init) { return new DeathSounds(this); } + } + + public class DeathSounds : INotifyKilled + { + DeathSoundsInfo info; + + public DeathSounds(DeathSoundsInfo info) { this.info = info; } + + public void Killed(Actor self, AttackInfo e) + { + // Killed by some non-standard means + if (e.Warhead == null) + return; + + var cp = self.CenterPosition; + + // Killed by fire + if (info.Burned != null && e.Warhead.InfDeath == 5) + Sound.Play(info.Burned, cp); + + // Killed by Tesla/Laser zap + if (info.Zapped != null && e.Warhead.InfDeath == 6) + Sound.Play(info.Zapped, cp); + + if ((e.Warhead.InfDeath < 5) || (info.Burned == null && info.Zapped == null)) + Sound.PlayVoiceLocal(info.DeathVoice, self, self.Owner.Country.Race, cp); + } + } +} \ No newline at end of file diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 206ed65fbb..ece8d2c481 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -216,6 +216,7 @@ + diff --git a/OpenRA.Mods.RA/Render/RenderInfantry.cs b/OpenRA.Mods.RA/Render/RenderInfantry.cs index 515cbe59d2..bec3c9a780 100644 --- a/OpenRA.Mods.RA/Render/RenderInfantry.cs +++ b/OpenRA.Mods.RA/Render/RenderInfantry.cs @@ -18,7 +18,7 @@ namespace OpenRA.Mods.RA.Render { public readonly int MinIdleWaitTicks = 30; public readonly int MaxIdleWaitTicks = 110; - public readonly bool UseInfantryDeath = true; + public readonly bool SpawnsCorpse = true; public readonly string[] IdleAnimations = { }; public readonly string[] StandAnimations = { "stand" }; @@ -125,19 +125,17 @@ namespace OpenRA.Mods.RA.Render } } + // TODO: Possibly move this into a separate trait public void Killed(Actor self, AttackInfo e) { // Killed by some non-standard means if (e.Warhead == null) return; - // TODO: Possibly move Die sound out of this Render trait entirely - if (info.UseInfantryDeath == true) + if (info.SpawnsCorpse) { - Sound.PlayVoice("Die", self, self.Owner.Country.Race); SpawnCorpse(self, "die{0}".F(e.Warhead.InfDeath)); - } - + } } public void SpawnCorpse(Actor self, string sequence) diff --git a/mods/cnc/rules/defaults.yaml b/mods/cnc/rules/defaults.yaml index 01a01e3a69..6fc1a5a9b1 100644 --- a/mods/cnc/rules/defaults.yaml +++ b/mods/cnc/rules/defaults.yaml @@ -187,6 +187,8 @@ DetectCloaked: Range: 1 ScriptTriggers: + DeathSounds: + Burned: yell1.aud ^CivInfantry: Inherits: ^Infantry @@ -266,6 +268,7 @@ Huntable: LuaScriptEvents: ScriptTriggers: + DeathSounds: ^Plane: AppearsOnRadar: @@ -588,4 +591,3 @@ BodyOrientation: LuaScriptEvents: ScriptTriggers: - diff --git a/mods/d2k/rules/defaults.yaml b/mods/d2k/rules/defaults.yaml index bb7ecc7d7d..621aaac7ce 100644 --- a/mods/d2k/rules/defaults.yaml +++ b/mods/d2k/rules/defaults.yaml @@ -195,6 +195,7 @@ Huntable: LuaScriptEvents: ScriptTriggers: + DeathSounds: ^Plane: AppearsOnRadar: diff --git a/mods/ra/maps/desert-shellmap/map.yaml b/mods/ra/maps/desert-shellmap/map.yaml index 1277021602..121f522868 100644 --- a/mods/ra/maps/desert-shellmap/map.yaml +++ b/mods/ra/maps/desert-shellmap/map.yaml @@ -1308,7 +1308,8 @@ Rules: SpeedModifier: ^Infantry: ScriptInvulnerable: - -Selectable: # short-term hack to make infantry not play die sounds until we fix RenderInfantry + DeathSounds: + DeathVoice: GivesBounty: Percentage: 0 GainsExperience: diff --git a/mods/ra/rules/defaults.yaml b/mods/ra/rules/defaults.yaml index eedca89b59..32f3932f04 100644 --- a/mods/ra/rules/defaults.yaml +++ b/mods/ra/rules/defaults.yaml @@ -168,6 +168,7 @@ Huntable: LuaScriptEvents: ScriptTriggers: + DeathSounds: ^Ship: AppearsOnRadar: diff --git a/mods/ts/rules/defaults.yaml b/mods/ts/rules/defaults.yaml index 0e18444daf..62fc46a939 100644 --- a/mods/ts/rules/defaults.yaml +++ b/mods/ts/rules/defaults.yaml @@ -132,6 +132,8 @@ Huntable: LuaScriptEvents: ScriptTriggers: + DeathSounds: + Zapped: electro1.aud ^CivilianInfantry: Inherits: ^Infantry diff --git a/mods/ts/rules/vehicles.yaml b/mods/ts/rules/vehicles.yaml index c2d00e4318..9025464ca8 100644 --- a/mods/ts/rules/vehicles.yaml +++ b/mods/ts/rules/vehicles.yaml @@ -480,7 +480,7 @@ MMCH: RevealsShroud: Range: 8c0 RenderInfantry: - UseInfantryDeath: false + SpawnsCorpse: false Turreted: AttackTurreted: WithTurret: @@ -550,7 +550,7 @@ SMECH: Armament: Weapon: AssaultCannon RenderInfantry: - UseInfantryDeath: false + SpawnsCorpse: false Selectable: Voices: Mech