Add support for transient text notifications matching speech notifications

This commit is contained in:
Ivaylo Draganov
2022-01-08 18:28:25 +02:00
committed by Paul Chote
parent 9f723be65a
commit 24b9482cc1
50 changed files with 372 additions and 46 deletions

View File

@@ -26,12 +26,13 @@ namespace OpenRA
SystemMessageLabel = "Battlefield Control"; SystemMessageLabel = "Battlefield Control";
} }
public static void AddTransientLine(string text) public static void AddTransientLine(string text, Player player)
{ {
if (string.IsNullOrEmpty(text)) if (string.IsNullOrEmpty(text))
return; return;
AddTextNotification(TextNotificationPool.Transients, SystemMessageLabel, text); if (player == null || player == player.World.LocalPlayer)
AddTextNotification(TextNotificationPool.Transients, SystemMessageLabel, text);
} }
public static void AddFeedbackLine(string text) public static void AddFeedbackLine(string text)

View File

@@ -71,6 +71,8 @@ namespace OpenRA.Mods.Cnc.Activities
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech",
infiltrates.Info.Notification, self.Owner.Faction.InternalName); infiltrates.Info.Notification, self.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(infiltrates.Info.TextNotification, self.Owner);
if (infiltrates.Info.EnterBehaviour == EnterBehaviour.Dispose) if (infiltrates.Info.EnterBehaviour == EnterBehaviour.Dispose)
self.Dispose(); self.Dispose();
else if (infiltrates.Info.EnterBehaviour == EnterBehaviour.Suicide) else if (infiltrates.Info.EnterBehaviour == EnterBehaviour.Suicide)

View File

@@ -37,10 +37,16 @@ namespace OpenRA.Mods.Cnc.Traits
[Desc("Sound the victim will hear when they get robbed.")] [Desc("Sound the victim will hear when they get robbed.")]
public readonly string InfiltratedNotification = null; public readonly string InfiltratedNotification = null;
[Desc("Text notification the victim will see when they get robbed.")]
public readonly string InfiltratedTextNotification = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("Sound the perpetrator will hear after successful infiltration.")] [Desc("Sound the perpetrator will hear after successful infiltration.")]
public readonly string InfiltrationNotification = null; public readonly string InfiltrationNotification = null;
[Desc("Text notification the perpetrator will see after successful infiltration.")]
public readonly string InfiltrationTextNotification = null;
[Desc("Whether to show the cash tick indicators rising from the actor.")] [Desc("Whether to show the cash tick indicators rising from the actor.")]
public readonly bool ShowTicks = true; public readonly bool ShowTicks = true;
@@ -74,6 +80,9 @@ namespace OpenRA.Mods.Cnc.Traits
if (info.InfiltrationNotification != null) if (info.InfiltrationNotification != null)
Game.Sound.PlayNotification(self.World.Map.Rules, infiltrator.Owner, "Speech", info.InfiltrationNotification, infiltrator.Owner.Faction.InternalName); Game.Sound.PlayNotification(self.World.Map.Rules, infiltrator.Owner, "Speech", info.InfiltrationNotification, infiltrator.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(info.InfiltratedTextNotification, self.Owner);
TextNotificationsManager.AddTransientLine(info.InfiltrationTextNotification, infiltrator.Owner);
if (info.ShowTicks) if (info.ShowTicks)
self.World.AddFrameEndTask(w => w.Add(new FloatingText(self.CenterPosition, infiltrator.Owner.Color, FloatingText.FormatCashTick(toGive), 30))); self.World.AddFrameEndTask(w => w.Add(new FloatingText(self.CenterPosition, infiltrator.Owner.Color, FloatingText.FormatCashTick(toGive), 30)));
} }

View File

@@ -26,10 +26,16 @@ namespace OpenRA.Mods.Cnc.Traits
[Desc("Sound the victim will hear when they get sabotaged.")] [Desc("Sound the victim will hear when they get sabotaged.")]
public readonly string InfiltratedNotification = null; public readonly string InfiltratedNotification = null;
[Desc("Text notification the victim will see when they get sabotaged.")]
public readonly string InfiltratedTextNotification = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("Sound the perpetrator will hear after successful infiltration.")] [Desc("Sound the perpetrator will hear after successful infiltration.")]
public readonly string InfiltrationNotification = null; public readonly string InfiltrationNotification = null;
[Desc("Text notification the perpetrator will see after successful infiltration.")]
public readonly string InfiltrationTextNotification = null;
public override object Create(ActorInitializer init) { return new InfiltrateForExploration(this); } public override object Create(ActorInitializer init) { return new InfiltrateForExploration(this); }
} }
@@ -53,6 +59,9 @@ namespace OpenRA.Mods.Cnc.Traits
if (info.InfiltrationNotification != null) if (info.InfiltrationNotification != null)
Game.Sound.PlayNotification(self.World.Map.Rules, infiltrator.Owner, "Speech", info.InfiltrationNotification, infiltrator.Owner.Faction.InternalName); Game.Sound.PlayNotification(self.World.Map.Rules, infiltrator.Owner, "Speech", info.InfiltrationNotification, infiltrator.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(info.InfiltratedTextNotification, self.Owner);
TextNotificationsManager.AddTransientLine(info.InfiltrationTextNotification, infiltrator.Owner);
infiltrator.Owner.Shroud.Explore(self.Owner.Shroud); infiltrator.Owner.Shroud.Explore(self.Owner.Shroud);
var preventReset = self.Owner.PlayerActor.TraitsImplementing<IPreventsShroudReset>() var preventReset = self.Owner.PlayerActor.TraitsImplementing<IPreventsShroudReset>()
.Any(p => p.PreventShroudReset(self)); .Any(p => p.PreventShroudReset(self));

View File

@@ -27,10 +27,16 @@ namespace OpenRA.Mods.Cnc.Traits
[Desc("Sound the victim will hear when they get sabotaged.")] [Desc("Sound the victim will hear when they get sabotaged.")]
public readonly string InfiltratedNotification = null; public readonly string InfiltratedNotification = null;
[Desc("Text notification the victim will see when they get sabotaged.")]
public readonly string InfiltratedTextNotification = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("Sound the perpetrator will hear after successful infiltration.")] [Desc("Sound the perpetrator will hear after successful infiltration.")]
public readonly string InfiltrationNotification = null; public readonly string InfiltrationNotification = null;
[Desc("Text notification the perpetrator will see after successful infiltration.")]
public readonly string InfiltrationTextNotification = null;
public override object Create(ActorInitializer init) { return new InfiltrateForPowerOutage(init.Self, this); } public override object Create(ActorInitializer init) { return new InfiltrateForPowerOutage(init.Self, this); }
} }
@@ -56,6 +62,9 @@ namespace OpenRA.Mods.Cnc.Traits
if (info.InfiltrationNotification != null) if (info.InfiltrationNotification != null)
Game.Sound.PlayNotification(self.World.Map.Rules, infiltrator.Owner, "Speech", info.InfiltrationNotification, infiltrator.Owner.Faction.InternalName); Game.Sound.PlayNotification(self.World.Map.Rules, infiltrator.Owner, "Speech", info.InfiltrationNotification, infiltrator.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(info.InfiltratedTextNotification, self.Owner);
TextNotificationsManager.AddTransientLine(info.InfiltrationTextNotification, infiltrator.Owner);
playerPower.TriggerPowerOutage(info.Duration); playerPower.TriggerPowerOutage(info.Duration);
} }

View File

