diff --git a/.github/workflows/packaging.yml b/.github/workflows/packaging.yml index 7a32f93..ebf41cf 100644 --- a/.github/workflows/packaging.yml +++ b/.github/workflows/packaging.yml @@ -14,10 +14,10 @@ jobs: runs-on: ubuntu-22.04 steps: - name: Clone Repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install .NET 6.0 - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 with: dotnet-version: '6.0.x' @@ -28,7 +28,7 @@ jobs: run: | make engine mkdir -p build/linux - sudo apt install libfuse2 + sudo apt-get install -y desktop-file-utils ./packaging/linux/buildpackage.sh "${GIT_TAG}" "${PWD}/build/linux" - name: Upload Packages @@ -42,13 +42,13 @@ jobs: macos: name: macOS Disk Image - runs-on: macos-11 + runs-on: macos-13 steps: - name: Clone Repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install .NET 6.0 - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 with: dotnet-version: '6.0.x' @@ -81,10 +81,10 @@ jobs: runs-on: ubuntu-22.04 steps: - name: Clone Repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install .NET 6.0 - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 with: dotnet-version: '6.0.x' @@ -107,4 +107,4 @@ jobs: tag: ${{ github.ref }} overwrite: true file_glob: true - file: build/windows/* + file: build/windows/* \ No newline at end of file diff --git a/OpenRA.Mods.Mobius/FileSystem/RemasterFileSystemLoader.cs b/OpenRA.Mods.Mobius/FileSystem/RemasterFileSystemLoader.cs new file mode 100644 index 0000000..1272f42 --- /dev/null +++ b/OpenRA.Mods.Mobius/FileSystem/RemasterFileSystemLoader.cs @@ -0,0 +1,90 @@ +#region Copyright & License Information +/* + * Copyright (c) The OpenRA Developers and Contributors + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. For more + * information, see COPYING. + */ +#endregion + +using System.Collections.Generic; +using System.IO; +using System.Linq; +using OpenRA.Mods.Common; +using OpenRA.Mods.Common.FileSystem; +using OpenRA.Mods.Common.Installer; + +namespace OpenRA.Mods.Mobius.FileSystem +{ + public class RemasterFileSystemLoader : IFileSystemLoader, IFileSystemExternalContent + { + [FieldLoader.Require] + public readonly string RemasterDataMount = null; + public readonly string InstallPromptMod = "remaster-content"; + public readonly Dictionary Packages = null; + public readonly Dictionary RemasterPackages = null; + + [FieldLoader.LoadUsing(nameof(LoadSources))] + readonly Dictionary sources = null; + + static object LoadSources(MiniYaml yaml) + { + var ret = new Dictionary(); + var sourcesNode = yaml.Nodes.Single(n => n.Key == "Sources"); + foreach (var s in sourcesNode.Value.Nodes) + ret.Add(s.Key, new ModContent.ModSource(s.Value)); + + return ret; + } + + bool contentAvailable = true; + + public void Mount(OpenRA.FileSystem.FileSystem fileSystem, ObjectCreator objectCreator) + { + if (Packages != null) + foreach (var kv in Packages) + fileSystem.Mount(kv.Key, kv.Value); + + if (RemasterPackages == null) + return; + + foreach (var kv in sources) + { + var sourceResolver = objectCreator.CreateObject($"{kv.Value.Type.Value}SourceResolver"); + var path = sourceResolver.FindSourcePath(kv.Value); + if (path != null) + { + var dataPath = Path.Combine(path, "Data"); + if (!Directory.Exists(dataPath)) + { + contentAvailable = false; + continue; + } + + fileSystem.Mount(dataPath, RemasterDataMount); + foreach (var p in RemasterPackages) + { + var package = fileSystem.OpenPackage(p.Key); + if (package == null) + { + contentAvailable = false; + continue; + } + + fileSystem.Mount(package, p.Value); + } + } + } + } + + bool IFileSystemExternalContent.InstallContentIfRequired(ModData modData) + { + if (!contentAvailable) + Game.InitializeMod(InstallPromptMod, new Arguments()); + + return !contentAvailable; + } + } +} diff --git a/OpenRA.Mods.Mobius/RemasterContentPromptLogic.cs b/OpenRA.Mods.Mobius/RemasterContentPromptLogic.cs index fc40837..5f990fd 100644 --- a/OpenRA.Mods.Mobius/RemasterContentPromptLogic.cs +++ b/OpenRA.Mods.Mobius/RemasterContentPromptLogic.cs @@ -18,7 +18,6 @@ public class RemasterContentPromptLogic : ChromeLogic [ObjectCreator.UseCtor] public RemasterContentPromptLogic(Widget widget, ModData modData) { - widget.Get("VERSION_LABEL").Text = modData.Manifest.Metadata.Version; widget.Get("QUIT_BUTTON").OnClick = Game.Exit; } } diff --git a/OpenRA.Mods.Mobius/RemasterInstallPromptLoadScreen.cs b/OpenRA.Mods.Mobius/RemasterInstallPromptLoadScreen.cs deleted file mode 100644 index f473de0..0000000 --- a/OpenRA.Mods.Mobius/RemasterInstallPromptLoadScreen.cs +++ /dev/null @@ -1,24 +0,0 @@ -#region Copyright & License Information -/* - * Copyright (c) The OpenRA Developers and Contributors - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. For more - * information, see COPYING. - */ -#endregion - -using OpenRA.Mods.Cnc; -using OpenRA.Widgets; - -namespace OpenRA.Mods.Mobius -{ - public sealed class RemasterInstallPromptLoadScreen : CncLoadScreen - { - public override void StartGame(Arguments args) - { - Ui.OpenWindow("PROMPT_CONTAINER", new WidgetArgs()); - } - } -} diff --git a/OpenRA.Mods.Mobius/RemasterLoadScreen.cs b/OpenRA.Mods.Mobius/RemasterLoadScreen.cs deleted file mode 100644 index ca16641..0000000 --- a/OpenRA.Mods.Mobius/RemasterLoadScreen.cs +++ /dev/null @@ -1,27 +0,0 @@ -#region Copyright & License Information -/* - * Copyright (c) The OpenRA Developers and Contributors - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. For more - * information, see COPYING. - */ -#endregion - -using OpenRA.Mods.Cnc; - -namespace OpenRA.Mods.Mobius -{ - public sealed class RemasterLoadScreen : CncLoadScreen - { - public override bool BeforeLoad() - { - var remasterContent = ModData.Manifest.Get(); - if (!remasterContent.TryMountPackages(ModData)) - return false; - - return base.BeforeLoad(); - } - } -} diff --git a/OpenRA.Mods.Mobius/RemasterPackages.cs b/OpenRA.Mods.Mobius/RemasterPackages.cs deleted file mode 100644 index 765593c..0000000 --- a/OpenRA.Mods.Mobius/RemasterPackages.cs +++ /dev/null @@ -1,74 +0,0 @@ -#region Copyright & License Information -/* - * Copyright (c) The OpenRA Developers and Contributors - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. For more - * information, see COPYING. - */ -#endregion - -using System.Collections.Generic; -using System.IO; -using System.Linq; -using OpenRA.Mods.Common.Installer; - -namespace OpenRA.Mods.Mobius -{ - public sealed class RemasterModContent : IGlobalModData - { - [FieldLoader.Require] - public readonly string RemasterDataMount = null; - public readonly string InstallPromptMod = "cnccontent"; - public readonly Dictionary Packages; - - [FieldLoader.Ignore] - readonly Dictionary sources = new(); - - public RemasterModContent(MiniYaml yaml) - { - FieldLoader.Load(this, yaml); - - var sourcesNode = yaml.Nodes.Single(n => n.Key == "Sources"); - foreach (var s in sourcesNode.Value.Nodes) - sources.Add(s.Key, new ModContent.ModSource(s.Value, null)); - } - - public bool TryMountPackagesInner(ModData modData) - { - foreach (var kv in sources) - { - var sourceResolver = modData.ObjectCreator.CreateObject($"{kv.Value.Type.Value}SourceResolver"); - var path = sourceResolver.FindSourcePath(kv.Value); - if (path != null) - { - modData.ModFiles.Mount(Path.Combine(path, "Data"), RemasterDataMount); - foreach (var p in Packages) - { - var package = modData.ModFiles.OpenPackage(p.Key); - if (package == null) - return false; - - modData.ModFiles.Mount(package, p.Value); - } - - return true; - } - } - - return false; - } - - public bool TryMountPackages(ModData modData) - { - if (!TryMountPackagesInner(modData)) - { - Game.InitializeMod(InstallPromptMod, new Arguments()); - return false; - } - - return true; - } - } -} diff --git a/OpenRA.Mods.Mobius/RemasterSpriteSequence.cs b/OpenRA.Mods.Mobius/RemasterSpriteSequence.cs index 62e61d3..c4099ef 100644 --- a/OpenRA.Mods.Mobius/RemasterSpriteSequence.cs +++ b/OpenRA.Mods.Mobius/RemasterSpriteSequence.cs @@ -10,6 +10,7 @@ #endregion using System.Collections.Generic; +using System.IO; using System.Linq; using OpenRA.Graphics; using OpenRA.Mods.Common.Graphics; @@ -17,6 +18,44 @@ namespace OpenRA.Mods.Cnc.Graphics { + sealed class MaskedFrame : ISpriteFrame + { + readonly ISpriteFrame inner; + readonly ISpriteFrame mask; + byte[] data; + + public MaskedFrame(ISpriteFrame inner, ISpriteFrame mask) + { + this.inner = inner; + this.mask = mask; + } + + public SpriteFrameType Type => inner.Type; + public Size Size => inner.Size; + public Size FrameSize => inner.FrameSize; + public float2 Offset => inner.Offset; + public bool DisableExportPadding => inner.DisableExportPadding; + + public byte[] Data + { + get + { + if (data == null) + { + data = new byte[inner.Data.Length]; + + var channels = inner.Data.Length / mask.Data.Length; + for (var j = 0; j < mask.Data.Length; j++) + if (mask.Data[j] != 0) + for (var k = 0; k < channels; k++) + data[j * channels + k] = inner.Data[j * channels + k]; + } + + return data; + } + } + } + public class RemasterSpriteSequenceLoader : ClassicTilesetSpecificSpriteSequenceLoader { public readonly float ClassicUpscaleFactor = 5.333333f; @@ -67,8 +106,6 @@ public class RemasterSpriteSequence : ClassicTilesetSpecificSpriteSequence [Desc("Sprite data is already pre-multiplied by alpha channel.")] protected static readonly SpriteSequenceField RemasteredPremultiplied = new(nameof(RemasteredPremultiplied), true); - static readonly int[] FirstFrame = { 0 }; - bool hasRemasteredSprite = true; IEnumerable ParseRemasterFilenames(ModData modData, string tileset, int[] frames, MiniYaml data, MiniYaml defaults) @@ -175,8 +212,6 @@ public RemasterSpriteSequence(SpriteCache cache, ISpriteSequenceLoader loader, s length = null; } - int? remasteredMaskToken; - public override void ReserveSprites(ModData modData, string tileset, SpriteCache cache, MiniYaml data, MiniYaml defaults) { var frames = LoadField(Frames, data, defaults); @@ -189,13 +224,37 @@ public override void ReserveSprites(ModData modData, string tileset, SpriteCache var blendMode = LoadField(BlendMode, data, defaults); var premultiplied = LoadField(RemasteredPremultiplied, data, defaults); + ISpriteFrame[] maskFrames = null; + AdjustFrame adjustFrame = null; if (!string.IsNullOrEmpty(remasteredMaskFilename)) - remasteredMaskToken = cache.ReserveFrames(remasteredMaskFilename, null, remasteredMaskFilenameLocation); + adjustFrame = MaskFrame; + + ISpriteFrame MaskFrame(ISpriteFrame f, int index, int total) + { + if (maskFrames == null) + { + maskFrames = cache.LoadFramesUncached(remasteredMaskFilename); + if (maskFrames == null) + throw new FileNotFoundException($"{remasteredMaskFilenameLocation}: {remasteredMaskFilename} not found", remasteredMaskFilename); + + if (maskFrames.Length != total) + throw new YamlException($"Sequence {image}.{Name} with {total} frames cannot use mask with {maskFrames.Length} frames."); + } + + var m = maskFrames[index]; + if (f.Size != m.Size) + throw new YamlException($"Sequence {image}.{Name} frame {index} with size {f.Size} frames cannot use mask with size {m.Size}."); + + if (m.Type != SpriteFrameType.Indexed8) + throw new YamlException($"Sequence {image}.{Name} mask frame {index} must be an indexed image."); + + return new MaskedFrame(f, maskFrames[index]); + } var combineNode = data.Nodes.FirstOrDefault(n => n.Key == Combine.Key); if (combineNode != null) { - for (var i = 0; i < combineNode.Value.Nodes.Count; i++) + for (var i = 0; i < combineNode.Value.Nodes.Length; i++) { var subData = combineNode.Value.Nodes[i].Value; var subOffset = LoadField(Offset, subData, NoData); @@ -206,11 +265,7 @@ public override void ReserveSprites(ModData modData, string tileset, SpriteCache foreach (var f in ParseRemasterCombineFilenames(modData, tileset, subFrames, subData)) { - int token; - if (remasteredMaskToken != null) - token = cache.ReserveFrames(f.Filename, f.LoadFrames, f.Location); - else - token = cache.ReserveSprites(f.Filename, f.LoadFrames, f.Location, hasRemasteredSprite && premultiplied); + var token = cache.ReserveSprites(f.Filename, f.LoadFrames, f.Location, adjustFrame, hasRemasteredSprite && premultiplied); spritesToLoad.Add(new SpriteReservation { @@ -229,11 +284,7 @@ public override void ReserveSprites(ModData modData, string tileset, SpriteCache { foreach (var f in ParseRemasterFilenames(modData, tileset, frames, data, defaults)) { - int token; - if (remasteredMaskToken != null) - token = cache.ReserveFrames(f.Filename, f.LoadFrames, f.Location); - else - token = cache.ReserveSprites(f.Filename, f.LoadFrames, f.Location, hasRemasteredSprite && premultiplied); + var token = cache.ReserveSprites(f.Filename, f.LoadFrames, f.Location, adjustFrame, hasRemasteredSprite && premultiplied); spritesToLoad.Add(new SpriteReservation { @@ -249,136 +300,6 @@ public override void ReserveSprites(ModData modData, string tileset, SpriteCache } } - public override void ResolveSprites(SpriteCache cache) - { - if (bounds != null) - return; - - Sprite depthSprite = null; - if (depthSpriteReservation != null) - depthSprite = cache.ResolveSprites(depthSpriteReservation.Value).First(s => s != null); - - Sprite[] allSprites; - if (remasteredMaskToken != null) - { - var maskFrames = cache.ResolveFrames(remasteredMaskToken.Value); - var allFrames = spritesToLoad.SelectMany(r => - { - var resolved = cache.ResolveFrames(r.Token); - if (r.Frames != null) - return r.Frames.Select(f => (r, resolved[f])); - - return resolved.Select(f => (r, f)); - }).ToArray(); - - var frameLength = length ?? allFrames.Length - start; - if (maskFrames.Length != frameLength) - throw new YamlException($"Sequence {image}.{Name} with {frameLength} frames cannot use mask with {maskFrames.Length} frames."); - - allSprites = new Sprite[allFrames.Length]; - for (var i = 0; i < frameLength; i++) - { - (var r, var frame) = allFrames[start + i]; - var mask = maskFrames[i]; - if (frame.Size != mask.Size) - throw new YamlException($"Sequence {image}.{Name} frame {i} with size {frame.Size} frames cannot use mask with size {mask.Size}."); - - if (mask.Type != SpriteFrameType.Indexed8) - throw new YamlException($"Sequence {image}.{Name} mask frame {i} must be an indexed image."); - - var data = new byte[frame.Data.Length]; - var channels = frame.Data.Length / mask.Data.Length; - for (var j = 0; j < mask.Data.Length; j++) - if (mask.Data[j] != 0) - for (var k = 0; k < channels; k++) - data[j * channels + k] = frame.Data[j * channels + k]; - - var s = cache.SheetBuilders[SheetBuilder.FrameTypeToSheetType(frame.Type)] - .Add(data, frame.Type, frame.Size, 0, frame.Offset); - - var dx = r.Offset.X + (r.FlipX ? -s.Offset.X : s.Offset.X); - var dy = r.Offset.Y + (r.FlipY ? -s.Offset.Y : s.Offset.Y); - var dz = r.Offset.Z + s.Offset.Z + r.ZRamp * dy; - s = new Sprite(s.Sheet, FlipRectangle(s.Bounds, r.FlipX, r.FlipY), r.ZRamp, new float3(dx, dy, dz), s.Channel, r.BlendMode); - - if (depthSprite != null) - { - var cw = (depthSprite.Bounds.Left + depthSprite.Bounds.Right) / 2 + (int)(s.Offset.X + depthSpriteOffset.X); - var ch = (depthSprite.Bounds.Top + depthSprite.Bounds.Bottom) / 2 + (int)(s.Offset.Y + depthSpriteOffset.Y); - var w = s.Bounds.Width / 2; - var h = s.Bounds.Height / 2; - - s = new SpriteWithSecondaryData(s, depthSprite.Sheet, Rectangle.FromLTRB(cw - w, ch - h, cw + w, ch + h), depthSprite.Channel); - } - - allSprites[start + i] = s; - } - } - else - { - allSprites = spritesToLoad.SelectMany(r => - { - var resolved = cache.ResolveSprites(r.Token); - if (r.Frames != null) - resolved = r.Frames.Select(f => resolved[f]).ToArray(); - - return resolved.Select(s => - { - if (s == null) - return null; - - var dx = r.Offset.X + (r.FlipX ? -s.Offset.X : s.Offset.X); - var dy = r.Offset.Y + (r.FlipY ? -s.Offset.Y : s.Offset.Y); - var dz = r.Offset.Z + s.Offset.Z + r.ZRamp * dy; - var sprite = new Sprite(s.Sheet, FlipRectangle(s.Bounds, r.FlipX, r.FlipY), r.ZRamp, new float3(dx, dy, dz), s.Channel, r.BlendMode); - if (depthSprite == null) - return sprite; - - var cw = (depthSprite.Bounds.Left + depthSprite.Bounds.Right) / 2 + (int)(s.Offset.X + depthSpriteOffset.X); - var ch = (depthSprite.Bounds.Top + depthSprite.Bounds.Bottom) / 2 + (int)(s.Offset.Y + depthSpriteOffset.Y); - var w = s.Bounds.Width / 2; - var h = s.Bounds.Height / 2; - - return new SpriteWithSecondaryData(sprite, depthSprite.Sheet, Rectangle.FromLTRB(cw - w, ch - h, cw + w, ch + h), depthSprite.Channel); - }); - }).ToArray(); - } - - length ??= allSprites.Length - start; - - if (alpha != null) - { - if (alpha.Length == 1) - alpha = Exts.MakeArray(length.Value, _ => alpha[0]); - else if (alpha.Length != length.Value) - throw new YamlException($"Sequence {image}.{Name} must define either 1 or {length.Value} Alpha values."); - } - else if (alphaFade) - alpha = Exts.MakeArray(length.Value, i => float2.Lerp(1f, 0f, i / (length.Value - 1f))); - - // Reindex sprites to order facings anti-clockwise and remove unused frames - var index = CalculateFrameIndices(start, length.Value, stride ?? length.Value, facings, null, transpose, reverseFacings, -1); - if (reverses) - { - index.AddRange(index.Skip(1).Take(length.Value - 2).Reverse()); - length = 2 * length - 2; - } - - if (index.Count == 0) - throw new YamlException($"Sequence {image}.{Name} does not define any frames."); - - var minIndex = index.Min(); - var maxIndex = index.Max(); - if (minIndex < 0 || maxIndex >= allSprites.Length) - throw new YamlException($"Sequence {image}.{Name} uses frames between {minIndex}..{maxIndex}, but only 0..{allSprites.Length - 1} exist."); - - sprites = index.Select(f => allSprites[f]).ToArray(); - if (shadowStart >= 0) - shadowSprites = index.Select(f => allSprites[f - start + shadowStart]).ToArray(); - - bounds = sprites.Concat(shadowSprites ?? Enumerable.Empty()).Select(OffsetSpriteBounds).Union(); - } - protected override float GetScale() { if (!hasRemasteredSprite) diff --git a/OpenRA.Mods.Mobius/Terrain/RemasterTileCache.cs b/OpenRA.Mods.Mobius/Terrain/RemasterTileCache.cs index eca44ac..977cef0 100644 --- a/OpenRA.Mods.Mobius/Terrain/RemasterTileCache.cs +++ b/OpenRA.Mods.Mobius/Terrain/RemasterTileCache.cs @@ -37,7 +37,7 @@ public RemasterTileCache(RemasterTerrain terrainInfo) var templateInfo = (RemasterTerrainTemplateInfo)t.Value; var templateTokens = new Dictionary(); - if (templateInfo.RemasteredFilenames?.Any() ?? false) + if ((templateInfo.RemasteredFilenames?.Count ?? 0) > 0) { foreach (var kv in templateInfo.RemasteredFilenames) templateTokens[kv.Key] = kv.Value diff --git a/OpenRA.Mods.Mobius/Traits/Palettes/ColorPickerColorShift.cs b/OpenRA.Mods.Mobius/Traits/Palettes/ColorPickerColorShift.cs deleted file mode 100644 index e675dfc..0000000 --- a/OpenRA.Mods.Mobius/Traits/Palettes/ColorPickerColorShift.cs +++ /dev/null @@ -1,85 +0,0 @@ -#region Copyright & License Information -/* - * Copyright (c) The OpenRA Developers and Contributors - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. For more - * information, see COPYING. - */ -#endregion - -using OpenRA.Graphics; -using OpenRA.Mods.Common.Traits; -using OpenRA.Primitives; -using OpenRA.Traits; - -namespace OpenRA.Mods.Mobius.Traits -{ - [TraitLocation(SystemActors.World | SystemActors.EditorWorld)] - [Desc("Create a color picker palette from another palette.")] - sealed class ColorPickerColorShiftInfo : TraitInfo - { - [PaletteReference] - [FieldLoader.Require] - [Desc("The name of the palette to base off.")] - public readonly string BasePalette = null; - - [Desc("Hues between this and MaxHue will be shifted.")] - public readonly float MinHue = 0.29f; - - [Desc("Hues between MinHue and this will be shifted.")] - public readonly float MaxHue = 0.37f; - - [Desc("Hue reference for the color shift.")] - public readonly float ReferenceHue = 0.33f; - - [Desc("Saturation reference for the color shift.")] - public readonly float ReferenceSaturation = 0.925f; - - [Desc("Value reference for the color shift.")] - public readonly float ReferenceValue = 0.95f; - - public override object Create(ActorInitializer init) { return new ColorPickerColorShift(this); } - } - - sealed class ColorPickerColorShift : ILoadsPalettes, ITickRender - { - readonly ColorPickerColorShiftInfo info; - Color color; - Color preferredColor; - - public ColorPickerColorShift(ColorPickerColorShiftInfo info) - { - this.info = info; - - // All users need to use the same TraitInfo instance, chosen as the default mod rules - var colorManager = Game.ModData.DefaultRules.Actors[SystemActors.World].TraitInfo(); - colorManager.OnColorPickerColorUpdate += c => preferredColor = c; - preferredColor = Game.Settings.Player.Color; - } - - void ILoadsPalettes.LoadPalettes(WorldRenderer wr) - { - color = preferredColor; - var (r, g, b) = color.ToLinear(); - var (h, s, v) = Color.RgbToHsv(r, g, b); - wr.SetPaletteColorShift(info.BasePalette, - h - info.ReferenceHue, s - info.ReferenceSaturation, v / info.ReferenceValue, - info.MinHue, info.MaxHue); - } - - void ITickRender.TickRender(WorldRenderer wr, Actor self) - { - if (color == preferredColor) - return; - - color = preferredColor; - var (r, g, b) = color.ToLinear(); - var (h, s, v) = Color.RgbToHsv(r, g, b); - wr.SetPaletteColorShift(info.BasePalette, - h - info.ReferenceHue, s - info.ReferenceSaturation, v / info.ReferenceValue, - info.MinHue, info.MaxHue); - } - } -} diff --git a/OpenRA.Mods.Mobius/Traits/Palettes/FixedColorShift.cs b/OpenRA.Mods.Mobius/Traits/Palettes/FixedColorShift.cs deleted file mode 100644 index 2b35668..0000000 --- a/OpenRA.Mods.Mobius/Traits/Palettes/FixedColorShift.cs +++ /dev/null @@ -1,66 +0,0 @@ -#region Copyright & License Information -/* - * Copyright (c) The OpenRA Developers and Contributors - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. For more - * information, see COPYING. - */ -#endregion - -using OpenRA.Graphics; -using OpenRA.Primitives; -using OpenRA.Traits; - -namespace OpenRA.Mods.Mobius.Traits -{ - [TraitLocation(SystemActors.World | SystemActors.EditorWorld)] - [Desc("Apply a fixed color shift to a palette. Use this to add RGBA compatibility to FixedColorPalette.")] - public class FixedColorShiftInfo : TraitInfo - { - [PaletteReference] - [FieldLoader.Require] - [Desc("The name of the palette to base off.")] - public readonly string BasePalette = null; - - [Desc("The fixed color to remap.")] - public readonly Color Color; - - [Desc("Hues between this and MaxHue will be shifted.")] - public readonly float MinHue = 0.29f; - - [Desc("Hues between MinHue and this will be shifted.")] - public readonly float MaxHue = 0.37f; - - [Desc("Hue reference for the color shift.")] - public readonly float ReferenceHue = 0.33f; - - [Desc("Saturation reference for the color shift.")] - public readonly float ReferenceSaturation = 0.925f; - - [Desc("Value reference for the color shift.")] - public readonly float ReferenceValue = 0.95f; - - public override object Create(ActorInitializer init) { return new FixedColorShift(this); } - } - - public class FixedColorShift : ILoadsPalettes - { - readonly FixedColorShiftInfo info; - - public FixedColorShift(FixedColorShiftInfo info) - { - this.info = info; - } - - public void LoadPalettes(WorldRenderer wr) - { - var (r, g, b) = info.Color.ToLinear(); - var (h, s, v) = Color.RgbToHsv(r, g, b); - wr.SetPaletteColorShift(info.BasePalette, - h - info.ReferenceHue, s - info.ReferenceSaturation, v / info.ReferenceValue, - info.MinHue, info.MaxHue); - } - } -} diff --git a/OpenRA.Mods.Mobius/Traits/Palettes/FixedPlayerColorShift.cs b/OpenRA.Mods.Mobius/Traits/Palettes/FixedPlayerColorShift.cs deleted file mode 100644 index c375075..0000000 --- a/OpenRA.Mods.Mobius/Traits/Palettes/FixedPlayerColorShift.cs +++ /dev/null @@ -1,48 +0,0 @@ -#region Copyright & License Information -/* - * Copyright (c) The OpenRA Developers and Contributors - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. For more - * information, see COPYING. - */ -#endregion - -using System.Collections.Generic; -using OpenRA.Graphics; -using OpenRA.Primitives; -using OpenRA.Traits; - -namespace OpenRA.Mods.Mobius.Traits -{ - [TraitLocation(SystemActors.World | SystemActors.EditorWorld)] - [Desc("Add fixed color shifts to player palettes. Use to add RGBA compatibility to IndexedPlayerPalette.")] - public class FixedPlayerColorShiftInfo : TraitInfo - { - [PaletteReference(true)] - [FieldLoader.Require] - [Desc("The name of the palette to base off.")] - public readonly string BasePalette = null; - - public readonly Dictionary PlayerIndex; - - public override object Create(ActorInitializer init) { return new FixedPlayerColorShift(this); } - } - - public class FixedPlayerColorShift : ILoadsPlayerPalettes - { - readonly FixedPlayerColorShiftInfo info; - - public FixedPlayerColorShift(FixedPlayerColorShiftInfo info) - { - this.info = info; - } - - public void LoadPlayerPalettes(WorldRenderer wr, string playerName, Color color, bool replaceExisting) - { - if (info.PlayerIndex.TryGetValue(playerName, out var shift)) - wr.SetPaletteColorShift(info.BasePalette + playerName, shift[0], shift[1], shift[2], shift[3], shift[4]); - } - } -} diff --git a/OpenRA.Mods.Mobius/Traits/Palettes/PlayerColorShift.cs b/OpenRA.Mods.Mobius/Traits/Palettes/PlayerColorShift.cs deleted file mode 100644 index d73411b..0000000 --- a/OpenRA.Mods.Mobius/Traits/Palettes/PlayerColorShift.cs +++ /dev/null @@ -1,63 +0,0 @@ -#region Copyright & License Information -/* - * Copyright (c) The OpenRA Developers and Contributors - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. For more - * information, see COPYING. - */ -#endregion - -using OpenRA.Graphics; -using OpenRA.Primitives; -using OpenRA.Traits; - -namespace OpenRA.Mods.Mobius.Traits -{ - [TraitLocation(SystemActors.World | SystemActors.EditorWorld)] - [Desc("Add color shifts to player palettes. Use to add RGBA compatibility to PlayerColorPalette.")] - public class PlayerColorShiftInfo : TraitInfo - { - [PaletteReference(true)] - [FieldLoader.Require] - [Desc("The name of the palette to base off.")] - public readonly string BasePalette = null; - - [Desc("Hues between this and MaxHue will be shifted.")] - public readonly float MinHue = 0.29f; - - [Desc("Hues between MinHue and this will be shifted.")] - public readonly float MaxHue = 0.37f; - - [Desc("Hue reference for the color shift.")] - public readonly float ReferenceHue = 0.33f; - - [Desc("Saturation reference for the color shift.")] - public readonly float ReferenceSaturation = 0.925f; - - [Desc("Value reference for the color shift.")] - public readonly float ReferenceValue = 0.95f; - - public override object Create(ActorInitializer init) { return new PlayerColorShift(this); } - } - - public class PlayerColorShift : ILoadsPlayerPalettes - { - readonly PlayerColorShiftInfo info; - - public PlayerColorShift(PlayerColorShiftInfo info) - { - this.info = info; - } - - public void LoadPlayerPalettes(WorldRenderer wr, string playerName, Color color, bool replaceExisting) - { - var (r, g, b) = color.ToLinear(); - var (h, s, v) = Color.RgbToHsv(r, g, b); - wr.SetPaletteColorShift(info.BasePalette + playerName, - h - info.ReferenceHue, s - info.ReferenceSaturation, v / info.ReferenceValue, - info.MinHue, info.MaxHue); - } - } -} diff --git a/OpenRA.Mods.Mobius/UtilityCommands/RemasterCheckMissingSprites.cs b/OpenRA.Mods.Mobius/UtilityCommands/RemasterCheckMissingSprites.cs deleted file mode 100644 index 397d9b8..0000000 --- a/OpenRA.Mods.Mobius/UtilityCommands/RemasterCheckMissingSprites.cs +++ /dev/null @@ -1,91 +0,0 @@ -#region Copyright & License Information -/* - * Copyright (c) The OpenRA Developers and Contributors - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. For more - * information, see COPYING. - */ -#endregion - -using System; -using OpenRA.Graphics; -using OpenRA.Mods.Common.Terrain; -using OpenRA.Mods.Common.Traits; - -namespace OpenRA.Mods.Mobius.UtilityCommands -{ - sealed class RemasterCheckMissingSprites : IUtilityCommand - { - string IUtilityCommand.Name => "--remaster-check-missing-sprites"; - - bool IUtilityCommand.ValidateArguments(string[] args) - { - return true; - } - - [Desc("Check tileset and sequence definitions for missing sprite files.")] - void IUtilityCommand.Run(Utility utility, string[] args) - { - // HACK: The engine code assumes that Game.modData is set. - var modData = Game.ModData = utility.ModData; - var failed = false; - - var remasterContent = modData.Manifest.Get(); - if (!remasterContent.TryMountPackages(modData)) - { - Console.WriteLine("Failed to mount remaster content"); - Environment.Exit(1); - } - - // We need two levels of YamlException handling to provide the desired behaviour: - // Parse errors within a single tileset should skip that tileset and allow the rest to be tested - // however, certain errors will be thrown by the outer modData.DefaultSequences, which prevent - // any tilesets from being checked further. - try - { - foreach (var kv in modData.DefaultTerrainInfo) - { - try - { - Console.WriteLine("Tileset: " + kv.Key); - if (kv.Value is ITemplatedTerrainInfo templatedTerrainInfo) - foreach (var r in modData.DefaultRules.Actors[SystemActors.World].TraitInfos()) - failed |= r.ValidateTileSprites(templatedTerrainInfo, Console.WriteLine); - - var sequences = new SequenceSet(modData.DefaultFileSystem, modData, kv.Key, null); - sequences.SpriteCache.LoadReservations(modData); - foreach ((var filename, var location) in sequences.SpriteCache.MissingFiles) - { - Console.WriteLine($"\t{location}: {filename} not found"); - failed = true; - } - } - catch (YamlException e) - { - // The stacktrace associated with yaml errors are not very useful - // Suppress them to make the lint output less intimidating for modders - Console.WriteLine($"\t{e.Message}"); - failed = true; - } - catch (Exception e) - { - Console.WriteLine($"Failed with exception: {e}"); - failed = true; - } - } - } - catch (YamlException e) - { - // The stacktrace associated with yaml errors are not very useful - // Suppress them to make the lint output less intimidating for modders - Console.WriteLine($"{e.Message}"); - failed = true; - } - - if (failed) - Environment.Exit(1); - } - } -} diff --git a/OpenRA.Mods.Mobius/UtilityCommands/RemasterDumpSequenceSheetsCommand.cs b/OpenRA.Mods.Mobius/UtilityCommands/RemasterDumpSequenceSheetsCommand.cs deleted file mode 100644 index ece2b52..0000000 --- a/OpenRA.Mods.Mobius/UtilityCommands/RemasterDumpSequenceSheetsCommand.cs +++ /dev/null @@ -1,77 +0,0 @@ -#region Copyright & License Information -/* - * Copyright (c) The OpenRA Developers and Contributors - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. For more - * information, see COPYING. - */ -#endregion - -using System; -using OpenRA.FileSystem; -using OpenRA.Graphics; - -namespace OpenRA.Mods.Mobius.UtilityCommands -{ - sealed class DumpSequenceSheetsCommand : IUtilityCommand - { - static readonly int[] ChannelMasks = { 2, 1, 0, 3 }; - - string IUtilityCommand.Name => "--remaster-dump-sequence-sheets"; - - bool IUtilityCommand.ValidateArguments(string[] args) - { - return args.Length >= 3; - } - - [Desc("PALETTE", "TILESET-OR-MAP", "Exports sequence texture atlas as a set of png images.")] - void IUtilityCommand.Run(Utility utility, string[] args) - { - // HACK: The engine code assumes that Game.modData is set. - var modData = Game.ModData = utility.ModData; - - var palette = new ImmutablePalette(args[1], new[] { 0 }, Array.Empty()); - - var remasterContent = modData.Manifest.Get(); - if (!remasterContent.TryMountPackages(modData)) - { - Console.WriteLine("Failed to mount remaster content"); - Environment.Exit(1); - } - - SequenceSet sequences; - if (!modData.DefaultTerrainInfo.ContainsKey(args[2])) - { - var mapPackage = new Folder(Platform.EngineDir).OpenPackage(args[2], modData.ModFiles); - if (mapPackage == null) - throw new InvalidOperationException($"{args[2]} is not a valid tileset or map path"); - - sequences = new Map(modData, mapPackage).Sequences; - } - else - sequences = new SequenceSet(modData.ModFiles, modData, args[2], null); - - sequences.LoadSprites(); - - var count = 0; - - var sb = sequences.SpriteCache.SheetBuilders[SheetType.Indexed]; - foreach (var s in sb.AllSheets) - { - var max = s == sb.Current ? (int)sb.CurrentChannel + 1 : 4; - for (var i = 0; i < max; i++) - s.AsPng((TextureChannel)ChannelMasks[i], palette).Save($"{count}.{i}.png"); - - count++; - } - - sb = sequences.SpriteCache.SheetBuilders[SheetType.BGRA]; - foreach (var s in sb.AllSheets) - s.AsPng().Save($"{count++}.png"); - - Console.WriteLine("Saved [0..{0}].png", count - 1); - } - } -} diff --git a/OpenRA.Mods.Mobius/UtilityCommands/RemasterDumpTilesetSheetsCommand.cs b/OpenRA.Mods.Mobius/UtilityCommands/RemasterDumpTilesetSheetsCommand.cs deleted file mode 100644 index e0d5193..0000000 --- a/OpenRA.Mods.Mobius/UtilityCommands/RemasterDumpTilesetSheetsCommand.cs +++ /dev/null @@ -1,67 +0,0 @@ -#region Copyright & License Information -/* - * Copyright (c) The OpenRA Developers and Contributors - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. For more - * information, see COPYING. - */ -#endregion - -using System; -using OpenRA.Graphics; -using OpenRA.Mods.Mobius.Terrain; - -namespace OpenRA.Mods.Mobius.UtilityCommands -{ - sealed class DumpTilesetSheetsCommand : IUtilityCommand - { - static readonly int[] ChannelMasks = { 2, 1, 0, 3 }; - - string IUtilityCommand.Name => "--remaster-dump-tileset-sheets"; - - bool IUtilityCommand.ValidateArguments(string[] args) - { - return args.Length >= 3; - } - - [Desc("PALETTE", "TILESET-OR-MAP", "Exports tileset texture atlas as a set of png images.")] - void IUtilityCommand.Run(Utility utility, string[] args) - { - // HACK: The engine code assumes that Game.modData is set. - var modData = Game.ModData = utility.ModData; - - var palette = new ImmutablePalette(args[1], new[] { 0 }, Array.Empty()); - - var remasterContent = modData.Manifest.Get(); - if (!remasterContent.TryMountPackages(modData)) - { - Console.WriteLine("Failed to mount remaster content"); - Environment.Exit(1); - } - - if (!modData.DefaultTerrainInfo.TryGetValue(args[2], out var terrainInfo)) - throw new InvalidOperationException($"{args[2]} is not a valid tileset"); - - var tileCache = new RemasterTileCache(terrainInfo as RemasterTerrain); - var count = 0; - - var sb = tileCache.SpriteCache.SheetBuilders[SheetType.Indexed]; - foreach (var s in sb.AllSheets) - { - var max = s == sb.Current ? (int)sb.CurrentChannel + 1 : 4; - for (var i = 0; i < max; i++) - s.AsPng((TextureChannel)ChannelMasks[i], palette).Save($"{count}.{i}.png"); - - count++; - } - - sb = tileCache.SpriteCache.SheetBuilders[SheetType.BGRA]; - foreach (var s in sb.AllSheets) - s.AsPng().Save($"{count++}.png"); - - Console.WriteLine("Saved [0..{0}].png", count - 1); - } - } -} diff --git a/OpenRA.Mods.Mobius/UtilityCommands/RemasterTilesetConverter.cs b/OpenRA.Mods.Mobius/UtilityCommands/RemasterTilesetConverter.cs index ad16762..71a6521 100644 --- a/OpenRA.Mods.Mobius/UtilityCommands/RemasterTilesetConverter.cs +++ b/OpenRA.Mods.Mobius/UtilityCommands/RemasterTilesetConverter.cs @@ -35,7 +35,7 @@ void IUtilityCommand.Run(Utility utility, string[] args) Game.ModData = utility.ModData; var tileset = MiniYaml.FromFile(args[1], discardCommentsAndWhitespace: false); - var templates = tileset.First(n => n.Key == "Templates"); + var templates = new MiniYamlBuilder(tileset.First(n => n.Key == "Templates").Value); var mapping = new XmlDocument(); using (var ffs = new FileStream(args[2], FileMode.Open)) @@ -47,7 +47,7 @@ void IUtilityCommand.Run(Utility utility, string[] args) } var rootTexturePath = mapping.SelectSingleNode("//RootTexturePath").InnerText.ToUpperInvariant(); - foreach (var template in templates.Value.Nodes) + foreach (var template in templates.Nodes) { var legacy = template.LastChildMatching("Images").Value.Value; var code = Path.GetFileNameWithoutExtension(legacy).ToUpperInvariant(); @@ -62,7 +62,7 @@ void IUtilityCommand.Run(Utility utility, string[] args) template.RemoveNodes("Frames"); template.RenameChildrenMatching("Images", "Filename"); - var imageNode = new MiniYamlNode("RemasteredFilenames", ""); + var imageNode = new MiniYamlNodeBuilder("RemasteredFilenames", ""); foreach (var t in tileNodes) { var tileNode = (XmlNode)t; @@ -77,7 +77,7 @@ void IUtilityCommand.Run(Utility utility, string[] args) imageNode.AddNode(index, FieldSaver.FormatValue(frames)); } - if (imageNode.Value.Nodes.Any()) + if (imageNode.Value.Nodes.Count > 0) template.AddNode(imageNode); } diff --git a/mod.config b/mod.config index 3213162..982fdd8 100644 --- a/mod.config +++ b/mod.config @@ -9,7 +9,7 @@ MOD_ID="cnc" # The OpenRA engine version to use for this project. -ENGINE_VERSION="ea55ca256d60f210e409055fc7b3a4c717023125" +ENGINE_VERSION="4f880f6269" ############################################################################## # Packaging @@ -85,7 +85,7 @@ PACKAGING_WINDOWS_LICENSE_FILE="./COPYING" # Space delimited list of additional files/directories to copy from the engine directory # when packaging your mod. e.g. "./mods/modcontent" -PACKAGING_COPY_ENGINE_FILES="./mods/modcontent ./mods/cnc" +PACKAGING_COPY_ENGINE_FILES="./mods/common-content ./mods/cnc" # Overwrite the version in mod.yaml with the tag used for the SDK release # Accepts values "True" or "False". diff --git a/mods/cnc/audio/notifications.yaml b/mods/cnc/audio/notifications.yaml index 82e70fe..fd219b0 100644 --- a/mods/cnc/audio/notifications.yaml +++ b/mods/cnc/audio/notifications.yaml @@ -67,6 +67,10 @@ Sounds: InterruptType: Overlap ChatLine: scold1 InterruptType: Interrupt + LobbyOptionChanged: beepy3 + InterruptType: Interrupt + PlayerLeft: country1 + InterruptType: Interrupt ClickDisabledSound: scold2 InterruptType: Interrupt ClickSound: button diff --git a/mods/cnc/chrome/mainmenu-prerelease-notification.yaml b/mods/cnc/chrome/mainmenu-prerelease-notification.yaml deleted file mode 100644 index 3ec5179..0000000 --- a/mods/cnc/chrome/mainmenu-prerelease-notification.yaml +++ /dev/null @@ -1,96 +0,0 @@ -Container@MAINMENU_PRERELEASE_NOTIFICATION: - Width: WINDOW_RIGHT - Height: WINDOW_BOTTOM - Logic: PreReleaseWarningPrompt - Children: - LogicKeyListener@GLOBAL_KEYHANDLER: - Logic: MusicHotkeyLogic, ScreenshotHotkeyLogic, MuteHotkeyLogic - StopMusicKey: StopMusic - PauseMusicKey: PauseMusic - PrevMusicKey: PrevMusic - NextMusicKey: NextMusic - TakeScreenshotKey: TakeScreenshot - MuteAudioKey: ToggleMute - Container@SHELLMAP_DECORATIONS: - Children: - Image@NOD: - X: WINDOW_RIGHT / 2 - 384 - Y: (WINDOW_BOTTOM - 256) / 2 - ImageCollection: logos - ImageName: nod-load - Image@GDI: - X: WINDOW_RIGHT / 2 + 128 - Y: (WINDOW_BOTTOM - 256) / 2 - ImageCollection: logos - ImageName: gdi-load - Image@EVA: - X: WINDOW_RIGHT - 128 - 43 - Y: 43 - Width: 128 - Height: 64 - ImageCollection: logos - ImageName: eva - Label@VERSION_LABEL: - X: WINDOW_RIGHT - 128 - 43 - Y: 116 - Width: 128 - Align: Center - Shadow: true - Background@BORDER: - Width: WINDOW_RIGHT - Height: WINDOW_BOTTOM - Background: shellmapborder - Container@dialog: - X: (WINDOW_RIGHT - WIDTH) / 2 - Y: (WINDOW_BOTTOM - HEIGHT) / 2 - Width: 550 - Height: 120 - Children: - Label@TITLE: - Width: PARENT_RIGHT - Y: 0 - 25 - Font: BigBold - Contrast: true - Align: Center - Text: Tiberian Dawn: Remastered preview - Background@bg: - Width: PARENT_RIGHT - Height: PARENT_BOTTOM - Background: panel-black - Children: - Label@PROMPT_TEXT_A: - X: 15 - Y: 15 - Width: PARENT_RIGHT - 30 - Height: 16 - Align: Center - Text: This pre-release build is made available as a proof of concept demonstrating - Label@PROMPT_TEXT_B: - X: 15 - Y: 15 + 18 - Width: PARENT_RIGHT - 30 - Height: 16 - Align: Center - Text: the capabilities of OpenRA using the C&C Remastered Collection assets. - Label@PROMPT_TEXT_C: - X: 15 - Y: 15 + 3 * 18 - Width: PARENT_RIGHT - 30 - Height: 16 - Align: Center - Text: Performance, memory usage, and loading times have not been optimized, and do - Label@PROMPT_TEXT_D: - X: 15 - Y: 15 + 4 * 18 - Width: PARENT_RIGHT - 30 - Height: 16 - Align: Center - Text: not reflect the expected final requirements. A dedicated GPU is recommended. - Button@CONTINUE_BUTTON: - X: PARENT_RIGHT - WIDTH - Y: PARENT_BOTTOM - 1 - Width: 140 - Height: 35 - Text: I Understand - Font: Bold - Key: return diff --git a/mods/cnc/chrome/mainmenu.yaml b/mods/cnc/chrome/mainmenu.yaml deleted file mode 100644 index 3294ddd..0000000 --- a/mods/cnc/chrome/mainmenu.yaml +++ /dev/null @@ -1,272 +0,0 @@ -Container@MENU_BACKGROUND: - Width: WINDOW_RIGHT - Height: WINDOW_BOTTOM - Logic: MainMenuLogic - Children: - LogicKeyListener@GLOBAL_KEYHANDLER: - Logic: MusicHotkeyLogic, ScreenshotHotkeyLogic, MuteHotkeyLogic - StopMusicKey: StopMusic - PauseMusicKey: PauseMusic - PrevMusicKey: PrevMusic - NextMusicKey: NextMusic - TakeScreenshotKey: TakeScreenshot - MuteAudioKey: ToggleMute - Container@SHELLMAP_DECORATIONS: - Children: - Image@NOD: - X: WINDOW_RIGHT / 2 - 384 - Y: (WINDOW_BOTTOM - 256) / 2 - ImageCollection: logos - ImageName: nod-load - Image@GDI: - X: WINDOW_RIGHT / 2 + 128 - Y: (WINDOW_BOTTOM - 256) / 2 - ImageCollection: logos - ImageName: gdi-load - Image@EVA: - X: WINDOW_RIGHT - 128 - 43 - Y: 43 - Width: 128 - Height: 64 - ImageCollection: logos - ImageName: eva - Label@VERSION_LABEL: - X: WINDOW_RIGHT - 128 - 43 - Y: 116 - Width: 128 - Align: Center - Shadow: true - Background@BORDER: - Width: WINDOW_RIGHT - Height: WINDOW_BOTTOM - Background: shellmapborder - Container@MENUS: - X: (WINDOW_RIGHT - WIDTH) / 2 - Y: WINDOW_BOTTOM - 33 - HEIGHT - 10 - Width: 890 - Height: 35 - Children: - Container@MAIN_MENU: - Width: PARENT_RIGHT - Children: - Label@MAINMENU_LABEL_TITLE: - X: 0 - Y: 0 - 28 - Width: PARENT_RIGHT - Height: 20 - Text: Main Menu - Align: Center - Font: Bold - Contrast: True - Button@SINGLEPLAYER_BUTTON: - X: 0 - Y: 0 - Width: 140 - Height: 35 - Text: Singleplayer - Button@MULTIPLAYER_BUTTON: - X: 150 - Y: 0 - Width: 140 - Height: 35 - Text: Multiplayer - Button@SETTINGS_BUTTON: - X: 300 - Y: 0 - Width: 140 - Height: 35 - Text: Settings - Button@EXTRAS_BUTTON: - X: 450 - Y: 0 - Width: 140 - Height: 35 - Text: Extras - Button@CONTENT_BUTTON: - X: 600 - Y: 0 - Width: 140 - Height: 35 - Text: Manage Content - Disabled: true - Button@QUIT_BUTTON: - X: 750 - Y: 0 - Width: 140 - Height: 35 - Text: Quit - Container@SINGLEPLAYER_MENU: - Width: PARENT_RIGHT - Visible: False - Children: - Label@SINGLEPLAYER_MENU_TITLE: - X: 0 - Y: 0 - 28 - Width: PARENT_RIGHT - Height: 20 - Text: Singleplayer - Align: Center - Font: Bold - Contrast: True - Button@SKIRMISH_BUTTON: - X: 0 - Y: 0 - Width: 140 - Height: 35 - Text: Skirmish - Button@MISSIONS_BUTTON: - X: 150 - Y: 0 - Width: 140 - Height: 35 - Text: Missions - Button@LOAD_BUTTON: - X: 300 - Y: 0 - Width: 140 - Height: 35 - Text: Load - Button@BACK_BUTTON: - Key: escape - X: 450 - Y: 0 - Width: 140 - Height: 35 - Text: Back - Container@EXTRAS_MENU: - Width: PARENT_RIGHT - Visible: False - Children: - Label@EXTRAS_MENU_TITLE: - X: 0 - Y: 0 - 28 - Width: PARENT_RIGHT - Height: 20 - Text: Extras - Align: Center - Font: Bold - Contrast: True - Button@REPLAYS_BUTTON: - X: 0 - Y: 0 - Width: 140 - Height: 35 - Text: Replays - Button@MUSIC_BUTTON: - X: 150 - Y: 0 - Width: 140 - Height: 35 - Text: Music - Button@MAP_EDITOR_BUTTON: - X: 300 - Y: 0 - Width: 140 - Height: 35 - Text: Map Editor - Font: Bold - Button@ASSETBROWSER_BUTTON: - X: 450 - Y: 0 - Width: 140 - Height: 35 - Text: Asset Browser - Button@CREDITS_BUTTON: - X: 600 - Y: 0 - Width: 140 - Height: 35 - Text: Credits - Button@BACK_BUTTON: - Key: escape - X: 750 - Y: 0 - Width: 140 - Height: 35 - Text: Back - Container@MAP_EDITOR_MENU: - Width: PARENT_RIGHT - Visible: False - Children: - Label@MAP_EDITOR_MENU_TITLE: - X: 0 - Y: 0 - 28 - Width: PARENT_RIGHT - Height: 20 - Text: Map Editor - Align: Center - Font: Bold - Contrast: True - Button@NEW_MAP_BUTTON: - X: 0 - Y: 0 - Width: 140 - Height: 35 - Text: New Map - Font: Bold - Button@LOAD_MAP_BUTTON: - X: 150 - Y: 0 - Width: 140 - Height: 35 - Text: Load Map - Font: Bold - Button@BACK_BUTTON: - X: 300 - Y: 0 - Width: 140 - Height: 35 - Text: Back - Font: Bold - Key: escape - Container@NEWS_BG: - Children: - DropDownButton@NEWS_BUTTON: - X: (WINDOW_RIGHT - WIDTH) / 2 - Y: 50 - Width: 400 - Height: 25 - Text: Battlefield News - Font: Bold - Container@UPDATE_NOTICE: - X: (WINDOW_RIGHT - WIDTH) / 2 - Y: 75 - Width: 128 - Children: - Label@A: - Width: PARENT_RIGHT - Height: 25 - Align: Center - Shadow: true - Text: You are running an outdated version of OpenRA. - Label@B: - Y: 20 - Width: PARENT_RIGHT - Height: 25 - Align: Center - Shadow: true - Text: Download the latest version from www.openra.net - Container@PERFORMANCE_INFO: - Logic: PerfDebugLogic - Children: - Label@PERF_TEXT: - X: WINDOW_RIGHT - WIDTH - 25 - Y: WINDOW_BOTTOM - HEIGHT - 100 - Width: 170 - Contrast: true - VAlign: Top - Background@GRAPH_BG: - X: WINDOW_RIGHT - WIDTH - 31 - Y: 31 - Width: 220 - Height: 220 - Background: panel-black - Children: - PerfGraph@GRAPH: - X: 10 - Y: 10 - Width: 200 - Height: 200 - Container@PLAYER_PROFILE_CONTAINER: - X: 31 - Y: 31 diff --git a/mods/cnc/chrome/overrides.yaml b/mods/cnc/chrome/overrides.yaml deleted file mode 100644 index 36d37ec..0000000 --- a/mods/cnc/chrome/overrides.yaml +++ /dev/null @@ -1,4 +0,0 @@ -Background@COLOR_CHOOSER: - Children: - ActorPreview@PREVIEW: - Scale: 0.3333 diff --git a/mods/cnc/fluent/campaign.ftl b/mods/cnc/fluent/campaign.ftl new file mode 100644 index 0000000..ef59a23 --- /dev/null +++ b/mods/cnc/fluent/campaign.ftl @@ -0,0 +1,32 @@ +## world +dropdown-difficulty = + .label = Difficulty + .description = The difficulty of the mission. + +options-difficulty = + .easy = Easy + .normal = Normal + .hard = Hard + +## player +bot-campaign-ai = + .name = Campaign Player AI + +## campaign-maprules.yaml +actor-moneycrate-name = Money Crate + +## gdi03, gdi07, gdi08a, gdi08b, gdi09, nod03a, nod03b +actor-hq-description = Provides an overview of the battlefield. + Requires power to operate. + +## gdi08a +actor-c3-name = Farmer Mike + +## gdi08b +civilian-killed = Civilian killed. + +## nod01 +actor-c10-name = Nikoomba + +## nod03a, nod03b +actor-prison-name = Prison diff --git a/mods/cnc/languages/lua/en.ftl b/mods/cnc/fluent/lua.ftl similarity index 76% rename from mods/cnc/languages/lua/en.ftl rename to mods/cnc/fluent/lua.ftl index 4d02df4..c997475 100644 --- a/mods/cnc/languages/lua/en.ftl +++ b/mods/cnc/fluent/lua.ftl @@ -1,12 +1,12 @@ ## campaign -objective-failed = Objective failed -objective-completed = Objective completed +objective-failed = Objective Failed +objective-completed = Objective Completed primary = Primary secondary = Secondary -new-primary-objective = New primary objective -new-secondary-objective = New secondary objective +new-primary-objective = New Primary Objective +new-secondary-objective = New Secondary Objective # cnc64gdi01 destroy-obelisk-sams = Destroy the SAM sites protecting the Obelisk. @@ -59,7 +59,7 @@ destroy-nod-force = Destroy the Nod strike force. ## gdi08b protect-mobius = Protect Dr. Mobius. protect-hospital = Protect the Hospital. -keep-civilians-alive = Keep at least { $civilians } out of 14 Civilians alive. +keep-civilians-alive = Keep at least { $civilians } out of 14 civilians alive. destroy-nod-bases = Destroy the Nod bases. ## gdi09 @@ -105,8 +105,8 @@ destroy-gdi-supporter-houses = Destroy the houses of the GDI supporters in the village. ## nod06c -infiltrate-barracks-factory-conyard = Infiltrate the barracks, weapon factory and - the construction yard. +infiltrate-barracks-factory-conyard = Infiltrate the barracks, weapons factory and + construction yard. ## nod07a find-nod-base = Find the Nod base. @@ -116,9 +116,9 @@ eliminate-gdi-forces = Eliminate all GDI forces in the area. ## nod07c capture-gdi-helipad = Capture the GDI helipad. -dont-capture-or-destroy = Don't capture or destroy any other +do-not-capture-or-destroy = Do not capture or destroy any other GDI main building. -orca-wreak-havoc = Use the GDI orca to wreak havoc at the village. +orca-wreak-havoc = Use the GDI Orca to wreak havoc in the village. distract-guards = Distract the guards by attacking the main entrance with your vehicles. @@ -134,29 +134,24 @@ secure-second-landing-zone = Secure the second landing zone. ## nod10a kill-gdi-scientist = Kill the GDI scientist. -destroy-tech-center = Destroy the GDI R&D center. +destroy-tech-center = Destroy the GDI Research Base. ## nod10b destroy-capture-warfactory = Destroy or capture the Weapons Factory. -destroy-mammoth-tanks = Destroy the Mammoth tanks in the R&D base. +destroy-mammoth-tanks = Destroy the Mammoth tanks in the Research Base. keep-commando-alive = Keep your Commando alive. ## eviction-notice -take-civilians-money-crates = Find all the civilians' money. - They won't need it anymore. -quickly-destroy-ion-cannon = Disable GDI Ion Cannon before - it fires two times. +take-civilians-money-crates = Find all the civilians' money; they won't be needing it anymore. +quickly-destroy-ion-cannon = Disable the GDI Ion Cannon before it fires twice. nod-soldier = Nod Soldier -civilians-runs = Hey, those civilians... where are they going? -destroy-ion-cannon-advise = The GDI are preparing their ion cannon. Don't let them get used to it. -village-destruction-warning = Be careful, commander. The GDI won't stand still while we burn the entire village. +civilians-running = Hey, those civilians... where are they going? +destroy-ion-cannon-advice = The GDI are preparing their Ion Cannon. Don't let them get comfortable using it. +village-destruction-warning = Be careful, commander. The GDI won't stay idle while we burn the entire village. ## twist-of-fate -clear-path = Repel the ambush and clear the way - for our MCV. -recover-old-base = Capture the Construction Yard in our recon - post to regain control. -air-strikes-intel-report = Nod airstrikes are being directed by a Communications Center, located northwest. We may gain useful information from its capture. -capture-nod-communications-center = Capture the Nod Communications Center to - the northwest. +clear-path = Repel the ambush and clear the way for our MCV. +recover-old-base = Capture the Construction Yard at our recon post to regain control. +air-strikes-intel-report = Nod airstrikes are being directed by a Communications Center to the northwest. We may gain useful information from its capture. +capture-nod-communications-center = Capture the Nod Communications Center to the northwest. communications-center-captured-sams-located = Our engineers located Nod SAM sites. They also disarmed an unusual trap on the Construction Yard to the south. diff --git a/mods/cnc/languages/difficulties/en.ftl b/mods/cnc/languages/difficulties/en.ftl deleted file mode 100644 index 90ad411..0000000 --- a/mods/cnc/languages/difficulties/en.ftl +++ /dev/null @@ -1,7 +0,0 @@ -dropdown-difficulty = - .label = Difficulty - .description = The difficulty of the mission - -options-difficulty = - .easy = Easy - .hard = Hard diff --git a/mods/cnc/mod.yaml b/mods/cnc/mod.yaml index b291c82..6edee3b 100644 --- a/mods/cnc/mod.yaml +++ b/mods/cnc/mod.yaml @@ -1,21 +1,20 @@ Metadata: - Title: Tiberian Dawn HD + 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, MegV3, ZipFile -Packages: - ^EngineDir - $cnc: cnc - ^EngineDir|mods/cnc: base - ^EngineDir|mods/common: common - base|scripts - common|scripts - -RemasterModContent: +FileSystem: RemasterFileSystem + Packages: + ^EngineDir + $cnc: cnc + ^EngineDir|mods/cnc: base + ^EngineDir|mods/common: common + base|scripts + common|scripts RemasterDataMount: data Sources: steam: @@ -26,7 +25,7 @@ RemasterModContent: RegistryPrefixes: HKEY_LOCAL_MACHINE\Software\, HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\ RegistryKey: Petroglyph\CnCRemastered RegistryValue: Install Dir - Packages: + RemasterPackages: data|CNCDATA/TIBERIAN_DAWN/CD1/CONQUER.MIX data|CNCDATA/TIBERIAN_DAWN/CD1/SOUNDS.MIX data|CNCDATA/TIBERIAN_DAWN/CD1/TEMPICNH.MIX @@ -115,16 +114,13 @@ Cursors: Chrome: base|chrome.yaml -Assemblies: - ^BinDir|OpenRA.Mods.Common.dll - ^BinDir|OpenRA.Mods.Cnc.dll - ^BinDir|OpenRA.Mods.Mobius.dll +Assemblies: OpenRA.Mods.Common.dll, OpenRA.Mods.Cnc.dll, OpenRA.Mods.Mobius.dll ChromeLayout: - cnc|chrome/mainmenu.yaml - cnc|chrome/mainmenu-prerelease-notification.yaml + base|chrome/mainmenu.yaml base|chrome/mainmenu-prompts.yaml base|chrome/playerprofile.yaml + base|chrome/encyclopedia.yaml base|chrome/multiplayer-browser.yaml base|chrome/multiplayer-browserpanels.yaml base|chrome/multiplayer-createserver.yaml @@ -171,10 +167,16 @@ ChromeLayout: base|chrome/editor.yaml common|chrome/text-notifications.yaml -Translations: - common|languages/en.ftl - common|languages/rules/en.ftl - base|languages/rules/en.ftl +FluentMessages: + common|fluent/common.ftl + common|fluent/hotkeys.ftl + common|fluent/rules.ftl + base|fluent/cnc.ftl + base|fluent/chrome.ftl + base|fluent/hotkeys.ftl + base|fluent/rules.ftl + +AllowUnusedFluentMessagesInExternalPackages: false Voices: cnc|audio/voices.yaml @@ -189,7 +191,6 @@ Hotkeys: common|hotkeys/game.yaml common|hotkeys/observer.yaml common|hotkeys/production-common.yaml - common|hotkeys/production-peractor.yaml common|hotkeys/supportpowers.yaml common|hotkeys/viewport.yaml common|hotkeys/chat.yaml @@ -197,14 +198,14 @@ Hotkeys: common|hotkeys/control-groups.yaml base|hotkeys.yaml -LoadScreen: RemasterLoadScreen +LoadScreen: CncLoadScreen Image: base|uibits/chrome.png Image2x: base|uibits/chrome-2x.png Image3x: base|uibits/chrome-3x.png - Text: Loading ServerTraits: LobbyCommands + SkirmishLogic PlayerPinger MasterServerPinger LobbySettingsNotification @@ -266,7 +267,7 @@ SoundFormats: Aud, Wav SpriteFormats: Tga, ShpTD, TmpTD, ShpTS, TmpRA, ShpRemastered, Dds, PngSheet -VideoFormats: Vqa +VideoFormats: Vqa, Wsa TerrainFormat: RemasterTerrain @@ -274,8 +275,6 @@ SpriteSequenceFormat: RemasterSpriteSequence BgraSheetSize: 8192 IndexedSheetSize: 512 -ModelSequenceFormat: PlaceholderModelSequence - AssetBrowser: SpriteExtensions: .shp, .tem, .win, .sno, .des, .jun, .ZIP, .DDS, .TGA AudioExtensions: .aud, .wav, .v00, .v01, .v02, .v03, .var @@ -309,7 +308,5 @@ GameSpeeds: Timestep: 20 OrderLatency: 6 -ModContent: - DiscordService: ApplicationId: 699223250181292033 diff --git a/mods/cnc/rules/campaign-maprules.yaml b/mods/cnc/rules/campaign-maprules.yaml index ee2515f..91bdc90 100644 --- a/mods/cnc/rules/campaign-maprules.yaml +++ b/mods/cnc/rules/campaign-maprules.yaml @@ -51,7 +51,7 @@ Player: DeveloperMode: CheckboxVisible: False ModularBot@CampaignAI: - Name: Campaign Player AI + Name: bot-campaign-ai.name Type: campaign airstrike.proxy: @@ -62,12 +62,16 @@ airstrike.proxy: ChargeInterval: 3000 SquadSize: 3 QuantizedFacings: 8 - Name: Air Strike - Description: Deploy an aerial napalm strike.\nBurns buildings and infantry along a line. + Name: actor-hq.airstrikepower-name + Description: actor-hq.airstrikepower-description EndChargeSpeechNotification: AirstrikeReady SelectTargetSpeechNotification: SelectTarget InsufficientPowerSpeechNotification: InsufficientPower IncomingSpeechNotification: EnemyPlanesApproaching + EndChargeTextNotification: notification-airstrike-ready + SelectTargetTextNotification: notification-select-target + InsufficientPowerTextNotification: notification-insufficient-power + IncomingTextNotification: notification-enemy-planes-approaching UnitType: a10 DisplayBeacon: True BeaconPoster: airstrike @@ -81,7 +85,7 @@ airstrike.proxy: MoneyCrate: Inherits: ^Crate Tooltip: - Name: Money Crate + Name: actor-moneycrate-name GiveCashCrateAction: Amount: 2000 Sequence: dollar diff --git a/mods/cnc/rules/overrides.yaml b/mods/cnc/rules/overrides.yaml index ba5b262..9c01e80 100644 --- a/mods/cnc/rules/overrides.yaml +++ b/mods/cnc/rules/overrides.yaml @@ -7,10 +7,6 @@ FogVariants: fog-typea, fog-typeb, fog-typec, fog-typed OverrideFullFog: fog-full -World: - LoadWidgetAtGameStart: - ShellmapRoot: MAINMENU_PRERELEASE_NOTIFICATION - V19: RenderSprites: PlayerPalette: derrick diff --git a/mods/cnc/sequences/misc-overrides.yaml b/mods/cnc/sequences/misc-overrides.yaml index 3405224..b5e2efd 100644 --- a/mods/cnc/sequences/misc-overrides.yaml +++ b/mods/cnc/sequences/misc-overrides.yaml @@ -36,6 +36,143 @@ smoke_m: end: RemasteredOffset: 11, -27 +scorch_flames: + large_flame: + Combine: + 0: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\FIRE1.ZIP + RemasteredOffset: 0, -16 + 1: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\FIRE1.ZIP + RemasteredOffset: 0, -16 + 2: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\FIRE1.ZIP + RemasteredOffset: 0, -16 + 3: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\FIRE1.ZIP + RemasteredOffset: 0, -16 + 4: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\FIRE2.ZIP + RemasteredOffset: 0, -16 + 5: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\FIRE2.ZIP + RemasteredOffset: 0, -16 + 6: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\FIRE2.ZIP + RemasteredOffset: 0, -16 + 7: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\SMOKE_M.ZIP + RemasteredOffset: 11, -27 + 8: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\SMOKE_M.ZIP + RemasteredOffset: 11, -27 + 9: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\SMOKE_M.ZIP + RemasteredOffset: 11, -27 + 10: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\SMOKE_M.ZIP + RemasteredOffset: 11, -27 + 11: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\SMOKE_M.ZIP + RemasteredOffset: 11, -27 + medium_flame: + Combine: + 0: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\FIRE2.ZIP + RemasteredOffset: 0, -16 + 1: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\FIRE2.ZIP + RemasteredOffset: 0, -16 + 2: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\FIRE2.ZIP + RemasteredOffset: 0, -16 + 3: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\FIRE2.ZIP + RemasteredOffset: 0, -16 + 4: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\FIRE2.ZIP + RemasteredOffset: 0, -16 + 5: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\SMOKE_M.ZIP + RemasteredOffset: 11, -27 + 6: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\SMOKE_M.ZIP + RemasteredOffset: 11, -27 + 7: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\SMOKE_M.ZIP + RemasteredOffset: 11, -27 + 8: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\SMOKE_M.ZIP + RemasteredOffset: 11, -27 + small_flame: + Combine: + 0: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\FIRE3.ZIP + RemasteredOffset: 0, -16 + 1: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\FIRE3.ZIP + RemasteredOffset: 0, -16 + 2: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\FIRE3.ZIP + RemasteredOffset: 0, -16 + 3: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\FIRE3.ZIP + RemasteredOffset: 0, -16 + 4: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\FIRE3.ZIP + RemasteredOffset: 0, -16 + 5: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\SMOKE_M.ZIP + RemasteredOffset: 11, -27 + 6: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\SMOKE_M.ZIP + RemasteredOffset: 11, -27 + 7: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\SMOKE_M.ZIP + RemasteredOffset: 11, -27 + RemasteredOffset: 0, -16 + tiny_flame: + Combine: + 0: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\FIRE4.ZIP + RemasteredOffset: 0, -16 + 1: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\FIRE4.ZIP + RemasteredOffset: 0, -16 + 2: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\FIRE4.ZIP + RemasteredOffset: 0, -16 + 3: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\FIRE4.ZIP + RemasteredOffset: 0, -16 + 4: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\SMOKE_M.ZIP + RemasteredOffset: 11, -27 + 5: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\SMOKE_M.ZIP + RemasteredOffset: 11, -27 + RemasteredOffset: 0, -16 + smoke: + Combine: + 0: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\SMOKE_M.ZIP + RemasteredOffset: 11, -27 + 1: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\SMOKE_M.ZIP + RemasteredOffset: 11, -27 + 2: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\SMOKE_M.ZIP + RemasteredOffset: 11, -27 + 3: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\SMOKE_M.ZIP + RemasteredOffset: 11, -27 + 4: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\SMOKE_M.ZIP + RemasteredOffset: 11, -27 + 5: + RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\SMOKE_M.ZIP + RemasteredOffset: 11, -27 + laserfire: idle: RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\VEH-HIT3.ZIP diff --git a/mods/cnccontent/prompt.yaml b/mods/cnccontent/prompt.yaml deleted file mode 100644 index cab8519..0000000 --- a/mods/cnccontent/prompt.yaml +++ /dev/null @@ -1,73 +0,0 @@ -Container@PROMPT_CONTAINER: - Width: WINDOW_RIGHT - Height: WINDOW_BOTTOM - Logic: RemasterContentPromptLogic - Children: - Container@SHELLMAP_DECORATIONS: - Children: - Image@NOD: - X: WINDOW_RIGHT / 2 - 384 - Y: (WINDOW_BOTTOM - 256) / 2 - ImageCollection: logos - ImageName: nod-load - Image@GDI: - X: WINDOW_RIGHT / 2 + 128 - Y: (WINDOW_BOTTOM - 256) / 2 - ImageCollection: logos - ImageName: gdi-load - Image@EVA: - X: WINDOW_RIGHT - 128 - 43 - Y: 43 - Width: 128 - Height: 64 - ImageCollection: logos - ImageName: eva - Label@VERSION_LABEL: - X: WINDOW_RIGHT - 128 - 43 - Y: 116 - Width: 128 - Align: Center - Shadow: true - Background@BORDER: - Width: WINDOW_RIGHT - Height: WINDOW_BOTTOM - Background: shellmapborder - Container@PROMPT_PANEL: - X: (WINDOW_RIGHT - WIDTH) / 2 - Y: (WINDOW_BOTTOM - 90) / 2 - Width: 600 - Height: 105 - Children: - Label@TITLE: - Width: PARENT_RIGHT - Y: 0 - 22 - Font: BigBold - Contrast: true - Align: Center - Text: Install Content - Background@bg: - Width: PARENT_RIGHT - Height: 70 - Background: panel-black - Children: - Label@DESC_A: - Y: (PARENT_BOTTOM - HEIGHT) / 2 - 10 - Width: PARENT_RIGHT - Height: 25 - Text: Tiberian Dawn requires artwork and audio from the C&C Remastered Collection. - Font: Bold - Align: Center - Label@DESC_B: - Y: (PARENT_BOTTOM - HEIGHT) / 2 + 10 - Width: PARENT_RIGHT - Height: 25 - Text: Please purchase and install the collection through Steam or Origin and try again. - Font: Bold - Align: Center - Button@QUIT_BUTTON: - X: PARENT_RIGHT - 140 - Y: 69 - Width: 140 - Height: 35 - Text: Quit - Key: escape diff --git a/mods/cnccontent/mod.yaml b/mods/remaster-content/mod.yaml similarity index 51% rename from mods/cnccontent/mod.yaml rename to mods/remaster-content/mod.yaml index 9784d97..1579a2b 100644 --- a/mods/cnccontent/mod.yaml +++ b/mods/remaster-content/mod.yaml @@ -3,43 +3,45 @@ Metadata: Version: {DEV_VERSION} Hidden: true -Packages: - ^EngineDir - $cnccontent: cnccontent - ^EngineDir|mods/cnc: cnc - ^EngineDir|mods/modcontent: modcontent - ^EngineDir|mods/common: common - cnc|uibits +FileSystem: DefaultFileSystem + Packages: + ^EngineDir + ^EngineDir|mods/common-content: content + ^EngineDir|mods/common: common + $remaster-content: cnccontent + Rules: - modcontent|rules.yaml + content|rules.yaml Cursors: - modcontent|cursors.yaml + content|cursors.yaml Chrome: - cnc|chrome.yaml + content|chrome.yaml -Assemblies: - ^BinDir|OpenRA.Mods.Common.dll - ^BinDir|OpenRA.Mods.Cnc.dll - ^BinDir|OpenRA.Mods.Mobius.dll +Assemblies: OpenRA.Mods.Common.dll, OpenRA.Mods.Cnc.dll, OpenRA.Mods.Mobius.dll ChromeLayout: cnccontent|prompt.yaml Notifications: - modcontent|notifications.yaml + content|notifications.yaml -LoadScreen: RemasterInstallPromptLoadScreen - Image: cnc|uibits/chrome.png - Image2x: cnc|uibits/chrome-2x.png - Image3x: cnc|uibits/chrome-3x.png - Text: Loading +LoadScreen: ModContentLoadScreen + Image: ^EngineDir|mods/common-content/chrome.png + Image2x: ^EngineDir|mods/common-content/chrome-2x.png + Image3x: ^EngineDir|mods/common-content/chrome-3x.png ChromeMetrics: common|metrics.yaml - modcontent|metrics.yaml + content|metrics.yaml + +FluentMessages: + common|fluent/common.ftl + content|fluent/content.ftl + content|fluent/chrome.ftl + cnccontent|prompt.ftl Fonts: Tiny: @@ -74,5 +76,3 @@ SpriteFormats: PngSheet TerrainFormat: DefaultTerrain SpriteSequenceFormat: DefaultSpriteSequence - -ModelSequenceFormat: PlaceholderModelSequence diff --git a/mods/remaster-content/prompt.ftl b/mods/remaster-content/prompt.ftl new file mode 100644 index 0000000..bda3f9a --- /dev/null +++ b/mods/remaster-content/prompt.ftl @@ -0,0 +1,4 @@ +label-content-prompt-panel-title = Install Content +modcontent-installprompt = + Tiberian Dawn requires artwork and audio from the C&C Remastered Collection. + Please purchase and install the collection through Steam or Origin and try again. \ No newline at end of file diff --git a/mods/remaster-content/prompt.yaml b/mods/remaster-content/prompt.yaml new file mode 100644 index 0000000..373f2eb --- /dev/null +++ b/mods/remaster-content/prompt.yaml @@ -0,0 +1,44 @@ +Background@MODCONTENT_BACKGROUND: + Logic: RemasterContentPromptLogic + Background: background + Width: WINDOW_WIDTH + Height: WINDOW_HEIGHT + Children: + Background@CONTENT_PROMPT_PANEL: + X: (WINDOW_WIDTH - WIDTH) / 2 + Y: (WINDOW_HEIGHT - HEIGHT) / 2 + Width: 600 + Height: 160 + Background: panel-bg + Children: + Label@TITLE: + X: 0 + Y: 12 + Width: PARENT_WIDTH + Height: 25 + Text: label-content-prompt-panel-title + Align: Center + Font: MediumBold + Background@RULE: + X: 30 + Y: 50 + Width: 540 + Height: 150 + Background: panel-rule + Label@HEADER_LABEL: + X: 30 + Y: 65 + Width: PARENT_WIDTH - 60 + Height: 16 + Text: modcontent-installprompt + Align: Center + WordWrap: true + Button@QUIT_BUTTON: + X: PARENT_WIDTH - WIDTH - 30 + Y: PARENT_HEIGHT - 52 + Background: button-highlighted + Width: 110 + Height: 32 + Text: button-quit + Font: Bold + Key: escape diff --git a/packaging/functions.sh b/packaging/functions.sh old mode 100755 new mode 100644 index fef9189..64b9524 --- a/packaging/functions.sh +++ b/packaging/functions.sh @@ -3,7 +3,7 @@ #### # This file must stay /bin/sh and POSIX compliant for macOS and BSD portability. -# Copy-paste the entire script into http://shellcheck.net to check. +# Copy-paste the entire script into https://shellcheck.net to check. #### # Compile and publish any mod assemblies to the target directory diff --git a/packaging/linux/buildpackage.sh b/packaging/linux/buildpackage.sh index be9fb19..c8bd0d1 100755 --- a/packaging/linux/buildpackage.sh +++ b/packaging/linux/buildpackage.sh @@ -89,9 +89,9 @@ fi # Add native libraries echo "Downloading appimagetool" if command -v curl >/dev/null 2>&1; then - curl -s -L -O https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage || exit 3 + curl -s -L -O https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage || exit 3 else - wget -cq https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage || exit 3 + wget -cq https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage || exit 3 fi echo "Building AppImage" diff --git a/packaging/windows/buildpackage.nsi b/packaging/windows/buildpackage.nsi index c254896..0155cf1 100644 --- a/packaging/windows/buildpackage.nsi +++ b/packaging/windows/buildpackage.nsi @@ -12,7 +12,7 @@ ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License -; along with OpenRA. If not, see . +; along with OpenRA. If not, see . !include "MUI2.nsh"