From 668e13b849e653d1ae3ca6d50e3c15802c99f250 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Tue, 1 Mar 2016 21:22:18 +0000 Subject: [PATCH] Move mission videos to rules. --- OpenRA.Game/Map/Map.cs | 24 ------------ OpenRA.Mods.Common/OpenRA.Mods.Common.csproj | 1 + .../Traits/World/MissionData.cs | 37 ++++++++++++++++++ .../UtilityCommands/ImportLegacyMapCommand.cs | 39 ++++++++++++++----- .../LoadIngamePlayerOrObserverUILogic.cs | 11 ++++-- .../Widgets/Logic/MissionBrowserLogic.cs | 34 ++++++++++------ 6 files changed, 97 insertions(+), 49 deletions(-) create mode 100644 OpenRA.Mods.Common/Traits/World/MissionData.cs diff --git a/OpenRA.Game/Map/Map.cs b/OpenRA.Game/Map/Map.cs index 3b1e217609..19fa1d1c78 100644 --- a/OpenRA.Game/Map/Map.cs +++ b/OpenRA.Game/Map/Map.cs @@ -56,15 +56,6 @@ namespace OpenRA } } - public class MapVideos - { - public string BackgroundInfo; - public string Briefing; - public string GameStart; - public string GameWon; - public string GameLost; - } - [Flags] public enum MapVisibility { @@ -109,18 +100,6 @@ namespace OpenRA return SubCellOffsets[(int)subCell]; } - [FieldLoader.LoadUsing("LoadVideos")] public MapVideos Videos; - - static object LoadVideos(MiniYaml y) - { - var videos = new MapVideos(); - var nodesDict = y.ToDictionary(); - if (nodesDict.ContainsKey("Videos")) - FieldLoader.Load(videos, nodesDict["Videos"]); - - return videos; - } - public static string ComputeUID(IReadOnlyPackage package) { // UID is calculated by taking an SHA1 of the yaml and binary data @@ -227,7 +206,6 @@ namespace OpenRA MapSize = new int2(size); Tileset = tileset.Id; - Videos = new MapVideos(); MapResources = Exts.Lazy(() => new CellLayer(Grid.Type, size)); @@ -468,9 +446,7 @@ namespace OpenRA root.Add(new MiniYamlNode(field, FieldSaver.FormatValue(this, f))); } - root.Add(new MiniYamlNode("Videos", FieldSaver.SaveDifferences(Videos, new MapVideos()))); root.Add(new MiniYamlNode("Players", null, PlayerDefinitions)); - root.Add(new MiniYamlNode("Actors", null, ActorDefinitions)); root.Add(new MiniYamlNode("Smudges", null, SmudgeDefinitions)); root.Add(new MiniYamlNode("Rules", null, RuleDefinitions)); diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index 48f6a2d047..915b947708 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -735,6 +735,7 @@ + diff --git a/OpenRA.Mods.Common/Traits/World/MissionData.cs b/OpenRA.Mods.Common/Traits/World/MissionData.cs new file mode 100644 index 0000000000..04817ce7b5 --- /dev/null +++ b/OpenRA.Mods.Common/Traits/World/MissionData.cs @@ -0,0 +1,37 @@ +#region Copyright & License Information +/* + * Copyright 2007-2016 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.Collections.Generic; +using OpenRA.Traits; + +namespace OpenRA.Mods.Common.Traits +{ + [Desc("Defines the FMVs that can be played by missions.")] + public class MissionDataInfo : TraitInfo + { + [Desc("Played by the \"Background Info\" button in the mission browser.")] + public readonly string BackgroundVideo; + + [Desc("Played by the \"Briefing\" button in the mission browser.")] + public readonly string BriefingVideo; + + [Desc("Automatically played before starting the mission.")] + public readonly string StartVideo; + + [Desc("Automatically played when the player wins the mission.")] + public readonly string WinVideo; + + [Desc("Automatically played when the player loses the mission.")] + public readonly string LossVideo; + } + + public class MissionData { } +} diff --git a/OpenRA.Mods.Common/UtilityCommands/ImportLegacyMapCommand.cs b/OpenRA.Mods.Common/UtilityCommands/ImportLegacyMapCommand.cs index 4ac7bb7dc0..2a1e18e287 100644 --- a/OpenRA.Mods.Common/UtilityCommands/ImportLegacyMapCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/ImportLegacyMapCommand.cs @@ -35,6 +35,7 @@ namespace OpenRA.Mods.Common.UtilityCommands public Map Map; public List Players = new List(); public MapPlayers MapPlayers; + public MiniYaml Rules = new MiniYaml(""); public bool ValidateArguments(string[] args) { @@ -75,7 +76,7 @@ namespace OpenRA.Mods.Common.UtilityCommands ReadPacks(file, filename); ReadTrees(file); - Map.Videos = LoadVideos(file, "BASIC"); + LoadVideos(file, "BASIC"); ReadActors(file); @@ -93,6 +94,8 @@ namespace OpenRA.Mods.Common.UtilityCommands Map.FixOpenAreas(); + Map.RuleDefinitions = Rules.Nodes; + var dest = Path.GetFileNameWithoutExtension(args[1]) + ".oramap"; var package = new ZipFile(modData.ModFiles, dest, true); Map.Save(package); @@ -144,10 +147,9 @@ namespace OpenRA.Mods.Common.UtilityCommands public abstract void ReadPacks(IniFile file, string filename); - static MapVideos LoadVideos(IniFile file, string section) + void LoadVideos(IniFile file, string section) { - var videos = new MapVideos(); - + var videos = new List(); foreach (var s in file.GetSection(section)) { if (s.Value != "x" && s.Value != "") @@ -155,25 +157,42 @@ namespace OpenRA.Mods.Common.UtilityCommands switch (s.Key) { case "Intro": - videos.BackgroundInfo = s.Value.ToLower() + ".vqa"; + videos.Add(new MiniYamlNode("BackgroundVideo", s.Value.ToLower() + ".vqa")); break; case "Brief": - videos.Briefing = s.Value.ToLower() + ".vqa"; + videos.Add(new MiniYamlNode("BriefingVideo", s.Value.ToLower() + ".vqa")); break; case "Action": - videos.GameStart = s.Value.ToLower() + ".vqa"; + videos.Add(new MiniYamlNode("StartVideo", s.Value.ToLower() + ".vqa")); break; case "Win": - videos.GameWon = s.Value.ToLower() + ".vqa"; + videos.Add(new MiniYamlNode("WinVideo", s.Value.ToLower() + ".vqa")); break; case "Lose": - videos.GameLost = s.Value.ToLower() + ".vqa"; + videos.Add(new MiniYamlNode("LossVideo", s.Value.ToLower() + ".vqa")); break; } } } - return videos; + if (videos.Any()) + { + var worldNode = Rules.Nodes.FirstOrDefault(n => n.Key == "World"); + if (worldNode == null) + { + worldNode = new MiniYamlNode("World", new MiniYaml("", new List())); + Rules.Nodes.Add(worldNode); + } + + var missionData = worldNode.Value.Nodes.FirstOrDefault(n => n.Key == "MissionData"); + if (missionData == null) + { + missionData = new MiniYamlNode("MissionData", new MiniYaml("", new List())); + worldNode.Value.Nodes.Add(missionData); + } + + missionData.Value.Nodes.AddRange(videos); + } } public virtual void ReadActors(IniFile file) diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/LoadIngamePlayerOrObserverUILogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/LoadIngamePlayerOrObserverUILogic.cs index 51be133f18..e51a32d3ff 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/LoadIngamePlayerOrObserverUILogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/LoadIngamePlayerOrObserverUILogic.cs @@ -63,10 +63,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (world.LocalPlayer != null) { var scriptContext = world.WorldActor.TraitOrDefault(); - var video = world.LocalPlayer.WinState == WinState.Won ? world.Map.Videos.GameWon : world.Map.Videos.GameLost; - - if (!string.IsNullOrEmpty(video) && !(scriptContext != null && scriptContext.FatalErrorOccurred)) - Media.PlayFMVFullscreen(world, video, () => { }); + var missionData = world.WorldActor.Info.TraitInfoOrDefault(); + if (missionData != null && !(scriptContext != null && scriptContext.FatalErrorOccurred)) + { + var video = world.LocalPlayer.WinState == WinState.Won ? missionData.WinVideo : missionData.LossVideo; + if (!string.IsNullOrEmpty(video)) + Media.PlayFMVFullscreen(world, video, () => { }); + } } var optionsButton = playerRoot.GetOrNull("OPTIONS_BUTTON"); diff --git a/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs index 8e201b70cb..c2d0bb9782 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/MissionBrowserLogic.cs @@ -181,6 +181,14 @@ namespace OpenRA.Mods.Common.Widgets.Logic var difficultyDisabled = true; var difficulties = new string[0]; + var briefingVideo = ""; + var briefingVideoVisible = false; + var briefingVideoDisabled = true; + + var infoVideo = ""; + var infoVideoVisible = false; + var infoVideoDisabled = true; + new Thread(() => { selectedMap.PreloadRules(); @@ -189,16 +197,20 @@ namespace OpenRA.Mods.Common.Widgets.Logic difficulty = mapOptions.Difficulty ?? mapOptions.Difficulties.FirstOrDefault(); difficulties = mapOptions.Difficulties; difficultyDisabled = mapOptions.DifficultyLocked || mapOptions.Difficulties.Length <= 1; + + var missionData = selectedMap.Rules.Actors["world"].TraitInfoOrDefault(); + if (missionData != null) + { + briefingVideo = missionData.BriefingVideo; + briefingVideoVisible = briefingVideo != null; + briefingVideoDisabled = !(briefingVideoVisible && modData.DefaultFileSystem.Exists(briefingVideo)); + + infoVideo = missionData.BackgroundVideo; + infoVideoVisible = infoVideo != null; + infoVideoDisabled = !(infoVideoVisible && modData.DefaultFileSystem.Exists(infoVideo)); + } }).Start(); - var briefingVideo = selectedMap.Videos.Briefing; - var briefingVideoVisible = briefingVideo != null; - var briefingVideoDisabled = !(briefingVideoVisible && modData.DefaultFileSystem.Exists(briefingVideo)); - - var infoVideo = selectedMap.Videos.BackgroundInfo; - var infoVideoVisible = infoVideo != null; - var infoVideoDisabled = !(infoVideoVisible && modData.DefaultFileSystem.Exists(infoVideo)); - startBriefingVideoButton.IsVisible = () => briefingVideoVisible && playingVideo != PlayingVideo.Briefing; startBriefingVideoButton.IsDisabled = () => briefingVideoDisabled || playingVideo != PlayingVideo.None; startBriefingVideoButton.OnClick = () => PlayVideo(videoPlayer, briefingVideo, PlayingVideo.Briefing, () => StopVideo(videoPlayer)); @@ -314,18 +326,18 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (selectedMap.InvalidCustomRules) return; - var gameStartVideo = selectedMap.Videos.GameStart; var orders = new[] { Order.Command("gamespeed {0}".F(gameSpeed)), Order.Command("difficulty {0}".F(difficulty)), Order.Command("state {0}".F(Session.ClientState.Ready)) }; - if (gameStartVideo != null && modData.DefaultFileSystem.Exists(gameStartVideo)) + var missionData = selectedMap.Rules.Actors["world"].TraitInfoOrDefault(); + if (missionData != null && missionData.StartVideo != null && modData.DefaultFileSystem.Exists(missionData.StartVideo)) { var fsPlayer = fullscreenVideoPlayer.Get("PLAYER"); fullscreenVideoPlayer.Visible = true; - PlayVideo(fsPlayer, gameStartVideo, PlayingVideo.GameStart, () => + PlayVideo(fsPlayer, missionData.StartVideo, PlayingVideo.GameStart, () => { StopVideo(fsPlayer); Game.CreateAndStartLocalServer(selectedMapPreview.Uid, orders, onStart);