check voice actor references
This commit is contained in:
@@ -36,7 +36,7 @@ namespace OpenRA.Mods.Common.Lint
|
||||
CheckReference(actorInfo, traitInfo, field, map.Rules.Actors, "actor");
|
||||
if (field.HasAttribute<WeaponReferenceAttribute>())
|
||||
CheckReference(actorInfo, traitInfo, field, map.Rules.Weapons, "weapon");
|
||||
if (field.HasAttribute<VoiceReferenceAttribute>())
|
||||
if (field.HasAttribute<VoiceSetReferenceAttribute>())
|
||||
CheckReference(actorInfo, traitInfo, field, map.Rules.Voices, "voice");
|
||||
}
|
||||
}
|
||||
|
||||
64
OpenRA.Mods.Common/Lint/CheckVoiceReferences.cs
Normal file
64
OpenRA.Mods.Common/Lint/CheckVoiceReferences.cs
Normal file
@@ -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<string> emitError, Action<string> emitWarning, Map map)
|
||||
{
|
||||
foreach (var actorInfo in map.Rules.Actors)
|
||||
{
|
||||
foreach (var traitInfo in actorInfo.Value.Traits.WithInterface<ITraitInfo>())
|
||||
{
|
||||
var fields = traitInfo.GetType().GetFields().Where(f => f.HasAttribute<VoiceSetReferenceAttribute>());
|
||||
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<string> emitError, Map map, string voiceSet)
|
||||
{
|
||||
var soundInfo = map.Rules.Voices[voiceSet.ToLowerInvariant()];
|
||||
|
||||
foreach (var traitInfo in actorInfo.Traits.WithInterface<ITraitInfo>())
|
||||
{
|
||||
var fields = traitInfo.GetType().GetFields().Where(f => f.HasAttribute<VoiceReferenceAttribute>());
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -185,6 +185,7 @@
|
||||
<Compile Include="Lint\CheckSyncAnnotations.cs" />
|
||||
<Compile Include="Lint\CheckTraitPrerequisites.cs" />
|
||||
<Compile Include="Lint\CheckDeathTypes.cs" />
|
||||
<Compile Include="Lint\CheckVoiceReferences.cs" />
|
||||
<Compile Include="Lint\LintBuildablePrerequisites.cs" />
|
||||
<Compile Include="Lint\LintExts.cs" />
|
||||
<Compile Include="LoadScreens\ModChooserLoadScreen.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<CPos, SubCell> OccupiedCells(ActorInfo info, CPos location, SubCell subCell = SubCell.Any) { return new ReadOnlyDictionary<CPos, SubCell>(); }
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<IMove>();
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public string VoicePhraseForOrder(Actor self, Order order)
|
||||
{
|
||||
if (order.OrderString == "AttackMove")
|
||||
return "AttackMove";
|
||||
return info.Voice;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -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); }
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<EngineerRepair> { }
|
||||
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<IOrderTargeter> 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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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); }
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -22,6 +22,9 @@ namespace OpenRA.Mods.Common.Traits
|
||||
class RepairableInfo : ITraitInfo, Requires<HealthInfo>
|
||||
{
|
||||
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)
|
||||
|
||||
@@ -17,10 +17,22 @@ using OpenRA.Traits;
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[Desc("Can enter a BridgeHut to trigger a repair.")]
|
||||
class RepairsBridgesInfo : TraitInfo<RepairsBridges> { }
|
||||
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<IOrderTargeter> 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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user