@@ -28,10 +28,16 @@ namespace OpenRA.Mods.Cnc.Traits
[Desc("Sound the victim will hear when technology gets stolen.")] [Desc("Sound the victim will hear when technology gets stolen.")]
public readonly string InfiltratedNotification = null; public readonly string InfiltratedNotification = null;
[Desc("Text notification the victim will see when technology gets stolen.")]
public readonly string InfiltratedTextNotification = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("Sound the perpetrator will hear after successful infiltration.")] [Desc("Sound the perpetrator will hear after successful infiltration.")]
public readonly string InfiltrationNotification = null; public readonly string InfiltrationNotification = null;
[Desc("Text notification the perpetrator will see after successful infiltration.")]
public readonly string InfiltrationTextNotification = null;
public override object Create(ActorInitializer init) { return new InfiltrateForSupportPower(this); } public override object Create(ActorInitializer init) { return new InfiltrateForSupportPower(this); }
} }
@@ -55,6 +61,9 @@ namespace OpenRA.Mods.Cnc.Traits
if (info.InfiltrationNotification != null) if (info.InfiltrationNotification != null)
Game.Sound.PlayNotification(self.World.Map.Rules, infiltrator.Owner, "Speech", info.InfiltrationNotification, infiltrator.Owner.Faction.InternalName); Game.Sound.PlayNotification(self.World.Map.Rules, infiltrator.Owner, "Speech", info.InfiltrationNotification, infiltrator.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(info.InfiltratedTextNotification, self.Owner);
TextNotificationsManager.AddTransientLine(info.InfiltrationTextNotification, infiltrator.Owner);
infiltrator.World.AddFrameEndTask(w => w.CreateActor(info.Proxy, new TypeDictionary infiltrator.World.AddFrameEndTask(w => w.CreateActor(info.Proxy, new TypeDictionary
{ {
new OwnerInit(infiltrator.Owner) new OwnerInit(infiltrator.Owner)

View File

@@ -22,13 +22,19 @@ namespace OpenRA.Mods.Cnc.Traits
public readonly BitSet<TargetableType> Types = default(BitSet<TargetableType>); public readonly BitSet<TargetableType> Types = default(BitSet<TargetableType>);
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("Sound the victim will hear when technology gets stolen.")] [Desc("Sound the victim will hear when they get sabotaged.")]
public readonly string InfiltratedNotification = null; public readonly string InfiltratedNotification = null;
[Desc("Text notification the victim will see when they get sabotaged.")]
public readonly string InfiltratedTextNotification = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("Sound the perpetrator will hear after successful infiltration.")] [Desc("Sound the perpetrator will hear after successful infiltration.")]
public readonly string InfiltrationNotification = null; public readonly string InfiltrationNotification = null;
[Desc("Text notification the perpetrator will see after successful infiltration.")]
public readonly string InfiltrationTextNotification = null;
public override object Create(ActorInitializer init) { return new InfiltrateForSupportPowerReset(this); } public override object Create(ActorInitializer init) { return new InfiltrateForSupportPowerReset(this); }
} }
@@ -52,6 +58,9 @@ namespace OpenRA.Mods.Cnc.Traits
if (info.InfiltrationNotification != null) if (info.InfiltrationNotification != null)
Game.Sound.PlayNotification(self.World.Map.Rules, infiltrator.Owner, "Speech", info.InfiltrationNotification, infiltrator.Owner.Faction.InternalName); Game.Sound.PlayNotification(self.World.Map.Rules, infiltrator.Owner, "Speech", info.InfiltrationNotification, infiltrator.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(info.InfiltratedTextNotification, self.Owner);
TextNotificationsManager.AddTransientLine(info.InfiltrationTextNotification, infiltrator.Owner);
var manager = self.Owner.PlayerActor.Trait<SupportPowerManager>(); var manager = self.Owner.PlayerActor.Trait<SupportPowerManager>();
var powers = manager.GetPowersForActor(self).Where(sp => !sp.Disabled); var powers = manager.GetPowersForActor(self).Where(sp => !sp.Disabled);
foreach (var power in powers) foreach (var power in powers)

View File

@@ -41,6 +41,9 @@ namespace OpenRA.Mods.Cnc.Traits
[Desc("Notification to play when a target is infiltrated.")] [Desc("Notification to play when a target is infiltrated.")]
public readonly string Notification = null; public readonly string Notification = null;
[Desc("Text notification to display when a target is infiltrated.")]
public readonly string TextNotification = null;
[Desc("Experience to grant to the infiltrating player.")] [Desc("Experience to grant to the infiltrating player.")]
public readonly int PlayerExperience = 0; public readonly int PlayerExperience = 0;

View File

@@ -18,17 +18,19 @@ namespace OpenRA.Mods.Common.Activities
class RepairBridge : Enter class RepairBridge : Enter
{ {
readonly EnterBehaviour enterBehaviour; readonly EnterBehaviour enterBehaviour;
readonly string notification; readonly string speechNotification;
readonly string textNotification;
Actor enterActor; Actor enterActor;
BridgeHut enterHut; BridgeHut enterHut;
LegacyBridgeHut enterLegacyHut; LegacyBridgeHut enterLegacyHut;
public RepairBridge(Actor self, in Target target, EnterBehaviour enterBehaviour, string notification, Color targetLineColor) public RepairBridge(Actor self, in Target target, EnterBehaviour enterBehaviour, string speechNotification, string textNotification, Color targetLineColor)
: base(self, target, targetLineColor) : base(self, target, targetLineColor)
{ {
this.enterBehaviour = enterBehaviour; this.enterBehaviour = enterBehaviour;
this.notification = notification; this.speechNotification = speechNotification;
this.textNotification = textNotification;
} }
bool CanEnterHut() bool CanEnterHut()
@@ -75,7 +77,8 @@ namespace OpenRA.Mods.Common.Activities
else if (enterHut != null) else if (enterHut != null)
enterHut.Repair(self); enterHut.Repair(self);
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", notification, self.Owner.Faction.InternalName); Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", speechNotification, self.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(textNotification, self.Owner);
if (enterBehaviour == EnterBehaviour.Dispose) if (enterBehaviour == EnterBehaviour.Dispose)
self.Dispose(); self.Dispose();

View File

@@ -262,6 +262,7 @@ namespace OpenRA.Mods.Common.Activities
host.Actor.Owner.PlayerActor.TraitOrDefault<PlayerExperience>()?.GiveExperience(repairsUnits.Info.PlayerExperience); host.Actor.Owner.PlayerActor.TraitOrDefault<PlayerExperience>()?.GiveExperience(repairsUnits.Info.PlayerExperience);
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", repairsUnits.Info.FinishRepairingNotification, self.Owner.Faction.InternalName); Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", repairsUnits.Info.FinishRepairingNotification, self.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(repairsUnits.Info.FinishRepairingTextNotification, self.Owner);
activeResupplyTypes &= ~ResupplyType.Repair; activeResupplyTypes &= ~ResupplyType.Repair;
return; return;
@@ -279,6 +280,7 @@ namespace OpenRA.Mods.Common.Activities
{ {
played = true; played = true;
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", repairsUnits.Info.StartRepairingNotification, self.Owner.Faction.InternalName); Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", repairsUnits.Info.StartRepairingNotification, self.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(repairsUnits.Info.StartRepairingTextNotification, self.Owner);
} }
if (!playerResources.TakeCash(cost, true)) if (!playerResources.TakeCash(cost, true))

View File

@@ -49,6 +49,7 @@ namespace OpenRA.Mods.Common.Activities
self.World.AddFrameEndTask(w => w.Add(new FloatingText(self.CenterPosition, self.Owner.Color, FloatingText.FormatCashTick(refund), 30))); self.World.AddFrameEndTask(w => w.Add(new FloatingText(self.CenterPosition, self.Owner.Color, FloatingText.FormatCashTick(refund), 30)));
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", sellableInfo.Notification, self.Owner.Faction.InternalName); Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", sellableInfo.Notification, self.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(sellableInfo.TextNotification, self.Owner);
self.Dispose(); self.Dispose();
return false; return false;

View File

@@ -26,6 +26,7 @@ namespace OpenRA.Mods.Common.Activities
public WAngle Facing = new WAngle(384); public WAngle Facing = new WAngle(384);
public string[] Sounds = Array.Empty<string>(); public string[] Sounds = Array.Empty<string>();
public string Notification = null; public string Notification = null;
public string TextNotification = null;
public int ForceHealthPercentage = 0; public int ForceHealthPercentage = 0;
public bool SkipMakeAnims = false; public bool SkipMakeAnims = false;
public string Faction = null; public string Faction = null;
@@ -95,6 +96,7 @@ namespace OpenRA.Mods.Common.Activities
Game.Sound.PlayToPlayer(SoundType.World, self.Owner, s, self.CenterPosition); Game.Sound.PlayToPlayer(SoundType.World, self.Owner, s, self.CenterPosition);
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Notification, self.Owner.Faction.InternalName); Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Notification, self.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(TextNotification, self.Owner);
var init = new TypeDictionary var init = new TypeDictionary
{ {

View File

@@ -180,6 +180,8 @@ namespace OpenRA.Mods.Common.Orders
if (!AcceptsPlug(topLeft, plugInfo)) if (!AcceptsPlug(topLeft, plugInfo))
{ {
Game.Sound.PlayNotification(world.Map.Rules, owner, "Speech", notification, owner.Faction.InternalName); Game.Sound.PlayNotification(world.Map.Rules, owner, "Speech", notification, owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(placeBuildingInfo.CannotPlaceTextNotification, owner);
yield break; yield break;
} }
} }
@@ -192,6 +194,8 @@ namespace OpenRA.Mods.Common.Orders
yield return order; yield return order;
Game.Sound.PlayNotification(world.Map.Rules, owner, "Speech", notification, owner.Faction.InternalName); Game.Sound.PlayNotification(world.Map.Rules, owner, "Speech", notification, owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(placeBuildingInfo.CannotPlaceTextNotification, owner);
yield break; yield break;
} }

View File

@@ -34,9 +34,12 @@ namespace OpenRA.Mods.Common.Traits
public readonly string PrimaryCondition = null; public readonly string PrimaryCondition = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("The speech notification to play when selecting a primary building.")] [Desc("Speech notification to play when selecting a primary building.")]
public readonly string SelectionNotification = null; public readonly string SelectionNotification = null;
[Desc("Text notification to display when selecting a primary building.")]
public readonly string SelectionTextNotification = null;
[Desc("List of production queues for which the primary flag should be set.", [Desc("List of production queues for which the primary flag should be set.",
"If empty, the list given in the `Produces` property of the `" + nameof(Production) + "` trait will be used.")] "If empty, the list given in the `Produces` property of the `" + nameof(Production) + "` trait will be used.")]
public readonly string[] ProductionQueues = Array.Empty<string>(); public readonly string[] ProductionQueues = Array.Empty<string>();
@@ -113,6 +116,7 @@ namespace OpenRA.Mods.Common.Traits
primaryToken = self.GrantCondition(Info.PrimaryCondition); primaryToken = self.GrantCondition(Info.PrimaryCondition);
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Info.SelectionNotification, self.Owner.Faction.InternalName); Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Info.SelectionNotification, self.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(Info.SelectionTextNotification, self.Owner);
} }
else if (primaryToken != Actor.InvalidConditionToken) else if (primaryToken != Actor.InvalidConditionToken)
primaryToken = self.RevokeCondition(primaryToken); primaryToken = self.RevokeCondition(primaryToken);

View File

@@ -21,8 +21,12 @@ namespace OpenRA.Mods.Common.Traits
public class ProductionAirdropInfo : ProductionInfo public class ProductionAirdropInfo : ProductionInfo
{ {
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("Speech notification to play when a unit is delivered.")]
public readonly string ReadyAudio = "Reinforce"; public readonly string ReadyAudio = "Reinforce";
[Desc("Text notification to display when a unit is delivered.")]
public readonly string ReadyTextNotification = null;
[FieldLoader.Require] [FieldLoader.Require]
[ActorReference(typeof(AircraftInfo))] [ActorReference(typeof(AircraftInfo))]
[Desc("Cargo aircraft used for delivery. Must have the `" + nameof(Aircraft) + "` trait.")] [Desc("Cargo aircraft used for delivery. Must have the `" + nameof(Aircraft) + "` trait.")]
@@ -112,6 +116,7 @@ namespace OpenRA.Mods.Common.Traits
self.World.AddFrameEndTask(ww => DoProduction(self, producee, exit, productionType, inits)); self.World.AddFrameEndTask(ww => DoProduction(self, producee, exit, productionType, inits));
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", info.ReadyAudio, self.Owner.Faction.InternalName); Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", info.ReadyAudio, self.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(info.ReadyTextNotification, self.Owner);
})); }));
actor.QueueActivity(new FlyOffMap(actor, Target.FromCell(w, endPos))); actor.QueueActivity(new FlyOffMap(actor, Target.FromCell(w, endPos)));

