Expose mod.yaml content to localisation.
Mod metadata, load screens and mod content is all now sourced from ftl files, allowing these items to be translated. Translations are now initialized as part of ModData creation, as currently they are made available too late for the usage we need here. The "modcontent" mod learns a new parameter for "Content.TranslationFile" - this allows a mod to provide the path of a translation file to the mod which it can load. This allows mods such as ra, cnc, d2k, ts to own the translations for their ModContent, yet still make them accessible to the modcontent mod. CheckFluentReference learns to validate all these new fields to ensure translations have been set.
This commit is contained in:
@@ -27,7 +27,6 @@ namespace OpenRA
|
||||
{
|
||||
public readonly string Id;
|
||||
public readonly string Version;
|
||||
public readonly string Title;
|
||||
public readonly string LaunchPath;
|
||||
public readonly string[] LaunchArgs;
|
||||
public Sprite Icon { get; internal set; }
|
||||
@@ -127,7 +126,6 @@ namespace OpenRA
|
||||
{
|
||||
new MiniYamlNode("Id", mod.Id),
|
||||
new MiniYamlNode("Version", mod.Metadata.Version),
|
||||
new MiniYamlNode("Title", mod.Metadata.Title),
|
||||
new MiniYamlNode("LaunchPath", launchPath),
|
||||
new MiniYamlNode("LaunchArgs", new[] { "Game.Mod=" + mod.Id }.Concat(launchArgs).JoinWith(", "))
|
||||
}));
|
||||
|
||||
@@ -395,7 +395,7 @@ namespace OpenRA
|
||||
Mods = new InstalledMods(modSearchPaths, explicitModPaths);
|
||||
Console.WriteLine("Internal mods:");
|
||||
foreach (var mod in Mods)
|
||||
Console.WriteLine($"\t{mod.Key}: {mod.Value.Metadata.Title} ({mod.Value.Metadata.Version})");
|
||||
Console.WriteLine($"\t{mod.Key} ({mod.Value.Metadata.Version})");
|
||||
|
||||
modLaunchWrapper = args.GetValue("Engine.LaunchWrapper", null);
|
||||
|
||||
@@ -420,7 +420,7 @@ namespace OpenRA
|
||||
|
||||
Console.WriteLine("External mods:");
|
||||
foreach (var mod in ExternalMods)
|
||||
Console.WriteLine($"\t{mod.Key}: {mod.Value.Title} ({mod.Value.Version})");
|
||||
Console.WriteLine($"\t{mod.Key} ({mod.Value.Version})");
|
||||
|
||||
InitializeMod(modID, args);
|
||||
}
|
||||
@@ -499,8 +499,8 @@ namespace OpenRA
|
||||
Cursor = new CursorManager(ModData.CursorProvider, ModData.Manifest.CursorSheetSize);
|
||||
|
||||
var metadata = ModData.Manifest.Metadata;
|
||||
if (!string.IsNullOrEmpty(metadata.WindowTitle))
|
||||
Renderer.Window.SetWindowTitle(metadata.WindowTitle);
|
||||
if (!string.IsNullOrEmpty(metadata.WindowTitleTranslated))
|
||||
Renderer.Window.SetWindowTitle(metadata.WindowTitleTranslated);
|
||||
|
||||
PerfHistory.Items["render"].HasNormalTick = false;
|
||||
PerfHistory.Items["batches"].HasNormalTick = false;
|
||||
|
||||
@@ -45,12 +45,20 @@ namespace OpenRA
|
||||
|
||||
public class ModMetadata
|
||||
{
|
||||
public string Title;
|
||||
public string Version;
|
||||
public string Website;
|
||||
public string WebIcon32;
|
||||
public string WindowTitle;
|
||||
public bool Hidden;
|
||||
// FieldLoader used here, must matching naming in YAML.
|
||||
#pragma warning disable IDE1006 // Naming Styles
|
||||
[FluentReference]
|
||||
readonly string Title;
|
||||
public readonly string Version;
|
||||
public readonly string Website;
|
||||
public readonly string WebIcon32;
|
||||
[FluentReference]
|
||||
readonly string WindowTitle;
|
||||
public readonly bool Hidden;
|
||||
#pragma warning restore IDE1006 // Naming Styles
|
||||
|
||||
public string TitleTranslated => FluentProvider.GetString(Title);
|
||||
public string WindowTitleTranslated => WindowTitle != null ? FluentProvider.GetString(WindowTitle) : null;
|
||||
}
|
||||
|
||||
/// <summary>Describes what is to be loaded in order to run a mod.</summary>
|
||||
|
||||
@@ -65,6 +65,8 @@ namespace OpenRA
|
||||
|
||||
Manifest.LoadCustomData(ObjectCreator);
|
||||
|
||||
FluentProvider.Initialize(this, DefaultFileSystem);
|
||||
|
||||
if (useLoadScreen)
|
||||
{
|
||||
LoadScreen = ObjectCreator.CreateObject<ILoadScreen>(Manifest.LoadScreen.Value);
|
||||
|
||||
@@ -182,13 +182,13 @@ namespace OpenRA.Network
|
||||
if (external != null && external.Version == Version)
|
||||
{
|
||||
// Use external mod registration to populate the section header
|
||||
ModTitle = external.Title;
|
||||
ModTitle = external.Id;
|
||||
}
|
||||
else if (Game.Mods.TryGetValue(Mod, out var mod))
|
||||
{
|
||||
// Use internal mod data to populate the section header, but
|
||||
// on-connect switching must use the external mod plumbing.
|
||||
ModTitle = mod.Metadata.Title;
|
||||
ModTitle = mod.Metadata.TitleTranslated;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -199,7 +199,7 @@ namespace OpenRA.Network
|
||||
.FirstOrDefault(m => m.Id == Mod);
|
||||
|
||||
if (guessMod != null)
|
||||
ModTitle = guessMod.Title;
|
||||
ModTitle = guessMod.Id;
|
||||
else
|
||||
ModTitle = $"Unknown mod: {Mod}";
|
||||
}
|
||||
@@ -222,7 +222,7 @@ namespace OpenRA.Network
|
||||
Map = server.Map.Uid;
|
||||
Mod = manifest.Id;
|
||||
Version = manifest.Metadata.Version;
|
||||
ModTitle = manifest.Metadata.Title;
|
||||
ModTitle = manifest.Metadata.TitleTranslated;
|
||||
ModWebsite = manifest.Metadata.Website;
|
||||
ModIcon32 = manifest.Metadata.WebIcon32;
|
||||
Protected = !string.IsNullOrEmpty(server.Settings.Password);
|
||||
|
||||
@@ -122,7 +122,7 @@ namespace OpenRA.Network
|
||||
Log.Write("sync", $"Player: {Game.Settings.Player.Name} ({Platform.CurrentPlatform} {Environment.OSVersion} {Platform.RuntimeVersion})");
|
||||
if (Game.IsHost)
|
||||
Log.Write("sync", "Player is host.");
|
||||
Log.Write("sync", $"Game ID: {orderManager.LobbyInfo.GlobalSettings.GameUid} (Mod: {mod.Title} at Version {mod.Version})");
|
||||
Log.Write("sync", $"Game ID: {orderManager.LobbyInfo.GlobalSettings.GameUid} (Mod: {mod.TitleTranslated} at Version {mod.Version})");
|
||||
Log.Write("sync", $"Sync for net frame {r.Frame} -------------");
|
||||
Log.Write("sync", $"SharedRandom: {r.SyncedRandom} (#{r.TotalCount})");
|
||||
Log.Write("sync", "Synced Traits:");
|
||||
|
||||
@@ -31,8 +31,8 @@ namespace OpenRA
|
||||
|
||||
if (Game.ModData != null)
|
||||
{
|
||||
var mod = Game.ModData.Manifest.Metadata;
|
||||
Log.Write("exception", $"{mod.Title} mod version {mod.Version}");
|
||||
var manifest = Game.ModData.Manifest;
|
||||
Log.Write("exception", $"{manifest.Id} mod version {manifest.Metadata.Version}");
|
||||
}
|
||||
|
||||
if (Game.OrderManager != null && Game.OrderManager.World != null && Game.OrderManager.World.Map != null)
|
||||
|
||||
@@ -19,6 +19,9 @@ namespace OpenRA.Mods.Cnc
|
||||
{
|
||||
public sealed class CncLoadScreen : SheetLoadScreen
|
||||
{
|
||||
[FluentReference]
|
||||
const string Loading = "loadscreen-loading";
|
||||
|
||||
int loadTick;
|
||||
|
||||
Sprite nodLogo, gdiLogo, evaLogo, brightBlock, dimBlock;
|
||||
@@ -31,11 +34,15 @@ namespace OpenRA.Mods.Cnc
|
||||
int lastDensity;
|
||||
Size lastResolution;
|
||||
|
||||
string message = "";
|
||||
|
||||
public override void Init(ModData modData, Dictionary<string, string> info)
|
||||
{
|
||||
base.Init(modData, info);
|
||||
|
||||
versionText = modData.Manifest.Metadata.Version;
|
||||
|
||||
message = FluentProvider.GetString(Loading);
|
||||
}
|
||||
|
||||
public override void DisplayInner(Renderer r, Sheet s, int density)
|
||||
@@ -89,7 +96,7 @@ namespace OpenRA.Mods.Cnc
|
||||
if (r.Fonts != null)
|
||||
{
|
||||
var loadingFont = r.Fonts["BigBold"];
|
||||
var loadingText = Info["Text"];
|
||||
var loadingText = message;
|
||||
var loadingPos = new float2((bounds.Width - loadingFont.Measure(loadingText).X) / 2, barY);
|
||||
loadingFont.DrawText(loadingText, loadingPos, Color.Gray);
|
||||
|
||||
|
||||
@@ -48,7 +48,12 @@ namespace OpenRA.Mods.Common.FileSystem
|
||||
if (contentInstalled)
|
||||
return false;
|
||||
|
||||
Game.InitializeMod(content.ContentInstallerMod, new Arguments("Content.Mod=" + modData.Manifest.Id));
|
||||
string translationPath;
|
||||
using (var fs = (FileStream)modData.DefaultFileSystem.Open(content.Translation))
|
||||
translationPath = fs.Name;
|
||||
Game.InitializeMod(
|
||||
content.ContentInstallerMod,
|
||||
new Arguments(new[] { "Content.Mod=" + modData.Manifest.Id, "Content.TranslationFile=" + translationPath }));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,16 +43,17 @@ namespace OpenRA.Mods.Common.Lint
|
||||
|
||||
var mapTranslations = FieldLoader.GetValue<string[]>("value", map.TranslationDefinitions.Value);
|
||||
|
||||
foreach (var language in GetModLanguages(modData))
|
||||
var allModTranslations = modData.Manifest.Translations.Append(modData.Manifest.Get<ModContent>().Translation).ToArray();
|
||||
foreach (var language in GetModLanguages(allModTranslations))
|
||||
{
|
||||
// Check keys and variables are not missing across all language files.
|
||||
// But for maps we don't warn on unused keys. They might be unused on *this* map,
|
||||
// but the mod or another map may use them and we don't have sight of that.
|
||||
CheckKeys(
|
||||
modData.Manifest.Translations.Concat(mapTranslations), map.Open, usedKeys,
|
||||
allModTranslations.Concat(mapTranslations), map.Open, usedKeys,
|
||||
language, _ => false, emitError, emitWarning);
|
||||
|
||||
var modFluentBundle = new FluentBundle(language, modData.Manifest.Translations, modData.DefaultFileSystem, _ => { });
|
||||
var modFluentBundle = new FluentBundle(language, allModTranslations, modData.DefaultFileSystem, _ => { });
|
||||
var mapFluentBundle = new FluentBundle(language, mapTranslations, map, error => emitError(error.Message));
|
||||
|
||||
foreach (var group in usedKeys.KeysWithContext)
|
||||
@@ -78,14 +79,15 @@ namespace OpenRA.Mods.Common.Lint
|
||||
foreach (var context in usedKeys.EmptyKeyContexts)
|
||||
emitWarning($"Empty key in mod translation files required by {context}");
|
||||
|
||||
foreach (var language in GetModLanguages(modData))
|
||||
var allModTranslations = modData.Manifest.Translations.Append(modData.Manifest.Get<ModContent>().Translation).ToArray();
|
||||
foreach (var language in GetModLanguages(allModTranslations))
|
||||
{
|
||||
Console.WriteLine($"Testing language: {language}");
|
||||
CheckModWidgets(modData, usedKeys, testedFields);
|
||||
|
||||
// With the fully populated keys, check keys and variables are not missing and not unused across all language files.
|
||||
var keyWithAttrs = CheckKeys(
|
||||
modData.Manifest.Translations, modData.DefaultFileSystem.Open, usedKeys,
|
||||
allModTranslations, modData.DefaultFileSystem.Open, usedKeys,
|
||||
language,
|
||||
file =>
|
||||
!modData.Manifest.AllowUnusedTranslationsInExternalPackages ||
|
||||
@@ -113,9 +115,9 @@ namespace OpenRA.Mods.Common.Lint
|
||||
$"`{field.ReflectedType.Name}.{field.Name}` - previous warnings may be incorrect");
|
||||
}
|
||||
|
||||
static IEnumerable<string> GetModLanguages(ModData modData)
|
||||
static IEnumerable<string> GetModLanguages(IEnumerable<string> translations)
|
||||
{
|
||||
return modData.Manifest.Translations
|
||||
return translations
|
||||
.Select(filename => FilenameRegex.Match(filename).Groups["language"].Value)
|
||||
.Distinct()
|
||||
.OrderBy(l => l);
|
||||
@@ -249,51 +251,55 @@ namespace OpenRA.Mods.Common.Lint
|
||||
.Where(t => t.IsSubclassOf(typeof(TraitInfo)) || t.IsSubclassOf(typeof(Warhead)))
|
||||
.SelectMany(t => t.GetFields().Where(f => f.HasAttribute<FluentReferenceAttribute>())));
|
||||
|
||||
// HACK: Need to hardcode the custom loader for GameSpeeds.
|
||||
var gameSpeeds = modData.Manifest.Get<GameSpeeds>();
|
||||
var gameSpeedNameField = typeof(GameSpeed).GetField(nameof(GameSpeed.Name));
|
||||
var gameSpeedFluentReference = Utility.GetCustomAttributes<FluentReferenceAttribute>(gameSpeedNameField, true)[0];
|
||||
testedFields.Add(gameSpeedNameField);
|
||||
foreach (var speed in gameSpeeds.Speeds.Values)
|
||||
usedKeys.Add(speed.Name, gameSpeedFluentReference, $"`{nameof(GameSpeed)}.{nameof(GameSpeed.Name)}`");
|
||||
// TODO: linter does not work with LoadUsing
|
||||
GetUsedTranslationKeysFromFieldsWithTranslationReferenceAttribute(
|
||||
usedKeys, testedFields, Utility.GetFields(typeof(GameSpeed)), modData.Manifest.Get<GameSpeeds>().Speeds.Values);
|
||||
|
||||
// TODO: linter does not work with LoadUsing
|
||||
foreach (var actorInfo in modData.DefaultRules.Actors)
|
||||
GetUsedTranslationKeysFromFieldsWithTranslationReferenceAttribute(
|
||||
usedKeys, testedFields,
|
||||
Utility.GetFields(typeof(ResourceRendererInfo.ResourceTypeInfo)),
|
||||
modData.DefaultRules.Actors
|
||||
.SelectMany(actorInfo => actorInfo.Value.TraitInfos<ResourceRendererInfo>())
|
||||
.SelectMany(info => info.ResourceTypes.Values));
|
||||
|
||||
const BindingFlags Binding = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
|
||||
var constFields = modData.ObjectCreator.GetTypes().SelectMany(modType => modType.GetFields(Binding)).Where(f => f.IsLiteral);
|
||||
GetUsedTranslationKeysFromFieldsWithTranslationReferenceAttribute(
|
||||
usedKeys, testedFields, constFields, new[] { (object)null });
|
||||
|
||||
var modMetadataFields = typeof(ModMetadata).GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
GetUsedTranslationKeysFromFieldsWithTranslationReferenceAttribute(
|
||||
usedKeys, testedFields, modMetadataFields, new[] { modData.Manifest.Metadata });
|
||||
|
||||
var modContent = modData.Manifest.Get<ModContent>();
|
||||
GetUsedTranslationKeysFromFieldsWithTranslationReferenceAttribute(
|
||||
usedKeys, testedFields, Utility.GetFields(typeof(ModContent)), new[] { modContent });
|
||||
GetUsedTranslationKeysFromFieldsWithTranslationReferenceAttribute(
|
||||
usedKeys, testedFields, Utility.GetFields(typeof(ModContent.ModPackage)), modContent.Packages.Values);
|
||||
|
||||
return (usedKeys, testedFields);
|
||||
}
|
||||
|
||||
static void GetUsedTranslationKeysFromFieldsWithTranslationReferenceAttribute(
|
||||
Keys usedKeys, List<FieldInfo> testedFields,
|
||||
IEnumerable<FieldInfo> newFields, IEnumerable<object> objects)
|
||||
{
|
||||
var fieldsWithAttribute =
|
||||
newFields
|
||||
.Select(f => (Field: f, FluentReference: Utility.GetCustomAttributes<FluentReferenceAttribute>(f, true).SingleOrDefault()))
|
||||
.Where(x => x.FluentReference != null)
|
||||
.ToArray();
|
||||
testedFields.AddRange(fieldsWithAttribute.Select(x => x.Field));
|
||||
foreach (var obj in objects)
|
||||
{
|
||||
foreach (var info in actorInfo.Value.TraitInfos<ResourceRendererInfo>())
|
||||
foreach (var (field, fluentReference) in fieldsWithAttribute)
|
||||
{
|
||||
var resourceTypeNameField = typeof(ResourceRendererInfo.ResourceTypeInfo).GetField(nameof(ResourceRendererInfo.ResourceTypeInfo.Name));
|
||||
var resourceTypeFluentReference = Utility.GetCustomAttributes<FluentReferenceAttribute>(resourceTypeNameField, true)[0];
|
||||
testedFields.Add(resourceTypeNameField);
|
||||
foreach (var resourceTypes in info.ResourceTypes)
|
||||
usedKeys.Add(
|
||||
resourceTypes.Value.Name,
|
||||
resourceTypeFluentReference,
|
||||
$"`{nameof(ResourceRendererInfo.ResourceTypeInfo)}.{nameof(ResourceRendererInfo.ResourceTypeInfo.Name)}`");
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var modType in modData.ObjectCreator.GetTypes())
|
||||
{
|
||||
const BindingFlags Binding = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
|
||||
foreach (var field in modType.GetFields(Binding))
|
||||
{
|
||||
// Checking for constant string fields.
|
||||
if (!field.IsLiteral)
|
||||
continue;
|
||||
|
||||
var fluentReference = Utility.GetCustomAttributes<FluentReferenceAttribute>(field, true).SingleOrDefault();
|
||||
if (fluentReference == null)
|
||||
continue;
|
||||
|
||||
testedFields.Add(field);
|
||||
var keys = LintExts.GetFieldValues(null, field, fluentReference.DictionaryReference);
|
||||
var keys = LintExts.GetFieldValues(obj, field, fluentReference.DictionaryReference);
|
||||
foreach (var key in keys)
|
||||
usedKeys.Add(key, fluentReference, $"`{field.ReflectedType.Name}.{field.Name}`");
|
||||
}
|
||||
}
|
||||
|
||||
return (usedKeys, testedFields);
|
||||
}
|
||||
|
||||
static void CheckModWidgets(ModData modData, Keys usedKeys, List<FieldInfo> testedFields)
|
||||
|
||||
@@ -30,10 +30,11 @@ namespace OpenRA.Mods.Common.Lint
|
||||
|
||||
void ILintPass.Run(Action<string> emitError, Action<string> emitWarning, ModData modData)
|
||||
{
|
||||
Run(emitError, emitWarning, modData.DefaultFileSystem, modData.Manifest.Translations);
|
||||
var allModTranslations = modData.Manifest.Translations.Append(modData.Manifest.Get<ModContent>().Translation);
|
||||
Run(emitError, emitWarning, modData.DefaultFileSystem, allModTranslations);
|
||||
}
|
||||
|
||||
static void Run(Action<string> emitError, Action<string> emitWarning, IReadOnlyFileSystem fileSystem, string[] paths)
|
||||
static void Run(Action<string> emitError, Action<string> emitWarning, IReadOnlyFileSystem fileSystem, IEnumerable<string> paths)
|
||||
{
|
||||
foreach (var path in paths)
|
||||
{
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Common.Widgets;
|
||||
using OpenRA.Primitives;
|
||||
@@ -18,6 +20,9 @@ namespace OpenRA.Mods.Common.LoadScreens
|
||||
{
|
||||
public sealed class LogoStripeLoadScreen : SheetLoadScreen
|
||||
{
|
||||
[FluentReference]
|
||||
const string Loading = "loadscreen-loading";
|
||||
|
||||
Rectangle stripeRect;
|
||||
float2 logoPos;
|
||||
Sprite stripe, logo;
|
||||
@@ -26,14 +31,13 @@ namespace OpenRA.Mods.Common.LoadScreens
|
||||
int lastDensity;
|
||||
Size lastResolution;
|
||||
|
||||
string[] messages = { "Loading..." };
|
||||
string[] messages = Array.Empty<string>();
|
||||
|
||||
public override void Init(ModData modData, Dictionary<string, string> info)
|
||||
{
|
||||
base.Init(modData, info);
|
||||
|
||||
if (info.TryGetValue("Text", out var text))
|
||||
messages = text.Split(',');
|
||||
messages = FluentProvider.GetString(Loading).Split(',').Select(x => x.Trim()).ToArray();
|
||||
}
|
||||
|
||||
public override void DisplayInner(Renderer r, Sheet s, int density)
|
||||
@@ -59,7 +63,7 @@ namespace OpenRA.Mods.Common.LoadScreens
|
||||
if (logo != null)
|
||||
r.RgbaSpriteRenderer.DrawSprite(logo, logoPos);
|
||||
|
||||
if (r.Fonts != null)
|
||||
if (r.Fonts != null && messages.Length > 0)
|
||||
{
|
||||
var text = messages.Random(Game.CosmeticRandom);
|
||||
var textSize = r.Fonts["Bold"].Measure(text);
|
||||
|
||||
@@ -52,6 +52,10 @@ namespace OpenRA.Mods.Common.LoadScreens
|
||||
if (modId == null || !Game.Mods.TryGetValue(modId, out var selectedMod))
|
||||
throw new InvalidOperationException("Invalid or missing Content.Mod argument.");
|
||||
|
||||
var translationFilePath = args.GetValue("Content.TranslationFile", null);
|
||||
if (translationFilePath == null || !File.Exists(translationFilePath))
|
||||
throw new InvalidOperationException("Invalid or missing Content.TranslationFile argument.");
|
||||
|
||||
var content = selectedMod.Get<ModContent>(Game.ModData.ObjectCreator);
|
||||
|
||||
Ui.LoadWidget("MODCONTENT_BACKGROUND", Ui.Root, new WidgetArgs());
|
||||
@@ -63,6 +67,7 @@ namespace OpenRA.Mods.Common.LoadScreens
|
||||
{ "continueLoading", () => Game.RunAfterTick(() => Game.InitializeMod(modId, new Arguments())) },
|
||||
{ "mod", selectedMod },
|
||||
{ "content", content },
|
||||
{ "translationFilePath", translationFilePath },
|
||||
};
|
||||
|
||||
Ui.OpenWindow("CONTENT_PROMPT_PANEL", widgetArgs);
|
||||
@@ -71,9 +76,10 @@ namespace OpenRA.Mods.Common.LoadScreens
|
||||
{
|
||||
var widgetArgs = new WidgetArgs
|
||||
{
|
||||
{ "onCancel", () => Game.RunAfterTick(() => Game.InitializeMod(modId, new Arguments())) },
|
||||
{ "mod", selectedMod },
|
||||
{ "content", content },
|
||||
{ "onCancel", () => Game.RunAfterTick(() => Game.InitializeMod(modId, new Arguments())) }
|
||||
{ "translationFilePath", translationFilePath },
|
||||
};
|
||||
|
||||
Ui.OpenWindow("CONTENT_PANEL", widgetArgs);
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace OpenRA
|
||||
{
|
||||
public class ModPackage
|
||||
{
|
||||
[FluentReference]
|
||||
public readonly string Title;
|
||||
public readonly string Identifier;
|
||||
public readonly string[] TestFiles = Array.Empty<string>();
|
||||
@@ -100,10 +101,13 @@ namespace OpenRA
|
||||
}
|
||||
}
|
||||
|
||||
[FluentReference]
|
||||
public readonly string InstallPromptMessage;
|
||||
public readonly string QuickDownload;
|
||||
[FluentReference]
|
||||
public readonly string HeaderMessage;
|
||||
public readonly string ContentInstallerMod = "modcontent";
|
||||
public readonly string Translation;
|
||||
|
||||
[FieldLoader.LoadUsing(nameof(LoadPackages))]
|
||||
public readonly Dictionary<string, ModPackage> Packages = new();
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
var maps = new List<(IReadWritePackage Package, string Map)>();
|
||||
if (args.Length < 2)
|
||||
{
|
||||
Console.WriteLine($"Testing mod: {modData.Manifest.Metadata.Title}");
|
||||
Console.WriteLine($"Testing mod: {modData.Manifest.Metadata.TitleTranslated}");
|
||||
|
||||
// Run all rule checks on the default mod rules.
|
||||
CheckRules(modData, modData.DefaultRules);
|
||||
|
||||
@@ -193,7 +193,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
var switchButton = panel.Get<ButtonWidget>("SWITCH_BUTTON");
|
||||
|
||||
var mod = CurrentServerSettings.ServerExternalMod;
|
||||
var modTitle = mod.Title;
|
||||
var modTitle = mod.Id;
|
||||
var modVersion = mod.Version;
|
||||
|
||||
switchButton.OnClick = () =>
|
||||
|
||||
@@ -87,6 +87,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
readonly ModData modData;
|
||||
readonly ModContent content;
|
||||
readonly Dictionary<string, ModContent.ModSource> sources;
|
||||
readonly FluentBundle externalFluentBundle;
|
||||
|
||||
readonly Widget panel;
|
||||
readonly LabelWidget titleLabel;
|
||||
@@ -116,11 +117,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
Mode visible = Mode.Progress;
|
||||
|
||||
[ObjectCreator.UseCtor]
|
||||
public InstallFromSourceLogic(Widget widget, ModData modData, ModContent content, Dictionary<string, ModContent.ModSource> sources)
|
||||
public InstallFromSourceLogic(
|
||||
Widget widget, ModData modData, ModContent content, Dictionary<string, ModContent.ModSource> sources, FluentBundle externalFluentBundle)
|
||||
{
|
||||
this.modData = modData;
|
||||
this.content = content;
|
||||
this.sources = sources;
|
||||
this.externalFluentBundle = externalFluentBundle;
|
||||
|
||||
Log.AddChannel("install", "install.log");
|
||||
|
||||
@@ -339,7 +342,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
{
|
||||
var containerWidget = (ContainerWidget)checkboxListTemplate.Clone();
|
||||
var checkboxWidget = containerWidget.Get<CheckboxWidget>("PACKAGE_CHECKBOX");
|
||||
checkboxWidget.GetText = () => package.Title;
|
||||
var title = externalFluentBundle.GetString(package.Title);
|
||||
checkboxWidget.GetText = () => title;
|
||||
checkboxWidget.IsDisabled = () => package.Required;
|
||||
checkboxWidget.IsChecked = () => selectedPackages[package.Identifier];
|
||||
checkboxWidget.OnClick = () => selectedPackages[package.Identifier] = !selectedPackages[package.Identifier];
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using OpenRA.FileSystem;
|
||||
using OpenRA.Widgets;
|
||||
@@ -30,10 +31,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
readonly Dictionary<string, ModContent.ModSource> sources = new();
|
||||
readonly Dictionary<string, ModContent.ModDownload> downloads = new();
|
||||
|
||||
readonly FluentBundle externalFluentBundle;
|
||||
|
||||
bool sourceAvailable;
|
||||
|
||||
[ObjectCreator.UseCtor]
|
||||
public ModContentLogic(Widget widget, Manifest mod, ModContent content, Action onCancel)
|
||||
public ModContentLogic(Widget widget, Manifest mod, ModContent content, Action onCancel, string translationFilePath)
|
||||
{
|
||||
this.content = content;
|
||||
|
||||
@@ -58,20 +61,25 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
|
||||
modFileSystem.UnmountAll();
|
||||
|
||||
externalFluentBundle = new FluentBundle(Game.Settings.Player.Language, File.ReadAllText(translationFilePath), _ => { });
|
||||
|
||||
scrollPanel = panel.Get<ScrollPanelWidget>("PACKAGES");
|
||||
template = scrollPanel.Get<ContainerWidget>("PACKAGE_TEMPLATE");
|
||||
|
||||
var headerTemplate = panel.Get<LabelWidget>("HEADER_TEMPLATE");
|
||||
var headerLines = !string.IsNullOrEmpty(content.HeaderMessage) ? content.HeaderMessage.Replace("\\n", "\n").Split('\n') : Array.Empty<string>();
|
||||
var headerLines =
|
||||
!string.IsNullOrEmpty(content.HeaderMessage)
|
||||
? externalFluentBundle.GetString(content.HeaderMessage)
|
||||
: null;
|
||||
var headerHeight = 0;
|
||||
foreach (var l in headerLines)
|
||||
if (headerLines != null)
|
||||
{
|
||||
var line = (LabelWidget)headerTemplate.Clone();
|
||||
line.GetText = () => l;
|
||||
line.Bounds.Y += headerHeight;
|
||||
panel.AddChild(line);
|
||||
var label = (LabelWidget)headerTemplate.Clone();
|
||||
label.GetText = () => headerLines;
|
||||
label.IncreaseHeightToFitCurrentText();
|
||||
panel.AddChild(label);
|
||||
|
||||
headerHeight += headerTemplate.Bounds.Height;
|
||||
headerHeight += label.Bounds.Height;
|
||||
}
|
||||
|
||||
panel.Bounds.Height += headerHeight;
|
||||
@@ -85,7 +93,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
sourceButton.OnClick = () => Ui.OpenWindow("SOURCE_INSTALL_PANEL", new WidgetArgs
|
||||
{
|
||||
{ "sources", sources },
|
||||
{ "content", content }
|
||||
{ "content", content },
|
||||
{ "externalFluentBundle", externalFluentBundle },
|
||||
});
|
||||
|
||||
var backButton = panel.Get<ButtonWidget>("BACK_BUTTON");
|
||||
@@ -109,7 +118,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
{
|
||||
var container = template.Clone();
|
||||
var titleWidget = container.Get<LabelWidget>("TITLE");
|
||||
var title = p.Value.Title;
|
||||
var title = externalFluentBundle.GetString(p.Value.Title);
|
||||
titleWidget.GetText = () => title;
|
||||
|
||||
var requiredWidget = container.Get<LabelWidget>("REQUIRED");
|
||||
|
||||
@@ -27,14 +27,17 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
const string Quit = "button-quit";
|
||||
|
||||
readonly ModContent content;
|
||||
readonly FluentBundle externalFluentBundle;
|
||||
bool requiredContentInstalled;
|
||||
|
||||
[ObjectCreator.UseCtor]
|
||||
public ModContentPromptLogic(ModData modData, Widget widget, Manifest mod, ModContent content, Action continueLoading)
|
||||
public ModContentPromptLogic(ModData modData, Widget widget, Manifest mod, ModContent content, Action continueLoading, string translationFilePath)
|
||||
{
|
||||
this.content = content;
|
||||
CheckRequiredContentInstalled();
|
||||
|
||||
externalFluentBundle = new FluentBundle(Game.Settings.Player.Language, File.ReadAllText(translationFilePath), _ => { });
|
||||
|
||||
var continueMessage = FluentProvider.GetString(Continue);
|
||||
var quitMessage = FluentProvider.GetString(Quit);
|
||||
|
||||
@@ -42,17 +45,17 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
var headerTemplate = panel.Get<LabelWidget>("HEADER_TEMPLATE");
|
||||
var headerLines =
|
||||
!string.IsNullOrEmpty(content.InstallPromptMessage)
|
||||
? content.InstallPromptMessage.Replace("\\n", "\n").Split('\n')
|
||||
: Array.Empty<string>();
|
||||
? externalFluentBundle.GetString(content.InstallPromptMessage)
|
||||
: null;
|
||||
var headerHeight = 0;
|
||||
foreach (var l in headerLines)
|
||||
if (headerLines != null)
|
||||
{
|
||||
var line = (LabelWidget)headerTemplate.Clone();
|
||||
line.GetText = () => l;
|
||||
line.Bounds.Y += headerHeight;
|
||||
panel.AddChild(line);
|
||||
var label = (LabelWidget)headerTemplate.Clone();
|
||||
label.GetText = () => headerLines;
|
||||
label.IncreaseHeightToFitCurrentText();
|
||||
panel.AddChild(label);
|
||||
|
||||
headerHeight += headerTemplate.Bounds.Height;
|
||||
headerHeight += label.Bounds.Height;
|
||||
}
|
||||
|
||||
panel.Bounds.Height += headerHeight;
|
||||
@@ -64,9 +67,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
{
|
||||
Ui.OpenWindow("CONTENT_PANEL", new WidgetArgs
|
||||
{
|
||||
{ "onCancel", CheckRequiredContentInstalled },
|
||||
{ "mod", mod },
|
||||
{ "content", content },
|
||||
{ "onCancel", CheckRequiredContentInstalled }
|
||||
{ "translationFilePath", translationFilePath },
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -93,7 +93,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
return;
|
||||
|
||||
var content = modData.Manifest.Get<ModContent>();
|
||||
Game.InitializeMod(content.ContentInstallerMod, new Arguments(new[] { "Content.Mod=" + modData.Manifest.Id }));
|
||||
string translationPath;
|
||||
using (var fs = (FileStream)modData.DefaultFileSystem.Open(content.Translation))
|
||||
translationPath = fs.Name;
|
||||
Game.InitializeMod(
|
||||
content.ContentInstallerMod,
|
||||
new Arguments(new[] { "Content.Mod=" + modData.Manifest.Id, "Content.TranslationFile=" + translationPath }));
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@@ -93,9 +93,6 @@ namespace OpenRA.Server
|
||||
modData.MapCache.LoadPreviewImages = false; // PERF: Server doesn't need previews, save memory by not loading them.
|
||||
modData.MapCache.LoadMaps();
|
||||
|
||||
// HACK: Related to the above one, initialize fluent so we can resolve lobby option ids to strings.
|
||||
FluentProvider.Initialize(modData, modData.DefaultFileSystem);
|
||||
|
||||
var endpoints = new List<IPEndPoint> { new(IPAddress.IPv6Any, settings.ListenPort), new(IPAddress.Any, settings.ListenPort) };
|
||||
var server = new Server(endpoints, settings, modData, ServerType.Dedicated);
|
||||
|
||||
|
||||
6
mods/cnc/languages/en.ftl
Normal file
6
mods/cnc/languages/en.ftl
Normal file
@@ -0,0 +1,6 @@
|
||||
## Metadata
|
||||
mod-title = Tiberian Dawn
|
||||
mod-windowtitle = OpenRA - Tiberian Dawn
|
||||
|
||||
## CncLoadScreen
|
||||
loadscreen-loading = Loading
|
||||
13
mods/cnc/languages/modcontent/en.ftl
Normal file
13
mods/cnc/languages/modcontent/en.ftl
Normal file
@@ -0,0 +1,13 @@
|
||||
modcontent-installprompt =
|
||||
Tiberian Dawn requires artwork and audio from the original game.
|
||||
|
||||
Quick Install will automatically download this content (without music or videos) from a mirror of the 2007 C&C Gold freeware release.
|
||||
|
||||
Advanced Install includes options for copying the music, videos, and other content from an original game disc or digital installation.
|
||||
modcontent-header =
|
||||
Game content may be extracted from the original game discs or an existing digital install. OpenRA can also download the base game files from an online mirror of the 2007 freeware release of C&C.
|
||||
modcontent-package-basefiles = Base Game Files
|
||||
modcontent-package-basemusic = Base Game Music
|
||||
modcontent-package-gdi = GDI Campaign Briefings
|
||||
modcontent-package-nod = Nod Campaign Briefings
|
||||
modcontent-package-covertopsmusic = Covert Operations Music
|
||||
@@ -1,9 +1,9 @@
|
||||
Metadata:
|
||||
Title: Tiberian Dawn
|
||||
Title: mod-title
|
||||
Version: {DEV_VERSION}
|
||||
Website: https://www.openra.net
|
||||
WebIcon32: https://www.openra.net/images/icons/cnc_32x32.png
|
||||
WindowTitle: OpenRA - Tiberian Dawn
|
||||
WindowTitle: mod-windowtitle
|
||||
|
||||
PackageFormats: Mix
|
||||
|
||||
@@ -146,6 +146,7 @@ ChromeLayout:
|
||||
Translations:
|
||||
common|languages/en.ftl
|
||||
common|languages/rules/en.ftl
|
||||
cnc|languages/en.ftl
|
||||
cnc|languages/chrome/en.ftl
|
||||
cnc|languages/rules/en.ftl
|
||||
|
||||
@@ -176,7 +177,6 @@ LoadScreen: CncLoadScreen
|
||||
Image: cnc|uibits/chrome.png
|
||||
Image2x: cnc|uibits/chrome-2x.png
|
||||
Image3x: cnc|uibits/chrome-3x.png
|
||||
Text: Loading
|
||||
|
||||
ServerTraits:
|
||||
LobbyCommands
|
||||
@@ -278,34 +278,34 @@ GameSpeeds:
|
||||
OrderLatency: 6
|
||||
|
||||
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 copying the music, videos, and\nother content from an original game disc or digital installation.
|
||||
InstallPromptMessage: modcontent-installprompt
|
||||
QuickDownload: basefiles
|
||||
HeaderMessage: Game content may be extracted from the original game discs or an\nexisting digital install. OpenRA can also download the base game\nfiles from an online mirror of the 2007 freeware release of C&C.
|
||||
HeaderMessage: modcontent-header
|
||||
Packages:
|
||||
ContentPackage@base:
|
||||
Title: Base Game Files
|
||||
Title: modcontent-package-basefiles
|
||||
Identifier: base
|
||||
TestFiles: ^SupportDir|Content/cnc/conquer.mix, ^SupportDir|Content/cnc/desert.mix, ^SupportDir|Content/cnc/sounds.mix, ^SupportDir|Content/cnc/speech.mix, ^SupportDir|Content/cnc/temperat.mix, ^SupportDir|Content/cnc/tempicnh.mix, ^SupportDir|Content/cnc/winter.mix
|
||||
Sources: gdi95, nod95, tfd, tuc-steam, tuc-origin, cncr-steam, cncr-origin
|
||||
Required: true
|
||||
Download: basefiles
|
||||
ContentPackage@music:
|
||||
Title: Base Game Music
|
||||
Title: modcontent-package-basemusic
|
||||
Identifier: music
|
||||
TestFiles: ^SupportDir|Content/cnc/scores.mix
|
||||
Sources: gdi95, nod95, tfd, tuc-steam, tuc-origin, cncr-steam, cncr-origin
|
||||
ContentPackage@movies-gdi:
|
||||
Title: GDI Campaign Briefings
|
||||
Title: modcontent-package-gdi
|
||||
Identifier: movies-gdi
|
||||
TestFiles: ^SupportDir|Content/cnc/movies/visor.vqa, ^SupportDir|Content/cnc/movies/turtkill.vqa, ^SupportDir|Content/cnc/movies/tbrinfo3.vqa, ^SupportDir|Content/cnc/movies/tbrinfo2.vqa, ^SupportDir|Content/cnc/movies/tbrinfo1.vqa, ^SupportDir|Content/cnc/movies/seige.vqa, ^SupportDir|Content/cnc/movies/samsite.vqa, ^SupportDir|Content/cnc/movies/samdie.vqa, ^SupportDir|Content/cnc/movies/sabotage.vqa, ^SupportDir|Content/cnc/movies/retro.vqa, ^SupportDir|Content/cnc/movies/podium.vqa, ^SupportDir|Content/cnc/movies/planecra.vqa, ^SupportDir|Content/cnc/movies/pintle.vqa, ^SupportDir|Content/cnc/movies/paratrop.vqa, ^SupportDir|Content/cnc/movies/nodsweep.vqa, ^SupportDir|Content/cnc/movies/nodlose.vqa, ^SupportDir|Content/cnc/movies/nodflees.vqa, ^SupportDir|Content/cnc/movies/nod1.vqa, ^SupportDir|Content/cnc/movies/nitejump.vqa, ^SupportDir|Content/cnc/movies/napalm.vqa, ^SupportDir|Content/cnc/movies/logo.vqa, ^SupportDir|Content/cnc/movies/landing.vqa, ^SupportDir|Content/cnc/movies/intro2.vqa, ^SupportDir|Content/cnc/movies/hellvaly.vqa, ^SupportDir|Content/cnc/movies/gunboat.vqa, ^SupportDir|Content/cnc/movies/generic.vqa, ^SupportDir|Content/cnc/movies/gdilose.vqa, ^SupportDir|Content/cnc/movies/gdifinb.vqa, ^SupportDir|Content/cnc/movies/gdifina.vqa, ^SupportDir|Content/cnc/movies/gdiend2.vqa, ^SupportDir|Content/cnc/movies/gdiend1.vqa, ^SupportDir|Content/cnc/movies/gdi9.vqa, ^SupportDir|Content/cnc/movies/gdi8b.vqa, ^SupportDir|Content/cnc/movies/gdi8a.vqa, ^SupportDir|Content/cnc/movies/gdi7.vqa, ^SupportDir|Content/cnc/movies/gdi6.vqa, ^SupportDir|Content/cnc/movies/gdi5.vqa, ^SupportDir|Content/cnc/movies/gdi4b.vqa, ^SupportDir|Content/cnc/movies/gdi4a.vqa, ^SupportDir|Content/cnc/movies/gdi3lose.vqa, ^SupportDir|Content/cnc/movies/gdi3.vqa, ^SupportDir|Content/cnc/movies/gdi2.vqa, ^SupportDir|Content/cnc/movies/gdi15.vqa, ^SupportDir|Content/cnc/movies/gdi14.vqa, ^SupportDir|Content/cnc/movies/gdi13.vqa, ^SupportDir|Content/cnc/movies/gdi12.vqa, ^SupportDir|Content/cnc/movies/gdi11.vqa, ^SupportDir|Content/cnc/movies/gdi10.vqa, ^SupportDir|Content/cnc/movies/gdi1.vqa, ^SupportDir|Content/cnc/movies/gameover.vqa, ^SupportDir|Content/cnc/movies/forestkl.vqa, ^SupportDir|Content/cnc/movies/flyy.vqa, ^SupportDir|Content/cnc/movies/flag.vqa, ^SupportDir|Content/cnc/movies/dino.vqa, ^SupportDir|Content/cnc/movies/desolat.vqa, ^SupportDir|Content/cnc/movies/consyard.vqa, ^SupportDir|Content/cnc/movies/cc2tease.vqa, ^SupportDir|Content/cnc/movies/burdet2.vqa, ^SupportDir|Content/cnc/movies/burdet1.vqa, ^SupportDir|Content/cnc/movies/bombflee.vqa, ^SupportDir|Content/cnc/movies/bombaway.vqa, ^SupportDir|Content/cnc/movies/bkground.vqa, ^SupportDir|Content/cnc/movies/bcanyon.vqa, ^SupportDir|Content/cnc/movies/banner.vqa
|
||||
Sources: gdi95, tfd, tuc-steam, tuc-origin, cncr-steam, cncr-origin
|
||||
ContentPackage@movies-nod:
|
||||
Title: Nod Campaign Briefings
|
||||
Title: modcontent-package-nod
|
||||
Identifier: movies-nod
|
||||
TestFiles: ^SupportDir|Content/cnc/movies/visor.vqa, ^SupportDir|Content/cnc/movies/trtkil_d.vqa, ^SupportDir|Content/cnc/movies/tiberfx.vqa, ^SupportDir|Content/cnc/movies/tankkill.vqa, ^SupportDir|Content/cnc/movies/tankgo.vqa, ^SupportDir|Content/cnc/movies/sundial.vqa, ^SupportDir|Content/cnc/movies/stealth.vqa, ^SupportDir|Content/cnc/movies/spycrash.vqa, ^SupportDir|Content/cnc/movies/sethpre.vqa, ^SupportDir|Content/cnc/movies/seige.vqa, ^SupportDir|Content/cnc/movies/samsite.vqa, ^SupportDir|Content/cnc/movies/retro.vqa, ^SupportDir|Content/cnc/movies/refint.vqa, ^SupportDir|Content/cnc/movies/obel.vqa, ^SupportDir|Content/cnc/movies/nuke.vqa, ^SupportDir|Content/cnc/movies/nodlose.vqa, ^SupportDir|Content/cnc/movies/nodfinal.vqa, ^SupportDir|Content/cnc/movies/nodend4.vqa, ^SupportDir|Content/cnc/movies/nodend3.vqa, ^SupportDir|Content/cnc/movies/nodend2.vqa, ^SupportDir|Content/cnc/movies/nodend1.vqa, ^SupportDir|Content/cnc/movies/nod9.vqa, ^SupportDir|Content/cnc/movies/nod8.vqa, ^SupportDir|Content/cnc/movies/nod7b.vqa, ^SupportDir|Content/cnc/movies/nod7a.vqa, ^SupportDir|Content/cnc/movies/nod6.vqa, ^SupportDir|Content/cnc/movies/nod5.vqa, ^SupportDir|Content/cnc/movies/nod4b.vqa, ^SupportDir|Content/cnc/movies/nod4a.vqa, ^SupportDir|Content/cnc/movies/nod3.vqa, ^SupportDir|Content/cnc/movies/nod2.vqa, ^SupportDir|Content/cnc/movies/nod1pre.vqa, ^SupportDir|Content/cnc/movies/nod13.vqa, ^SupportDir|Content/cnc/movies/nod12.vqa, ^SupportDir|Content/cnc/movies/nod11.vqa, ^SupportDir|Content/cnc/movies/nod10b.vqa, ^SupportDir|Content/cnc/movies/nod10a.vqa, ^SupportDir|Content/cnc/movies/nod1.vqa, ^SupportDir|Content/cnc/movies/logo.vqa, ^SupportDir|Content/cnc/movies/landing.vqa, ^SupportDir|Content/cnc/movies/kanepre.vqa, ^SupportDir|Content/cnc/movies/intro2.vqa, ^SupportDir|Content/cnc/movies/insites.vqa, ^SupportDir|Content/cnc/movies/generic.vqa, ^SupportDir|Content/cnc/movies/gdi1.vqa, ^SupportDir|Content/cnc/movies/gameover.vqa, ^SupportDir|Content/cnc/movies/forestkl.vqa, ^SupportDir|Content/cnc/movies/flag.vqa, ^SupportDir|Content/cnc/movies/dino.vqa, ^SupportDir|Content/cnc/movies/dessweep.vqa, ^SupportDir|Content/cnc/movies/deskill.vqa, ^SupportDir|Content/cnc/movies/desflees.vqa, ^SupportDir|Content/cnc/movies/consyard.vqa, ^SupportDir|Content/cnc/movies/cc2tease.vqa, ^SupportDir|Content/cnc/movies/bombflee.vqa, ^SupportDir|Content/cnc/movies/bombaway.vqa, ^SupportDir|Content/cnc/movies/bcanyon.vqa, ^SupportDir|Content/cnc/movies/banner.vqa, ^SupportDir|Content/cnc/movies/akira.vqa, ^SupportDir|Content/cnc/movies/airstrk.vqa
|
||||
Sources: nod95, tfd, tuc-steam, tuc-origin, cncr-steam, cncr-origin
|
||||
ContentPackage@music-covertops:
|
||||
Title: Covert Operations Music
|
||||
Title: modcontent-package-covertopsmusic
|
||||
Identifier: music-covertops
|
||||
TestFiles: ^SupportDir|Content/cnc/scores-covertops.mix
|
||||
Sources: covertops, tfd, tuc-steam, tuc-origin, cncr-steam, cncr-origin
|
||||
@@ -318,6 +318,7 @@ ModContent:
|
||||
cnc|installer/nod95.yaml
|
||||
cnc|installer/origin.yaml
|
||||
cnc|installer/steam.yaml
|
||||
Translation: cnc|languages/modcontent/en.ftl
|
||||
|
||||
DiscordService:
|
||||
ApplicationId: 699223250181292033
|
||||
|
||||
6
mods/d2k/languages/en.ftl
Normal file
6
mods/d2k/languages/en.ftl
Normal file
@@ -0,0 +1,6 @@
|
||||
## Metadata
|
||||
mod-title = Dune 2000
|
||||
mod-windowtitle = OpenRA - Dune 2000
|
||||
|
||||
## LogoStripLoadScreen
|
||||
loadscreen-loading = Filling Crates..., Breeding Sandworms..., Fuelling carryalls..., Deploying harvesters..., Preparing thopters..., Summoning mentats...
|
||||
12
mods/d2k/languages/modcontent/en.ftl
Normal file
12
mods/d2k/languages/modcontent/en.ftl
Normal file
@@ -0,0 +1,12 @@
|
||||
modcontent-installprompt =
|
||||
Dune 2000 requires artwork and audio from the original game.
|
||||
|
||||
Quick Install will automatically download this content (without music or videos) from an online mirror of the game files.
|
||||
|
||||
Advanced Install includes options for copying the music, videos, and other content from an original game disc.
|
||||
modcontent-header =
|
||||
The original game content may be copied from an original game disc, or downloaded from an online mirror of the game files.
|
||||
modcontent-package-basefiles = Base Game Files
|
||||
modcontent-package-106patch = 1.06 Patch Content
|
||||
modcontent-package-music = Game Music
|
||||
modcontent-package-briefings = Campaign Briefings
|
||||
@@ -1,9 +1,9 @@
|
||||
Metadata:
|
||||
Title: Dune 2000
|
||||
Title: mod-title
|
||||
Version: {DEV_VERSION}
|
||||
Website: https://www.openra.net
|
||||
WebIcon32: https://www.openra.net/images/icons/d2k_32x32.png
|
||||
WindowTitle: OpenRA - Dune 2000
|
||||
WindowTitle: mod-windowtitle
|
||||
|
||||
PackageFormats: D2kSoundResources
|
||||
|
||||
@@ -124,6 +124,7 @@ Translations:
|
||||
common|languages/en.ftl
|
||||
common|languages/chrome/en.ftl
|
||||
common|languages/rules/en.ftl
|
||||
d2k|languages/en.ftl
|
||||
d2k|languages/chrome/en.ftl
|
||||
d2k|languages/rules/en.ftl
|
||||
|
||||
@@ -160,7 +161,6 @@ LoadScreen: LogoStripeLoadScreen
|
||||
Image: d2k|uibits/loadscreen.png
|
||||
Image2x: d2k|uibits/loadscreen-2x.png
|
||||
Image3x: d2k|uibits/loadscreen-3x.png
|
||||
Text: Filling Crates..., Breeding Sandworms..., Fuelling carryalls..., Deploying harvesters..., Preparing thopters..., Summoning mentats...
|
||||
|
||||
ServerTraits:
|
||||
LobbyCommands
|
||||
@@ -259,31 +259,31 @@ GameSpeeds:
|
||||
OrderLatency: 6
|
||||
|
||||
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.
|
||||
HeaderMessage: The original game content may be copied from an original game disc,\nor downloaded from an online mirror of the game files.
|
||||
InstallPromptMessage: modcontent-installprompt
|
||||
HeaderMessage: modcontent-header
|
||||
QuickDownload: quickinstall
|
||||
Packages:
|
||||
ContentPackage@base:
|
||||
Title: Base Game Files
|
||||
Title: modcontent-package-basefiles
|
||||
Identifier: base
|
||||
TestFiles: ^SupportDir|Content/d2k/v3/BLOXBASE.R16, ^SupportDir|Content/d2k/v3/BLOXBAT.R16, ^SupportDir|Content/d2k/v3/BLOXBGBS.R16, ^SupportDir|Content/d2k/v3/BLOXICE.R16, ^SupportDir|Content/d2k/v3/BLOXTREE.R16, ^SupportDir|Content/d2k/v3/BLOXWAST.R16, ^SupportDir|Content/d2k/v3/SOUND.RS, ^SupportDir|Content/d2k/v3/PALETTE.BIN
|
||||
Sources: d2k, gruntmods
|
||||
Required: true
|
||||
Download: basefiles
|
||||
ContentPackage@patch:
|
||||
Title: 1.06 Patch Content
|
||||
Title: modcontent-package-106patch
|
||||
Identifier: patch
|
||||
TestFiles: ^SupportDir|Content/d2k/v3/DATA.R16
|
||||
Sources: gruntmods
|
||||
Required: true
|
||||
Download: patch106
|
||||
ContentPackage@music:
|
||||
Title: Game Music
|
||||
Title: modcontent-package-music
|
||||
Identifier: music
|
||||
TestFiles: ^SupportDir|Content/d2k/v3/Music/AMBUSH.AUD, ^SupportDir|Content/d2k/v3/Music/WAITGAME.AUD
|
||||
Sources: d2k, gruntmods
|
||||
ContentPackage@movies:
|
||||
Title: Campaign Briefings
|
||||
Title: modcontent-package-briefings
|
||||
Identifier: movies
|
||||
TestFiles: ^SupportDir|Content/d2k/v3/Movies/A_BR01_E.VQA
|
||||
Sources: d2k
|
||||
@@ -292,6 +292,7 @@ ModContent:
|
||||
Sources:
|
||||
d2k|installer/d2k.yaml
|
||||
d2k|installer/gruntmods.yaml
|
||||
Translation: d2k|languages/modcontent/en.ftl
|
||||
|
||||
DiscordService:
|
||||
ApplicationId: 712711732770111550
|
||||
|
||||
@@ -21,10 +21,12 @@ Background@CONTENT_PANEL:
|
||||
Align: Center
|
||||
Font: MediumBold
|
||||
Label@HEADER_TEMPLATE:
|
||||
X: 30
|
||||
Y: 66
|
||||
Width: PARENT_RIGHT
|
||||
Width: PARENT_RIGHT - 60
|
||||
Height: 16
|
||||
Align: Center
|
||||
WordWrap: true
|
||||
ScrollPanel@PACKAGES:
|
||||
X: 30
|
||||
Y: 84
|
||||
@@ -342,10 +344,12 @@ Background@CONTENT_PROMPT_PANEL:
|
||||
Align: Center
|
||||
Font: MediumBold
|
||||
Label@HEADER_TEMPLATE:
|
||||
X: 30
|
||||
Y: 65
|
||||
Width: PARENT_RIGHT
|
||||
Width: PARENT_RIGHT - 60
|
||||
Height: 16
|
||||
Align: Center
|
||||
WordWrap: true
|
||||
Button@ADVANCED_BUTTON:
|
||||
X: 30
|
||||
Y: PARENT_BOTTOM - 52
|
||||
|
||||
2
mods/modcontent/languages/en.ftl
Normal file
2
mods/modcontent/languages/en.ftl
Normal file
@@ -0,0 +1,2 @@
|
||||
## Metadata
|
||||
mod-title = Mod Content Manager
|
||||
@@ -1,5 +1,5 @@
|
||||
Metadata:
|
||||
Title: Mod Content Manager
|
||||
Title: mod-title
|
||||
Version: {DEV_VERSION}
|
||||
Hidden: true
|
||||
|
||||
@@ -37,6 +37,7 @@ ChromeMetrics:
|
||||
|
||||
Translations:
|
||||
common|languages/en.ftl
|
||||
modcontent|languages/en.ftl
|
||||
|
||||
Fonts:
|
||||
Tiny:
|
||||
|
||||
6
mods/ra/languages/en.ftl
Normal file
6
mods/ra/languages/en.ftl
Normal file
@@ -0,0 +1,6 @@
|
||||
## Metadata
|
||||
mod-title = Red Alert
|
||||
mod-windowtitle = OpenRA - Red Alert
|
||||
|
||||
## LogoStripeLoadScreen
|
||||
loadscreen-loading = Filling Crates..., Charging Capacitors..., Reticulating Splines..., Planting Trees..., Building Bridges..., Aging Empires..., Compiling EVA..., Constructing Pylons..., Activating Skynet..., Splitting Atoms...
|
||||
16
mods/ra/languages/modcontent/en.ftl
Normal file
16
mods/ra/languages/modcontent/en.ftl
Normal file
@@ -0,0 +1,16 @@
|
||||
modcontent-installprompt =
|
||||
Red Alert requires artwork and audio from the original game.
|
||||
|
||||
Quick Install will automatically download this content (without music or videos) from a mirror of the 2008 Red Alert freeware release.
|
||||
|
||||
Advanced Install includes options for copying the music, videos, and other content from an original game disc or digital installation.
|
||||
modcontent-header =
|
||||
Game content may be extracted from the original game discs or an existing digital install. OpenRA can also download the base game files from an online mirror of the 2008 freeware release of RA.
|
||||
modcontent-package-basefiles = Base Game Files
|
||||
modcontent-package-aftermathfiles = Aftermath Expansion Files
|
||||
modcontent-package-deserttileset = C&C Desert Tileset
|
||||
modcontent-package-basemusic = Base Game Music
|
||||
modcontent-package-allied = Allied Campaign Briefings
|
||||
modcontent-package-soviet = Soviet Campaign Briefings
|
||||
modcontent-package-counterstrikemusic = Counterstrike Music
|
||||
modcontent-package-aftermathmusic = Aftermath Music
|
||||
@@ -1,9 +1,9 @@
|
||||
Metadata:
|
||||
Title: Red Alert
|
||||
Title: mod-title
|
||||
Version: {DEV_VERSION}
|
||||
Website: https://www.openra.net
|
||||
WebIcon32: https://www.openra.net/images/icons/ra_32x32.png
|
||||
WindowTitle: OpenRA - Red Alert
|
||||
WindowTitle: mod-windowtitle
|
||||
|
||||
PackageFormats: Mix
|
||||
|
||||
@@ -142,6 +142,7 @@ Translations:
|
||||
common|languages/en.ftl
|
||||
common|languages/chrome/en.ftl
|
||||
common|languages/rules/en.ftl
|
||||
ra|languages/en.ftl
|
||||
ra|languages/chrome/en.ftl
|
||||
ra|languages/rules/en.ftl
|
||||
|
||||
@@ -179,7 +180,6 @@ LoadScreen: LogoStripeLoadScreen
|
||||
Image: ra|uibits/loadscreen.png
|
||||
Image2x: ra|uibits/loadscreen-2x.png
|
||||
Image3x: ra|uibits/loadscreen-3x.png
|
||||
Text: Filling Crates..., Charging Capacitors..., Reticulating Splines..., Planting Trees..., Building Bridges..., Aging Empires..., Compiling EVA..., Constructing Pylons..., Activating Skynet..., Splitting Atoms...
|
||||
|
||||
ServerTraits:
|
||||
LobbyCommands
|
||||
@@ -281,53 +281,53 @@ GameSpeeds:
|
||||
OrderLatency: 6
|
||||
|
||||
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 copying the music, videos, and\nother content from an original game disc or digital installation.
|
||||
InstallPromptMessage: modcontent-installprompt
|
||||
QuickDownload: quickinstall
|
||||
HeaderMessage: Game content may be extracted from the original game discs or an\nexisting digital install. OpenRA can also download the base game\nfiles from an online mirror of the 2008 freeware release of RA.
|
||||
HeaderMessage: modcontent-header
|
||||
Packages:
|
||||
ContentPackage@base:
|
||||
Title: Base Game Files
|
||||
Title: modcontent-package-basefiles
|
||||
Identifier: base
|
||||
TestFiles: ^SupportDir|Content/ra/v2/allies.mix, ^SupportDir|Content/ra/v2/conquer.mix, ^SupportDir|Content/ra/v2/interior.mix, ^SupportDir|Content/ra/v2/hires.mix, ^SupportDir|Content/ra/v2/lores.mix, ^SupportDir|Content/ra/v2/local.mix, ^SupportDir|Content/ra/v2/speech.mix, ^SupportDir|Content/ra/v2/russian.mix, ^SupportDir|Content/ra/v2/snow.mix, ^SupportDir|Content/ra/v2/sounds.mix, ^SupportDir|Content/ra/v2/temperat.mix
|
||||
Sources: allied, soviet, tfd, ra-steam, ra-origin, cncr-steam, cncr-origin
|
||||
Required: true
|
||||
Download: basefiles
|
||||
ContentPackage@aftermathbase:
|
||||
Title: Aftermath Expansion Files
|
||||
Title: modcontent-package-aftermathfiles
|
||||
Identifier: aftermathbase
|
||||
TestFiles: ^SupportDir|Content/ra/v2/expand/expand2.mix, ^SupportDir|Content/ra/v2/expand/hires1.mix, ^SupportDir|Content/ra/v2/expand/lores1.mix, ^SupportDir|Content/ra/v2/expand/chrotnk1.aud, ^SupportDir|Content/ra/v2/expand/fixit1.aud, ^SupportDir|Content/ra/v2/expand/jburn1.aud, ^SupportDir|Content/ra/v2/expand/jchrge1.aud, ^SupportDir|Content/ra/v2/expand/jcrisp1.aud, ^SupportDir|Content/ra/v2/expand/jdance1.aud, ^SupportDir|Content/ra/v2/expand/jjuice1.aud, ^SupportDir|Content/ra/v2/expand/jjump1.aud, ^SupportDir|Content/ra/v2/expand/jlight1.aud, ^SupportDir|Content/ra/v2/expand/jpower1.aud, ^SupportDir|Content/ra/v2/expand/jshock1.aud, ^SupportDir|Content/ra/v2/expand/jyes1.aud, ^SupportDir|Content/ra/v2/expand/madchrg2.aud, ^SupportDir|Content/ra/v2/expand/madexplo.aud, ^SupportDir|Content/ra/v2/expand/mboss1.aud, ^SupportDir|Content/ra/v2/expand/mhear1.aud, ^SupportDir|Content/ra/v2/expand/mhotdig1.aud, ^SupportDir|Content/ra/v2/expand/mhowdy1.aud, ^SupportDir|Content/ra/v2/expand/mhuh1.aud, ^SupportDir|Content/ra/v2/expand/mlaff1.aud, ^SupportDir|Content/ra/v2/expand/mrise1.aud, ^SupportDir|Content/ra/v2/expand/mwrench1.aud, ^SupportDir|Content/ra/v2/expand/myeehaw1.aud, ^SupportDir|Content/ra/v2/expand/myes1.aud
|
||||
Sources: aftermath, tfd, ra-steam, ra-origin, cncr-steam, cncr-origin
|
||||
Required: true
|
||||
Download: aftermath
|
||||
ContentPackage@cncdesert:
|
||||
Title: C&C Desert Tileset
|
||||
Title: modcontent-package-deserttileset
|
||||
Identifier: cncdesert
|
||||
TestFiles: ^SupportDir|Content/ra/v2/cnc/desert.mix
|
||||
Sources: tfd, cnc-steam, cnc-origin, cnc95, cncr-steam, cncr-origin
|
||||
Required: true
|
||||
Download: cncdesert
|
||||
ContentPackage@music:
|
||||
Title: Base Game Music
|
||||
Title: modcontent-package-basemusic
|
||||
Identifier: music
|
||||
TestFiles: ^SupportDir|Content/ra/v2/scores.mix
|
||||
Sources: allied, soviet, tfd, ra-steam, ra-origin, cncr-steam, cncr-origin
|
||||
ContentPackage@movies-allied:
|
||||
Title: Allied Campaign Briefings
|
||||
Title: modcontent-package-allied
|
||||
Identifier: movies-allied
|
||||
TestFiles: ^SupportDir|Content/ra/v2/movies/aagun.vqa, ^SupportDir|Content/ra/v2/movies/aftrmath.vqa, ^SupportDir|Content/ra/v2/movies/ally1.vqa, ^SupportDir|Content/ra/v2/movies/ally10.vqa, ^SupportDir|Content/ra/v2/movies/ally10b.vqa, ^SupportDir|Content/ra/v2/movies/ally11.vqa, ^SupportDir|Content/ra/v2/movies/ally12.vqa, ^SupportDir|Content/ra/v2/movies/ally14.vqa, ^SupportDir|Content/ra/v2/movies/ally2.vqa, ^SupportDir|Content/ra/v2/movies/ally4.vqa, ^SupportDir|Content/ra/v2/movies/ally5.vqa, ^SupportDir|Content/ra/v2/movies/ally6.vqa, ^SupportDir|Content/ra/v2/movies/ally8.vqa, ^SupportDir|Content/ra/v2/movies/ally9.vqa, ^SupportDir|Content/ra/v2/movies/allyend.vqa, ^SupportDir|Content/ra/v2/movies/allymorf.vqa, ^SupportDir|Content/ra/v2/movies/apcescpe.vqa, ^SupportDir|Content/ra/v2/movies/assess.vqa, ^SupportDir|Content/ra/v2/movies/battle.vqa, ^SupportDir|Content/ra/v2/movies/binoc.vqa, ^SupportDir|Content/ra/v2/movies/bmap.vqa, ^SupportDir|Content/ra/v2/movies/brdgtilt.vqa, ^SupportDir|Content/ra/v2/movies/crontest.vqa, ^SupportDir|Content/ra/v2/movies/cronfail.vqa, ^SupportDir|Content/ra/v2/movies/destroyr.vqa, ^SupportDir|Content/ra/v2/movies/dud.vqa, ^SupportDir|Content/ra/v2/movies/elevator.vqa, ^SupportDir|Content/ra/v2/movies/flare.vqa, ^SupportDir|Content/ra/v2/movies/frozen.vqa, ^SupportDir|Content/ra/v2/movies/grvestne.vqa, ^SupportDir|Content/ra/v2/movies/landing.vqa, ^SupportDir|Content/ra/v2/movies/masasslt.vqa, ^SupportDir|Content/ra/v2/movies/mcv.vqa, ^SupportDir|Content/ra/v2/movies/mcv_land.vqa, ^SupportDir|Content/ra/v2/movies/montpass.vqa, ^SupportDir|Content/ra/v2/movies/oildrum.vqa, ^SupportDir|Content/ra/v2/movies/overrun.vqa, ^SupportDir|Content/ra/v2/movies/prolog.vqa, ^SupportDir|Content/ra/v2/movies/redintro.vqa, ^SupportDir|Content/ra/v2/movies/shipsink.vqa, ^SupportDir|Content/ra/v2/movies/shorbom1.vqa, ^SupportDir|Content/ra/v2/movies/shorbom2.vqa, ^SupportDir|Content/ra/v2/movies/shorbomb.vqa, ^SupportDir|Content/ra/v2/movies/snowbomb.vqa, ^SupportDir|Content/ra/v2/movies/soviet1.vqa, ^SupportDir|Content/ra/v2/movies/sovtstar.vqa, ^SupportDir|Content/ra/v2/movies/spy.vqa, ^SupportDir|Content/ra/v2/movies/tanya1.vqa, ^SupportDir|Content/ra/v2/movies/tanya2.vqa, ^SupportDir|Content/ra/v2/movies/toofar.vqa, ^SupportDir|Content/ra/v2/movies/trinity.vqa
|
||||
Sources: allied, tfd, ra-steam, ra-origin, cncr-steam, cncr-origin
|
||||
ContentPackage@movies-soviet:
|
||||
Title: Soviet Campaign Briefings
|
||||
Title: modcontent-package-soviet
|
||||
Identifier: movies-soviet
|
||||
TestFiles: ^SupportDir|Content/ra/v2/movies/aagun.vqa, ^SupportDir|Content/ra/v2/movies/cronfail.vqa, ^SupportDir|Content/ra/v2/movies/airfield.vqa, ^SupportDir|Content/ra/v2/movies/ally1.vqa, ^SupportDir|Content/ra/v2/movies/allymorf.vqa, ^SupportDir|Content/ra/v2/movies/averted.vqa, ^SupportDir|Content/ra/v2/movies/beachead.vqa, ^SupportDir|Content/ra/v2/movies/bmap.vqa, ^SupportDir|Content/ra/v2/movies/bombrun.vqa, ^SupportDir|Content/ra/v2/movies/countdwn.vqa, ^SupportDir|Content/ra/v2/movies/double.vqa, ^SupportDir|Content/ra/v2/movies/dpthchrg.vqa, ^SupportDir|Content/ra/v2/movies/execute.vqa, ^SupportDir|Content/ra/v2/movies/flare.vqa, ^SupportDir|Content/ra/v2/movies/landing.vqa, ^SupportDir|Content/ra/v2/movies/mcvbrdge.vqa, ^SupportDir|Content/ra/v2/movies/mig.vqa, ^SupportDir|Content/ra/v2/movies/movingin.vqa, ^SupportDir|Content/ra/v2/movies/mtnkfact.vqa, ^SupportDir|Content/ra/v2/movies/nukestok.vqa, ^SupportDir|Content/ra/v2/movies/onthprwl.vqa, ^SupportDir|Content/ra/v2/movies/periscop.vqa, ^SupportDir|Content/ra/v2/movies/prolog.vqa, ^SupportDir|Content/ra/v2/movies/radrraid.vqa, ^SupportDir|Content/ra/v2/movies/redintro.vqa, ^SupportDir|Content/ra/v2/movies/search.vqa, ^SupportDir|Content/ra/v2/movies/sfrozen.vqa, ^SupportDir|Content/ra/v2/movies/sitduck.vqa, ^SupportDir|Content/ra/v2/movies/slntsrvc.vqa, ^SupportDir|Content/ra/v2/movies/snowbomb.vqa, ^SupportDir|Content/ra/v2/movies/snstrafe.vqa, ^SupportDir|Content/ra/v2/movies/sovbatl.vqa, ^SupportDir|Content/ra/v2/movies/sovcemet.vqa, ^SupportDir|Content/ra/v2/movies/sovfinal.vqa, ^SupportDir|Content/ra/v2/movies/soviet1.vqa, ^SupportDir|Content/ra/v2/movies/soviet10.vqa, ^SupportDir|Content/ra/v2/movies/soviet11.vqa, ^SupportDir|Content/ra/v2/movies/soviet12.vqa, ^SupportDir|Content/ra/v2/movies/soviet13.vqa, ^SupportDir|Content/ra/v2/movies/soviet14.vqa, ^SupportDir|Content/ra/v2/movies/soviet2.vqa, ^SupportDir|Content/ra/v2/movies/soviet3.vqa, ^SupportDir|Content/ra/v2/movies/soviet4.vqa, ^SupportDir|Content/ra/v2/movies/soviet5.vqa, ^SupportDir|Content/ra/v2/movies/soviet6.vqa, ^SupportDir|Content/ra/v2/movies/soviet7.vqa, ^SupportDir|Content/ra/v2/movies/soviet8.vqa, ^SupportDir|Content/ra/v2/movies/soviet9.vqa, ^SupportDir|Content/ra/v2/movies/sovmcv.vqa, ^SupportDir|Content/ra/v2/movies/sovtstar.vqa, ^SupportDir|Content/ra/v2/movies/spotter.vqa, ^SupportDir|Content/ra/v2/movies/strafe.vqa, ^SupportDir|Content/ra/v2/movies/take_off.vqa, ^SupportDir|Content/ra/v2/movies/tesla.vqa, ^SupportDir|Content/ra/v2/movies/v2rocket.vqa
|
||||
Sources: soviet, tfd, ra-steam, ra-origin
|
||||
ContentPackage@music-counterstrike:
|
||||
Title: Counterstrike Music
|
||||
Title: modcontent-package-counterstrikemusic
|
||||
Identifier: music-counterstrike
|
||||
TestFiles: ^SupportDir|Content/ra/v2/expand/araziod.aud, ^SupportDir|Content/ra/v2/expand/backstab.aud, ^SupportDir|Content/ra/v2/expand/chaos2.aud, ^SupportDir|Content/ra/v2/expand/shut_it.aud, ^SupportDir|Content/ra/v2/expand/2nd_hand.aud, ^SupportDir|Content/ra/v2/expand/twinmix1.aud, ^SupportDir|Content/ra/v2/expand/under3.aud, ^SupportDir|Content/ra/v2/expand/vr2.aud,
|
||||
Sources: counterstrike, ra-steam, ra-origin, cncr-steam, cncr-origin
|
||||
ContentPackage@music-aftermath:
|
||||
Title: Aftermath Music
|
||||
Title: modcontent-package-aftermathmusic
|
||||
Identifier: music-aftermath
|
||||
TestFiles: ^SupportDir|Content/ra/v2/expand/await.aud, ^SupportDir|Content/ra/v2/expand/bog.aud, ^SupportDir|Content/ra/v2/expand/float_v2.aud, ^SupportDir|Content/ra/v2/expand/gloom.aud, ^SupportDir|Content/ra/v2/expand/grndwire.aud, ^SupportDir|Content/ra/v2/expand/rpt.aud, ^SupportDir|Content/ra/v2/expand/search.aud, ^SupportDir|Content/ra/v2/expand/traction.aud, ^SupportDir|Content/ra/v2/expand/wastelnd.aud
|
||||
Sources: aftermath, ra-steam, ra-origin, cncr-steam, cncr-origin
|
||||
@@ -342,6 +342,7 @@ ModContent:
|
||||
ra|installer/origin.yaml
|
||||
ra|installer/soviet95.yaml
|
||||
ra|installer/steam.yaml
|
||||
Translation: ra|languages/modcontent/en.ftl
|
||||
|
||||
DiscordService:
|
||||
ApplicationId: 699222659766026240
|
||||
|
||||
6
mods/ts/languages/en.ftl
Normal file
6
mods/ts/languages/en.ftl
Normal file
@@ -0,0 +1,6 @@
|
||||
## Metadata
|
||||
mod-title = Tiberian Sun
|
||||
mod-windowtitle = OpenRA - Tiberian Sun
|
||||
|
||||
## LogoStripeLoadScreen
|
||||
loadscreen-loading = Updating EVA installation..., Changing perspective...
|
||||
12
mods/ts/languages/modcontent/en.ftl
Normal file
12
mods/ts/languages/modcontent/en.ftl
Normal file
@@ -0,0 +1,12 @@
|
||||
modcontent-installprompt =
|
||||
Tiberian Sun requires artwork and audio from the original game.
|
||||
|
||||
Quick Install will automatically download this content (without music or videos) from a mirror of the 2012 Tiberian Sun freeware release.
|
||||
|
||||
Advanced Install includes options for copying the music, videos, and other content from an original game disc or digital installation.
|
||||
modcontent-header =
|
||||
Game content may be extracted from the original game discs or an existing digital install. OpenRA can also download the base game files from an online mirror of the 2012 freeware release of TS.
|
||||
modcontent-package-basefiles = Base Game Files
|
||||
modcontent-package-basemusic = Base Game Music
|
||||
modcontent-package-firestormfiles = Firestorm Expansion Files
|
||||
modcontent-package-firestormmusic = Firestorm Expansion Music
|
||||
@@ -1,9 +1,9 @@
|
||||
Metadata:
|
||||
Title: Tiberian Sun
|
||||
Title: mod-title
|
||||
Version: {DEV_VERSION}
|
||||
Website: https://www.openra.net
|
||||
WebIcon32: https://www.openra.net/images/icons/ts_32x32.png
|
||||
WindowTitle: OpenRA - Tiberian Sun
|
||||
WindowTitle: mod-windowtitle
|
||||
|
||||
PackageFormats: Mix
|
||||
|
||||
@@ -187,6 +187,7 @@ Translations:
|
||||
common|languages/en.ftl
|
||||
common|languages/chrome/en.ftl
|
||||
common|languages/rules/en.ftl
|
||||
ts|languages/en.ftl
|
||||
ts|languages/chrome/en.ftl
|
||||
ts|languages/rules/en.ftl
|
||||
|
||||
@@ -216,7 +217,6 @@ Hotkeys:
|
||||
|
||||
LoadScreen: LogoStripeLoadScreen
|
||||
Image: ts|uibits/loadscreen.png
|
||||
Text: Updating EVA installation..., Changing perspective...
|
||||
|
||||
ServerTraits:
|
||||
LobbyCommands
|
||||
@@ -312,31 +312,31 @@ GameSpeeds:
|
||||
OrderLatency: 6
|
||||
|
||||
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 copying the music, videos, and\nother content from an original game disc or digital installation.
|
||||
InstallPromptMessage: modcontent-installprompt
|
||||
QuickDownload: quickinstall
|
||||
HeaderMessage: Game content may be extracted from the original game discs or an\nexisting digital install. OpenRA can also download the base game\nfiles from an online mirror of the 2012 freeware release of TS.
|
||||
HeaderMessage: modcontent-header
|
||||
Packages:
|
||||
ContentPackage@tibsun:
|
||||
Title: Base Game Files
|
||||
Title: modcontent-package-basefiles
|
||||
Identifier: tibsun
|
||||
TestFiles: ^SupportDir|Content/ts/cache.mix, ^SupportDir|Content/ts/conquer.mix, ^SupportDir|Content/ts/isosnow.mix, ^SupportDir|Content/ts/isotemp.mix, ^SupportDir|Content/ts/local.mix, ^SupportDir|Content/ts/sidec01.mix, ^SupportDir|Content/ts/sidec02.mix, ^SupportDir|Content/ts/sno.mix, ^SupportDir|Content/ts/snow.mix, ^SupportDir|Content/ts/sounds.mix, ^SupportDir|Content/ts/speech01.mix, ^SupportDir|Content/ts/tem.mix, ^SupportDir|Content/ts/temperat.mix
|
||||
Sources: tibsun, tfd, steam, origin
|
||||
Required: true
|
||||
Download: basefiles
|
||||
ContentPackage@tibsun-music:
|
||||
Title: Base Game Music
|
||||
Title: modcontent-package-basemusic
|
||||
Identifier: tibsun-music
|
||||
TestFiles: ^SupportDir|Content/ts/scores.mix
|
||||
Sources: tibsun, tfd, steam, origin
|
||||
ContentPackage@fstorm:
|
||||
Title: Firestorm Expansion Files
|
||||
Title: modcontent-package-firestormfiles
|
||||
Identifier: fstorm
|
||||
TestFiles: ^SupportDir|Content/ts/firestorm/e01sc01.mix, ^SupportDir|Content/ts/firestorm/e01sc02.mix, ^SupportDir|Content/ts/firestorm/e01vox01.mix, ^SupportDir|Content/ts/firestorm/e01vox02.mix
|
||||
Sources: tfd, steam, origin, fstorm
|
||||
Required: true
|
||||
Download: fstorm
|
||||
ContentPackage@fstorm-music:
|
||||
Title: Firestorm Expansion Music
|
||||
Title: modcontent-package-firestormmusic
|
||||
Identifier: fstorm-music
|
||||
Sources: tfd, steam, origin, fstorm
|
||||
TestFiles: ^SupportDir|Content/ts/firestorm/scores01.mix
|
||||
@@ -348,6 +348,7 @@ ModContent:
|
||||
ts|installer/steam.yaml
|
||||
ts|installer/origin.yaml
|
||||
ts|installer/tibsun.yaml
|
||||
Translation: ts|languages/modcontent/en.ftl
|
||||
|
||||
DiscordService:
|
||||
ApplicationId: 712713986558394399
|
||||
|
||||
Reference in New Issue
Block a user