Previously the StartGameNotification and MusicPlaylist traits used the IWorldLoaded interface to play an audio notification and begin music when the game started. However this interface is used by many traits to perform initial loading whilst the load screen was visible, and this loading can take time. Since the traits could run in any order, then audio notification might fire before another trait with a long loading time. This is not ideal as we want the time between the audio notification occurring and the player being able to interact to be as short and reliable as possible. Now, we introduce a new IPostWorldLoaded which runs after all other loading activity, and we switch StartGameNotification and MusicPlaylist to use it. This allows timing sensitive traits that want to run right at the end of loading to fire reliably and with minimal delay. The player perception of hearing the notification and being able to interact is now much snappier.
77 lines
2.4 KiB
C#
77 lines
2.4 KiB
C#
#region Copyright & License Information
|
|
/*
|
|
* Copyright (c) The OpenRA Developers and Contributors
|
|
* 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 OpenRA.Graphics;
|
|
using OpenRA.Traits;
|
|
|
|
namespace OpenRA.Mods.Common.Traits
|
|
{
|
|
[TraitLocation(SystemActors.World)]
|
|
sealed class StartGameNotificationInfo : TraitInfo
|
|
{
|
|
[NotificationReference("Speech")]
|
|
public readonly string Notification = "StartGame";
|
|
|
|
[TranslationReference(optional: true)]
|
|
public readonly string TextNotification = null;
|
|
|
|
[NotificationReference("Speech")]
|
|
public readonly string LoadedNotification = "GameLoaded";
|
|
|
|
[TranslationReference(optional: true)]
|
|
public readonly string LoadedTextNotification = null;
|
|
|
|
[NotificationReference("Speech")]
|
|
public readonly string SavedNotification = "GameSaved";
|
|
|
|
[TranslationReference(optional: true)]
|
|
public readonly string SavedTextNotification = null;
|
|
|
|
public override object Create(ActorInitializer init) { return new StartGameNotification(this); }
|
|
}
|
|
|
|
sealed class StartGameNotification : IPostWorldLoaded, INotifyGameLoaded, INotifyGameSaved
|
|
{
|
|
readonly StartGameNotificationInfo info;
|
|
public StartGameNotification(StartGameNotificationInfo info)
|
|
{
|
|
this.info = info;
|
|
}
|
|
|
|
void IPostWorldLoaded.PostWorldLoaded(World world, WorldRenderer wr)
|
|
{
|
|
if (!world.IsLoadingGameSave)
|
|
{
|
|
Game.Sound.PlayNotification(world.Map.Rules, null, "Speech", info.Notification, world.RenderPlayer?.Faction.InternalName);
|
|
TextNotificationsManager.AddTransientLine(null, info.TextNotification);
|
|
}
|
|
}
|
|
|
|
void INotifyGameLoaded.GameLoaded(World world)
|
|
{
|
|
if (!world.IsReplay)
|
|
{
|
|
Game.Sound.PlayNotification(world.Map.Rules, null, "Speech", info.LoadedNotification, world.RenderPlayer?.Faction.InternalName);
|
|
TextNotificationsManager.AddTransientLine(null, info.LoadedTextNotification);
|
|
}
|
|
}
|
|
|
|
void INotifyGameSaved.GameSaved(World world)
|
|
{
|
|
if (!world.IsReplay)
|
|
{
|
|
Game.Sound.PlayNotification(world.Map.Rules, null, "Speech", info.SavedNotification, world.RenderPlayer?.Faction.InternalName);
|
|
TextNotificationsManager.AddTransientLine(null, info.SavedTextNotification);
|
|
}
|
|
}
|
|
}
|
|
}
|