View File

@@ -46,9 +46,12 @@ namespace OpenRA.Mods.Common.Traits
public readonly CVec[] Path = Array.Empty<CVec>(); public readonly CVec[] Path = Array.Empty<CVec>();
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("The speech notification to play when setting a new rallypoint.")] [Desc("Speech notification to play when setting a new rallypoint.")]
public readonly string Notification = null; public readonly string Notification = null;
[Desc("Text notification to display when setting a new rallypoint.")]
public readonly string TextNotification = null;
[Desc("Used to group equivalent actors to allow force-setting a rallypoint (e.g. for Primary production).")] [Desc("Used to group equivalent actors to allow force-setting a rallypoint (e.g. for Primary production).")]
public readonly string ForceSetType = null; public readonly string ForceSetType = null;
@@ -101,6 +104,7 @@ namespace OpenRA.Mods.Common.Traits
if (order.OrderID == OrderID) if (order.OrderID == OrderID)
{ {
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Info.Notification, self.Owner.Faction.InternalName); Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Info.Notification, self.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(Info.TextNotification, self.Owner);
return new Order(order.OrderID, self, target, queued) return new Order(order.OrderID, self, target, queued)
{ {

View File

@@ -49,6 +49,8 @@ namespace OpenRA.Mods.Common.Traits
[NotificationReference("Speech")] [NotificationReference("Speech")]
public readonly string RepairingNotification = null; public readonly string RepairingNotification = null;
public readonly string RepairingTextNotification = null;
public override object Create(ActorInitializer init) { return new RepairableBuilding(init.Self, this); } public override object Create(ActorInitializer init) { return new RepairableBuilding(init.Self, this); }
} }
@@ -111,7 +113,10 @@ namespace OpenRA.Mods.Common.Traits
return; return;
Repairers.Add(player); Repairers.Add(player);
Game.Sound.PlayNotification(self.World.Map.Rules, player, "Speech", Info.RepairingNotification, player.Faction.InternalName); Game.Sound.PlayNotification(self.World.Map.Rules, player, "Speech", Info.RepairingNotification, player.Faction.InternalName);
TextNotificationsManager.AddTransientLine(Info.RepairingTextNotification, self.Owner);
UpdateCondition(self); UpdateCondition(self);
} }

View File

@@ -31,12 +31,16 @@ namespace OpenRA.Mods.Common.Traits
[NotificationReference("Speech")] [NotificationReference("Speech")]
public readonly string EnabledSpeech = null; public readonly string EnabledSpeech = null;
public readonly string EnabledTextNotification = null;
[NotificationReference("Sounds")] [NotificationReference("Sounds")]
public readonly string DisabledSound = null; public readonly string DisabledSound = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
public readonly string DisabledSpeech = null; public readonly string DisabledSpeech = null;
public readonly string DisabledTextNotification = null;
public override object Create(ActorInitializer init) { return new ToggleConditionOnOrder(this); } public override object Create(ActorInitializer init) { return new ToggleConditionOnOrder(this); }
} }
@@ -62,6 +66,8 @@ namespace OpenRA.Mods.Common.Traits
if (Info.EnabledSpeech != null) if (Info.EnabledSpeech != null)
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Info.EnabledSpeech, self.Owner.Faction.InternalName); Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Info.EnabledSpeech, self.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(Info.EnabledTextNotification, self.Owner);
} }
else if (!granted && conditionToken != Actor.InvalidConditionToken) else if (!granted && conditionToken != Actor.InvalidConditionToken)
{ {
@@ -72,6 +78,8 @@ namespace OpenRA.Mods.Common.Traits
if (Info.DisabledSpeech != null) if (Info.DisabledSpeech != null)
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Info.DisabledSpeech, self.Owner.Faction.InternalName); Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Info.DisabledSpeech, self.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(Info.DisabledTextNotification, self.Owner);
} }
} }

View File

@@ -36,9 +36,12 @@ namespace OpenRA.Mods.Common.Traits
public readonly string Sound = null; public readonly string Sound = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("Notification to play when the crate is collected.")] [Desc("Speech notification to play when the crate is collected.")]
public readonly string Notification = null; public readonly string Notification = null;
[Desc("Text notification to display when the crate is collected.")]
public readonly string TextNotification = null;
[Desc("The earliest time (in ticks) that this crate action can occur on.")] [Desc("The earliest time (in ticks) that this crate action can occur on.")]
public readonly int TimeDelay = 0; public readonly int TimeDelay = 0;
@@ -92,6 +95,8 @@ namespace OpenRA.Mods.Common.Traits
Game.Sound.PlayNotification(self.World.Map.Rules, collector.Owner, "Speech", Game.Sound.PlayNotification(self.World.Map.Rules, collector.Owner, "Speech",
Info.Notification, collector.Owner.Faction.InternalName); Info.Notification, collector.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(Info.TextNotification, collector.Owner);
if (Info.Image != null && Info.Sequence != null) if (Info.Image != null && Info.Sequence != null)
collector.World.AddFrameEndTask(w => w.Add(new SpriteEffect(collector, w, Info.Image, Info.Sequence, Info.Palette))); collector.World.AddFrameEndTask(w => w.Add(new SpriteEffect(collector, w, Info.Image, Info.Sequence, Info.Palette)));
} }

View File

@@ -49,6 +49,8 @@ namespace OpenRA.Mods.Common.Traits
[NotificationReference("Sounds")] [NotificationReference("Sounds")]
public readonly string LevelUpNotification = null; public readonly string LevelUpNotification = null;
public readonly string LevelUpTextNotification = null;
public override object Create(ActorInitializer init) { return new GainsExperience(init, this); } public override object Create(ActorInitializer init) { return new GainsExperience(init, this); }
} }
@@ -119,6 +121,8 @@ namespace OpenRA.Mods.Common.Traits
if (!silent) if (!silent)
{ {
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Sounds", info.LevelUpNotification, self.Owner.Faction.InternalName); Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Sounds", info.LevelUpNotification, self.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(info.LevelUpTextNotification, self.Owner);
if (info.LevelUpImage != null && info.LevelUpSequence != null) if (info.LevelUpImage != null && info.LevelUpSequence != null)
self.World.AddFrameEndTask(w => w.Add(new SpriteEffect(self, w, info.LevelUpImage, info.LevelUpSequence, info.LevelUpPalette))); self.World.AddFrameEndTask(w => w.Add(new SpriteEffect(self, w, info.LevelUpImage, info.LevelUpSequence, info.LevelUpPalette)));
} }

View File

@@ -28,14 +28,20 @@ namespace OpenRA.Mods.Common.Traits
public readonly int RadarPingDuration = 250; public readonly int RadarPingDuration = 250;
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("The audio notification type to play.")] [Desc("Speech notification type to play.")]
public readonly string Notification = "BaseAttack"; public readonly string Notification = "BaseAttack";
[Desc("Text notification to display.")]
public string TextNotification = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("The audio notification to play to allies when under attack.", [Desc("Speech notification to play to allies when under attack.",
"Won't play a notification to allies if this is null.")] "Won't play a notification to allies if this is null.")]
public readonly string AllyNotification = null; public readonly string AllyNotification = null;
[Desc("Text notification to display to allies when under attack.")]
public string AllyTextNotification = null;
public override object Create(ActorInitializer init) { return new BaseAttackNotifier(init.Self, this); } public override object Create(ActorInitializer init) { return new BaseAttackNotifier(init.Self, this); }
} }
@@ -55,6 +61,11 @@ namespace OpenRA.Mods.Common.Traits
void INotifyDamage.Damaged(Actor self, AttackInfo e) void INotifyDamage.Damaged(Actor self, AttackInfo e)
{ {
var localPlayer = self.World.LocalPlayer;
if (localPlayer == null || localPlayer.Spectating)
return;
if (e.Attacker == null) if (e.Attacker == null)
return; return;
@@ -74,12 +85,17 @@ namespace OpenRA.Mods.Common.Traits
if (Game.RunTime > lastAttackTime + info.NotifyInterval) if (Game.RunTime > lastAttackTime + info.NotifyInterval)
{ {
var rules = self.World.Map.Rules; var rules = self.World.Map.Rules;
Game.Sound.PlayNotification(rules, self.Owner, "Speech", info.Notification, self.Owner.Faction.InternalName);
if (info.AllyNotification != null) if (self.Owner == localPlayer)
foreach (Player p in self.World.Players) {
if (p != self.Owner && p.IsAlliedWith(self.Owner) && p != e.Attacker.Owner) Game.Sound.PlayNotification(rules, self.Owner, "Speech", info.Notification, self.Owner.Faction.InternalName);
Game.Sound.PlayNotification(rules, p, "Speech", info.AllyNotification, p.Faction.InternalName); TextNotificationsManager.AddTransientLine(info.TextNotification, self.Owner);
}
else if (localPlayer.IsAlliedWith(self.Owner) && localPlayer != e.Attacker.Owner)
{
Game.Sound.PlayNotification(rules, localPlayer, "Speech", info.AllyNotification, localPlayer.Faction.InternalName);
TextNotificationsManager.AddTransientLine(info.AllyTextNotification, localPlayer);
}
radarPings?.Add(() => self.Owner.IsAlliedWith(self.World.RenderPlayer), self.CenterPosition, info.RadarPingColor, info.RadarPingDuration); radarPings?.Add(() => self.Owner.IsAlliedWith(self.World.RenderPlayer), self.CenterPosition, info.RadarPingColor, info.RadarPingDuration);

View File

@@ -103,7 +103,10 @@ namespace OpenRA.Mods.Common.Traits
Game.RunAfterDelay(info.NotificationDelay, () => Game.RunAfterDelay(info.NotificationDelay, () =>
{ {
if (Game.IsCurrentWorld(player.World) && player == player.World.LocalPlayer) if (Game.IsCurrentWorld(player.World) && player == player.World.LocalPlayer)
{
Game.Sound.PlayNotification(player.World.Map.Rules, player, "Speech", mo.Info.LoseNotification, player.Faction.InternalName); Game.Sound.PlayNotification(player.World.Map.Rules, player, "Speech", mo.Info.LoseNotification, player.Faction.InternalName);
TextNotificationsManager.AddTransientLine(mo.Info.LoseTextNotification, player);
}
}); });
} }
@@ -116,7 +119,10 @@ namespace OpenRA.Mods.Common.Traits
Game.RunAfterDelay(info.NotificationDelay, () => Game.RunAfterDelay(info.NotificationDelay, () =>
{ {
if (Game.IsCurrentWorld(player.World) && player == player.World.LocalPlayer) if (Game.IsCurrentWorld(player.World) && player == player.World.LocalPlayer)
{
Game.Sound.PlayNotification(player.World.Map.Rules, player, "Speech", mo.Info.WinNotification, player.Faction.InternalName); Game.Sound.PlayNotification(player.World.Map.Rules, player, "Speech", mo.Info.WinNotification, player.Faction.InternalName);
TextNotificationsManager.AddTransientLine(mo.Info.WinTextNotification, player);
}
}); });
} }
} }

