Merge pull request #8710 from GraionDilach/victory-music

Implements victory and defeat music.
This commit is contained in:
Oliver Brakmann
2015-07-13 22:01:20 +02:00
21 changed files with 89 additions and 5 deletions

View File

@@ -352,6 +352,8 @@ namespace OpenRA.Traits
void OnObjectiveFailed(Player player, int objectiveID);
}
public interface IGameOver { void GameOver(World world); }
public interface IWarhead
{
int Delay { get; }

View File

@@ -17,14 +17,31 @@ namespace OpenRA.Traits
[Desc("Trait for music handling. Attach this to the world actor.")]
public class MusicPlaylistInfo : ITraitInfo
{
[Desc("Music to play when the map starts.", "Plays the first song on the playlist when undefined.")]
public readonly string StartingMusic = null;
[Desc("Should the starting music loop?")]
public readonly bool LoopStartingMusic = false;
[Desc("Music to play when the game has been won.")]
public readonly string VictoryMusic = null;
[Desc("Should the victory music loop?")]
public readonly bool LoopVictoryMusic = false;
[Desc("Music to play when the game has been lost.")]
public readonly string DefeatMusic = null;
[Desc("Should the defeat music loop?")]
public readonly bool LoopDefeatMusic = false;
public object Create(ActorInitializer init) { return new MusicPlaylist(init.World, this); }
}
public class MusicPlaylist : INotifyActorDisposing
public class MusicPlaylist : INotifyActorDisposing, IGameOver
{
readonly MusicPlaylistInfo info;
readonly MusicInfo[] random;
readonly MusicInfo[] playlist;
@@ -35,6 +52,8 @@ namespace OpenRA.Traits
public MusicPlaylist(World world, MusicPlaylistInfo info)
{
this.info = info;
IsMusicAvailable = world.Map.Rules.InstalledMusic.Any();
playlist = world.Map.Rules.InstalledMusic.Select(a => a.Value).ToArray();
@@ -71,6 +90,40 @@ namespace OpenRA.Traits
return playlist;
}
public void GameOver(World world)
{
if (!IsMusicAvailable)
return;
var playedSong = currentSong;
if (world.LocalPlayer.WinState == WinState.Won)
{
if (!string.IsNullOrEmpty(info.VictoryMusic)
&& world.Map.Rules.Music.ContainsKey(info.VictoryMusic)
&& world.Map.Rules.Music[info.VictoryMusic].Exists)
{
currentSong = world.Map.Rules.Music[info.VictoryMusic];
repeat = info.LoopVictoryMusic;
}
}
else
{
// Most RTS treats observers losing the game,
// no need for a special handling involving them here.
if (!string.IsNullOrEmpty(info.DefeatMusic)
&& world.Map.Rules.Music.ContainsKey(info.DefeatMusic)
&& world.Map.Rules.Music[info.DefeatMusic].Exists)
{
currentSong = world.Map.Rules.Music[info.DefeatMusic];
repeat = info.LoopDefeatMusic;
}
}
if (playedSong != currentSong)
Play();
}
void Play()
{
if (currentSong == null || !IsMusicAvailable)

View File

@@ -58,6 +58,10 @@ namespace OpenRA
if (!gameOver)
{
gameOver = true;
foreach (var t in WorldActor.TraitsImplementing<IGameOver>())
t.GameOver(this);
GameOver();
}
}