Merge pull request #8012 from reaperrr/voiceset
Extracted actor Voices from Selectable into own Voiced trait
This commit is contained in:
@@ -443,6 +443,7 @@
|
||||
<Compile Include="Traits\Upgrades\UpgradeActorsNear.cs" />
|
||||
<Compile Include="Traits\Upgrades\UpgradeManager.cs" />
|
||||
<Compile Include="Traits\Valued.cs" />
|
||||
<Compile Include="Traits\Voiced.cs" />
|
||||
<Compile Include="Traits\Wanders.cs" />
|
||||
<Compile Include="Traits\World\BridgeLayer.cs" />
|
||||
<Compile Include="Traits\World\CrateSpawner.cs" />
|
||||
|
||||
@@ -39,6 +39,9 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Terrain types that this actor is allowed to eject actors onto. Leave empty for all terrain types.")]
|
||||
public readonly string[] UnloadTerrainTypes = { };
|
||||
|
||||
[Desc("Voice to play when ordered to unload the passengers.")]
|
||||
public readonly string UnloadVoice = "Unload";
|
||||
|
||||
[Desc("Which direction the passenger will face (relative to the transport) when unloading.")]
|
||||
public readonly int PassengerFacing = 128;
|
||||
|
||||
@@ -204,10 +207,10 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public string VoicePhraseForOrder(Actor self, Order order)
|
||||
{
|
||||
if (order.OrderString != "Unload" || IsEmpty(self))
|
||||
if (order.OrderString != "Unload" || IsEmpty(self) || !self.HasVoice(Info.UnloadVoice))
|
||||
return null;
|
||||
|
||||
return self.HasVoice("Unload") ? "Unload" : "Move";
|
||||
return Info.UnloadVoice;
|
||||
}
|
||||
|
||||
public bool MoveDisabled(Actor self) { return reserves.Any(); }
|
||||
|
||||
@@ -13,13 +13,26 @@ using OpenRA.Traits;
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[Desc("Play the Build voice of this actor when trained.")]
|
||||
public class AnnounceOnBuildInfo : TraitInfo<AnnounceOnBuild> { }
|
||||
public class AnnounceOnBuildInfo : ITraitInfo
|
||||
{
|
||||
[Desc("Voice to use when built/trained.")]
|
||||
public readonly string BuildVoice = "Build";
|
||||
|
||||
public object Create(ActorInitializer init) { return new AnnounceOnBuild(init.Self, this); }
|
||||
}
|
||||
|
||||
public class AnnounceOnBuild : INotifyBuildComplete
|
||||
{
|
||||
readonly AnnounceOnBuildInfo info;
|
||||
|
||||
public AnnounceOnBuild(Actor self, AnnounceOnBuildInfo info)
|
||||
{
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public void BuildingComplete(Actor self)
|
||||
{
|
||||
Sound.PlayVoice("Build", self, self.Owner.Country.Race);
|
||||
self.PlayVoice(info.BuildVoice);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,9 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Minimum duration (in seconds) between sound events.")]
|
||||
public readonly int Interval = 5;
|
||||
|
||||
[Desc("Voice to use when killing something.")]
|
||||
public readonly string KillVoice = "Kill";
|
||||
|
||||
public object Create(ActorInitializer init) { return new AnnounceOnKill(init.Self, this); }
|
||||
}
|
||||
|
||||
@@ -39,7 +42,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (e.DamageState == DamageState.Dead && damaged != e.Attacker)
|
||||
{
|
||||
if (self.World.WorldTick - lastAnnounce > info.Interval * 25)
|
||||
Sound.PlayVoice("Kill", self, self.Owner.Country.Race);
|
||||
self.PlayVoice(info.KillVoice);
|
||||
|
||||
lastAnnounce = self.World.WorldTick;
|
||||
}
|
||||
|
||||
@@ -40,11 +40,9 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (e.Warhead == null)
|
||||
return;
|
||||
|
||||
var cp = self.CenterPosition;
|
||||
|
||||
if (info.DeathTypes.Contains(e.Warhead.DeathType) ||
|
||||
(!info.DeathTypes.Any() && !self.Info.Traits.WithInterface<DeathSoundsInfo>().Any(dsi => dsi.DeathTypes.Contains(e.Warhead.DeathType))))
|
||||
Sound.PlayVoiceLocal(info.DeathSound, self, self.Owner.Country.Race, cp, info.VolumeMultiplier);
|
||||
if (info.DeathTypes.Contains(e.Warhead.DeathType) || (!info.DeathTypes.Any() &&
|
||||
!self.Info.Traits.WithInterface<DeathSoundsInfo>().Any(dsi => dsi.DeathTypes.Contains(e.Warhead.DeathType))))
|
||||
self.PlayVoiceLocal(info.DeathSound, info.VolumeMultiplier);
|
||||
}
|
||||
}
|
||||
}
|
||||
75
OpenRA.Mods.Common/Traits/Voiced.cs
Normal file
75
OpenRA.Mods.Common/Traits/Voiced.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
#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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.GameRules;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[Desc("This actor has a voice.")]
|
||||
public class VoicedInfo : ITraitInfo
|
||||
{
|
||||
[Desc("Which voice set to use.")]
|
||||
[VoiceReference] public readonly string VoiceSet = null;
|
||||
|
||||
[Desc("Multiply volume with this factor.")]
|
||||
public readonly float Volume = 1f;
|
||||
|
||||
public object Create(ActorInitializer init) { return new Voiced(init.Self, this); }
|
||||
}
|
||||
|
||||
public class Voiced : IVoiced
|
||||
{
|
||||
public readonly VoicedInfo Info;
|
||||
|
||||
public Voiced(Actor self, VoicedInfo info)
|
||||
{
|
||||
Info = info;
|
||||
}
|
||||
|
||||
public string VoiceSet { get { return Info.VoiceSet; } }
|
||||
|
||||
public bool PlayVoice(Actor self, string phrase, string variant)
|
||||
{
|
||||
if (phrase == null)
|
||||
return false;
|
||||
|
||||
if (string.IsNullOrEmpty(Info.VoiceSet))
|
||||
return false;
|
||||
|
||||
var type = Info.VoiceSet.ToLowerInvariant();
|
||||
var volume = Info.Volume;
|
||||
return Sound.PlayPredefined(self.World.Map.Rules, null, self, type, phrase, variant, true, WPos.Zero, volume, true);
|
||||
}
|
||||
|
||||
public bool PlayVoiceLocal(Actor self, string phrase, string variant, float volume)
|
||||
{
|
||||
if (phrase == null)
|
||||
return false;
|
||||
|
||||
if (string.IsNullOrEmpty(Info.VoiceSet))
|
||||
return false;
|
||||
|
||||
var type = Info.VoiceSet.ToLowerInvariant();
|
||||
return Sound.PlayPredefined(self.World.Map.Rules, null, self, type, phrase, variant, false, self.CenterPosition, volume, true);
|
||||
}
|
||||
|
||||
public bool HasVoice(Actor self, string voice)
|
||||
{
|
||||
if (string.IsNullOrEmpty(Info.VoiceSet))
|
||||
return false;
|
||||
|
||||
var voices = self.World.Map.Rules.Voices[Info.VoiceSet.ToLowerInvariant()];
|
||||
return voices != null && voices.Voices.ContainsKey(voice);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -943,6 +943,28 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
node.Key = node.Key.Replace("ProvidesCustomPrerequisite", "ProvidesPrerequisite");
|
||||
}
|
||||
|
||||
if (engineVersion < 20150509)
|
||||
{
|
||||
if (depth == 0 && node.Value.Nodes.Exists(n => n.Key == "Selectable"))
|
||||
{
|
||||
var selectable = node.Value.Nodes.FirstOrDefault(n => n.Key == "Selectable");
|
||||
var selectableNodes = selectable.Value.Nodes;
|
||||
var voice = selectableNodes.FirstOrDefault(n => n.Key == "Voice");
|
||||
var selectableVoice = voice != null ? FieldLoader.GetValue<string>("Voice", voice.Value.Value) : "";
|
||||
|
||||
if (voice != null)
|
||||
{
|
||||
node.Value.Nodes.Add(new MiniYamlNode("Voiced", "", new List<MiniYamlNode>
|
||||
{
|
||||
new MiniYamlNode("VoiceSet", selectableVoice),
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if (node.Key.StartsWith("Selectable"))
|
||||
node.Value.Nodes.RemoveAll(p => p.Key == "Voice");
|
||||
}
|
||||
|
||||
UpgradeActorRules(engineVersion, ref node.Value.Nodes, node, depth + 1);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user