View File

@@ -89,8 +89,9 @@ namespace OpenRA.Mods.Common.Traits
if (lastKnownActorIds.Contains(actor.Actor.ActorID)) if (lastKnownActorIds.Contains(actor.Actor.ActorID))
continue; continue;
// Should we play a sound notification? // Should we play a notification?
var playNotification = !playedNotifications.Contains(actor.Trait.Info.Notification) && ticksBeforeNextNotification <= 0; var notificationId = $"{actor.Trait.Info.Notification} {actor.Trait.Info.TextNotification}";
var playNotification = !playedNotifications.Contains(notificationId) && ticksBeforeNextNotification <= 0;
// Notify the actor that he has been discovered // Notify the actor that he has been discovered
foreach (var trait in actor.Actor.TraitsImplementing<INotifyDiscovered>()) foreach (var trait in actor.Actor.TraitsImplementing<INotifyDiscovered>())
@@ -109,7 +110,7 @@ namespace OpenRA.Mods.Common.Traits
if (!playNotification) if (!playNotification)
continue; continue;
playedNotifications.Add(actor.Trait.Info.Notification); playedNotifications.Add(notificationId);
announcedAny = true; announcedAny = true;
} }

View File

@@ -28,9 +28,12 @@ namespace OpenRA.Mods.Common.Traits
public readonly int RadarPingDuration = 250; public readonly int RadarPingDuration = 250;
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("The audio notification type to play.")] [Desc("Speech notification type to play.")]
public readonly string Notification = "HarvesterAttack"; public readonly string Notification = "HarvesterAttack";
[Desc("Text notification to display.")]
public string TextNotification = null;
public override object Create(ActorInitializer init) { return new HarvesterAttackNotifier(init.Self, this); } public override object Create(ActorInitializer init) { return new HarvesterAttackNotifier(init.Self, this); }
} }
@@ -61,6 +64,8 @@ namespace OpenRA.Mods.Common.Traits
if (Game.RunTime > lastAttackTime + info.NotifyInterval) if (Game.RunTime > lastAttackTime + info.NotifyInterval)
{ {
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", info.Notification, self.Owner.Faction.InternalName); Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", info.Notification, self.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(info.TextNotification, self.Owner);
radarPings?.Add(() => self.Owner.IsAlliedWith(self.World.RenderPlayer), self.CenterPosition, info.RadarPingColor, info.RadarPingDuration); radarPings?.Add(() => self.Owner.IsAlliedWith(self.World.RenderPlayer), self.CenterPosition, info.RadarPingColor, info.RadarPingDuration);
lastAttackTime = Game.RunTime; lastAttackTime = Game.RunTime;

View File

@@ -54,12 +54,18 @@ namespace OpenRA.Mods.Common.Traits
[NotificationReference("Speech")] [NotificationReference("Speech")]
public readonly string WinNotification = null; public readonly string WinNotification = null;
public readonly string WinTextNotification = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
public readonly string LoseNotification = null; public readonly string LoseNotification = null;
public readonly string LoseTextNotification = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
public readonly string LeaveNotification = null; public readonly string LeaveNotification = null;
public readonly string LeaveTextNotification = null;
public override object Create(ActorInitializer init) { return new MissionObjectives(init.Self.Owner, this); } public override object Create(ActorInitializer init) { return new MissionObjectives(init.Self.Owner, this); }
} }

View File

@@ -26,12 +26,19 @@ namespace OpenRA.Mods.Common.Traits
public readonly int NewOptionsNotificationDelay = 10; public readonly int NewOptionsNotificationDelay = 10;
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("Notification to play after building placement if new construction options are available.")] [Desc("Speech notification to play after building placement if new construction options are available.")]
public readonly string NewOptionsNotification = null; public readonly string NewOptionsNotification = null;
[Desc("Text notification to display after building placement if new construction options are available.")]
public readonly string NewOptionsTextNotification = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("Speech notification to play if building placement is not possible.")]
public readonly string CannotPlaceNotification = null; public readonly string CannotPlaceNotification = null;
[Desc("Text notification to display if building placement is not possible.")]
public readonly string CannotPlaceTextNotification = null;
[Desc("Hotkey to toggle between PlaceBuildingVariants when placing a structure.")] [Desc("Hotkey to toggle between PlaceBuildingVariants when placing a structure.")]
public readonly HotkeyReference ToggleVariantKey = new HotkeyReference(); public readonly HotkeyReference ToggleVariantKey = new HotkeyReference();
@@ -223,6 +230,8 @@ namespace OpenRA.Mods.Common.Traits
void PlayNotification(Actor self) void PlayNotification(Actor self)
{ {
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", info.NewOptionsNotification, self.Owner.Faction.InternalName); Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", info.NewOptionsNotification, self.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(info.NewOptionsTextNotification, self.Owner);
triggerNotification = false; triggerNotification = false;
tick = 0; tick = 0;
} }

View File

