diff --git a/OpenRA.Game/ContentInstaller.cs b/OpenRA.Game/ContentInstaller.cs deleted file mode 100644 index 1d4c388939..0000000000 --- a/OpenRA.Game/ContentInstaller.cs +++ /dev/null @@ -1,41 +0,0 @@ -#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; - -namespace OpenRA -{ - // Referenced from ModMetadata, so needs to be in OpenRA.Game :( - public class ContentInstaller : IGlobalModData - { - public enum FilenameCase { Input, ForceLower, ForceUpper } - - public readonly string[] TestFiles = { }; - public readonly string[] DiskTestFiles = { }; - public readonly string PackageToExtractFromCD = null; - public readonly bool OverwriteFiles = true; - - public readonly FilenameCase OutputFilenameCase = FilenameCase.ForceLower; - public readonly Dictionary CopyFilesFromCD = new Dictionary(); - public readonly Dictionary ExtractFilesFromCD = new Dictionary(); - - public readonly string PackageMirrorList = null; - - public readonly string MusicPackageMirrorList = null; - public readonly int ShippedSoundtracks = 0; - - /// InstallShield .CAB file IDs, used to extract Mod-specific files. - public readonly HashSet InstallShieldCABFileIds = new HashSet(); - - /// InstallShield .CAB file IDs, used to extract Mod-specific archives and extract contents of ExtractFilesFromCD. - public readonly HashSet InstallShieldCABFilePackageIds = new HashSet(); - } -} diff --git a/OpenRA.Game/FileSystem/InstallShieldPackage.cs b/OpenRA.Game/FileSystem/InstallShieldPackage.cs index a479f7ae40..5089edd74b 100644 --- a/OpenRA.Game/FileSystem/InstallShieldPackage.cs +++ b/OpenRA.Game/FileSystem/InstallShieldPackage.cs @@ -18,7 +18,7 @@ namespace OpenRA.FileSystem { public sealed class InstallShieldPackage : IReadOnlyPackage { - struct Entry + public struct Entry { public readonly uint Offset; public readonly uint Length; @@ -124,6 +124,8 @@ namespace OpenRA.FileSystem return index.ContainsKey(filename); } + public IReadOnlyDictionary Index { get { return new ReadOnlyDictionary(index); } } + public void Dispose() { s.Dispose(); diff --git a/OpenRA.Game/FileSystem/MixFile.cs b/OpenRA.Game/FileSystem/MixFile.cs index fee7538b2e..7a36fb7e15 100644 --- a/OpenRA.Game/FileSystem/MixFile.cs +++ b/OpenRA.Game/FileSystem/MixFile.cs @@ -205,6 +205,15 @@ namespace OpenRA.FileSystem return GetContent(e); } + public IReadOnlyDictionary Index + { + get + { + var absoluteIndex = index.ToDictionary(e => e.Key, e => new PackageEntry(e.Value.Hash, (uint)(e.Value.Offset + dataStart), e.Value.Length)); + return new ReadOnlyDictionary(absoluteIndex); + } + } + public bool Contains(string filename) { return index.ContainsKey(filename); diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs index 0e669f5c74..ea17fed72d 100644 --- a/OpenRA.Game/Game.cs +++ b/OpenRA.Game/Game.cs @@ -344,8 +344,10 @@ namespace OpenRA using (new PerfTimer("LoadMaps")) ModData.MapCache.LoadMaps(); - var installData = ModData.Manifest.Get(); - var isModContentInstalled = installData.TestFiles.All(f => File.Exists(Platform.ResolvePath(f))); + var content = ModData.Manifest.Get(); + var isModContentInstalled = content.Packages + .Where(p => p.Value.Required) + .All(p => p.Value.TestFiles.All(f => File.Exists(Platform.ResolvePath(f)))); // Mod assets are missing! if (!isModContentInstalled) diff --git a/OpenRA.Game/ModContent.cs b/OpenRA.Game/ModContent.cs new file mode 100644 index 0000000000..acb8f65d5d --- /dev/null +++ b/OpenRA.Game/ModContent.cs @@ -0,0 +1,118 @@ +#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 System.IO; +using System.Linq; + +namespace OpenRA +{ + public class ModContent : IGlobalModData + { + public class ModPackage + { + public readonly string Title; + public readonly string[] TestFiles = { }; + public readonly string[] Discs = { }; + public readonly bool Required; + public readonly string Download; + + public ModPackage(MiniYaml yaml) + { + Title = yaml.Value; + FieldLoader.Load(this, yaml); + } + + public bool IsInstalled() + { + return TestFiles.All(file => File.Exists(Path.GetFullPath(Platform.ResolvePath(file)))); + } + } + + public class ModDisc + { + public readonly string Title; + public readonly Dictionary IDFiles; + + [FieldLoader.Ignore] public readonly List Install; + + public ModDisc(MiniYaml yaml) + { + Title = yaml.Value; + var installNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Install"); + if (installNode != null) + Install = installNode.Value.Nodes; + + FieldLoader.Load(this, yaml); + } + } + + public class ModDownload + { + public readonly string Title; + public readonly string URL; + public readonly string MirrorList; + public readonly Dictionary Extract; + + public ModDownload(MiniYaml yaml) + { + Title = yaml.Value; + FieldLoader.Load(this, yaml); + } + } + + public readonly string InstallPromptMessage; + public readonly string QuickDownload; + public readonly string HeaderMessage; + + [FieldLoader.LoadUsing("LoadPackages")] + public readonly Dictionary Packages = new Dictionary(); + + static object LoadPackages(MiniYaml yaml) + { + var packages = new Dictionary(); + var packageNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Packages"); + if (packageNode != null) + foreach (var node in packageNode.Value.Nodes) + packages.Add(node.Key, new ModPackage(node.Value)); + + return packages; + } + + [FieldLoader.LoadUsing("LoadDownloads")] + public readonly Dictionary Downloads; + + static object LoadDownloads(MiniYaml yaml) + { + var downloads = new Dictionary(); + var downloadNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Downloads"); + if (downloadNode != null) + foreach (var node in downloadNode.Value.Nodes) + downloads.Add(node.Key, new ModDownload(node.Value)); + + return downloads; + } + + [FieldLoader.LoadUsing("LoadDiscs")] + public readonly Dictionary Discs; + + static object LoadDiscs(MiniYaml yaml) + { + var discs = new Dictionary(); + var discNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Discs"); + if (discNode != null) + foreach (var node in discNode.Value.Nodes) + discs.Add(node.Key, new ModDisc(node.Value)); + + return discs; + } + } +} diff --git a/OpenRA.Game/ModMetadata.cs b/OpenRA.Game/ModMetadata.cs index f0f271e098..a85728d426 100644 --- a/OpenRA.Game/ModMetadata.cs +++ b/OpenRA.Game/ModMetadata.cs @@ -30,7 +30,7 @@ namespace OpenRA public bool Hidden; public Dictionary RequiresMods; - public ContentInstaller Content; + public ModContent ModContent; public IReadOnlyPackage Package; static Dictionary ValidateMods() @@ -78,8 +78,8 @@ namespace OpenRA else metadata.RequiresMods = new Dictionary(); - if (nd.ContainsKey("ContentInstaller")) - metadata.Content = FieldLoader.Load(nd["ContentInstaller"]); + if (nd.ContainsKey("ModContent")) + metadata.ModContent = FieldLoader.Load(nd["ModContent"]); // Mods in the support directory and oramod packages (which are listed later // in the CandidateMods list) override mods in the main install. diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj index ae3b220ae1..060a15d2ab 100644 --- a/OpenRA.Game/OpenRA.Game.csproj +++ b/OpenRA.Game/OpenRA.Game.csproj @@ -103,7 +103,6 @@ - @@ -249,6 +248,7 @@ + diff --git a/OpenRA.Game/Widgets/Widget.cs b/OpenRA.Game/Widgets/Widget.cs index 0c58992546..f6dc0a8e2a 100644 --- a/OpenRA.Game/Widgets/Widget.cs +++ b/OpenRA.Game/Widgets/Widget.cs @@ -33,9 +33,23 @@ namespace OpenRA.Widgets public static void CloseWindow() { if (WindowList.Count > 0) - Root.RemoveChild(WindowList.Pop()); + { + var hidden = WindowList.Pop(); + Root.RemoveChild(hidden); + if (hidden.LogicObjects != null) + foreach (var l in hidden.LogicObjects) + l.BecameHidden(); + } + if (WindowList.Count > 0) - Root.AddChild(WindowList.Peek()); + { + var restore = WindowList.Peek(); + Root.AddChild(restore); + + if (restore.LogicObjects != null) + foreach (var l in restore.LogicObjects) + l.BecameVisible(); + } } public static Widget OpenWindow(string id) @@ -148,6 +162,8 @@ namespace OpenRA.Widgets { public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } public virtual void Tick() { } + public virtual void BecameHidden() { } + public virtual void BecameVisible() { } protected virtual void Dispose(bool disposing) { } } diff --git a/OpenRA.Mods.Common/FileFormats/MSCabCompression.cs b/OpenRA.Mods.Common/FileFormats/MSCabCompression.cs new file mode 100644 index 0000000000..998b8e9992 --- /dev/null +++ b/OpenRA.Mods.Common/FileFormats/MSCabCompression.cs @@ -0,0 +1,131 @@ +#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; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using ICSharpCode.SharpZipLib.Zip.Compression; +using ICSharpCode.SharpZipLib.Zip.Compression.Streams; + +namespace OpenRA.Mods.Common.FileFormats +{ + public sealed class MSCabCompression + { + class CabFolder + { + public readonly uint BlockOffset; + public readonly ushort BlockCount; + public readonly ushort CompressionType; + + public CabFolder(Stream stream) + { + BlockOffset = stream.ReadUInt32(); + BlockCount = stream.ReadUInt16(); + CompressionType = stream.ReadUInt16(); + } + } + + class CabFile + { + public readonly string FileName; + public readonly uint DecompressedLength; + public readonly uint DecompressedOffset; + public readonly ushort FolderIndex; + + public CabFile(Stream stream) + { + DecompressedLength = stream.ReadUInt32(); + DecompressedOffset = stream.ReadUInt32(); + FolderIndex = stream.ReadUInt16(); + stream.Position += 6; + FileName = stream.ReadASCIIZ(); + } + } + + readonly CabFolder[] folders; + readonly CabFile[] files; + readonly Stream stream; + + public MSCabCompression(Stream stream) + { + this.stream = stream; + + var signature = stream.ReadASCII(4); + if (signature != "MSCF") + throw new InvalidDataException("Not a Microsoft CAB package!"); + + stream.Position += 12; + var filesOffset = stream.ReadUInt32(); + stream.Position += 6; + var folderCount = stream.ReadUInt16(); + var fileCount = stream.ReadUInt16(); + if (stream.ReadUInt16() != 0) + throw new InvalidDataException("Only plain packages (without reserved header space or prev/next archives) are supported!"); + + stream.Position += 4; + + folders = new CabFolder[folderCount]; + for (var i = 0; i < folderCount; i++) + { + folders[i] = new CabFolder(stream); + if (folders[i].CompressionType != 1) + throw new InvalidDataException("Compression type is not supported"); + } + + files = new CabFile[fileCount]; + stream.Seek(filesOffset, SeekOrigin.Begin); + for (var i = 0; i < fileCount; i++) + files[i] = new CabFile(stream); + } + + public byte[] ExtractFile(string filename, Action onProgress = null) + { + var file = files.FirstOrDefault(f => f.FileName == filename); + if (file == null) + return null; + + var folder = folders[file.FolderIndex]; + stream.Seek(folder.BlockOffset, SeekOrigin.Begin); + + using (var outputStream = new MemoryStream()) + { + var inflater = new Inflater(true); + var buffer = new byte[4096]; + for (var i = 0; i < folder.BlockCount; i++) + { + if (onProgress != null) + onProgress((int)(100 * outputStream.Position / file.DecompressedLength)); + + // Ignore checksums + stream.Position += 4; + var blockLength = stream.ReadUInt16(); + stream.Position += 4; + + using (var batch = new MemoryStream(stream.ReadBytes(blockLength - 2))) + using (var inflaterStream = new InflaterInputStream(batch, inflater)) + { + int n; + while ((n = inflaterStream.Read(buffer, 0, buffer.Length)) > 0) + outputStream.Write(buffer, 0, n); + } + + inflater.Reset(); + } + + outputStream.Seek(file.DecompressedOffset, SeekOrigin.Begin); + return outputStream.ReadBytes((int)file.DecompressedLength); + } + } + + public IEnumerable Contents { get { return files.Select(f => f.FileName); } } + } +} diff --git a/OpenRA.Mods.Common/InstallUtils.cs b/OpenRA.Mods.Common/InstallUtils.cs deleted file mode 100644 index 8486133cb4..0000000000 --- a/OpenRA.Mods.Common/InstallUtils.cs +++ /dev/null @@ -1,189 +0,0 @@ -#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; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using ICSharpCode.SharpZipLib; -using ICSharpCode.SharpZipLib.Zip; -using OpenRA.FileSystem; - -namespace OpenRA.Mods.Common -{ - public static class InstallUtils - { - static IEnumerable GetEntries(this ZipInputStream z) - { - for (;;) - { - var e = z.GetNextEntry(); - if (e != null) yield return e; else break; - } - } - - public static string GetMountedDisk(Func isValidDisk) - { - var volumes = DriveInfo.GetDrives() - .Where(v => v.DriveType == DriveType.CDRom && v.IsReady) - .Select(v => v.RootDirectory.FullName); - - return volumes.FirstOrDefault(isValidDisk); - } - - static string GetFileName(string path, ContentInstaller.FilenameCase caseModifier) - { - // Gets the file path, splitting on both / and \ - var index = path.LastIndexOfAny(new[] { '\\', '/' }); - var output = path.Substring(index + 1); - - switch (caseModifier) - { - case ContentInstaller.FilenameCase.ForceLower: - return output.ToLowerInvariant(); - case ContentInstaller.FilenameCase.ForceUpper: - return output.ToUpperInvariant(); - default: - return output; - } - } - - // TODO: The package should be mounted into its own context to avoid name collisions with installed files - public static bool ExtractFromPackage(FileSystem.FileSystem fileSystem, string srcPath, string package, Dictionary filesByDirectory, - string destPath, bool overwrite, ContentInstaller.FilenameCase caseModifier, Action onProgress, Action onError) - { - Directory.CreateDirectory(destPath); - - Log.Write("debug", "Mounting {0}".F(srcPath)); - fileSystem.Mount(srcPath); - Log.Write("debug", "Mounting {0}".F(package)); - fileSystem.Mount(package); - - foreach (var directory in filesByDirectory) - { - var targetDir = directory.Key; - - foreach (var file in directory.Value) - { - var containingDir = Path.Combine(destPath, targetDir); - var dest = Path.Combine(containingDir, GetFileName(file, caseModifier)); - if (File.Exists(dest)) - { - if (overwrite) - File.Delete(dest); - else - { - Log.Write("debug", "Skipping {0}".F(dest)); - continue; - } - } - - Directory.CreateDirectory(containingDir); - - using (var sourceStream = fileSystem.Open(file)) - using (var destStream = File.Create(dest)) - { - Log.Write("debug", "Extracting {0} to {1}".F(file, dest)); - onProgress("Extracting " + file); - destStream.Write(sourceStream.ReadAllBytes()); - } - } - } - - return true; - } - - public static bool CopyFiles(string srcPath, Dictionary files, string destPath, - bool overwrite, ContentInstaller.FilenameCase caseModifier, Action onProgress, Action onError) - { - Directory.CreateDirectory(destPath); - - foreach (var folder in files) - { - var targetDir = folder.Key; - - foreach (var file in folder.Value) - { - var sourcePath = Path.Combine(srcPath, file); - if (!File.Exists(sourcePath)) - { - onError("Cannot find " + file); - return false; - } - - var destFile = GetFileName(file, caseModifier); - var containingDir = Path.Combine(destPath, targetDir); - var dest = Path.Combine(containingDir, destFile); - if (File.Exists(dest) && !overwrite) - { - Log.Write("debug", "Skipping {0}".F(dest)); - continue; - } - - Directory.CreateDirectory(containingDir); - - onProgress("Copying " + destFile); - Log.Write("debug", "Copy {0} to {1}".F(sourcePath, dest)); - File.Copy(sourcePath, dest, true); - } - } - - return true; - } - - public static bool ExtractZip(string zipFile, string dest, Action onProgress, Action onError) - { - if (!File.Exists(zipFile)) - { - onError("Invalid path: " + zipFile); - return false; - } - - var extracted = new List(); - try - { - using (var stream = File.OpenRead(zipFile)) - using (var z = new ZipInputStream(stream)) - z.ExtractZip(dest, extracted, s => onProgress("Extracting " + s)); - } - catch (SharpZipBaseException) - { - foreach (var f in extracted) - File.Delete(f); - - onError("Invalid archive"); - return false; - } - - return true; - } - - // TODO: this belongs in FileSystem/ZipFile - static void ExtractZip(this ZipInputStream z, string destPath, List extracted, Action onProgress) - { - foreach (var entry in z.GetEntries()) - { - if (!entry.IsFile) continue; - - onProgress(entry.Name); - - Directory.CreateDirectory(Path.Combine(destPath, Path.GetDirectoryName(entry.Name))); - var path = Path.Combine(destPath, entry.Name); - extracted.Add(path); - - using (var f = File.Create(path)) - z.CopyTo(f); - } - - z.Close(); - } - } -} diff --git a/OpenRA.Mods.Common/LoadScreens/ModChooserLoadScreen.cs b/OpenRA.Mods.Common/LoadScreens/ModChooserLoadScreen.cs index 4ac0df895e..99c24ee948 100644 --- a/OpenRA.Mods.Common/LoadScreens/ModChooserLoadScreen.cs +++ b/OpenRA.Mods.Common/LoadScreens/ModChooserLoadScreen.cs @@ -50,14 +50,7 @@ namespace OpenRA.Mods.Common.LoadScreens var widgetArgs = new WidgetArgs(); Ui.LoadWidget("MODCHOOSER_BACKGROUND", Ui.Root, widgetArgs); - - if (args != null && args.Contains("installMusic")) - { - widgetArgs.Add("modId", args.GetValue("installMusic", "")); - Ui.OpenWindow("INSTALL_MUSIC_PANEL", widgetArgs); - } - else - Ui.OpenWindow("MODCHOOSER_DIALOG", widgetArgs); + Ui.OpenWindow("MODCHOOSER_DIALOG", widgetArgs); } public void Dispose() diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index 867149f46c..b101e1b150 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -610,11 +610,7 @@ - - - - @@ -662,7 +658,6 @@ - @@ -751,6 +746,15 @@ + + + + + + + + + diff --git a/OpenRA.Mods.Common/Traits/World/MusicPlaylist.cs b/OpenRA.Mods.Common/Traits/World/MusicPlaylist.cs index ab6122f3a8..3510b733b8 100644 --- a/OpenRA.Mods.Common/Traits/World/MusicPlaylist.cs +++ b/OpenRA.Mods.Common/Traits/World/MusicPlaylist.cs @@ -74,10 +74,8 @@ namespace OpenRA.Mods.Common.Traits } else { - // Start playback with a random song, but only if the player has installed more music - var installData = Game.ModData.Manifest.Get(); - if (playlist.Length > installData.ShippedSoundtracks) - currentSong = random.FirstOrDefault(); + // Start playback with a random song + currentSong = random.FirstOrDefault(); } if (SongExists(info.StartingMusic)) diff --git a/OpenRA.Mods.Common/UtilityCommands/ListInstallShieldContentsCommand.cs b/OpenRA.Mods.Common/UtilityCommands/ListInstallShieldContentsCommand.cs new file mode 100644 index 0000000000..52678b81aa --- /dev/null +++ b/OpenRA.Mods.Common/UtilityCommands/ListInstallShieldContentsCommand.cs @@ -0,0 +1,46 @@ +#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; +using System.IO; +using System.Linq; +using OpenRA.FileSystem; + +namespace OpenRA.Mods.Common.UtilityCommands +{ + class ListInstallShieldContents : IUtilityCommand + { + public string Name { get { return "--list-installshield"; } } + + public bool ValidateArguments(string[] args) + { + return args.Length == 2; + } + + [Desc("ARCHIVE.Z", "Lists the content ranges for a InstallShield V3 file")] + public void Run(ModData modData, string[] args) + { + var filename = Path.GetFileName(args[1]); + var path = Path.GetDirectoryName(args[1]); + + var fs = new OpenRA.FileSystem.FileSystem(); + fs.Mount(path, "parent"); + var package = new InstallShieldPackage(fs, "parent|" + filename); + + foreach (var kv in package.Index) + { + Console.WriteLine("{0}:", kv.Key); + Console.WriteLine("\tOffset: {0}", 255 + kv.Value.Offset); + Console.WriteLine("\tLength: {0}", kv.Value.Length); + } + } + } +} diff --git a/OpenRA.Mods.Common/UtilityCommands/ListMSCabContentsCommand.cs b/OpenRA.Mods.Common/UtilityCommands/ListMSCabContentsCommand.cs new file mode 100644 index 0000000000..c5d90d7a7f --- /dev/null +++ b/OpenRA.Mods.Common/UtilityCommands/ListMSCabContentsCommand.cs @@ -0,0 +1,35 @@ +#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; +using System.IO; +using OpenRA.Mods.Common.FileFormats; + +namespace OpenRA.Mods.Common.UtilityCommands +{ + class ListMSCabContentsCommand : IUtilityCommand + { + public string Name { get { return "--list-mscab"; } } + + public bool ValidateArguments(string[] args) + { + return args.Length == 2; + } + + [Desc("ARCHIVE.CAB", "Lists the filenames contained within a MSCAB file")] + public void Run(ModData modData, string[] args) + { + var package = new MSCabCompression(File.OpenRead(args[1])); + foreach (var file in package.Contents) + Console.WriteLine("{0}", file); + } + } +} diff --git a/OpenRA.Mods.Common/UtilityCommands/ListMixContentsCommand.cs b/OpenRA.Mods.Common/UtilityCommands/ListMixContentsCommand.cs new file mode 100644 index 0000000000..39063b5605 --- /dev/null +++ b/OpenRA.Mods.Common/UtilityCommands/ListMixContentsCommand.cs @@ -0,0 +1,50 @@ +#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; +using System.IO; +using System.Linq; +using OpenRA.FileSystem; + +namespace OpenRA.Mods.Common.UtilityCommands +{ + class ListMixContents : IUtilityCommand + { + public string Name { get { return "--list-mix"; } } + + public bool ValidateArguments(string[] args) + { + return args.Length == 2; + } + + [Desc("ARCHIVE.Z", "Lists the content ranges for a mix file")] + public void Run(ModData modData, string[] args) + { + var filename = Path.GetFileName(args[1]); + var path = Path.GetDirectoryName(args[1]); + + var fs = new OpenRA.FileSystem.FileSystem(); + + // Needed to access the global mix database + fs.LoadFromManifest(modData.Manifest); + + fs.Mount(path, "parent"); + var package = new MixFile(fs, "parent|" + filename); + + foreach (var kv in package.Index.OrderBy(kv => kv.Value.Offset)) + { + Console.WriteLine("{0}:", kv.Key); + Console.WriteLine("\tOffset: {0}", kv.Value.Offset); + Console.WriteLine("\tLength: {0}", kv.Value.Length); + } + } + } +} diff --git a/OpenRA.Mods.Common/Widgets/ImageWidget.cs b/OpenRA.Mods.Common/Widgets/ImageWidget.cs index ace095e384..2838ee6055 100644 --- a/OpenRA.Mods.Common/Widgets/ImageWidget.cs +++ b/OpenRA.Mods.Common/Widgets/ImageWidget.cs @@ -17,16 +17,27 @@ namespace OpenRA.Mods.Common.Widgets { public class ImageWidget : Widget { + public readonly string TooltipTemplate; + public readonly string TooltipContainer; + public string ImageCollection = ""; public string ImageName = ""; public bool ClickThrough = true; public Func GetImageName; public Func GetImageCollection; + [Translate] public string TooltipText; + + Lazy tooltipContainer; + public Func GetTooltipText; + public ImageWidget() { GetImageName = () => ImageName; GetImageCollection = () => ImageCollection; + GetTooltipText = () => TooltipText; + tooltipContainer = Exts.Lazy(() => + Ui.Root.Get(TooltipContainer)); } protected ImageWidget(ImageWidget other) @@ -37,6 +48,12 @@ namespace OpenRA.Mods.Common.Widgets GetImageName = other.GetImageName; ImageCollection = other.ImageCollection; GetImageCollection = other.GetImageCollection; + + TooltipTemplate = other.TooltipTemplate; + TooltipContainer = other.TooltipContainer; + GetTooltipText = other.GetTooltipText; + tooltipContainer = Exts.Lazy(() => + Ui.Root.Get(TooltipContainer)); } public override Widget Clone() { return new ImageWidget(this); } @@ -57,5 +74,21 @@ namespace OpenRA.Mods.Common.Widgets { return !ClickThrough && RenderBounds.Contains(mi.Location); } + + public override void MouseEntered() + { + if (TooltipContainer == null || GetTooltipText == null) + return; + + tooltipContainer.Value.SetTooltip(TooltipTemplate, new WidgetArgs() { { "getText", GetTooltipText } }); + } + + public override void MouseExited() + { + if (TooltipContainer == null) + return; + + tooltipContainer.Value.RemoveTooltip(); + } } } diff --git a/OpenRA.Mods.Common/Widgets/Logic/Installation/DownloadPackageLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Installation/DownloadPackageLogic.cs new file mode 100644 index 0000000000..4ec8588251 --- /dev/null +++ b/OpenRA.Mods.Common/Widgets/Logic/Installation/DownloadPackageLogic.cs @@ -0,0 +1,234 @@ +#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; +using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using System.Net; +using System.Text; +using ICSharpCode.SharpZipLib; +using ICSharpCode.SharpZipLib.Zip; +using OpenRA.Support; +using OpenRA.Widgets; + +namespace OpenRA.Mods.Common.Widgets.Logic +{ + public class DownloadPackageLogic : ChromeLogic + { + static readonly string[] SizeSuffixes = { "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" }; + readonly ModContent.ModDownload download; + readonly Action onSuccess; + + readonly Widget panel; + readonly ProgressBarWidget progressBar; + + Func getStatusText = () => ""; + string downloadHost; + + [ObjectCreator.UseCtor] + public DownloadPackageLogic(Widget widget, ModContent.ModDownload download, Action onSuccess) + { + this.download = download; + this.onSuccess = onSuccess; + + Log.AddChannel("install", "install.log"); + + panel = widget.Get("PACKAGE_DOWNLOAD_PANEL"); + progressBar = panel.Get("PROGRESS_BAR"); + + var statusLabel = panel.Get("STATUS_LABEL"); + var statusFont = Game.Renderer.Fonts[statusLabel.Font]; + var status = new CachedTransform(s => WidgetUtils.TruncateText(s, statusLabel.Bounds.Width, statusFont)); + statusLabel.GetText = () => status.Update(getStatusText()); + + var text = "Downloading {0}".F(download.Title); + panel.Get("TITLE").Text = text; + + ShowDownloadDialog(); + } + + void ShowDownloadDialog() + { + getStatusText = () => "Fetching list of mirrors..."; + progressBar.Indeterminate = true; + + var retryButton = panel.Get("RETRY_BUTTON"); + retryButton.IsVisible = () => false; + + var cancelButton = panel.Get("CANCEL_BUTTON"); + + var file = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + + Action deleteTempFile = () => + { + Log.Write("install", "Deleting temporary file " + file); + File.Delete(file); + }; + + Action onDownloadProgress = i => + { + var dataReceived = 0.0f; + var dataTotal = 0.0f; + var mag = 0; + var dataSuffix = ""; + + if (i.TotalBytesToReceive < 0) + { + dataTotal = float.NaN; + dataReceived = i.BytesReceived; + dataSuffix = SizeSuffixes[0]; + } + else + { + mag = (int)Math.Log(i.TotalBytesToReceive, 1024); + dataTotal = i.TotalBytesToReceive / (float)(1L << (mag * 10)); + dataReceived = i.BytesReceived / (float)(1L << (mag * 10)); + dataSuffix = SizeSuffixes[mag]; + } + + progressBar.Indeterminate = false; + progressBar.Percentage = i.ProgressPercentage; + + getStatusText = () => "Downloading from {4} {1:0.00}/{2:0.00} {3} ({0}%)".F(i.ProgressPercentage, + dataReceived, dataTotal, dataSuffix, + downloadHost ?? "unknown host"); + }; + + Action onExtractProgress = s => Game.RunAfterTick(() => getStatusText = () => s); + + Action onError = s => Game.RunAfterTick(() => + { + Log.Write("install", "Download failed: " + s); + + progressBar.Indeterminate = false; + progressBar.Percentage = 100; + getStatusText = () => "Error: " + s; + retryButton.IsVisible = () => true; + }); + + Action onDownloadComplete = (i, cancelled) => + { + if (i.Error != null) + { + onError(Download.FormatErrorMessage(i.Error)); + return; + } + + if (cancelled) + { + onError("Download cancelled"); + return; + } + + // Automatically extract + getStatusText = () => "Extracting..."; + progressBar.Indeterminate = true; + + var extracted = new List(); + try + { + using (var stream = File.OpenRead(file)) + using (var z = new ZipFile(stream)) + { + foreach (var kv in download.Extract) + { + var entry = z.GetEntry(kv.Value); + if (!entry.IsFile) + continue; + + onExtractProgress("Extracting " + entry.Name); + Log.Write("install", "Extracting " + entry.Name); + var targetPath = Platform.ResolvePath(kv.Key); + Directory.CreateDirectory(Path.GetDirectoryName(targetPath)); + extracted.Add(targetPath); + + using (var zz = z.GetInputStream(entry)) + using (var f = File.Create(targetPath)) + zz.CopyTo(f); + } + + z.Close(); + } + + Game.RunAfterTick(() => { Ui.CloseWindow(); onSuccess(); }); + } + catch (Exception) + { + Log.Write("install", "Extraction failed"); + + foreach (var f in extracted) + { + Log.Write("install", "Deleting " + f); + File.Delete(f); + } + + onError("Invalid archive"); + } + finally + { + deleteTempFile(); + } + }; + + Action downloadUrl = url => + { + Log.Write("install", "Downloading " + url); + + downloadHost = new Uri(url).Host; + var dl = new Download(url, file, onDownloadProgress, onDownloadComplete); + cancelButton.OnClick = () => { dl.Cancel(); deleteTempFile(); Ui.CloseWindow(); }; + retryButton.OnClick = () => { dl.Cancel(); ShowDownloadDialog(); }; + }; + + if (download.MirrorList != null) + { + Log.Write("install", "Fetching mirrors from " + download.MirrorList); + + Action onFetchMirrorsComplete = (i, cancelled) => + { + progressBar.Indeterminate = true; + + if (i.Error != null) + { + onError(Download.FormatErrorMessage(i.Error)); + return; + } + + if (cancelled) + { + onError("Download cancelled"); + return; + } + + try + { + var data = Encoding.UTF8.GetString(i.Result); + var mirrorList = data.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries); + downloadUrl(mirrorList.Random(new MersenneTwister())); + } + catch (Exception e) + { + Log.Write("install", "Mirror selection failed with error:"); + Log.Write("install", e.ToString()); + onError("Online mirror is not available. Please install from an original disc."); + } + }; + + var updateMirrors = new Download(download.MirrorList, onDownloadProgress, onFetchMirrorsComplete); + cancelButton.OnClick = () => { updateMirrors.Cancel(); Ui.CloseWindow(); }; + retryButton.OnClick = () => { updateMirrors.Cancel(); ShowDownloadDialog(); }; + } + else + downloadUrl(download.URL); + } + } +} diff --git a/OpenRA.Mods.Common/Widgets/Logic/Installation/DownloadPackagesLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Installation/DownloadPackagesLogic.cs deleted file mode 100644 index 0101ddb27c..0000000000 --- a/OpenRA.Mods.Common/Widgets/Logic/Installation/DownloadPackagesLogic.cs +++ /dev/null @@ -1,159 +0,0 @@ -#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; -using System.ComponentModel; -using System.IO; -using System.Net; -using System.Text; -using OpenRA.Support; -using OpenRA.Widgets; - -namespace OpenRA.Mods.Common.Widgets.Logic -{ - public class DownloadPackagesLogic : ChromeLogic - { - static readonly string[] SizeSuffixes = { "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" }; - readonly Widget panel; - readonly string modId; - readonly string mirrorListUrl; - readonly ProgressBarWidget progressBar; - readonly LabelWidget statusLabel; - readonly Action afterInstall; - string mirror; - - [ObjectCreator.UseCtor] - public DownloadPackagesLogic(Widget widget, Action afterInstall, string mirrorListUrl, string modId) - { - this.mirrorListUrl = mirrorListUrl; - this.afterInstall = afterInstall; - this.modId = modId; - - panel = widget.Get("INSTALL_DOWNLOAD_PANEL"); - progressBar = panel.Get("PROGRESS_BAR"); - statusLabel = panel.Get("STATUS_LABEL"); - - var text = "Downloading {0} assets...".F(ModMetadata.AllMods[modId].Title); - panel.Get("TITLE").Text = text; - - ShowDownloadDialog(); - } - - void ShowDownloadDialog() - { - statusLabel.GetText = () => "Fetching list of mirrors..."; - progressBar.Indeterminate = true; - - var retryButton = panel.Get("RETRY_BUTTON"); - retryButton.IsVisible = () => false; - - var cancelButton = panel.Get("CANCEL_BUTTON"); - - var file = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); - var dest = Platform.ResolvePath("^", "Content", modId); - - Action onDownloadProgress = i => - { - var dataReceived = 0.0f; - var dataTotal = 0.0f; - var mag = 0; - var dataSuffix = ""; - - if (i.TotalBytesToReceive < 0) - { - dataTotal = float.NaN; - dataReceived = i.BytesReceived; - dataSuffix = SizeSuffixes[0]; - } - else - { - mag = (int)Math.Log(i.TotalBytesToReceive, 1024); - dataTotal = i.TotalBytesToReceive / (float)(1L << (mag * 10)); - dataReceived = i.BytesReceived / (float)(1L << (mag * 10)); - dataSuffix = SizeSuffixes[mag]; - } - - progressBar.Indeterminate = false; - progressBar.Percentage = i.ProgressPercentage; - - statusLabel.GetText = () => "Downloading from {4} {1:0.00}/{2:0.00} {3} ({0}%)".F(i.ProgressPercentage, - dataReceived, dataTotal, dataSuffix, - mirror != null ? new Uri(mirror).Host : "unknown host"); - }; - - Action onExtractProgress = s => Game.RunAfterTick(() => statusLabel.GetText = () => s); - - Action onError = s => Game.RunAfterTick(() => - { - statusLabel.GetText = () => "Error: " + s; - retryButton.IsVisible = () => true; - }); - - Action onDownloadComplete = (i, cancelled) => - { - if (i.Error != null) - { - onError(Download.FormatErrorMessage(i.Error)); - return; - } - - if (cancelled) - { - onError("Download cancelled"); - return; - } - - // Automatically extract - statusLabel.GetText = () => "Extracting..."; - progressBar.Indeterminate = true; - if (InstallUtils.ExtractZip(file, dest, onExtractProgress, onError)) - { - Game.RunAfterTick(() => - { - Ui.CloseWindow(); - afterInstall(); - }); - } - }; - - Action onFetchMirrorsComplete = (i, cancelled) => - { - progressBar.Indeterminate = true; - - if (i.Error != null) - { - onError(Download.FormatErrorMessage(i.Error)); - return; - } - - if (cancelled) - { - onError("Download cancelled"); - return; - } - - var data = Encoding.UTF8.GetString(i.Result); - var mirrorList = data.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries); - mirror = mirrorList.Random(new MersenneTwister()); - - // Save the package to a temp file - var dl = new Download(mirror, file, onDownloadProgress, onDownloadComplete); - cancelButton.OnClick = () => { dl.Cancel(); Ui.CloseWindow(); }; - retryButton.OnClick = () => { dl.Cancel(); ShowDownloadDialog(); }; - }; - - // Get the list of mirrors - var updateMirrors = new Download(mirrorListUrl, onDownloadProgress, onFetchMirrorsComplete); - cancelButton.OnClick = () => { updateMirrors.Cancel(); Ui.CloseWindow(); }; - retryButton.OnClick = () => { updateMirrors.Cancel(); ShowDownloadDialog(); }; - } - } -} diff --git a/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallFromCDLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallFromCDLogic.cs deleted file mode 100644 index e1de4d41fb..0000000000 --- a/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallFromCDLogic.cs +++ /dev/null @@ -1,218 +0,0 @@ -#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; -using System.IO; -using System.Linq; -using System.Threading; -using OpenRA.FileSystem; -using OpenRA.Widgets; - -namespace OpenRA.Mods.Common.Widgets.Logic -{ - public class InstallFromCDLogic : ChromeLogic - { - readonly ModData modData; - readonly string modId; - readonly Widget panel; - readonly ProgressBarWidget progressBar; - readonly LabelWidget statusLabel; - readonly Action afterInstall; - readonly ButtonWidget retryButton, backButton; - readonly Widget installingContainer, insertDiskContainer; - readonly ContentInstaller installData; - - [ObjectCreator.UseCtor] - public InstallFromCDLogic(Widget widget, ModData modData, Action afterInstall, string modId) - { - this.modData = modData; - this.modId = modId; - installData = ModMetadata.AllMods[modId].Content; - this.afterInstall = afterInstall; - panel = widget.Get("INSTALL_FROMCD_PANEL"); - progressBar = panel.Get("PROGRESS_BAR"); - statusLabel = panel.Get("STATUS_LABEL"); - - backButton = panel.Get("BACK_BUTTON"); - backButton.OnClick = Ui.CloseWindow; - - retryButton = panel.Get("RETRY_BUTTON"); - retryButton.OnClick = CheckForDisk; - - installingContainer = panel.Get("INSTALLING"); - insertDiskContainer = panel.Get("INSERT_DISK"); - CheckForDisk(); - } - - bool IsValidDisk(string diskRoot) - { - return installData.DiskTestFiles.All(f => File.Exists(Path.Combine(diskRoot, f))); - } - - bool IsTFD(string diskpath) - { - var test = File.Exists(Path.Combine(diskpath, "data1.hdr")); - var i = 0; - - while (test && i < 14) - test &= File.Exists(Path.Combine(diskpath, "data{0}.cab".F(++i))); - - return test; - } - - void CheckForDisk() - { - var path = InstallUtils.GetMountedDisk(IsValidDisk); - - if (path != null) - Install(path); - else if ((installData.InstallShieldCABFileIds.Count != 0 || installData.InstallShieldCABFilePackageIds.Count != 0) - && (path = InstallUtils.GetMountedDisk(IsTFD)) != null) - InstallTFD(Platform.ResolvePath(path, "data1.hdr")); - else - { - var text = "Please insert a {0} install CD and click Retry.".F(ModMetadata.AllMods[modId].Title); - insertDiskContainer.Get("INFO2").Text = text; - - insertDiskContainer.IsVisible = () => true; - installingContainer.IsVisible = () => false; - } - } - - void InstallTFD(string source) - { - backButton.IsDisabled = () => true; - retryButton.IsDisabled = () => true; - insertDiskContainer.IsVisible = () => false; - installingContainer.IsVisible = () => true; - progressBar.Percentage = 0; - - new Thread(() => - { - using (var cabExtractor = new InstallShieldCABExtractor(modData.ModFiles, source)) - { - var denom = installData.InstallShieldCABFileIds.Count; - var extractFiles = installData.ExtractFilesFromCD; - - if (installData.InstallShieldCABFilePackageIds.Count > 0) - denom += extractFiles.SelectMany(x => x.Value).Count(); - - var installPercent = 100 / denom; - - foreach (uint index in installData.InstallShieldCABFileIds) - { - var filename = cabExtractor.FileName(index); - statusLabel.GetText = () => "Extracting {0}".F(filename); - var dest = Platform.ResolvePath("^", "Content", modId, filename.ToLowerInvariant()); - cabExtractor.ExtractFile(index, dest); - progressBar.Percentage += installPercent; - } - - var ArchivesToExtract = installData.InstallShieldCABFilePackageIds.Select(x => x.Split(':')); - var destDir = Platform.ResolvePath("^", "Content", modId); - var onError = (Action)(s => { }); - var overwrite = installData.OverwriteFiles; - - var onProgress = (Action)(s => Game.RunAfterTick(() => - { - progressBar.Percentage += installPercent; - - statusLabel.GetText = () => s; - })); - - foreach (var archive in ArchivesToExtract) - { - var filename = cabExtractor.FileName(uint.Parse(archive[0])); - statusLabel.GetText = () => "Extracting {0}".F(filename); - var destFile = Platform.ResolvePath("^", "Content", modId, filename.ToLowerInvariant()); - cabExtractor.ExtractFile(uint.Parse(archive[0]), destFile); - InstallUtils.ExtractFromPackage(modData.ModFiles, source, destFile, extractFiles, destDir, overwrite, installData.OutputFilenameCase, onProgress, onError); - progressBar.Percentage += installPercent; - } - } - - Game.RunAfterTick(() => - { - Ui.CloseWindow(); - afterInstall(); - }); - }) { IsBackground = true }.Start(); - } - - void Install(string source) - { - backButton.IsDisabled = () => true; - retryButton.IsDisabled = () => true; - insertDiskContainer.IsVisible = () => false; - installingContainer.IsVisible = () => true; - var dest = Platform.ResolvePath("^", "Content", modId); - var copyFiles = installData.CopyFilesFromCD; - - var packageToExtract = installData.PackageToExtractFromCD.Split(':'); - var extractPackage = packageToExtract.First(); - - var extractFiles = installData.ExtractFilesFromCD; - - var overwrite = installData.OverwriteFiles; - var installCounter = 0; - var installTotal = copyFiles.SelectMany(x => x.Value).Count() + extractFiles.SelectMany(x => x.Value).Count(); - var onProgress = (Action)(s => Game.RunAfterTick(() => - { - progressBar.Percentage = installCounter * 100 / installTotal; - installCounter++; - - statusLabel.GetText = () => s; - })); - - var onError = (Action)(s => Game.RunAfterTick(() => - { - statusLabel.GetText = () => "Error: " + s; - backButton.IsDisabled = () => false; - retryButton.IsDisabled = () => false; - })); - - new Thread(() => - { - try - { - if (!InstallUtils.CopyFiles(source, copyFiles, dest, overwrite, installData.OutputFilenameCase, onProgress, onError)) - { - onError("Copying files from CD failed."); - return; - } - - if (!string.IsNullOrEmpty(extractPackage)) - { - if (!InstallUtils.ExtractFromPackage(modData.ModFiles, source, extractPackage, extractFiles, dest, - overwrite, installData.OutputFilenameCase, onProgress, onError)) - { - onError("Extracting files from CD failed."); - return; - } - } - - Game.RunAfterTick(() => - { - statusLabel.GetText = () => "Game assets have been extracted."; - Ui.CloseWindow(); - afterInstall(); - }); - } - catch (Exception e) - { - onError("Installation failed.\n{0}".F(e.Message)); - Log.Write("debug", e.ToString()); - return; - } - }) { IsBackground = true }.Start(); - } - } -} diff --git a/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallFromDiscLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallFromDiscLogic.cs new file mode 100644 index 0000000000..b451812e6e --- /dev/null +++ b/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallFromDiscLogic.cs @@ -0,0 +1,422 @@ +#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; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Security.Cryptography; +using System.Threading.Tasks; +using OpenRA.FileFormats; +using OpenRA.Mods.Common.FileFormats; +using OpenRA.Widgets; + +namespace OpenRA.Mods.Common.Widgets.Logic +{ + public class InstallFromDiscLogic : ChromeLogic + { + enum Mode { Progress, Message, List } + + readonly ModContent content; + + readonly Widget panel; + readonly LabelWidget titleLabel; + readonly ButtonWidget primaryButton; + readonly ButtonWidget secondaryButton; + + // Progress panel + readonly Widget progressContainer; + readonly ProgressBarWidget progressBar; + readonly LabelWidget progressLabel; + + // Message panel + readonly Widget messageContainer; + readonly LabelWidget messageLabel; + + // List Panel + readonly Widget listContainer; + readonly ScrollPanelWidget listPanel; + readonly LabelWidget listTemplate; + readonly LabelWidget listLabel; + + Mode visible = Mode.Progress; + + [ObjectCreator.UseCtor] + public InstallFromDiscLogic(Widget widget, ModContent content, Action afterInstall) + { + this.content = content; + + Log.AddChannel("install", "install.log"); + + // this.afterInstall = afterInstall; + panel = widget.Get("DISC_INSTALL_PANEL"); + + titleLabel = panel.Get("TITLE"); + + primaryButton = panel.Get("PRIMARY_BUTTON"); + secondaryButton = panel.Get("SECONDARY_BUTTON"); + + // Progress view + progressContainer = panel.Get("PROGRESS"); + progressContainer.IsVisible = () => visible == Mode.Progress; + progressBar = panel.Get("PROGRESS_BAR"); + progressLabel = panel.Get("PROGRESS_MESSAGE"); + progressLabel.IsVisible = () => visible == Mode.Progress; + + // Message view + messageContainer = panel.Get("MESSAGE"); + messageContainer.IsVisible = () => visible == Mode.Message; + messageLabel = messageContainer.Get("MESSAGE_MESSAGE"); + + // List view + listContainer = panel.Get("LIST"); + listContainer.IsVisible = () => visible == Mode.List; + + listPanel = listContainer.Get("LIST_PANEL"); + listTemplate = listPanel.Get("LIST_TEMPLATE"); + listPanel.RemoveChildren(); + + listLabel = listContainer.Get("LIST_MESSAGE"); + + DetectContentDisks(); + } + + void DetectContentDisks() + { + var message = "Detecting drives"; + ShowProgressbar("Checking Discs", () => message); + ShowBackRetry(DetectContentDisks); + + new Task(() => + { + var volumes = DriveInfo.GetDrives() + .Where(v => v.DriveType == DriveType.CDRom && v.IsReady) + .Select(v => v.RootDirectory.FullName); + + foreach (var kv in content.Discs) + { + message = "Searching for " + kv.Value.Title; + + foreach (var volume in volumes) + { + if (PathIsDiscMount(volume, kv.Value)) + { + var packages = content.Packages.Values + .Where(p => p.Discs.Contains(kv.Key) && !p.IsInstalled()) + .Select(p => p.Title); + + // Ignore disc if content is already installed + if (packages.Any()) + { + Game.RunAfterTick(() => + { + ShowList(kv.Value.Title, "The following content packages will be installed:", packages); + ShowContinueCancel(() => InstallFromDisc(volume, kv.Value)); + }); + + return; + } + } + } + } + + var discTitles = content.Packages.Values + .Where(p => !p.IsInstalled()) + .SelectMany(p => p.Discs) + .Select(d => content.Discs[d].Title) + .Distinct(); + + Game.RunAfterTick(() => + { + ShowList("Disc Content Not Found", "Please insert or mount one of the following discs and try again", discTitles); + ShowBackRetry(DetectContentDisks); + }); + }).Start(); + } + + void InstallFromDisc(string path, ModContent.ModDisc disc) + { + var message = ""; + ShowProgressbar("Installing Content", () => message); + ShowDisabledCancel(); + + new Task(() => + { + var extracted = new List(); + + try + { + foreach (var i in disc.Install) + { + switch (i.Key) + { + case "copy": + { + var sourceDir = Path.Combine(path, i.Value.Value); + foreach (var node in i.Value.Nodes) + { + var sourcePath = Path.Combine(sourceDir, node.Value.Value); + var targetPath = Platform.ResolvePath(node.Key); + if (File.Exists(targetPath)) + { + Log.Write("install", "Ignoring installed file " + targetPath); + continue; + } + + Log.Write("install", "Copying {0} -> {1}".F(sourcePath, targetPath)); + message = "Copying " + Path.GetFileName(sourcePath); + extracted.Add(targetPath); + Directory.CreateDirectory(Path.GetDirectoryName(targetPath)); + File.Copy(sourcePath, targetPath); + } + + break; + } + + case "extract-raw": + { + ExtractFromPackage(ExtractionType.Raw, path, i.Value, extracted, ref message); + break; + } + + case "extract-blast": + { + ExtractFromPackage(ExtractionType.Blast, path, i.Value, extracted, ref message); + break; + } + + case "extract-mscab": + { + ExtractFromMSCab(path, i.Value, extracted, m => message = m); + break; + } + + default: + Game.Debug("debug", "Unknown installation command {0} - ignoring", i.Key); + break; + } + } + + Game.RunAfterTick(Ui.CloseWindow); + } + catch (Exception e) + { + Log.Write("install", e.ToString()); + + foreach (var f in extracted) + { + Log.Write("install", "Deleting " + f); + File.Delete(f); + } + + Game.RunAfterTick(() => + { + ShowMessage("Installation Failed", "Refer to install.log in the logs directory for details."); + ShowBackRetry(() => InstallFromDisc(path, disc)); + }); + } + }).Start(); + } + + enum ExtractionType { Raw, Blast } + + static void ExtractFromPackage(ExtractionType type, string path, MiniYaml actionYaml, List extractedFiles, ref string progressMessage) + { + var sourcePath = Path.Combine(path, actionYaml.Value); + using (var source = File.OpenRead(sourcePath)) + { + foreach (var node in actionYaml.Nodes) + { + var targetPath = Platform.ResolvePath(node.Key); + + if (File.Exists(targetPath)) + { + Log.Write("install", "Skipping installed file " + targetPath); + continue; + } + + var offsetNode = node.Value.Nodes.FirstOrDefault(n => n.Key == "Offset"); + if (offsetNode == null) + { + Log.Write("install", "Skipping entry with missing Offset definition " + targetPath); + continue; + } + + var lengthNode = node.Value.Nodes.FirstOrDefault(n => n.Key == "Length"); + if (lengthNode == null) + { + Log.Write("install", "Skipping entry with missing Length definition " + targetPath); + continue; + } + + var length = FieldLoader.GetValue("Length", lengthNode.Value.Value); + + source.Position = FieldLoader.GetValue("Offset", offsetNode.Value.Value); + + extractedFiles.Add(targetPath); + Directory.CreateDirectory(Path.GetDirectoryName(targetPath)); + using (var target = File.OpenWrite(targetPath)) + { + // This is a bit dumb memory-wise, but we load the whole thing when running the game anyway + Log.Write("install", "Extracting {0} -> {1}".F(sourcePath, targetPath)); + progressMessage = "Extracting " + Path.GetFileName(Path.GetFileName(targetPath)); + + var data = source.ReadBytes(length); + if (type == ExtractionType.Blast) + data = Blast.Decompress(data); + + target.Write(data); + } + } + } + } + + static void ExtractFromMSCab(string path, MiniYaml actionYaml, List extractedFiles, Action updateMessage) + { + var sourcePath = Path.Combine(path, actionYaml.Value); + using (var source = File.OpenRead(sourcePath)) + { + var reader = new MSCabCompression(source); + foreach (var node in actionYaml.Nodes) + { + var targetPath = Platform.ResolvePath(node.Key); + + if (File.Exists(targetPath)) + { + Log.Write("install", "Skipping installed file " + targetPath); + continue; + } + + extractedFiles.Add(targetPath); + Directory.CreateDirectory(Path.GetDirectoryName(targetPath)); + using (var target = File.OpenWrite(targetPath)) + { + // This is a bit dumb memory-wise, but we load the whole thing when running the game anyway + Log.Write("install", "Extracting {0} -> {1}".F(sourcePath, targetPath)); + + var displayFilename = Path.GetFileName(Path.GetFileName(targetPath)); + Action onProgress = percent => updateMessage("Extracting {0} ({1}%)".F(displayFilename, percent)); + target.Write(reader.ExtractFile(node.Value.Value, onProgress)); + } + } + } + } + + bool PathIsDiscMount(string path, ModContent.ModDisc disc) + { + try + { + foreach (var kv in disc.IDFiles) + { + var filePath = Path.Combine(path, kv.Key); + if (!File.Exists(filePath)) + return false; + + using (var fileStream = File.OpenRead(filePath)) + using (var csp = SHA1.Create()) + { + var hash = new string(csp.ComputeHash(fileStream).SelectMany(a => a.ToString("x2")).ToArray()); + if (hash != kv.Value) + return false; + } + } + } + catch (Exception) + { + return false; + } + + return true; + } + + void ShowMessage(string title, string message) + { + visible = Mode.Message; + titleLabel.Text = title; + messageLabel.Text = message; + + primaryButton.Bounds.Y += messageContainer.Bounds.Height - panel.Bounds.Height; + secondaryButton.Bounds.Y += messageContainer.Bounds.Height - panel.Bounds.Height; + panel.Bounds.Y -= (messageContainer.Bounds.Height - panel.Bounds.Height) / 2; + panel.Bounds.Height = messageContainer.Bounds.Height; + } + + void ShowProgressbar(string title, Func getMessage) + { + visible = Mode.Progress; + titleLabel.Text = title; + progressBar.IsIndeterminate = () => true; + + var font = Game.Renderer.Fonts[progressLabel.Font]; + var status = new CachedTransform(s => WidgetUtils.TruncateText(s, progressLabel.Bounds.Width, font)); + progressLabel.GetText = () => status.Update(getMessage()); + + primaryButton.Bounds.Y += progressContainer.Bounds.Height - panel.Bounds.Height; + secondaryButton.Bounds.Y += progressContainer.Bounds.Height - panel.Bounds.Height; + panel.Bounds.Y -= (progressContainer.Bounds.Height - panel.Bounds.Height) / 2; + panel.Bounds.Height = progressContainer.Bounds.Height; + } + + void ShowList(string title, string message, IEnumerable items) + { + visible = Mode.List; + titleLabel.Text = title; + listLabel.Text = message; + + listPanel.RemoveChildren(); + foreach (var i in items) + { + var item = i; + var labelWidget = (LabelWidget)listTemplate.Clone(); + labelWidget.GetText = () => item; + listPanel.AddChild(labelWidget); + } + + primaryButton.Bounds.Y += listContainer.Bounds.Height - panel.Bounds.Height; + secondaryButton.Bounds.Y += listContainer.Bounds.Height - panel.Bounds.Height; + panel.Bounds.Y -= (listContainer.Bounds.Height - panel.Bounds.Height) / 2; + panel.Bounds.Height = listContainer.Bounds.Height; + } + + void ShowContinueCancel(Action continueAction) + { + primaryButton.OnClick = continueAction; + primaryButton.Text = "Continue"; + primaryButton.Visible = true; + + secondaryButton.OnClick = Ui.CloseWindow; + secondaryButton.Text = "Cancel"; + secondaryButton.Visible = true; + secondaryButton.Disabled = false; + Game.RunAfterTick(Ui.ResetTooltips); + } + + void ShowBackRetry(Action retryAction) + { + primaryButton.OnClick = retryAction; + primaryButton.Text = "Retry"; + primaryButton.Visible = true; + + secondaryButton.OnClick = Ui.CloseWindow; + secondaryButton.Text = "Back"; + secondaryButton.Visible = true; + secondaryButton.Disabled = false; + Game.RunAfterTick(Ui.ResetTooltips); + } + + void ShowDisabledCancel() + { + primaryButton.Visible = false; + secondaryButton.Disabled = true; + Game.RunAfterTick(Ui.ResetTooltips); + } + } +} diff --git a/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallLogic.cs deleted file mode 100644 index 3e5d47fb87..0000000000 --- a/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallLogic.cs +++ /dev/null @@ -1,43 +0,0 @@ -#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 OpenRA.Widgets; - -namespace OpenRA.Mods.Common.Widgets.Logic -{ - public class InstallLogic : ChromeLogic - { - [ObjectCreator.UseCtor] - public InstallLogic(Widget widget, string mirrorListUrl, string modId) - { - var panel = widget.Get("INSTALL_PANEL"); - var widgetArgs = new WidgetArgs - { - { "afterInstall", () => { Game.InitializeMod(modId, new Arguments()); } }, - { "mirrorListUrl", mirrorListUrl }, - { "modId", modId } - }; - - var mod = ModMetadata.AllMods[modId]; - var text = "OpenRA requires the original {0} game content.".F(mod.Title); - panel.Get("DESC1").Text = text; - - var downloadButton = panel.Get("DOWNLOAD_BUTTON"); - downloadButton.OnClick = () => Ui.OpenWindow("INSTALL_DOWNLOAD_PANEL", widgetArgs); - downloadButton.IsDisabled = () => string.IsNullOrEmpty(mod.Content.PackageMirrorList); - - panel.Get("INSTALL_BUTTON").OnClick = () => - Ui.OpenWindow("INSTALL_FROMCD_PANEL", widgetArgs); - - panel.Get("BACK_BUTTON").OnClick = Ui.CloseWindow; - } - } -} diff --git a/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallMusicLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallMusicLogic.cs deleted file mode 100644 index d8efc53be5..0000000000 --- a/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallMusicLogic.cs +++ /dev/null @@ -1,60 +0,0 @@ -#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; -using OpenRA.Widgets; - -namespace OpenRA.Mods.Common.Widgets.Logic -{ - public class InstallMusicLogic : ChromeLogic - { - [ObjectCreator.UseCtor] - public InstallMusicLogic(Widget widget, string modId) - { - var installMusicContainer = widget.Get("INSTALL_MUSIC_PANEL"); - - Action loadDefaultMod = () => Game.RunAfterTick(() => Game.InitializeMod(modId, null)); - - var cancelButton = installMusicContainer.GetOrNull("BACK_BUTTON"); - if (cancelButton != null) - cancelButton.OnClick = loadDefaultMod; - - var copyFromDiscButton = installMusicContainer.GetOrNull("INSTALL_MUSIC_BUTTON"); - if (copyFromDiscButton != null) - { - copyFromDiscButton.OnClick = () => - { - Ui.OpenWindow("INSTALL_FROMCD_PANEL", new WidgetArgs - { - { "afterInstall", loadDefaultMod }, - { "modId", modId } - }); - }; - } - - var downloadButton = installMusicContainer.GetOrNull("DOWNLOAD_MUSIC_BUTTON"); - if (downloadButton != null) - { - var installData = ModMetadata.AllMods[modId].Content; - downloadButton.IsDisabled = () => string.IsNullOrEmpty(installData.MusicPackageMirrorList); - downloadButton.OnClick = () => - { - Ui.OpenWindow("INSTALL_DOWNLOAD_PANEL", new WidgetArgs - { - { "afterInstall", loadDefaultMod }, - { "mirrorListUrl", installData.MusicPackageMirrorList }, - { "modId", modId } - }); - }; - } - } - } -} diff --git a/OpenRA.Mods.Common/Widgets/Logic/Installation/ModContentDiscTooltipLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Installation/ModContentDiscTooltipLogic.cs new file mode 100644 index 0000000000..4f679567b6 --- /dev/null +++ b/OpenRA.Mods.Common/Widgets/Logic/Installation/ModContentDiscTooltipLogic.cs @@ -0,0 +1,53 @@ +#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; +using System.IO; +using System.Linq; +using OpenRA.Widgets; + +namespace OpenRA.Mods.Common.Widgets.Logic +{ + public class ModContentDiscTooltipLogic : ChromeLogic + { + [ObjectCreator.UseCtor] + public ModContentDiscTooltipLogic(Widget widget, Func getText) + { + var discs = widget.Get("DISCS"); + var template = discs.Get("DISC_TEMPLATE"); + discs.RemoveChildren(); + + var desc = widget.Get("DESCRIPTION"); + + var font = Game.Renderer.Fonts[template.Font]; + var discTitles = getText().Split('\n'); + + var maxWidth = 0; + var sideMargin = desc.Bounds.X; + var bottomMargin = discs.Bounds.Height; + foreach (var disc in discTitles) + { + var label = (LabelWidget)template.Clone(); + var title = disc; + label.GetText = () => title; + label.Bounds.Y = discs.Bounds.Height; + label.Bounds.Width = font.Measure(disc).X; + + maxWidth = Math.Max(maxWidth, label.Bounds.Width + label.Bounds.X); + discs.AddChild(label); + discs.Bounds.Height += label.Bounds.Height; + } + + widget.Bounds.Width = 2 * sideMargin + maxWidth; + widget.Bounds.Height = discs.Bounds.Y + bottomMargin + discs.Bounds.Height; + } + } +} diff --git a/OpenRA.Mods.Common/Widgets/Logic/Installation/ModContentLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Installation/ModContentLogic.cs new file mode 100644 index 0000000000..2b5ca3cf04 --- /dev/null +++ b/OpenRA.Mods.Common/Widgets/Logic/Installation/ModContentLogic.cs @@ -0,0 +1,127 @@ +#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; +using System.IO; +using System.Linq; +using OpenRA.Widgets; + +namespace OpenRA.Mods.Common.Widgets.Logic +{ + public class ModContentLogic : ChromeLogic + { + readonly ModContent content; + readonly ScrollPanelWidget scrollPanel; + readonly Widget template; + bool discAvailable; + + [ObjectCreator.UseCtor] + public ModContentLogic(Widget widget, string modId, Action onCancel) + { + var panel = widget.Get("CONTENT_PANEL"); + + content = ModMetadata.AllMods[modId].ModContent; + scrollPanel = panel.Get("PACKAGES"); + template = scrollPanel.Get("PACKAGE_TEMPLATE"); + + var headerTemplate = panel.Get("HEADER_TEMPLATE"); + var headerLines = !string.IsNullOrEmpty(content.HeaderMessage) ? content.HeaderMessage.Replace("\\n", "\n").Split('\n') : new string[0]; + var headerHeight = 0; + foreach (var l in headerLines) + { + var line = (LabelWidget)headerTemplate.Clone(); + line.GetText = () => l; + line.Bounds.Y += headerHeight; + panel.AddChild(line); + + headerHeight += headerTemplate.Bounds.Height; + } + + panel.Bounds.Height += headerHeight; + panel.Bounds.Y -= headerHeight / 2; + scrollPanel.Bounds.Y += headerHeight; + + var discButton = panel.Get("CHECK_DISC_BUTTON"); + discButton.Bounds.Y += headerHeight; + discButton.IsVisible = () => discAvailable; + + discButton.OnClick = () => Ui.OpenWindow("DISC_INSTALL_PANEL", new WidgetArgs + { + { "afterInstall", () => { } }, + { "content", content } + }); + + var backButton = panel.Get("BACK_BUTTON"); + backButton.Bounds.Y += headerHeight; + backButton.OnClick = () => { Ui.CloseWindow(); onCancel(); }; + + PopulateContentList(); + Game.RunAfterTick(Ui.ResetTooltips); + } + + public override void BecameVisible() + { + PopulateContentList(); + } + + void PopulateContentList() + { + scrollPanel.RemoveChildren(); + + foreach (var p in content.Packages) + { + var container = template.Clone(); + var titleWidget = container.Get("TITLE"); + var title = p.Value.Title; + titleWidget.GetText = () => title; + + var requiredWidget = container.Get("REQUIRED"); + requiredWidget.IsVisible = () => p.Value.Required; + + var discWidget = container.Get("DISC"); + var discs = p.Value.Discs.Select(s => content.Discs[s].Title).Distinct(); + var discList = discs.JoinWith("\n"); + var discAvailable = discs.Any(); + discWidget.GetTooltipText = () => discList; + discWidget.IsVisible = () => discAvailable; + + var installed = p.Value.IsInstalled(); + var downloadButton = container.Get("DOWNLOAD"); + var downloadEnabled = !installed && p.Value.Download != null; + downloadButton.IsVisible = () => downloadEnabled; + + if (downloadEnabled) + { + var download = content.Downloads[p.Value.Download]; + var widgetArgs = new WidgetArgs + { + { "download", download }, + { "onSuccess", () => { } } + }; + + downloadButton.OnClick = () => Ui.OpenWindow("PACKAGE_DOWNLOAD_PANEL", widgetArgs); + } + + var installedWidget = container.Get("INSTALLED"); + installedWidget.IsVisible = () => installed; + + var requiresDiscWidget = container.Get("REQUIRES_DISC"); + requiresDiscWidget.IsVisible = () => !installed && !downloadEnabled; + if (!discAvailable) + requiresDiscWidget.GetText = () => "Manual Install"; + + scrollPanel.AddChild(container); + } + + discAvailable = content.Packages.Values.Any(p => p.Discs.Any() && !p.IsInstalled()); + } + } +} diff --git a/OpenRA.Mods.Common/Widgets/Logic/Installation/ModContentPromptLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Installation/ModContentPromptLogic.cs new file mode 100644 index 0000000000..63d41c0e15 --- /dev/null +++ b/OpenRA.Mods.Common/Widgets/Logic/Installation/ModContentPromptLogic.cs @@ -0,0 +1,72 @@ +#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; +using OpenRA.Widgets; + +namespace OpenRA.Mods.Common.Widgets.Logic +{ + public class ModContentPromptLogic : ChromeLogic + { + [ObjectCreator.UseCtor] + public ModContentPromptLogic(Widget widget, string modId, Action continueLoading) + { + var panel = widget.Get("CONTENT_PROMPT_PANEL"); + + var mod = ModMetadata.AllMods[modId]; + var content = ModMetadata.AllMods[modId].ModContent; + + var headerTemplate = panel.Get("HEADER_TEMPLATE"); + var headerLines = !string.IsNullOrEmpty(content.InstallPromptMessage) ? content.InstallPromptMessage.Replace("\\n", "\n").Split('\n') : new string[0]; + var headerHeight = 0; + foreach (var l in headerLines) + { + var line = (LabelWidget)headerTemplate.Clone(); + line.GetText = () => l; + line.Bounds.Y += headerHeight; + panel.AddChild(line); + + headerHeight += headerTemplate.Bounds.Height; + } + + panel.Bounds.Height += headerHeight; + panel.Bounds.Y -= headerHeight / 2; + + var advancedButton = panel.Get("ADVANCED_BUTTON"); + advancedButton.Bounds.Y += headerHeight; + advancedButton.OnClick = () => + { + Ui.OpenWindow("CONTENT_PANEL", new WidgetArgs + { + { "modId", modId }, + { "onCancel", Ui.CloseWindow } + }); + }; + + var quickButton = panel.Get("QUICK_BUTTON"); + quickButton.IsVisible = () => !string.IsNullOrEmpty(content.QuickDownload); + quickButton.Bounds.Y += headerHeight; + quickButton.OnClick = () => + { + Ui.OpenWindow("PACKAGE_DOWNLOAD_PANEL", new WidgetArgs + { + { "download", content.Downloads[content.QuickDownload] }, + { "onSuccess", continueLoading } + }); + }; + + var backButton = panel.Get("BACK_BUTTON"); + backButton.Bounds.Y += headerHeight; + backButton.OnClick = Ui.CloseWindow; + Game.RunAfterTick(Ui.ResetTooltips); + } + } +} diff --git a/OpenRA.Mods.Common/Widgets/Logic/ModBrowserLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/ModBrowserLogic.cs index c766f1d4cc..7a74dbd966 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/ModBrowserLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/ModBrowserLogic.cs @@ -27,8 +27,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic readonly ModMetadata[] allMods; readonly Dictionary previews = new Dictionary(); readonly Dictionary logos = new Dictionary(); - readonly Cache modInstallStatus; - readonly Cache modPrerequisitesFulfilled; readonly Widget modChooserPanel; readonly ButtonWidget loadButton; readonly SheetBuilder sheetBuilder; @@ -40,14 +38,24 @@ namespace OpenRA.Mods.Common.Widgets.Logic [ObjectCreator.UseCtor] public ModBrowserLogic(Widget widget, ModData modData) { - modInstallStatus = new Cache(IsModInstalled); - modPrerequisitesFulfilled = new Cache(Game.IsModInstalled); - modChooserPanel = widget; loadButton = modChooserPanel.Get("LOAD_BUTTON"); loadButton.OnClick = () => LoadMod(selectedMod); loadButton.IsDisabled = () => selectedMod.Id == modData.Manifest.Mod.Id; + var contentButton = modChooserPanel.Get("CONFIGURE_BUTTON"); + contentButton.IsDisabled = () => selectedMod.ModContent == null; + contentButton.OnClick = () => + { + var widgetArgs = new WidgetArgs + { + { "modId", selectedMod.Id }, + { "onCancel", () => { } } + }; + + Ui.OpenWindow("CONTENT_PANEL", widgetArgs); + }; + modChooserPanel.Get("QUIT_BUTTON").OnClick = Game.Exit; modList = modChooserPanel.Get("MOD_LIST"); @@ -160,14 +168,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic var selectedIndex = Array.IndexOf(allMods, mod); if (selectedIndex - modOffset > 4) modOffset = selectedIndex - 4; - - loadButton.Text = !modPrerequisitesFulfilled[mod.Id] ? "Install mod" : - modInstallStatus[mod] ? "Load Mod" : "Install Assets"; } void LoadMod(ModMetadata mod) { - if (!modPrerequisitesFulfilled[mod.Id]) + if (!Game.IsModInstalled(mod.Id)) { var widgetArgs = new WidgetArgs { @@ -178,17 +183,16 @@ namespace OpenRA.Mods.Common.Widgets.Logic return; } - if (!modInstallStatus[mod]) + if (!IsModInstalled(mod)) { var widgetArgs = new WidgetArgs { { "continueLoading", () => - Game.RunAfterTick(() => Game.InitializeMod(Game.Settings.Game.Mod, new Arguments())) }, - { "mirrorListUrl", mod.Content.PackageMirrorList }, + Game.RunAfterTick(() => Game.InitializeMod(mod.Id, new Arguments())) }, { "modId", mod.Id } }; - Ui.OpenWindow("INSTALL_PANEL", widgetArgs); + Ui.OpenWindow("CONTENT_PROMPT_PANEL", widgetArgs); return; } @@ -203,7 +207,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic static bool IsModInstalled(ModMetadata mod) { - return mod.Content.TestFiles.All(file => File.Exists(Path.GetFullPath(Platform.ResolvePath(file)))); + return mod.ModContent.Packages + .Where(p => p.Value.Required) + .All(p => p.Value.TestFiles.All(f => File.Exists(Platform.ResolvePath(f)))); } } } diff --git a/OpenRA.Mods.Common/Widgets/Logic/MusicPlayerLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/MusicPlayerLogic.cs index 3274f9a060..80b35f227b 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/MusicPlayerLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/MusicPlayerLogic.cs @@ -103,18 +103,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic musicSlider.OnChange += x => Game.Sound.MusicVolume = x; musicSlider.Value = Game.Sound.MusicVolume; - var installButton = widget.GetOrNull("INSTALL_BUTTON"); - if (installButton != null) - { - installButton.IsDisabled = () => world.Type != WorldType.Shellmap; - var args = new[] { "installMusic={0}".F(modData.Manifest.Mod.Id) }; - installButton.OnClick = () => - Game.RunAfterTick(() => Game.InitializeMod("modchooser", new Arguments(args))); - - var installData = modData.Manifest.Get(); - installButton.IsVisible = () => modData.DefaultRules.InstalledMusic.ToArray().Length <= installData.ShippedSoundtracks; - } - var songWatcher = widget.GetOrNull("SONG_WATCHER"); if (songWatcher != null) { diff --git a/OpenRA.Mods.Common/Widgets/ScrollPanelWidget.cs b/OpenRA.Mods.Common/Widgets/ScrollPanelWidget.cs index 4493e59e0e..ba23b09600 100644 --- a/OpenRA.Mods.Common/Widgets/ScrollPanelWidget.cs +++ b/OpenRA.Mods.Common/Widgets/ScrollPanelWidget.cs @@ -34,6 +34,7 @@ namespace OpenRA.Mods.Common.Widgets { readonly Ruleset modRules; public int ScrollbarWidth = 24; + public int BorderWidth = 1; public int TopBottomSpacing = 2; public int ItemSpacing = 0; public int ButtonDepth = ChromeMetrics.Get("ButtonDepth"); @@ -165,7 +166,7 @@ namespace OpenRA.Mods.Common.Widgets WidgetUtils.DrawRGBA(ChromeProvider.GetImage("scrollbar", downPressed || downDisabled ? "down_pressed" : "down_arrow"), new float2(downButtonRect.Left + downOffset, downButtonRect.Top + downOffset)); - var drawBounds = backgroundRect.InflateBy(-1, -1, -1, -1); + var drawBounds = backgroundRect.InflateBy(-BorderWidth, -BorderWidth, -BorderWidth, -BorderWidth); Game.Renderer.EnableScissor(drawBounds); drawBounds.Offset((-ChildOrigin).ToPoint()); diff --git a/mods/cnc/chrome/lobby-music.yaml b/mods/cnc/chrome/lobby-music.yaml index 8ec356ded0..0786683670 100644 --- a/mods/cnc/chrome/lobby-music.yaml +++ b/mods/cnc/chrome/lobby-music.yaml @@ -170,21 +170,27 @@ Container@LOBBY_MUSIC_BIN: Visible: false Children: Label@TITLE: - Y: 75 + Y: 65 Width: PARENT_RIGHT-24 Height: 25 Font: Bold Align: Center - Text: No Music Available + Text: Music Not Installed Label@DESCA: - Y: 95 + Y: 85 Width: PARENT_RIGHT-24 Height: 25 Align: Center - Text: Music can be installed from the - Label@DESCA: - Y: 115 + Text: The game music can be installed + Label@DESCB: + Y: 105 Width: PARENT_RIGHT-24 Height: 25 Align: Center - Text: game Extras menu. + Text: from the "Manage Content" menu + Label@DESCC: + Y: 125 + Width: PARENT_RIGHT-24 + Height: 25 + Align: Center + Text: in the mod chooser. diff --git a/mods/cnc/chrome/music.yaml b/mods/cnc/chrome/music.yaml index a2225bb305..f9c8931b21 100644 --- a/mods/cnc/chrome/music.yaml +++ b/mods/cnc/chrome/music.yaml @@ -154,15 +154,37 @@ Container@MUSIC_PANEL: Height: 20 Font: Regular Text: Loop - Label@NO_MUSIC_LABEL: + Container@NO_MUSIC_LABEL: X: 15 - Y: 147 + Y: 120 Width: 330 - Height: 25 - Font: Bold - Align: Center + Height: 80 Visible: false - Text: No Music Installed + Children: + Label@TITLE: + Width: PARENT_RIGHT-24 + Height: 25 + Font: Bold + Align: Center + Text: Music Not Installed + Label@DESCA: + Y: 20 + Width: PARENT_RIGHT-24 + Height: 25 + Align: Center + Text: The game music can be installed + Label@DESCB: + Y: 40 + Width: PARENT_RIGHT-24 + Height: 25 + Align: Center + Text: from the "Manage Content" menu + Label@DESCC: + Y: 60 + Width: PARENT_RIGHT-24 + Height: 25 + Align: Center + Text: in the mod chooser. Button@BACK_BUTTON: Key: escape X: 0 @@ -170,73 +192,9 @@ Container@MUSIC_PANEL: Width: 140 Height: 35 Text: Back - Button@INSTALL_BUTTON: - X: 220 - Y: 399 - Width: 140 - Height: 35 - Text: Install Music Label@MUTE_LABEL: X: 165 Y: 399 Width: 300 Height: 20 - Font: Small - -Container@INSTALL_MUSIC_PANEL: - Logic: InstallMusicLogic - X: (WINDOW_RIGHT - WIDTH)/2 - Y: (WINDOW_BOTTOM - 150)/2 - Width: 640 - Height: 150 - Children: - Label@TITLE: - Width: PARENT_RIGHT - Y: 0-25 - Font: BigBold - Contrast: true - Align: Center - Text: Install Music - Background@bg: - Width: 640 - Height: 150 - Background: panel-black - Children: - Image@INSTALL: - X: 11 - Y: 11 - ImageCollection: logos - ImageName: install - Label@INFO: - X: 170 - Y: 35 - Width: PARENT_RIGHT-30 - Height: 25 - Text: The soundtrack is currently unavailable. - Font: Bold - Label@INFO2: - X: 170 - Y: 70 - Width: PARENT_RIGHT-185 - Height: 25 - WordWrap: true - Text: OpenRA can download the music files from the internet, or you can install from the original C&C CDs. - Font: Bold - Button@CANCEL_BUTTON: - Key: escape - Y: 149 - Width: 140 - Height: 35 - Text: Back - Button@DOWNLOAD_BUTTON: - X: 350 - Y: 149 - Width: 140 - Height: 35 - Text: Download - Button@COPY_FROM_CD_BUTTON: - X: 500 - Y: 149 - Width: 140 - Height: 35 - Text: Use CD + Font: Small \ No newline at end of file diff --git a/mods/cnc/mod.yaml b/mods/cnc/mod.yaml index 6ef4201c25..721e30dd2d 100644 --- a/mods/cnc/mod.yaml +++ b/mods/cnc/mod.yaml @@ -24,6 +24,7 @@ Packages: ~movies.mix ~scores.mix ~scores2.mix + ~scores-covertops.mix ~transit.mix cnc|bits/snow.mix cnc|bits @@ -143,19 +144,6 @@ LoadScreen: CncLoadScreen Image: cnc|uibits/chrome.png Text: Loading -ContentInstaller: - TestFiles: ^Content/cnc/conquer.mix, ^Content/cnc/desert.mix, ^Content/cnc/sounds.mix, ^Content/cnc/speech.mix, ^Content/cnc/temperat.mix, ^Content/cnc/tempicnh.mix, ^Content/cnc/winter.mix - PackageMirrorList: http://www.openra.net/packages/cnc-mirrors.txt - DiskTestFiles: conquer.mix, desert.mix, install/setup.z - PackageToExtractFromCD: install/setup.z - ExtractFilesFromCD: - .: C&C95\SPEECH.MIX, C&C95\TEMPICNH.MIX, C&C95\TRANSIT.MIX - CopyFilesFromCD: - .: conquer.mix, desert.mix, general.mix, scores.mix, sounds.mix, temperat.mix, winter.mix - ShippedSoundtracks: 4 - MusicPackageMirrorList: http://www.openra.net/packages/cnc-music-mirrors.txt - InstallShieldCABFileIds: 66, 45, 42, 65, 68, 67, 71, 47, 49, 60, 75, 73, 53 - ServerTraits: LobbyCommands PlayerPinger @@ -232,3 +220,155 @@ GameSpeeds: OrderLatency: 6 ColorValidator: + +ModContent: + InstallPromptMessage: Tiberian Dawn requires artwork and audio from the original game.\n\nQuick Install will automatically download this content (without music\nor videos) from a mirror of the 2007 C&C Gold freeware release.\n\nAdvanced Install includes options for downloading the music and for\ncopying the videos and other content from an original game disc. + QuickDownload: basefiles + HeaderMessage: The original game content may be copied from an original game disc,\nor downloaded from an online mirror of the 2007 freeware release. + Packages: + base: Base Game Files + TestFiles: ^Content/cnc/conquer.mix, ^Content/cnc/desert.mix, ^Content/cnc/sounds.mix, ^Content/cnc/speech.mix, ^Content/cnc/temperat.mix, ^Content/cnc/tempicnh.mix, ^Content/cnc/winter.mix + Discs: gdi95, gdi95-linux, nod95, nod95-linux + Required: true + Download: basefiles + music: Base Game Music + TestFiles: ^Content/cnc/scores.mix + Discs: gdi95, gdi95-linux, nod95, nod95-linux + Download: music + movies-gdi: GDI Campaign Briefings + TestFiles: ^Content/cnc/movies-gdi.mix + Discs: gdi95, gdi95-linux + movies-nod: Nod Campaign Briefings + TestFiles: ^Content/cnc/movies-nod.mix + Discs: nod95, nod95-linux + music-covertops: Covert Operations Music + TestFiles: ^Content/cnc/scores-covertops.mix + Discs: covertops, covertops-linux + Downloads: + basefiles: Base Freeware Content + MirrorList: http://www.openra.net/packages/cnc-mirrors.txt + Extract: + ^Content/cnc/conquer.mix: conquer.mix + ^Content/cnc/desert.mix: desert.mix + ^Content/cnc/general.mix: general.mix + ^Content/cnc/sounds.mix: sounds.mix + ^Content/cnc/speech.mix: speech.mix + ^Content/cnc/temperat.mix: temperat.mix + ^Content/cnc/tempicnh.mix: tempicnh.mix + ^Content/cnc/transit.mix: transit.mix + ^Content/cnc/winter.mix: winter.mix + music: Freeware Music + MirrorList: http://www.openra.net/packages/cnc-music-mirrors.txt + Extract: + ^Content/cnc/scores.mix: scores.mix + Discs: + gdi95: C&C Gold (GDI Disc, English) + IDFiles: + DISK.WAV: 8bef9a6687c0fe0afd57c6561df58fa6e64f145d + CONQUER.MIX: 833e02a09aae694659eb312d3838367f681d1b30 + Install: + copy: . + ^Content/cnc/conquer.mix: CONQUER.MIX + ^Content/cnc/desert.mix: DESERT.MIX + ^Content/cnc/general.mix: GENERAL.MIX + ^Content/cnc/scores.mix: SCORES.MIX + ^Content/cnc/sounds.mix: SOUNDS.MIX + ^Content/cnc/temperat.mix: TEMPERAT.MIX + ^Content/cnc/winter.mix: WINTER.MIX + ^Content/cnc/movies-gdi.mix: MOVIES.MIX + extract-blast: INSTALL/SETUP.Z + ^Content/cnc/speech.mix: + Offset: 10203213 + Length: 603293 + ^Content/cnc/tempicnh.mix: + Offset: 10925941 + Length: 119096 + ^Content/cnc/transit.mix: + Offset: 11078017 + Length: 3724462 + gdi95-linux: C&C Gold (GDI Disc, English) + IDFiles: + disk.wav: 8bef9a6687c0fe0afd57c6561df58fa6e64f145d + conquer.mix: 833e02a09aae694659eb312d3838367f681d1b30 + Install: + copy: . + ^Content/cnc/conquer.mix: conquer.mix + ^Content/cnc/desert.mix: desert.mix + ^Content/cnc/general.mix: general.mix + ^Content/cnc/scores.mix: scores.mix + ^Content/cnc/sounds.mix: sounds.mix + ^Content/cnc/temperat.mix: temperat.mix + ^Content/cnc/winter.mix: winter.mix + ^Content/cnc/movies-gdi.mix: movies.mix + extract-blast: install/setup.z + ^Content/cnc/speech.mix: + Offset: 10203213 + Length: 603293 + ^Content/cnc/tempicnh.mix: + Offset: 10925941 + Length: 119096 + ^Content/cnc/transit.mix: + Offset: 11078017 + Length: 3724462 + nod95: C&C Gold (Nod Disc, English) + IDFiles: + DISK.WAV: 83a0235525afa5cd6096f2967e3eae032996e38c + CONQUER.MIX: 833e02a09aae694659eb312d3838367f681d1b30 + Install: + copy: . + ^Content/cnc/conquer.mix: CONQUER.MIX + ^Content/cnc/desert.mix: DESERT.MIX + ^Content/cnc/general.mix: GENERAL.MIX + ^Content/cnc/scores.mix: SCORES.MIX + ^Content/cnc/sounds.mix: SOUNDS.MIX + ^Content/cnc/temperat.mix: TEMPERAT.MIX + ^Content/cnc/winter.mix: WINTER.MIX + ^Content/cnc/movies-nod.mix: MOVIES.MIX + extract-blast: INSTALL/SETUP.Z + ^Content/cnc/speech.mix: + Offset: 10203213 + Length: 603293 + ^Content/cnc/tempicnh.mix: + Offset: 10925941 + Length: 119096 + ^Content/cnc/transit.mix: + Offset: 11078017 + Length: 3724462 + nod95-linux: C&C Gold (Nod Disc, English) + IDFiles: + disk.wav: 83a0235525afa5cd6096f2967e3eae032996e38c + conquer.mix: 833e02a09aae694659eb312d3838367f681d1b30 + Install: + copy: . + ^Content/cnc/conquer.mix: conquer.mix + ^Content/cnc/desert.mix: desert.mix + ^Content/cnc/general.mix: general.mix + ^Content/cnc/scores.mix: scores.mix + ^Content/cnc/sounds.mix: sounds.mix + ^Content/cnc/temperat.mix: temperat.mix + ^Content/cnc/winter.mix: winter.mix + ^Content/cnc/movies-nod.mix: movies.mix + extract-blast: install/setup.z + ^Content/cnc/speech.mix: + Offset: 10203213 + Length: 603293 + ^Content/cnc/tempicnh.mix: + Offset: 10925941 + Length: 119096 + ^Content/cnc/transit.mix: + Offset: 11078017 + Length: 3724462 + covertops: Covert Operations Expansion (English) + IDFiles: + GAME/GAME.DAT: be5a6c4c0a581da09e8f34a3bbf7bd17e525085c + CONQUER.MIX: 713b53fa4c188ca9619c6bbeadbfc86513704266 + Install: + copy: . + ^Content/cnc/scores-covertops.mix: SCORES.MIX + covertops-linux: Covert Operations Expansion (English) + IDFiles: + game/game.dat: be5a6c4c0a581da09e8f34a3bbf7bd17e525085c + conquer.mix: 713b53fa4c188ca9619c6bbeadbfc86513704266 + Install: + copy: . + ^Content/cnc/scores-covertops.mix: scores.mix diff --git a/mods/d2k/mod.yaml b/mods/d2k/mod.yaml index 293205472d..2047101b7e 100644 --- a/mods/d2k/mod.yaml +++ b/mods/d2k/mod.yaml @@ -131,23 +131,7 @@ Translations: LoadScreen: LogoStripeLoadScreen Image: d2k|uibits/loadscreen.png - Text: Filling Crates..., Breeding Sandworms..., Fuelling carryalls..., Deploying harvesters..., Preparing 'thopters..., Summoning mentats... - -ContentInstaller: - OutputFilenameCase: ForceUpper -# TODO: check if DATA.R8 is at 1.03 patch level with 4840 frames - TestFiles: ^Content/d2k/BLOXBASE.R8, ^Content/d2k/BLOXBAT.R8, ^Content/d2k/BLOXBGBS.R8, ^Content/d2k/BLOXICE.R8, ^Content/d2k/BLOXTREE.R8, ^Content/d2k/BLOXWAST.R8, ^Content/d2k/DATA.R8, ^Content/d2k/SOUND.RS, ^Content/d2k/PALETTE.BIN - PackageMirrorList: http://www.openra.net/packages/d2k-103-mirrors.txt - DiskTestFiles: music/ambush.aud, setup/setup.z - PackageToExtractFromCD: setup/setup.z - OverwriteFiles: False - ExtractFilesFromCD: - .: DUNE\Data\GAMESFX\SOUND.RS, DUNE\Data\DATA.R8, DUNE\Data\MOUSE.R8, DUNE\Data\BLOXBASE.R8, DUNE\Data\BLOXBAT.R8, DUNE\Data\BLOXBGBS.R8, DUNE\Data\BLOXICE.R8, DUNE\Data\BLOXTREE.R8, DUNE\Data\BLOXWAST.R8, DUNE\Data\bin\PALETTE.BIN - GAMESFX: DUNE\Data\GAMESFX\A_ECONF1.AUD, DUNE\Data\GAMESFX\A_ECONF2.AUD, DUNE\Data\GAMESFX\A_ECONF3.AUD, DUNE\Data\GAMESFX\A_ESEL1.AUD, DUNE\Data\GAMESFX\A_ESEL2.AUD, DUNE\Data\GAMESFX\A_ESEL3.AUD, DUNE\Data\GAMESFX\A_FCONF1.AUD, DUNE\Data\GAMESFX\A_FCONF2.AUD, DUNE\Data\GAMESFX\A_FCONF3.AUD, DUNE\Data\GAMESFX\A_FCONF4.AUD, DUNE\Data\GAMESFX\A_FSEL1.AUD, DUNE\Data\GAMESFX\A_FSEL2.AUD, DUNE\Data\GAMESFX\A_FSEL3.AUD, DUNE\Data\GAMESFX\A_FSEL4.AUD, DUNE\Data\GAMESFX\AI_1MIN.AUD, DUNE\Data\GAMESFX\AI_2MIN.AUD, DUNE\Data\GAMESFX\AI_3MIN.AUD, DUNE\Data\GAMESFX\AI_4MIN.AUD, DUNE\Data\GAMESFX\AI_5MIN.AUD, DUNE\Data\GAMESFX\AI_ABORT.AUD, DUNE\Data\GAMESFX\AI_ATACK.AUD, DUNE\Data\GAMESFX\AI_BDRDY.AUD, DUNE\Data\GAMESFX\AI_BLOST.AUD, DUNE\Data\GAMESFX\AI_BUILD.AUD, DUNE\Data\GAMESFX\AI_CANCL.AUD, DUNE\Data\GAMESFX\AI_CAPT.AUD, DUNE\Data\GAMESFX\A_ICONF1.AUD, DUNE\Data\GAMESFX\A_ICONF2.AUD, DUNE\Data\GAMESFX\A_ICONF3.AUD, DUNE\Data\GAMESFX\AI_DHRDY.AUD, DUNE\Data\GAMESFX\AI_DPLOY.AUD, DUNE\Data\GAMESFX\AI_ENEMY.AUD, DUNE\Data\GAMESFX\AI_GANEW.AUD, DUNE\Data\GAMESFX\AI_GLOAD.AUD, DUNE\Data\GAMESFX\AI_GSAVE.AUD, DUNE\Data\GAMESFX\AI_GUARD.AUD, DUNE\Data\GAMESFX\AI_HATTK.AUD, DUNE\Data\GAMESFX\AI_HOLD.AUD, DUNE\Data\GAMESFX\AI_LAUNC.AUD, DUNE\Data\GAMESFX\AI_MAP1A.AUD, DUNE\Data\GAMESFX\AI_MAP1B.AUD, DUNE\Data\GAMESFX\AI_MAP1C.AUD, DUNE\Data\GAMESFX\AI_MAP2A.AUD, DUNE\Data\GAMESFX\AI_MAP2B.AUD, DUNE\Data\GAMESFX\AI_MAP2C.AUD, DUNE\Data\GAMESFX\AI_MAP3A.AUD, DUNE\Data\GAMESFX\AI_MAP4A.AUD, DUNE\Data\GAMESFX\AI_MAP5A.AUD, DUNE\Data\GAMESFX\AI_MAP6A.AUD, DUNE\Data\GAMESFX\AI_MAP7A.AUD, DUNE\Data\GAMESFX\AI_MAP8A.AUD, DUNE\Data\GAMESFX\AI_MAP9A.AUD, DUNE\Data\GAMESFX\AI_MEND.AUD, DUNE\Data\GAMESFX\AI_MFAIL.AUD, DUNE\Data\GAMESFX\AI_MONEY.AUD, DUNE\Data\GAMESFX\AI_MWIN.AUD, DUNE\Data\GAMESFX\AI_NEWOP.AUD, DUNE\Data\GAMESFX\AI_NROOM.AUD, DUNE\Data\GAMESFX\AI_ORDER.AUD, DUNE\Data\GAMESFX\AI_PLACE.AUD, DUNE\Data\GAMESFX\AI_POWER.AUD, DUNE\Data\GAMESFX\AI_PREP.AUD, DUNE\Data\GAMESFX\AI_PRMRY.AUD, DUNE\Data\GAMESFX\AI_REINF.AUD, DUNE\Data\GAMESFX\AI_RUN.AUD, DUNE\Data\GAMESFX\A_ISEL1.AUD, DUNE\Data\GAMESFX\A_ISEL2.AUD, DUNE\Data\GAMESFX\A_ISEL3.AUD, DUNE\Data\GAMESFX\AI_SELL.AUD, DUNE\Data\GAMESFX\AI_SILOS.AUD, DUNE\Data\GAMESFX\AI_SPORT.AUD, DUNE\Data\GAMESFX\AI_TRAIN.AUD, DUNE\Data\GAMESFX\AI_ULOST.AUD, DUNE\Data\GAMESFX\AI_UNRDY.AUD, DUNE\Data\GAMESFX\AI_UPGOP.AUD, DUNE\Data\GAMESFX\AI_UPGRD.AUD, DUNE\Data\GAMESFX\AI_WATTK.AUD, DUNE\Data\GAMESFX\AI_WSIGN.AUD, DUNE\Data\GAMESFX\A_VCONF1.AUD, DUNE\Data\GAMESFX\A_VCONF2.AUD, DUNE\Data\GAMESFX\A_VCONF3.AUD, DUNE\Data\GAMESFX\A_VSEL1.AUD, DUNE\Data\GAMESFX\A_VSEL2.AUD, DUNE\Data\GAMESFX\A_VSEL3.AUD, DUNE\Data\GAMESFX\G_SCONF1.AUD, DUNE\Data\GAMESFX\G_SCONF2.AUD, DUNE\Data\GAMESFX\G_SCONF3.AUD, DUNE\Data\GAMESFX\G_SSEL1.AUD, DUNE\Data\GAMESFX\G_SSEL2.AUD, DUNE\Data\GAMESFX\G_SSEL3.AUD, DUNE\Data\GAMESFX\H_ECONF1.AUD, DUNE\Data\GAMESFX\H_ECONF2.AUD, DUNE\Data\GAMESFX\H_ECONF3.AUD, DUNE\Data\GAMESFX\H_ESEL1.AUD, DUNE\Data\GAMESFX\H_ESEL2.AUD, DUNE\Data\GAMESFX\H_ESEL3.AUD, DUNE\Data\GAMESFX\HI_1MIN.AUD, DUNE\Data\GAMESFX\HI_2MIN.AUD, DUNE\Data\GAMESFX\HI_3MIN.AUD, DUNE\Data\GAMESFX\HI_4MIN.AUD, DUNE\Data\GAMESFX\HI_5MIN.AUD, DUNE\Data\GAMESFX\HI_ABORT.AUD, DUNE\Data\GAMESFX\HI_ATACK.AUD, DUNE\Data\GAMESFX\HI_BDRDY.AUD, DUNE\Data\GAMESFX\HI_BLOST.AUD, DUNE\Data\GAMESFX\HI_BUILD.AUD, DUNE\Data\GAMESFX\HI_CANCL.AUD, DUNE\Data\GAMESFX\HI_CAPT.AUD, DUNE\Data\GAMESFX\H_ICONF1.AUD, DUNE\Data\GAMESFX\H_ICONF2.AUD, DUNE\Data\GAMESFX\H_ICONF3.AUD, DUNE\Data\GAMESFX\HI_DHRDY.AUD, DUNE\Data\GAMESFX\HI_DPLOY.AUD, DUNE\Data\GAMESFX\HI_ENEMY.AUD, DUNE\Data\GAMESFX\HI_GANEW.AUD, DUNE\Data\GAMESFX\HI_GLOAD.AUD, DUNE\Data\GAMESFX\HI_GSAVE.AUD, DUNE\Data\GAMESFX\HI_GUARD.AUD, DUNE\Data\GAMESFX\HI_HATTK.AUD, DUNE\Data\GAMESFX\HI_HOLD.AUD, DUNE\Data\GAMESFX\HI_LAUNC.AUD, DUNE\Data\GAMESFX\HI_MAP1A.AUD, DUNE\Data\GAMESFX\HI_MAP1B.AUD, DUNE\Data\GAMESFX\HI_MAP1C.AUD, DUNE\Data\GAMESFX\HI_MAP2A.AUD, DUNE\Data\GAMESFX\HI_MAP2B.AUD, DUNE\Data\GAMESFX\HI_MAP2C.AUD, DUNE\Data\GAMESFX\HI_MAP3A.AUD, DUNE\Data\GAMESFX\HI_MAP3B.AUD, DUNE\Data\GAMESFX\HI_MAP4A.AUD, DUNE\Data\GAMESFX\HI_MAP4B.AUD, DUNE\Data\GAMESFX\HI_MAP5A.AUD, DUNE\Data\GAMESFX\HI_MAP6A.AUD, DUNE\Data\GAMESFX\HI_MAP6B.AUD, DUNE\Data\GAMESFX\HI_MAP7A.AUD, DUNE\Data\GAMESFX\HI_MAP9A.AUD, DUNE\Data\GAMESFX\HI_MAP9.AUD, DUNE\Data\GAMESFX\HI_MEND.AUD, DUNE\Data\GAMESFX\HI_MFAIL.AUD, DUNE\Data\GAMESFX\HI_MONEY.AUD, DUNE\Data\GAMESFX\HI_MWIN.AUD, DUNE\Data\GAMESFX\HI_NEWOP.AUD, DUNE\Data\GAMESFX\HI_NROOM.AUD, DUNE\Data\GAMESFX\HI_ORDER.AUD, DUNE\Data\GAMESFX\HI_PLACE.AUD, DUNE\Data\GAMESFX\HI_POWER.AUD, DUNE\Data\GAMESFX\HI_PREP.AUD, DUNE\Data\GAMESFX\HI_PRMRY.AUD, DUNE\Data\GAMESFX\HI_REINF.AUD, DUNE\Data\GAMESFX\HI_RUN.AUD, DUNE\Data\GAMESFX\H_ISEL1.AUD, DUNE\Data\GAMESFX\H_ISEL2.AUD, DUNE\Data\GAMESFX\H_ISEL3.AUD, DUNE\Data\GAMESFX\HI_SELL.AUD, DUNE\Data\GAMESFX\HI_SILOS.AUD, DUNE\Data\GAMESFX\HI_SPORT.AUD, DUNE\Data\GAMESFX\HI_TRAIN.AUD, DUNE\Data\GAMESFX\HI_ULOST.AUD, DUNE\Data\GAMESFX\HI_UNRDY.AUD, DUNE\Data\GAMESFX\HI_UPGOP.AUD, DUNE\Data\GAMESFX\HI_UPGRD.AUD, DUNE\Data\GAMESFX\HI_WATTK.AUD, DUNE\Data\GAMESFX\HI_WSIGN.AUD, DUNE\Data\GAMESFX\H_VCONF1.AUD, DUNE\Data\GAMESFX\H_VCONF2.AUD, DUNE\Data\GAMESFX\H_VCONF3.AUD, DUNE\Data\GAMESFX\H_VSEL1.AUD, DUNE\Data\GAMESFX\H_VSEL2.AUD, DUNE\Data\GAMESFX\H_VSEL3.AUD, DUNE\Data\GAMESFX\O_ECONF1.AUD, DUNE\Data\GAMESFX\O_ECONF2.AUD, DUNE\Data\GAMESFX\O_ECONF3.AUD, DUNE\Data\GAMESFX\O_ESEL1.AUD, DUNE\Data\GAMESFX\O_ESEL2.AUD, DUNE\Data\GAMESFX\O_ESEL3.AUD, DUNE\Data\GAMESFX\OI_1MIN.AUD, DUNE\Data\GAMESFX\OI_2MIN.AUD, DUNE\Data\GAMESFX\OI_3MIN.AUD, DUNE\Data\GAMESFX\OI_4MIN.AUD, DUNE\Data\GAMESFX\OI_5MIN.AUD, DUNE\Data\GAMESFX\OI_ABORT.AUD, DUNE\Data\GAMESFX\OI_ATACK.AUD, DUNE\Data\GAMESFX\OI_BDRDY.AUD, DUNE\Data\GAMESFX\OI_BLOST.AUD, DUNE\Data\GAMESFX\OI_BUILD.AUD, DUNE\Data\GAMESFX\OI_CANCL.AUD, DUNE\Data\GAMESFX\OI_CAPT.AUD, DUNE\Data\GAMESFX\O_ICONF1.AUD, DUNE\Data\GAMESFX\O_ICONF2.AUD, DUNE\Data\GAMESFX\O_ICONF3.AUD, DUNE\Data\GAMESFX\OI_DHRDY.AUD, DUNE\Data\GAMESFX\OI_DPLOY.AUD, DUNE\Data\GAMESFX\OI_ENEMY.AUD, DUNE\Data\GAMESFX\OI_GANEW.AUD, DUNE\Data\GAMESFX\OI_GLOAD.AUD, DUNE\Data\GAMESFX\OI_GSAVE.AUD, DUNE\Data\GAMESFX\OI_GUARD.AUD, DUNE\Data\GAMESFX\OI_HATTK.AUD, DUNE\Data\GAMESFX\OI_HOLD.AUD, DUNE\Data\GAMESFX\OI_LAUNC.AUD, DUNE\Data\GAMESFX\OI_MAP1A.AUD, DUNE\Data\GAMESFX\OI_MAP1B.AUD, DUNE\Data\GAMESFX\OI_MAP1C.AUD, DUNE\Data\GAMESFX\OI_MAP2A.AUD, DUNE\Data\GAMESFX\OI_MAP2B.AUD, DUNE\Data\GAMESFX\OI_MAP2C.AUD, DUNE\Data\GAMESFX\OI_MAP3A.AUD, DUNE\Data\GAMESFX\OI_MAP4A.AUD, DUNE\Data\GAMESFX\OI_MAP5A.AUD, DUNE\Data\GAMESFX\OI_MAP6A.AUD, DUNE\Data\GAMESFX\OI_MAP7A.AUD, DUNE\Data\GAMESFX\OI_MAP8A.AUD, DUNE\Data\GAMESFX\OI_MAP9A.AUD, DUNE\Data\GAMESFX\OI_MEND.AUD, DUNE\Data\GAMESFX\OI_MFAIL.AUD, DUNE\Data\GAMESFX\OI_MONEY.AUD, DUNE\Data\GAMESFX\OI_MWIN.AUD, DUNE\Data\GAMESFX\OI_NEWOP.AUD, DUNE\Data\GAMESFX\OI_NROOM.AUD, DUNE\Data\GAMESFX\OI_ORDER.AUD, DUNE\Data\GAMESFX\OI_PLACE.AUD, DUNE\Data\GAMESFX\OI_POWER.AUD, DUNE\Data\GAMESFX\OI_PREP.AUD, DUNE\Data\GAMESFX\OI_PRMRY.AUD, DUNE\Data\GAMESFX\OI_REINF.AUD, DUNE\Data\GAMESFX\OI_RUN.AUD, DUNE\Data\GAMESFX\O_ISEL1.AUD, DUNE\Data\GAMESFX\O_ISEL2.AUD, DUNE\Data\GAMESFX\O_ISEL3.AUD, DUNE\Data\GAMESFX\OI_SELL.AUD, DUNE\Data\GAMESFX\OI_SILOS.AUD, DUNE\Data\GAMESFX\OI_SPORT.AUD, DUNE\Data\GAMESFX\OI_TRAIN.AUD, DUNE\Data\GAMESFX\OI_ULOST.AUD, DUNE\Data\GAMESFX\OI_UNRDY.AUD, DUNE\Data\GAMESFX\OI_UPGOP.AUD, DUNE\Data\GAMESFX\OI_UPGRD.AUD, DUNE\Data\GAMESFX\OI_WATTK.AUD, DUNE\Data\GAMESFX\OI_WSIGN.AUD, DUNE\Data\GAMESFX\O_SCONF1.AUD, DUNE\Data\GAMESFX\O_SCONF2.AUD, DUNE\Data\GAMESFX\O_SCONF3.AUD, DUNE\Data\GAMESFX\O_SSEL1.AUD, DUNE\Data\GAMESFX\O_SSEL2.AUD, DUNE\Data\GAMESFX\O_SSEL3.AUD, DUNE\Data\GAMESFX\O_VCONF1.AUD, DUNE\Data\GAMESFX\O_VCONF2.AUD, DUNE\Data\GAMESFX\O_VCONF3.AUD, DUNE\Data\GAMESFX\O_VSEL1.AUD, DUNE\Data\GAMESFX\O_VSEL2.AUD, DUNE\Data\GAMESFX\O_VSEL3.AUD - CopyFilesFromCD: - Movies: movies/a_br01_e.vqa, movies/a_br02_e.vqa, movies/a_br03_e.vqa, movies/a_br04_e.vqa, movies/a_br05_e.vqa, movies/a_br06_e.vqa, movies/a_br07_e.vqa, movies/a_br08_e.vqa, movies/a_br09_e.vqa, movies/a_finl_e.vqa, movies/a_lose_e.vqa, movies/a_mntg_e.vqa, movies/h_br01_e.vqa, movies/h_br02_e.vqa, movies/h_br03_e.vqa, movies/h_br04_e.vqa, movies/h_br05_e.vqa, movies/h_br06_e.vqa, movies/h_br07_e.vqa, movies/h_br08_e.vqa, movies/h_br09_e.vqa, movies/h_finl_e.vqa, movies/h_lose_e.vqa, movies/h_mntg_e.vqa, movies/o_br01_e.vqa, movies/o_br02_e.vqa, movies/o_br03_e.vqa, movies/o_br04_e.vqa, movies/o_br05_e.vqa, movies/o_br06_e.vqa, movies/o_br07_e.vqa, movies/o_br08_e.vqa, movies/o_br09_e.vqa, movies/o_finl_e.vqa, movies/o_lose_e.vqa, movies/o_mntg_e.vqa, movies/g_int1_e.vqa, movies/g_int2_e.vqa, movies/g_maps_e.vqa, movies/g_pln2_e.vqa, movies/g_plnt_e.vqa, movies/t_titl_e.vqa - Music: music/ambush.aud, music/arakatak.aud, music/atregain.aud, music/entordos.aud, music/fightpwr.aud, music/fremen.aud, music/hark_bat.aud, music/landsand.aud, music/options.aud, music/plotting.aud, music/risehark.aud, music/robotix.aud, music/score.aud, music/soldappr.aud, music/spicesct.aud, music/undercon.aud, music/waitgame.aud - ShippedSoundtracks: 1 + Text: Filling Crates..., Breeding Sandworms..., Fuelling carryalls..., Deploying harvesters..., Preparing thopters..., Summoning mentats... ServerTraits: LobbyCommands @@ -215,3 +199,1986 @@ GameSpeeds: OrderLatency: 6 ColorValidator: + +ModContent: + InstallPromptMessage: Dune 2000 requires artwork and audio from the original game.\n\nQuick Install will automatically download this content (without\nmusic or videos) from an online mirror of the game files.\n\nAdvanced Install includes options for copying the music, videos,\nand other content from an original game disc. + QuickDownload: basefiles + HeaderMessage: The original game content may be copied from an original game disc,\nor downloaded from an online mirror of the game files. + Packages: + base: Base Game Files + TestFiles: ^Content/d2k/BLOXBASE.R8, ^Content/d2k/BLOXBAT.R8, ^Content/d2k/BLOXBGBS.R8, ^Content/d2k/BLOXICE.R8, ^Content/d2k/BLOXTREE.R8, ^Content/d2k/BLOXWAST.R8, ^Content/d2k/DATA.R8, ^Content/d2k/SOUND.RS, ^Content/d2k/PALETTE.BIN + Discs: d2k, d2k-linux + Required: true + Download: basefiles + music: Game Music + TestFiles: ^Content/d2k/Music/AMBUSH.AUD + Discs: d2k, d2k-linux + movies: Campaign Briefings + TestFiles: ^Content/d2k/Movies/A_BR01_E.VQA + Discs: d2k, d2k-linux + Downloads: + basefiles: Base Content + MirrorList: http://www.openra.net/packages/d2k-103-mirrors.txt + Extract: + ^Content/d2k/BLOXBASE.R8: BLOXBASE.R8 + ^Content/d2k/BLOXBAT.R8: BLOXBAT.R8 + ^Content/d2k/BLOXBGBS.R8: BLOXBGBS.R8 + ^Content/d2k/BLOXICE.R8: BLOXICE.R8 + ^Content/d2k/BLOXTREE.R8: BLOXTREE.R8 + ^Content/d2k/BLOXWAST.R8: BLOXWAST.R8 + ^Content/d2k/DATA.R8: DATA.R8 + ^Content/d2k/MOUSE.R8: MOUSE.R8 + ^Content/d2k/PALETTE.BIN: PALETTE.BIN + ^Content/d2k/SOUND.RS: SOUND.RS + ^Content/d2k/GAMESFX/AI_1MIN.AUD: GAMESFX/AI_1MIN.AUD + ^Content/d2k/GAMESFX/AI_2MIN.AUD: GAMESFX/AI_2MIN.AUD + ^Content/d2k/GAMESFX/AI_3MIN.AUD: GAMESFX/AI_3MIN.AUD + ^Content/d2k/GAMESFX/AI_4MIN.AUD: GAMESFX/AI_4MIN.AUD + ^Content/d2k/GAMESFX/AI_5MIN.AUD: GAMESFX/AI_5MIN.AUD + ^Content/d2k/GAMESFX/AI_ABORT.AUD: GAMESFX/AI_ABORT.AUD + ^Content/d2k/GAMESFX/AI_ATACK.AUD: GAMESFX/AI_ATACK.AUD + ^Content/d2k/GAMESFX/AI_BDRDY.AUD: GAMESFX/AI_BDRDY.AUD + ^Content/d2k/GAMESFX/AI_BLOST.AUD: GAMESFX/AI_BLOST.AUD + ^Content/d2k/GAMESFX/AI_BUILD.AUD: GAMESFX/AI_BUILD.AUD + ^Content/d2k/GAMESFX/AI_CANCL.AUD: GAMESFX/AI_CANCL.AUD + ^Content/d2k/GAMESFX/AI_CAPT.AUD: GAMESFX/AI_CAPT.AUD + ^Content/d2k/GAMESFX/AI_DHRDY.AUD: GAMESFX/AI_DHRDY.AUD + ^Content/d2k/GAMESFX/AI_DPLOY.AUD: GAMESFX/AI_DPLOY.AUD + ^Content/d2k/GAMESFX/AI_ENEMY.AUD: GAMESFX/AI_ENEMY.AUD + ^Content/d2k/GAMESFX/AI_GANEW.AUD: GAMESFX/AI_GANEW.AUD + ^Content/d2k/GAMESFX/AI_GLOAD.AUD: GAMESFX/AI_GLOAD.AUD + ^Content/d2k/GAMESFX/AI_GSAVE.AUD: GAMESFX/AI_GSAVE.AUD + ^Content/d2k/GAMESFX/AI_GUARD.AUD: GAMESFX/AI_GUARD.AUD + ^Content/d2k/GAMESFX/AI_HATTK.AUD: GAMESFX/AI_HATTK.AUD + ^Content/d2k/GAMESFX/AI_HOLD.AUD: GAMESFX/AI_HOLD.AUD + ^Content/d2k/GAMESFX/AI_LAUNC.AUD: GAMESFX/AI_LAUNC.AUD + ^Content/d2k/GAMESFX/AI_MAP1A.AUD: GAMESFX/AI_MAP1A.AUD + ^Content/d2k/GAMESFX/AI_MAP1B.AUD: GAMESFX/AI_MAP1B.AUD + ^Content/d2k/GAMESFX/AI_MAP1C.AUD: GAMESFX/AI_MAP1C.AUD + ^Content/d2k/GAMESFX/AI_MAP2A.AUD: GAMESFX/AI_MAP2A.AUD + ^Content/d2k/GAMESFX/AI_MAP2B.AUD: GAMESFX/AI_MAP2B.AUD + ^Content/d2k/GAMESFX/AI_MAP2C.AUD: GAMESFX/AI_MAP2C.AUD + ^Content/d2k/GAMESFX/AI_MAP3A.AUD: GAMESFX/AI_MAP3A.AUD + ^Content/d2k/GAMESFX/AI_MAP4A.AUD: GAMESFX/AI_MAP4A.AUD + ^Content/d2k/GAMESFX/AI_MAP5A.AUD: GAMESFX/AI_MAP5A.AUD + ^Content/d2k/GAMESFX/AI_MAP6A.AUD: GAMESFX/AI_MAP6A.AUD + ^Content/d2k/GAMESFX/AI_MAP7A.AUD: GAMESFX/AI_MAP7A.AUD + ^Content/d2k/GAMESFX/AI_MAP8A.AUD: GAMESFX/AI_MAP8A.AUD + ^Content/d2k/GAMESFX/AI_MAP9A.AUD: GAMESFX/AI_MAP9A.AUD + ^Content/d2k/GAMESFX/AI_MEND.AUD: GAMESFX/AI_MEND.AUD + ^Content/d2k/GAMESFX/AI_MFAIL.AUD: GAMESFX/AI_MFAIL.AUD + ^Content/d2k/GAMESFX/AI_MONEY.AUD: GAMESFX/AI_MONEY.AUD + ^Content/d2k/GAMESFX/AI_MWIN.AUD: GAMESFX/AI_MWIN.AUD + ^Content/d2k/GAMESFX/AI_NEWOP.AUD: GAMESFX/AI_NEWOP.AUD + ^Content/d2k/GAMESFX/AI_NROOM.AUD: GAMESFX/AI_NROOM.AUD + ^Content/d2k/GAMESFX/AI_ORDER.AUD: GAMESFX/AI_ORDER.AUD + ^Content/d2k/GAMESFX/AI_PLACE.AUD: GAMESFX/AI_PLACE.AUD + ^Content/d2k/GAMESFX/AI_POWER.AUD: GAMESFX/AI_POWER.AUD + ^Content/d2k/GAMESFX/AI_PREP.AUD: GAMESFX/AI_PREP.AUD + ^Content/d2k/GAMESFX/AI_PRMRY.AUD: GAMESFX/AI_PRMRY.AUD + ^Content/d2k/GAMESFX/AI_REINF.AUD: GAMESFX/AI_REINF.AUD + ^Content/d2k/GAMESFX/AI_RUN.AUD: GAMESFX/AI_RUN.AUD + ^Content/d2k/GAMESFX/AI_SELL.AUD: GAMESFX/AI_SELL.AUD + ^Content/d2k/GAMESFX/AI_SILOS.AUD: GAMESFX/AI_SILOS.AUD + ^Content/d2k/GAMESFX/AI_SPORT.AUD: GAMESFX/AI_SPORT.AUD + ^Content/d2k/GAMESFX/AI_TRAIN.AUD: GAMESFX/AI_TRAIN.AUD + ^Content/d2k/GAMESFX/AI_ULOST.AUD: GAMESFX/AI_ULOST.AUD + ^Content/d2k/GAMESFX/AI_UNRDY.AUD: GAMESFX/AI_UNRDY.AUD + ^Content/d2k/GAMESFX/AI_UPGOP.AUD: GAMESFX/AI_UPGOP.AUD + ^Content/d2k/GAMESFX/AI_UPGRD.AUD: GAMESFX/AI_UPGRD.AUD + ^Content/d2k/GAMESFX/AI_WATTK.AUD: GAMESFX/AI_WATTK.AUD + ^Content/d2k/GAMESFX/AI_WSIGN.AUD: GAMESFX/AI_WSIGN.AUD + ^Content/d2k/GAMESFX/A_ECONF1.AUD: GAMESFX/A_ECONF1.AUD + ^Content/d2k/GAMESFX/A_ECONF2.AUD: GAMESFX/A_ECONF2.AUD + ^Content/d2k/GAMESFX/A_ECONF3.AUD: GAMESFX/A_ECONF3.AUD + ^Content/d2k/GAMESFX/A_ESEL1.AUD: GAMESFX/A_ESEL1.AUD + ^Content/d2k/GAMESFX/A_ESEL2.AUD: GAMESFX/A_ESEL2.AUD + ^Content/d2k/GAMESFX/A_ESEL3.AUD: GAMESFX/A_ESEL3.AUD + ^Content/d2k/GAMESFX/A_FCONF1.AUD: GAMESFX/A_FCONF1.AUD + ^Content/d2k/GAMESFX/A_FCONF2.AUD: GAMESFX/A_FCONF2.AUD + ^Content/d2k/GAMESFX/A_FCONF3.AUD: GAMESFX/A_FCONF3.AUD + ^Content/d2k/GAMESFX/A_FCONF4.AUD: GAMESFX/A_FCONF4.AUD + ^Content/d2k/GAMESFX/A_FSEL1.AUD: GAMESFX/A_FSEL1.AUD + ^Content/d2k/GAMESFX/A_FSEL2.AUD: GAMESFX/A_FSEL2.AUD + ^Content/d2k/GAMESFX/A_FSEL3.AUD: GAMESFX/A_FSEL3.AUD + ^Content/d2k/GAMESFX/A_FSEL4.AUD: GAMESFX/A_FSEL4.AUD + ^Content/d2k/GAMESFX/A_ICONF1.AUD: GAMESFX/A_ICONF1.AUD + ^Content/d2k/GAMESFX/A_ICONF2.AUD: GAMESFX/A_ICONF2.AUD + ^Content/d2k/GAMESFX/A_ICONF3.AUD: GAMESFX/A_ICONF3.AUD + ^Content/d2k/GAMESFX/A_ISEL1.AUD: GAMESFX/A_ISEL1.AUD + ^Content/d2k/GAMESFX/A_ISEL2.AUD: GAMESFX/A_ISEL2.AUD + ^Content/d2k/GAMESFX/A_ISEL3.AUD: GAMESFX/A_ISEL3.AUD + ^Content/d2k/GAMESFX/A_VCONF1.AUD: GAMESFX/A_VCONF1.AUD + ^Content/d2k/GAMESFX/A_VCONF2.AUD: GAMESFX/A_VCONF2.AUD + ^Content/d2k/GAMESFX/A_VCONF3.AUD: GAMESFX/A_VCONF3.AUD + ^Content/d2k/GAMESFX/A_VSEL1.AUD: GAMESFX/A_VSEL1.AUD + ^Content/d2k/GAMESFX/A_VSEL2.AUD: GAMESFX/A_VSEL2.AUD + ^Content/d2k/GAMESFX/A_VSEL3.AUD: GAMESFX/A_VSEL3.AUD + ^Content/d2k/GAMESFX/G_SCONF1.AUD: GAMESFX/G_SCONF1.AUD + ^Content/d2k/GAMESFX/G_SCONF2.AUD: GAMESFX/G_SCONF2.AUD + ^Content/d2k/GAMESFX/G_SCONF3.AUD: GAMESFX/G_SCONF3.AUD + ^Content/d2k/GAMESFX/G_SSEL1.AUD: GAMESFX/G_SSEL1.AUD + ^Content/d2k/GAMESFX/G_SSEL2.AUD: GAMESFX/G_SSEL2.AUD + ^Content/d2k/GAMESFX/G_SSEL3.AUD: GAMESFX/G_SSEL3.AUD + ^Content/d2k/GAMESFX/HI_1MIN.AUD: GAMESFX/HI_1MIN.AUD + ^Content/d2k/GAMESFX/HI_2MIN.AUD: GAMESFX/HI_2MIN.AUD + ^Content/d2k/GAMESFX/HI_3MIN.AUD: GAMESFX/HI_3MIN.AUD + ^Content/d2k/GAMESFX/HI_4MIN.AUD: GAMESFX/HI_4MIN.AUD + ^Content/d2k/GAMESFX/HI_5MIN.AUD: GAMESFX/HI_5MIN.AUD + ^Content/d2k/GAMESFX/HI_ABORT.AUD: GAMESFX/HI_ABORT.AUD + ^Content/d2k/GAMESFX/HI_ATACK.AUD: GAMESFX/HI_ATACK.AUD + ^Content/d2k/GAMESFX/HI_BDRDY.AUD: GAMESFX/HI_BDRDY.AUD + ^Content/d2k/GAMESFX/HI_BLOST.AUD: GAMESFX/HI_BLOST.AUD + ^Content/d2k/GAMESFX/HI_BUILD.AUD: GAMESFX/HI_BUILD.AUD + ^Content/d2k/GAMESFX/HI_CANCL.AUD: GAMESFX/HI_CANCL.AUD + ^Content/d2k/GAMESFX/HI_CAPT.AUD: GAMESFX/HI_CAPT.AUD + ^Content/d2k/GAMESFX/HI_DHRDY.AUD: GAMESFX/HI_DHRDY.AUD + ^Content/d2k/GAMESFX/HI_DPLOY.AUD: GAMESFX/HI_DPLOY.AUD + ^Content/d2k/GAMESFX/HI_ENEMY.AUD: GAMESFX/HI_ENEMY.AUD + ^Content/d2k/GAMESFX/HI_GANEW.AUD: GAMESFX/HI_GANEW.AUD + ^Content/d2k/GAMESFX/HI_GLOAD.AUD: GAMESFX/HI_GLOAD.AUD + ^Content/d2k/GAMESFX/HI_GSAVE.AUD: GAMESFX/HI_GSAVE.AUD + ^Content/d2k/GAMESFX/HI_GUARD.AUD: GAMESFX/HI_GUARD.AUD + ^Content/d2k/GAMESFX/HI_HATTK.AUD: GAMESFX/HI_HATTK.AUD + ^Content/d2k/GAMESFX/HI_HOLD.AUD: GAMESFX/HI_HOLD.AUD + ^Content/d2k/GAMESFX/HI_LAUNC.AUD: GAMESFX/HI_LAUNC.AUD + ^Content/d2k/GAMESFX/HI_MAP1A.AUD: GAMESFX/HI_MAP1A.AUD + ^Content/d2k/GAMESFX/HI_MAP1B.AUD: GAMESFX/HI_MAP1B.AUD + ^Content/d2k/GAMESFX/HI_MAP1C.AUD: GAMESFX/HI_MAP1C.AUD + ^Content/d2k/GAMESFX/HI_MAP2A.AUD: GAMESFX/HI_MAP2A.AUD + ^Content/d2k/GAMESFX/HI_MAP2B.AUD: GAMESFX/HI_MAP2B.AUD + ^Content/d2k/GAMESFX/HI_MAP2C.AUD: GAMESFX/HI_MAP2C.AUD + ^Content/d2k/GAMESFX/HI_MAP3A.AUD: GAMESFX/HI_MAP3A.AUD + ^Content/d2k/GAMESFX/HI_MAP3B.AUD: GAMESFX/HI_MAP3B.AUD + ^Content/d2k/GAMESFX/HI_MAP4A.AUD: GAMESFX/HI_MAP4A.AUD + ^Content/d2k/GAMESFX/HI_MAP4B.AUD: GAMESFX/HI_MAP4B.AUD + ^Content/d2k/GAMESFX/HI_MAP5A.AUD: GAMESFX/HI_MAP5A.AUD + ^Content/d2k/GAMESFX/HI_MAP6A.AUD: GAMESFX/HI_MAP6A.AUD + ^Content/d2k/GAMESFX/HI_MAP6B.AUD: GAMESFX/HI_MAP6B.AUD + ^Content/d2k/GAMESFX/HI_MAP7A.AUD: GAMESFX/HI_MAP7A.AUD + ^Content/d2k/GAMESFX/HI_MAP9.AUD: GAMESFX/HI_MAP9.AUD + ^Content/d2k/GAMESFX/HI_MAP9A.AUD: GAMESFX/HI_MAP9A.AUD + ^Content/d2k/GAMESFX/HI_MEND.AUD: GAMESFX/HI_MEND.AUD + ^Content/d2k/GAMESFX/HI_MFAIL.AUD: GAMESFX/HI_MFAIL.AUD + ^Content/d2k/GAMESFX/HI_MONEY.AUD: GAMESFX/HI_MONEY.AUD + ^Content/d2k/GAMESFX/HI_MWIN.AUD: GAMESFX/HI_MWIN.AUD + ^Content/d2k/GAMESFX/HI_NEWOP.AUD: GAMESFX/HI_NEWOP.AUD + ^Content/d2k/GAMESFX/HI_NROOM.AUD: GAMESFX/HI_NROOM.AUD + ^Content/d2k/GAMESFX/HI_ORDER.AUD: GAMESFX/HI_ORDER.AUD + ^Content/d2k/GAMESFX/HI_PLACE.AUD: GAMESFX/HI_PLACE.AUD + ^Content/d2k/GAMESFX/HI_POWER.AUD: GAMESFX/HI_POWER.AUD + ^Content/d2k/GAMESFX/HI_PREP.AUD: GAMESFX/HI_PREP.AUD + ^Content/d2k/GAMESFX/HI_PRMRY.AUD: GAMESFX/HI_PRMRY.AUD + ^Content/d2k/GAMESFX/HI_REINF.AUD: GAMESFX/HI_REINF.AUD + ^Content/d2k/GAMESFX/HI_RUN.AUD: GAMESFX/HI_RUN.AUD + ^Content/d2k/GAMESFX/HI_SELL.AUD: GAMESFX/HI_SELL.AUD + ^Content/d2k/GAMESFX/HI_SILOS.AUD: GAMESFX/HI_SILOS.AUD + ^Content/d2k/GAMESFX/HI_SPORT.AUD: GAMESFX/HI_SPORT.AUD + ^Content/d2k/GAMESFX/HI_TRAIN.AUD: GAMESFX/HI_TRAIN.AUD + ^Content/d2k/GAMESFX/HI_ULOST.AUD: GAMESFX/HI_ULOST.AUD + ^Content/d2k/GAMESFX/HI_UNRDY.AUD: GAMESFX/HI_UNRDY.AUD + ^Content/d2k/GAMESFX/HI_UPGOP.AUD: GAMESFX/HI_UPGOP.AUD + ^Content/d2k/GAMESFX/HI_UPGRD.AUD: GAMESFX/HI_UPGRD.AUD + ^Content/d2k/GAMESFX/HI_WATTK.AUD: GAMESFX/HI_WATTK.AUD + ^Content/d2k/GAMESFX/HI_WSIGN.AUD: GAMESFX/HI_WSIGN.AUD + ^Content/d2k/GAMESFX/H_ECONF1.AUD: GAMESFX/H_ECONF1.AUD + ^Content/d2k/GAMESFX/H_ECONF2.AUD: GAMESFX/H_ECONF2.AUD + ^Content/d2k/GAMESFX/H_ECONF3.AUD: GAMESFX/H_ECONF3.AUD + ^Content/d2k/GAMESFX/H_ESEL1.AUD: GAMESFX/H_ESEL1.AUD + ^Content/d2k/GAMESFX/H_ESEL2.AUD: GAMESFX/H_ESEL2.AUD + ^Content/d2k/GAMESFX/H_ESEL3.AUD: GAMESFX/H_ESEL3.AUD + ^Content/d2k/GAMESFX/H_ICONF1.AUD: GAMESFX/H_ICONF1.AUD + ^Content/d2k/GAMESFX/H_ICONF2.AUD: GAMESFX/H_ICONF2.AUD + ^Content/d2k/GAMESFX/H_ICONF3.AUD: GAMESFX/H_ICONF3.AUD + ^Content/d2k/GAMESFX/H_ISEL1.AUD: GAMESFX/H_ISEL1.AUD + ^Content/d2k/GAMESFX/H_ISEL2.AUD: GAMESFX/H_ISEL2.AUD + ^Content/d2k/GAMESFX/H_ISEL3.AUD: GAMESFX/H_ISEL3.AUD + ^Content/d2k/GAMESFX/H_VCONF1.AUD: GAMESFX/H_VCONF1.AUD + ^Content/d2k/GAMESFX/H_VCONF2.AUD: GAMESFX/H_VCONF2.AUD + ^Content/d2k/GAMESFX/H_VCONF3.AUD: GAMESFX/H_VCONF3.AUD + ^Content/d2k/GAMESFX/H_VSEL1.AUD: GAMESFX/H_VSEL1.AUD + ^Content/d2k/GAMESFX/H_VSEL2.AUD: GAMESFX/H_VSEL2.AUD + ^Content/d2k/GAMESFX/H_VSEL3.AUD: GAMESFX/H_VSEL3.AUD + ^Content/d2k/GAMESFX/OI_1MIN.AUD: GAMESFX/OI_1MIN.AUD + ^Content/d2k/GAMESFX/OI_2MIN.AUD: GAMESFX/OI_2MIN.AUD + ^Content/d2k/GAMESFX/OI_3MIN.AUD: GAMESFX/OI_3MIN.AUD + ^Content/d2k/GAMESFX/OI_4MIN.AUD: GAMESFX/OI_4MIN.AUD + ^Content/d2k/GAMESFX/OI_5MIN.AUD: GAMESFX/OI_5MIN.AUD + ^Content/d2k/GAMESFX/OI_ABORT.AUD: GAMESFX/OI_ABORT.AUD + ^Content/d2k/GAMESFX/OI_ATACK.AUD: GAMESFX/OI_ATACK.AUD + ^Content/d2k/GAMESFX/OI_BDRDY.AUD: GAMESFX/OI_BDRDY.AUD + ^Content/d2k/GAMESFX/OI_BLOST.AUD: GAMESFX/OI_BLOST.AUD + ^Content/d2k/GAMESFX/OI_BUILD.AUD: GAMESFX/OI_BUILD.AUD + ^Content/d2k/GAMESFX/OI_CANCL.AUD: GAMESFX/OI_CANCL.AUD + ^Content/d2k/GAMESFX/OI_CAPT.AUD: GAMESFX/OI_CAPT.AUD + ^Content/d2k/GAMESFX/OI_DHRDY.AUD: GAMESFX/OI_DHRDY.AUD + ^Content/d2k/GAMESFX/OI_DPLOY.AUD: GAMESFX/OI_DPLOY.AUD + ^Content/d2k/GAMESFX/OI_ENEMY.AUD: GAMESFX/OI_ENEMY.AUD + ^Content/d2k/GAMESFX/OI_GANEW.AUD: GAMESFX/OI_GANEW.AUD + ^Content/d2k/GAMESFX/OI_GLOAD.AUD: GAMESFX/OI_GLOAD.AUD + ^Content/d2k/GAMESFX/OI_GSAVE.AUD: GAMESFX/OI_GSAVE.AUD + ^Content/d2k/GAMESFX/OI_GUARD.AUD: GAMESFX/OI_GUARD.AUD + ^Content/d2k/GAMESFX/OI_HATTK.AUD: GAMESFX/OI_HATTK.AUD + ^Content/d2k/GAMESFX/OI_HOLD.AUD: GAMESFX/OI_HOLD.AUD + ^Content/d2k/GAMESFX/OI_LAUNC.AUD: GAMESFX/OI_LAUNC.AUD + ^Content/d2k/GAMESFX/OI_MAP1A.AUD: GAMESFX/OI_MAP1A.AUD + ^Content/d2k/GAMESFX/OI_MAP1B.AUD: GAMESFX/OI_MAP1B.AUD + ^Content/d2k/GAMESFX/OI_MAP1C.AUD: GAMESFX/OI_MAP1C.AUD + ^Content/d2k/GAMESFX/OI_MAP2A.AUD: GAMESFX/OI_MAP2A.AUD + ^Content/d2k/GAMESFX/OI_MAP2B.AUD: GAMESFX/OI_MAP2B.AUD + ^Content/d2k/GAMESFX/OI_MAP2C.AUD: GAMESFX/OI_MAP2C.AUD + ^Content/d2k/GAMESFX/OI_MAP3A.AUD: GAMESFX/OI_MAP3A.AUD + ^Content/d2k/GAMESFX/OI_MAP4A.AUD: GAMESFX/OI_MAP4A.AUD + ^Content/d2k/GAMESFX/OI_MAP5A.AUD: GAMESFX/OI_MAP5A.AUD + ^Content/d2k/GAMESFX/OI_MAP6A.AUD: GAMESFX/OI_MAP6A.AUD + ^Content/d2k/GAMESFX/OI_MAP7A.AUD: GAMESFX/OI_MAP7A.AUD + ^Content/d2k/GAMESFX/OI_MAP8A.AUD: GAMESFX/OI_MAP8A.AUD + ^Content/d2k/GAMESFX/OI_MAP9A.AUD: GAMESFX/OI_MAP9A.AUD + ^Content/d2k/GAMESFX/OI_MEND.AUD: GAMESFX/OI_MEND.AUD + ^Content/d2k/GAMESFX/OI_MFAIL.AUD: GAMESFX/OI_MFAIL.AUD + ^Content/d2k/GAMESFX/OI_MONEY.AUD: GAMESFX/OI_MONEY.AUD + ^Content/d2k/GAMESFX/OI_MWIN.AUD: GAMESFX/OI_MWIN.AUD + ^Content/d2k/GAMESFX/OI_NEWOP.AUD: GAMESFX/OI_NEWOP.AUD + ^Content/d2k/GAMESFX/OI_NROOM.AUD: GAMESFX/OI_NROOM.AUD + ^Content/d2k/GAMESFX/OI_ORDER.AUD: GAMESFX/OI_ORDER.AUD + ^Content/d2k/GAMESFX/OI_PLACE.AUD: GAMESFX/OI_PLACE.AUD + ^Content/d2k/GAMESFX/OI_POWER.AUD: GAMESFX/OI_POWER.AUD + ^Content/d2k/GAMESFX/OI_PREP.AUD: GAMESFX/OI_PREP.AUD + ^Content/d2k/GAMESFX/OI_PRMRY.AUD: GAMESFX/OI_PRMRY.AUD + ^Content/d2k/GAMESFX/OI_REINF.AUD: GAMESFX/OI_REINF.AUD + ^Content/d2k/GAMESFX/OI_RUN.AUD: GAMESFX/OI_RUN.AUD + ^Content/d2k/GAMESFX/OI_SELL.AUD: GAMESFX/OI_SELL.AUD + ^Content/d2k/GAMESFX/OI_SILOS.AUD: GAMESFX/OI_SILOS.AUD + ^Content/d2k/GAMESFX/OI_SPORT.AUD: GAMESFX/OI_SPORT.AUD + ^Content/d2k/GAMESFX/OI_TRAIN.AUD: GAMESFX/OI_TRAIN.AUD + ^Content/d2k/GAMESFX/OI_ULOST.AUD: GAMESFX/OI_ULOST.AUD + ^Content/d2k/GAMESFX/OI_UNRDY.AUD: GAMESFX/OI_UNRDY.AUD + ^Content/d2k/GAMESFX/OI_UPGOP.AUD: GAMESFX/OI_UPGOP.AUD + ^Content/d2k/GAMESFX/OI_UPGRD.AUD: GAMESFX/OI_UPGRD.AUD + ^Content/d2k/GAMESFX/OI_WATTK.AUD: GAMESFX/OI_WATTK.AUD + ^Content/d2k/GAMESFX/OI_WSIGN.AUD: GAMESFX/OI_WSIGN.AUD + ^Content/d2k/GAMESFX/O_ECONF1.AUD: GAMESFX/O_ECONF1.AUD + ^Content/d2k/GAMESFX/O_ECONF2.AUD: GAMESFX/O_ECONF2.AUD + ^Content/d2k/GAMESFX/O_ECONF3.AUD: GAMESFX/O_ECONF3.AUD + ^Content/d2k/GAMESFX/O_ESEL1.AUD: GAMESFX/O_ESEL1.AUD + ^Content/d2k/GAMESFX/O_ESEL2.AUD: GAMESFX/O_ESEL2.AUD + ^Content/d2k/GAMESFX/O_ESEL3.AUD: GAMESFX/O_ESEL3.AUD + ^Content/d2k/GAMESFX/O_ICONF1.AUD: GAMESFX/O_ICONF1.AUD + ^Content/d2k/GAMESFX/O_ICONF2.AUD: GAMESFX/O_ICONF2.AUD + ^Content/d2k/GAMESFX/O_ICONF3.AUD: GAMESFX/O_ICONF3.AUD + ^Content/d2k/GAMESFX/O_ISEL1.AUD: GAMESFX/O_ISEL1.AUD + ^Content/d2k/GAMESFX/O_ISEL2.AUD: GAMESFX/O_ISEL2.AUD + ^Content/d2k/GAMESFX/O_ISEL3.AUD: GAMESFX/O_ISEL3.AUD + ^Content/d2k/GAMESFX/O_SCONF1.AUD: GAMESFX/O_SCONF1.AUD + ^Content/d2k/GAMESFX/O_SCONF2.AUD: GAMESFX/O_SCONF2.AUD + ^Content/d2k/GAMESFX/O_SCONF3.AUD: GAMESFX/O_SCONF3.AUD + ^Content/d2k/GAMESFX/O_SSEL1.AUD: GAMESFX/O_SSEL1.AUD + ^Content/d2k/GAMESFX/O_SSEL2.AUD: GAMESFX/O_SSEL2.AUD + ^Content/d2k/GAMESFX/O_SSEL3.AUD: GAMESFX/O_SSEL3.AUD + ^Content/d2k/GAMESFX/O_VCONF1.AUD: GAMESFX/O_VCONF1.AUD + ^Content/d2k/GAMESFX/O_VCONF2.AUD: GAMESFX/O_VCONF2.AUD + ^Content/d2k/GAMESFX/O_VCONF3.AUD: GAMESFX/O_VCONF3.AUD + ^Content/d2k/GAMESFX/O_VSEL1.AUD: GAMESFX/O_VSEL1.AUD + ^Content/d2k/GAMESFX/O_VSEL2.AUD: GAMESFX/O_VSEL2.AUD + ^Content/d2k/GAMESFX/O_VSEL3.AUD: GAMESFX/O_VSEL3.AUD + Discs: + d2k: Dune 2000 (English) + IDFiles: + MUSIC/AMBUSH.AUD: bd5926a56a83bc0e49f96037e1f909014ac0772a + SETUP/SETUP.Z: 937f5ceb1236bf3f3d4e43929305ffe5004078e7 + Install: + copy: MOVIES + ^Content/d2k/Movies/A_BR01_E.VQA: A_BR01_E.VQA + ^Content/d2k/Movies/A_BR02_E.VQA: A_BR02_E.VQA + ^Content/d2k/Movies/A_BR03_E.VQA: A_BR03_E.VQA + ^Content/d2k/Movies/A_BR04_E.VQA: A_BR04_E.VQA + ^Content/d2k/Movies/A_BR05_E.VQA: A_BR05_E.VQA + ^Content/d2k/Movies/A_BR06_E.VQA: A_BR06_E.VQA + ^Content/d2k/Movies/A_BR07_E.VQA: A_BR07_E.VQA + ^Content/d2k/Movies/A_BR08_E.VQA: A_BR08_E.VQA + ^Content/d2k/Movies/A_BR09_E.VQA: A_BR09_E.VQA + ^Content/d2k/Movies/A_FINL_E.VQA: A_FINL_E.VQA + ^Content/d2k/Movies/A_LOSE_E.VQA: A_LOSE_E.VQA + ^Content/d2k/Movies/A_MNTG_E.VQA: A_MNTG_E.VQA + ^Content/d2k/Movies/H_BR01_E.VQA: H_BR01_E.VQA + ^Content/d2k/Movies/H_BR02_E.VQA: H_BR02_E.VQA + ^Content/d2k/Movies/H_BR03_E.VQA: H_BR03_E.VQA + ^Content/d2k/Movies/H_BR04_E.VQA: H_BR04_E.VQA + ^Content/d2k/Movies/H_BR05_E.VQA: H_BR05_E.VQA + ^Content/d2k/Movies/H_BR06_E.VQA: H_BR06_E.VQA + ^Content/d2k/Movies/H_BR07_E.VQA: H_BR07_E.VQA + ^Content/d2k/Movies/H_BR08_E.VQA: H_BR08_E.VQA + ^Content/d2k/Movies/H_BR09_E.VQA: H_BR09_E.VQA + ^Content/d2k/Movies/H_FINL_E.VQA: H_FINL_E.VQA + ^Content/d2k/Movies/H_LOSE_E.VQA: H_LOSE_E.VQA + ^Content/d2k/Movies/H_MNTG_E.VQA: H_MNTG_E.VQA + ^Content/d2k/Movies/O_BR01_E.VQA: O_BR01_E.VQA + ^Content/d2k/Movies/O_BR02_E.VQA: O_BR02_E.VQA + ^Content/d2k/Movies/O_BR03_E.VQA: O_BR03_E.VQA + ^Content/d2k/Movies/O_BR04_E.VQA: O_BR04_E.VQA + ^Content/d2k/Movies/O_BR05_E.VQA: O_BR05_E.VQA + ^Content/d2k/Movies/O_BR06_E.VQA: O_BR06_E.VQA + ^Content/d2k/Movies/O_BR07_E.VQA: O_BR07_E.VQA + ^Content/d2k/Movies/O_BR08_E.VQA: O_BR08_E.VQA + ^Content/d2k/Movies/O_BR09_E.VQA: O_BR09_E.VQA + ^Content/d2k/Movies/O_FINL_E.VQA: O_FINL_E.VQA + ^Content/d2k/Movies/O_LOSE_E.VQA: O_LOSE_E.VQA + ^Content/d2k/Movies/O_MNTG_E.VQA: O_MNTG_E.VQA + ^Content/d2k/Movies/G_INT1_E.VQA: G_INT1_E.VQA + ^Content/d2k/Movies/G_INT2_E.VQA: G_INT2_E.VQA + ^Content/d2k/Movies/G_MAPS_E.VQA: G_MAPS_E.VQA + ^Content/d2k/Movies/G_PLN2_E.VQA: G_PLN2_E.VQA + ^Content/d2k/Movies/G_PLNT_E.VQA: G_PLNT_E.VQA + ^Content/d2k/Movies/T_TITL_E.VQA: T_TITL_E.VQA + copy: MUSIC + ^Content/d2k/Music/AMBUSH.AUD: AMBUSH.AUD + ^Content/d2k/Music/ARAKATAK.AUD: ARAKATAK.AUD + ^Content/d2k/Music/ATREGAIN.AUD: ATREGAIN.AUD + ^Content/d2k/Music/ENTORDOS.AUD: ENTORDOS.AUD + ^Content/d2k/Music/FIGHTPWR.AUD: FIGHTPWR.AUD + ^Content/d2k/Music/FREMEN.AUD: FREMEN.AUD + ^Content/d2k/Music/HARK_BAT.AUD: HARK_BAT.AUD + ^Content/d2k/Music/LANDSAND.AUD: LANDSAND.AUD + ^Content/d2k/Music/OPTIONS.AUD: OPTIONS.AUD + ^Content/d2k/Music/PLOTTING.AUD: PLOTTING.AUD + ^Content/d2k/Music/RISEHARK.AUD: RISEHARK.AUD + ^Content/d2k/Music/ROBOTIX.AUD: ROBOTIX.AUD + ^Content/d2k/Music/SCORE.AUD: SCORE.AUD + ^Content/d2k/Music/SOLDAPPR.AUD: SOLDAPPR.AUD + ^Content/d2k/Music/SPICESCT.AUD: SPICESCT.AUD + ^Content/d2k/Music/UNDERCON.AUD: UNDERCON.AUD + ^Content/d2k/Music/WAITGAME.A: WAITGAME.AUD + extract-blast: SETUP/SETUP.Z + ^Content/d2k/BLOXBAT.R8: + Offset: 1156652 + Length: 512750 + ^Content/d2k/BLOXBASE.R8: + Offset: 1669402 + Length: 497092 + ^Content/d2k/BLOXBGBS.R8: + Offset: 4055223 + Length: 499135 + ^Content/d2k/BLOXICE.R8: + Offset: 5524509 + Length: 514963 + ^Content/d2k/BLOXTREE.R8: + Offset: 6994370 + Length: 509867 + ^Content/d2k/BLOXWAST.R8: + Offset: 8455018 + Length: 508567 + ^Content/d2k/DATA.R8: + Offset: 11940547 + Length: 2044557 + ^Content/d2k/MOUSE.R8: + Offset: 14012491 + Length: 16996 + ^Content/d2k/PALETTE.BIN: + Offset: 22938401 + Length: 815 + ^Content/d2k/GAMESFX/A_ECONF2.AUD: + Offset: 15560305 + Length: 9647 + ^Content/d2k/GAMESFX/A_ECONF1.AUD: + Offset: 15569952 + Length: 8676 + ^Content/d2k/GAMESFX/A_ECONF3.AUD: + Offset: 15578628 + Length: 9641 + ^Content/d2k/GAMESFX/A_ESEL1.AUD: + Offset: 15588269 + Length: 7371 + ^Content/d2k/GAMESFX/A_ESEL2.AUD: + Offset: 15595640 + Length: 11326 + ^Content/d2k/GAMESFX/A_ESEL3.AUD: + Offset: 15606966 + Length: 11329 + ^Content/d2k/GAMESFX/A_FCONF1.AUD: + Offset: 15618295 + Length: 8964 + ^Content/d2k/GAMESFX/A_FCONF2.AUD: + Offset: 15627259 + Length: 11336 + ^Content/d2k/GAMESFX/A_FCONF3.AUD: + Offset: 15638595 + Length: 14606 + ^Content/d2k/GAMESFX/OI_ENEMY.AUD: + Offset: 15653201 + Length: 27230 + ^Content/d2k/GAMESFX/AI_POWER.AUD: + Offset: 15680431 + Length: 19621 + ^Content/d2k/GAMESFX/AI_PREP.AUD: + Offset: 15700052 + Length: 28781 + ^Content/d2k/GAMESFX/AI_PRMRY.AUD: + Offset: 15728833 + Length: 29703 + ^Content/d2k/GAMESFX/AI_REINF.AUD: + Offset: 15758536 + Length: 29555 + ^Content/d2k/GAMESFX/AI_GANEW.AUD: + Offset: 15788091 + Length: 27961 + ^Content/d2k/GAMESFX/HI_SPORT.AUD: + Offset: 15816052 + Length: 20925 + ^Content/d2k/GAMESFX/OI_GSAVE.AUD: + Offset: 15836977 + Length: 10925 + ^Content/d2k/GAMESFX/OI_GUARD.AUD: + Offset: 15847902 + Length: 8125 + ^Content/d2k/GAMESFX/HI_MAP3B.AUD: + Offset: 15856027 + Length: 26212 + ^Content/d2k/GAMESFX/HI_MAP4A.AUD: + Offset: 15882239 + Length: 27166 + ^Content/d2k/GAMESFX/HI_MAP5A.AUD: + Offset: 15909405 + Length: 31126 + ^Content/d2k/GAMESFX/HI_MAP6A.AUD: + Offset: 15940531 + Length: 33481 + ^Content/d2k/GAMESFX/O_ECONF3.AUD: + Offset: 15974012 + Length: 17265 + ^Content/d2k/GAMESFX/O_SCONF3.AUD: + Offset: 15991277 + Length: 14523 + ^Content/d2k/GAMESFX/O_SSEL1.AUD: + Offset: 16005800 + Length: 18266 + ^Content/d2k/GAMESFX/O_SSEL2.AUD: + Offset: 16024066 + Length: 8467 + ^Content/d2k/GAMESFX/O_SSEL3.AUD: + Offset: 16032533 + Length: 9748 + ^Content/d2k/GAMESFX/O_VCONF1.AUD: + Offset: 16042281 + Length: 14264 + ^Content/d2k/GAMESFX/O_VCONF2.AUD: + Offset: 16056545 + Length: 12087 + ^Content/d2k/GAMESFX/O_VCONF3.AUD: + Offset: 16068632 + Length: 14428 + ^Content/d2k/GAMESFX/OI_MWIN.AUD: + Offset: 16083060 + Length: 16985 + ^Content/d2k/GAMESFX/O_ECONF1.AUD: + Offset: 16100045 + Length: 12638 + ^Content/d2k/GAMESFX/O_ECONF2.AUD: + Offset: 16112683 + Length: 13229 + ^Content/d2k/GAMESFX/OI_NROOM.AUD: + Offset: 16125912 + Length: 26572 + ^Content/d2k/GAMESFX/O_ESEL1.AUD: + Offset: 16152484 + Length: 12085 + ^Content/d2k/GAMESFX/O_ESEL2.AUD: + Offset: 16164569 + Length: 18232 + ^Content/d2k/GAMESFX/O_ESEL3.AUD: + Offset: 16182801 + Length: 8328 + ^Content/d2k/GAMESFX/O_ICONF1.AUD: + Offset: 16191129 + Length: 12497 + ^Content/d2k/GAMESFX/O_ICONF2.AUD: + Offset: 16203626 + Length: 9546 + ^Content/d2k/GAMESFX/O_ICONF3.AUD: + Offset: 16213172 + Length: 17135 + ^Content/d2k/GAMESFX/HI_MAP4B.AUD: + Offset: 16230307 + Length: 26937 + ^Content/d2k/GAMESFX/O_ISEL2.AUD: + Offset: 16257244 + Length: 17940 + ^Content/d2k/GAMESFX/HI_BLOST.AUD: + Offset: 16275184 + Length: 14985 + ^Content/d2k/GAMESFX/HI_BUILD.AUD: + Offset: 16290169 + Length: 9089 + ^Content/d2k/GAMESFX/HI_MAP6B.AUD: + Offset: 16299258 + Length: 28401 + ^Content/d2k/GAMESFX/HI_MAP7A.AUD: + Offset: 16327659 + Length: 23949 + ^Content/d2k/GAMESFX/HI_MAP9.AUD: + Offset: 16351608 + Length: 29489 + ^Content/d2k/GAMESFX/A_VSEL3.AUD: + Offset: 16381097 + Length: 11016 + ^Content/d2k/GAMESFX/AI_1MIN.AUD: + Offset: 16392113 + Length: 27566 + ^Content/d2k/GAMESFX/AI_2MIN.AUD: + Offset: 16419679 + Length: 26539 + ^Content/d2k/GAMESFX/AI_3MIN.AUD: + Offset: 16446218 + Length: 30821 + ^Content/d2k/GAMESFX/O_VSEL1.AUD: + Offset: 16477039 + Length: 7978 + ^Content/d2k/GAMESFX/HI_RUN.AUD: + Offset: 16485017 + Length: 11880 + ^Content/d2k/GAMESFX/A_FSEL1.AUD: + Offset: 16496897 + Length: 8995 + ^Content/d2k/GAMESFX/A_FSEL2.AUD: + Offset: 16505892 + Length: 10120 + ^Content/d2k/GAMESFX/A_FSEL3.AUD: + Offset: 16516012 + Length: 8999 + ^Content/d2k/GAMESFX/A_FSEL4.AUD: + Offset: 16525011 + Length: 6593 + ^Content/d2k/GAMESFX/OI_MAP8A.AUD: + Offset: 16531604 + Length: 34790 + ^Content/d2k/GAMESFX/OI_MAP9A.AUD: + Offset: 16566394 + Length: 35606 + ^Content/d2k/GAMESFX/OI_MEND.AUD: + Offset: 16602000 + Length: 10303 + ^Content/d2k/GAMESFX/OI_MFAIL.AUD: + Offset: 16612303 + Length: 22969 + ^Content/d2k/GAMESFX/AI_4MIN.AUD: + Offset: 16635272 + Length: 31816 + ^Content/d2k/GAMESFX/AI_CANCL.AUD: + Offset: 16667088 + Length: 19585 + ^Content/d2k/GAMESFX/OI_ULOST.AUD: + Offset: 16686673 + Length: 14563 + ^Content/d2k/GAMESFX/OI_UNRDY.AUD: + Offset: 16701236 + Length: 13353 + ^Content/d2k/GAMESFX/O_VSEL3.AUD: + Offset: 16714589 + Length: 9671 + ^Content/d2k/GAMESFX/OI_1MIN.AUD: + Offset: 16724260 + Length: 15031 + ^Content/d2k/GAMESFX/OI_MAP7A.AUD: + Offset: 16739291 + Length: 28368 + ^Content/d2k/GAMESFX/HI_TRAIN.AUD: + Offset: 16767659 + Length: 9649 + ^Content/d2k/GAMESFX/HI_ULOST.AUD: + Offset: 16777308 + Length: 17157 + ^Content/d2k/GAMESFX/HI_UNRDY.AUD: + Offset: 16794465 + Length: 13407 + ^Content/d2k/GAMESFX/OI_MAP2A.AUD: + Offset: 16807872 + Length: 29910 + ^Content/d2k/GAMESFX/HI_REINF.AUD: + Offset: 16837782 + Length: 22890 + ^Content/d2k/GAMESFX/OI_MAP2C.AUD: + Offset: 16860672 + Length: 22923 + ^Content/d2k/GAMESFX/OI_MAP3A.AUD: + Offset: 16883595 + Length: 34017 + ^Content/d2k/GAMESFX/OI_MAP4A.AUD: + Offset: 16917612 + Length: 56714 + ^Content/d2k/GAMESFX/OI_SPORT.AUD: + Offset: 16974326 + Length: 27200 + ^Content/d2k/GAMESFX/OI_UPGOP.AUD: + Offset: 17001526 + Length: 19828 + ^Content/d2k/GAMESFX/OI_UPGRD.AUD: + Offset: 17021354 + Length: 13869 + ^Content/d2k/GAMESFX/OI_WATTK.AUD: + Offset: 17035223 + Length: 14197 + ^Content/d2k/GAMESFX/AI_MONEY.AUD: + Offset: 17049420 + Length: 29136 + ^Content/d2k/GAMESFX/AI_SELL.AUD: + Offset: 17078556 + Length: 26204 + ^Content/d2k/GAMESFX/HI_NEWOP.AUD: + Offset: 17104760 + Length: 24264 + ^Content/d2k/GAMESFX/AI_5MIN.AUD: + Offset: 17129024 + Length: 43921 + ^Content/d2k/GAMESFX/OI_HATTK.AUD: + Offset: 17172945 + Length: 22151 + ^Content/d2k/GAMESFX/H_VSEL2.AUD: + Offset: 17195096 + Length: 12300 + ^Content/d2k/GAMESFX/OI_MAP1B.AUD: + Offset: 17207396 + Length: 21971 + ^Content/d2k/GAMESFX/OI_MAP1C.AUD: + Offset: 17229367 + Length: 22041 + ^Content/d2k/GAMESFX/AI_GSAVE.AUD: + Offset: 17251408 + Length: 21545 + ^Content/d2k/GAMESFX/AI_GUARD.AUD: + Offset: 17272953 + Length: 14344 + ^Content/d2k/GAMESFX/AI_HATTK.AUD: + Offset: 17287297 + Length: 28156 + ^Content/d2k/GAMESFX/AI_HOLD.AUD: + Offset: 17315453 + Length: 16983 + ^Content/d2k/GAMESFX/HI_UPGOP.AUD: + Offset: 17332436 + Length: 19583 + ^Content/d2k/GAMESFX/HI_UPGRD.AUD: + Offset: 17352019 + Length: 12875 + ^Content/d2k/GAMESFX/OI_MAP2B.AUD: + Offset: 17364894 + Length: 20974 + ^Content/d2k/GAMESFX/HI_WSIGN.AUD: + Offset: 17385868 + Length: 14699 + ^Content/d2k/GAMESFX/HI_HATTK.AUD: + Offset: 17400567 + Length: 20919 + ^Content/d2k/GAMESFX/O_SCONF2.AUD: + Offset: 17421486 + Length: 18984 + ^Content/d2k/GAMESFX/HI_HOLD.AUD: + Offset: 17440470 + Length: 11779 + ^Content/d2k/GAMESFX/A_VSEL2.AUD: + Offset: 17452249 + Length: 13980 + ^Content/d2k/GAMESFX/AI_ATACK.AUD: + Offset: 17466229 + Length: 33483 + ^Content/d2k/GAMESFX/AI_BDRDY.AUD: + Offset: 17499712 + Length: 26566 + ^Content/d2k/GAMESFX/AI_BLOST.AUD: + Offset: 17526278 + Length: 25237 + ^Content/d2k/GAMESFX/AI_BUILD.AUD: + Offset: 17551515 + Length: 16072 + ^Content/d2k/GAMESFX/HI_GLOAD.AUD: + Offset: 17567587 + Length: 12037 + ^Content/d2k/GAMESFX/AI_CAPT.AUD: + Offset: 17579624 + Length: 30243 + ^Content/d2k/GAMESFX/AI_DHRDY.AUD: + Offset: 17609867 + Length: 31710 + ^Content/d2k/GAMESFX/AI_DPLOY.AUD: + Offset: 17641577 + Length: 27450 + ^Content/d2k/GAMESFX/AI_ENEMY.AUD: + Offset: 17669027 + Length: 30854 + ^Content/d2k/GAMESFX/A_VCONF1.AUD: + Offset: 17699881 + Length: 10860 + ^Content/d2k/GAMESFX/HI_PLACE.AUD: + Offset: 17710741 + Length: 19337 + ^Content/d2k/GAMESFX/HI_POWER.AUD: + Offset: 17730078 + Length: 15004 + ^Content/d2k/GAMESFX/HI_PREP.AUD: + Offset: 17745082 + Length: 23023 + ^Content/d2k/GAMESFX/HI_PRMRY.AUD: + Offset: 17768105 + Length: 22321 + ^Content/d2k/GAMESFX/OI_MONEY.AUD: + Offset: 17790426 + Length: 21698 + ^Content/d2k/GAMESFX/O_ISEL1.AUD: + Offset: 17812124 + Length: 10282 + ^Content/d2k/GAMESFX/OI_NEWOP.AUD: + Offset: 17822406 + Length: 28615 + ^Content/d2k/GAMESFX/A_VCONF3.AUD: + Offset: 17851021 + Length: 12771 + ^Content/d2k/GAMESFX/A_VSEL1.AUD: + Offset: 17863792 + Length: 9917 + ^Content/d2k/GAMESFX/OI_PLACE.AUD: + Offset: 17873709 + Length: 18502 + ^Content/d2k/GAMESFX/OI_POWER.AUD: + Offset: 17892211 + Length: 12832 + ^Content/d2k/GAMESFX/OI_PREP.AUD: + Offset: 17905043 + Length: 22413 + ^Content/d2k/GAMESFX/OI_PRMRY.AUD: + Offset: 17927456 + Length: 29577 + ^Content/d2k/GAMESFX/OI_REINF.AUD: + Offset: 17957033 + Length: 24798 + ^Content/d2k/GAMESFX/OI_RUN.AUD: + Offset: 17981831 + Length: 14784 + ^Content/d2k/GAMESFX/OI_CAPT.AUD: + Offset: 17996615 + Length: 18526 + ^Content/d2k/GAMESFX/H_ECONF1.AUD: + Offset: 18015141 + Length: 12390 + ^Content/d2k/GAMESFX/O_VSEL2.AUD: + Offset: 18027531 + Length: 11851 + ^Content/d2k/GAMESFX/H_VSEL3.AUD: + Offset: 18039382 + Length: 9867 + ^Content/d2k/GAMESFX/HI_1MIN.AUD: + Offset: 18049249 + Length: 16907 + ^Content/d2k/GAMESFX/HI_2MIN.AUD: + Offset: 18066156 + Length: 17659 + ^Content/d2k/GAMESFX/HI_3MIN.AUD: + Offset: 18083815 + Length: 20337 + ^Content/d2k/GAMESFX/HI_4MIN.AUD: + Offset: 18104152 + Length: 18877 + ^Content/d2k/GAMESFX/HI_5MIN.AUD: + Offset: 18123029 + Length: 30788 + ^Content/d2k/GAMESFX/HI_ABORT.AUD: + Offset: 18153817 + Length: 18322 + ^Content/d2k/GAMESFX/HI_ATACK.AUD: + Offset: 18172139 + Length: 22178 + ^Content/d2k/GAMESFX/HI_NROOM.AUD: + Offset: 18194317 + Length: 24878 + ^Content/d2k/GAMESFX/OI_SILOS.AUD: + Offset: 18219195 + Length: 15741 + ^Content/d2k/GAMESFX/A_FCONF4.AUD: + Offset: 18234936 + Length: 14892 + ^Content/d2k/GAMESFX/OI_MAP5A.AUD: + Offset: 18249828 + Length: 23026 + ^Content/d2k/GAMESFX/OI_MAP6A.AUD: + Offset: 18272854 + Length: 43938 + ^Content/d2k/GAMESFX/HI_CANCL.AUD: + Offset: 18316792 + Length: 10992 + ^Content/d2k/GAMESFX/HI_CAPT.AUD: + Offset: 18327784 + Length: 19514 + ^Content/d2k/GAMESFX/HI_DHRDY.AUD: + Offset: 18347298 + Length: 23895 + ^Content/d2k/GAMESFX/HI_DPLOY.AUD: + Offset: 18371193 + Length: 18626 + ^Content/d2k/GAMESFX/HI_ENEMY.AUD: + Offset: 18389819 + Length: 22564 + ^Content/d2k/GAMESFX/HI_GANEW.AUD: + Offset: 18412383 + Length: 18445 + ^Content/d2k/GAMESFX/OI_DHRDY.AUD: + Offset: 18430828 + Length: 19492 + ^Content/d2k/GAMESFX/HI_GSAVE.AUD: + Offset: 18450320 + Length: 14194 + ^Content/d2k/GAMESFX/HI_GUARD.AUD: + Offset: 18464514 + Length: 8310 + ^Content/d2k/GAMESFX/H_VSEL1.AUD: + Offset: 18472824 + Length: 8332 + ^Content/d2k/GAMESFX/OI_ORDER.AUD: + Offset: 18481156 + Length: 15789 + ^Content/d2k/GAMESFX/G_SCONF1.AUD: + Offset: 18496945 + Length: 9791 + ^Content/d2k/GAMESFX/G_SCONF2.AUD: + Offset: 18506736 + Length: 15099 + ^Content/d2k/GAMESFX/G_SCONF3.AUD: + Offset: 18521835 + Length: 14863 + ^Content/d2k/GAMESFX/G_SSEL1.AUD: + Offset: 18536698 + Length: 9753 + ^Content/d2k/GAMESFX/G_SSEL2.AUD: + Offset: 18546451 + Length: 9329 + ^Content/d2k/GAMESFX/G_SSEL3.AUD: + Offset: 18555780 + Length: 9449 + ^Content/d2k/GAMESFX/OI_SELL.AUD: + Offset: 18565229 + Length: 15600 + ^Content/d2k/GAMESFX/H_ECONF2.AUD: + Offset: 18580829 + Length: 16157 + ^Content/d2k/GAMESFX/H_ECONF3.AUD: + Offset: 18596986 + Length: 13149 + ^Content/d2k/GAMESFX/H_ESEL1.AUD: + Offset: 18610135 + Length: 13928 + ^Content/d2k/GAMESFX/H_ESEL2.AUD: + Offset: 18624063 + Length: 16430 + ^Content/d2k/GAMESFX/AI_MAP2C.AUD: + Offset: 18640493 + Length: 41640 + ^Content/d2k/GAMESFX/AI_MAP3A.AUD: + Offset: 18682133 + Length: 41809 + ^Content/d2k/GAMESFX/AI_MAP4A.AUD: + Offset: 18723942 + Length: 29117 + ^Content/d2k/GAMESFX/AI_MAP5A.AUD: + Offset: 18753059 + Length: 36982 + ^Content/d2k/GAMESFX/AI_MAP6A.AUD: + Offset: 18790041 + Length: 60681 + ^Content/d2k/GAMESFX/HI_BDRDY.AUD: + Offset: 18850722 + Length: 21396 + ^Content/d2k/GAMESFX/AI_MAP8A.AUD: + Offset: 18872118 + Length: 37995 + ^Content/d2k/GAMESFX/AI_MAP9A.AUD: + Offset: 18910113 + Length: 32674 + ^Content/d2k/GAMESFX/AI_MEND.AUD: + Offset: 18942787 + Length: 18399 + ^Content/d2k/GAMESFX/AI_MFAIL.AUD: + Offset: 18961186 + Length: 26359 + ^Content/d2k/GAMESFX/AI_GLOAD.AUD: + Offset: 18987545 + Length: 21335 + ^Content/d2k/GAMESFX/HI_MAP9A.AUD: + Offset: 19008880 + Length: 28418 + ^Content/d2k/GAMESFX/HI_MEND.AUD: + Offset: 19037298 + Length: 9269 + ^Content/d2k/GAMESFX/HI_MFAIL.AUD: + Offset: 19046567 + Length: 19854 + ^Content/d2k/GAMESFX/HI_MONEY.AUD: + Offset: 19066421 + Length: 20038 + ^Content/d2k/GAMESFX/HI_MWIN.AUD: + Offset: 19086459 + Length: 16073 + ^Content/d2k/GAMESFX/HI_WATTK.AUD: + Offset: 19102532 + Length: 14873 + ^Content/d2k/GAMESFX/AI_MAP1A.AUD: + Offset: 19117405 + Length: 41683 + ^Content/d2k/GAMESFX/AI_MAP1B.AUD: + Offset: 19159088 + Length: 34475 + ^Content/d2k/GAMESFX/AI_MAP1C.AUD: + Offset: 19193563 + Length: 34903 + ^Content/d2k/GAMESFX/AI_MAP2A.AUD: + Offset: 19228466 + Length: 59613 + ^Content/d2k/GAMESFX/AI_ABORT.AUD: + Offset: 19288079 + Length: 22150 + ^Content/d2k/GAMESFX/H_ESEL3.AUD: + Offset: 19310229 + Length: 9090 + ^Content/d2k/GAMESFX/AI_SILOS.AUD: + Offset: 19319319 + Length: 21350 + ^Content/d2k/GAMESFX/AI_SPORT.AUD: + Offset: 19340669 + Length: 31478 + ^Content/d2k/GAMESFX/AI_TRAIN.AUD: + Offset: 19372147 + Length: 19876 + ^Content/d2k/GAMESFX/AI_ULOST.AUD: + Offset: 19392023 + Length: 22359 + ^Content/d2k/GAMESFX/AI_MAP7A.AUD: + Offset: 19414382 + Length: 28902 + ^Content/d2k/GAMESFX/AI_UPGOP.AUD: + Offset: 19443284 + Length: 26855 + ^Content/d2k/GAMESFX/AI_UPGRD.AUD: + Offset: 19470139 + Length: 19104 + ^Content/d2k/GAMESFX/AI_WATTK.AUD: + Offset: 19489243 + Length: 24655 + ^Content/d2k/GAMESFX/AI_WSIGN.AUD: + Offset: 19513898 + Length: 23032 + ^Content/d2k/GAMESFX/AI_MAP2B.AUD: + Offset: 19536930 + Length: 35588 + ^Content/d2k/GAMESFX/A_ICONF1.AUD: + Offset: 19572518 + Length: 8945 + ^Content/d2k/GAMESFX/A_ICONF2.AUD: + Offset: 19581463 + Length: 9005 + ^Content/d2k/GAMESFX/A_ICONF3.AUD: + Offset: 19590468 + Length: 9606 + ^Content/d2k/GAMESFX/A_ISEL1.AUD: + Offset: 19600074 + Length: 11671 + ^Content/d2k/GAMESFX/OI_CANCL.AUD: + Offset: 19611745 + Length: 10644 + ^Content/d2k/GAMESFX/H_ISEL2.AUD: + Offset: 19622389 + Length: 10387 + ^Content/d2k/GAMESFX/H_ISEL3.AUD: + Offset: 19632776 + Length: 17225 + ^Content/d2k/GAMESFX/H_VCONF1.AUD: + Offset: 19650001 + Length: 10077 + ^Content/d2k/GAMESFX/H_VCONF2.AUD: + Offset: 19660078 + Length: 13616 + ^Content/d2k/GAMESFX/H_VCONF3.AUD: + Offset: 19673694 + Length: 11251 + ^Content/d2k/GAMESFX/OI_TRAIN.AUD: + Offset: 19684945 + Length: 8144 + ^Content/d2k/GAMESFX/HI_ORDER.AUD: + Offset: 19693089 + Length: 14865 + ^Content/d2k/GAMESFX/OI_WSIGN.AUD: + Offset: 19707954 + Length: 11912 + ^Content/d2k/GAMESFX/OI_BLOST.AUD: + Offset: 19719866 + Length: 19540 + ^Content/d2k/GAMESFX/OI_BUILD.AUD: + Offset: 19739406 + Length: 10246 + ^Content/d2k/GAMESFX/AI_LAUNC.AUD: + Offset: 19749652 + Length: 31148 + ^Content/d2k/GAMESFX/A_ISEL3.AUD: + Offset: 19780800 + Length: 8307 + ^Content/d2k/GAMESFX/A_VCONF2.AUD: + Offset: 19789107 + Length: 14331 + ^Content/d2k/GAMESFX/OI_HOLD.AUD: + Offset: 19803438 + Length: 11295 + ^Content/d2k/GAMESFX/OI_LAUNC.AUD: + Offset: 19814733 + Length: 20437 + ^Content/d2k/GAMESFX/OI_MAP1A.AUD: + Offset: 19835170 + Length: 27739 + ^Content/d2k/GAMESFX/HI_LAUNC.AUD: + Offset: 19862909 + Length: 22200 + ^Content/d2k/GAMESFX/H_ICONF1.AUD: + Offset: 19885109 + Length: 9620 + ^Content/d2k/GAMESFX/H_ICONF2.AUD: + Offset: 19894729 + Length: 13368 + ^Content/d2k/GAMESFX/H_ICONF3.AUD: + Offset: 19908097 + Length: 15612 + ^Content/d2k/GAMESFX/H_ISEL1.AUD: + Offset: 19923709 + Length: 8279 + ^Content/d2k/GAMESFX/A_ISEL2.AUD: + Offset: 19931988 + Length: 11383 + ^Content/d2k/GAMESFX/AI_RUN.AUD: + Offset: 19943371 + Length: 18511 + ^Content/d2k/GAMESFX/HI_SILOS.AUD: + Offset: 19961882 + Length: 14244 + ^Content/d2k/GAMESFX/HI_MAP1A.AUD: + Offset: 19976126 + Length: 24075 + ^Content/d2k/GAMESFX/HI_MAP1B.AUD: + Offset: 20000201 + Length: 26716 + ^Content/d2k/GAMESFX/HI_MAP1C.AUD: + Offset: 20026917 + Length: 21716 + ^Content/d2k/GAMESFX/HI_MAP2A.AUD: + Offset: 20048633 + Length: 32417 + ^Content/d2k/GAMESFX/HI_MAP2B.AUD: + Offset: 20081050 + Length: 33724 + ^Content/d2k/GAMESFX/HI_MAP2C.AUD: + Offset: 20114774 + Length: 21828 + ^Content/d2k/GAMESFX/HI_MAP3A.AUD: + Offset: 20136602 + Length: 30404 + ^Content/d2k/GAMESFX/O_ISEL3.AUD: + Offset: 20167006 + Length: 9862 + ^Content/d2k/GAMESFX/O_SCONF1.AUD: + Offset: 20176868 + Length: 18149 + ^Content/d2k/GAMESFX/OI_2MIN.AUD: + Offset: 20195017 + Length: 14697 + ^Content/d2k/GAMESFX/OI_3MIN.AUD: + Offset: 20209714 + Length: 17316 + ^Content/d2k/GAMESFX/OI_4MIN.AUD: + Offset: 20227030 + Length: 14869 + ^Content/d2k/GAMESFX/OI_5MIN.AUD: + Offset: 20241899 + Length: 29873 + ^Content/d2k/GAMESFX/OI_ABORT.AUD: + Offset: 20271772 + Length: 16335 + ^Content/d2k/GAMESFX/OI_ATACK.AUD: + Offset: 20288107 + Length: 20565 + ^Content/d2k/GAMESFX/OI_BDRDY.AUD: + Offset: 20308672 + Length: 25497 + ^Content/d2k/GAMESFX/HI_SELL.AUD: + Offset: 20334169 + Length: 17142 + ^Content/d2k/GAMESFX/OI_DPLOY.AUD: + Offset: 20351311 + Length: 20120 + ^Content/d2k/GAMESFX/AI_PLACE.AUD: + Offset: 20371431 + Length: 29921 + ^Content/d2k/GAMESFX/OI_GANEW.AUD: + Offset: 20401352 + Length: 14467 + ^Content/d2k/GAMESFX/OI_GLOAD.AUD: + Offset: 20415819 + Length: 10906 + ^Content/d2k/GAMESFX/AI_MWIN.AUD: + Offset: 20426725 + Length: 25959 + ^Content/d2k/GAMESFX/AI_NEWOP.AUD: + Offset: 20452684 + Length: 34175 + ^Content/d2k/GAMESFX/AI_NROOM.AUD: + Offset: 20486859 + Length: 30124 + ^Content/d2k/GAMESFX/AI_ORDER.AUD: + Offset: 20516983 + Length: 21881 + ^Content/d2k/GAMESFX/AI_UNRDY.AUD: + Offset: 20538864 + Length: 20567 + ^Content/d2k/SOUND.RS: + Offset: 20559431 + Length: 1929247 + d2k-linux: Dune 2000 (English) + IDFiles: + music/ambush.aud: bd5926a56a83bc0e49f96037e1f909014ac0772a + setup/setup.z: 937f5ceb1236bf3f3d4e43929305ffe5004078e7 + Install: + copy: movies + ^Content/d2k/Movies/A_BR01_E.VQA: a_br01_e.vqa + ^Content/d2k/Movies/A_BR02_E.VQA: a_br02_e.vqa + ^Content/d2k/Movies/A_BR03_E.VQA: a_br03_e.vqa + ^Content/d2k/Movies/A_BR04_E.VQA: a_br04_e.vqa + ^Content/d2k/Movies/A_BR05_E.VQA: a_br05_e.vqa + ^Content/d2k/Movies/A_BR06_E.VQA: a_br06_e.vqa + ^Content/d2k/Movies/A_BR07_E.VQA: a_br07_e.vqa + ^Content/d2k/Movies/A_BR08_E.VQA: a_br08_e.vqa + ^Content/d2k/Movies/A_BR09_E.VQA: a_br09_e.vqa + ^Content/d2k/Movies/A_FINL_E.VQA: a_finl_e.vqa + ^Content/d2k/Movies/A_LOSE_E.VQA: a_lose_e.vqa + ^Content/d2k/Movies/A_MNTG_E.VQA: a_mntg_e.vqa + ^Content/d2k/Movies/H_BR01_E.VQA: h_br01_e.vqa + ^Content/d2k/Movies/H_BR02_E.VQA: h_br02_e.vqa + ^Content/d2k/Movies/H_BR03_E.VQA: h_br03_e.vqa + ^Content/d2k/Movies/H_BR04_E.VQA: h_br04_e.vqa + ^Content/d2k/Movies/H_BR05_E.VQA: h_br05_e.vqa + ^Content/d2k/Movies/H_BR06_E.VQA: h_br06_e.vqa + ^Content/d2k/Movies/H_BR07_E.VQA: h_br07_e.vqa + ^Content/d2k/Movies/H_BR08_E.VQA: h_br08_e.vqa + ^Content/d2k/Movies/H_BR09_E.VQA: h_br09_e.vqa + ^Content/d2k/Movies/H_FINL_E.VQA: h_finl_e.vqa + ^Content/d2k/Movies/H_LOSE_E.VQA: h_lose_e.vqa + ^Content/d2k/Movies/H_MNTG_E.VQA: h_mntg_e.vqa + ^Content/d2k/Movies/O_BR01_E.VQA: o_br01_e.vqa + ^Content/d2k/Movies/O_BR02_E.VQA: o_br02_e.vqa + ^Content/d2k/Movies/O_BR03_E.VQA: o_br03_e.vqa + ^Content/d2k/Movies/O_BR04_E.VQA: o_br04_e.vqa + ^Content/d2k/Movies/O_BR05_E.VQA: o_br05_e.vqa + ^Content/d2k/Movies/O_BR06_E.VQA: o_br06_e.vqa + ^Content/d2k/Movies/O_BR07_E.VQA: o_br07_e.vqa + ^Content/d2k/Movies/O_BR08_E.VQA: o_br08_e.vqa + ^Content/d2k/Movies/O_BR09_E.VQA: o_br09_e.vqa + ^Content/d2k/Movies/O_FINL_E.VQA: o_finl_e.vqa + ^Content/d2k/Movies/O_LOSE_E.VQA: o_lose_e.vqa + ^Content/d2k/Movies/O_MNTG_E.VQA: o_mntg_e.vqa + ^Content/d2k/Movies/G_INT1_E.VQA: g_int1_e.vqa + ^Content/d2k/Movies/G_INT2_E.VQA: g_int2_e.vqa + ^Content/d2k/Movies/G_MAPS_E.VQA: g_maps_e.vqa + ^Content/d2k/Movies/G_PLN2_E.VQA: g_pln2_e.vqa + ^Content/d2k/Movies/G_PLNT_E.VQA: g_plnt_e.vqa + ^Content/d2k/Movies/T_TITL_E.VQA: t_titl_e.vqa + copy: music + ^Content/d2k/Music/AMBUSH.AUD: ambush.aud + ^Content/d2k/Music/ARAKATAK.AUD: arakatak.aud + ^Content/d2k/Music/ATREGAIN.AUD: atregain.aud + ^Content/d2k/Music/ENTORDOS.AUD: entordos.aud + ^Content/d2k/Music/FIGHTPWR.AUD: fightpwr.aud + ^Content/d2k/Music/FREMEN.AUD: fremen.aud + ^Content/d2k/Music/HARK_BAT.AUD: hark_bat.aud + ^Content/d2k/Music/LANDSAND.AUD: landsand.aud + ^Content/d2k/Music/OPTIONS.AUD: options.aud + ^Content/d2k/Music/PLOTTING.AUD: plotting.aud + ^Content/d2k/Music/RISEHARK.AUD: risehark.aud + ^Content/d2k/Music/ROBOTIX.AUD: robotix.aud + ^Content/d2k/Music/SCORE.AUD: score.aud + ^Content/d2k/Music/SOLDAPPR.AUD: soldappr.aud + ^Content/d2k/Music/SPICESCT.AUD: spicesct.aud + ^Content/d2k/Music/UNDERCON.AUD: undercon.aud + ^Content/d2k/Music/WAITGAME.A: waitgame.aud + extract-blast: setup/setup.z + ^Content/d2k/BLOXBAT.R8: + Offset: 1156652 + Length: 512750 + ^Content/d2k/BLOXBASE.R8: + Offset: 1669402 + Length: 497092 + ^Content/d2k/BLOXBGBS.R8: + Offset: 4055223 + Length: 499135 + ^Content/d2k/BLOXICE.R8: + Offset: 5524509 + Length: 514963 + ^Content/d2k/BLOXTREE.R8: + Offset: 6994370 + Length: 509867 + ^Content/d2k/BLOXWAST.R8: + Offset: 8455018 + Length: 508567 + ^Content/d2k/DATA.R8: + Offset: 11940547 + Length: 2044557 + ^Content/d2k/MOUSE.R8: + Offset: 14012491 + Length: 16996 + ^Content/d2k/PALETTE.BIN: + Offset: 22938401 + Length: 815 + ^Content/d2k/GAMESFX/A_ECONF2.AUD: + Offset: 15560305 + Length: 9647 + ^Content/d2k/GAMESFX/A_ECONF1.AUD: + Offset: 15569952 + Length: 8676 + ^Content/d2k/GAMESFX/A_ECONF3.AUD: + Offset: 15578628 + Length: 9641 + ^Content/d2k/GAMESFX/A_ESEL1.AUD: + Offset: 15588269 + Length: 7371 + ^Content/d2k/GAMESFX/A_ESEL2.AUD: + Offset: 15595640 + Length: 11326 + ^Content/d2k/GAMESFX/A_ESEL3.AUD: + Offset: 15606966 + Length: 11329 + ^Content/d2k/GAMESFX/A_FCONF1.AUD: + Offset: 15618295 + Length: 8964 + ^Content/d2k/GAMESFX/A_FCONF2.AUD: + Offset: 15627259 + Length: 11336 + ^Content/d2k/GAMESFX/A_FCONF3.AUD: + Offset: 15638595 + Length: 14606 + ^Content/d2k/GAMESFX/OI_ENEMY.AUD: + Offset: 15653201 + Length: 27230 + ^Content/d2k/GAMESFX/AI_POWER.AUD: + Offset: 15680431 + Length: 19621 + ^Content/d2k/GAMESFX/AI_PREP.AUD: + Offset: 15700052 + Length: 28781 + ^Content/d2k/GAMESFX/AI_PRMRY.AUD: + Offset: 15728833 + Length: 29703 + ^Content/d2k/GAMESFX/AI_REINF.AUD: + Offset: 15758536 + Length: 29555 + ^Content/d2k/GAMESFX/AI_GANEW.AUD: + Offset: 15788091 + Length: 27961 + ^Content/d2k/GAMESFX/HI_SPORT.AUD: + Offset: 15816052 + Length: 20925 + ^Content/d2k/GAMESFX/OI_GSAVE.AUD: + Offset: 15836977 + Length: 10925 + ^Content/d2k/GAMESFX/OI_GUARD.AUD: + Offset: 15847902 + Length: 8125 + ^Content/d2k/GAMESFX/HI_MAP3B.AUD: + Offset: 15856027 + Length: 26212 + ^Content/d2k/GAMESFX/HI_MAP4A.AUD: + Offset: 15882239 + Length: 27166 + ^Content/d2k/GAMESFX/HI_MAP5A.AUD: + Offset: 15909405 + Length: 31126 + ^Content/d2k/GAMESFX/HI_MAP6A.AUD: + Offset: 15940531 + Length: 33481 + ^Content/d2k/GAMESFX/O_ECONF3.AUD: + Offset: 15974012 + Length: 17265 + ^Content/d2k/GAMESFX/O_SCONF3.AUD: + Offset: 15991277 + Length: 14523 + ^Content/d2k/GAMESFX/O_SSEL1.AUD: + Offset: 16005800 + Length: 18266 + ^Content/d2k/GAMESFX/O_SSEL2.AUD: + Offset: 16024066 + Length: 8467 + ^Content/d2k/GAMESFX/O_SSEL3.AUD: + Offset: 16032533 + Length: 9748 + ^Content/d2k/GAMESFX/O_VCONF1.AUD: + Offset: 16042281 + Length: 14264 + ^Content/d2k/GAMESFX/O_VCONF2.AUD: + Offset: 16056545 + Length: 12087 + ^Content/d2k/GAMESFX/O_VCONF3.AUD: + Offset: 16068632 + Length: 14428 + ^Content/d2k/GAMESFX/OI_MWIN.AUD: + Offset: 16083060 + Length: 16985 + ^Content/d2k/GAMESFX/O_ECONF1.AUD: + Offset: 16100045 + Length: 12638 + ^Content/d2k/GAMESFX/O_ECONF2.AUD: + Offset: 16112683 + Length: 13229 + ^Content/d2k/GAMESFX/OI_NROOM.AUD: + Offset: 16125912 + Length: 26572 + ^Content/d2k/GAMESFX/O_ESEL1.AUD: + Offset: 16152484 + Length: 12085 + ^Content/d2k/GAMESFX/O_ESEL2.AUD: + Offset: 16164569 + Length: 18232 + ^Content/d2k/GAMESFX/O_ESEL3.AUD: + Offset: 16182801 + Length: 8328 + ^Content/d2k/GAMESFX/O_ICONF1.AUD: + Offset: 16191129 + Length: 12497 + ^Content/d2k/GAMESFX/O_ICONF2.AUD: + Offset: 16203626 + Length: 9546 + ^Content/d2k/GAMESFX/O_ICONF3.AUD: + Offset: 16213172 + Length: 17135 + ^Content/d2k/GAMESFX/HI_MAP4B.AUD: + Offset: 16230307 + Length: 26937 + ^Content/d2k/GAMESFX/O_ISEL2.AUD: + Offset: 16257244 + Length: 17940 + ^Content/d2k/GAMESFX/HI_BLOST.AUD: + Offset: 16275184 + Length: 14985 + ^Content/d2k/GAMESFX/HI_BUILD.AUD: + Offset: 16290169 + Length: 9089 + ^Content/d2k/GAMESFX/HI_MAP6B.AUD: + Offset: 16299258 + Length: 28401 + ^Content/d2k/GAMESFX/HI_MAP7A.AUD: + Offset: 16327659 + Length: 23949 + ^Content/d2k/GAMESFX/HI_MAP9.AUD: + Offset: 16351608 + Length: 29489 + ^Content/d2k/GAMESFX/A_VSEL3.AUD: + Offset: 16381097 + Length: 11016 + ^Content/d2k/GAMESFX/AI_1MIN.AUD: + Offset: 16392113 + Length: 27566 + ^Content/d2k/GAMESFX/AI_2MIN.AUD: + Offset: 16419679 + Length: 26539 + ^Content/d2k/GAMESFX/AI_3MIN.AUD: + Offset: 16446218 + Length: 30821 + ^Content/d2k/GAMESFX/O_VSEL1.AUD: + Offset: 16477039 + Length: 7978 + ^Content/d2k/GAMESFX/HI_RUN.AUD: + Offset: 16485017 + Length: 11880 + ^Content/d2k/GAMESFX/A_FSEL1.AUD: + Offset: 16496897 + Length: 8995 + ^Content/d2k/GAMESFX/A_FSEL2.AUD: + Offset: 16505892 + Length: 10120 + ^Content/d2k/GAMESFX/A_FSEL3.AUD: + Offset: 16516012 + Length: 8999 + ^Content/d2k/GAMESFX/A_FSEL4.AUD: + Offset: 16525011 + Length: 6593 + ^Content/d2k/GAMESFX/OI_MAP8A.AUD: + Offset: 16531604 + Length: 34790 + ^Content/d2k/GAMESFX/OI_MAP9A.AUD: + Offset: 16566394 + Length: 35606 + ^Content/d2k/GAMESFX/OI_MEND.AUD: + Offset: 16602000 + Length: 10303 + ^Content/d2k/GAMESFX/OI_MFAIL.AUD: + Offset: 16612303 + Length: 22969 + ^Content/d2k/GAMESFX/AI_4MIN.AUD: + Offset: 16635272 + Length: 31816 + ^Content/d2k/GAMESFX/AI_CANCL.AUD: + Offset: 16667088 + Length: 19585 + ^Content/d2k/GAMESFX/OI_ULOST.AUD: + Offset: 16686673 + Length: 14563 + ^Content/d2k/GAMESFX/OI_UNRDY.AUD: + Offset: 16701236 + Length: 13353 + ^Content/d2k/GAMESFX/O_VSEL3.AUD: + Offset: 16714589 + Length: 9671 + ^Content/d2k/GAMESFX/OI_1MIN.AUD: + Offset: 16724260 + Length: 15031 + ^Content/d2k/GAMESFX/OI_MAP7A.AUD: + Offset: 16739291 + Length: 28368 + ^Content/d2k/GAMESFX/HI_TRAIN.AUD: + Offset: 16767659 + Length: 9649 + ^Content/d2k/GAMESFX/HI_ULOST.AUD: + Offset: 16777308 + Length: 17157 + ^Content/d2k/GAMESFX/HI_UNRDY.AUD: + Offset: 16794465 + Length: 13407 + ^Content/d2k/GAMESFX/OI_MAP2A.AUD: + Offset: 16807872 + Length: 29910 + ^Content/d2k/GAMESFX/HI_REINF.AUD: + Offset: 16837782 + Length: 22890 + ^Content/d2k/GAMESFX/OI_MAP2C.AUD: + Offset: 16860672 + Length: 22923 + ^Content/d2k/GAMESFX/OI_MAP3A.AUD: + Offset: 16883595 + Length: 34017 + ^Content/d2k/GAMESFX/OI_MAP4A.AUD: + Offset: 16917612 + Length: 56714 + ^Content/d2k/GAMESFX/OI_SPORT.AUD: + Offset: 16974326 + Length: 27200 + ^Content/d2k/GAMESFX/OI_UPGOP.AUD: + Offset: 17001526 + Length: 19828 + ^Content/d2k/GAMESFX/OI_UPGRD.AUD: + Offset: 17021354 + Length: 13869 + ^Content/d2k/GAMESFX/OI_WATTK.AUD: + Offset: 17035223 + Length: 14197 + ^Content/d2k/GAMESFX/AI_MONEY.AUD: + Offset: 17049420 + Length: 29136 + ^Content/d2k/GAMESFX/AI_SELL.AUD: + Offset: 17078556 + Length: 26204 + ^Content/d2k/GAMESFX/HI_NEWOP.AUD: + Offset: 17104760 + Length: 24264 + ^Content/d2k/GAMESFX/AI_5MIN.AUD: + Offset: 17129024 + Length: 43921 + ^Content/d2k/GAMESFX/OI_HATTK.AUD: + Offset: 17172945 + Length: 22151 + ^Content/d2k/GAMESFX/H_VSEL2.AUD: + Offset: 17195096 + Length: 12300 + ^Content/d2k/GAMESFX/OI_MAP1B.AUD: + Offset: 17207396 + Length: 21971 + ^Content/d2k/GAMESFX/OI_MAP1C.AUD: + Offset: 17229367 + Length: 22041 + ^Content/d2k/GAMESFX/AI_GSAVE.AUD: + Offset: 17251408 + Length: 21545 + ^Content/d2k/GAMESFX/AI_GUARD.AUD: + Offset: 17272953 + Length: 14344 + ^Content/d2k/GAMESFX/AI_HATTK.AUD: + Offset: 17287297 + Length: 28156 + ^Content/d2k/GAMESFX/AI_HOLD.AUD: + Offset: 17315453 + Length: 16983 + ^Content/d2k/GAMESFX/HI_UPGOP.AUD: + Offset: 17332436 + Length: 19583 + ^Content/d2k/GAMESFX/HI_UPGRD.AUD: + Offset: 17352019 + Length: 12875 + ^Content/d2k/GAMESFX/OI_MAP2B.AUD: + Offset: 17364894 + Length: 20974 + ^Content/d2k/GAMESFX/HI_WSIGN.AUD: + Offset: 17385868 + Length: 14699 + ^Content/d2k/GAMESFX/HI_HATTK.AUD: + Offset: 17400567 + Length: 20919 + ^Content/d2k/GAMESFX/O_SCONF2.AUD: + Offset: 17421486 + Length: 18984 + ^Content/d2k/GAMESFX/HI_HOLD.AUD: + Offset: 17440470 + Length: 11779 + ^Content/d2k/GAMESFX/A_VSEL2.AUD: + Offset: 17452249 + Length: 13980 + ^Content/d2k/GAMESFX/AI_ATACK.AUD: + Offset: 17466229 + Length: 33483 + ^Content/d2k/GAMESFX/AI_BDRDY.AUD: + Offset: 17499712 + Length: 26566 + ^Content/d2k/GAMESFX/AI_BLOST.AUD: + Offset: 17526278 + Length: 25237 + ^Content/d2k/GAMESFX/AI_BUILD.AUD: + Offset: 17551515 + Length: 16072 + ^Content/d2k/GAMESFX/HI_GLOAD.AUD: + Offset: 17567587 + Length: 12037 + ^Content/d2k/GAMESFX/AI_CAPT.AUD: + Offset: 17579624 + Length: 30243 + ^Content/d2k/GAMESFX/AI_DHRDY.AUD: + Offset: 17609867 + Length: 31710 + ^Content/d2k/GAMESFX/AI_DPLOY.AUD: + Offset: 17641577 + Length: 27450 + ^Content/d2k/GAMESFX/AI_ENEMY.AUD: + Offset: 17669027 + Length: 30854 + ^Content/d2k/GAMESFX/A_VCONF1.AUD: + Offset: 17699881 + Length: 10860 + ^Content/d2k/GAMESFX/HI_PLACE.AUD: + Offset: 17710741 + Length: 19337 + ^Content/d2k/GAMESFX/HI_POWER.AUD: + Offset: 17730078 + Length: 15004 + ^Content/d2k/GAMESFX/HI_PREP.AUD: + Offset: 17745082 + Length: 23023 + ^Content/d2k/GAMESFX/HI_PRMRY.AUD: + Offset: 17768105 + Length: 22321 + ^Content/d2k/GAMESFX/OI_MONEY.AUD: + Offset: 17790426 + Length: 21698 + ^Content/d2k/GAMESFX/O_ISEL1.AUD: + Offset: 17812124 + Length: 10282 + ^Content/d2k/GAMESFX/OI_NEWOP.AUD: + Offset: 17822406 + Length: 28615 + ^Content/d2k/GAMESFX/A_VCONF3.AUD: + Offset: 17851021 + Length: 12771 + ^Content/d2k/GAMESFX/A_VSEL1.AUD: + Offset: 17863792 + Length: 9917 + ^Content/d2k/GAMESFX/OI_PLACE.AUD: + Offset: 17873709 + Length: 18502 + ^Content/d2k/GAMESFX/OI_POWER.AUD: + Offset: 17892211 + Length: 12832 + ^Content/d2k/GAMESFX/OI_PREP.AUD: + Offset: 17905043 + Length: 22413 + ^Content/d2k/GAMESFX/OI_PRMRY.AUD: + Offset: 17927456 + Length: 29577 + ^Content/d2k/GAMESFX/OI_REINF.AUD: + Offset: 17957033 + Length: 24798 + ^Content/d2k/GAMESFX/OI_RUN.AUD: + Offset: 17981831 + Length: 14784 + ^Content/d2k/GAMESFX/OI_CAPT.AUD: + Offset: 17996615 + Length: 18526 + ^Content/d2k/GAMESFX/H_ECONF1.AUD: + Offset: 18015141 + Length: 12390 + ^Content/d2k/GAMESFX/O_VSEL2.AUD: + Offset: 18027531 + Length: 11851 + ^Content/d2k/GAMESFX/H_VSEL3.AUD: + Offset: 18039382 + Length: 9867 + ^Content/d2k/GAMESFX/HI_1MIN.AUD: + Offset: 18049249 + Length: 16907 + ^Content/d2k/GAMESFX/HI_2MIN.AUD: + Offset: 18066156 + Length: 17659 + ^Content/d2k/GAMESFX/HI_3MIN.AUD: + Offset: 18083815 + Length: 20337 + ^Content/d2k/GAMESFX/HI_4MIN.AUD: + Offset: 18104152 + Length: 18877 + ^Content/d2k/GAMESFX/HI_5MIN.AUD: + Offset: 18123029 + Length: 30788 + ^Content/d2k/GAMESFX/HI_ABORT.AUD: + Offset: 18153817 + Length: 18322 + ^Content/d2k/GAMESFX/HI_ATACK.AUD: + Offset: 18172139 + Length: 22178 + ^Content/d2k/GAMESFX/HI_NROOM.AUD: + Offset: 18194317 + Length: 24878 + ^Content/d2k/GAMESFX/OI_SILOS.AUD: + Offset: 18219195 + Length: 15741 + ^Content/d2k/GAMESFX/A_FCONF4.AUD: + Offset: 18234936 + Length: 14892 + ^Content/d2k/GAMESFX/OI_MAP5A.AUD: + Offset: 18249828 + Length: 23026 + ^Content/d2k/GAMESFX/OI_MAP6A.AUD: + Offset: 18272854 + Length: 43938 + ^Content/d2k/GAMESFX/HI_CANCL.AUD: + Offset: 18316792 + Length: 10992 + ^Content/d2k/GAMESFX/HI_CAPT.AUD: + Offset: 18327784 + Length: 19514 + ^Content/d2k/GAMESFX/HI_DHRDY.AUD: + Offset: 18347298 + Length: 23895 + ^Content/d2k/GAMESFX/HI_DPLOY.AUD: + Offset: 18371193 + Length: 18626 + ^Content/d2k/GAMESFX/HI_ENEMY.AUD: + Offset: 18389819 + Length: 22564 + ^Content/d2k/GAMESFX/HI_GANEW.AUD: + Offset: 18412383 + Length: 18445 + ^Content/d2k/GAMESFX/OI_DHRDY.AUD: + Offset: 18430828 + Length: 19492 + ^Content/d2k/GAMESFX/HI_GSAVE.AUD: + Offset: 18450320 + Length: 14194 + ^Content/d2k/GAMESFX/HI_GUARD.AUD: + Offset: 18464514 + Length: 8310 + ^Content/d2k/GAMESFX/H_VSEL1.AUD: + Offset: 18472824 + Length: 8332 + ^Content/d2k/GAMESFX/OI_ORDER.AUD: + Offset: 18481156 + Length: 15789 + ^Content/d2k/GAMESFX/G_SCONF1.AUD: + Offset: 18496945 + Length: 9791 + ^Content/d2k/GAMESFX/G_SCONF2.AUD: + Offset: 18506736 + Length: 15099 + ^Content/d2k/GAMESFX/G_SCONF3.AUD: + Offset: 18521835 + Length: 14863 + ^Content/d2k/GAMESFX/G_SSEL1.AUD: + Offset: 18536698 + Length: 9753 + ^Content/d2k/GAMESFX/G_SSEL2.AUD: + Offset: 18546451 + Length: 9329 + ^Content/d2k/GAMESFX/G_SSEL3.AUD: + Offset: 18555780 + Length: 9449 + ^Content/d2k/GAMESFX/OI_SELL.AUD: + Offset: 18565229 + Length: 15600 + ^Content/d2k/GAMESFX/H_ECONF2.AUD: + Offset: 18580829 + Length: 16157 + ^Content/d2k/GAMESFX/H_ECONF3.AUD: + Offset: 18596986 + Length: 13149 + ^Content/d2k/GAMESFX/H_ESEL1.AUD: + Offset: 18610135 + Length: 13928 + ^Content/d2k/GAMESFX/H_ESEL2.AUD: + Offset: 18624063 + Length: 16430 + ^Content/d2k/GAMESFX/AI_MAP2C.AUD: + Offset: 18640493 + Length: 41640 + ^Content/d2k/GAMESFX/AI_MAP3A.AUD: + Offset: 18682133 + Length: 41809 + ^Content/d2k/GAMESFX/AI_MAP4A.AUD: + Offset: 18723942 + Length: 29117 + ^Content/d2k/GAMESFX/AI_MAP5A.AUD: + Offset: 18753059 + Length: 36982 + ^Content/d2k/GAMESFX/AI_MAP6A.AUD: + Offset: 18790041 + Length: 60681 + ^Content/d2k/GAMESFX/HI_BDRDY.AUD: + Offset: 18850722 + Length: 21396 + ^Content/d2k/GAMESFX/AI_MAP8A.AUD: + Offset: 18872118 + Length: 37995 + ^Content/d2k/GAMESFX/AI_MAP9A.AUD: + Offset: 18910113 + Length: 32674 + ^Content/d2k/GAMESFX/AI_MEND.AUD: + Offset: 18942787 + Length: 18399 + ^Content/d2k/GAMESFX/AI_MFAIL.AUD: + Offset: 18961186 + Length: 26359 + ^Content/d2k/GAMESFX/AI_GLOAD.AUD: + Offset: 18987545 + Length: 21335 + ^Content/d2k/GAMESFX/HI_MAP9A.AUD: + Offset: 19008880 + Length: 28418 + ^Content/d2k/GAMESFX/HI_MEND.AUD: + Offset: 19037298 + Length: 9269 + ^Content/d2k/GAMESFX/HI_MFAIL.AUD: + Offset: 19046567 + Length: 19854 + ^Content/d2k/GAMESFX/HI_MONEY.AUD: + Offset: 19066421 + Length: 20038 + ^Content/d2k/GAMESFX/HI_MWIN.AUD: + Offset: 19086459 + Length: 16073 + ^Content/d2k/GAMESFX/HI_WATTK.AUD: + Offset: 19102532 + Length: 14873 + ^Content/d2k/GAMESFX/AI_MAP1A.AUD: + Offset: 19117405 + Length: 41683 + ^Content/d2k/GAMESFX/AI_MAP1B.AUD: + Offset: 19159088 + Length: 34475 + ^Content/d2k/GAMESFX/AI_MAP1C.AUD: + Offset: 19193563 + Length: 34903 + ^Content/d2k/GAMESFX/AI_MAP2A.AUD: + Offset: 19228466 + Length: 59613 + ^Content/d2k/GAMESFX/AI_ABORT.AUD: + Offset: 19288079 + Length: 22150 + ^Content/d2k/GAMESFX/H_ESEL3.AUD: + Offset: 19310229 + Length: 9090 + ^Content/d2k/GAMESFX/AI_SILOS.AUD: + Offset: 19319319 + Length: 21350 + ^Content/d2k/GAMESFX/AI_SPORT.AUD: + Offset: 19340669 + Length: 31478 + ^Content/d2k/GAMESFX/AI_TRAIN.AUD: + Offset: 19372147 + Length: 19876 + ^Content/d2k/GAMESFX/AI_ULOST.AUD: + Offset: 19392023 + Length: 22359 + ^Content/d2k/GAMESFX/AI_MAP7A.AUD: + Offset: 19414382 + Length: 28902 + ^Content/d2k/GAMESFX/AI_UPGOP.AUD: + Offset: 19443284 + Length: 26855 + ^Content/d2k/GAMESFX/AI_UPGRD.AUD: + Offset: 19470139 + Length: 19104 + ^Content/d2k/GAMESFX/AI_WATTK.AUD: + Offset: 19489243 + Length: 24655 + ^Content/d2k/GAMESFX/AI_WSIGN.AUD: + Offset: 19513898 + Length: 23032 + ^Content/d2k/GAMESFX/AI_MAP2B.AUD: + Offset: 19536930 + Length: 35588 + ^Content/d2k/GAMESFX/A_ICONF1.AUD: + Offset: 19572518 + Length: 8945 + ^Content/d2k/GAMESFX/A_ICONF2.AUD: + Offset: 19581463 + Length: 9005 + ^Content/d2k/GAMESFX/A_ICONF3.AUD: + Offset: 19590468 + Length: 9606 + ^Content/d2k/GAMESFX/A_ISEL1.AUD: + Offset: 19600074 + Length: 11671 + ^Content/d2k/GAMESFX/OI_CANCL.AUD: + Offset: 19611745 + Length: 10644 + ^Content/d2k/GAMESFX/H_ISEL2.AUD: + Offset: 19622389 + Length: 10387 + ^Content/d2k/GAMESFX/H_ISEL3.AUD: + Offset: 19632776 + Length: 17225 + ^Content/d2k/GAMESFX/H_VCONF1.AUD: + Offset: 19650001 + Length: 10077 + ^Content/d2k/GAMESFX/H_VCONF2.AUD: + Offset: 19660078 + Length: 13616 + ^Content/d2k/GAMESFX/H_VCONF3.AUD: + Offset: 19673694 + Length: 11251 + ^Content/d2k/GAMESFX/OI_TRAIN.AUD: + Offset: 19684945 + Length: 8144 + ^Content/d2k/GAMESFX/HI_ORDER.AUD: + Offset: 19693089 + Length: 14865 + ^Content/d2k/GAMESFX/OI_WSIGN.AUD: + Offset: 19707954 + Length: 11912 + ^Content/d2k/GAMESFX/OI_BLOST.AUD: + Offset: 19719866 + Length: 19540 + ^Content/d2k/GAMESFX/OI_BUILD.AUD: + Offset: 19739406 + Length: 10246 + ^Content/d2k/GAMESFX/AI_LAUNC.AUD: + Offset: 19749652 + Length: 31148 + ^Content/d2k/GAMESFX/A_ISEL3.AUD: + Offset: 19780800 + Length: 8307 + ^Content/d2k/GAMESFX/A_VCONF2.AUD: + Offset: 19789107 + Length: 14331 + ^Content/d2k/GAMESFX/OI_HOLD.AUD: + Offset: 19803438 + Length: 11295 + ^Content/d2k/GAMESFX/OI_LAUNC.AUD: + Offset: 19814733 + Length: 20437 + ^Content/d2k/GAMESFX/OI_MAP1A.AUD: + Offset: 19835170 + Length: 27739 + ^Content/d2k/GAMESFX/HI_LAUNC.AUD: + Offset: 19862909 + Length: 22200 + ^Content/d2k/GAMESFX/H_ICONF1.AUD: + Offset: 19885109 + Length: 9620 + ^Content/d2k/GAMESFX/H_ICONF2.AUD: + Offset: 19894729 + Length: 13368 + ^Content/d2k/GAMESFX/H_ICONF3.AUD: + Offset: 19908097 + Length: 15612 + ^Content/d2k/GAMESFX/H_ISEL1.AUD: + Offset: 19923709 + Length: 8279 + ^Content/d2k/GAMESFX/A_ISEL2.AUD: + Offset: 19931988 + Length: 11383 + ^Content/d2k/GAMESFX/AI_RUN.AUD: + Offset: 19943371 + Length: 18511 + ^Content/d2k/GAMESFX/HI_SILOS.AUD: + Offset: 19961882 + Length: 14244 + ^Content/d2k/GAMESFX/HI_MAP1A.AUD: + Offset: 19976126 + Length: 24075 + ^Content/d2k/GAMESFX/HI_MAP1B.AUD: + Offset: 20000201 + Length: 26716 + ^Content/d2k/GAMESFX/HI_MAP1C.AUD: + Offset: 20026917 + Length: 21716 + ^Content/d2k/GAMESFX/HI_MAP2A.AUD: + Offset: 20048633 + Length: 32417 + ^Content/d2k/GAMESFX/HI_MAP2B.AUD: + Offset: 20081050 + Length: 33724 + ^Content/d2k/GAMESFX/HI_MAP2C.AUD: + Offset: 20114774 + Length: 21828 + ^Content/d2k/GAMESFX/HI_MAP3A.AUD: + Offset: 20136602 + Length: 30404 + ^Content/d2k/GAMESFX/O_ISEL3.AUD: + Offset: 20167006 + Length: 9862 + ^Content/d2k/GAMESFX/O_SCONF1.AUD: + Offset: 20176868 + Length: 18149 + ^Content/d2k/GAMESFX/OI_2MIN.AUD: + Offset: 20195017 + Length: 14697 + ^Content/d2k/GAMESFX/OI_3MIN.AUD: + Offset: 20209714 + Length: 17316 + ^Content/d2k/GAMESFX/OI_4MIN.AUD: + Offset: 20227030 + Length: 14869 + ^Content/d2k/GAMESFX/OI_5MIN.AUD: + Offset: 20241899 + Length: 29873 + ^Content/d2k/GAMESFX/OI_ABORT.AUD: + Offset: 20271772 + Length: 16335 + ^Content/d2k/GAMESFX/OI_ATACK.AUD: + Offset: 20288107 + Length: 20565 + ^Content/d2k/GAMESFX/OI_BDRDY.AUD: + Offset: 20308672 + Length: 25497 + ^Content/d2k/GAMESFX/HI_SELL.AUD: + Offset: 20334169 + Length: 17142 + ^Content/d2k/GAMESFX/OI_DPLOY.AUD: + Offset: 20351311 + Length: 20120 + ^Content/d2k/GAMESFX/AI_PLACE.AUD: + Offset: 20371431 + Length: 29921 + ^Content/d2k/GAMESFX/OI_GANEW.AUD: + Offset: 20401352 + Length: 14467 + ^Content/d2k/GAMESFX/OI_GLOAD.AUD: + Offset: 20415819 + Length: 10906 + ^Content/d2k/GAMESFX/AI_MWIN.AUD: + Offset: 20426725 + Length: 25959 + ^Content/d2k/GAMESFX/AI_NEWOP.AUD: + Offset: 20452684 + Length: 34175 + ^Content/d2k/GAMESFX/AI_NROOM.AUD: + Offset: 20486859 + Length: 30124 + ^Content/d2k/GAMESFX/AI_ORDER.AUD: + Offset: 20516983 + Length: 21881 + ^Content/d2k/GAMESFX/AI_UNRDY.AUD: + Offset: 20538864 + Length: 20567 + ^Content/d2k/SOUND.RS: + Offset: 20559431 + Length: 1929247 diff --git a/mods/modchooser/chrome.png b/mods/modchooser/chrome.png index ce09238bda..7659af598a 100644 Binary files a/mods/modchooser/chrome.png and b/mods/modchooser/chrome.png differ diff --git a/mods/modchooser/chrome.yaml b/mods/modchooser/chrome.yaml index 632e84ca8a..cea14509ba 100644 --- a/mods/modchooser/chrome.yaml +++ b/mods/modchooser/chrome.yaml @@ -31,6 +31,17 @@ panel-thinborder: chrome.png corner-bl: 1,573,2,2 corner-br: 61,573,2,2 +panel-thinborder-light: chrome.png + background: 643,515,58,58 + border-r: 701,515,2,58 + border-l: 641,515,2,58 + border-b: 643,573,58,2 + border-t: 643,513,58,2 + corner-tl: 641,513,2,2 + corner-tr: 701,513,2,2 + corner-bl: 641,573,2,2 + corner-br: 701,573,2,2 + button: chrome.png background: 138,522,44,44 border-r: 182,522,10,44 @@ -53,19 +64,9 @@ button-hover: chrome.png corner-bl: 192,566,10,10 corner-br: 246,566,10,10 -# Copy of button button-disabled: chrome.png - background: 138,522,44,44 - border-r: 182,522,10,44 - border-l: 128,522,10,44 - border-b: 138,566,44,10 - border-t: 138,512,44,10 - corner-tl: 128,512,10,10 - corner-tr: 182,512,10,10 - corner-bl: 128,566,10,10 - corner-br: 182,566,10,10 + Inherits: button -# Copy of button-highlighted-hover button-pressed: chrome.png background: 330,522,44,44 border-r: 374,522,10,44 @@ -89,40 +90,42 @@ button-highlighted: chrome.png corner-br: 310,566,10,10 button-highlighted-hover: chrome.png - background: 330,522,44,44 - border-r: 374,522,10,44 - border-l: 320,522,10,44 - border-b: 330,566,44,10 - border-t: 330,512,44,10 - corner-tl: 320,512,10,10 - corner-tr: 374,512,10,10 - corner-bl: 320,566,10,10 - corner-br: 374,566,10,10 + Inherits: button-pressed -# Copy of button-mod-highlighted-hover button-highlighted-pressed: chrome.png - background: 330,522,44,44 - border-r: 374,522,10,44 - border-l: 320,522,10,44 - border-b: 330,566,44,10 - border-t: 330,512,44,10 - corner-tl: 320,512,10,10 - corner-tr: 374,512,10,10 - corner-bl: 320,566,10,10 - corner-br: 374,566,10,10 + Inherits: button-pressed - -# Copy of button-mod-highlighted button-highlighted-disabled: chrome.png - background: 266,522,44,44 - border-r: 310,522,10,44 - border-l: 256,522,10,44 - border-b: 266,566,44,10 - border-t: 266,512,44,10 - corner-tl: 256,512,10,10 - corner-tr: 310,512,10,10 - corner-bl: 256,566,10,10 - corner-br: 310,566,10,10 + Inherits: button-highlighted + +button-highlighted-thin: chrome.png + background: 522,522,44,44 + border-r: 566,522,10,44 + border-l: 512,522,10,44 + border-b: 522,566,44,10 + border-t: 522,512,44,10 + corner-tl: 512,512,10,10 + corner-tr: 566,512,10,10 + corner-bl: 512,566,10,10 + corner-br: 566,566,10,10 + +button-highlighted-thin-hover: chrome.png + Inherits: button-highlighted-thin-pressed + +button-highlighted-thin-pressed: chrome.png + background: 586,522,44,44 + border-r: 630,522,10,44 + border-l: 576,522,10,44 + border-b: 586,566,44,10 + border-t: 586,512,44,10 + corner-tl: 576,512,10,10 + corner-tr: 630,512,10,10 + corner-bl: 576,566,10,10 + corner-br: 630,566,10,10 + +button-highlighted-thin-disabled: chrome.png + Inherits: button-highlighted-thin + progressbar-bg: chrome.png background: 453,565,56,6 @@ -155,4 +158,26 @@ background: chrome.png modchooser: chrome.png logo: 0,576,280,128 leftarrow:384,512,20,64 - rightarrow:404,512,20,64 \ No newline at end of file + rightarrow:404,512,20,64 + cdicon: 448,512,20,20 + +scrollpanel-bg: chrome.png + Inherits: panel-thinborder + +scrollpanel-button: chrome.png + Inherits: panel-thinborder + +scrollpanel-button-hover: chrome.png + Inherits: panel-thinborder-light + +scrollpanel-button-disabled: chrome.png + Inherits: panel-thinborder + +scrollpanel-button-pressed: chrome.png + Inherits: panel-thinborder-light + +scrollbar: chrome.png + down_arrow: 480,512,16,16 + down_pressed: 480,512,16,16 + up_arrow: 480,528,16,16 + up_pressed: 480,528,16,16 diff --git a/mods/modchooser/content.yaml b/mods/modchooser/content.yaml new file mode 100644 index 0000000000..7c35ad2e3a --- /dev/null +++ b/mods/modchooser/content.yaml @@ -0,0 +1,370 @@ +Background@CONTENT_PANEL: + Logic: ModContentLogic + X: (WINDOW_RIGHT - WIDTH) / 2 + Y: (WINDOW_BOTTOM - HEIGHT) / 2 + Width: 500 + Height: 268 + Background: panel-bg + Children: + Background@RULE: + X: 30 + Y: 50 + Width: 440 + Height: 150 + Background: panel-rule + Label@TITLE: + X: 0 + Y: 12 + Width: PARENT_RIGHT + Height: 25 + Text: Manage Content + Align: Center + Font: MediumBold + Label@HEADER_TEMPLATE: + Y: 65 + Width: PARENT_RIGHT + Height: 16 + Align: Center + ScrollPanel@PACKAGES: + X: 30 + Y: 84 + Width: PARENT_RIGHT - 60 + Height: 115 + TopBottomSpacing: 4 + ItemSpacing: 2 + BorderWidth: 2 + Children: + Container@PACKAGE_TEMPLATE: + X: 6 + Width: PARENT_RIGHT - 16 + Height: 23 + Children: + Label@TITLE: + Width: 275 + Height: 23 + Label@REQUIRED: + X: 185 + Y: 0-2 + Width: 90 + Height: 23 + Align: Center + Font: Bold + TextColor: CC0000 + Text: Required + Image@DISC: + X: 275 + Y: 1 + Width: 20 + Height: 20 + ImageCollection: modchooser + ImageName: cdicon + TooltipContainer: TOOLTIP_CONTAINER + TooltipTemplate: DISC_TOOLTIP + Button@DOWNLOAD: + X: 304 + Y: 0 + Width: 100 + Height: 23 + Background: button-highlighted-thin + Text: Download + Label@INSTALLED: + X: 304 + Y: 0-2 + Width: 100 + Height: 23 + Align: Center + Font: Bold + TextColor: 00CC00 + Text: Installed + Label@REQUIRES_DISC: + X: 304 + Y: 0-2 + Width: 100 + Height: 23 + Align: Center + Font: Bold + TextColor: DDDDDD + Text: Requires Disc + Button@CHECK_DISC_BUTTON: + X: 30 + Y: PARENT_BOTTOM - 52 + Background: button-highlighted + Width: 110 + Height: 32 + Text: Detect Disc + Font: Bold + Button@BACK_BUTTON: + X: PARENT_RIGHT - 140 + Y: PARENT_BOTTOM - 52 + Background: button-highlighted + Width: 110 + Height: 32 + Text: Back + Font: Bold + Key: escape + TooltipContainer@TOOLTIP_CONTAINER: + +Background@DISC_TOOLTIP: + Logic: ModContentDiscTooltipLogic + Background: panel-thinborder + Height: 25 + Children: + Label@DESCRIPTION: + X: 5 + Height: 23 + Font: Bold + Text: Content available from: + Container@DISCS: + Y: 15 + Width: PARENT_RIGHT - 10 + Height: 7 # used as bottom margin + Children: + Label@DISC_TEMPLATE: + X: 20 + Height: 14 + Font: TinyBold + +Container@PACKAGE_DOWNLOAD_PANEL: + Logic: DownloadPackageLogic + X: (WINDOW_RIGHT - WIDTH) / 2 + Y: (WINDOW_BOTTOM - HEIGHT) / 2 + Width: 500 + Height: 177 + Children: + Background: + Width: PARENT_RIGHT + Height: PARENT_BOTTOM + Background: panel-bg + Background@RULE: + X: 30 + Y: 50 + Width: 440 + Height: 150 + Background: panel-rule + Label@TITLE: + X: 0 + Y: 12 + Width: PARENT_RIGHT + Height: 25 + Align: Center + Font: MediumBold + ProgressBar@PROGRESS_BAR: + X: 30 + Y: 64 + Width: PARENT_RIGHT - 60 + Height: 16 + BarMargin: 0, 0 + Label@STATUS_LABEL: + X: 30 + Y: 85 + Width: PARENT_RIGHT - 60 + Height: 25 + Align: Left + Button@RETRY_BUTTON: + X: 30 + Y: PARENT_BOTTOM - 52 + Background: button-highlighted + Width: 120 + Height: 32 + Visible: false + Text: Retry + Font: Bold + Key: return + Button@CANCEL_BUTTON: + X: PARENT_RIGHT - 30 - WIDTH + Y: PARENT_BOTTOM - 52 + Background: button-highlighted + Width: 110 + Height: 32 + Text: Cancel + Font: Bold + Key: escape + +Background@DISC_INSTALL_PANEL: + Logic: InstallFromDiscLogic + X: (WINDOW_RIGHT - WIDTH)/2 + Y: (WINDOW_BOTTOM - HEIGHT)/2 + Width: 500 + Height: 177 + Background: panel-bg + Children: + Background@RULE: + X: 30 + Y: 50 + Width: 440 + Height:150 + Background: panel-rule + Label@TITLE: + Y: 12 + Width: PARENT_RIGHT + Height: 25 + Align: Center + Font: MediumBold + Container@PROGRESS: + Width: PARENT_RIGHT + Height: PARENT_BOTTOM + Visible: false + Children: + ProgressBar@PROGRESS_BAR: + X: 30 + Y: 60 + Width: PARENT_RIGHT - 60 + Height: 16 + BarMargin: 0, 0 + Label@PROGRESS_MESSAGE: + X: 30 + Y: 80 + Width: PARENT_RIGHT - 60 + Height: 25 + Align: Left + Container@MESSAGE: + Width: PARENT_RIGHT + Height: PARENT_BOTTOM + Height: 157 + Visible: false + Children: + Label@MESSAGE_MESSAGE: + Y: 65 + Width: PARENT_RIGHT + Height: 25 + Align: Center + Container@LIST: + Width: PARENT_RIGHT + Height: 268 + Visible: false + Children: + Label@LIST_MESSAGE: + Y: 65 + Width: PARENT_RIGHT + Height: 16 + Align: Center + ScrollPanel@LIST_PANEL: + X: 30 + Y: 99 + Width: PARENT_RIGHT - 60 + Height: 100 + TopBottomSpacing: 4 + ItemSpacing: 2 + BorderWidth: 2 + Children: + Label@LIST_TEMPLATE: + X: 6 + Width: PARENT_RIGHT - 16 + Height: 23 + Button@PRIMARY_BUTTON: + X: 30 + Y: PARENT_BOTTOM - 52 + Background: button-highlighted + Width: 110 + Height: 32 + Font: Bold + Key: return + Button@SECONDARY_BUTTON: + X: PARENT_RIGHT - 140 + Y: PARENT_BOTTOM - 52 + Background: button-highlighted + Width: 110 + Height: 32 + Font: Bold + Key: escape + +Background@CONTENT_PROMPT_PANEL: + Logic: ModContentPromptLogic + X: (WINDOW_RIGHT - WIDTH)/2 + Y: (WINDOW_BOTTOM - HEIGHT)/2 + Width: 500 + Height: 140 + Background: panel-bg + Children: + Background@RULE: + X: 30 + Y: 50 + Width: 440 + Height: 150 + Background: panel-rule + Label@TITLE: + X: 0 + Y: 12 + Width: PARENT_RIGHT + Height: 25 + Text: Install Content + Align: Center + Font: MediumBold + Label@HEADER_TEMPLATE: + Y: 65 + Width: PARENT_RIGHT + Height: 16 + Align: Center + Button@ADVANCED_BUTTON: + X: 30 + Y: PARENT_BOTTOM - 52 + Background: button-highlighted + Width: 140 + Height: 32 + Text: Advanced Install + Font: Bold + Button@QUICK_BUTTON: + X: 185 + Y: PARENT_BOTTOM - 52 + Background: button-highlighted + Width: 110 + Height: 32 + Text: Quick Install + Font: Bold + Button@BACK_BUTTON: + X: PARENT_RIGHT - WIDTH - 30 + Y: PARENT_BOTTOM - 52 + Background: button-highlighted + Width: 110 + Height: 32 + Text: Back + Font: Bold + Key: escape + +Container@INSTALL_MOD_PANEL: + Logic: InstallModLogic + X: (WINDOW_RIGHT - WIDTH)/2 + Y: (WINDOW_BOTTOM - HEIGHT)/2 + Width: 500 + Height: 177 + Children: + Background: + Width: PARENT_RIGHT + Height: PARENT_BOTTOM + Background: panel-bg + Background@RULE: + X: 30 + Y: 50 + Width: 440 + Height: 150 + Background: panel-rule + Label@TITLE: + X: 0 + Y: 12 + Width: PARENT_RIGHT + Height: 25 + Text: Missing dependencies + Align: Center + Font: MediumBold + Label@DESC: + X: 0 + Y: 65 + Width: PARENT_RIGHT + Height: 25 + Align: Center + Text: Please fully install the following mods then try again: + Label@MOD_LIST: + X: 0 + Y: 85 + Width: PARENT_RIGHT + Height: 25 + Align: Center + Button@BACK_BUTTON: + X: PARENT_RIGHT - 130 + Y: PARENT_BOTTOM - 52 + Background: button-highlighted + Width: 110 + Height: 32 + Text: Back + Font: Bold + Key: escape diff --git a/mods/modchooser/install.yaml b/mods/modchooser/install.yaml deleted file mode 100644 index 92921272d2..0000000000 --- a/mods/modchooser/install.yaml +++ /dev/null @@ -1,309 +0,0 @@ -Container@INSTALL_PANEL: - Logic: InstallLogic - X: (WINDOW_RIGHT - WIDTH)/2 - Y: (WINDOW_BOTTOM - HEIGHT)/2 - Width: 500 - Height: 177 - Children: - Background: - Width: PARENT_RIGHT - Height: PARENT_BOTTOM - Background: panel-bg - Background@RULE: - X: 30 - Y: 50 - Width: 440 - Height:150 - Background:panel-rule - Label@TITLE: - X: 0 - Y: 12 - Width: PARENT_RIGHT - Height: 25 - Text: Install Assets - Align: Center - Font: MediumBold - Label@DESC1: - X: 0 - Y: 65 - Width: PARENT_RIGHT - Height: 25 - Align: Center - Label@DESC2: - X: 0 - Y: 85 - Width: PARENT_RIGHT - Height: 25 - Text: Content can be downloaded (if available), or copied from the install CD. - Align: Center - Button@DOWNLOAD_BUTTON: - X: 20 - Y: PARENT_BOTTOM - 52 - Background:button-highlighted - Width: 110 - Height: 32 - Text: Download - Font: Bold - Button@INSTALL_BUTTON: - X: 140 - Y: PARENT_BOTTOM - 52 - Background:button-highlighted - Width: 110 - Height: 32 - Text: Use CD - Font: Bold - Button@BACK_BUTTON: - X: PARENT_RIGHT - 130 - Y: PARENT_BOTTOM - 52 - Background:button-highlighted - Width: 110 - Height: 32 - Text: Back - Font: Bold - Key: escape - -Container@INSTALL_DOWNLOAD_PANEL: - Logic: DownloadPackagesLogic - X: (WINDOW_RIGHT - WIDTH)/2 - Y: (WINDOW_BOTTOM - HEIGHT)/2 - Width: 500 - Height: 177 - Children: - Background: - Width: PARENT_RIGHT - Height: PARENT_BOTTOM - Background: panel-bg - Background@RULE: - X: 30 - Y: 50 - Width: 440 - Height:150 - Background:panel-rule - Label@TITLE: - X: 0 - Y: 12 - Width: PARENT_RIGHT - Height: 25 - Align: Center - Font: MediumBold - ProgressBar@PROGRESS_BAR: - X: 50 - Y: 64 - Width: PARENT_RIGHT - 100 - Height: 16 - BarMargin: 0, 0 - Label@STATUS_LABEL: - X: 36 - Y: 85 - Width: PARENT_RIGHT - 100 - Height: 25 - Align: Left - Button@RETRY_BUTTON: - X: PARENT_RIGHT - 280 - Y: PARENT_BOTTOM - 52 - Background:button-highlighted - Width: 120 - Height: 32 - Visible: false - Text: Retry - Font: Bold - Key: return - Button@CANCEL_BUTTON: - X: PARENT_RIGHT - 130 - Y: PARENT_BOTTOM - 52 - Background:button-highlighted - Width: 110 - Height: 32 - Text: Cancel - Font: Bold - Key: escape - -Container@INSTALL_FROMCD_PANEL: - Logic: InstallFromCDLogic - X: (WINDOW_RIGHT - WIDTH)/2 - Y: (WINDOW_BOTTOM - HEIGHT)/2 - Width: 500 - Height: 177 - Children: - Background: - Width: PARENT_RIGHT - Height: PARENT_BOTTOM - Background: panel-bg - Background@RULE: - X: 30 - Y: 50 - Width: 440 - Height:150 - Background:panel-rule - Label@TITLE: - X: 0 - Y: 12 - Width: PARENT_RIGHT - Height: 25 - Text: Fetching assets from CD... - Align: Center - Font: MediumBold - Container@INSTALLING: - Width: PARENT_RIGHT - Height: PARENT_BOTTOM - Visible: false - Children: - ProgressBar@PROGRESS_BAR: - X: 50 - Y: 60 - Width: PARENT_RIGHT - 100 - Height: 16 - BarMargin: 0, 0 - Label@STATUS_LABEL: - X: 36 - Y: 80 - Width: PARENT_RIGHT - 100 - Height: 25 - Align: Left - Container@INSERT_DISK: - Width: PARENT_RIGHT - Height: PARENT_BOTTOM - Visible: false - Children: - Label@INFO1: - Y: 65 - Width: PARENT_RIGHT - Height: 25 - Text: Disk not found. - Align: Center - Label@INFO2: - Y: 85 - Width: PARENT_RIGHT - Height: 25 - Align: Center - Button@RETRY_BUTTON: - X: 20 - Y: PARENT_BOTTOM - 52 - Background:button-highlighted - Width: 110 - Height: 32 - Text: Retry - Font: Bold - Key: return - Button@BACK_BUTTON: - X: PARENT_RIGHT - 130 - Y: PARENT_BOTTOM - 52 - Background:button-highlighted - Width: 110 - Height: 32 - Text: Back - Font: Bold - Key: escape - - -Container@INSTALL_MUSIC_PANEL: - Logic: InstallMusicLogic - X: (WINDOW_RIGHT - WIDTH)/2 - Y: (WINDOW_BOTTOM - HEIGHT)/2 - Width: 500 - Height: 177 - Children: - Background: - Width: PARENT_RIGHT - Height: PARENT_BOTTOM - Background: panel-bg - Background@RULE: - X: 30 - Y: 50 - Width: 440 - Height:150 - Background:panel-rule - Label@TITLE: - X: 0 - Y: 12 - Width: PARENT_RIGHT - Height: 25 - Text: Install Music - Align: Center - Font: MediumBold - Label@DESC1: - X: 0 - Y: 65 - Width: PARENT_RIGHT - Height: 25 - Text: OpenRA can download the music files from the internet (if available), - Align: Center - Label@DESC2: - X: 0 - Y: 85 - Width: PARENT_RIGHT - Height: 25 - Text: or you can install them from an original CD. - Align: Center - Button@DOWNLOAD_MUSIC_BUTTON: - X: 20 - Y: PARENT_BOTTOM - 52 - Background:button-highlighted - Width: 110 - Height: 32 - Text: Download - Font: Bold - Button@INSTALL_MUSIC_BUTTON: - X: 140 - Y: PARENT_BOTTOM - 52 - Background:button-highlighted - Width: 110 - Height: 32 - Text: Use CD - Font: Bold - Button@BACK_BUTTON: - X: PARENT_RIGHT - 130 - Y: PARENT_BOTTOM - 52 - Background:button-highlighted - Width: 110 - Height: 32 - Text: Back - Font: Bold - Key: escape -Container@INSTALL_MOD_PANEL: - Logic: InstallModLogic - X: (WINDOW_RIGHT - WIDTH)/2 - Y: (WINDOW_BOTTOM - HEIGHT)/2 - Width: 500 - Height: 177 - Children: - Background: - Width: PARENT_RIGHT - Height: PARENT_BOTTOM - Background: panel-bg - Background@RULE: - X: 30 - Y: 50 - Width: 440 - Height: 150 - Background: panel-rule - Label@TITLE: - X: 0 - Y: 12 - Width: PARENT_RIGHT - Height: 25 - Text: Missing dependencies - Align: Center - Font: MediumBold - Label@DESC: - X: 0 - Y: 65 - Width: PARENT_RIGHT - Height: 25 - Align: Center - Text: Please fully install the following mods then try again: - Label@MOD_LIST: - X: 0 - Y: 85 - Width: PARENT_RIGHT - Height: 25 - Align: Center - Button@BACK_BUTTON: - X: PARENT_RIGHT - 130 - Y: PARENT_BOTTOM - 52 - Background: button-highlighted - Width: 110 - Height: 32 - Text: Back - Font: Bold - Key: escape diff --git a/mods/modchooser/mod.yaml b/mods/modchooser/mod.yaml index 96ce3e0d00..148466d6ac 100644 --- a/mods/modchooser/mod.yaml +++ b/mods/modchooser/mod.yaml @@ -22,7 +22,7 @@ Assemblies: ChromeLayout: modchooser|modchooser.yaml - modchooser|install.yaml + modchooser|content.yaml Notifications: modchooser|notifications.yaml diff --git a/mods/modchooser/modchooser.yaml b/mods/modchooser/modchooser.yaml index a4d83bc54e..c4ce98d92f 100644 --- a/mods/modchooser/modchooser.yaml +++ b/mods/modchooser/modchooser.yaml @@ -1,162 +1,169 @@ Background@MODCHOOSER_BACKGROUND: Background: background - Width:WINDOW_RIGHT - Height:WINDOW_BOTTOM + Width: WINDOW_RIGHT + Height: WINDOW_BOTTOM Background@MODCHOOSER_DIALOG: - Logic:ModBrowserLogic + Logic: ModBrowserLogic Children: Container: - X:(WINDOW_RIGHT - WIDTH)/2 - Y:(WINDOW_BOTTOM - 500)/2 - Width:750 - Height:550-4-32 + X: (WINDOW_RIGHT - WIDTH) / 2 + Y: (WINDOW_BOTTOM - 500) / 2 + Width: 750 + Height: 514 Children: Background@DIALOG_BACKGROUND: - Y:69 - Width:PARENT_RIGHT - Height:PARENT_BOTTOM - 69 - Background:panel-bg + Y: 69 + Width: PARENT_RIGHT + Height: PARENT_BOTTOM - 69 + Background: panel-bg Children: Label: - X:53 - Y:30 - Align:Left - Font:MediumBold - Text:Choose your Battlefield: + X: 53 + Y: 30 + Align: Left + Font: MediumBold + Text: Choose your Battlefield: Container@MOD_LIST: - X:53 - Y:60 - Width:PARENT_RIGHT-106 - Height:150 + X: 53 + Y: 60 + Width: PARENT_RIGHT-106 + Height: 150 Children: Button@MOD_TEMPLATE: - X:16 - Width:114 - Height:114 - TooltipContainer:TOOLTIP_CONTAINER - IgnoreChildMouseOver:true + X: 16 + Width: 114 + Height: 114 + TooltipContainer: TOOLTIP_CONTAINER + IgnoreChildMouseOver: true Children: Container@MOD_NO_LOGO: - Width:PARENT_RIGHT - Height:PARENT_BOTTOM + Width: PARENT_RIGHT + Height: PARENT_BOTTOM Children: Label@A: - Width:PARENT_RIGHT - Height:PARENT_BOTTOM-20 - Text:Missing or - Align:center + Width: PARENT_RIGHT + Height: PARENT_BOTTOM-20 + Text: Missing or + Align: Center Label@B: - Y:20 - Width:PARENT_RIGHT - Height:PARENT_BOTTOM-20 - Text:invalid logo - Align:center + Y: 20 + Width: PARENT_RIGHT + Height: PARENT_BOTTOM-20 + Text: invalid logo + Align: Center RGBASprite@MOD_LOGO: - X:9 - Y:9 + X: 9 + Y: 9 Button@PREV_MOD: - X:15 - Y:60+41-16 - Width:25 - Height:64 - IgnoreChildMouseOver:true + X: 15 + Y: 85 + Width: 25 + Height: 64 + IgnoreChildMouseOver: true Children: Image: - X:2 - ImageCollection:modchooser - ImageName:leftarrow + X: 2 + ImageCollection: modchooser + ImageName: leftarrow Button@NEXT_MOD: - X:PARENT_RIGHT - WIDTH - 20 - Y:60+41-16 - Width:25 - Height:64 - IgnoreChildMouseOver:true + X: PARENT_RIGHT - WIDTH - 20 + Y: 85 + Width: 25 + Height: 64 + IgnoreChildMouseOver: true Children: Image: - X:3 - ImageCollection:modchooser - ImageName:rightarrow + X: 3 + ImageCollection: modchooser + ImageName: rightarrow Background@RULE: - X:53 - Y:PARENT_BOTTOM - 249 - Width:PARENT_RIGHT-106 - Height:150 - Background:panel-rule + X: 30 + Y: PARENT_BOTTOM - 249 + Width: PARENT_RIGHT - 60 + Height: 150 + Background: panel-rule Label@MOD_TITLE: - X:PARENT_RIGHT - 53 - 140 - 170 - Y:PARENT_BOTTOM-220 - Align:Left - Font:Bold + X: PARENT_RIGHT - 400 + Y: PARENT_BOTTOM-220 + Align: Left + Font: Bold Label@MOD_AUTHOR: - X:PARENT_RIGHT - 53 - 140 - 170 - Y:PARENT_BOTTOM-205 - Align:Left - Font:TinyBold + X: PARENT_RIGHT - 400 + Y: PARENT_BOTTOM-205 + Align: Left + Font: TinyBold Label@MOD_VERSION: - X:PARENT_RIGHT - 53 - 140 - 170 - Y:PARENT_BOTTOM-192 - Align:Left - Font:Tiny + X: PARENT_RIGHT - 400 + Y: PARENT_BOTTOM-192 + Align: Left + Font: Tiny Label@MOD_DESC: - X:PARENT_RIGHT - 53 - 140 - 170 - Y:PARENT_BOTTOM-175 - Align:Left - VAlign:Top - Font:Tiny + X: PARENT_RIGHT - 400 + Y: PARENT_BOTTOM-175 + Align: Left + VAlign: Top + Font: Tiny Background@PREVIEW: - X:53 - Y:PARENT_BOTTOM - 25 - HEIGHT - Width:300 - Height:200 - Background:panel-thinborder + X: 30 + Y: PARENT_BOTTOM - 25 - HEIGHT + Width: 300 + Height: 200 + Background: panel-thinborder Children: Label: - Width:PARENT_RIGHT - Height:PARENT_BOTTOM - Text:Missing or invalid preview - Align:Center + Width: PARENT_RIGHT + Height: PARENT_BOTTOM + Text: Missing or invalid preview + Align: Center RGBASprite@MOD_PREVIEW: - X:2 - Y:2 + X: 2 + Y: 2 Button@LOAD_BUTTON: - Background:button-highlighted - Key:return - X:PARENT_RIGHT - 53 - WIDTH - 170 - Y:PARENT_BOTTOM - 25 - HEIGHT - Width:140 - Height:32 - Text:Load Mod + X: PARENT_RIGHT - 300 - WIDTH + Y: PARENT_BOTTOM - 25 - HEIGHT + Width: 100 + Height: 32 + Text: Play + Background: button-highlighted + Key: return + Button@CONFIGURE_BUTTON: + X: PARENT_RIGHT - 145 - WIDTH + Y: PARENT_BOTTOM - 25 - HEIGHT + Width: 140 + Height: 32 + Text: Manage Content + Background: button-highlighted Button@QUIT_BUTTON: - Background:button-highlighted - X:PARENT_RIGHT - 53 - WIDTH - Y:PARENT_BOTTOM - 25 - HEIGHT - Width:140 - Height:32 - Text:Quit + X: PARENT_RIGHT - 30 - WIDTH + Y: PARENT_BOTTOM - 25 - HEIGHT + Width: 100 + Height: 32 + Text: Quit + Background: button-highlighted Background@DIALOG_HEADER: - Width:PARENT_RIGHT - Height:72 - Background:panel-header + Width: PARENT_RIGHT + Height: 72 + Background: panel-header Children: Image: - X:(PARENT_RIGHT - WIDTH)/2 - Y:0-28 - Width:280 - ImageCollection:modchooser - ImageName:logo + X: (PARENT_RIGHT - WIDTH) / 2 + Y: 0-28 + Width: 280 + ImageCollection: modchooser + ImageName: logo TooltipContainer@TOOLTIP_CONTAINER: Background@BUTTON_TOOLTIP: - Logic:ButtonTooltipLogic - Background:panel-thinborder - Height:25 + Logic: ButtonTooltipLogic + Background: panel-thinborder + Height: 25 Children: Label@LABEL: - X:5 - Height:23 - Font:Bold + X: 5 + Height: 23 + Font: Bold Label@HOTKEY: - TextColor:255,255,0 - Height:23 - Font:Bold \ No newline at end of file + TextColor: FFFF00 + Height: 23 + Font: Bold \ No newline at end of file diff --git a/mods/ra/chrome/lobby-music.yaml b/mods/ra/chrome/lobby-music.yaml index eeb7d95377..864c9ce5bf 100644 --- a/mods/ra/chrome/lobby-music.yaml +++ b/mods/ra/chrome/lobby-music.yaml @@ -160,21 +160,27 @@ Container@LOBBY_MUSIC_BIN: Visible: false Children: Label@TITLE: - Y: 75 + Y: 65 Width: PARENT_RIGHT-24 Height: 25 Font: Bold Align: Center - Text: No Music Available + Text: Music Not Installed Label@DESCA: - Y: 95 + Y: 85 Width: PARENT_RIGHT-24 Height: 25 Align: Center - Text: Music can be installed from the - Label@DESCA: - Y: 115 + Text: The game music can be installed + Label@DESCB: + Y: 105 Width: PARENT_RIGHT-24 Height: 25 Align: Center - Text: game Extras menu. + Text: from the "Manage Content" menu + Label@DESCC: + Y: 125 + Width: PARENT_RIGHT-24 + Height: 25 + Align: Center + Text: in the mod chooser. diff --git a/mods/ra/chrome/musicplayer.yaml b/mods/ra/chrome/musicplayer.yaml index 04a29cd8cc..fc6290bf01 100644 --- a/mods/ra/chrome/musicplayer.yaml +++ b/mods/ra/chrome/musicplayer.yaml @@ -141,22 +141,37 @@ Background@MUSIC_PANEL: Width: 70 Height: 20 Text: Loop - Label@NO_MUSIC_LABEL: + Container@NO_MUSIC_LABEL: X: 15 - Y: 147 + Y: 135 Width: 330 - Height: 25 - Font: Bold - Align: Center + Height: 80 Visible: false - Text: No Music Installed - Button@INSTALL_BUTTON: - X: 20 - Y: PARENT_BOTTOM - 45 - Width: 120 - Height: 25 - Text: Install Music - Font: Bold + Children: + Label@TITLE: + Width: PARENT_RIGHT-24 + Height: 25 + Font: Bold + Align: Center + Text: Music Not Installed + Label@DESCA: + Y: 20 + Width: PARENT_RIGHT-24 + Height: 25 + Align: Center + Text: The game music can be installed + Label@DESCB: + Y: 40 + Width: PARENT_RIGHT-24 + Height: 25 + Align: Center + Text: from the "Manage Content" menu + Label@DESCC: + Y: 60 + Width: PARENT_RIGHT-24 + Height: 25 + Align: Center + Text: in the mod chooser. Button@BACK_BUTTON: X: PARENT_RIGHT - 140 Y: PARENT_BOTTOM - 45 @@ -171,54 +186,3 @@ Background@MUSIC_PANEL: Width: 300 Height: 20 Font: Small - -Background@INSTALL_MUSIC_PANEL: - Logic: InstallMusicLogic - X: (WINDOW_RIGHT - WIDTH)/2 - Y: (WINDOW_BOTTOM - HEIGHT)/2 - Width: 500 - Height: 160 - Children: - Label@TITLE: - X: 0 - Y: 20 - Width: PARENT_RIGHT - Height: 25 - Text: Install Music - Align: Center - Font: Bold - Label@DESC1: - X: 0 - Y: 50 - Width: PARENT_RIGHT - Height: 25 - Text: The soundtrack is currently unavailable. - Align: Center - Label@DESC2: - X: 0 - Y: 70 - Width: PARENT_RIGHT - Height: 25 - Text: Please choose an installation method. - Align: Center - Button@COPY_FROM_CD_BUTTON: - X: 20 - Y: PARENT_BOTTOM - 45 - Width: 110 - Height: 25 - Text: Use CD - Font: Bold - Button@DOWNLOAD_BUTTON: - X: 140 - Y: PARENT_BOTTOM - 45 - Width: 110 - Height: 25 - Text: Download - Font: Bold - Button@CANCEL_BUTTON: - X: PARENT_RIGHT - 130 - Y: PARENT_BOTTOM - 45 - Width: 110 - Height: 25 - Text: Back - Font: Bold diff --git a/mods/ra/mod.yaml b/mods/ra/mod.yaml index 1a82d24cf8..1a8407fb10 100644 --- a/mods/ra/mod.yaml +++ b/mods/ra/mod.yaml @@ -145,20 +145,6 @@ LoadScreen: LogoStripeLoadScreen Image: ra|uibits/loadscreen.png Text: Filling Crates..., Charging Capacitors..., Reticulating Splines..., Planting Trees..., Building Bridges..., Aging Empires..., Compiling EVA..., Constructing Pylons..., Activating Skynet..., Splitting Atoms... -ContentInstaller: - TestFiles: ^Content/ra/allies.mix, ^Content/ra/conquer.mix, ^Content/ra/interior.mix, ^Content/ra/redalert.mix, ^Content/ra/russian.mix, ^Content/ra/snow.mix, ^Content/ra/sounds.mix, ^Content/ra/temperat.mix - PackageMirrorList: http://www.openra.net/packages/ra-mirrors.txt - DiskTestFiles: MAIN.MIX, INSTALL/REDALERT.MIX - PackageToExtractFromCD: MAIN.MIX - ExtractFilesFromCD: - .: conquer.mix, russian.mix, allies.mix, sounds.mix, scores.mix, snow.mix, interior.mix, temperat.mix, general.mix - CopyFilesFromCD: - .: INSTALL/REDALERT.MIX - ShippedSoundtracks: 2 - MusicPackageMirrorList: http://www.openra.net/packages/ra-music-mirrors.txt - InstallShieldCABFilePackageIds: 105 - InstallShieldCABFileIds: 116 - ServerTraits: LobbyCommands PlayerPinger @@ -234,3 +220,203 @@ GameSpeeds: OrderLatency: 6 ColorValidator: + +ModContent: + InstallPromptMessage: Red Alert requires artwork and audio from the original game.\n\nQuick Install will automatically download this content (without music\nor videos) from a mirror of the 2008 Red Alert freeware release.\n\nAdvanced Install includes options for downloading the music and for\ncopying the videos and other content from an original game disc. + QuickDownload: basefiles + HeaderMessage: The original game content may be copied from an original game disc,\nor downloaded from an online mirror of the 2008 freeware release. + Packages: + base: Base Game Files + TestFiles: ^Content/ra/allies.mix, ^Content/ra/conquer.mix, ^Content/ra/interior.mix, ^Content/ra/redalert.mix, ^Content/ra/russian.mix, ^Content/ra/snow.mix, ^Content/ra/sounds.mix, ^Content/ra/temperat.mix + Discs: allied, allied-linux, soviet, soviet-linux + Required: true + Download: basefiles + music: Base Game Music + TestFiles: ^Content/ra/scores.mix + Discs: allied, allied-linux, soviet, soviet-linux + Download: music + movies-allied: Allied Campaign Briefings + TestFiles: ^Content/ra/movies1.mix + Discs: allied, allied-linux + movies-soviet: Soviet Campaign Briefings + TestFiles: ^Content/ra/movies2.mix + Discs: soviet, soviet-linux + music-covertops: Counterstrike Music + TestFiles: ^Content/ra/scores-counterstrike.mix + Discs: counterstrike, counterstrike-linux + Downloads: + basefiles: Base Freeware Content + MirrorList: http://www.openra.net/packages/ra-mirrors.txt + Extract: + ^Content/ra/allies.mix: allies.mix + ^Content/ra/conquer.mix: conquer.mix + ^Content/ra/general.mix: general.mix + ^Content/ra/interior.mix: interior.mix + ^Content/ra/redalert.mix: redalert.mix + ^Content/ra/russian.mix: russian.mix + ^Content/ra/snow.mix: snow.mix + ^Content/ra/sounds.mix: sounds.mix + ^Content/ra/temperat.mix: temperat.mix + music: Freeware Music + MirrorList: http://www.openra.net/packages/ra-music-mirrors.txt + Extract: + ^Content/ra/scores.mix: scores.mix + Discs: + allied: Red Alert 95 (Allied Disc, English) + IDFiles: + eahelp.GID: 13a8a4a1e7d9d6d893c38df5a39262c4689aeba5 + INSTALL/REDALERT.MIX: 0e58f4b54f44f6cd29fecf8cf379d33cf2d4caef + Install: + copy: INSTALL + ^Content/ra/redalert.mix: REDALERT.MIX + extract-raw: MAIN.MIX + ^Content/ra/conquer.mix: + Offset: 236 + Length: 2177047 + ^Content/ra/interior.mix: + Offset: 17172192 + Length: 247425 + ^Content/ra/movies1.mix: + Offset: 17419617 + Length: 369362336 + ^Content/ra/scores.mix: + Offset: 386781953 + Length: 64171360 + ^Content/ra/snow.mix: + Offset: 450953313 + Length: 1030861 + ^Content/ra/sounds.mix: + Offset: 451984174 + Length: 1006778 + ^Content/ra/russian.mix: + Offset: 452990952 + Length: 266077 + ^Content/ra/allies.mix: + Offset: 453257029 + Length: 309406 + ^Content/ra/temperat.mix: + Offset: 453566435 + Length: 1038859 + allied-linux: Red Alert 95 (Allied Disc, English) + IDFiles: + eahelp.gid: 13a8a4a1e7d9d6d893c38df5a39262c4689aeba5 + install/redalert.mix: 0e58f4b54f44f6cd29fecf8cf379d33cf2d4caef + Install: + copy: install + ^Content/ra/redalert.mix: redalert.mix + extract-raw: main.mix + ^Content/ra/conquer.mix: + Offset: 236 + Length: 2177047 + ^Content/ra/interior.mix: + Offset: 17172192 + Length: 247425 + ^Content/ra/movies1.mix: + Offset: 17419617 + Length: 369362336 + ^Content/ra/scores.mix: + Offset: 386781953 + Length: 64171360 + ^Content/ra/snow.mix: + Offset: 450953313 + Length: 1030861 + ^Content/ra/sounds.mix: + Offset: 451984174 + Length: 1006778 + ^Content/ra/russian.mix: + Offset: 452990952 + Length: 266077 + ^Content/ra/allies.mix: + Offset: 453257029 + Length: 309406 + ^Content/ra/temperat.mix: + Offset: 453566435 + Length: 1038859 + soviet: Red Alert 95 (Soviet Disc, English) + IDFiles: + automenu.apm: bb61132a492bfb37069a0139f95671da3655d916 + INSTALL/REDALERT.MIX: 0e58f4b54f44f6cd29fecf8cf379d33cf2d4caef + Install: + copy: INSTALL + ^Content/cnc/redalert.mix: REDALERT.MIX + extract-raw: MAIN.MIX + ^Content/ra/conquer.mix: + Offset: 236 + Length: 2177047 + ^Content/ra/interior.mix: + Offset: 17172192 + Length: 247425 + ^Content/ra/movies2.mix: + Offset: 17419617 + Length: 415334456 + ^Content/ra/scores.mix: + Offset: 432754073 + Length: 64171360 + ^Content/ra/snow.mix: + Offset: 496925433 + Length: 1030861 + ^Content/ra/russian.mix: + Offset: 497956294 + Length: 266077 + ^Content/ra/allies.mix: + Offset: 498222371 + Length: 309406 + ^Content/ra/sounds.mix: + Offset: 498531777 + Length: 1006778 + ^Content/ra/temperat.mix: + Offset: 499538555 + Length: 1038859 + soviet-linux: Red Alert 95 (Soviet Disc, English) + IDFiles: + automenu.apm: bb61132a492bfb37069a0139f95671da3655d916 + install/redalert.mix: 0e58f4b54f44f6cd29fecf8cf379d33cf2d4caef + Install: + copy: install + ^Content/cnc/redalert.mix: redalert.mix + extract-raw: main.mix + ^Content/ra/conquer.mix: + Offset: 236 + Length: 2177047 + ^Content/ra/interior.mix: + Offset: 17172192 + Length: 247425 + ^Content/ra/movies2.mix: + Offset: 17419617 + Length: 415334456 + ^Content/ra/scores.mix: + Offset: 432754073 + Length: 64171360 + ^Content/ra/snow.mix: + Offset: 496925433 + Length: 1030861 + ^Content/ra/russian.mix: + Offset: 497956294 + Length: 266077 + ^Content/ra/allies.mix: + Offset: 498222371 + Length: 309406 + ^Content/ra/sounds.mix: + Offset: 498531777 + Length: 1006778 + ^Content/ra/temperat.mix: + Offset: 499538555 + Length: 1038859 + counterstrike: Counterstrike Expansion (English) + IDFiles: + README.TXT: 0efe8087383f0b159a9633f891fb5f53c6097cd4 + SETUP/INSTALL/CSTRIKE.RTP: fae8ba82db71574f6ecd8fb4ff4026fcb65d2adc + Install: + extract-raw: MAIN.MIX + ^Content/ra/scores-counterstrike.mix: + Offset: 144899491 + Length: 87483135 + counterstrike-linux: Counterstrike Expansion (English) + IDFiles: + readme.txt: 0efe8087383f0b159a9633f891fb5f53c6097cd4 + setup/install/cstrike.rtp: fae8ba82db71574f6ecd8fb4ff4026fcb65d2adc + Install: + extract-raw: main.mix + ^Content/ra/scores-counterstrike.mix: + Offset: 144899491 + Length: 87483135 diff --git a/mods/ts/mod.yaml b/mods/ts/mod.yaml index b4c4fd00d6..9224d242fd 100644 --- a/mods/ts/mod.yaml +++ b/mods/ts/mod.yaml @@ -1,4 +1,4 @@ -Metadata: + Metadata: Title: Tiberian Sun Description: Developer stub, not yet ready for release! Version: {DEV_VERSION} @@ -189,20 +189,6 @@ LoadScreen: LogoStripeLoadScreen Image: ts|uibits/loadscreen.png Text: Updating EVA installation..., Changing perspective... -ContentInstaller: - TestFiles: ^Content/ts/cache.mix, ^Content/ts/conquer.mix, ^Content/ts/isosnow.mix, ^Content/ts/isotemp.mix, ^Content/ts/local.mix, ^Content/ts/sidec01.mix, ^Content/ts/sidec02.mix, ^Content/ts/sno.mix, ^Content/ts/snow.mix, ^Content/ts/sounds.mix, ^Content/ts/speech01.mix, ^Content/ts/tem.mix, ^Content/ts/temperat.mix - PackageMirrorList: http://www.openra.net/packages/ts-mirrors.txt - DiskTestFiles: MULTI.MIX, INSTALL/TIBSUN.MIX - CopyFilesFromCD: - .: INSTALL/TIBSUN.MIX, SCORES.MIX, MULTI.MIX - PackageToExtractFromCD: INSTALL/TIBSUN.MIX - ExtractFilesFromCD: - .: cache.mix, conquer.mix, isosnow.mix, isotemp.mix, local.mix, sidec01.mix, sidec02.mix, sno.mix, snow.mix, sounds.mix, speech01.mix, tem.mix, temperat.mix - ShippedSoundtracks: 2 - MusicPackageMirrorList: http://www.openra.net/packages/ts-music-mirrors.txt - InstallShieldCABFilePackageIds: 332 - InstallShieldCABFileIds: 323, 364 - ServerTraits: LobbyCommands PlayerPinger @@ -272,3 +258,141 @@ GameSpeeds: OrderLatency: 6 ColorValidator: + +ModContent: + InstallPromptMessage: Tiberian Sun requires artwork and audio from the original game.\n\nQuick Install will automatically download this content (without music\nor videos) from a mirror of the 2012 Tiberian Sun freeware release.\n\nAdvanced Install includes options for downloading the music and for\ncopying the videos and other content from an original game disc. + QuickDownload: basefiles + HeaderMessage: The original game content may be copied from an original game disc,\nor downloaded from an online mirror of the 2012 freeware release. + Packages: + base: Base Game Files + TestFiles: ^Content/ts/cache.mix, ^Content/ts/conquer.mix, ^Content/ts/isosnow.mix, ^Content/ts/isotemp.mix, ^Content/ts/local.mix, ^Content/ts/sidec01.mix, ^Content/ts/sidec02.mix, ^Content/ts/sno.mix, ^Content/ts/snow.mix, ^Content/ts/sounds.mix, ^Content/ts/speech01.mix, ^Content/ts/tem.mix, ^Content/ts/temperat.mix + Discs: tibsun, tibsun-linux + Required: true + Download: basefiles + music: Base Game Music + TestFiles: ^Content/ts/scores.mix + Discs: tibsun, tibsun-linux + Download: music + Downloads: + basefiles: Base Freeware Content + MirrorList: http://www.openra.net/packages/ts-mirrors.txt + Extract: + ^Content/ts/cache.mix: cache.mix + ^Content/ts/conquer.mix: conquer.mix + ^Content/ts/isosnow.mix: isosnow.mix + ^Content/ts/isotemp.mix: isotemp.mix + ^Content/ts/local.mix: local.mix + ^Content/ts/sidec01.mix: sidec01.mix + ^Content/ts/sidec02.mix: sidec02.mix + ^Content/ts/sno.mix: sno.mix + ^Content/ts/snow.mix: snow.mix + ^Content/ts/sounds.mix: sounds.mix + ^Content/ts/speech01.mix: speech01.mix + ^Content/ts/speech02.mix: speech02.mix + ^Content/ts/tem.mix: tem.mix + ^Content/ts/temperat.mix: temperat.mix + music: Freeware Music + MirrorList: http://www.openra.net/packages/ts-music-mirrors.txt + Extract: + ^Content/ts/scores.mix: scores.mix + Discs: + tibsun: Tiberan Sun (GDI or Nod Disc, English) + IDFiles: + README.TXT: 45745c4a0c888317ec900208a426472779c42bf7 + AUTOPLAY.WAV: 2dfce5d00f98b641849c29942b651f4e98d30e30 + Install: + copy: . + ^Content/ts/scores.mix: SCORES.MIX + extract-raw: INSTALL/TIBSUN.MIX + ^Content/ts/cache.mix: + Offset: 300 + Length: 169176 + ^Content/ts/conquer.mix: + Offset: 169484 + Length: 5700088 + ^Content/ts/isosnow.mix: + Offset: 5869580 + Length: 7624750 + ^Content/ts/isotemp.mix: + Offset: 13494332 + Length: 8617646 + ^Content/ts/local.mix: + Offset: 22111980 + Length: 18044736 + ^Content/ts/sidec01.mix: + Offset: 40156716 + Length: 998476 + ^Content/ts/sidec02.mix: + Offset: 41155196 + Length: 1039996 + ^Content/ts/snow.mix: + Offset: 56104508 + Length: 2087806 + ^Content/ts/sno.mix: + Offset: 58192316 + Length: 7826 + ^Content/ts/sounds.mix: + Offset: 58200156 + Length: 3224136 + ^Content/ts/speech01.mix: + Offset: 61424300 + Length: 6028236 + ^Content/ts/speech02.mix: + Offset: 67452540 + Length: 5596628 + ^Content/ts/tem.mix: + Offset: 73049180 + Length: 7746 + ^Content/ts/temperat.mix: + Offset: 73056940 + Length: 2037606 + tibsun-linux: Tiberan Sun (GDI or Nod Disc, English) + IDFiles: + readme.txt: 45745c4a0c888317ec900208a426472779c42bf7 + autoplay.wav: 2dfce5d00f98b641849c29942b651f4e98d30e30 + Install: + copy: . + ^Content/ts/scores.mix: scores.mix + extract-raw: install/tibsun.mix + ^Content/ts/cache.mix: + Offset: 300 + Length: 169176 + ^Content/ts/conquer.mix: + Offset: 169484 + Length: 5700088 + ^Content/ts/isosnow.mix: + Offset: 5869580 + Length: 7624750 + ^Content/ts/isotemp.mix: + Offset: 13494332 + Length: 8617646 + ^Content/ts/local.mix: + Offset: 22111980 + Length: 18044736 + ^Content/ts/sidec01.mix: + Offset: 40156716 + Length: 998476 + ^Content/ts/sidec02.mix: + Offset: 41155196 + Length: 1039996 + ^Content/ts/snow.mix: + Offset: 56104508 + Length: 2087806 + ^Content/ts/sno.mix: + Offset: 58192316 + Length: 7826 + ^Content/ts/sounds.mix: + Offset: 58200156 + Length: 3224136 + ^Content/ts/speech01.mix: + Offset: 61424300 + Length: 6028236 + ^Content/ts/speech02.mix: + Offset: 67452540 + Length: 5596628 + ^Content/ts/tem.mix: + Offset: 73049180 + Length: 7746 + ^Content/ts/temperat.mix: + Offset: 73056940 + Length: 2037606