/// <summary> /// /// </summary> /// <param name="fileSystem"></param> /// <param name="additionalSequences"></param> /// <returns></returns> Sequences Load(IReadOnlyFileSystem fileSystem, MiniYaml additionalSequences) { var nodes = MiniYaml.Load(fileSystem, modData.Manifest.Sequences, additionalSequences); var items = new Dictionary <string, UnitSequences>(); foreach (var n in nodes) { //Work around the loop closure issue in older versions of C# var node = n; var key = node.Value.ToLines(node.Key).JoinWith("|"); UnitSequences t; if (sequenceCache.TryGetValue(key, out t)) { items.Add(node.Key, t); } else { t = Exts.Lazy(() => modData.SpriteSequenceLoader.ParseSequences(modData, tileSet, SpriteCache, node)); sequenceCache.Add(key, t); items.Add(node.Key, t); } } return(new ReadOnlyDictionary <string, UnitSequences>(items)); }
/// <exception cref="ArgumentNullException">Thrown if manifestPropertySelector is null.</exception> public static MiniYamlNode GetTopLevelNodeByKey(ModData modData, string key, Func <Manifest, string[]> manifestPropertySelector, Func <Map, MiniYaml> mapPropertySelector = null, string mapPath = null) { if (manifestPropertySelector == null) { throw new ArgumentNullException("manifestPropertySelector", "Must pass a non-null manifestPropertySelector"); } Map map = null; if (mapPath != null) { try { map = new Map(modData, new Folder(".").OpenPackage(mapPath, modData.ModFiles)); } catch (InvalidDataException ex) { Console.WriteLine("Could not load map '{0}' so this data does not include the map's overrides.", mapPath); Console.WriteLine(ex); map = null; } } var manifestNodes = manifestPropertySelector.Invoke(modData.Manifest); var mapProperty = map == null || mapPropertySelector == null ? null : mapPropertySelector.Invoke(map); var fs = map ?? modData.DefaultFileSystem; var topLevelNodes = MiniYaml.Load(fs, manifestNodes, mapProperty); return(topLevelNodes.FirstOrDefault(n => n.Key == key)); }
Sequences Load(IReadOnlyFileSystem fileSystem, MiniYaml additionalSequences) { var nodes = MiniYaml.Load(fileSystem, modData.Manifest.Sequences, additionalSequences); var items = new Dictionary <string, UnitSequences>(); foreach (var node in nodes) { // Nodes starting with ^ are inheritable but never loaded directly if (node.Key.StartsWith(ActorInfo.AbstractActorPrefix, StringComparison.Ordinal)) { continue; } var key = node.Value.ToLines(node.Key).JoinWith("|"); if (sequenceCache.TryGetValue(key, out var t)) { items.Add(node.Key, t); } else { t = Exts.Lazy(() => modData.SpriteSequenceLoader.ParseSequences(modData, tileSet, SpriteCache, node)); sequenceCache.Add(key, t); items.Add(node.Key, t); } } return(items); }
void IUtilityCommand.Run(Utility utility, string[] args) { // HACK: The engine code assumes that Game.modData is set. var modData = Game.ModData = utility.ModData; var actorType = args[1]; string mapPath = null; Map map = null; if (args.Length == 3) { try { mapPath = args[2]; map = new Map(modData, modData.ModFiles.OpenPackage(mapPath, new Folder("."))); } catch (InvalidDataException) { Console.WriteLine("Could not load map '{0}'.", mapPath); Environment.Exit(2); } } var fs = map ?? modData.DefaultFileSystem; var topLevelNodes = MiniYaml.Load(fs, modData.Manifest.Rules, map == null ? null : map.RuleDefinitions); var result = topLevelNodes.FirstOrDefault(n => n.Key == actorType); if (result == null) { Console.WriteLine("Could not find actor '{0}' (name is case-sensitive).", actorType); Environment.Exit(1); } Console.WriteLine(result.Value.Nodes.WriteToString()); }
public void Run(Action <string> emitError, Action <string> emitWarning, ModData modData, Map map) { if (map.SequenceDefinitions == null) { return; } this.emitError = emitError; sequenceDefinitions = MiniYaml.Load(map, modData.Manifest.Sequences, map.SequenceDefinitions); var rules = map.Rules; var factions = rules.Actors["world"].TraitInfos <FactionInfo>().Select(f => f.InternalName).ToArray(); var sequenceProviders = new[] { rules.Sequences }; foreach (var actorInfo in rules.Actors) { foreach (var renderInfo in actorInfo.Value.TraitInfos <RenderSpritesInfo>()) { foreach (var faction in factions) { foreach (var sequenceProvider in sequenceProviders) { var image = renderInfo.GetImage(actorInfo.Value, sequenceProvider, faction); if (sequenceDefinitions.All(s => s.Key != image.ToLowerInvariant())) { emitError("Sprite image {0} from actor {1} using faction {2} has no sequence definition." .F(image, actorInfo.Value.Name, faction)); } } } } foreach (var traitInfo in actorInfo.Value.TraitInfos <ITraitInfo>()) { var fields = traitInfo.GetType().GetFields(); foreach (var field in fields) { if (field.HasAttribute <SequenceReferenceAttribute>()) { var sequences = LintExts.GetFieldValues(traitInfo, field, emitError); foreach (var sequence in sequences) { if (string.IsNullOrEmpty(sequence)) { continue; } var renderInfo = actorInfo.Value.TraitInfos <RenderSpritesInfo>().FirstOrDefault(); if (renderInfo == null) { continue; } foreach (var faction in factions) { var sequenceReference = field.GetCustomAttributes <SequenceReferenceAttribute>(true).FirstOrDefault(); if (sequenceReference != null && !string.IsNullOrEmpty(sequenceReference.ImageReference)) { var imageField = fields.FirstOrDefault(f => f.Name == sequenceReference.ImageReference); if (imageField != null) { foreach (var imageOverride in LintExts.GetFieldValues(traitInfo, imageField, emitError)) { if (string.IsNullOrEmpty(imageOverride)) { emitWarning("Custom sprite image of actor {0} is null.".F(actorInfo.Value.Name)); continue; } if (sequenceDefinitions.All(s => s.Key != imageOverride.ToLowerInvariant())) { emitError("Custom sprite image {0} from actor {1} has no sequence definition.".F(imageOverride, actorInfo.Value.Name)); } else { CheckDefinitions(imageOverride, sequenceReference, actorInfo, sequence, faction, field, traitInfo); } } } } else { foreach (var sequenceProvider in sequenceProviders) { var image = renderInfo.GetImage(actorInfo.Value, sequenceProvider, faction); CheckDefinitions(image, sequenceReference, actorInfo, sequence, faction, field, traitInfo); } } } } } } } foreach (var weaponInfo in rules.Weapons) { var projectileInfo = weaponInfo.Value.Projectile; if (projectileInfo == null) { continue; } var fields = projectileInfo.GetType().GetFields(); foreach (var field in fields) { if (field.HasAttribute <SequenceReferenceAttribute>()) { var sequences = LintExts.GetFieldValues(projectileInfo, field, emitError); foreach (var sequence in sequences) { if (string.IsNullOrEmpty(sequence)) { continue; } var sequenceReference = field.GetCustomAttributes <SequenceReferenceAttribute>(true).FirstOrDefault(); if (sequenceReference != null && !string.IsNullOrEmpty(sequenceReference.ImageReference)) { var imageField = fields.FirstOrDefault(f => f.Name == sequenceReference.ImageReference); if (imageField != null) { foreach (var imageOverride in LintExts.GetFieldValues(projectileInfo, imageField, emitError)) { if (!string.IsNullOrEmpty(imageOverride)) { var definitions = sequenceDefinitions.FirstOrDefault(n => n.Key == imageOverride.ToLowerInvariant()); if (definitions == null) { emitError("Can't find sequence definition for projectile image {0} at weapon {1}.".F(imageOverride, weaponInfo.Key)); } else if (!definitions.Value.Nodes.Any(n => n.Key == sequence)) { emitError("Projectile sprite image {0} from weapon {1} does not define sequence {2} from field {3} of {4}" .F(imageOverride, weaponInfo.Key, sequence, field.Name, projectileInfo)); } } } } } } } } } } }
public ModContentLogic(Widget widget, ModData modData, Manifest mod, ModContent content, Action onCancel) { this.content = content; var panel = widget.Get("CONTENT_PANEL"); var modObjectCreator = new ObjectCreator(mod, Game.Mods); var modPackageLoaders = modObjectCreator.GetLoaders <IPackageLoader>(mod.PackageFormats, "package"); var modFileSystem = new FS(Game.Mods, modPackageLoaders); modFileSystem.LoadFromManifest(mod); var sourceYaml = MiniYaml.Load(modFileSystem, content.Sources, null); foreach (var s in sourceYaml) { sources.Add(s.Key, new ModContent.ModSource(s.Value)); } var downloadYaml = MiniYaml.Load(modFileSystem, content.Downloads, null); foreach (var d in downloadYaml) { downloads.Add(d.Key, new ModContent.ModDownload(d.Value)); } modFileSystem.UnmountAll(); scrollPanel = panel.Get <ScrollPanelWidget>("PACKAGES"); template = scrollPanel.Get <ContainerWidget>("PACKAGE_TEMPLATE"); var headerTemplate = panel.Get <LabelWidget>("HEADER_TEMPLATE"); var headerLines = !string.IsNullOrEmpty(content.HeaderMessage) ? content.HeaderMessage.Replace("\\n", "\n").Split('\n') : new string[0]; var headerHeight = 0; foreach (var l in headerLines) { var line = (LabelWidget)headerTemplate.Clone(); line.GetText = () => l; line.Bounds.Y += headerHeight; panel.AddChild(line); headerHeight += headerTemplate.Bounds.Height; } panel.Bounds.Height += headerHeight; panel.Bounds.Y -= headerHeight / 2; scrollPanel.Bounds.Y += headerHeight; var discButton = panel.Get <ButtonWidget>("CHECK_DISC_BUTTON"); discButton.Bounds.Y += headerHeight; discButton.IsVisible = () => discAvailable; discButton.OnClick = () => Ui.OpenWindow("DISC_INSTALL_PANEL", new WidgetArgs { { "afterInstall", () => { } }, { "sources", sources }, { "content", content } }); var backButton = panel.Get <ButtonWidget>("BACK_BUTTON"); backButton.Bounds.Y += headerHeight; backButton.OnClick = () => { Ui.CloseWindow(); onCancel(); }; PopulateContentList(); Game.RunAfterTick(Ui.ResetTooltips); }
public ModContentPromptLogic(Widget widget, Manifest mod, ModContent content, Action continueLoading) { var panel = widget.Get("CONTENT_PROMPT_PANEL"); var headerTemplate = panel.Get <LabelWidget>("HEADER_TEMPLATE"); var headerLines = !string.IsNullOrEmpty(content.InstallPromptMessage) ? content.InstallPromptMessage.Replace("\\n", "\n").Split('\n') : new string[0]; var headerHeight = 0; foreach (var l in headerLines) { var line = (LabelWidget)headerTemplate.Clone(); line.GetText = () => l; line.Bounds.Y += headerHeight; panel.AddChild(line); headerHeight += headerTemplate.Bounds.Height; } panel.Bounds.Height += headerHeight; panel.Bounds.Y -= headerHeight / 2; var advancedButton = panel.Get <ButtonWidget>("ADVANCED_BUTTON"); advancedButton.Bounds.Y += headerHeight; advancedButton.OnClick = () => { Ui.OpenWindow("CONTENT_PANEL", new WidgetArgs { { "mod", mod }, { "content", content }, { "onCancel", Ui.CloseWindow } }); }; var quickButton = panel.Get <ButtonWidget>("QUICK_BUTTON"); quickButton.IsVisible = () => !string.IsNullOrEmpty(content.QuickDownload); quickButton.Bounds.Y += headerHeight; quickButton.OnClick = () => { var modFileSystem = new FileSystem.FileSystem(Game.Mods); modFileSystem.LoadFromManifest(mod); var downloadYaml = MiniYaml.Load(modFileSystem, content.Downloads, null); modFileSystem.UnmountAll(); var download = downloadYaml.FirstOrDefault(n => n.Key == content.QuickDownload); if (download == null) { throw new InvalidOperationException("Mod QuickDownload `{0}` definition not found.".F(content.QuickDownload)); } Ui.OpenWindow("PACKAGE_DOWNLOAD_PANEL", new WidgetArgs { { "download", new ModContent.ModDownload(download.Value) }, { "onSuccess", continueLoading } }); }; var backButton = panel.Get <ButtonWidget>("BACK_BUTTON"); backButton.Bounds.Y += headerHeight; backButton.OnClick = Ui.CloseWindow; Game.RunAfterTick(Ui.ResetTooltips); }
public ModContentPromptLogic(Widget widget, ModData modData, Manifest mod, ModContent content, Action continueLoading) { this.content = content; CheckRequiredContentInstalled(); var panel = widget.Get("CONTENT_PROMPT_PANEL"); var headerTemplate = panel.Get <LabelWidget>("HEADER_TEMPLATE"); var headerLines = !string.IsNullOrEmpty(content.InstallPromptMessage) ? content.InstallPromptMessage.Replace("\\n", "\n").Split('\n') : new string[0]; var headerHeight = 0; foreach (var l in headerLines) { var line = (LabelWidget)headerTemplate.Clone(); line.GetText = () => l; line.Bounds.Y += headerHeight; panel.AddChild(line); headerHeight += headerTemplate.Bounds.Height; } panel.Bounds.Height += headerHeight; panel.Bounds.Y -= headerHeight / 2; var advancedButton = panel.Get <ButtonWidget>("ADVANCED_BUTTON"); advancedButton.Bounds.Y += headerHeight; advancedButton.OnClick = () => { Ui.OpenWindow("CONTENT_PANEL", new WidgetArgs { { "mod", mod }, { "content", content }, { "onCancel", CheckRequiredContentInstalled } }); }; var quickButton = panel.Get <ButtonWidget>("QUICK_BUTTON"); quickButton.IsVisible = () => !string.IsNullOrEmpty(content.QuickDownload); quickButton.Bounds.Y += headerHeight; quickButton.OnClick = () => { var modObjectCreator = new ObjectCreator(mod, Game.Mods); var modPackageLoaders = modObjectCreator.GetLoaders <IPackageLoader>(mod.PackageFormats, "package"); var modFileSystem = new FS(mod.Id, Game.Mods, modPackageLoaders); modFileSystem.LoadFromManifest(mod); var downloadYaml = MiniYaml.Load(modFileSystem, content.Downloads, null); modFileSystem.UnmountAll(); var download = downloadYaml.FirstOrDefault(n => n.Key == content.QuickDownload); if (download == null) { throw new InvalidOperationException($"Mod QuickDownload `{content.QuickDownload}` definition not found."); } Ui.OpenWindow("PACKAGE_DOWNLOAD_PANEL", new WidgetArgs { { "download", new ModContent.ModDownload(download.Value) }, { "onSuccess", continueLoading } }); }; var quitButton = panel.Get <ButtonWidget>("QUIT_BUTTON"); quitButton.GetText = () => requiredContentInstalled ? "Continue" : "Quit"; quitButton.Bounds.Y += headerHeight; quitButton.OnClick = () => { if (requiredContentInstalled) { continueLoading(); } else { Game.Exit(); } }; Game.RunAfterTick(Ui.ResetTooltips); }
private List <GroupSequence> LoadGroupSetsFromFile() { var yamlDefs = MiniYaml.Load(Game.ModData.DefaultFileSystem, new[] { "op2-groups.yaml" }, null); var groupSequences = new List <GroupSequence>(); foreach (var group in yamlDefs) { var fart = group.Value.Nodes.First(x => x.Key == "ActorType").Value; var groupNodes = group.Value.Nodes; var groupSequence = new GroupSequence { Name = group.Key, ActorType = (ActorType)Enum.Parse(typeof(ActorType), groupNodes.First(x => x.Key == "ActorType").Value.Value.ToString()), }; var createBaseActor = groupNodes.FirstOrDefault(x => x.Key == "CreateBaseActor")?.Value?.Value ?.ToString().ToLowerInvariant(); if (!string.IsNullOrWhiteSpace(createBaseActor)) { groupSequence.CreateBaseActor = createBaseActor == "true"; } var createExampleActor = groupNodes.FirstOrDefault(x => x.Key == "CreateExampleActor")?.Value?.Value ?.ToString().ToLowerInvariant(); if (!string.IsNullOrWhiteSpace(createExampleActor)) { groupSequence.CreateExampleActor = createExampleActor == "true"; } var withBlankIdle = groupNodes.FirstOrDefault(x => x.Key == "WithBlankIdle")?.Value?.Value ?.ToString().ToLowerInvariant(); if (!string.IsNullOrWhiteSpace(withBlankIdle)) { groupSequence.WithBlankIdle = withBlankIdle == "true"; } var setsNode = group.Value.Nodes.First(x => x.Key == "Sets").Value.Nodes; var sets = new List <GroupSequenceSet>(); foreach (var set in setsNode) { var setNodes = set.Value.Nodes; var groupSequenceSet = new GroupSequenceSet { Sequence = set.Value.Value, Start = int.Parse(setNodes.First(x => x.Key == "Start").Value.Value.ToString()), }; if (int.TryParse(setNodes.FirstOrDefault(x => x.Key == "Length")?.Value?.Value?.ToString(), out var length)) { groupSequenceSet.Length = length; } if (int.TryParse(setNodes.FirstOrDefault(x => x.Key == "OffsetX")?.Value?.Value?.ToString(), out var offsetX)) { groupSequenceSet.OffsetX = offsetX; } if (int.TryParse(setNodes.FirstOrDefault(x => x.Key == "OffsetY")?.Value?.Value?.ToString(), out var offsetY)) { groupSequenceSet.OffsetY = offsetY; } if (int.TryParse(setNodes.FirstOrDefault(x => x.Key == "OffsetZ")?.Value?.Value?.ToString(), out var offsetZ)) { groupSequenceSet.OffsetZ = offsetZ; } if (int.TryParse(setNodes.FirstOrDefault(x => x.Key == "StartOffset")?.Value?.Value?.ToString(), out var startOffset)) { groupSequenceSet.StartOffset = startOffset; } sets.Add(groupSequenceSet); } groupSequence.Sets = sets.ToArray(); groupSequences.Add(groupSequence); } return(groupSequences); }