@@ -44,6 +44,9 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Speech notification to play when the player does not have any funds.")] [Desc("Speech notification to play when the player does not have any funds.")]
public readonly string InsufficientFundsNotification = null; public readonly string InsufficientFundsNotification = null;
[Desc("Text notification to display when the player does not have any funds.")]
public readonly string InsufficientFundsTextNotification = null;
[Desc("Delay (in ticks) during which warnings will be muted.")] [Desc("Delay (in ticks) during which warnings will be muted.")]
public readonly int InsufficientFundsNotificationInterval = 30000; public readonly int InsufficientFundsNotificationInterval = 30000;
@@ -179,11 +182,11 @@ namespace OpenRA.Mods.Common.Traits
{ {
if (Cash + Resources < num) if (Cash + Resources < num)
{ {
if (notifyLowFunds && !string.IsNullOrEmpty(Info.InsufficientFundsNotification) && if (notifyLowFunds && Game.RunTime > lastNotificationTime + Info.InsufficientFundsNotificationInterval)
Game.RunTime > lastNotificationTime + Info.InsufficientFundsNotificationInterval)
{ {
lastNotificationTime = Game.RunTime; lastNotificationTime = Game.RunTime;
Game.Sound.PlayNotification(owner.World.Map.Rules, owner, "Speech", Info.InsufficientFundsNotification, owner.Faction.InternalName); Game.Sound.PlayNotification(owner.World.Map.Rules, owner, "Speech", Info.InsufficientFundsNotification, owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(Info.InsufficientFundsTextNotification, owner);
} }
return false; return false;

View File

@@ -61,18 +61,29 @@ namespace OpenRA.Mods.Common.Traits
"The filename of the audio is defined per faction in notifications.yaml.")] "The filename of the audio is defined per faction in notifications.yaml.")]
public readonly string ReadyAudio = null; public readonly string ReadyAudio = null;
[Desc("Notification displayed when production is complete.")]
public readonly string ReadyTextNotification = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("Notification played when you can't train another actor", [Desc("Notification played when you can't train another actor",
"when the build limit exceeded or the exit is jammed.", "when the build limit exceeded or the exit is jammed.",
"The filename of the audio is defined per faction in notifications.yaml.")] "The filename of the audio is defined per faction in notifications.yaml.")]
public readonly string BlockedAudio = null; public readonly string BlockedAudio = null;
[Desc("Notification displayed when you can't train another actor",
"when the build limit exceeded or the exit is jammed.")]
public readonly string BlockedTextNotification = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("Notification played when you can't queue another actor", [Desc("Notification played when you can't queue another actor",
"when the queue length limit is exceeded.", "when the queue length limit is exceeded.",
"The filename of the audio is defined per faction in notifications.yaml.")] "The filename of the audio is defined per faction in notifications.yaml.")]
public readonly string LimitedAudio = null; public readonly string LimitedAudio = null;
[Desc("Notification displayed when you can't queue another actor",
"when the queue length limit is exceeded.")]
public readonly string LimitedTextNotification = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("Notification played when you can't place a building.", [Desc("Notification played when you can't place a building.",
"Overrides PlaceBuilding.CannotPlaceNotification for this queue.", "Overrides PlaceBuilding.CannotPlaceNotification for this queue.",
@@ -84,16 +95,25 @@ namespace OpenRA.Mods.Common.Traits
"The filename of the audio is defined per faction in notifications.yaml.")] "The filename of the audio is defined per faction in notifications.yaml.")]
public readonly string QueuedAudio = null; public readonly string QueuedAudio = null;
[Desc("Notification displayed when user clicks on the build palette icon.")]
public readonly string QueuedTextNotification = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("Notification played when player right-clicks on the build palette icon.", [Desc("Notification played when player right-clicks on the build palette icon.",
"The filename of the audio is defined per faction in notifications.yaml.")] "The filename of the audio is defined per faction in notifications.yaml.")]
public readonly string OnHoldAudio = null; public readonly string OnHoldAudio = null;
[Desc("Notification displayed when player right-clicks on the build palette icon.")]
public readonly string OnHoldTextNotification = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("Notification played when player right-clicks on a build palette icon that is already on hold.", [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.")] "The filename of the audio is defined per faction in notifications.yaml.")]
public readonly string CancelledAudio = null; public readonly string CancelledAudio = null;
[Desc("Notification displayed when player right-clicks on a build palette icon that is already on hold.")]
public readonly string CancelledTextNotification = null;
public override object Create(ActorInitializer init) { return new ProductionQueue(init, this); } public override object Create(ActorInitializer init) { return new ProductionQueue(init, this); }
public void RulesetLoaded(Ruleset rules, ActorInfo ai) public void RulesetLoaded(Ruleset rules, ActorInfo ai)
@@ -333,9 +353,10 @@ namespace OpenRA.Mods.Common.Traits
} }
} }
public bool CanQueue(ActorInfo actor, out string notificationAudio) public bool CanQueue(ActorInfo actor, out string notificationAudio, out string notificationText)
{ {
notificationAudio = Info.BlockedAudio; notificationAudio = Info.BlockedAudio;
notificationText = Info.BlockedTextNotification;
var bi = actor.TraitInfoOrDefault<BuildableInfo>(); var bi = actor.TraitInfoOrDefault<BuildableInfo>();
if (bi == null) if (bi == null)
@@ -346,6 +367,7 @@ namespace OpenRA.Mods.Common.Traits
if (Info.QueueLimit > 0 && Queue.Count >= Info.QueueLimit) if (Info.QueueLimit > 0 && Queue.Count >= Info.QueueLimit)
{ {
notificationAudio = Info.LimitedAudio; notificationAudio = Info.LimitedAudio;
notificationText = Info.LimitedTextNotification;
return false; return false;
} }
@@ -353,6 +375,7 @@ namespace OpenRA.Mods.Common.Traits
if (Info.ItemLimit > 0 && queueCount >= Info.ItemLimit) if (Info.ItemLimit > 0 && queueCount >= Info.ItemLimit)
{ {
notificationAudio = Info.LimitedAudio; notificationAudio = Info.LimitedAudio;
notificationText = Info.LimitedTextNotification;
return false; return false;
} }
@@ -366,6 +389,7 @@ namespace OpenRA.Mods.Common.Traits
} }
notificationAudio = Info.QueuedAudio; notificationAudio = Info.QueuedAudio;
notificationText = Info.QueuedTextNotification;
return true; return true;
} }
@@ -424,13 +448,22 @@ namespace OpenRA.Mods.Common.Traits
var isBuilding = unit.HasTraitInfo<BuildingInfo>(); var isBuilding = unit.HasTraitInfo<BuildingInfo>();
if (isBuilding && !hasPlayedSound) if (isBuilding && !hasPlayedSound)
{
hasPlayedSound = Game.Sound.PlayNotification(rules, self.Owner, "Speech", Info.ReadyAudio, self.Owner.Faction.InternalName); hasPlayedSound = Game.Sound.PlayNotification(rules, self.Owner, "Speech", Info.ReadyAudio, self.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(Info.ReadyTextNotification, self.Owner);
}
else if (!isBuilding) else if (!isBuilding)
{ {
if (BuildUnit(unit)) if (BuildUnit(unit))
{
Game.Sound.PlayNotification(rules, self.Owner, "Speech", Info.ReadyAudio, self.Owner.Faction.InternalName); Game.Sound.PlayNotification(rules, self.Owner, "Speech", Info.ReadyAudio, self.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(Info.ReadyTextNotification, self.Owner);
}
else if (!hasPlayedSound && time > 0) else if (!hasPlayedSound && time > 0)
{
hasPlayedSound = Game.Sound.PlayNotification(rules, self.Owner, "Speech", Info.BlockedAudio, self.Owner.Faction.InternalName); hasPlayedSound = Game.Sound.PlayNotification(rules, self.Owner, "Speech", Info.BlockedAudio, self.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(Info.BlockedTextNotification, self.Owner);
}
} }
})), !order.Queued); })), !order.Queued);
} }

View File

@@ -24,9 +24,12 @@ namespace OpenRA.Mods.Common.Traits
public readonly int Threshold = 80; public readonly int Threshold = 80;
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("The speech to play for the warning.")] [Desc("Speech to play for the warning.")]
public readonly string Notification = "SilosNeeded"; public readonly string Notification = "SilosNeeded";
[Desc("Text to display for the warning.")]
public readonly string TextNotification = null;
public override object Create(ActorInitializer init) { return new ResourceStorageWarning(init.Self, this); } public override object Create(ActorInitializer init) { return new ResourceStorageWarning(init.Self, this); }
} }
@@ -50,7 +53,10 @@ namespace OpenRA.Mods.Common.Traits
var owner = self.Owner; var owner = self.Owner;
if (resources.Resources > info.Threshold * resources.ResourceCapacity / 100) if (resources.Resources > info.Threshold * resources.ResourceCapacity / 100)
{
Game.Sound.PlayNotification(self.World.Map.Rules, owner, "Speech", info.Notification, owner.Faction.InternalName); Game.Sound.PlayNotification(self.World.Map.Rules, owner, "Speech", info.Notification, owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(info.TextNotification, owner);
}
lastSiloAdviceTime = Game.RunTime; lastSiloAdviceTime = Game.RunTime;
} }

View File

@@ -140,7 +140,10 @@ namespace OpenRA.Mods.Common.Traits
Game.RunAfterDelay(info.NotificationDelay, () => Game.RunAfterDelay(info.NotificationDelay, () =>
{ {
if (Game.IsCurrentWorld(player.World) && player == player.World.LocalPlayer) if (Game.IsCurrentWorld(player.World) && player == player.World.LocalPlayer)
{
Game.Sound.PlayNotification(player.World.Map.Rules, player, "Speech", mo.Info.LoseNotification, player.Faction.InternalName); Game.Sound.PlayNotification(player.World.Map.Rules, player, "Speech", mo.Info.LoseNotification, player.Faction.InternalName);
TextNotificationsManager.AddTransientLine(mo.Info.LoseTextNotification, player);
}
}); });
} }
@@ -153,7 +156,10 @@ namespace OpenRA.Mods.Common.Traits
Game.RunAfterDelay(info.NotificationDelay, () => Game.RunAfterDelay(info.NotificationDelay, () =>
{ {
if (Game.IsCurrentWorld(player.World) && player == player.World.LocalPlayer) if (Game.IsCurrentWorld(player.World) && player == player.World.LocalPlayer)
{
Game.Sound.PlayNotification(player.World.Map.Rules, player, "Speech", mo.Info.WinNotification, player.Faction.InternalName); Game.Sound.PlayNotification(player.World.Map.Rules, player, "Speech", mo.Info.WinNotification, player.Faction.InternalName);
TextNotificationsManager.AddTransientLine(mo.Info.WinTextNotification, player);
}
}); });
} }
} }

View File

@@ -25,6 +25,8 @@ namespace OpenRA.Mods.Common.Traits
[NotificationReference("Speech")] [NotificationReference("Speech")]
public readonly string SpeechNotification = null; public readonly string SpeechNotification = null;
public readonly string TextNotification = null;
public override object Create(ActorInitializer init) { return new PowerManager(init.Self, this); } public override object Create(ActorInitializer init) { return new PowerManager(init.Self, this); }
} }
@@ -161,6 +163,8 @@ namespace OpenRA.Mods.Common.Traits
if (isLowPower && Game.RunTime > lastPowerAdviceTime + info.AdviceInterval) if (isLowPower && Game.RunTime > lastPowerAdviceTime + info.AdviceInterval)
{ {
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", info.SpeechNotification, self.Owner.Faction.InternalName); Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", info.SpeechNotification, self.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(info.TextNotification, self.Owner);
lastPowerAdviceTime = Game.RunTime; lastPowerAdviceTime = Game.RunTime;
} }

View File

@@ -29,9 +29,12 @@ namespace OpenRA.Mods.Common.Traits
public readonly string ChuteSound = null; public readonly string ChuteSound = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("Notification to play when dropping the unit.")] [Desc("Speech notification to play when dropping the unit.")]
public readonly string ReadyAudio = null; public readonly string ReadyAudio = null;
[Desc("Text notification to display when dropping the unit.")]
public readonly string ReadyTextNotification = null;
public override object Create(ActorInitializer init) { return new ProductionParadrop(init, this); } public override object Create(ActorInitializer init) { return new ProductionParadrop(init, this); }
} }
@@ -97,6 +100,7 @@ namespace OpenRA.Mods.Common.Traits
self.World.AddFrameEndTask(ww => DoProduction(self, producee, exit?.Info, productionType, inits)); self.World.AddFrameEndTask(ww => DoProduction(self, producee, exit?.Info, productionType, inits));
Game.Sound.Play(SoundType.World, info.ChuteSound, self.CenterPosition); Game.Sound.Play(SoundType.World, info.ChuteSound, self.CenterPosition);
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", info.ReadyAudio, self.Owner.Faction.InternalName); Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", info.ReadyAudio, self.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(info.ReadyTextNotification, self.Owner);
})); }));
actor.QueueActivity(new Fly(actor, Target.FromCell(w, endPos))); actor.QueueActivity(new Fly(actor, Target.FromCell(w, endPos)));

View File

