Improve lookups of nodes by key in MiniYaml.
When handling the Nodes collection in MiniYaml, individual nodes are located via one of two methods:
// Lookup a single key with linear search.
var node = yaml.Nodes.FirstOrDefault(n => n.Key == "SomeKey");
// Convert to dictionary, expecting many key lookups.
var dict = nodes.ToDictionary();
// Lookup a single key in the dictionary.
var node = dict["SomeKey"];
To simplify lookup of individual keys via linear search, provide helper methods NodeWithKeyOrDefault and NodeWithKey. These helpers do the equivalent of Single{OrDefault} searches. Whilst this requires checking the whole list, it provides a useful correctness check. Two duplicated keys in TS yaml are fixed as a result. We can also optimize the helpers to not use LINQ, avoiding allocation of the delegate to search for a key.
Adjust existing code to use either lnear searches or dictionary lookups based on whether it will be resolving many keys. Resolving few keys can be done with linear searches to avoid building a dictionary. Resolving many keys should be done with a dictionary to avoid quaradtic runtime from repeated linear searches.
This commit is contained in:
committed by
Matthias Mailänder
parent
0ab7caedd9
commit
b7e0ed9b87
@@ -94,17 +94,17 @@ namespace OpenRA
|
||||
|
||||
if (sheetBuilder != null)
|
||||
{
|
||||
var iconNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Icon");
|
||||
var iconNode = yaml.NodeWithKeyOrDefault("Icon");
|
||||
if (iconNode != null && !string.IsNullOrEmpty(iconNode.Value.Value))
|
||||
using (var stream = new MemoryStream(Convert.FromBase64String(iconNode.Value.Value)))
|
||||
mod.Icon = sheetBuilder.Add(new Png(stream));
|
||||
|
||||
var icon2xNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Icon2x");
|
||||
var icon2xNode = yaml.NodeWithKeyOrDefault("Icon2x");
|
||||
if (icon2xNode != null && !string.IsNullOrEmpty(icon2xNode.Value.Value))
|
||||
using (var stream = new MemoryStream(Convert.FromBase64String(icon2xNode.Value.Value)))
|
||||
mod.Icon2x = sheetBuilder.Add(new Png(stream), 1f / 2);
|
||||
|
||||
var icon3xNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Icon3x");
|
||||
var icon3xNode = yaml.NodeWithKeyOrDefault("Icon3x");
|
||||
if (icon3xNode != null && !string.IsNullOrEmpty(icon3xNode.Value.Value))
|
||||
using (var stream = new MemoryStream(Convert.FromBase64String(icon3xNode.Value.Value)))
|
||||
mod.Icon3x = sheetBuilder.Add(new Png(stream), 1f / 3);
|
||||
|
||||
@@ -40,16 +40,16 @@ namespace OpenRA.GameRules
|
||||
static Dictionary<string, SoundPool> ParseSoundPool(MiniYaml y, string key)
|
||||
{
|
||||
var ret = new Dictionary<string, SoundPool>();
|
||||
var classifiction = y.Nodes.First(x => x.Key == key);
|
||||
var classifiction = y.NodeWithKey(key);
|
||||
foreach (var t in classifiction.Value.Nodes)
|
||||
{
|
||||
var volumeModifier = 1f;
|
||||
var volumeModifierNode = t.Value.Nodes.FirstOrDefault(x => x.Key == nameof(SoundPool.VolumeModifier));
|
||||
var volumeModifierNode = t.Value.NodeWithKeyOrDefault(nameof(SoundPool.VolumeModifier));
|
||||
if (volumeModifierNode != null)
|
||||
volumeModifier = FieldLoader.GetValue<float>(volumeModifierNode.Key, volumeModifierNode.Value.Value);
|
||||
|
||||
var interruptType = SoundPool.DefaultInterruptType;
|
||||
var interruptTypeNode = t.Value.Nodes.FirstOrDefault(x => x.Key == nameof(SoundPool.InterruptType));
|
||||
var interruptTypeNode = t.Value.NodeWithKeyOrDefault(nameof(SoundPool.InterruptType));
|
||||
if (interruptTypeNode != null)
|
||||
interruptType = FieldLoader.GetValue<SoundPool.InterruptType>(interruptTypeNode.Key, interruptTypeNode.Value.Value);
|
||||
|
||||
|
||||
@@ -145,7 +145,8 @@ namespace OpenRA.GameRules
|
||||
|
||||
static object LoadProjectile(MiniYaml yaml)
|
||||
{
|
||||
if (!yaml.ToDictionary().TryGetValue("Projectile", out var proj))
|
||||
var proj = yaml.NodeWithKeyOrDefault("Projectile")?.Value;
|
||||
if (proj == null)
|
||||
return null;
|
||||
|
||||
var ret = Game.CreateObject<IProjectileInfo>(proj.Value + "Info");
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
@@ -38,7 +37,7 @@ namespace OpenRA
|
||||
static object LoadSpeeds(MiniYaml y)
|
||||
{
|
||||
var ret = new Dictionary<string, GameSpeed>();
|
||||
var speedsNode = y.Nodes.FirstOrDefault(n => n.Key == "Speeds");
|
||||
var speedsNode = y.NodeWithKeyOrDefault("Speeds");
|
||||
if (speedsNode == null)
|
||||
throw new YamlException("Error parsing GameSpeeds: Missing Speeds node!");
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace OpenRA.Graphics
|
||||
var sequenceYaml = MiniYaml.Merge(modData.Manifest.Cursors.Select(
|
||||
s => MiniYaml.FromStream(fileSystem.Open(s), s)));
|
||||
|
||||
var nodesDict = new MiniYaml(null, sequenceYaml).ToDictionary();
|
||||
var cursorsYaml = new MiniYaml(null, sequenceYaml).NodeWithKey("Cursors").Value;
|
||||
|
||||
// Overwrite previous definitions if there are duplicates
|
||||
var pals = new Dictionary<string, IProvidesCursorPaletteInfo>();
|
||||
@@ -35,14 +35,14 @@ namespace OpenRA.Graphics
|
||||
if (p.Palette != null)
|
||||
pals[p.Palette] = p;
|
||||
|
||||
Palettes = nodesDict["Cursors"].Nodes.Select(n => n.Value.Value)
|
||||
Palettes = cursorsYaml.Nodes.Select(n => n.Value.Value)
|
||||
.Where(p => p != null)
|
||||
.Distinct()
|
||||
.ToDictionary(p => p, p => pals[p].ReadPalette(modData.DefaultFileSystem));
|
||||
|
||||
var frameCache = new FrameCache(fileSystem, modData.SpriteLoaders);
|
||||
var cursors = new Dictionary<string, CursorSequence>();
|
||||
foreach (var s in nodesDict["Cursors"].Nodes)
|
||||
foreach (var s in cursorsYaml.Nodes)
|
||||
foreach (var sequence in s.Value.Nodes)
|
||||
cursors.Add(sequence.Key, new CursorSequence(frameCache, sequence.Key, s.Key, s.Value.Value, sequence.Value));
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
@@ -31,29 +30,26 @@ namespace OpenRA
|
||||
if (!string.IsNullOrEmpty(node.Value))
|
||||
Default = FieldLoader.GetValue<Hotkey>("value", node.Value);
|
||||
|
||||
var descriptionNode = node.Nodes.FirstOrDefault(n => n.Key == "Description");
|
||||
if (descriptionNode != null)
|
||||
Description = descriptionNode.Value.Value;
|
||||
var nodeDict = node.ToDictionary();
|
||||
|
||||
var typesNode = node.Nodes.FirstOrDefault(n => n.Key == "Types");
|
||||
if (typesNode != null)
|
||||
Types = FieldLoader.GetValue<HashSet<string>>("Types", typesNode.Value.Value);
|
||||
if (nodeDict.TryGetValue("Description", out var descriptionYaml))
|
||||
Description = descriptionYaml.Value;
|
||||
|
||||
var contextsNode = node.Nodes.FirstOrDefault(n => n.Key == "Contexts");
|
||||
if (contextsNode != null)
|
||||
Contexts = FieldLoader.GetValue<HashSet<string>>("Contexts", contextsNode.Value.Value);
|
||||
if (nodeDict.TryGetValue("Types", out var typesYaml))
|
||||
Types = FieldLoader.GetValue<HashSet<string>>("Types", typesYaml.Value);
|
||||
|
||||
var platformNode = node.Nodes.FirstOrDefault(n => n.Key == "Platform");
|
||||
if (platformNode != null)
|
||||
if (nodeDict.TryGetValue("Contexts", out var contextYaml))
|
||||
Contexts = FieldLoader.GetValue<HashSet<string>>("Contexts", contextYaml.Value);
|
||||
|
||||
if (nodeDict.TryGetValue("Platform", out var platformYaml))
|
||||
{
|
||||
var platformOverride = platformNode.Value.Nodes.FirstOrDefault(n => n.Key == Platform.CurrentPlatform.ToString());
|
||||
var platformOverride = platformYaml.NodeWithKeyOrDefault(Platform.CurrentPlatform.ToString());
|
||||
if (platformOverride != null)
|
||||
Default = FieldLoader.GetValue<Hotkey>("value", platformOverride.Value.Value);
|
||||
}
|
||||
|
||||
var readonlyNode = node.Nodes.FirstOrDefault(n => n.Key == "Readonly");
|
||||
if (readonlyNode != null)
|
||||
Readonly = FieldLoader.GetValue<bool>("Readonly", readonlyNode.Value.Value);
|
||||
if (nodeDict.TryGetValue("Readonly", out var readonlyYaml))
|
||||
Readonly = FieldLoader.GetValue<bool>("Readonly", readonlyYaml.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,7 +214,7 @@ namespace OpenRA
|
||||
if (!yaml.ContainsKey(key))
|
||||
return Array.Empty<string>();
|
||||
|
||||
return yaml[key].ToDictionary().Keys.ToArray();
|
||||
return yaml[key].Nodes.Select(n => n.Key).ToArray();
|
||||
}
|
||||
|
||||
static IReadOnlyDictionary<string, string> YamlDictionary(Dictionary<string, MiniYaml> yaml, string key)
|
||||
|
||||
@@ -95,9 +95,9 @@ namespace OpenRA
|
||||
t == typeof(MiniYaml) ? Type.MiniYaml : Type.Normal;
|
||||
}
|
||||
|
||||
public void Deserialize(Map map, ImmutableArray<MiniYamlNode> nodes)
|
||||
public void Deserialize(Map map, MiniYaml yaml)
|
||||
{
|
||||
var node = nodes.FirstOrDefault(n => n.Key == key);
|
||||
var node = yaml.NodeWithKeyOrDefault(key);
|
||||
if (node == null)
|
||||
{
|
||||
if (required)
|
||||
@@ -363,13 +363,13 @@ namespace OpenRA
|
||||
|
||||
var yaml = new MiniYaml(null, MiniYaml.FromStream(Package.GetStream("map.yaml"), package.Name));
|
||||
foreach (var field in YamlFields)
|
||||
field.Deserialize(this, yaml.Nodes);
|
||||
field.Deserialize(this, yaml);
|
||||
|
||||
if (MapFormat < SupportedMapFormat)
|
||||
throw new InvalidDataException($"Map format {MapFormat} is not supported.\n File: {package.Name}");
|
||||
|
||||
PlayerDefinitions = MiniYaml.NodesOrEmpty(yaml, "Players");
|
||||
ActorDefinitions = MiniYaml.NodesOrEmpty(yaml, "Actors");
|
||||
PlayerDefinitions = yaml.NodeWithKeyOrDefault("Players")?.Value.Nodes ?? ImmutableArray<MiniYamlNode>.Empty;
|
||||
ActorDefinitions = yaml.NodeWithKeyOrDefault("Actors")?.Value.Nodes ?? ImmutableArray<MiniYamlNode>.Empty;
|
||||
|
||||
Grid = modData.Manifest.Get<MapGrid>();
|
||||
|
||||
|
||||
@@ -141,6 +141,34 @@ namespace OpenRA
|
||||
return new MiniYaml(Value, newNodes);
|
||||
}
|
||||
|
||||
public MiniYamlNode NodeWithKey(string key)
|
||||
{
|
||||
var result = NodeWithKeyOrDefault(key);
|
||||
if (result == null)
|
||||
throw new InvalidDataException($"No node with key '{key}'");
|
||||
return result;
|
||||
}
|
||||
|
||||
public MiniYamlNode NodeWithKeyOrDefault(string key)
|
||||
{
|
||||
// PERF: Avoid LINQ.
|
||||
var first = true;
|
||||
MiniYamlNode result = null;
|
||||
foreach (var node in Nodes)
|
||||
{
|
||||
if (node.Key != key)
|
||||
continue;
|
||||
|
||||
if (!first)
|
||||
throw new InvalidDataException($"Duplicate key '{node.Key}' in {node.Location}");
|
||||
|
||||
first = false;
|
||||
result = node;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Dictionary<string, MiniYaml> ToDictionary()
|
||||
{
|
||||
return ToDictionary(MiniYamlIdentity);
|
||||
@@ -175,11 +203,6 @@ namespace OpenRA
|
||||
Nodes = ImmutableArray.CreateRange(nodes);
|
||||
}
|
||||
|
||||
public static ImmutableArray<MiniYamlNode> NodesOrEmpty(MiniYaml y, string s)
|
||||
{
|
||||
return y.Nodes.FirstOrDefault(n => n.Key == s)?.Value.Nodes ?? ImmutableArray<MiniYamlNode>.Empty;
|
||||
}
|
||||
|
||||
static List<MiniYamlNode> FromLines(IEnumerable<ReadOnlyMemory<char>> lines, string filename, bool discardCommentsAndWhitespace, Dictionary<string, string> stringPool)
|
||||
{
|
||||
stringPool ??= new Dictionary<string, string>();
|
||||
@@ -668,6 +691,11 @@ namespace OpenRA
|
||||
foreach (var line in Nodes.ToLines())
|
||||
yield return "\t" + line;
|
||||
}
|
||||
|
||||
public MiniYamlNodeBuilder NodeWithKeyOrDefault(string key)
|
||||
{
|
||||
return Nodes.SingleOrDefault(n => n.Key == key);
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
|
||||
@@ -140,7 +140,7 @@ namespace OpenRA.Network
|
||||
static object LoadClients(MiniYaml yaml)
|
||||
{
|
||||
var clients = new List<GameClient>();
|
||||
var clientsNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Clients");
|
||||
var clientsNode = yaml.NodeWithKeyOrDefault("Clients");
|
||||
if (clientsNode != null)
|
||||
{
|
||||
var regex = new Regex(@"Client@\d+");
|
||||
@@ -159,7 +159,7 @@ namespace OpenRA.Network
|
||||
// Games advertised using the old API used a single Mods field
|
||||
if (Mod == null || Version == null)
|
||||
{
|
||||
var modsNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Mods");
|
||||
var modsNode = yaml.NodeWithKeyOrDefault("Mods");
|
||||
if (modsNode != null)
|
||||
{
|
||||
var modVersion = modsNode.Value.Value.Split('@');
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace OpenRA.Network
|
||||
static object LoadArguments(MiniYaml yaml)
|
||||
{
|
||||
var arguments = new Dictionary<string, object>();
|
||||
var argumentsNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Arguments");
|
||||
var argumentsNode = yaml.NodeWithKeyOrDefault("Arguments");
|
||||
if (argumentsNode != null)
|
||||
{
|
||||
foreach (var argumentNode in argumentsNode.Value.Nodes)
|
||||
|
||||
@@ -227,7 +227,7 @@ namespace OpenRA.Network
|
||||
{
|
||||
var gs = FieldLoader.Load<Global>(data);
|
||||
|
||||
var optionsNode = data.Nodes.FirstOrDefault(n => n.Key == "Options");
|
||||
var optionsNode = data.NodeWithKeyOrDefault("Options");
|
||||
if (optionsNode != null)
|
||||
foreach (var n in optionsNode.Value.Nodes)
|
||||
gs.LobbyOptions[n.Key] = FieldLoader.Load<LobbyOptionState>(n.Value);
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Graphics;
|
||||
@@ -94,10 +93,10 @@ namespace OpenRA
|
||||
});
|
||||
}
|
||||
|
||||
var labelNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Label");
|
||||
var icon24Node = yaml.Nodes.FirstOrDefault(n => n.Key == "Icon24");
|
||||
var icon48Node = yaml.Nodes.FirstOrDefault(n => n.Key == "Icon48");
|
||||
var icon72Node = yaml.Nodes.FirstOrDefault(n => n.Key == "Icon72");
|
||||
var labelNode = yaml.NodeWithKeyOrDefault("Label");
|
||||
var icon24Node = yaml.NodeWithKeyOrDefault("Icon24");
|
||||
var icon48Node = yaml.NodeWithKeyOrDefault("Icon48");
|
||||
var icon72Node = yaml.NodeWithKeyOrDefault("Icon72");
|
||||
if (labelNode == null)
|
||||
return null;
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
@@ -31,7 +30,7 @@ namespace OpenRA
|
||||
{
|
||||
var badges = new List<PlayerBadge>();
|
||||
|
||||
var badgesNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Badges");
|
||||
var badgesNode = yaml.NodeWithKeyOrDefault("Badges");
|
||||
if (badgesNode != null)
|
||||
{
|
||||
var playerDatabase = Game.ModData.Manifest.Get<PlayerDatabase>();
|
||||
|
||||
@@ -385,7 +385,7 @@ namespace OpenRA
|
||||
else
|
||||
{
|
||||
// Update or add the custom value
|
||||
var fieldYaml = sectionYaml.Value.Nodes.FirstOrDefault(n => n.Key == fli.YamlName);
|
||||
var fieldYaml = sectionYaml.Value.NodeWithKeyOrDefault(fli.YamlName);
|
||||
if (fieldYaml != null)
|
||||
fieldYaml.Value.Value = serialized;
|
||||
else
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
@@ -350,7 +349,7 @@ namespace OpenRA.Traits
|
||||
public interface IGameSaveTraitData
|
||||
{
|
||||
List<MiniYamlNode> IssueTraitData(Actor self);
|
||||
void ResolveTraitData(Actor self, ImmutableArray<MiniYamlNode> data);
|
||||
void ResolveTraitData(Actor self, MiniYaml data);
|
||||
}
|
||||
|
||||
[RequireExplicitImplementation]
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace OpenRA
|
||||
foreach (var c in child.Value.Nodes)
|
||||
LoadWidget(args, widget, c);
|
||||
|
||||
var logicNode = node.Value.Nodes.FirstOrDefault(n => n.Key == "Logic");
|
||||
var logicNode = node.Value.NodeWithKeyOrDefault("Logic");
|
||||
var logic = logicNode?.Value.ToDictionary();
|
||||
args.Add("logicArgs", logic);
|
||||
|
||||
|
||||
@@ -423,7 +423,7 @@ namespace OpenRA
|
||||
if (tp.Actor == null)
|
||||
break;
|
||||
|
||||
tp.Trait.ResolveTraitData(tp.Actor, kv.Value.Nodes);
|
||||
tp.Trait.ResolveTraitData(tp.Actor, kv.Value);
|
||||
}
|
||||
|
||||
gameSaveTraitData.Clear();
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Common.Graphics;
|
||||
|
||||
@@ -39,10 +38,10 @@ namespace OpenRA.Mods.Cnc.Graphics
|
||||
|
||||
protected override IEnumerable<ReservationInfo> ParseFilenames(ModData modData, string tileset, int[] frames, MiniYaml data, MiniYaml defaults)
|
||||
{
|
||||
var node = data.Nodes.FirstOrDefault(n => n.Key == TilesetFilenames.Key) ?? defaults.Nodes.FirstOrDefault(n => n.Key == TilesetFilenames.Key);
|
||||
var node = data.NodeWithKeyOrDefault(TilesetFilenames.Key) ?? defaults.NodeWithKeyOrDefault(TilesetFilenames.Key);
|
||||
if (node != null)
|
||||
{
|
||||
var tilesetNode = node.Value.Nodes.FirstOrDefault(n => n.Key == tileset);
|
||||
var tilesetNode = node.Value.NodeWithKeyOrDefault(tileset);
|
||||
if (tilesetNode != null)
|
||||
{
|
||||
var loadFrames = CalculateFrameIndices(start, length, stride ?? length ?? 0, facings, frames, transpose, reverseFacings, shadowStart);
|
||||
@@ -55,10 +54,10 @@ namespace OpenRA.Mods.Cnc.Graphics
|
||||
|
||||
protected override IEnumerable<ReservationInfo> ParseCombineFilenames(ModData modData, string tileset, int[] frames, MiniYaml data)
|
||||
{
|
||||
var node = data.Nodes.FirstOrDefault(n => n.Key == TilesetFilenames.Key);
|
||||
var node = data.NodeWithKeyOrDefault(TilesetFilenames.Key);
|
||||
if (node != null)
|
||||
{
|
||||
var tilesetNode = node.Value.Nodes.FirstOrDefault(n => n.Key == tileset);
|
||||
var tilesetNode = node.Value.NodeWithKeyOrDefault(tileset);
|
||||
if (tilesetNode != null)
|
||||
{
|
||||
if (frames == null)
|
||||
|
||||
@@ -130,7 +130,7 @@ namespace OpenRA.Mods.Cnc.UtilityCommands
|
||||
|
||||
protected MiniYamlNodeBuilder GetWorldNodeBuilderFromRules()
|
||||
{
|
||||
var worldNode = Map.RuleDefinitions.Nodes.FirstOrDefault(n => n.Key == "World");
|
||||
var worldNode = Map.RuleDefinitions.NodeWithKeyOrDefault("World");
|
||||
var worldNodeBuilder = worldNode != null
|
||||
? new MiniYamlNodeBuilder(worldNode)
|
||||
: new MiniYamlNodeBuilder("World", new MiniYamlBuilder("", new List<MiniYamlNode>()));
|
||||
@@ -166,7 +166,7 @@ namespace OpenRA.Mods.Cnc.UtilityCommands
|
||||
|
||||
var worldNodeBuilder = GetWorldNodeBuilderFromRules();
|
||||
|
||||
var missionData = worldNodeBuilder.Value.Nodes.FirstOrDefault(n => n.Key == "MissionData");
|
||||
var missionData = worldNodeBuilder.Value.NodeWithKeyOrDefault("MissionData");
|
||||
if (missionData == null)
|
||||
{
|
||||
missionData = new MiniYamlNodeBuilder("MissionData", new MiniYamlBuilder("", new List<MiniYamlNode>()));
|
||||
@@ -237,7 +237,7 @@ namespace OpenRA.Mods.Cnc.UtilityCommands
|
||||
{
|
||||
var worldNodeBuilder = GetWorldNodeBuilderFromRules();
|
||||
|
||||
var missionData = worldNodeBuilder.Value.Nodes.FirstOrDefault(n => n.Key == "MissionData");
|
||||
var missionData = worldNodeBuilder.Value.NodeWithKeyOrDefault("MissionData");
|
||||
if (missionData == null)
|
||||
{
|
||||
missionData = new MiniYamlNodeBuilder("MissionData", new MiniYamlBuilder("", new List<MiniYamlNode>()));
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace OpenRA.Mods.Common.Graphics
|
||||
IReadOnlyDictionary<string, ISpriteSequence> ISpriteSequenceLoader.ParseSequences(ModData modData, string tileset, SpriteCache cache, MiniYamlNode imageNode)
|
||||
{
|
||||
var sequences = new Dictionary<string, ISpriteSequence>();
|
||||
var node = imageNode.Value.Nodes.SingleOrDefault(n => n.Key == "Defaults");
|
||||
var node = imageNode.Value.NodeWithKeyOrDefault("Defaults");
|
||||
var defaults = node?.Value ?? NoData;
|
||||
imageNode = imageNode.WithValue(imageNode.Value.WithNodes(imageNode.Value.Nodes.Remove(node)));
|
||||
|
||||
@@ -262,7 +262,7 @@ namespace OpenRA.Mods.Common.Graphics
|
||||
|
||||
protected static T LoadField<T>(string key, T fallback, MiniYaml data, MiniYaml defaults = null)
|
||||
{
|
||||
var node = data.Nodes.FirstOrDefault(n => n.Key == key) ?? defaults?.Nodes.FirstOrDefault(n => n.Key == key);
|
||||
var node = data.NodeWithKeyOrDefault(key) ?? defaults?.NodeWithKeyOrDefault(key);
|
||||
if (node == null)
|
||||
return fallback;
|
||||
|
||||
@@ -276,7 +276,7 @@ namespace OpenRA.Mods.Common.Graphics
|
||||
|
||||
protected static T LoadField<T>(SpriteSequenceField<T> field, MiniYaml data, MiniYaml defaults, out MiniYamlNode.SourceLocation location)
|
||||
{
|
||||
var node = data.Nodes.FirstOrDefault(n => n.Key == field.Key) ?? defaults?.Nodes.FirstOrDefault(n => n.Key == field.Key);
|
||||
var node = data.NodeWithKeyOrDefault(field.Key) ?? defaults?.NodeWithKeyOrDefault(field.Key);
|
||||
if (node == null)
|
||||
{
|
||||
location = default;
|
||||
@@ -414,7 +414,7 @@ namespace OpenRA.Mods.Common.Graphics
|
||||
var offset = LoadField(Offset, data, defaults);
|
||||
var blendMode = LoadField(BlendMode, data, defaults);
|
||||
|
||||
var combineNode = data.Nodes.FirstOrDefault(n => n.Key == Combine.Key);
|
||||
var combineNode = data.NodeWithKeyOrDefault(Combine.Key);
|
||||
if (combineNode != null)
|
||||
{
|
||||
for (var i = 0; i < combineNode.Value.Nodes.Length; i++)
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
|
||||
namespace OpenRA.Mods.Common.Graphics
|
||||
@@ -37,10 +36,10 @@ namespace OpenRA.Mods.Common.Graphics
|
||||
|
||||
protected override IEnumerable<ReservationInfo> ParseFilenames(ModData modData, string tileset, int[] frames, MiniYaml data, MiniYaml defaults)
|
||||
{
|
||||
var node = data.Nodes.FirstOrDefault(n => n.Key == TilesetFilenames.Key) ?? defaults.Nodes.FirstOrDefault(n => n.Key == TilesetFilenames.Key);
|
||||
var node = data.NodeWithKeyOrDefault(TilesetFilenames.Key) ?? defaults.NodeWithKeyOrDefault(TilesetFilenames.Key);
|
||||
if (node != null)
|
||||
{
|
||||
var tilesetNode = node.Value.Nodes.FirstOrDefault(n => n.Key == tileset);
|
||||
var tilesetNode = node.Value.NodeWithKeyOrDefault(tileset);
|
||||
if (tilesetNode != null)
|
||||
{
|
||||
var loadFrames = CalculateFrameIndices(start, length, stride ?? length ?? 0, facings, frames, transpose, reverseFacings, shadowStart);
|
||||
@@ -53,10 +52,10 @@ namespace OpenRA.Mods.Common.Graphics
|
||||
|
||||
protected override IEnumerable<ReservationInfo> ParseCombineFilenames(ModData modData, string tileset, int[] frames, MiniYaml data)
|
||||
{
|
||||
var node = data.Nodes.FirstOrDefault(n => n.Key == TilesetFilenames.Key);
|
||||
var node = data.NodeWithKeyOrDefault(TilesetFilenames.Key);
|
||||
if (node != null)
|
||||
{
|
||||
var tilesetNode = node.Value.Nodes.FirstOrDefault(n => n.Key == tileset);
|
||||
var tilesetNode = node.Value.NodeWithKeyOrDefault(tileset);
|
||||
if (tilesetNode != null)
|
||||
{
|
||||
if (frames == null)
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using FS = OpenRA.FileSystem.FileSystem;
|
||||
|
||||
namespace OpenRA.Mods.Common.Installer
|
||||
@@ -33,8 +32,8 @@ namespace OpenRA.Mods.Common.Installer
|
||||
|
||||
using (var fileStream = File.OpenRead(filePath))
|
||||
{
|
||||
var offsetNode = kv.Value.Nodes.FirstOrDefault(n => n.Key == "Offset");
|
||||
var lengthNode = kv.Value.Nodes.FirstOrDefault(n => n.Key == "Length");
|
||||
var offsetNode = kv.Value.NodeWithKeyOrDefault("Offset");
|
||||
var lengthNode = kv.Value.NodeWithKeyOrDefault("Length");
|
||||
if (offsetNode != null || lengthNode != null)
|
||||
{
|
||||
var offset = 0L;
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.Common.FileFormats;
|
||||
using OpenRA.Mods.Common.Widgets.Logic;
|
||||
using FS = OpenRA.FileSystem.FileSystem;
|
||||
@@ -26,11 +25,11 @@ namespace OpenRA.Mods.Common.Installer
|
||||
// Yaml path may be specified relative to a named directory (e.g. ^SupportDir) or the detected source path
|
||||
var sourcePath = actionYaml.Value.StartsWith('^') ? Platform.ResolvePath(actionYaml.Value) : FS.ResolveCaseInsensitivePath(Path.Combine(path, actionYaml.Value));
|
||||
|
||||
var volumeNode = actionYaml.Nodes.FirstOrDefault(n => n.Key == "Volumes");
|
||||
var volumeNode = actionYaml.NodeWithKeyOrDefault("Volumes");
|
||||
if (volumeNode == null)
|
||||
throw new InvalidDataException("extract-iscab entry doesn't define a Volumes node");
|
||||
|
||||
var extractNode = actionYaml.Nodes.FirstOrDefault(n => n.Key == "Extract");
|
||||
var extractNode = actionYaml.NodeWithKeyOrDefault("Extract");
|
||||
if (extractNode == null)
|
||||
throw new InvalidDataException("extract-iscab entry doesn't define an Extract node");
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.Common.Widgets.Logic;
|
||||
using FS = OpenRA.FileSystem.FileSystem;
|
||||
|
||||
@@ -37,14 +36,14 @@ namespace OpenRA.Mods.Common.Installer
|
||||
continue;
|
||||
}
|
||||
|
||||
var offsetNode = node.Value.Nodes.FirstOrDefault(n => n.Key == "Offset");
|
||||
var offsetNode = node.Value.NodeWithKeyOrDefault("Offset");
|
||||
if (offsetNode == null)
|
||||
{
|
||||
Log.Write("install", "Skipping entry with missing Offset definition " + targetPath);
|
||||
continue;
|
||||
}
|
||||
|
||||
var lengthNode = node.Value.Nodes.FirstOrDefault(n => n.Key == "Length");
|
||||
var lengthNode = node.Value.NodeWithKeyOrDefault("Length");
|
||||
if (lengthNode == null)
|
||||
{
|
||||
Log.Write("install", "Skipping entry with missing Length definition " + targetPath);
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace OpenRA.Mods.Common.Installer
|
||||
{
|
||||
public string FindSourcePath(ModContent.ModSource modSource)
|
||||
{
|
||||
modSource.Type.ToDictionary().TryGetValue("AppId", out var appId);
|
||||
var appId = modSource.Type.NodeWithKeyOrDefault("AppId");
|
||||
|
||||
if (appId == null)
|
||||
return null;
|
||||
@@ -35,7 +35,7 @@ namespace OpenRA.Mods.Common.Installer
|
||||
|
||||
foreach (var prefix in prefixes)
|
||||
{
|
||||
if (Registry.GetValue($"{prefix}GOG.com\\Games\\{appId.Value}", "path", null) is not string installDir)
|
||||
if (Registry.GetValue($"{prefix}GOG.com\\Games\\{appId.Value.Value}", "path", null) is not string installDir)
|
||||
continue;
|
||||
|
||||
if (InstallerUtils.IsValidSourcePath(installDir, modSource))
|
||||
|
||||
@@ -23,14 +23,14 @@ namespace OpenRA.Mods.Common.Installer
|
||||
{
|
||||
public string FindSourcePath(ModContent.ModSource modSource)
|
||||
{
|
||||
modSource.Type.ToDictionary().TryGetValue("AppId", out var appId);
|
||||
var appId = modSource.Type.NodeWithKeyOrDefault("AppId");
|
||||
|
||||
if (appId == null)
|
||||
return null;
|
||||
|
||||
foreach (var steamDirectory in SteamDirectory())
|
||||
{
|
||||
var manifestPath = Path.Combine(steamDirectory, "steamapps", $"appmanifest_{appId.Value}.acf");
|
||||
var manifestPath = Path.Combine(steamDirectory, "steamapps", $"appmanifest_{appId.Value.Value}.acf");
|
||||
|
||||
if (!File.Exists(manifestPath))
|
||||
continue;
|
||||
|
||||
@@ -33,11 +33,11 @@ namespace OpenRA.Mods.Common.Lint
|
||||
{
|
||||
var fileSystem = modData.DefaultFileSystem;
|
||||
var sequenceYaml = MiniYaml.Merge(modData.Manifest.Cursors.Select(s => MiniYaml.FromStream(fileSystem.Open(s), s)));
|
||||
var nodesDict = new MiniYaml(null, sequenceYaml).ToDictionary();
|
||||
var cursorsYaml = new MiniYaml(null, sequenceYaml).NodeWithKey("Cursors").Value;
|
||||
|
||||
// Avoid using CursorProvider as it attempts to load palettes from the file system.
|
||||
var cursors = new List<string>();
|
||||
foreach (var s in nodesDict["Cursors"].Nodes)
|
||||
foreach (var s in cursorsYaml.Nodes)
|
||||
foreach (var sequence in s.Value.Nodes)
|
||||
cursors.Add(sequence.Key);
|
||||
|
||||
|
||||
@@ -66,15 +66,15 @@ namespace OpenRA
|
||||
ObjectCreator = objectCreator;
|
||||
Title = yaml.Value;
|
||||
|
||||
var type = yaml.Nodes.FirstOrDefault(n => n.Key == "Type");
|
||||
var type = yaml.NodeWithKeyOrDefault("Type");
|
||||
if (type != null)
|
||||
Type = type.Value;
|
||||
|
||||
var idFiles = yaml.Nodes.FirstOrDefault(n => n.Key == "IDFiles");
|
||||
var idFiles = yaml.NodeWithKeyOrDefault("IDFiles");
|
||||
if (idFiles != null)
|
||||
IDFiles = idFiles.Value;
|
||||
|
||||
var installNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Install");
|
||||
var installNode = yaml.NodeWithKeyOrDefault("Install");
|
||||
if (installNode != null)
|
||||
Install = installNode.Value.Nodes;
|
||||
|
||||
@@ -111,7 +111,7 @@ namespace OpenRA
|
||||
static object LoadPackages(MiniYaml yaml)
|
||||
{
|
||||
var packages = new Dictionary<string, ModPackage>();
|
||||
var packageNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Packages");
|
||||
var packageNode = yaml.NodeWithKeyOrDefault("Packages");
|
||||
if (packageNode != null)
|
||||
foreach (var node in packageNode.Value.Nodes)
|
||||
packages.Add(node.Key, new ModPackage(node.Value));
|
||||
@@ -124,7 +124,7 @@ namespace OpenRA
|
||||
|
||||
static object LoadDownloads(MiniYaml yaml)
|
||||
{
|
||||
var downloadNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Downloads");
|
||||
var downloadNode = yaml.NodeWithKeyOrDefault("Downloads");
|
||||
return downloadNode != null ? downloadNode.Value.Nodes.Select(n => n.Key).ToArray() : Array.Empty<string>();
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ namespace OpenRA
|
||||
|
||||
static object LoadSources(MiniYaml yaml)
|
||||
{
|
||||
var sourceNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Sources");
|
||||
var sourceNode = yaml.NodeWithKeyOrDefault("Sources");
|
||||
return sourceNode != null ? sourceNode.Value.Nodes.Select(n => n.Key).ToArray() : Array.Empty<string>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace OpenRA.Mods.Common.Terrain
|
||||
{
|
||||
FieldLoader.Load(this, my);
|
||||
|
||||
var nodes = my.ToDictionary()["Tiles"].Nodes;
|
||||
var nodes = my.NodeWithKey("Tiles").Value.Nodes;
|
||||
|
||||
if (!PickAny)
|
||||
{
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
else
|
||||
{
|
||||
var owner = map.PlayerDefinitions.Single(p => s.Get<OwnerInit>().InternalName == p.Value.Nodes.Last(k => k.Key == "Name").Value.Value);
|
||||
var colorValue = owner.Value.Nodes.FirstOrDefault(n => n.Key == "Color");
|
||||
var colorValue = owner.Value.NodeWithKeyOrDefault("Color");
|
||||
var ownerColor = colorValue?.Value.Value ?? "FFFFFF";
|
||||
Color.TryParse(ownerColor, out color);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
|
||||
@@ -326,16 +325,16 @@ namespace OpenRA.Mods.Common.Traits
|
||||
};
|
||||
}
|
||||
|
||||
void IGameSaveTraitData.ResolveTraitData(Actor self, ImmutableArray<MiniYamlNode> data)
|
||||
void IGameSaveTraitData.ResolveTraitData(Actor self, MiniYaml data)
|
||||
{
|
||||
if (self.World.IsReplay)
|
||||
return;
|
||||
|
||||
var initialBaseCenterNode = data.FirstOrDefault(n => n.Key == "InitialBaseCenter");
|
||||
var initialBaseCenterNode = data.NodeWithKeyOrDefault("InitialBaseCenter");
|
||||
if (initialBaseCenterNode != null)
|
||||
initialBaseCenter = FieldLoader.GetValue<CPos>("InitialBaseCenter", initialBaseCenterNode.Value.Value);
|
||||
|
||||
var defenseCenterNode = data.FirstOrDefault(n => n.Key == "DefenseCenter");
|
||||
var defenseCenterNode = data.NodeWithKeyOrDefault("DefenseCenter");
|
||||
if (defenseCenterNode != null)
|
||||
DefenseCenter = FieldLoader.GetValue<CPos>("DefenseCenter", defenseCenterNode.Value.Value);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
|
||||
@@ -213,12 +212,12 @@ namespace OpenRA.Mods.Common.Traits
|
||||
};
|
||||
}
|
||||
|
||||
void IGameSaveTraitData.ResolveTraitData(Actor self, ImmutableArray<MiniYamlNode> data)
|
||||
void IGameSaveTraitData.ResolveTraitData(Actor self, MiniYaml data)
|
||||
{
|
||||
if (self.World.IsReplay)
|
||||
return;
|
||||
|
||||
var initialBaseCenterNode = data.FirstOrDefault(n => n.Key == "InitialBaseCenter");
|
||||
var initialBaseCenterNode = data.NodeWithKeyOrDefault("InitialBaseCenter");
|
||||
if (initialBaseCenterNode != null)
|
||||
initialBaseCenter = FieldLoader.GetValue<CPos>("InitialBaseCenter", initialBaseCenterNode.Value.Value);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.Common.Traits.BotModules.Squads;
|
||||
using OpenRA.Primitives;
|
||||
@@ -526,52 +525,46 @@ namespace OpenRA.Mods.Common.Traits
|
||||
};
|
||||
}
|
||||
|
||||
void IGameSaveTraitData.ResolveTraitData(Actor self, ImmutableArray<MiniYamlNode> data)
|
||||
void IGameSaveTraitData.ResolveTraitData(Actor self, MiniYaml data)
|
||||
{
|
||||
if (self.World.IsReplay)
|
||||
return;
|
||||
|
||||
var initialBaseCenterNode = data.FirstOrDefault(n => n.Key == "InitialBaseCenter");
|
||||
if (initialBaseCenterNode != null)
|
||||
initialBaseCenter = FieldLoader.GetValue<CPos>("InitialBaseCenter", initialBaseCenterNode.Value.Value);
|
||||
var nodes = data.ToDictionary();
|
||||
|
||||
var unitsHangingAroundTheBaseNode = data.FirstOrDefault(n => n.Key == "UnitsHangingAroundTheBase");
|
||||
if (unitsHangingAroundTheBaseNode != null)
|
||||
if (nodes.TryGetValue("InitialBaseCenter", out var initialBaseCenterNode))
|
||||
initialBaseCenter = FieldLoader.GetValue<CPos>("InitialBaseCenter", initialBaseCenterNode.Value);
|
||||
|
||||
if (nodes.TryGetValue("UnitsHangingAroundTheBase", out var unitsHangingAroundTheBaseNode))
|
||||
{
|
||||
unitsHangingAroundTheBase.Clear();
|
||||
unitsHangingAroundTheBase.AddRange(FieldLoader.GetValue<uint[]>("UnitsHangingAroundTheBase", unitsHangingAroundTheBaseNode.Value.Value)
|
||||
unitsHangingAroundTheBase.AddRange(FieldLoader.GetValue<uint[]>("UnitsHangingAroundTheBase", unitsHangingAroundTheBaseNode.Value)
|
||||
.Select(a => self.World.GetActorById(a)).Where(a => a != null));
|
||||
}
|
||||
|
||||
var activeUnitsNode = data.FirstOrDefault(n => n.Key == "ActiveUnits");
|
||||
if (activeUnitsNode != null)
|
||||
if (nodes.TryGetValue("ActiveUnits", out var activeUnitsNode))
|
||||
{
|
||||
activeUnits.Clear();
|
||||
activeUnits.UnionWith(FieldLoader.GetValue<uint[]>("ActiveUnits", activeUnitsNode.Value.Value)
|
||||
activeUnits.UnionWith(FieldLoader.GetValue<uint[]>("ActiveUnits", activeUnitsNode.Value)
|
||||
.Select(a => self.World.GetActorById(a)).Where(a => a != null));
|
||||
}
|
||||
|
||||
var rushTicksNode = data.FirstOrDefault(n => n.Key == "RushTicks");
|
||||
if (rushTicksNode != null)
|
||||
rushTicks = FieldLoader.GetValue<int>("RushTicks", rushTicksNode.Value.Value);
|
||||
if (nodes.TryGetValue("RushTicks", out var rushTicksNode))
|
||||
rushTicks = FieldLoader.GetValue<int>("RushTicks", rushTicksNode.Value);
|
||||
|
||||
var assignRolesTicksNode = data.FirstOrDefault(n => n.Key == "AssignRolesTicks");
|
||||
if (assignRolesTicksNode != null)
|
||||
assignRolesTicks = FieldLoader.GetValue<int>("AssignRolesTicks", assignRolesTicksNode.Value.Value);
|
||||
if (nodes.TryGetValue("AssignRolesTicks", out var assignRolesTicksNode))
|
||||
assignRolesTicks = FieldLoader.GetValue<int>("AssignRolesTicks", assignRolesTicksNode.Value);
|
||||
|
||||
var attackForceTicksNode = data.FirstOrDefault(n => n.Key == "AttackForceTicks");
|
||||
if (attackForceTicksNode != null)
|
||||
attackForceTicks = FieldLoader.GetValue<int>("AttackForceTicks", attackForceTicksNode.Value.Value);
|
||||
if (nodes.TryGetValue("AttackForceTicks", out var attackForceTicksNode))
|
||||
attackForceTicks = FieldLoader.GetValue<int>("AttackForceTicks", attackForceTicksNode.Value);
|
||||
|
||||
var minAttackForceDelayTicksNode = data.FirstOrDefault(n => n.Key == "MinAttackForceDelayTicks");
|
||||
if (minAttackForceDelayTicksNode != null)
|
||||
minAttackForceDelayTicks = FieldLoader.GetValue<int>("MinAttackForceDelayTicks", minAttackForceDelayTicksNode.Value.Value);
|
||||
if (nodes.TryGetValue("MinAttackForceDelayTicks", out var minAttackForceDelayTicksNode))
|
||||
minAttackForceDelayTicks = FieldLoader.GetValue<int>("MinAttackForceDelayTicks", minAttackForceDelayTicksNode.Value);
|
||||
|
||||
var squadsNode = data.FirstOrDefault(n => n.Key == "Squads");
|
||||
if (squadsNode != null)
|
||||
if (nodes.TryGetValue("Squads", out var squadsNode))
|
||||
{
|
||||
Squads.Clear();
|
||||
foreach (var n in squadsNode.Value.Nodes)
|
||||
foreach (var n in squadsNode.Nodes)
|
||||
Squads.Add(Squad.Deserialize(bot, this, n.Value));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,12 +155,12 @@ namespace OpenRA.Mods.Common.Traits.BotModules.Squads
|
||||
var type = SquadType.Rush;
|
||||
var target = ((Actor)null, WVec.Zero);
|
||||
|
||||
var typeNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Type");
|
||||
var typeNode = yaml.NodeWithKeyOrDefault("Type");
|
||||
if (typeNode != null)
|
||||
type = FieldLoader.GetValue<SquadType>("Type", typeNode.Value.Value);
|
||||
|
||||
var actorToTargetNode = yaml.Nodes.FirstOrDefault(n => n.Key == "ActorToTarget");
|
||||
var targetOffsetNode = yaml.Nodes.FirstOrDefault(n => n.Key == "TargetOffset");
|
||||
var actorToTargetNode = yaml.NodeWithKeyOrDefault("ActorToTarget");
|
||||
var targetOffsetNode = yaml.NodeWithKeyOrDefault("TargetOffset");
|
||||
if (actorToTargetNode != null && targetOffsetNode != null)
|
||||
{
|
||||
var actorToTarget = squadManager.World.GetActorById(FieldLoader.GetValue<uint>("ActorToTarget", actorToTargetNode.Value.Value));
|
||||
@@ -170,7 +170,7 @@ namespace OpenRA.Mods.Common.Traits.BotModules.Squads
|
||||
|
||||
var squad = new Squad(bot, squadManager, type, target);
|
||||
|
||||
var unitsNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Units");
|
||||
var unitsNode = yaml.NodeWithKeyOrDefault("Units");
|
||||
if (unitsNode != null)
|
||||
squad.Units.UnionWith(FieldLoader.GetValue<uint[]>("Units", unitsNode.Value.Value)
|
||||
.Select(a => squadManager.World.GetActorById(a)));
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
|
||||
@@ -27,7 +26,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
static object LoadDecisions(MiniYaml yaml)
|
||||
{
|
||||
var ret = new List<SupportPowerDecision>();
|
||||
var decisions = yaml.Nodes.FirstOrDefault(n => n.Key == "Decisions");
|
||||
var decisions = yaml.NodeWithKeyOrDefault("Decisions");
|
||||
if (decisions != null)
|
||||
foreach (var d in decisions.Value.Nodes)
|
||||
ret.Add(new SupportPowerDecision(d.Value));
|
||||
@@ -224,12 +223,12 @@ namespace OpenRA.Mods.Common.Traits
|
||||
};
|
||||
}
|
||||
|
||||
void IGameSaveTraitData.ResolveTraitData(Actor self, ImmutableArray<MiniYamlNode> data)
|
||||
void IGameSaveTraitData.ResolveTraitData(Actor self, MiniYaml data)
|
||||
{
|
||||
if (self.World.IsReplay)
|
||||
return;
|
||||
|
||||
var waitingPowersNode = data.FirstOrDefault(n => n.Key == "WaitingPowers");
|
||||
var waitingPowersNode = data.NodeWithKeyOrDefault("WaitingPowers");
|
||||
if (waitingPowersNode != null)
|
||||
{
|
||||
foreach (var n in waitingPowersNode.Value.Nodes)
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
|
||||
@@ -234,19 +233,19 @@ namespace OpenRA.Mods.Common.Traits
|
||||
};
|
||||
}
|
||||
|
||||
void IGameSaveTraitData.ResolveTraitData(Actor self, ImmutableArray<MiniYamlNode> data)
|
||||
void IGameSaveTraitData.ResolveTraitData(Actor self, MiniYaml data)
|
||||
{
|
||||
if (self.World.IsReplay)
|
||||
return;
|
||||
|
||||
var queuedBuildRequestsNode = data.FirstOrDefault(n => n.Key == "QueuedBuildRequests");
|
||||
var queuedBuildRequestsNode = data.NodeWithKeyOrDefault("QueuedBuildRequests");
|
||||
if (queuedBuildRequestsNode != null)
|
||||
{
|
||||
queuedBuildRequests.Clear();
|
||||
queuedBuildRequests.AddRange(FieldLoader.GetValue<string[]>("QueuedBuildRequests", queuedBuildRequestsNode.Value.Value));
|
||||
}
|
||||
|
||||
var idleUnitCountNode = data.FirstOrDefault(n => n.Key == "IdleUnitCount");
|
||||
var idleUnitCountNode = data.NodeWithKeyOrDefault("IdleUnitCount");
|
||||
if (idleUnitCountNode != null)
|
||||
idleUnitCount = FieldLoader.GetValue<int>("IdleUnitCount", idleUnitCountNode.Value.Value);
|
||||
}
|
||||
|
||||
@@ -64,10 +64,10 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
protected static object LoadFootprint(MiniYaml yaml)
|
||||
{
|
||||
var footprintYaml = yaml.Nodes.FirstOrDefault(n => n.Key == "Footprint");
|
||||
var footprintYaml = yaml.NodeWithKeyOrDefault("Footprint");
|
||||
var footprintChars = footprintYaml?.Value.Value.Where(x => !char.IsWhiteSpace(x)).ToArray() ?? new[] { 'x' };
|
||||
|
||||
var dimensionsYaml = yaml.Nodes.FirstOrDefault(n => n.Key == "Dimensions");
|
||||
var dimensionsYaml = yaml.NodeWithKeyOrDefault("Dimensions");
|
||||
var dim = dimensionsYaml != null ? FieldLoader.GetValue<CVec>("Dimensions", dimensionsYaml.Value.Value) : new CVec(1, 1);
|
||||
|
||||
if (footprintChars.Length != dim.X * dim.Y)
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
IHitShape ret;
|
||||
|
||||
var shapeNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Type");
|
||||
var shapeNode = yaml.NodeWithKeyOrDefault("Type");
|
||||
var shape = shapeNode != null ? shapeNode.Value.Value : string.Empty;
|
||||
|
||||
if (!string.IsNullOrEmpty(shape))
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Traits;
|
||||
@@ -50,13 +49,13 @@ namespace OpenRA.Mods.Common.Traits
|
||||
return nodes;
|
||||
}
|
||||
|
||||
void IGameSaveTraitData.ResolveTraitData(Actor self, ImmutableArray<MiniYamlNode> data)
|
||||
void IGameSaveTraitData.ResolveTraitData(Actor self, MiniYaml data)
|
||||
{
|
||||
var viewportNode = data.FirstOrDefault(n => n.Key == "Viewport");
|
||||
var viewportNode = data.NodeWithKeyOrDefault("Viewport");
|
||||
if (viewportNode != null)
|
||||
worldRenderer.Viewport.Center(FieldLoader.GetValue<WPos>("Viewport", viewportNode.Value.Value));
|
||||
|
||||
var renderPlayerNode = data.FirstOrDefault(n => n.Key == "RenderPlayer");
|
||||
var renderPlayerNode = data.NodeWithKeyOrDefault("RenderPlayer");
|
||||
if (renderPlayerNode != null)
|
||||
{
|
||||
var renderPlayerActorID = FieldLoader.GetValue<uint>("RenderPlayer", renderPlayerNode.Value.Value);
|
||||
|
||||
@@ -133,9 +133,9 @@ namespace OpenRA.Mods.Common.Traits
|
||||
};
|
||||
}
|
||||
|
||||
void IGameSaveTraitData.ResolveTraitData(Actor self, ImmutableArray<MiniYamlNode> data)
|
||||
void IGameSaveTraitData.ResolveTraitData(Actor self, MiniYaml data)
|
||||
{
|
||||
var groupsNode = data.FirstOrDefault(n => n.Key == "Groups");
|
||||
var groupsNode = data.NodeWithKeyOrDefault("Groups");
|
||||
if (groupsNode != null)
|
||||
{
|
||||
foreach (var n in groupsNode.Value.Nodes)
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
protected static object LoadResourceTypes(MiniYaml yaml)
|
||||
{
|
||||
var ret = new Dictionary<string, ResourceLayerInfo.ResourceTypeInfo>();
|
||||
var resources = yaml.Nodes.FirstOrDefault(n => n.Key == "ResourceTypes");
|
||||
var resources = yaml.NodeWithKeyOrDefault("ResourceTypes");
|
||||
if (resources != null)
|
||||
foreach (var r in resources.Value.Nodes)
|
||||
ret[r.Key] = new ResourceLayerInfo.ResourceTypeInfo(r.Value);
|
||||
|
||||
@@ -84,16 +84,16 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
protected static object LoadSpeeds(MiniYaml y)
|
||||
{
|
||||
var speeds = y.ToDictionary()["TerrainSpeeds"].Nodes;
|
||||
var speeds = y.NodeWithKey("TerrainSpeeds").Value.Nodes;
|
||||
var ret = new Dictionary<string, TerrainInfo>(speeds.Length);
|
||||
foreach (var t in speeds)
|
||||
{
|
||||
var speed = FieldLoader.GetValue<int>("speed", t.Value.Value);
|
||||
if (speed > 0)
|
||||
{
|
||||
var nodesDict = t.Value.ToDictionary();
|
||||
var cost = nodesDict.TryGetValue("PathingCost", out var entry)
|
||||
? FieldLoader.GetValue<short>("cost", entry.Value)
|
||||
var pathingCost = t.Value.NodeWithKeyOrDefault("PathingCost");
|
||||
var cost = pathingCost != null
|
||||
? FieldLoader.GetValue<short>("cost", pathingCost.Value.Value)
|
||||
: 10000 / speed;
|
||||
ret.Add(t.Key, new TerrainInfo(speed, (short)cost));
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
protected static object LoadResourceTypes(MiniYaml yaml)
|
||||
{
|
||||
var ret = new Dictionary<string, ResourceTypeInfo>();
|
||||
var resources = yaml.Nodes.FirstOrDefault(n => n.Key == "ResourceTypes");
|
||||
var resources = yaml.NodeWithKeyOrDefault("ResourceTypes");
|
||||
if (resources != null)
|
||||
foreach (var r in resources.Value.Nodes)
|
||||
ret[r.Key] = new ResourceTypeInfo(r.Value);
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
protected static object LoadResourceTypes(MiniYaml yaml)
|
||||
{
|
||||
var ret = new Dictionary<string, ResourceTypeInfo>();
|
||||
var resources = yaml.Nodes.FirstOrDefault(n => n.Key == "ResourceTypes");
|
||||
var resources = yaml.NodeWithKeyOrDefault("ResourceTypes");
|
||||
if (resources != null)
|
||||
foreach (var r in resources.Value.Nodes)
|
||||
ret[r.Key] = new ResourceTypeInfo(r.Value);
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
|
||||
@@ -186,9 +185,9 @@ namespace OpenRA.Mods.Common.Traits
|
||||
};
|
||||
}
|
||||
|
||||
void IGameSaveTraitData.ResolveTraitData(Actor self, ImmutableArray<MiniYamlNode> data)
|
||||
void IGameSaveTraitData.ResolveTraitData(Actor self, MiniYaml data)
|
||||
{
|
||||
var selectionNode = data.FirstOrDefault(n => n.Key == "Selection");
|
||||
var selectionNode = data.NodeWithKeyOrDefault("Selection");
|
||||
if (selectionNode != null)
|
||||
{
|
||||
var selected = FieldLoader.GetValue<uint[]>("Selection", selectionNode.Value.Value)
|
||||
|
||||
@@ -56,11 +56,11 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public static object LoadInitialSmudges(MiniYaml yaml)
|
||||
{
|
||||
var nd = yaml.ToDictionary();
|
||||
var smudges = new Dictionary<CPos, MapSmudge>();
|
||||
if (nd.TryGetValue("InitialSmudges", out var smudgeYaml))
|
||||
var smudgeYaml = yaml.NodeWithKeyOrDefault("InitialSmudges");
|
||||
if (smudgeYaml != null)
|
||||
{
|
||||
foreach (var node in smudgeYaml.Nodes)
|
||||
foreach (var node in smudgeYaml.Value.Nodes)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -230,7 +230,7 @@ namespace OpenRA.Mods.Common.UpdateRules.Rules
|
||||
if (!string.IsNullOrEmpty(sequenceNode.Value.Value))
|
||||
explicitlyNamedSequences.Add(sequenceNode.Key);
|
||||
|
||||
var resolvedSequenceNode = resolvedImageNode.Value.Nodes.SingleOrDefault(n => n.Key == sequenceNode.Key);
|
||||
var resolvedSequenceNode = resolvedImageNode.Value.NodeWithKeyOrDefault(sequenceNode.Key);
|
||||
if (resolvedSequenceNode == null)
|
||||
continue;
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ namespace OpenRA.Mods.Common.UpdateRules
|
||||
|
||||
manualSteps.AddRange(rule.BeforeUpdate(modData));
|
||||
|
||||
var mapActorsNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Actors");
|
||||
var mapActorsNode = yaml.NodeWithKeyOrDefault("Actors");
|
||||
if (mapActorsNode != null)
|
||||
{
|
||||
var mapActors = new YamlFileSet()
|
||||
@@ -111,7 +111,7 @@ namespace OpenRA.Mods.Common.UpdateRules
|
||||
files.AddRange(mapActors);
|
||||
}
|
||||
|
||||
var mapRulesNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Rules");
|
||||
var mapRulesNode = yaml.NodeWithKeyOrDefault("Rules");
|
||||
if (mapRulesNode != null)
|
||||
{
|
||||
if (rule is IBeforeUpdateActors before)
|
||||
@@ -125,7 +125,7 @@ namespace OpenRA.Mods.Common.UpdateRules
|
||||
files.AddRange(mapRules);
|
||||
}
|
||||
|
||||
var mapWeaponsNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Weapons");
|
||||
var mapWeaponsNode = yaml.NodeWithKeyOrDefault("Weapons");
|
||||
if (mapWeaponsNode != null)
|
||||
{
|
||||
if (rule is IBeforeUpdateWeapons before)
|
||||
@@ -139,7 +139,7 @@ namespace OpenRA.Mods.Common.UpdateRules
|
||||
files.AddRange(mapWeapons);
|
||||
}
|
||||
|
||||
var mapSequencesNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Sequences");
|
||||
var mapSequencesNode = yaml.NodeWithKeyOrDefault("Sequences");
|
||||
if (mapSequencesNode != null)
|
||||
{
|
||||
if (rule is IBeforeUpdateSequences before)
|
||||
@@ -216,19 +216,19 @@ namespace OpenRA.Mods.Common.UpdateRules
|
||||
continue;
|
||||
|
||||
var yaml = new MiniYamlBuilder(new MiniYaml(null, MiniYaml.FromStream(mapStream, package.Name, false)));
|
||||
var mapRulesNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Rules");
|
||||
var mapRulesNode = yaml.NodeWithKeyOrDefault("Rules");
|
||||
if (mapRulesNode != null)
|
||||
foreach (var f in LoadExternalMapYaml(modData, mapRulesNode.Value, externalFilenames))
|
||||
if (!modRules.Any(m => m.Item1 == f.Item1 && m.Item2 == f.Item2))
|
||||
modRules.Add(f);
|
||||
|
||||
var mapWeaponsNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Weapons");
|
||||
var mapWeaponsNode = yaml.NodeWithKeyOrDefault("Weapons");
|
||||
if (mapWeaponsNode != null)
|
||||
foreach (var f in LoadExternalMapYaml(modData, mapWeaponsNode.Value, externalFilenames))
|
||||
if (!modWeapons.Any(m => m.Item1 == f.Item1 && m.Item2 == f.Item2))
|
||||
modWeapons.Add(f);
|
||||
|
||||
var mapSequencesNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Sequences");
|
||||
var mapSequencesNode = yaml.NodeWithKeyOrDefault("Sequences");
|
||||
if (mapSequencesNode != null)
|
||||
foreach (var f in LoadExternalMapYaml(modData, mapSequencesNode.Value, externalFilenames))
|
||||
if (!modSequences.Any(m => m.Item1 == f.Item1 && m.Item2 == f.Item2))
|
||||
@@ -285,7 +285,7 @@ namespace OpenRA.Mods.Common.UpdateRules
|
||||
foreach (var manualStep in transform(modData, current))
|
||||
yield return manualStep;
|
||||
|
||||
var childrenNode = current.Value.Nodes.FirstOrDefault(n => n.Key == "Children");
|
||||
var childrenNode = current.Value.NodeWithKeyOrDefault("Children");
|
||||
if (childrenNode != null)
|
||||
foreach (var node in childrenNode.Value.Nodes)
|
||||
if (node.Key != null)
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Common.Lint;
|
||||
using OpenRA.Traits;
|
||||
@@ -47,27 +46,27 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
yield break;
|
||||
|
||||
var selectPrefix = "";
|
||||
var selectPrefixNode = widgetNode.Value.Nodes.FirstOrDefault(n => n.Key == "SelectGroupKeyPrefix");
|
||||
var selectPrefixNode = widgetNode.Value.NodeWithKeyOrDefault("SelectGroupKeyPrefix");
|
||||
if (selectPrefixNode != null)
|
||||
selectPrefix = selectPrefixNode.Value.Value;
|
||||
|
||||
var createPrefix = "";
|
||||
var createPrefixNode = widgetNode.Value.Nodes.FirstOrDefault(n => n.Key == "CreateGroupKeyPrefix");
|
||||
var createPrefixNode = widgetNode.Value.NodeWithKeyOrDefault("CreateGroupKeyPrefix");
|
||||
if (createPrefixNode != null)
|
||||
createPrefix = createPrefixNode.Value.Value;
|
||||
|
||||
var addToPrefix = "";
|
||||
var addToPrefixNode = widgetNode.Value.Nodes.FirstOrDefault(n => n.Key == "AddToGroupKeyPrefix");
|
||||
var addToPrefixNode = widgetNode.Value.NodeWithKeyOrDefault("AddToGroupKeyPrefix");
|
||||
if (addToPrefixNode != null)
|
||||
addToPrefix = addToPrefixNode.Value.Value;
|
||||
|
||||
var combineWithPrefix = "";
|
||||
var combineWithPrefixNode = widgetNode.Value.Nodes.FirstOrDefault(n => n.Key == "CombineWithGroupKeyPrefix");
|
||||
var combineWithPrefixNode = widgetNode.Value.NodeWithKeyOrDefault("CombineWithGroupKeyPrefix");
|
||||
if (combineWithPrefixNode != null)
|
||||
combineWithPrefix = combineWithPrefixNode.Value.Value;
|
||||
|
||||
var jumpToPrefix = "";
|
||||
var jumpToPrefixNode = widgetNode.Value.Nodes.FirstOrDefault(n => n.Key == "JumpToGroupKeyPrefix");
|
||||
var jumpToPrefixNode = widgetNode.Value.NodeWithKeyOrDefault("JumpToGroupKeyPrefix");
|
||||
if (jumpToPrefixNode != null)
|
||||
jumpToPrefix = jumpToPrefixNode.Value.Value;
|
||||
|
||||
|
||||
@@ -246,7 +246,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
{
|
||||
void RunSourceActions(MiniYamlNode contentPackageYaml)
|
||||
{
|
||||
var sourceActionListYaml = contentPackageYaml.Value.Nodes.FirstOrDefault(x => x.Key == "Actions");
|
||||
var sourceActionListYaml = contentPackageYaml.Value.NodeWithKeyOrDefault("Actions");
|
||||
if (sourceActionListYaml == null)
|
||||
return;
|
||||
|
||||
@@ -263,7 +263,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
|
||||
foreach (var packageInstallationNode in modSource.Install.Where(x => x.Key == "ContentPackage"))
|
||||
{
|
||||
var packageName = packageInstallationNode.Value.Nodes.SingleOrDefault(x => x.Key == "Name")?.Value.Value;
|
||||
var packageName = packageInstallationNode.Value.NodeWithKeyOrDefault("Name")?.Value.Value;
|
||||
if (!string.IsNullOrEmpty(packageName) && selectedPackages.TryGetValue(packageName, out var required) && required)
|
||||
RunSourceActions(packageInstallationNode);
|
||||
}
|
||||
@@ -338,9 +338,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
checkboxWidget.OnClick = () => selectedPackages[package.Identifier] = !selectedPackages[package.Identifier];
|
||||
|
||||
var contentPackageNode = source.Install.FirstOrDefault(x =>
|
||||
x.Value.Nodes.FirstOrDefault(y => y.Key == "Name")?.Value.Value == package.Identifier);
|
||||
x.Value.NodeWithKeyOrDefault("Name")?.Value.Value == package.Identifier);
|
||||
|
||||
var tooltipText = contentPackageNode?.Value.Nodes.FirstOrDefault(x => x.Key == nameof(ModContent.ModSource.TooltipText))?.Value.Value;
|
||||
var tooltipText = contentPackageNode?.Value.NodeWithKeyOrDefault(nameof(ModContent.ModSource.TooltipText))?.Value.Value;
|
||||
var tooltipIcon = containerWidget.Get<ImageWidget>("PACKAGE_INFO");
|
||||
tooltipIcon.IsVisible = () => !string.IsNullOrWhiteSpace(tooltipText);
|
||||
tooltipIcon.GetTooltipText = () => tooltipText;
|
||||
|
||||
@@ -487,7 +487,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
continue;
|
||||
|
||||
var game = new MiniYamlBuilder(MiniYaml.FromString(bl.Data)[0].Value);
|
||||
var idNode = game.Nodes.FirstOrDefault(n => n.Key == "Id");
|
||||
var idNode = game.NodeWithKeyOrDefault("Id");
|
||||
|
||||
// Skip beacons created by this instance and replace Id by expected int value
|
||||
if (idNode != null && idNode.Value.Value != Platform.SessionGUID.ToString())
|
||||
@@ -495,7 +495,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
idNode.Value.Value = "-1";
|
||||
|
||||
// Rewrite the server address with the correct IP
|
||||
var addressNode = game.Nodes.FirstOrDefault(n => n.Key == "Address");
|
||||
var addressNode = game.NodeWithKeyOrDefault("Address");
|
||||
if (addressNode != null)
|
||||
addressNode.Value.Value = bl.Address.ToString().Split(':')[0] + ":" + addressNode.Value.Value.Split(':')[1];
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
{
|
||||
foreach (var hg in hotkeyGroupsYaml.Nodes)
|
||||
{
|
||||
var typesNode = hg.Value.Nodes.FirstOrDefault(n => n.Key == "Types");
|
||||
var typesNode = hg.Value.NodeWithKeyOrDefault("Types");
|
||||
if (typesNode != null)
|
||||
hotkeyGroups.Add(hg.Key, FieldLoader.GetValue<HashSet<string>>("Types", typesNode.Value.Value));
|
||||
}
|
||||
|
||||
@@ -132,12 +132,12 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
public static IEnumerable<string> LinterHotkeyNames(MiniYamlNode widgetNode, Action<string> emitError)
|
||||
{
|
||||
var prefix = "";
|
||||
var prefixNode = widgetNode.Value.Nodes.FirstOrDefault(n => n.Key == "HotkeyPrefix");
|
||||
var prefixNode = widgetNode.Value.NodeWithKeyOrDefault("HotkeyPrefix");
|
||||
if (prefixNode != null)
|
||||
prefix = prefixNode.Value.Value;
|
||||
|
||||
var count = 0;
|
||||
var countNode = widgetNode.Value.Nodes.FirstOrDefault(n => n.Key == "HotkeyCount");
|
||||
var countNode = widgetNode.Value.NodeWithKeyOrDefault("HotkeyCount");
|
||||
if (countNode != null)
|
||||
count = FieldLoader.GetValue<int>("HotkeyCount", countNode.Value.Value);
|
||||
|
||||
|
||||
@@ -70,12 +70,12 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
public static IEnumerable<string> LinterHotkeyNames(MiniYamlNode widgetNode, Action<string> emitError)
|
||||
{
|
||||
var prefix = "";
|
||||
var prefixNode = widgetNode.Value.Nodes.FirstOrDefault(n => n.Key == "HotkeyPrefix");
|
||||
var prefixNode = widgetNode.Value.NodeWithKeyOrDefault("HotkeyPrefix");
|
||||
if (prefixNode != null)
|
||||
prefix = prefixNode.Value.Value;
|
||||
|
||||
var count = 0;
|
||||
var countNode = widgetNode.Value.Nodes.FirstOrDefault(n => n.Key == "HotkeyCount");
|
||||
var countNode = widgetNode.Value.NodeWithKeyOrDefault("HotkeyCount");
|
||||
if (countNode != null)
|
||||
count = FieldLoader.GetValue<int>("HotkeyCount", countNode.Value.Value);
|
||||
|
||||
|
||||
@@ -105,17 +105,17 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
public static IEnumerable<string> LinterHotkeyNames(MiniYamlNode widgetNode, Action<string> emitError)
|
||||
{
|
||||
var savePrefix = "";
|
||||
var savePrefixNode = widgetNode.Value.Nodes.FirstOrDefault(n => n.Key == "BookmarkSaveKeyPrefix");
|
||||
var savePrefixNode = widgetNode.Value.NodeWithKeyOrDefault("BookmarkSaveKeyPrefix");
|
||||
if (savePrefixNode != null)
|
||||
savePrefix = savePrefixNode.Value.Value;
|
||||
|
||||
var restorePrefix = "";
|
||||
var restorePrefixNode = widgetNode.Value.Nodes.FirstOrDefault(n => n.Key == "BookmarkRestoreKeyPrefix");
|
||||
var restorePrefixNode = widgetNode.Value.NodeWithKeyOrDefault("BookmarkRestoreKeyPrefix");
|
||||
if (restorePrefixNode != null)
|
||||
restorePrefix = restorePrefixNode.Value.Value;
|
||||
|
||||
var count = 0;
|
||||
var countNode = widgetNode.Value.Nodes.FirstOrDefault(n => n.Key == "BookmarkKeyCount");
|
||||
var countNode = widgetNode.Value.NodeWithKeyOrDefault("BookmarkKeyCount");
|
||||
if (countNode != null)
|
||||
count = FieldLoader.GetValue<int>("BookmarkKeyCount", countNode.Value.Value);
|
||||
|
||||
|
||||
@@ -384,7 +384,7 @@ namespace OpenRA.Mods.D2k.UtilityCommands
|
||||
actorNodes.Add(new MiniYamlNode("Actor" + (map.ActorDefinitions.Count + actorNodes.Count), a.Save()));
|
||||
|
||||
if (map.PlayerDefinitions.Concat(playerNodes).All(
|
||||
x => x.Value.Nodes.Single(y => y.Key == "Name").Value.Value != kvp.Owner))
|
||||
x => x.Value.NodeWithKey("Name").Value.Value != kvp.Owner))
|
||||
{
|
||||
var playerInfo = PlayerReferenceDataByPlayerName[kvp.Owner];
|
||||
var playerReference = new PlayerReference
|
||||
|
||||
@@ -247,7 +247,7 @@ Test:
|
||||
.First(n => n.Key == "Test").Value.Nodes;
|
||||
|
||||
Assert.IsTrue(result.Any(n => n.Key == "MockString"), "Node should have the MockString child, but does not.");
|
||||
Assert.IsTrue(result.First(n => n.Key == "MockString").Value.ToDictionary()["AString"].Value == "Override",
|
||||
Assert.IsTrue(result.First(n => n.Key == "MockString").Value.NodeWithKey("AString").Value.Value == "Override",
|
||||
"MockString value has not been set with the correct override value for AString.");
|
||||
}
|
||||
|
||||
@@ -272,7 +272,7 @@ Test:
|
||||
.First(n => n.Key == "Test").Value.Nodes;
|
||||
|
||||
Assert.IsTrue(result.Any(n => n.Key == "MockString"), "Node should have the MockString child, but does not.");
|
||||
Assert.IsTrue(result.First(n => n.Key == "MockString").Value.ToDictionary()["AString"].Value == "Override",
|
||||
Assert.IsTrue(result.First(n => n.Key == "MockString").Value.NodeWithKey("AString").Value.Value == "Override",
|
||||
"MockString value has not been set with the correct override value for AString.");
|
||||
}
|
||||
|
||||
|
||||
@@ -779,7 +779,6 @@ ctdam:
|
||||
damaged-idle-water-b:
|
||||
Filename: ctdam_b.shp
|
||||
Start: 24
|
||||
Start: 8
|
||||
Length: 8
|
||||
Tick: 200
|
||||
|
||||
|
||||
@@ -1667,7 +1667,6 @@ napuls.nod:
|
||||
ZOffset: 512
|
||||
BlendMode: Additive
|
||||
IgnoreWorldTint: True
|
||||
IgnoreWorldTint: True
|
||||
DepthSprite:
|
||||
icon:
|
||||
Filename: sidebar-nod|empicon.shp
|
||||
|
||||
Reference in New Issue
Block a user