Add a lint test for audio notifications.
Only traits are linted - the UI still hardcodes too many audio references for this to be worthwhile.
This commit is contained in:
57
OpenRA.Mods.Common/Lint/CheckNotifications.cs
Normal file
57
OpenRA.Mods.Common/Lint/CheckNotifications.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2018 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, either version 3 of
|
||||
* the License, or (at your option) any later version. For more
|
||||
* information, see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using OpenRA.GameRules;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Lint
|
||||
{
|
||||
class CheckNotifications : ILintRulesPass
|
||||
{
|
||||
public void Run(Action<string> emitError, Action<string> emitWarning, Ruleset rules)
|
||||
{
|
||||
foreach (var actorInfo in rules.Actors)
|
||||
{
|
||||
foreach (var traitInfo in actorInfo.Value.TraitInfos<ITraitInfo>())
|
||||
{
|
||||
var fields = traitInfo.GetType().GetFields();
|
||||
foreach (var field in fields.Where(x => x.HasAttribute<NotificationReferenceAttribute>()))
|
||||
{
|
||||
string type = null;
|
||||
var notificationReference = field.GetCustomAttributes<NotificationReferenceAttribute>(true).First();
|
||||
if (!string.IsNullOrEmpty(notificationReference.NotificationTypeFieldName))
|
||||
{
|
||||
var fieldInfo = fields.First(f => f.Name == notificationReference.NotificationTypeFieldName);
|
||||
type = (string)fieldInfo.GetValue(traitInfo);
|
||||
}
|
||||
else
|
||||
type = notificationReference.NotificationType;
|
||||
|
||||
var notifications = LintExts.GetFieldValues(traitInfo, field, emitError);
|
||||
foreach (var notification in notifications)
|
||||
{
|
||||
if (string.IsNullOrEmpty(notification))
|
||||
continue;
|
||||
|
||||
SoundInfo soundInfo;
|
||||
if (string.IsNullOrEmpty(type) || !rules.Notifications.TryGetValue(type.ToLowerInvariant(), out soundInfo) ||
|
||||
!soundInfo.Notifications.ContainsKey(notification))
|
||||
emitError("Undefined notification reference {0}.{1} detected at {2} for {3}".F(
|
||||
type ?? "(null)", notification, traitInfo.GetType().Name, actorInfo.Key));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -148,6 +148,7 @@
|
||||
<Compile Include="Effects\SpriteEffect.cs" />
|
||||
<Compile Include="Graphics\RailgunRenderable.cs" />
|
||||
<Compile Include="Effects\LaunchEffect.cs" />
|
||||
<Compile Include="Lint\CheckNotifications.cs" />
|
||||
<Compile Include="Projectiles\AreaBeam.cs" />
|
||||
<Compile Include="Projectiles\Bullet.cs" />
|
||||
<Compile Include="Projectiles\InstantHit.cs" />
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("The condition to grant to self while this is the primary building.")]
|
||||
public readonly string PrimaryCondition = null;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
[Desc("The speech notification to play when selecting a primary building.")]
|
||||
public readonly string SelectionNotification = null;
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("The condition to grant to self while being repaired.")]
|
||||
public readonly string RepairCondition = null;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
public readonly string RepairingNotification = null;
|
||||
|
||||
public override object Create(ActorInitializer init) { return new RepairableBuilding(init.Self, this); }
|
||||
|
||||
@@ -26,10 +26,16 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Order name that toggles the condition.")]
|
||||
public readonly string OrderName = null;
|
||||
|
||||
[NotificationReference("Sounds")]
|
||||
public readonly string EnabledSound = null;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
public readonly string EnabledSpeech = null;
|
||||
|
||||
[NotificationReference("Sounds")]
|
||||
public readonly string DisabledSound = null;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
public readonly string DisabledSpeech = null;
|
||||
|
||||
public override object Create(ActorInitializer init) { return new ToggleConditionOnOrder(init.Self, this); }
|
||||
|
||||
@@ -36,6 +36,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Should the level-up animation be suppressed when actor is created?")]
|
||||
public readonly bool SuppressLevelupAnimation = true;
|
||||
|
||||
[NotificationReference("Sounds")]
|
||||
public readonly string LevelUpNotification = null;
|
||||
|
||||
public object Create(ActorInitializer init) { return new GainsExperience(init, this); }
|
||||
|
||||
@@ -26,9 +26,11 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Length of time (in ticks) to display a location ping in the minimap.")]
|
||||
public readonly int RadarPingDuration = 10 * 25;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
[Desc("The audio notification type to play.")]
|
||||
public string Notification = "BaseAttack";
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
[Desc("The audio notification to play to allies when under attack.",
|
||||
"Won't play a notification to allies if this is null.")]
|
||||
public string AllyNotification = null;
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Length of time (in ticks) to display a location ping in the minimap.")]
|
||||
public readonly int RadarPingDuration = 10 * 25;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
[Desc("The audio notification type to play.")]
|
||||
public string Notification = "HarvesterAttack";
|
||||
|
||||
|
||||
@@ -48,8 +48,13 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Delay between the game over condition being met, and the game actually ending, in milliseconds.")]
|
||||
public readonly int GameOverDelay = 1500;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
public readonly string WinNotification = null;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
public readonly string LoseNotification = null;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
public readonly string LeaveNotification = null;
|
||||
|
||||
public object Create(ActorInitializer init) { return new MissionObjectives(init.World, this); }
|
||||
|
||||
@@ -18,7 +18,10 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public class PlaceBeaconInfo : ITraitInfo
|
||||
{
|
||||
public readonly int Duration = 30 * 25;
|
||||
|
||||
public readonly string NotificationType = "Sounds";
|
||||
|
||||
[NotificationReference(typeFromField: "NotificationType")]
|
||||
public readonly string Notification = "Beacon";
|
||||
|
||||
public readonly bool IsPlayerPalette = true;
|
||||
|
||||
@@ -31,9 +31,11 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Play NewOptionsNotification this many ticks after building placement.")]
|
||||
public readonly int NewOptionsNotificationDelay = 10;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
[Desc("Notification to play after building placement if new construction options are available.")]
|
||||
public readonly string NewOptionsNotification = null;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
public readonly string CannotPlaceNotification = null;
|
||||
|
||||
public object Create(ActorInitializer init) { return new PlaceBuilding(this); }
|
||||
|
||||
@@ -41,13 +41,17 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Display order for the DefaultCash option.")]
|
||||
public readonly int DefaultCashDropdownDisplayOrder = 0;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
[Desc("Speech notification to play when the player does not have any funds.")]
|
||||
public readonly string InsufficientFundsNotification = null;
|
||||
|
||||
[Desc("Delay (in ticks) during which warnings will be muted.")]
|
||||
public readonly int InsufficientFundsNotificationDelay = 750;
|
||||
|
||||
[NotificationReference("Sounds")]
|
||||
public readonly string CashTickUpNotification = null;
|
||||
|
||||
[NotificationReference("Sounds")]
|
||||
public readonly string CashTickDownNotification = null;
|
||||
|
||||
IEnumerable<LobbyOption> ILobbyOptions.LobbyOptions(Ruleset rules)
|
||||
|
||||
@@ -50,28 +50,34 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("The build time is multiplied with this value on low power.")]
|
||||
public readonly int LowPowerSlowdown = 3;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
[Desc("Notification played when production is complete.",
|
||||
"The filename of the audio is defined per faction in notifications.yaml.")]
|
||||
public readonly string ReadyAudio = null;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
[Desc("Notification played when you can't train another actor",
|
||||
"when the build limit exceeded or the exit is jammed.",
|
||||
"The filename of the audio is defined per faction in notifications.yaml.")]
|
||||
public readonly string BlockedAudio = null;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
[Desc("Notification played when you can't queue another actor",
|
||||
"when the queue length limit is exceeded.",
|
||||
"The filename of the audio is defined per faction in notifications.yaml.")]
|
||||
public readonly string LimitedAudio = null;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
[Desc("Notification played when user clicks on the build palette icon.",
|
||||
"The filename of the audio is defined per faction in notifications.yaml.")]
|
||||
public readonly string QueuedAudio = null;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
[Desc("Notification played when player right-clicks on the build palette icon.",
|
||||
"The filename of the audio is defined per faction in notifications.yaml.")]
|
||||
public readonly string OnHoldAudio = null;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
[Desc("Notification played when player right-clicks on a build palette icon that is already on hold.",
|
||||
"The filename of the audio is defined per faction in notifications.yaml.")]
|
||||
public readonly string CancelledAudio = null;
|
||||
|
||||
@@ -22,6 +22,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("The percentage threshold above which a warning is played.")]
|
||||
public readonly int Threshold = 80;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
[Desc("The speech to play for the warning.")]
|
||||
public readonly string Notification = "SilosNeeded";
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public class PowerManagerInfo : ITraitInfo, Requires<DeveloperModeInfo>
|
||||
{
|
||||
public readonly int AdviceInterval = 250;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
public readonly string SpeechNotification = null;
|
||||
|
||||
public object Create(ActorInitializer init) { return new PowerManager(init.Self, this); }
|
||||
|
||||
@@ -27,6 +27,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Sound to play when dropping the unit.")]
|
||||
public readonly string ChuteSound = null;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
[Desc("Notification to play when dropping the unit.")]
|
||||
public readonly string ReadyAudio = null;
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Cursor to use when repairing is denied.")]
|
||||
public readonly string TargetBlockedCursor = "goldwrench-blocked";
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
[Desc("Speech notification to play when a bridge is repaired.")]
|
||||
public readonly string RepairNotification = null;
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
public class RepairsUnitsInfo : PausableConditionalTraitInfo
|
||||
@@ -21,9 +23,11 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Time (in ticks) between two repair steps.")]
|
||||
public readonly int Interval = 24;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
[Desc("The sound played when starting to repair a unit.")]
|
||||
public readonly string StartRepairingNotification = null;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
[Desc("The sound played when repairing a unit is done.")]
|
||||
public readonly string FinishRepairingNotification = null;
|
||||
|
||||
|
||||
@@ -15,7 +15,9 @@ namespace OpenRA.Mods.Common.Traits.Sound
|
||||
{
|
||||
class ActorLostNotificationInfo : ITraitInfo
|
||||
{
|
||||
[NotificationReference("Speech")]
|
||||
public readonly string Notification = "UnitLost";
|
||||
|
||||
public readonly bool NotifyAll = false;
|
||||
|
||||
public object Create(ActorInitializer init) { return new ActorLostNotification(this); }
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace OpenRA.Mods.Common.Traits.Sound
|
||||
[Desc("Should there be a radar ping on enemies' radar at the actor's location when they see him")]
|
||||
public readonly bool PingRadar = false;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
public readonly string Notification = null;
|
||||
|
||||
public readonly bool AnnounceNeutrals = false;
|
||||
|
||||
@@ -15,12 +15,14 @@ namespace OpenRA.Mods.Common.Traits.Sound
|
||||
{
|
||||
public class CaptureNotificationInfo : ITraitInfo
|
||||
{
|
||||
[NotificationReference("Speech")]
|
||||
[Desc("The speech notification to play to the new owner.")]
|
||||
public readonly string Notification = "BuildingCaptured";
|
||||
|
||||
[Desc("Specifies if Notification is played with the voice of the new owners faction.")]
|
||||
public readonly bool NewOwnerVoice = true;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
[Desc("The speech notification to play to the old owner.")]
|
||||
public readonly string LoseNotification = null;
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public readonly int SquadSize = 1;
|
||||
public readonly WVec SquadOffset = new WVec(-1536, 1536, 0);
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
[Desc("Notification to play when entering the drop zone.")]
|
||||
public readonly string ReinforcementsArrivedSpeechNotification = null;
|
||||
|
||||
|
||||
@@ -26,10 +26,12 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Production queue type to use")]
|
||||
public readonly string Type = null;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
[Desc("Notification played when production is activated.",
|
||||
"The filename of the audio is defined per faction in notifications.yaml.")]
|
||||
public readonly string ReadyAudio = null;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
[Desc("Notification played when the exit is jammed.",
|
||||
"The filename of the audio is defined per faction in notifications.yaml.")]
|
||||
public readonly string BlockedAudio = null;
|
||||
|
||||
@@ -32,16 +32,33 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public readonly string[] Prerequisites = { };
|
||||
|
||||
public readonly string BeginChargeSound = null;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
public readonly string BeginChargeSpeechNotification = null;
|
||||
|
||||
public readonly string EndChargeSound = null;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
public readonly string EndChargeSpeechNotification = null;
|
||||
|
||||
public readonly string SelectTargetSound = null;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
public readonly string SelectTargetSpeechNotification = null;
|
||||
|
||||
public readonly string InsufficientPowerSound = null;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
public readonly string InsufficientPowerSpeechNotification = null;
|
||||
|
||||
public readonly string LaunchSound = null;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
public readonly string LaunchSpeechNotification = null;
|
||||
|
||||
public readonly string IncomingSound = null;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
public readonly string IncomingSpeechNotification = null;
|
||||
|
||||
[Desc("Defines to which players the timer is shown.")]
|
||||
|
||||
@@ -34,9 +34,11 @@ namespace OpenRA.Mods.Common.Traits
|
||||
[Desc("Sounds to play when the transformation is blocked.")]
|
||||
public readonly string[] NoTransformSounds = { };
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
[Desc("Notification to play when transforming.")]
|
||||
public readonly string TransformNotification = null;
|
||||
|
||||
[NotificationReference("Speech")]
|
||||
[Desc("Notification to play when the transformation is blocked.")]
|
||||
public readonly string NoTransformNotification = null;
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
class StartGameNotificationInfo : ITraitInfo
|
||||
{
|
||||
[NotificationReference("Speech")]
|
||||
public readonly string Notification = "StartGame";
|
||||
|
||||
public object Create(ActorInitializer init) { return new StartGameNotification(this); }
|
||||
|
||||
Reference in New Issue
Block a user