@@ -42,6 +42,9 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Speech notification to play when a bridge is repaired.")] [Desc("Speech notification to play when a bridge is repaired.")]
public readonly string RepairNotification = null; public readonly string RepairNotification = null;
[Desc("Text notification to display when a bridge is repaired.")]
public readonly string RepairTextNotification = null;
public override object Create(ActorInitializer init) { return new RepairsBridges(this); } public override object Create(ActorInitializer init) { return new RepairsBridges(this); }
} }
@@ -107,7 +110,7 @@ namespace OpenRA.Mods.Common.Traits
else else
return; return;
self.QueueActivity(order.Queued, new RepairBridge(self, order.Target, info.EnterBehaviour, info.RepairNotification, info.TargetLineColor)); self.QueueActivity(order.Queued, new RepairBridge(self, order.Target, info.EnterBehaviour, info.RepairNotification, info.RepairTextNotification, info.TargetLineColor));
self.ShowTargetLines(); self.ShowTargetLines();
} }
} }

View File

@@ -28,13 +28,19 @@ namespace OpenRA.Mods.Common.Traits
public readonly BitSet<DamageType> RepairDamageTypes = default(BitSet<DamageType>); public readonly BitSet<DamageType> RepairDamageTypes = default(BitSet<DamageType>);
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("The sound played when starting to repair a unit.")] [Desc("Speech notification played when starting to repair a unit.")]
public readonly string StartRepairingNotification = null; public readonly string StartRepairingNotification = null;
[Desc("Text notification displayed when starting to repair a unit.")]
public readonly string StartRepairingTextNotification = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("The sound played when repairing a unit is done.")] [Desc("Speech notification played when repairing a unit is done.")]
public readonly string FinishRepairingNotification = null; public readonly string FinishRepairingNotification = null;
[Desc("Text notification displayed when repairing a unit is done.")]
public readonly string FinishRepairingTextNotification = null;
[Desc("Experience gained by the player owning this actor for repairing an allied unit.")] [Desc("Experience gained by the player owning this actor for repairing an allied unit.")]
public readonly int PlayerExperience = 0; public readonly int PlayerExperience = 0;

View File

@@ -27,9 +27,12 @@ namespace OpenRA.Mods.Common.Traits
public readonly string[] SellSounds = Array.Empty<string>(); public readonly string[] SellSounds = Array.Empty<string>();
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("The audio notification type to play.")] [Desc("Speech notification to play.")]
public readonly string Notification = null; public readonly string Notification = null;
[Desc("Text notification to display.")]
public string TextNotification = null;
[Desc("Whether to show the cash tick indicators rising from the actor.")] [Desc("Whether to show the cash tick indicators rising from the actor.")]
public readonly bool ShowTicks = true; public readonly bool ShowTicks = true;

View File

@@ -16,8 +16,12 @@ namespace OpenRA.Mods.Common.Traits.Sound
class ActorLostNotificationInfo : ConditionalTraitInfo class ActorLostNotificationInfo : ConditionalTraitInfo
{ {
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("Speech notification to play.")]
public readonly string Notification = "UnitLost"; public readonly string Notification = "UnitLost";
[Desc("Text notification to display.")]
public readonly string TextNotification = null;
public readonly bool NotifyAll = false; public readonly bool NotifyAll = false;
public override object Create(ActorInitializer init) { return new ActorLostNotification(this); } public override object Create(ActorInitializer init) { return new ActorLostNotification(this); }
@@ -33,8 +37,15 @@ namespace OpenRA.Mods.Common.Traits.Sound
if (IsTraitDisabled) if (IsTraitDisabled)
return; return;
var player = Info.NotifyAll ? self.World.LocalPlayer : self.Owner; var localPlayer = self.World.LocalPlayer;
if (localPlayer == null || localPlayer.Spectating)
return;
var player = Info.NotifyAll ? localPlayer : self.Owner;
Game.Sound.PlayNotification(self.World.Map.Rules, player, "Speech", Info.Notification, self.Owner.Faction.InternalName); Game.Sound.PlayNotification(self.World.Map.Rules, player, "Speech", Info.Notification, self.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(Info.TextNotification, player);
} }
} }
} }

View File

@@ -23,8 +23,12 @@ namespace OpenRA.Mods.Common.Traits.Sound
public readonly bool PingRadar = false; public readonly bool PingRadar = false;
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("Speech notification to play.")]
public readonly string Notification = null; public readonly string Notification = null;
[Desc("Text notification to display.")]
public readonly string TextNotification = null;
public readonly bool AnnounceNeutrals = false; public readonly bool AnnounceNeutrals = false;
public override object Create(ActorInitializer init) { return new AnnounceOnSeen(init.Self, this); } public override object Create(ActorInitializer init) { return new AnnounceOnSeen(init.Self, this); }
@@ -56,6 +60,9 @@ namespace OpenRA.Mods.Common.Traits.Sound
if (discoverer != null && !string.IsNullOrEmpty(Info.Notification)) if (discoverer != null && !string.IsNullOrEmpty(Info.Notification))
Game.Sound.PlayNotification(self.World.Map.Rules, discoverer, "Speech", Info.Notification, discoverer.Faction.InternalName); Game.Sound.PlayNotification(self.World.Map.Rules, discoverer, "Speech", Info.Notification, discoverer.Faction.InternalName);
if (discoverer != null)
TextNotificationsManager.AddTransientLine(Info.TextNotification, discoverer);
// Radar notification // Radar notification
if (Info.PingRadar) if (Info.PingRadar)
radarPings.Value?.Add(() => true, self.CenterPosition, Color.Red, 50); radarPings.Value?.Add(() => true, self.CenterPosition, Color.Red, 50);

View File

@@ -17,16 +17,22 @@ namespace OpenRA.Mods.Common.Traits.Sound
public class CaptureNotificationInfo : TraitInfo public class CaptureNotificationInfo : TraitInfo
{ {
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("The speech notification to play to the new owner.")] [Desc("Speech notification to play to the new owner.")]
public readonly string Notification = "BuildingCaptured"; public readonly string Notification = "BuildingCaptured";
[Desc("Text notification to display to the new owner.")]
public readonly string TextNotification = null;
[Desc("Specifies if Notification is played with the voice of the new owners faction.")] [Desc("Specifies if Notification is played with the voice of the new owners faction.")]
public readonly bool NewOwnerVoice = true; public readonly bool NewOwnerVoice = true;
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("The speech notification to play to the old owner.")] [Desc("Speech notification to play to the old owner.")]
public readonly string LoseNotification = null; public readonly string LoseNotification = null;
[Desc("Text notification to display to the old owner.")]
public readonly string LoseTextNotification = null;
[Desc("Specifies if LoseNotification is played with the voice of the new owners faction.")] [Desc("Specifies if LoseNotification is played with the voice of the new owners faction.")]
public readonly bool LoseNewOwnerVoice = false; public readonly bool LoseNewOwnerVoice = false;
@@ -45,9 +51,11 @@ namespace OpenRA.Mods.Common.Traits.Sound
{ {
var faction = info.NewOwnerVoice ? newOwner.Faction.InternalName : oldOwner.Faction.InternalName; var faction = info.NewOwnerVoice ? newOwner.Faction.InternalName : oldOwner.Faction.InternalName;
Game.Sound.PlayNotification(self.World.Map.Rules, newOwner, "Speech", info.Notification, faction); Game.Sound.PlayNotification(self.World.Map.Rules, newOwner, "Speech", info.Notification, faction);
TextNotificationsManager.AddTransientLine(info.TextNotification, newOwner);
var loseFaction = info.LoseNewOwnerVoice ? newOwner.Faction.InternalName : oldOwner.Faction.InternalName; var loseFaction = info.LoseNewOwnerVoice ? newOwner.Faction.InternalName : oldOwner.Faction.InternalName;
Game.Sound.PlayNotification(self.World.Map.Rules, oldOwner, "Speech", info.LoseNotification, loseFaction); Game.Sound.PlayNotification(self.World.Map.Rules, oldOwner, "Speech", info.LoseNotification, loseFaction);
TextNotificationsManager.AddTransientLine(info.LoseTextNotification, oldOwner);
} }
} }
} }

View File

@@ -27,9 +27,12 @@ namespace OpenRA.Mods.Common.Traits
public readonly WVec SquadOffset = new WVec(-1536, 1536, 0); public readonly WVec SquadOffset = new WVec(-1536, 1536, 0);
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("Notification to play when entering the drop zone.")] [Desc("Speech notification to play when entering the drop zone.")]
public readonly string ReinforcementsArrivedSpeechNotification = null; public readonly string ReinforcementsArrivedSpeechNotification = null;
[Desc("Text notification to display when entering the drop zone.")]
public readonly string ReinforcementsArrivedTextNotification = null;
[Desc("Number of facings that the delivery aircraft may approach from.")] [Desc("Number of facings that the delivery aircraft may approach from.")]
public readonly int QuantizedFacings = 32; public readonly int QuantizedFacings = 32;
@@ -134,9 +137,13 @@ namespace OpenRA.Mods.Common.Traits
RemoveBeacon(beacon); RemoveBeacon(beacon);
if (!aircraftInRange.Any(kv => kv.Value)) if (!aircraftInRange.Any(kv => kv.Value))
{
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech",
info.ReinforcementsArrivedSpeechNotification, self.Owner.Faction.InternalName); info.ReinforcementsArrivedSpeechNotification, self.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(info.ReinforcementsArrivedTextNotification, self.Owner);
}
aircraftInRange[a] = true; aircraftInRange[a] = true;
}; };

View File

