From eeb86135fcdabbae57a6239cd82dd0c6d13b3d0e Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sat, 3 Aug 2024 15:07:40 +0100 Subject: [PATCH] Update engine to latest bleed. --- OpenRA.Mods.Mobius/RemasterSpriteSequence.cs | 214 ++++++------------ .../Terrain/RemasterTileCache.cs | 2 +- .../Traits/Palettes/ColorPickerColorShift.cs | 85 ------- .../Traits/Palettes/FixedColorShift.cs | 66 ------ .../Traits/Palettes/FixedPlayerColorShift.cs | 48 ---- .../Traits/Palettes/PlayerColorShift.cs | 63 ------ .../RemasterTilesetConverter.cs | 8 +- mod.config | 2 +- .../mainmenu-prerelease-notification.yaml | 12 +- mods/cnc/chrome/mainmenu.yaml | 53 ++--- mods/cnc/chrome/overrides.yaml | 4 - mods/cnc/languages/campaign/en.ftl | 28 +++ mods/cnc/languages/difficulties/en.ftl | 7 - mods/cnc/languages/overrides/en.ftl | 6 + mods/cnc/mod.yaml | 6 +- mods/cnc/rules/campaign-maprules.yaml | 10 +- 16 files changed, 152 insertions(+), 462 deletions(-) delete mode 100644 OpenRA.Mods.Mobius/Traits/Palettes/ColorPickerColorShift.cs delete mode 100644 OpenRA.Mods.Mobius/Traits/Palettes/FixedColorShift.cs delete mode 100644 OpenRA.Mods.Mobius/Traits/Palettes/FixedPlayerColorShift.cs delete mode 100644 OpenRA.Mods.Mobius/Traits/Palettes/PlayerColorShift.cs delete mode 100644 mods/cnc/chrome/overrides.yaml create mode 100644 mods/cnc/languages/campaign/en.ftl delete mode 100644 mods/cnc/languages/difficulties/en.ftl create mode 100644 mods/cnc/languages/overrides/en.ftl diff --git a/OpenRA.Mods.Mobius/RemasterSpriteSequence.cs b/OpenRA.Mods.Mobius/RemasterSpriteSequence.cs index 62e61d3..a8f9fc2 100644 --- a/OpenRA.Mods.Mobius/RemasterSpriteSequence.cs +++ b/OpenRA.Mods.Mobius/RemasterSpriteSequence.cs @@ -9,7 +9,9 @@ */ #endregion +using System; using System.Collections.Generic; +using System.IO; using System.Linq; using OpenRA.Graphics; using OpenRA.Mods.Common.Graphics; @@ -17,6 +19,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 +107,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 +213,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 +225,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; + Func 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 +266,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 +285,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 +301,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/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..5f2a63f 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="6f01f101b4" ############################################################################## # Packaging diff --git a/mods/cnc/chrome/mainmenu-prerelease-notification.yaml b/mods/cnc/chrome/mainmenu-prerelease-notification.yaml index 3ec5179..be6b401 100644 --- a/mods/cnc/chrome/mainmenu-prerelease-notification.yaml +++ b/mods/cnc/chrome/mainmenu-prerelease-notification.yaml @@ -52,7 +52,7 @@ Container@MAINMENU_PRERELEASE_NOTIFICATION: Font: BigBold Contrast: true Align: Center - Text: Tiberian Dawn: Remastered preview + Text: prerelease-notification-title Background@bg: Width: PARENT_RIGHT Height: PARENT_BOTTOM @@ -64,33 +64,33 @@ Container@MAINMENU_PRERELEASE_NOTIFICATION: Width: PARENT_RIGHT - 30 Height: 16 Align: Center - Text: This pre-release build is made available as a proof of concept demonstrating + Text: prerelease-notification-desca 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. + Text: prerelease-notification-descb 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 + Text: prerelease-notification-descc 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. + Text: prerelease-notification-descd Button@CONTINUE_BUTTON: X: PARENT_RIGHT - WIDTH Y: PARENT_BOTTOM - 1 Width: 140 Height: 35 - Text: I Understand + Text: prerelease-notification-confirm Font: Bold Key: return diff --git a/mods/cnc/chrome/mainmenu.yaml b/mods/cnc/chrome/mainmenu.yaml index 3294ddd..add07cd 100644 --- a/mods/cnc/chrome/mainmenu.yaml +++ b/mods/cnc/chrome/mainmenu.yaml @@ -54,7 +54,7 @@ Container@MENU_BACKGROUND: Y: 0 - 28 Width: PARENT_RIGHT Height: 20 - Text: Main Menu + Text: label-main-menu-mainmenu-title Align: Center Font: Bold Contrast: True @@ -63,38 +63,38 @@ Container@MENU_BACKGROUND: Y: 0 Width: 140 Height: 35 - Text: Singleplayer + Text: label-singleplayer-title Button@MULTIPLAYER_BUTTON: X: 150 Y: 0 Width: 140 Height: 35 - Text: Multiplayer + Text: label-multiplayer-title Button@SETTINGS_BUTTON: X: 300 Y: 0 Width: 140 Height: 35 - Text: Settings + Text: button-settings-title Button@EXTRAS_BUTTON: X: 450 Y: 0 Width: 140 Height: 35 - Text: Extras + Text: button-extras-title Button@CONTENT_BUTTON: X: 600 Y: 0 Width: 140 Height: 35 - Text: Manage Content + Text: button-main-menu-content Disabled: true Button@QUIT_BUTTON: X: 750 Y: 0 Width: 140 Height: 35 - Text: Quit + Text: button-quit Container@SINGLEPLAYER_MENU: Width: PARENT_RIGHT Visible: False @@ -104,7 +104,7 @@ Container@MENU_BACKGROUND: Y: 0 - 28 Width: PARENT_RIGHT Height: 20 - Text: Singleplayer + Text: label-singleplayer-title Align: Center Font: Bold Contrast: True @@ -113,26 +113,26 @@ Container@MENU_BACKGROUND: Y: 0 Width: 140 Height: 35 - Text: Skirmish + Text: button-singleplayer-menu-skirmish Button@MISSIONS_BUTTON: X: 150 Y: 0 Width: 140 Height: 35 - Text: Missions + Text: label-missions-title Button@LOAD_BUTTON: X: 300 Y: 0 Width: 140 Height: 35 - Text: Load + Text: button-singleplayer-menu-load Button@BACK_BUTTON: Key: escape X: 450 Y: 0 Width: 140 Height: 35 - Text: Back + Text: button-back Container@EXTRAS_MENU: Width: PARENT_RIGHT Visible: False @@ -142,7 +142,7 @@ Container@MENU_BACKGROUND: Y: 0 - 28 Width: PARENT_RIGHT Height: 20 - Text: Extras + Text: button-extras-title Align: Center Font: Bold Contrast: True @@ -151,39 +151,39 @@ Container@MENU_BACKGROUND: Y: 0 Width: 140 Height: 35 - Text: Replays + Text: button-extras-menu-replays Button@MUSIC_BUTTON: X: 150 Y: 0 Width: 140 Height: 35 - Text: Music + Text: label-music-title Button@MAP_EDITOR_BUTTON: X: 300 Y: 0 Width: 140 Height: 35 - Text: Map Editor + Text: label-map-editor-title Font: Bold Button@ASSETBROWSER_BUTTON: X: 450 Y: 0 Width: 140 Height: 35 - Text: Asset Browser + Text: button-extras-menu-assetbrowser Button@CREDITS_BUTTON: X: 600 Y: 0 Width: 140 Height: 35 - Text: Credits + Text: label-credits-title Button@BACK_BUTTON: Key: escape X: 750 Y: 0 Width: 140 Height: 35 - Text: Back + Text: button-back Container@MAP_EDITOR_MENU: Width: PARENT_RIGHT Visible: False @@ -193,7 +193,7 @@ Container@MENU_BACKGROUND: Y: 0 - 28 Width: PARENT_RIGHT Height: 20 - Text: Map Editor + Text: label-map-editor-title Align: Center Font: Bold Contrast: True @@ -202,21 +202,21 @@ Container@MENU_BACKGROUND: Y: 0 Width: 140 Height: 35 - Text: New Map + Text: button-map-editor-new-map Font: Bold Button@LOAD_MAP_BUTTON: X: 150 Y: 0 Width: 140 Height: 35 - Text: Load Map + Text: button-map-editor-load-map Font: Bold Button@BACK_BUTTON: X: 300 Y: 0 Width: 140 Height: 35 - Text: Back + Text: button-back Font: Bold Key: escape Container@NEWS_BG: @@ -226,7 +226,7 @@ Container@MENU_BACKGROUND: Y: 50 Width: 400 Height: 25 - Text: Battlefield News + Text: dropdownbutton-news-bg-button Font: Bold Container@UPDATE_NOTICE: X: (WINDOW_RIGHT - WIDTH) / 2 @@ -238,14 +238,14 @@ Container@MENU_BACKGROUND: Height: 25 Align: Center Shadow: true - Text: You are running an outdated version of OpenRA. + Text: label-update-notice-a Label@B: Y: 20 Width: PARENT_RIGHT Height: 25 Align: Center Shadow: true - Text: Download the latest version from www.openra.net + Text: label-update-notice-b Container@PERFORMANCE_INFO: Logic: PerfDebugLogic Children: @@ -270,3 +270,4 @@ Container@MENU_BACKGROUND: 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/languages/campaign/en.ftl b/mods/cnc/languages/campaign/en.ftl new file mode 100644 index 0000000..5735ca3 --- /dev/null +++ b/mods/cnc/languages/campaign/en.ftl @@ -0,0 +1,28 @@ +## world +dropdown-difficulty = + .label = Difficulty + .description = The difficulty of the mission + +options-difficulty = + .easy = Easy + .normal = Normal + .hard = Hard + +## 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/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/languages/overrides/en.ftl b/mods/cnc/languages/overrides/en.ftl new file mode 100644 index 0000000..5a05b0e --- /dev/null +++ b/mods/cnc/languages/overrides/en.ftl @@ -0,0 +1,6 @@ +prerelease-notification-title = Tiberian Dawn: Remastered preview +prerelease-notification-desca = This pre-release build is made available as a proof of concept demonstrating +prerelease-notification-descb = the capabilities of OpenRA using the C&C Remastered Collection assets. +prerelease-notification-descc = Performance, memory usage, and loading times have not been optimized, and do +prerelease-notification-descd = not reflect the expected final requirements. A dedicated GPU is recommended. +prerelease-notification-confirm = I Understand \ No newline at end of file diff --git a/mods/cnc/mod.yaml b/mods/cnc/mod.yaml index b291c82..bac7aa4 100644 --- a/mods/cnc/mod.yaml +++ b/mods/cnc/mod.yaml @@ -174,7 +174,11 @@ ChromeLayout: Translations: common|languages/en.ftl common|languages/rules/en.ftl + base|languages/chrome/en.ftl base|languages/rules/en.ftl + cnc|languages/overrides/en.ftl + +AllowUnusedTranslationsInExternalPackages: false Voices: cnc|audio/voices.yaml @@ -274,8 +278,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 diff --git a/mods/cnc/rules/campaign-maprules.yaml b/mods/cnc/rules/campaign-maprules.yaml index ee2515f..ed475b4 100644 --- a/mods/cnc/rules/campaign-maprules.yaml +++ b/mods/cnc/rules/campaign-maprules.yaml @@ -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