diff --git a/OpenRA.Game/Selection.cs b/OpenRA.Game/Selection.cs index a3aefed01a..7b47d03fe8 100644 --- a/OpenRA.Game/Selection.cs +++ b/OpenRA.Game/Selection.cs @@ -57,9 +57,21 @@ namespace OpenRA } } - var voicedActor = actors.FirstOrDefault(a => a.Owner == world.LocalPlayer && a.IsInWorld && a.HasTrait()); - if (voicedActor != null) - voicedActor.PlayVoice("Select"); + // Play the selection voice from one of the selected actors + // TODO: This probably should only be considering the newly selected actors + // TODO: Ship this into an INotifySelection trait to remove the engine dependency on Selectable + foreach (var actor in actors) + { + if (actor.Owner != world.LocalPlayer || !actor.IsInWorld) + continue; + + var selectable = actor.Info.Traits.GetOrDefault(); + if (selectable == null || !actor.HasVoice(selectable.Voice)) + continue; + + actor.PlayVoice(selectable.Voice); + break; + } foreach (var a in newSelection) foreach (var sel in a.TraitsImplementing()) diff --git a/OpenRA.Game/Sound/Sound.cs b/OpenRA.Game/Sound/Sound.cs index 5af665c5d7..0240737948 100644 --- a/OpenRA.Game/Sound/Sound.cs +++ b/OpenRA.Game/Sound/Sound.cs @@ -324,12 +324,6 @@ namespace OpenRA if (voicedActor != null) { - if (!rules.VoicePools.Value.ContainsKey("Attack")) - rules.VoicePools.Value.Add("Attack", rules.VoicePools.Value["Move"]); - - if (!rules.VoicePools.Value.ContainsKey("AttackMove")) - rules.VoicePools.Value.Add("AttackMove", rules.VoicePools.Value["Move"]); - if (!rules.VoicePools.Value.ContainsKey(definition)) throw new InvalidOperationException("Can't find {0} in voice pool.".F(definition)); diff --git a/OpenRA.Game/Traits/LintAttributes.cs b/OpenRA.Game/Traits/LintAttributes.cs index 393243fb3c..5a72b07a82 100644 --- a/OpenRA.Game/Traits/LintAttributes.cs +++ b/OpenRA.Game/Traits/LintAttributes.cs @@ -20,6 +20,9 @@ namespace OpenRA.Traits [AttributeUsage(AttributeTargets.Field)] public sealed class WeaponReferenceAttribute : Attribute { } + [AttributeUsage(AttributeTargets.Field)] + public sealed class VoiceSetReferenceAttribute : Attribute { } + [AttributeUsage(AttributeTargets.Field)] public sealed class VoiceReferenceAttribute : Attribute { } } diff --git a/OpenRA.Game/Traits/Selectable.cs b/OpenRA.Game/Traits/Selectable.cs index 727515a047..801ab3a0f7 100644 --- a/OpenRA.Game/Traits/Selectable.cs +++ b/OpenRA.Game/Traits/Selectable.cs @@ -22,6 +22,8 @@ namespace OpenRA.Traits + "Defaults to the actor name when not defined or inherited.")] public readonly string Class = null; + [VoiceReference] public readonly string Voice = "Select"; + public object Create(ActorInitializer init) { return new Selectable(init.Self, this); } } @@ -29,9 +31,12 @@ namespace OpenRA.Traits { public readonly string Class = null; + public SelectableInfo Info; + public Selectable(Actor self, SelectableInfo info) { Class = string.IsNullOrEmpty(info.Class) ? self.Info.Name : info.Class; + Info = info; } } } diff --git a/OpenRA.Mods.Common/Lint/CheckActorReferences.cs b/OpenRA.Mods.Common/Lint/CheckActorReferences.cs index f59d51bf58..a253fa8b11 100644 --- a/OpenRA.Mods.Common/Lint/CheckActorReferences.cs +++ b/OpenRA.Mods.Common/Lint/CheckActorReferences.cs @@ -36,7 +36,7 @@ namespace OpenRA.Mods.Common.Lint CheckReference(actorInfo, traitInfo, field, map.Rules.Actors, "actor"); if (field.HasAttribute()) CheckReference(actorInfo, traitInfo, field, map.Rules.Weapons, "weapon"); - if (field.HasAttribute()) + if (field.HasAttribute()) CheckReference(actorInfo, traitInfo, field, map.Rules.Voices, "voice"); } } diff --git a/OpenRA.Mods.Common/Lint/CheckVoiceReferences.cs b/OpenRA.Mods.Common/Lint/CheckVoiceReferences.cs new file mode 100644 index 0000000000..0acf1b77ce --- /dev/null +++ b/OpenRA.Mods.Common/Lint/CheckVoiceReferences.cs @@ -0,0 +1,64 @@ +#region Copyright & License Information +/* + * Copyright 2007-2015 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; +using System.Linq; +using System.Reflection; +using OpenRA.Traits; + +namespace OpenRA.Mods.Common.Lint +{ + public class CheckVoiceReferences : ILintPass + { + public void Run(Action emitError, Action emitWarning, Map map) + { + foreach (var actorInfo in map.Rules.Actors) + { + foreach (var traitInfo in actorInfo.Value.Traits.WithInterface()) + { + var fields = traitInfo.GetType().GetFields().Where(f => f.HasAttribute()); + foreach (var field in fields) + { + var voiceSets = LintExts.GetFieldValues(traitInfo, field, emitError); + foreach (var voiceSet in voiceSets) + { + if (string.IsNullOrEmpty(voiceSet)) + continue; + + CheckVoices(actorInfo.Value, emitError, map, voiceSet); + } + } + } + } + } + + void CheckVoices(ActorInfo actorInfo, Action emitError, Map map, string voiceSet) + { + var soundInfo = map.Rules.Voices[voiceSet.ToLowerInvariant()]; + + foreach (var traitInfo in actorInfo.Traits.WithInterface()) + { + var fields = traitInfo.GetType().GetFields().Where(f => f.HasAttribute()); + foreach (var field in fields) + { + var voices = LintExts.GetFieldValues(traitInfo, field, emitError); + foreach (var voice in voices) + { + if (string.IsNullOrEmpty(voice)) + continue; + + if (!soundInfo.Voices.Keys.Contains(voice)) + emitError("Actor {0} using voice set {1} does not define {2} voice required by {3}.".F(actorInfo.Name, voiceSet, voice, traitInfo)); + } + } + } + } + } +} \ No newline at end of file diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index 88c7471ccc..7ddbb3a6a0 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -185,6 +185,7 @@ + diff --git a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs index e578e6a949..3cdc4ed4bc 100644 --- a/OpenRA.Mods.Common/Traits/Air/Aircraft.cs +++ b/OpenRA.Mods.Common/Traits/Air/Aircraft.cs @@ -44,6 +44,8 @@ namespace OpenRA.Mods.Common.Traits public int GetInitialFacing() { return InitialFacing; } public WRange GetCruiseAltitude() { return CruiseAltitude; } + [VoiceReference] public readonly string Voice = "Action"; + public IReadOnlyDictionary OccupiedCells(ActorInfo info, CPos location, SubCell subCell = SubCell.Any) { return new ReadOnlyDictionary(); } bool IOccupySpaceInfo.SharesCell { get { return false; } } } @@ -300,7 +302,7 @@ namespace OpenRA.Mods.Common.Traits case "Enter": case "ReturnToBase": case "Stop": - return "Move"; + return info.Voice; default: return null; } } diff --git a/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs b/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs index 39efb4e5bb..369e8689bf 100644 --- a/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs +++ b/OpenRA.Mods.Common/Traits/Attack/AttackBase.cs @@ -32,6 +32,8 @@ namespace OpenRA.Mods.Common.Traits [Desc("Does not care about shroud or fog. Enables the actor to launch an attack against a target even if he has no visibility of it.")] public readonly bool IgnoresVisibility = false; + [VoiceReference] public readonly string Voice = "Action"; + public abstract object Create(ActorInitializer init); } @@ -141,7 +143,7 @@ namespace OpenRA.Mods.Common.Traits public string VoicePhraseForOrder(Actor self, Order order) { - return order.OrderString == "Attack" ? "Attack" : null; + return order.OrderString == "Attack" ? Info.Voice : null; } public abstract Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove); diff --git a/OpenRA.Mods.Common/Traits/AttackMove.cs b/OpenRA.Mods.Common/Traits/AttackMove.cs index c8eccf938e..0ba7203938 100644 --- a/OpenRA.Mods.Common/Traits/AttackMove.cs +++ b/OpenRA.Mods.Common/Traits/AttackMove.cs @@ -18,6 +18,8 @@ namespace OpenRA.Mods.Common.Traits [Desc("Provides access to the attack-move command, which will make the actor automatically engage viable targets while moving to the destination.")] class AttackMoveInfo : ITraitInfo { + [VoiceReference] public readonly string Voice = "Action"; + public object Create(ActorInitializer init) { return new AttackMove(init.Self, this); } } @@ -27,16 +29,18 @@ namespace OpenRA.Mods.Common.Traits public CPos? TargetLocation = null; readonly IMove move; + readonly AttackMoveInfo info; public AttackMove(Actor self, AttackMoveInfo info) { move = self.Trait(); + this.info = info; } public string VoicePhraseForOrder(Actor self, Order order) { if (order.OrderString == "AttackMove") - return "AttackMove"; + return info.Voice; return null; } diff --git a/OpenRA.Mods.Common/Traits/C4Demolition.cs b/OpenRA.Mods.Common/Traits/C4Demolition.cs index e0cc121c40..a7183d3d63 100644 --- a/OpenRA.Mods.Common/Traits/C4Demolition.cs +++ b/OpenRA.Mods.Common/Traits/C4Demolition.cs @@ -22,16 +22,21 @@ namespace OpenRA.Mods.Common.Traits [Desc("Delay to demolish the target once the C4 is planted." + "Measured in game ticks. Default is 1.8 seconds.")] public readonly int C4Delay = 45; + [Desc("Number of times to flash the target")] public readonly int Flashes = 3; + [Desc("Delay before the flashing starts")] public readonly int FlashesDelay = 4; + [Desc("Interval between each flash")] public readonly int FlashInterval = 4; + [Desc("Duration of each flash")] public readonly int FlashDuration = 3; + [Desc("Voice string when planting explosive charges.")] - public readonly string Voice = "Attack"; + [VoiceReference] public readonly string Voice = "Action"; public object Create(ActorInitializer init) { return new C4Demolition(this); } } diff --git a/OpenRA.Mods.Common/Traits/Captures.cs b/OpenRA.Mods.Common/Traits/Captures.cs index c3c6da1745..aebdf65cff 100644 --- a/OpenRA.Mods.Common/Traits/Captures.cs +++ b/OpenRA.Mods.Common/Traits/Captures.cs @@ -26,6 +26,8 @@ namespace OpenRA.Mods.Common.Traits [Desc("Only used if Sabotage=true. Sabotage damage expressed as a percentage of enemy health removed.")] public readonly float SabotageHPRemoval = 0.5f; + [VoiceReference] public readonly string Voice = "Action"; + public object Create(ActorInitializer init) { return new Captures(init.Self, this); } } @@ -59,7 +61,7 @@ namespace OpenRA.Mods.Common.Traits public string VoicePhraseForOrder(Actor self, Order order) { - return order.OrderString == "CaptureActor" ? "Attack" : null; + return order.OrderString == "CaptureActor" ? Info.Voice : null; } public void ResolveOrder(Actor self, Order order) diff --git a/OpenRA.Mods.Common/Traits/Cargo.cs b/OpenRA.Mods.Common/Traits/Cargo.cs index c8b430b097..598901f189 100644 --- a/OpenRA.Mods.Common/Traits/Cargo.cs +++ b/OpenRA.Mods.Common/Traits/Cargo.cs @@ -40,7 +40,7 @@ namespace OpenRA.Mods.Common.Traits public readonly string[] UnloadTerrainTypes = { }; [Desc("Voice to play when ordered to unload the passengers.")] - public readonly string UnloadVoice = "Unload"; + [VoiceReference] public readonly string UnloadVoice = "Action"; [Desc("Which direction the passenger will face (relative to the transport) when unloading.")] public readonly int PassengerFacing = 128; diff --git a/OpenRA.Mods.Common/Traits/EngineerRepair.cs b/OpenRA.Mods.Common/Traits/EngineerRepair.cs index 461957136e..ea4cff0c51 100644 --- a/OpenRA.Mods.Common/Traits/EngineerRepair.cs +++ b/OpenRA.Mods.Common/Traits/EngineerRepair.cs @@ -17,10 +17,22 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { [Desc("Can instantly repair other actors, but gets consumed afterwards.")] - class EngineerRepairInfo : TraitInfo { } + class EngineerRepairInfo : ITraitInfo + { + [VoiceReference] public readonly string Voice = "Action"; + + public object Create(ActorInitializer init) { return new EngineerRepair(init, this); } + } class EngineerRepair : IIssueOrder, IResolveOrder, IOrderVoice { + readonly EngineerRepairInfo info; + + public EngineerRepair(ActorInitializer init, EngineerRepairInfo info) + { + this.info = info; + } + public IEnumerable Orders { get { yield return new EngineerRepairOrderTargeter(); } @@ -63,7 +75,7 @@ namespace OpenRA.Mods.Common.Traits public string VoicePhraseForOrder(Actor self, Order order) { return order.OrderString == "EngineerRepair" && IsValidOrder(self, order) - ? "Attack" : null; + ? info.Voice : null; } public void ResolveOrder(Actor self, Order order) diff --git a/OpenRA.Mods.Common/Traits/ExternalCaptures.cs b/OpenRA.Mods.Common/Traits/ExternalCaptures.cs index cd5302fe97..53e2ed7313 100644 --- a/OpenRA.Mods.Common/Traits/ExternalCaptures.cs +++ b/OpenRA.Mods.Common/Traits/ExternalCaptures.cs @@ -21,9 +21,12 @@ namespace OpenRA.Mods.Common.Traits { [Desc("Types of actors that it can capture, as long as the type also exists in the ExternalCapturable Type: trait.")] public readonly string[] CaptureTypes = { "building" }; + [Desc("Destroy the unit after capturing.")] public readonly bool ConsumeActor = false; + [VoiceReference] public readonly string Voice = "Action"; + public object Create(ActorInitializer init) { return new ExternalCaptures(init.Self, this); } } @@ -83,7 +86,7 @@ namespace OpenRA.Mods.Common.Traits public string VoicePhraseForOrder(Actor self, Order order) { return order.OrderString == "ExternalCaptureActor" && IsValidOrder(self, order) - ? "Attack" : null; + ? Info.Voice : null; } public void ResolveOrder(Actor self, Order order) diff --git a/OpenRA.Mods.Common/Traits/Guard.cs b/OpenRA.Mods.Common/Traits/Guard.cs index 0c856daec6..9ff2113b1d 100644 --- a/OpenRA.Mods.Common/Traits/Guard.cs +++ b/OpenRA.Mods.Common/Traits/Guard.cs @@ -21,7 +21,7 @@ namespace OpenRA.Mods.Common.Traits [Desc("The player can give this unit the order to follow and protect friendly units with the Guardable trait.")] public class GuardInfo : ITraitInfo { - public readonly string Voice = "Move"; + [VoiceReference] public readonly string Voice = "Action"; public object Create(ActorInitializer init) { return new Guard(this); } } diff --git a/OpenRA.Mods.Common/Traits/Harvester.cs b/OpenRA.Mods.Common/Traits/Harvester.cs index a923ddce0c..10cbf43b15 100644 --- a/OpenRA.Mods.Common/Traits/Harvester.cs +++ b/OpenRA.Mods.Common/Traits/Harvester.cs @@ -22,23 +22,35 @@ namespace OpenRA.Mods.Common.Traits public class HarvesterInfo : ITraitInfo { public readonly string[] DeliveryBuildings = { }; + [Desc("How much resources it can carry.")] public readonly int Capacity = 28; + public readonly int LoadTicksPerBale = 4; + [Desc("How fast it can dump it's carryage.")] public readonly int UnloadTicksPerBale = 4; + [Desc("How many squares to show the fill level.")] public readonly int PipCount = 7; + public readonly int HarvestFacings = 0; + [Desc("Which resources it can harvest.")] public readonly string[] Resources = { }; + [Desc("Percentage of maximum speed when fully loaded.")] public readonly int FullyLoadedSpeed = 85; + [Desc("Initial search radius (in cells) from the refinery that created us.")] public readonly int SearchFromProcRadius = 24; + [Desc("Search radius (in cells) from the last harvest order location to find more resources.")] public readonly int SearchFromOrderRadius = 12; + [VoiceReference] public readonly string HarvestVoice = "Action"; + [VoiceReference] public readonly string DeliverVoice = "Action"; + public object Create(ActorInitializer init) { return new Harvester(init.Self, this); } } @@ -270,7 +282,13 @@ namespace OpenRA.Mods.Common.Traits public string VoicePhraseForOrder(Actor self, Order order) { - return (order.OrderString == "Harvest" || (order.OrderString == "Deliver" && !IsEmpty)) ? "Move" : null; + if (order.OrderString == "Harvest") + return info.HarvestVoice; + + if (order.OrderString == "Deliver" && !IsEmpty) + return info.DeliverVoice; + + return null; } public void ResolveOrder(Actor self, Order order) diff --git a/OpenRA.Mods.Common/Traits/Mobile.cs b/OpenRA.Mods.Common/Traits/Mobile.cs index f0240d38b9..d460930e22 100644 --- a/OpenRA.Mods.Common/Traits/Mobile.cs +++ b/OpenRA.Mods.Common/Traits/Mobile.cs @@ -61,6 +61,8 @@ namespace OpenRA.Mods.Common.Traits public readonly string Cursor = "move"; public readonly string BlockedCursor = "move-blocked"; + [VoiceReference] public readonly string Voice = "Action"; + public virtual object Create(ActorInitializer init) { return new Mobile(init, this); } static object LoadSpeeds(MiniYaml y) @@ -533,7 +535,7 @@ namespace OpenRA.Mods.Common.Traits case "Move": case "Scatter": case "Stop": - return "Move"; + return Info.Voice; default: return null; } diff --git a/OpenRA.Mods.Common/Traits/Passenger.cs b/OpenRA.Mods.Common/Traits/Passenger.cs index a829b7df92..8fad87167d 100644 --- a/OpenRA.Mods.Common/Traits/Passenger.cs +++ b/OpenRA.Mods.Common/Traits/Passenger.cs @@ -103,6 +103,8 @@ namespace OpenRA.Mods.Common.Traits [Desc("Upgrade types to grant to transport.")] public readonly string[] GrantUpgrades = { }; + [VoiceReference] public readonly string Voice = "Action"; + public object Create(ActorInitializer init) { return new Passenger(this); } } @@ -154,7 +156,7 @@ namespace OpenRA.Mods.Common.Traits { if ((order.OrderString != "EnterTransport" && order.OrderString != "EnterTransports") || !CanEnter(order.TargetActor)) return null; - return "Move"; + return Info.Voice; } public void ResolveOrder(Actor self, Order order) diff --git a/OpenRA.Mods.Common/Traits/Repairable.cs b/OpenRA.Mods.Common/Traits/Repairable.cs index 665432616c..a0b25009c7 100644 --- a/OpenRA.Mods.Common/Traits/Repairable.cs +++ b/OpenRA.Mods.Common/Traits/Repairable.cs @@ -22,6 +22,9 @@ namespace OpenRA.Mods.Common.Traits class RepairableInfo : ITraitInfo, Requires { public readonly string[] RepairBuildings = { "fix" }; + + [VoiceReference] public readonly string Voice = "Action"; + public virtual object Create(ActorInitializer init) { return new Repairable(init.Self, this); } } @@ -76,7 +79,7 @@ namespace OpenRA.Mods.Common.Traits public string VoicePhraseForOrder(Actor self, Order order) { - return (order.OrderString == "Repair" && CanRepair()) ? "Move" : null; + return (order.OrderString == "Repair" && CanRepair()) ? info.Voice : null; } public void ResolveOrder(Actor self, Order order) diff --git a/OpenRA.Mods.Common/Traits/RepairsBridges.cs b/OpenRA.Mods.Common/Traits/RepairsBridges.cs index e66e7c2831..31fc51bd24 100644 --- a/OpenRA.Mods.Common/Traits/RepairsBridges.cs +++ b/OpenRA.Mods.Common/Traits/RepairsBridges.cs @@ -17,10 +17,22 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { [Desc("Can enter a BridgeHut to trigger a repair.")] - class RepairsBridgesInfo : TraitInfo { } + class RepairsBridgesInfo : ITraitInfo + { + [VoiceReference] public readonly string Voice = "Action"; + + public object Create(ActorInitializer init) { return new RepairsBridges(this); } + } class RepairsBridges : IIssueOrder, IResolveOrder, IOrderVoice { + readonly RepairsBridgesInfo info; + + public RepairsBridges(RepairsBridgesInfo info) + { + this.info = info; + } + public IEnumerable Orders { get { yield return new RepairBridgeOrderTargeter(); } @@ -43,7 +55,7 @@ namespace OpenRA.Mods.Common.Traits if (hut == null) return null; - return hut.BridgeDamageState == DamageState.Undamaged || hut.Repairing || hut.Bridge.IsDangling ? null : "Attack"; + return hut.BridgeDamageState == DamageState.Undamaged || hut.Repairing || hut.Bridge.IsDangling ? null : info.Voice; } public void ResolveOrder(Actor self, Order order) diff --git a/OpenRA.Mods.Common/Traits/SupplyTruck.cs b/OpenRA.Mods.Common/Traits/SupplyTruck.cs index acfad395d5..c80a63ddde 100644 --- a/OpenRA.Mods.Common/Traits/SupplyTruck.cs +++ b/OpenRA.Mods.Common/Traits/SupplyTruck.cs @@ -21,6 +21,9 @@ namespace OpenRA.Mods.Common.Traits { [Desc("The amount of cash the owner recieves.")] public readonly int Payload = 500; + + [VoiceReference] public readonly string Voice = "Action"; + public object Create(ActorInitializer init) { return new SupplyTruck(this); } } @@ -51,7 +54,7 @@ namespace OpenRA.Mods.Common.Traits public string VoicePhraseForOrder(Actor self, Order order) { - return "Move"; + return info.Voice; } public void ResolveOrder(Actor self, Order order) diff --git a/OpenRA.Mods.Common/Traits/Transforms.cs b/OpenRA.Mods.Common/Traits/Transforms.cs index c3f4845593..a6acd7d661 100644 --- a/OpenRA.Mods.Common/Traits/Transforms.cs +++ b/OpenRA.Mods.Common/Traits/Transforms.cs @@ -45,6 +45,8 @@ namespace OpenRA.Mods.Common.Traits [Desc("Cursor to display when unable to (un)deploy the actor.")] public readonly string DeployBlockedCursor = "deploy-blocked"; + [VoiceReference] public readonly string Voice = "Action"; + public virtual object Create(ActorInitializer init) { return new Transforms(init, this); } } @@ -65,7 +67,7 @@ namespace OpenRA.Mods.Common.Traits public string VoicePhraseForOrder(Actor self, Order order) { - return (order.OrderString == "DeployTransform") ? "Move" : null; + return (order.OrderString == "DeployTransform") ? info.Voice : null; } bool CanDeploy() diff --git a/OpenRA.Mods.Common/Traits/Voiced.cs b/OpenRA.Mods.Common/Traits/Voiced.cs index e6359aabe2..1a12a474cb 100644 --- a/OpenRA.Mods.Common/Traits/Voiced.cs +++ b/OpenRA.Mods.Common/Traits/Voiced.cs @@ -19,7 +19,7 @@ namespace OpenRA.Mods.Common.Traits public class VoicedInfo : ITraitInfo { [Desc("Which voice set to use.")] - [VoiceReference] public readonly string VoiceSet = null; + [VoiceSetReference] public readonly string VoiceSet = null; [Desc("Multiply volume with this factor.")] public readonly float Volume = 1f; diff --git a/OpenRA.Mods.RA/Traits/DemoTruck.cs b/OpenRA.Mods.RA/Traits/DemoTruck.cs index 813771d507..9b50d545c7 100644 --- a/OpenRA.Mods.RA/Traits/DemoTruck.cs +++ b/OpenRA.Mods.RA/Traits/DemoTruck.cs @@ -19,10 +19,22 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Traits { - class DemoTruckInfo : TraitInfo, Requires { } + class DemoTruckInfo : ITraitInfo, Requires + { + [VoiceReference] public readonly string Voice = "Action"; + + public object Create(ActorInitializer init) { return new DemoTruck(init.Self, this); } + } class DemoTruck : IIssueOrder, IResolveOrder, IOrderVoice { + readonly DemoTruckInfo info; + + public DemoTruck(Actor self, DemoTruckInfo info) + { + this.info = info; + } + static void Explode(Actor self) { self.World.AddFrameEndTask(w => self.InflictDamage(self, int.MaxValue, null)); @@ -50,7 +62,7 @@ namespace OpenRA.Mods.RA.Traits public string VoicePhraseForOrder(Actor self, Order order) { - return "Attack"; + return info.Voice; } public void ResolveOrder(Actor self, Order order) diff --git a/OpenRA.Mods.RA/Traits/Disguise.cs b/OpenRA.Mods.RA/Traits/Disguise.cs index 0a4f9f6bd4..3fe169f14a 100644 --- a/OpenRA.Mods.RA/Traits/Disguise.cs +++ b/OpenRA.Mods.RA/Traits/Disguise.cs @@ -57,10 +57,22 @@ namespace OpenRA.Mods.RA.Traits } [Desc("Provides access to the disguise command, which makes the actor appear to be another player's actor.")] - class DisguiseInfo : TraitInfo { } + class DisguiseInfo : ITraitInfo + { + [VoiceReference] public readonly string Voice = "Action"; + + public object Create(ActorInitializer init) { return new Disguise(init.Self, this); } + } class Disguise : IEffectiveOwner, IIssueOrder, IResolveOrder, IOrderVoice, IRadarColorModifier, INotifyAttack { + readonly DisguiseInfo info; + + public Disguise(Actor self, DisguiseInfo info) + { + this.info = info; + } + public Player AsPlayer { get; private set; } public string AsSprite { get; private set; } public ITooltipInfo AsTooltipInfo { get; private set; } @@ -95,7 +107,7 @@ namespace OpenRA.Mods.RA.Traits public string VoicePhraseForOrder(Actor self, Order order) { - return order.OrderString == "Disguise" ? "Attack" : null; + return order.OrderString == "Disguise" ? info.Voice : null; } public Color RadarColorOverride(Actor self) diff --git a/OpenRA.Mods.RA/Traits/Infiltration/Infiltrates.cs b/OpenRA.Mods.RA/Traits/Infiltration/Infiltrates.cs index 4c70ee10b3..dbdfa7015d 100644 --- a/OpenRA.Mods.RA/Traits/Infiltration/Infiltrates.cs +++ b/OpenRA.Mods.RA/Traits/Infiltration/Infiltrates.cs @@ -22,6 +22,8 @@ namespace OpenRA.Mods.RA.Traits { public readonly string[] Types = { }; + [VoiceReference] public readonly string Voice = "Action"; + public object Create(ActorInitializer init) { return new Infiltrates(this); } } @@ -81,7 +83,7 @@ namespace OpenRA.Mods.RA.Traits public string VoicePhraseForOrder(Actor self, Order order) { return order.OrderString == "Infiltrate" && IsValidOrder(self, order) - ? "Attack" : null; + ? info.Voice : null; } public void ResolveOrder(Actor self, Order order) diff --git a/OpenRA.Mods.RA/Traits/MadTank.cs b/OpenRA.Mods.RA/Traits/MadTank.cs index c11e7098ae..886b08384d 100644 --- a/OpenRA.Mods.RA/Traits/MadTank.cs +++ b/OpenRA.Mods.RA/Traits/MadTank.cs @@ -45,6 +45,8 @@ namespace OpenRA.Mods.RA.Traits [ActorReference] public readonly string DriverActor = "e1"; + [VoiceReference] public readonly string Voice = "Action"; + public object Create(ActorInitializer init) { return new MadTank(init.Self, this); } } @@ -107,7 +109,7 @@ namespace OpenRA.Mods.RA.Traits public string VoicePhraseForOrder(Actor self, Order order) { - return "Attack"; + return info.Voice; } void Detonate() diff --git a/OpenRA.Mods.RA/Traits/PortableChrono.cs b/OpenRA.Mods.RA/Traits/PortableChrono.cs index 3c67999a08..c1065a5527 100644 --- a/OpenRA.Mods.RA/Traits/PortableChrono.cs +++ b/OpenRA.Mods.RA/Traits/PortableChrono.cs @@ -41,6 +41,8 @@ namespace OpenRA.Mods.RA.Traits [Desc("Cursor to display when unable to deploy the actor.")] public readonly string DeployBlockedCursor = "deploy-blocked"; + [VoiceReference] public readonly string Voice = "Action"; + public object Create(ActorInitializer init) { return new PortableChrono(this); } } @@ -93,7 +95,7 @@ namespace OpenRA.Mods.RA.Traits public string VoicePhraseForOrder(Actor self, Order order) { - return order.OrderString == "PortableChronoTeleport" && CanTeleport ? "Move" : null; + return order.OrderString == "PortableChronoTeleport" && CanTeleport ? Info.Voice : null; } public void ResetChargeTime() diff --git a/mods/cnc/audio/voices.yaml b/mods/cnc/audio/voices.yaml index c69770bf45..747163cc81 100644 --- a/mods/cnc/audio/voices.yaml +++ b/mods/cnc/audio/voices.yaml @@ -4,7 +4,7 @@ GenericVoice: gdi: .v01,.v03 Voices: Select: await1,ready,report1,yessir1 - Move: ackno,affirm1,noprob,ritaway,roger,ugotit + Action: ackno,affirm1,noprob,ritaway,roger,ugotit Die: nuyell1,nuyell4,nuyell5,nuyell6 Burned: yell1 Zapped: nuyell3 @@ -17,13 +17,13 @@ VehicleVoice: gdi: .v00,.v02 Voices: Select: vehic1,yessir1,report1,await1,unit1 - Move: ackno,affirm1,movout1 + Action: ackno,affirm1,movout1 Unload: movout1 CivilianMaleVoice: Voices: Select: guyyeah1 - Move: guyokay1 + Action: guyokay1 Die: nuyell1,nuyell4,nuyell5,nuyell6 Burned: yell1 Zapped: nuyell3 @@ -32,7 +32,7 @@ CivilianMaleVoice: CivilianFemaleVoice: Voices: Select: girlyeah - Move: girlokay + Action: girlokay Die: nuyell1,nuyell4,nuyell5,nuyell6 Burned: yell1 Zapped: nuyell3 diff --git a/mods/cnc/rules/aircraft.yaml b/mods/cnc/rules/aircraft.yaml index 35128e930d..1078f8bcaa 100644 --- a/mods/cnc/rules/aircraft.yaml +++ b/mods/cnc/rules/aircraft.yaml @@ -170,6 +170,7 @@ C17: PipCount: 10 Invulnerable: -Selectable: + -Voiced: -TargetableUnit: -GainsExperience: FlyAwayOnIdle: @@ -219,6 +220,7 @@ A10: Weapon: Napalm LocalOffset: 0,-256,-43, 0,256,-43 -Selectable: + -Voiced: -TargetableUnit: -GainsExperience: FlyAwayOnIdle: diff --git a/mods/cnc/rules/civilian.yaml b/mods/cnc/rules/civilian.yaml index e6e78e2994..3dea3fa881 100644 --- a/mods/cnc/rules/civilian.yaml +++ b/mods/cnc/rules/civilian.yaml @@ -437,6 +437,7 @@ VICE: Tiberium: 100 BlueTiberium: 100 Beach: 60 + Voice: Move SelectionDecorations: VisualBounds: 24,24 Selectable: @@ -446,6 +447,7 @@ VICE: AutoTarget: ScanRadius: 5 AttackMove: + Voice: Attack HiddenUnderFog: GivesExperience: Valued: @@ -458,6 +460,7 @@ VICE: MuzzleSequence: muzzle MuzzleSplitFacings: 8 AttackFrontal: + Voice: Attack AttackWander: WanderMoveRadius: 2 MinMoveDelayInTicks: 25 @@ -467,6 +470,7 @@ VICE: SplitFacings: true CombatDebugOverlay: Guard: + Voice: Move Guardable: UpdatesPlayerStatistics: BodyOrientation: diff --git a/mods/cnc/rules/defaults.yaml b/mods/cnc/rules/defaults.yaml index 9107d871f4..fc2fcffbad 100644 --- a/mods/cnc/rules/defaults.yaml +++ b/mods/cnc/rules/defaults.yaml @@ -300,6 +300,7 @@ Tiberium: 70 BlueTiberium: 70 Beach: 80 + Voice: Move SelectionDecorations: Selectable: Bounds: 24,24 @@ -317,7 +318,9 @@ AutoTarget: ScanRadius: 4 AttackMove: + Voice: Attack AttackFrontal: + Voice: Attack UpdatesPlayerStatistics: Huntable: ScriptTriggers: diff --git a/mods/cnc/rules/infantry.yaml b/mods/cnc/rules/infantry.yaml index 95e1c43bd5..29bb40ef5b 100644 --- a/mods/cnc/rules/infantry.yaml +++ b/mods/cnc/rules/infantry.yaml @@ -179,19 +179,27 @@ RMBO: Queue: Infantry.GDI Mobile: Speed: 71 + Voice: Move + Guard: + Voice: Move Health: HP: 150 Passenger: PipType: Red + Voice: Move RevealsShroud: Range: 6c0 AutoTarget: ScanRadius: 6 C4Demolition: C4Delay: 45 + Voice: Demolish Armament: Weapon: Sniper AttackFrontal: + Voice: Attack + AttackMove: + Voice: Attack TakeCover: WithInfantryBody: IdleSequences: idle1,idle2,idle3 diff --git a/mods/d2k/audio/voices.yaml b/mods/d2k/audio/voices.yaml index d0e3355809..912d23da14 100644 --- a/mods/d2k/audio/voices.yaml +++ b/mods/d2k/audio/voices.yaml @@ -12,12 +12,11 @@ GenericVoice: harkonnen: H Voices: Select: G_SSEL1,G_SSEL2,G_SSEL3 - Move: G_SCONF1,G_SCONF2,G_SCONF3 - Attack: G_SCONF1,G_SCONF2,G_SCONF3 + Action: G_SCONF1,G_SCONF2,G_SCONF3 Die: KILLGUY1,KILLGUY2,KILLGUY3,KILLGUY4,KILLGUY5,KILLGUY6,KILLGUY7,KILLGUY8,KILLGUY9 Guard: I_GUARD - DisablePrefixes: Select, Move, Attack, Die - DisableVariants: Select, Move, Attack, Guard + DisablePrefixes: Select, Action, Die + DisableVariants: Select, Action, Guard VehicleVoice: DefaultVariant: .AUD @@ -27,8 +26,7 @@ VehicleVoice: harkonnen: H Voices: Select: _VSEL1,_VSEL2,_VSEL3 - Move: _VCONF1,_VCONF2,_VCONF3 - Attack: _VCONF1,_VCONF2,_VCONF3 + Action: _VCONF1,_VCONF2,_VCONF3 Guard: I_GUARD InfantryVoice: @@ -43,12 +41,11 @@ InfantryVoice: harkonnen: H Voices: Select: _ISEL1,_ISEL2,_ISEL3 - Move: _ICONF1,_ICONF2,_ICONF3 - Attack: _ICONF1,_ICONF2,_ICONF3 + Action: _ICONF1,_ICONF2,_ICONF3 Die: KILLGUY1,KILLGUY2,KILLGUY3,KILLGUY4,KILLGUY5,KILLGUY6,KILLGUY7,KILLGUY8,KILLGUY9 Guard: I_GUARD DisablePrefixes: Die - DisableVariants: Select, Move, Attack, Guard + DisableVariants: Select, Action, Guard EngineerVoice: DefaultVariant: .AUD @@ -62,11 +59,11 @@ EngineerVoice: harkonnen: H Voices: Select: _ESEL1,_ESEL2,_ESEL3 - Move: _ECONF1,_ECONF2,_ECONF3 + Action: _ECONF1,_ECONF2,_ECONF3 Die: KILLGUY1,KILLGUY2,KILLGUY3,KILLGUY4,KILLGUY5,KILLGUY6,KILLGUY7,KILLGUY8,KILLGUY9 Guard: I_GUARD DisablePrefixes: Die - DisableVariants: Select, Move, Guard + DisableVariants: Select, Action, Guard FremenVoice: DefaultVariant: .AUD @@ -80,12 +77,11 @@ FremenVoice: harkonnen: H Voices: Select: A_FSEL1,A_FSEL2,A_FSEL3, A_SEL4 - Move: A_FCONF1,A_FCONF2,A_FCONF3, A_FCONF4 - Attack: A_FCONF1,A_FCONF2,A_FCONF3, A_FCONF4 + Action: A_FCONF1,A_FCONF2,A_FCONF3, A_FCONF4 Die: KILLGUY1,KILLGUY2,KILLGUY3,KILLGUY4,KILLGUY5,KILLGUY6,KILLGUY7,KILLGUY8,KILLGUY9 Guard: I_GUARD - DisablePrefixes: Select, Move, Attack, Die - DisableVariants: Select, Move, Attack, Guard + DisablePrefixes: Select, Action, Die + DisableVariants: Select, Action, Guard SaboteurVoice: DefaultVariant: .AUD @@ -99,8 +95,8 @@ SaboteurVoice: harkonnen: H Voices: Select: O_SSEL1,O_SSEL2,O_SSEL3 - Move: O_SCONF1,O_SCONF2,O_SCONF3 + Action: O_SCONF1,O_SCONF2,O_SCONF3 Die: KILLGUY1,KILLGUY2,KILLGUY3,KILLGUY4,KILLGUY5,KILLGUY6,KILLGUY7,KILLGUY8,KILLGUY9 Guard: I_GUARD - DisablePrefixes: Select, Move, Die - DisableVariants: Select, Move, Guard \ No newline at end of file + DisablePrefixes: Select, Action, Die + DisableVariants: Select, Action, Guard \ No newline at end of file diff --git a/mods/d2k/rules/aircraft.yaml b/mods/d2k/rules/aircraft.yaml index 263b5ac493..d7366be154 100644 --- a/mods/d2k/rules/aircraft.yaml +++ b/mods/d2k/rules/aircraft.yaml @@ -63,6 +63,7 @@ carryall.infantry: MaxWeight: 5 Types: Infantry -Selectable: + -Voiced: -TargetableAircraft: -GainsExperience: Tooltip: @@ -117,6 +118,7 @@ frigate: -GainsExperience: FlyAwayOnIdle: RejectsOrders: + -Voiced: orni: Inherits: ^Helicopter @@ -172,6 +174,7 @@ orni.bomber: WithFacingSpriteBody: WithShadow: -Selectable: + -Voiced: -GainsExperience: Tooltip: Name: Ornithopter diff --git a/mods/d2k/rules/infantry.yaml b/mods/d2k/rules/infantry.yaml index a415bfe1b6..3b8124d976 100644 --- a/mods/d2k/rules/infantry.yaml +++ b/mods/d2k/rules/infantry.yaml @@ -221,7 +221,6 @@ saboteur: WithInfantryBody: C4Demolition: C4Delay: 45 - Voice: Move -AutoTarget: AttractsWorms: Intensity: 120 diff --git a/mods/ra/audio/voices.yaml b/mods/ra/audio/voices.yaml index 1d828bea0f..e57e3c25a6 100644 --- a/mods/ra/audio/voices.yaml +++ b/mods/ra/audio/voices.yaml @@ -9,7 +9,7 @@ GenericVoice: ukraine: .r01,.r03 Voices: Select: await1,ready,report1,yessir1 - Move: ackno,affirm1,noprob,overout,ritaway,roger,ugotit + Action: ackno,affirm1,noprob,overout,ritaway,roger,ugotit Die: dedman1,dedman2,dedman3,dedman4,dedman5,dedman7,dedman8 Burned: dedman10 Zapped: dedman6 @@ -26,13 +26,12 @@ VehicleVoice: ukraine: .r00,.r02 Voices: Select: vehic1,yessir1,report1,await1 - Move: ackno,affirm1 - Unload: ackno,affirm1 + Action: ackno,affirm1 EngineerVoice: Voices: Select: eengin1,eyessir1 - Move: eaffirm1,emovout1 + Action: eaffirm1,emovout1 Die: dedman1,dedman2,dedman3,dedman4,dedman5,dedman7,dedman8 Burned: dedman10 Zapped: dedman6 @@ -40,7 +39,7 @@ EngineerVoice: MedicVoice: Voices: Select: mrespon1,myessir1 - Move: maffirm1,mmovout1 + Action: maffirm1,mmovout1 Die: dedman1,dedman2,dedman3,dedman4,dedman5,dedman7,dedman8 Burned: dedman10 Zapped: dedman6 @@ -49,7 +48,7 @@ MechanicVoice: Voices: Select: mhuh1,mhowdy1,myes1,mrise1 Move: mboss1,mhear1 - Attack: mhotdig1,mwrench1 + Action: mhotdig1,mwrench1 Die: dedman1,dedman2,dedman3,dedman4,dedman5,dedman7,dedman8 Burned: dedman10 Zapped: dedman6 @@ -58,7 +57,7 @@ TanyaVoice: Voices: Select: yo1,yes1,yeah1 Move: onit1,cmon1,rokroll1 - Attack: tuffguy1,bombit1 + Action: tuffguy1,bombit1 Die: tandeth1 Burned: tandeth1 Zapped: tandeth1 @@ -79,7 +78,7 @@ SpyVoice: Voices: Select: syessir1,scomnd1 Move: sonway1,sindeed1 - Attack: sking1 + Action: sking1 Die: dedman1,dedman2,dedman3,dedman4,dedman5,dedman7,dedman8 Burned: dedman10 Zapped: dedman6 @@ -87,7 +86,7 @@ SpyVoice: ThiefVoice: Voices: Select: swhat1,syeah1 - Move: saffirm1,smout1,sokay1 + Action: saffirm1,smout1,sokay1 Die: dedman1,dedman2,dedman3,dedman4,dedman5,dedman7,dedman8 Burned: dedman10 Zapped: dedman6 @@ -95,7 +94,7 @@ ThiefVoice: CivilianMaleVoice: Voices: Select: guyyeah1 - Move: guyokay1 + Action: guyokay1 Die: dedman1,dedman2,dedman3,dedman4,dedman5,dedman7,dedman8 Burned: dedman10 Zapped: dedman6 @@ -103,7 +102,7 @@ CivilianMaleVoice: CivilianFemaleVoice: Voices: Select: girlyeah - Move: girlokay + Action: girlokay Die: dedman1,dedman2,dedman3,dedman4,dedman5,dedman7,dedman8 Burned: dedman10 Zapped: dedman6 @@ -111,7 +110,7 @@ CivilianFemaleVoice: EinsteinVoice: Voices: Select: einah1 - Move: einok1,einyes1 + Action: einok1,einyes1 Die: dedman1,dedman2,dedman3,dedman4,dedman5,dedman7,dedman8 Burned: dedman10 Zapped: dedman6 @@ -128,8 +127,7 @@ ShokVoice: AntVoice: Voices: Select: antbite - Move: antbite - Attack: antbite + Action: antbite Die: antdie Burned: antdie Zapped: antdie diff --git a/mods/ra/rules/aircraft.yaml b/mods/ra/rules/aircraft.yaml index 56343c4a39..bbb86c7b2d 100644 --- a/mods/ra/rules/aircraft.yaml +++ b/mods/ra/rules/aircraft.yaml @@ -14,6 +14,7 @@ BADR: Cargo: MaxWeight: 10 -Selectable: + -Voiced: -GainsExperience: Tooltip: Name: Badger @@ -53,6 +54,7 @@ BADR.Bomber: Ammo: 7 WithFacingSpriteBody: -Selectable: + -Voiced: -GainsExperience: Tooltip: Name: Badger @@ -348,6 +350,7 @@ U2: WithFacingSpriteBody: AttackBomber: -Selectable: + -Voiced: -TargetableAircraft: -GainsExperience: Contrail@1: diff --git a/mods/ra/rules/infantry.yaml b/mods/ra/rules/infantry.yaml index ed6e532d14..d0b4c516d9 100644 --- a/mods/ra/rules/infantry.yaml +++ b/mods/ra/rules/infantry.yaml @@ -19,11 +19,19 @@ DOG: HP: 12 Mobile: Speed: 99 + Voice: Move + Guard: + Voice: Move + Passenger: + Voice: Move RevealsShroud: Range: 5c0 Armament: Weapon: DogJaw AttackLeap: + Voice: Attack + AttackMove: + Voice: Move TargetableUnit: TargetTypes: Ground, Infantry WithInfantryBody: @@ -203,12 +211,16 @@ SPY: HP: 25 Mobile: Speed: 56 + Voice: Move + -Guard: RevealsShroud: Range: 5c0 Passenger: PipType: Yellow + Voice: Move TakeCover: Disguise: + Voice: Move Infiltrates: Types: SpyInfiltrate -AutoTarget: @@ -219,6 +231,8 @@ SPY: Armament: Weapon: SilencedPPK AttackFrontal: + AttackMove: + Voice: Move Voiced: VoiceSet: SpyVoice @@ -252,6 +266,9 @@ E7: HP: 100 Mobile: Speed: 71 + Voice: Move + Guard: + Voice: Move RevealsShroud: Range: 6c0 C4Demolition: @@ -259,6 +276,7 @@ E7: Voice: Demolish Passenger: PipType: Red + Voice: Move Armament@PRIMARY: Weapon: Colt45 Armament@SECONDARY: @@ -326,16 +344,19 @@ MECH: HP: 80 Mobile: Speed: 56 + Voice: Move RevealsShroud: Range: 3c0 Passenger: PipType: Yellow + Voice: Move AutoHeal: Armament: Weapon: Repair AttackMedic: Cursor: repair OutsideRangeCursor: repair + Voice: Move Captures: CaptureTypes: husk TakeCover: @@ -401,6 +422,16 @@ GNRL: Name: General Selectable: Class: GNRL + Mobile: + Voice: Move + AttackFrontal: + Voice: Attack + AttackMove: + Voice: Move + Passenger: + Voice: Move + Guard: + Voice: Move Voiced: VoiceSet: StavrosVoice @@ -469,6 +500,7 @@ SHOK: HP: 100 Mobile: Speed: 56 + Voice: Move RevealsShroud: Range: 5c0 Armament@PRIMARY: @@ -478,6 +510,13 @@ SHOK: Name: garrisoned Weapon: PortaTesla AttackFrontal: + Voice: Attack + AttackMove: + Voice: Move + Passenger: + Voice: Move + Guard: + Voice: Move TakeCover: WithInfantryBody: IdleSequences: idle1,idle2 diff --git a/mods/ts/audio/voices.yaml b/mods/ts/audio/voices.yaml index a1cc798eba..1971435522 100644 --- a/mods/ts/audio/voices.yaml +++ b/mods/ts/audio/voices.yaml @@ -40,7 +40,7 @@ Medic: Voices: Select: 20-I000, 20-I004, 20-I006 Move: 20-I008, 20-I010, 20-I012 - Attack: 20-I016, 20-I018, 20-I020 + Action: 20-I016, 20-I018, 20-I020 Die: DEDMAN1, DEDMAN3, DEDMAN4, DEDMAN5, DEDMAN6 Burned: DEDMAN2 Zapped: ELECTRO1 @@ -49,7 +49,7 @@ Engineer: Voices: Select: 19-I000, 19-I002, 19-I006 Move: 19-I010, 19-I016 - Attack: 19-I018, 19-I016 + Action: 19-I018, 19-I016 Die: DEDMAN1, DEDMAN3, DEDMAN4, DEDMAN5, DEDMAN6 Burned: DEDMAN2 Zapped: ELECTRO1 @@ -78,7 +78,7 @@ Spy: Voices: Select: 21-I000, 21-I002, 21-I004 Move: 21-I010, 21-I012, 21-I016 - Attack: 21-I010, 21-I012, 21-I022 + Action: 21-I010, 21-I012, 21-I022 # Feedback: 21-I000, 21-I002 # TODO Die: DEDMAN1, DEDMAN3, DEDMAN4, DEDMAN5, DEDMAN6 Burned: DEDMAN2 @@ -88,7 +88,7 @@ Hijacker: Voices: Select: 24-I000, 24-I002, 24-I004, 24-I006 Move: 24-I008, 24-I010, 24-I012, 24-I014 - Attack: 24-I016, 24-I018, 24-I020, 24-I022, 24-I024 + Action: 24-I016, 24-I018, 24-I020, 24-I022, 24-I024 Die: DEDMAN1, DEDMAN3, DEDMAN4, DEDMAN5, DEDMAN6 Burned: DEDMAN2 Zapped: ELECTRO1 @@ -149,9 +149,9 @@ Slavick: Fiend: Voices: - Select: - Move: - Attack: + Select: FIEND1 + Attack: FIEND1 + Move: FIEND1 Die: FIEND1 Burned: FIEND1 Zapped: FIEND1 diff --git a/mods/ts/rules/aircraft.yaml b/mods/ts/rules/aircraft.yaml index cdf343eb56..78d15e151a 100644 --- a/mods/ts/rules/aircraft.yaml +++ b/mods/ts/rules/aircraft.yaml @@ -20,9 +20,11 @@ DPOD: Types: Infantry MaxWeight: 1 PipCount: 1 + UnloadVoice: Move Armament: Weapon: Vulcan2 AttackHeli: + Voice: Attack AmmoPool: Ammo: 5 PipCount: 5 @@ -54,6 +56,7 @@ DSHP: Types: Infantry MaxWeight: 5 PipCount: 5 + UnloadVoice: Move RenderVoxels: WithVoxelBody: Hovers: @@ -85,6 +88,7 @@ ORCA: Weapon: Hellfire AttackHeli: FacingTolerance: 20 + Voice: Attack AmmoPool: Ammo: 5 PipCount: 5 @@ -125,6 +129,7 @@ ORCAB: Armament: Weapon: Bomb AttackPlane: + Voice: Attack FacingTolerance: 20 AmmoPool: Ammo: 10 @@ -163,6 +168,7 @@ ORCATRAN: Types: Infantry MaxWeight: 5 PipCount: 5 + UnloadVoice: Move RenderVoxels: WithVoxelBody: Hovers: @@ -223,6 +229,7 @@ SCRIN: Armament: Weapon: Proton AttackPlane: + Voice: Attack FacingTolerance: 20 AmmoPool: Ammo: 15 @@ -264,6 +271,7 @@ APACHE: Weapon: HarpyClaw AttackHeli: FacingTolerance: 20 + Voice: Attack AmmoPool: Ammo: 12 PipCount: 4 diff --git a/mods/ts/rules/civilian-infantry.yaml b/mods/ts/rules/civilian-infantry.yaml index 663c93b870..45f1d34060 100644 --- a/mods/ts/rules/civilian-infantry.yaml +++ b/mods/ts/rules/civilian-infantry.yaml @@ -16,6 +16,7 @@ WEEDGUY: Weapon: FireballLauncher LocalOffset: 85,0,384 AttackFrontal: + Voice: Attack WithInfantryBody: TakeCover: @@ -39,6 +40,7 @@ UMAGON: Armament: Weapon: Sniper AttackFrontal: + Voice: Attack TakeCover: WithInfantryBody: IdleSequences: idle1,idle2 @@ -86,6 +88,7 @@ MUTANT: Armament: Weapon: Vulcan AttackFrontal: + Voice: Attack TakeCover: WithInfantryBody: IdleSequences: idle1,idle2 @@ -109,6 +112,7 @@ MWMN: Armament: Weapon: Vulcan AttackFrontal: + Voice: Attack TakeCover: WithInfantryBody: IdleSequences: idle1,idle2 @@ -132,6 +136,7 @@ MUTANT3: Armament: Weapon: Vulcan AttackFrontal: + Voice: Attack TakeCover: WithInfantryBody: IdleSequences: idle1,idle2 @@ -218,6 +223,7 @@ DOGGIE: Armament: Weapon: FiendShard AttackFrontal: + Voice: Attack AttackWander: WanderMoveRadius: 2 MinMoveDelayInTicks: 25 @@ -246,6 +252,7 @@ VISLRG: Weapon: SlimeAttack AutoTarget: AttackFrontal: + Voice: Attack AttackWander: WanderMoveRadius: 2 MinMoveDelayInTicks: 25 @@ -260,6 +267,7 @@ CIV1: Armament: Weapon: Pistola AttackFrontal: + Voice: Attack CIV2: Inherits: ^CivilianInfantry @@ -270,4 +278,5 @@ CIV3: Armament: Weapon: Pistola AttackFrontal: + Voice: Attack diff --git a/mods/ts/rules/civilian-vehicles.yaml b/mods/ts/rules/civilian-vehicles.yaml index 40527cbecc..dc266acf40 100644 --- a/mods/ts/rules/civilian-vehicles.yaml +++ b/mods/ts/rules/civilian-vehicles.yaml @@ -24,6 +24,7 @@ Weapon: MammothTusk LocalOffset: 0,256,426, 0,-256,426 AttackTurreted: + Voice: Attack AutoTarget: SelfHealing: Ticks: 10 @@ -76,6 +77,7 @@ ICBM: Facing: 96 TransformSounds: NoTransformSounds: + Voice: Move BUS: Inherits: ^Vehicle @@ -96,6 +98,7 @@ BUS: Types: Infantry MaxWeight: 20 PipCount: 5 + UnloadVoice: Unload RenderVoxels: WithVoxelBody: @@ -118,6 +121,7 @@ PICK: Types: Infantry MaxWeight: 2 PipCount: 5 + UnloadVoice: Unload RenderVoxels: WithVoxelBody: @@ -140,6 +144,7 @@ CAR: Types: Infantry MaxWeight: 4 PipCount: 5 + UnloadVoice: Unload RenderVoxels: WithVoxelBody: @@ -162,5 +167,6 @@ WINI: Types: Infantry MaxWeight: 5 PipCount: 5 + UnloadVoice: Unload RenderVoxels: WithVoxelBody: \ No newline at end of file diff --git a/mods/ts/rules/defaults.yaml b/mods/ts/rules/defaults.yaml index 7a53d3715c..1bca90d77a 100644 --- a/mods/ts/rules/defaults.yaml +++ b/mods/ts/rules/defaults.yaml @@ -213,6 +213,7 @@ Rough: 70 Tiberium: 80 BlueTiberium: 80 + Voice: Move SelectionDecorations: Palette: pips Selectable: @@ -241,8 +242,10 @@ EnergyDeath: 6 AutoTarget: AttackMove: + Voice: Move Passenger: CargoType: Infantry + Voice: Move HiddenUnderFog: GivesExperience: DrawLineToTarget: @@ -259,6 +262,7 @@ UpdatesPlayerStatistics: CombatDebugOverlay: Guard: + Voice: Move Guardable: BodyOrientation: Huntable: @@ -314,6 +318,7 @@ Tiberium: 80 BlueTiberium: 80 ROT: 5 + Voice: Move Selectable: SelectionDecorations: Palette: pips @@ -323,9 +328,12 @@ TargetTypes: Ground, Vehicle Repairable: RepairBuildings: gadept + Voice: Move Passenger: CargoType: Vehicle + Voice: Move AttackMove: + Voice: Move HiddenUnderFog: GivesExperience: DrawLineToTarget: @@ -340,6 +348,7 @@ UpdatesPlayerStatistics: CombatDebugOverlay: Guard: + Voice: Move Guardable: BodyOrientation: CameraPitch: 90 @@ -383,6 +392,7 @@ Tiberium: 80 BlueTiberium: 80 ROT: 5 + Voice: Move Selectable: SelectionDecorations: Palette: pips @@ -392,9 +402,12 @@ TargetTypes: Ground, Vehicle Repairable: RepairBuildings: gadept + Voice: Move Passenger: CargoType: Vehicle + Voice: Move AttackMove: + Voice: Move HiddenUnderFog: GivesExperience: DrawLineToTarget: @@ -409,6 +422,7 @@ UpdatesPlayerStatistics: CombatDebugOverlay: Guard: + Voice: Move Guardable: BodyOrientation: CameraPitch: 90 @@ -455,8 +469,10 @@ RearmBuildings: LandWhenIdle: no CruiseAltitude: 2048 + Voice: Move HiddenUnderFog: AttackMove: + Voice: Move GivesExperience: DrawLineToTarget: ActorLostNotification: @@ -466,6 +482,7 @@ Huntable: ScriptTriggers: Guard: + Voice: Move Guardable: UpgradeManager: MustBeDestroyed: @@ -478,6 +495,7 @@ RearmBuildings: gahpad, nahpad LandWhenIdle: no CruiseAltitude: 2560 + Voice: Move ReturnOnIdle: ^Viceroid: diff --git a/mods/ts/rules/gdi-infantry.yaml b/mods/ts/rules/gdi-infantry.yaml index 4f98062957..cf8aa68a23 100644 --- a/mods/ts/rules/gdi-infantry.yaml +++ b/mods/ts/rules/gdi-infantry.yaml @@ -18,6 +18,7 @@ E2: LocalOffset: 0,0,555 FireDelay: 5 AttackFrontal: + Voice: Attack TakeCover: WithInfantryBody: IdleSequences: idle1,idle2 @@ -43,7 +44,7 @@ MEDIC: CrushSound: squishy2.aud Armament: Weapon: Heal - AttackFrontal: + AttackMedic: TakeCover: WithInfantryBody: IdleSequences: idle1,idle2 @@ -79,6 +80,7 @@ JUMPJET: Weapon: JumpCannon -Crushable: AttackFrontal: + Voice: Attack TakeCover: WithInfantryBody: @@ -111,8 +113,10 @@ GHOST: Crushable: CrushSound: squishy2.aud AttackFrontal: + Voice: Attack C4Demolition: C4Delay: 45 + Voice: Attack TakeCover: WithInfantryBody: IdleSequences: idle1,idle2 diff --git a/mods/ts/rules/gdi-vehicles.yaml b/mods/ts/rules/gdi-vehicles.yaml index eaef2bfeed..0ba93fbc65 100644 --- a/mods/ts/rules/gdi-vehicles.yaml +++ b/mods/ts/rules/gdi-vehicles.yaml @@ -26,6 +26,7 @@ APC: Types: Infantry MaxWeight: 5 PipCount: 5 + UnloadVoice: Unload RenderSprites: RenderVoxels: WithVoxelWaterBody: @@ -69,6 +70,7 @@ HVR: ROT: 7 Offset: -128,0,85 AttackTurreted: + Voice: Attack AutoTarget: RenderSprites: RenderVoxels: @@ -101,6 +103,7 @@ SMECH: RevealsShroud: Range: 6c0 AttackFrontal: + Voice: Attack AutoTarget: Armament: Weapon: AssaultCannon @@ -144,6 +147,7 @@ MMCH: Turreted: ROT: 5 AttackTurreted: + Voice: Attack WithTurret: Recoils: no Armament: @@ -184,6 +188,7 @@ HMEC: Range: 8c0 RenderSprites: AttackFrontal: + Voice: Attack AutoTarget: Armament@MISSILES: Weapon: MammothTusk @@ -220,6 +225,7 @@ SONIC: Weapon: SonicZap LocalOffset: -50,0,410 AttackTurreted: + Voice: Attack Turreted: ROT: 5 Offset: -170,0,0 diff --git a/mods/ts/rules/nod-infantry.yaml b/mods/ts/rules/nod-infantry.yaml index 873ec14e7d..79c386922e 100644 --- a/mods/ts/rules/nod-infantry.yaml +++ b/mods/ts/rules/nod-infantry.yaml @@ -19,6 +19,7 @@ E3: Weapon: Bazooka LocalOffset: 128,0,640 AttackFrontal: + Voice: Attack TakeCover: WithInfantryBody: IdleSequences: idle1,idle2 @@ -53,6 +54,7 @@ CYBORG: Armament: Weapon: Vulcan3 AttackFrontal: + Voice: Attack WithInfantryBody: IdleSequences: idle1,idle2 WithPermanentInjury: @@ -91,6 +93,7 @@ CYC2: Weapon: CyCannon LocalOffset: 170,85,683 AttackFrontal: + Voice: Attack WithInfantryBody: IdleSequences: idle1,idle2 WithPermanentInjury: diff --git a/mods/ts/rules/nod-support.yaml b/mods/ts/rules/nod-support.yaml index bbed7dd7af..446c4ed937 100644 --- a/mods/ts/rules/nod-support.yaml +++ b/mods/ts/rules/nod-support.yaml @@ -191,6 +191,7 @@ GATICK: UpgradeMinEnabledLevel: 1 MuzzleSequence: muzzle AttackTurreted: + Voice: Attack BodyOrientation: QuantizedFacings: 32 AutoTarget: @@ -206,6 +207,7 @@ GATICK: Facing: 159 TransformSounds: place2.aud NoTransformSounds: + Voice: Move WithMuzzleFlash: -WithDeathAnimation: @@ -234,6 +236,7 @@ GAARTY: LocalOffset: 811,0,0 MuzzleSequence: muzzle AttackTurreted: + Voice: Attack BodyOrientation: QuantizedFacings: 32 AutoTarget: @@ -250,6 +253,7 @@ GAARTY: Facing: 96 TransformSounds: place2.aud NoTransformSounds: + Voice: Move WithMuzzleFlash: -WithDeathAnimation: diff --git a/mods/ts/rules/nod-vehicles.yaml b/mods/ts/rules/nod-vehicles.yaml index 90126f8cf3..7a58045bd2 100644 --- a/mods/ts/rules/nod-vehicles.yaml +++ b/mods/ts/rules/nod-vehicles.yaml @@ -24,6 +24,7 @@ BGGY: MuzzleSequence: muzzle MuzzleSplitFacings: 8 AttackFrontal: + Voice: Attack AutoTarget: RenderSprites: RenderVoxels: @@ -62,6 +63,7 @@ BIKE: UpgradeMinEnabledLevel: 1 LocalOffset: -128,-170,213, -128,170,213 AttackFrontal: + Voice: Attack AutoTarget: RenderSprites: RenderVoxels: @@ -87,6 +89,7 @@ TTNK: Armor: Type: Light AttackFrontal: + Voice: Attack Armament@PRIMARY: Weapon: 90mm LocalOffset: 256,0,256 @@ -111,6 +114,7 @@ TTNK: Facing: 159 TransformSounds: place2.aud NoTransformSounds: + Voice: Move ART2: Inherits: ^Tank @@ -141,6 +145,7 @@ ART2: Facing: 96 TransformSounds: NoTransformSounds: + Voice: Move REPAIR: Inherits: ^Tank @@ -165,6 +170,7 @@ REPAIR: AttackMedic: Cursor: repair OutsideRangeCursor: repair + Voice: Attack RenderSprites: RenderVoxels: WithVoxelBody: @@ -218,6 +224,7 @@ SAPC: Types: Infantry MaxWeight: 5 PipCount: 5 + UnloadVoice: Unload RenderSprites: RenderVoxels: WithVoxelBody: @@ -246,6 +253,7 @@ SUBTANK: Armament: Weapon: FireballLauncher AttackFrontal: + Voice: Attack AutoTarget: RenderSprites: RenderVoxels: @@ -281,6 +289,7 @@ STNK: Weapon: Dragon LocalOffset: 213,43,128, 213,-43,128 AttackFrontal: + Voice: Attack AutoTarget: InitialStance: HoldFire RenderSprites: diff --git a/mods/ts/rules/shared-infantry.yaml b/mods/ts/rules/shared-infantry.yaml index 203e930a7a..c21a6731bd 100644 --- a/mods/ts/rules/shared-infantry.yaml +++ b/mods/ts/rules/shared-infantry.yaml @@ -23,6 +23,7 @@ E1: UpgradeTypes: eliteweapon UpgradeMinEnabledLevel: 1 AttackFrontal: + Voice: Attack TakeCover: WithInfantryBody: IdleSequences: idle1,idle2 diff --git a/mods/ts/rules/shared-vehicles.yaml b/mods/ts/rules/shared-vehicles.yaml index 2e6be2ea30..84a273fe8a 100644 --- a/mods/ts/rules/shared-vehicles.yaml +++ b/mods/ts/rules/shared-vehicles.yaml @@ -30,6 +30,7 @@ MCV: Facing: 96 TransformSounds: facbld1.aud NoTransformSounds: + Voice: Move RenderSprites: RenderVoxels: WithVoxelBody: @@ -57,6 +58,8 @@ HARV: UnloadTicksPerBale: 1 SearchFromProcRadius: 24 SearchFromOrderRadius: 12 + HarvestVoice: Attack + DeliverVoice: Move Mobile: Speed: 71 Crushes: wall, crate @@ -117,6 +120,7 @@ LPST: Facing: 159 TransformSounds: NoTransformSounds: + Voice: Move GGHUNT: Inherits: ^Vehicle @@ -135,6 +139,7 @@ GGHUNT: Range: 7c0 WithFacingSpriteBody: DemoTruck: + Voice: Attack Explodes: Weapon: SuicideBomb EmptyWeapon: SuicideBomb