@@ -28,15 +28,21 @@ namespace OpenRA.Mods.Common.Traits
public readonly string Type = null; public readonly string Type = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("Notification played when production is activated.", [Desc("Speech notification played when production is activated.",
"The filename of the audio is defined per faction in notifications.yaml.")] "The filename of the audio is defined per faction in notifications.yaml.")]
public readonly string ReadyAudio = null; public readonly string ReadyAudio = null;
[Desc("Text notification displayed when production is activated.")]
public readonly string ReadyTextNotification = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("Notification played when the exit is jammed.", [Desc("Speech notification played when the exit is jammed.",
"The filename of the audio is defined per faction in notifications.yaml.")] "The filename of the audio is defined per faction in notifications.yaml.")]
public readonly string BlockedAudio = null; public readonly string BlockedAudio = null;
[Desc("Text notification displayed when the exit is jammed.")]
public readonly string BlockedTextNotification = null;
public override object Create(ActorInitializer init) { return new ProduceActorPower(init, this); } public override object Create(ActorInitializer init) { return new ProduceActorPower(init, this); }
} }
@@ -91,9 +97,15 @@ namespace OpenRA.Mods.Common.Traits
} }
if (activated) if (activated)
{
Game.Sound.PlayNotification(self.World.Map.Rules, manager.Self.Owner, "Speech", info.ReadyAudio, self.Owner.Faction.InternalName); Game.Sound.PlayNotification(self.World.Map.Rules, manager.Self.Owner, "Speech", info.ReadyAudio, self.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(info.ReadyTextNotification, manager.Self.Owner);
}
else else
{
Game.Sound.PlayNotification(self.World.Map.Rules, manager.Self.Owner, "Speech", info.BlockedAudio, self.Owner.Faction.InternalName); Game.Sound.PlayNotification(self.World.Map.Rules, manager.Self.Owner, "Speech", info.BlockedAudio, self.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(info.BlockedTextNotification, manager.Self.Owner);
}
} }
} }
} }

View File

@@ -95,6 +95,9 @@ namespace OpenRA.Mods.Common.Traits
Game.Sound.PlayToPlayer(SoundType.UI, manager.Self.Owner, Info.SelectTargetSound); Game.Sound.PlayToPlayer(SoundType.UI, manager.Self.Owner, Info.SelectTargetSound);
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech",
Info.SelectTargetSpeechNotification, self.Owner.Faction.InternalName); Info.SelectTargetSpeechNotification, self.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(Info.SelectTargetTextNotification, manager.Self.Owner);
self.World.OrderGenerator = new SelectSpawnActorPowerTarget(order, manager, this, MouseButton.Left); self.World.OrderGenerator = new SelectSpawnActorPowerTarget(order, manager, this, MouseButton.Left);
} }

View File

@@ -53,36 +53,50 @@ namespace OpenRA.Mods.Common.Traits
[NotificationReference("Speech")] [NotificationReference("Speech")]
public readonly string DetectedSpeechNotification = null; public readonly string DetectedSpeechNotification = null;
public readonly string DetectedTextNotification = null;
public readonly string BeginChargeSound = null; public readonly string BeginChargeSound = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
public readonly string BeginChargeSpeechNotification = null; public readonly string BeginChargeSpeechNotification = null;
public readonly string BeginChargeTextNotification = null;
public readonly string EndChargeSound = null; public readonly string EndChargeSound = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
public readonly string EndChargeSpeechNotification = null; public readonly string EndChargeSpeechNotification = null;
public readonly string EndChargeTextNotification = null;
public readonly string SelectTargetSound = null; public readonly string SelectTargetSound = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
public readonly string SelectTargetSpeechNotification = null; public readonly string SelectTargetSpeechNotification = null;
public readonly string SelectTargetTextNotification = null;
public readonly string InsufficientPowerSound = null; public readonly string InsufficientPowerSound = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
public readonly string InsufficientPowerSpeechNotification = null; public readonly string InsufficientPowerSpeechNotification = null;
public readonly string InsufficientPowerTextNotification = null;
public readonly string LaunchSound = null; public readonly string LaunchSound = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
public readonly string LaunchSpeechNotification = null; public readonly string LaunchSpeechNotification = null;
public readonly string LaunchTextNotification = null;
public readonly string IncomingSound = null; public readonly string IncomingSound = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
public readonly string IncomingSpeechNotification = null; public readonly string IncomingSpeechNotification = null;
public readonly string IncomingTextNotification = null;
[Desc("Defines to which players the timer is shown.")] [Desc("Defines to which players the timer is shown.")]
public readonly PlayerRelationship DisplayTimerRelationships = PlayerRelationship.None; public readonly PlayerRelationship DisplayTimerRelationships = PlayerRelationship.None;
@@ -147,11 +161,12 @@ namespace OpenRA.Mods.Common.Traits
{ {
base.Created(self); base.Created(self);
var renderPlayer = self.World.RenderPlayer; var player = self.World.LocalPlayer;
if (renderPlayer != null && renderPlayer != self.Owner) if (player != null && player != self.Owner)
{ {
Game.Sound.Play(SoundType.UI, Info.DetectedSound); Game.Sound.Play(SoundType.UI, Info.DetectedSound);
Game.Sound.PlayNotification(self.World.Map.Rules, renderPlayer, "Speech", info.DetectedSpeechNotification, renderPlayer.Faction.InternalName); Game.Sound.PlayNotification(self.World.Map.Rules, player, "Speech", info.DetectedSpeechNotification, player.Faction.InternalName);
TextNotificationsManager.AddTransientLine(info.DetectedTextNotification, player);
} }
} }
@@ -165,6 +180,8 @@ namespace OpenRA.Mods.Common.Traits
Game.Sound.PlayToPlayer(SoundType.UI, self.Owner, Info.BeginChargeSound); Game.Sound.PlayToPlayer(SoundType.UI, self.Owner, Info.BeginChargeSound);
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech",
Info.BeginChargeSpeechNotification, self.Owner.Faction.InternalName); Info.BeginChargeSpeechNotification, self.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(Info.BeginChargeTextNotification, self.Owner);
} }
public virtual void Charged(Actor self, string key) public virtual void Charged(Actor self, string key)
@@ -173,6 +190,8 @@ namespace OpenRA.Mods.Common.Traits
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech",
Info.EndChargeSpeechNotification, self.Owner.Faction.InternalName); Info.EndChargeSpeechNotification, self.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(Info.EndChargeTextNotification, self.Owner);
foreach (var notify in self.TraitsImplementing<INotifySupportPower>()) foreach (var notify in self.TraitsImplementing<INotifySupportPower>())
notify.Charged(self); notify.Charged(self);
} }
@@ -199,13 +218,19 @@ namespace OpenRA.Mods.Common.Traits
public virtual void PlayLaunchSounds() public virtual void PlayLaunchSounds()
{ {
var renderPlayer = Self.World.RenderPlayer; var localPlayer = Self.World.LocalPlayer;
var isAllied = Self.Owner.IsAlliedWith(renderPlayer);
if (localPlayer == null || localPlayer.Spectating)
return;
var isAllied = Self.Owner.IsAlliedWith(localPlayer);
Game.Sound.Play(SoundType.UI, isAllied ? Info.LaunchSound : Info.IncomingSound); Game.Sound.Play(SoundType.UI, isAllied ? Info.LaunchSound : Info.IncomingSound);
var toPlayer = isAllied ? renderPlayer ?? Self.Owner : renderPlayer; var toPlayer = isAllied ? localPlayer ?? Self.Owner : localPlayer;
var speech = isAllied ? Info.LaunchSpeechNotification : Info.IncomingSpeechNotification; var speech = isAllied ? Info.LaunchSpeechNotification : Info.IncomingSpeechNotification;
Game.Sound.PlayNotification(Self.World.Map.Rules, toPlayer, "Speech", speech, toPlayer.Faction.InternalName); Game.Sound.PlayNotification(Self.World.Map.Rules, toPlayer, "Speech", speech, toPlayer.Faction.InternalName);
TextNotificationsManager.AddTransientLine(isAllied ? Info.LaunchTextNotification : Info.IncomingTextNotification, toPlayer);
} }
public IEnumerable<CPos> CellsMatching(CPos location, char[] footprint, CVec dimensions) public IEnumerable<CPos> CellsMatching(CPos location, char[] footprint, CVec dimensions)

View File

@@ -231,6 +231,8 @@ namespace OpenRA.Mods.Common.Traits
Game.Sound.PlayNotification(power.Self.World.Map.Rules, power.Self.Owner, "Speech", Game.Sound.PlayNotification(power.Self.World.Map.Rules, power.Self.Owner, "Speech",
Info.SelectTargetSpeechNotification, power.Self.Owner.Faction.InternalName); Info.SelectTargetSpeechNotification, power.Self.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(Info.SelectTargetTextNotification, power.Self.Owner);
power.SelectTarget(power.Self, Key, Manager); power.SelectTarget(power.Self, Key, Manager);
} }

View File

@@ -39,13 +39,19 @@ namespace OpenRA.Mods.Common.Traits
public readonly string[] NoTransformSounds = Array.Empty<string>(); public readonly string[] NoTransformSounds = Array.Empty<string>();
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("Notification to play when transforming.")] [Desc("Speech notification to play when transforming.")]
public readonly string TransformNotification = null; public readonly string TransformNotification = null;
[Desc("Text notification to display when transforming.")]
public readonly string TransformTextNotification = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
[Desc("Notification to play when the transformation is blocked.")] [Desc("Speech notification to play when the transformation is blocked.")]
public readonly string NoTransformNotification = null; public readonly string NoTransformNotification = null;
[Desc("Text notification to display when the transformation is blocked.")]
public readonly string NoTransformTextNotification = null;
[CursorReference] [CursorReference]
[Desc("Cursor to display when able to (un)deploy the actor.")] [Desc("Cursor to display when able to (un)deploy the actor.")]
public readonly string DeployCursor = "deploy"; public readonly string DeployCursor = "deploy";
@@ -97,6 +103,7 @@ namespace OpenRA.Mods.Common.Traits
Facing = Info.Facing, Facing = Info.Facing,
Sounds = Info.TransformSounds, Sounds = Info.TransformSounds,
Notification = Info.TransformNotification, Notification = Info.TransformNotification,
TextNotification = Info.TransformTextNotification,
Faction = faction Faction = faction
}; };
} }
@@ -136,6 +143,7 @@ namespace OpenRA.Mods.Common.Traits
Game.Sound.PlayToPlayer(SoundType.World, self.Owner, s); Game.Sound.PlayToPlayer(SoundType.World, self.Owner, s);
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Info.NoTransformNotification, self.Owner.Faction.InternalName); Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Info.NoTransformNotification, self.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(Info.NoTransformTextNotification, self.Owner);
return; return;
} }

View File

@@ -20,12 +20,18 @@ namespace OpenRA.Mods.Common.Traits
[NotificationReference("Speech")] [NotificationReference("Speech")]
public readonly string Notification = "StartGame"; public readonly string Notification = "StartGame";
public readonly string TextNotification = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
public readonly string LoadedNotification = "GameLoaded"; public readonly string LoadedNotification = "GameLoaded";
public readonly string LoadedTextNotification = null;
[NotificationReference("Speech")] [NotificationReference("Speech")]
public readonly string SavedNotification = "GameSaved"; public readonly string SavedNotification = "GameSaved";
public readonly string SavedTextNotification = null;
public override object Create(ActorInitializer init) { return new StartGameNotification(this); } public override object Create(ActorInitializer init) { return new StartGameNotification(this); }
} }
@@ -40,19 +46,28 @@ namespace OpenRA.Mods.Common.Traits
void IWorldLoaded.WorldLoaded(World world, WorldRenderer wr) void IWorldLoaded.WorldLoaded(World world, WorldRenderer wr)
{ {
if (!world.IsLoadingGameSave) if (!world.IsLoadingGameSave)
{
Game.Sound.PlayNotification(world.Map.Rules, null, "Speech", info.Notification, world.RenderPlayer == null ? null : world.RenderPlayer.Faction.InternalName); Game.Sound.PlayNotification(world.Map.Rules, null, "Speech", info.Notification, world.RenderPlayer == null ? null : world.RenderPlayer.Faction.InternalName);
TextNotificationsManager.AddTransientLine(info.TextNotification, null);
}
} }
void INotifyGameLoaded.GameLoaded(World world) void INotifyGameLoaded.GameLoaded(World world)
{ {
if (!world.IsReplay) if (!world.IsReplay)
{
Game.Sound.PlayNotification(world.Map.Rules, null, "Speech", info.LoadedNotification, world.RenderPlayer == null ? null : world.RenderPlayer.Faction.InternalName); Game.Sound.PlayNotification(world.Map.Rules, null, "Speech", info.LoadedNotification, world.RenderPlayer == null ? null : world.RenderPlayer.Faction.InternalName);
TextNotificationsManager.AddTransientLine(info.LoadedTextNotification, null);
}
} }
void INotifyGameSaved.GameSaved(World world) void INotifyGameSaved.GameSaved(World world)
{ {
if (!world.IsReplay) if (!world.IsReplay)
{
Game.Sound.PlayNotification(world.Map.Rules, null, "Speech", info.SavedNotification, world.RenderPlayer == null ? null : world.RenderPlayer.Faction.InternalName); Game.Sound.PlayNotification(world.Map.Rules, null, "Speech", info.SavedNotification, world.RenderPlayer == null ? null : world.RenderPlayer.Faction.InternalName);
TextNotificationsManager.AddTransientLine(info.SavedTextNotification, null);
}
} }
} }
} }

View File

@@ -121,6 +121,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{ {
var faction = world.LocalPlayer?.Faction.InternalName; var faction = world.LocalPlayer?.Faction.InternalName;
Game.Sound.PlayNotification(world.Map.Rules, null, "Speech", moi.LeaveNotification, faction); Game.Sound.PlayNotification(world.Map.Rules, null, "Speech", moi.LeaveNotification, faction);
TextNotificationsManager.AddTransientLine(moi.LeaveTextNotification, null);
} }
} }

View File

@@ -305,6 +305,8 @@ namespace OpenRA.Mods.Common.Widgets
// Resume a paused item // Resume a paused item
Game.Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Sounds", ClickSound, null); Game.Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Sounds", ClickSound, null);
Game.Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Speech", CurrentQueue.Info.QueuedAudio, World.LocalPlayer.Faction.InternalName); Game.Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Speech", CurrentQueue.Info.QueuedAudio, World.LocalPlayer.Faction.InternalName);
TextNotificationsManager.AddTransientLine(CurrentQueue.Info.QueuedTextNotification, World.LocalPlayer);
World.IssueOrder(Order.PauseProduction(CurrentQueue.Actor, icon.Name, false)); World.IssueOrder(Order.PauseProduction(CurrentQueue.Actor, icon.Name, false));
return true; return true;
} }
@@ -315,10 +317,13 @@ namespace OpenRA.Mods.Common.Widgets
{ {
// Queue a new item // Queue a new item
Game.Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Sounds", ClickSound, null); Game.Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Sounds", ClickSound, null);
var canQueue = CurrentQueue.CanQueue(buildable, out var notification); var canQueue = CurrentQueue.CanQueue(buildable, out var notification, out var textNotification);
if (!CurrentQueue.AllQueued().Any()) if (!CurrentQueue.AllQueued().Any())
{
Game.Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Speech", notification, World.LocalPlayer.Faction.InternalName); Game.Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Speech", notification, World.LocalPlayer.Faction.InternalName);
TextNotificationsManager.AddTransientLine(textNotification, World.LocalPlayer);
}
if (canQueue) if (canQueue)
{ {
@@ -342,12 +347,16 @@ namespace OpenRA.Mods.Common.Widgets
{ {
// Instantly cancel items that haven't started, have finished, or if the queue doesn't support pausing // Instantly cancel items that haven't started, have finished, or if the queue doesn't support pausing
Game.Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Speech", CurrentQueue.Info.CancelledAudio, World.LocalPlayer.Faction.InternalName); Game.Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Speech", CurrentQueue.Info.CancelledAudio, World.LocalPlayer.Faction.InternalName);
TextNotificationsManager.AddTransientLine(CurrentQueue.Info.CancelledTextNotification, World.LocalPlayer);
World.IssueOrder(Order.CancelProduction(CurrentQueue.Actor, icon.Name, handleCount)); World.IssueOrder(Order.CancelProduction(CurrentQueue.Actor, icon.Name, handleCount));
} }
else else
{ {
// Pause an existing item // Pause an existing item
Game.Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Speech", CurrentQueue.Info.OnHoldAudio, World.LocalPlayer.Faction.InternalName); Game.Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Speech", CurrentQueue.Info.OnHoldAudio, World.LocalPlayer.Faction.InternalName);
TextNotificationsManager.AddTransientLine(CurrentQueue.Info.OnHoldTextNotification, World.LocalPlayer);
World.IssueOrder(Order.PauseProduction(CurrentQueue.Actor, icon.Name, true)); World.IssueOrder(Order.PauseProduction(CurrentQueue.Actor, icon.Name, true));
} }
@@ -362,6 +371,8 @@ namespace OpenRA.Mods.Common.Widgets
// Directly cancel, skipping "on-hold" // Directly cancel, skipping "on-hold"
Game.Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Sounds", ClickSound, null); Game.Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Sounds", ClickSound, null);
Game.Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Speech", CurrentQueue.Info.CancelledAudio, World.LocalPlayer.Faction.InternalName); Game.Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Speech", CurrentQueue.Info.CancelledAudio, World.LocalPlayer.Faction.InternalName);
TextNotificationsManager.AddTransientLine(CurrentQueue.Info.CancelledTextNotification, World.LocalPlayer);
World.IssueOrder(Order.CancelProduction(CurrentQueue.Actor, icon.Name, handleCount)); World.IssueOrder(Order.CancelProduction(CurrentQueue.Actor, icon.Name, handleCount));
return true; return true;

View File

@@ -173,6 +173,8 @@ namespace OpenRA.Mods.Common.Widgets
Game.Sound.PlayToPlayer(SoundType.UI, spm.Self.Owner, clicked.Power.Info.InsufficientPowerSound); Game.Sound.PlayToPlayer(SoundType.UI, spm.Self.Owner, clicked.Power.Info.InsufficientPowerSound);
Game.Sound.PlayNotification(spm.Self.World.Map.Rules, spm.Self.Owner, "Speech", Game.Sound.PlayNotification(spm.Self.World.Map.Rules, spm.Self.Owner, "Speech",
clicked.Power.Info.InsufficientPowerSpeechNotification, spm.Self.Owner.Faction.InternalName); clicked.Power.Info.InsufficientPowerSpeechNotification, spm.Self.Owner.Faction.InternalName);
TextNotificationsManager.AddTransientLine(clicked.Power.Info.InsufficientPowerTextNotification, spm.Self.Owner);
} }
else else
clicked.Power.Target(); clicked.Power.Target();

View File

@@ -82,6 +82,9 @@ namespace OpenRA.Mods.D2k.Activities
foreach (var player in affectedPlayers) foreach (var player in affectedPlayers)
self.World.AddFrameEndTask(w => w.Add(new MapNotificationEffect(player, "Speech", swallow.Info.WormAttackNotification, 25, true, attackPosition, Color.Red))); self.World.AddFrameEndTask(w => w.Add(new MapNotificationEffect(player, "Speech", swallow.Info.WormAttackNotification, 25, true, attackPosition, Color.Red)));
if (affectedPlayers.Contains(self.World.LocalPlayer))
TextNotificationsManager.AddTransientLine(swallow.Info.WormAttackTextNotification, self.World.LocalPlayer);
var barrel = armament.CheckFire(self, facing, target); var barrel = armament.CheckFire(self, facing, target);
if (barrel == null) if (barrel == null)
return false; return false;

View File

@@ -38,6 +38,8 @@ namespace OpenRA.Mods.D2k.Traits
[NotificationReference("Speech")] [NotificationReference("Speech")]
public readonly string WormAttackNotification = "WormAttack"; public readonly string WormAttackNotification = "WormAttack";
public readonly string WormAttackTextNotification = "Worm attack.";
public override object Create(ActorInitializer init) { return new AttackSwallow(init.Self, this); } public override object Create(ActorInitializer init) { return new AttackSwallow(init.Self, this); }
} }