상속: IFolder
예제 #1
0
        public void Run(ModData modData, string[] args)
        {
            // HACK: The engine code assumes that Game.modData is set.
            Game.ModData = modData;

            var rules = Ruleset.LoadDefaultsForTileSet(modData, "ARRAKIS");
            var map = D2kMapImporter.Import(args[1], modData.Manifest.Mod.Id, args[2], rules);

            if (map == null)
                return;

            var dest = Path.GetFileNameWithoutExtension(args[1]) + ".oramap";
            var package = new ZipFile(modData.DefaultFileSystem, dest, true);
            map.Save(package);
            Console.WriteLine(dest + " saved.");
        }
예제 #2
0
        static Dictionary<string, ModMetadata> ValidateMods()
        {
            var ret = new Dictionary<string, ModMetadata>();
            foreach (var pair in GetCandidateMods())
            {
                IReadOnlyPackage package = null;
                try
                {
                    if (Directory.Exists(pair.Second))
                        package = new Folder(pair.Second);
                    else
                    {
                        try
                        {
                            package = new ZipFile(null, pair.Second);
                        }
                        catch
                        {
                            throw new InvalidDataException(pair.Second + " is not a valid mod package");
                        }
                    }

                    if (!package.Contains("mod.yaml"))
                    {
                        package.Dispose();
                        continue;
                    }

                    var yaml = new MiniYaml(null, MiniYaml.FromStream(package.GetStream("mod.yaml")));
                    var nd = yaml.ToDictionary();
                    if (!nd.ContainsKey("Metadata"))
                    {
                        package.Dispose();
                        continue;
                    }

                    var metadata = FieldLoader.Load<ModMetadata>(nd["Metadata"]);
                    metadata.Id = pair.First;
                    metadata.Package = package;

                    if (nd.ContainsKey("RequiresMods"))
                        metadata.RequiresMods = nd["RequiresMods"].ToDictionary(my => my.Value);
                    else
                        metadata.RequiresMods = new Dictionary<string, string>();

                    if (nd.ContainsKey("ContentInstaller"))
                        metadata.Content = FieldLoader.Load<ContentInstaller>(nd["ContentInstaller"]);

                    // Mods in the support directory and oramod packages (which are listed later
                    // in the CandidateMods list) override mods in the main install.
                    ret[pair.First] = metadata;
                }
                catch (Exception ex)
                {
                    if (package != null)
                        package.Dispose();
                    Console.WriteLine("An exception occurred when trying to load ModMetadata for `{0}`:".F(pair.First));
                    Console.WriteLine(ex.Message);
                }
            }

            return ret;
        }
예제 #3
0
        void IUtilityCommand.Run(ModData modData, string[] args)
        {
            // HACK: The engine code assumes that Game.modData is set.
            Game.ModData = modData;

            var filename = args[1];
            var file = new IniFile(File.Open(args[1], FileMode.Open));
            var basic = file.GetSection("Basic");
            var mapSection = file.GetSection("Map");
            var tileset = mapSection.GetValue("Theater", "");
            var iniSize = mapSection.GetValue("Size", "0, 0, 0, 0").Split(',').Select(int.Parse).ToArray();
            var iniBounds = mapSection.GetValue("LocalSize", "0, 0, 0, 0").Split(',').Select(int.Parse).ToArray();
            var size = new Size(iniSize[2], 2 * iniSize[3]);

            var map = new Map(Game.ModData, modData.DefaultTileSets[tileset], size.Width, size.Height)
            {
                Title = basic.GetValue("Name", Path.GetFileNameWithoutExtension(filename)),
                Author = "Westwood Studios",
                Bounds = new Rectangle(iniBounds[0], iniBounds[1], iniBounds[2], 2 * iniBounds[3] + 2 * iniBounds[1]),
                RequiresMod = modData.Manifest.Mod.Id
            };

            var fullSize = new int2(iniSize[2], iniSize[3]);
            ReadTiles(map, file, fullSize);
            ReadActors(map, file, "Structures", fullSize);
            ReadActors(map, file, "Units", fullSize);
            ReadActors(map, file, "Infantry", fullSize);
            ReadTerrainActors(map, file, fullSize);
            ReadWaypoints(map, file, fullSize);
            ReadOverlay(map, file, fullSize);
            ReadLighting(map, file);

            var spawnCount = map.ActorDefinitions.Count(n => n.Value.Value == "mpspawn");
            var mapPlayers = new MapPlayers(map.Rules, spawnCount);
            map.PlayerDefinitions = mapPlayers.ToMiniYaml();

            var dest = Path.GetFileNameWithoutExtension(args[1]) + ".oramap";
            var package = new ZipFile(modData.DefaultFileSystem, dest, true);
            map.Save(package);
            Console.WriteLine(dest + " saved.");
        }
예제 #4
0
        public SaveMapLogic(Widget widget, ModData modData, Action<string> onSave, Action onExit,
			Map map, List<MiniYamlNode> playerDefinitions, List<MiniYamlNode> actorDefinitions)
        {
            var title = widget.Get<TextFieldWidget>("TITLE");
            title.Text = map.Title;

            var author = widget.Get<TextFieldWidget>("AUTHOR");
            author.Text = map.Author;

            // TODO: This should use a multi-selection dropdown once they exist
            var visibilityDropdown = widget.Get<DropDownButtonWidget>("VISIBILITY_DROPDOWN");
            {
                var mapVisibility = new List<string>(Enum.GetNames(typeof(MapVisibility)));
                Func<string, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                {
                    var item = ScrollItemWidget.Setup(template,
                        () => visibilityDropdown.Text == option,
                        () => { visibilityDropdown.Text = option; });
                    item.Get<LabelWidget>("LABEL").GetText = () => option;
                    return item;
                };

                visibilityDropdown.Text = Enum.GetName(typeof(MapVisibility), map.Visibility);
                visibilityDropdown.OnClick = () =>
                    visibilityDropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 210, mapVisibility, setupItem);
            }

            var writableDirectories = new List<SaveDirectory>();
            SaveDirectory selectedDirectory = null;

            var directoryDropdown = widget.Get<DropDownButtonWidget>("DIRECTORY_DROPDOWN");
            {
                Func<SaveDirectory, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                {
                    var item = ScrollItemWidget.Setup(template,
                        () => selectedDirectory == option,
                        () => selectedDirectory = option);
                    item.Get<LabelWidget>("LABEL").GetText = () => option.DisplayName;
                    return item;
                };

                foreach (var kv in modData.MapCache.MapLocations)
                {
                    var folder = kv.Key as Folder;
                    if (folder == null)
                        continue;

                    try
                    {
                        using (var fs = File.Create(Path.Combine(folder.Name, ".testwritable"), 1, FileOptions.DeleteOnClose))
                        {
                            // Do nothing: we just want to test whether we can create the file
                        }

                        writableDirectories.Add(new SaveDirectory(folder, kv.Value));
                    }
                    catch
                    {
                        // Directory is not writable
                    }
                }

                if (map.Package != null)
                    selectedDirectory = writableDirectories.FirstOrDefault(k => k.Folder.Contains(map.Package.Name));

                // Prioritize MapClassification.User directories over system directories
                if (selectedDirectory == null)
                    selectedDirectory = writableDirectories.OrderByDescending(kv => kv.Classification).First();

                directoryDropdown.GetText = () => selectedDirectory == null ? "" : selectedDirectory.DisplayName;
                directoryDropdown.OnClick = () =>
                    directoryDropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 210, writableDirectories, setupItem);
            }

            var mapIsUnpacked = map.Package != null && (map.Package is Folder || map.Package is ZipFolder);

            var filename = widget.Get<TextFieldWidget>("FILENAME");
            filename.Text = map.Package == null ? "" : mapIsUnpacked ? Path.GetFileName(map.Package.Name) : Path.GetFileNameWithoutExtension(map.Package.Name);
            var fileType = mapIsUnpacked ? MapFileType.Unpacked : MapFileType.OraMap;

            var fileTypes = new Dictionary<MapFileType, MapFileTypeInfo>()
            {
                { MapFileType.OraMap, new MapFileTypeInfo { Extension = ".oramap", UiLabel = ".oramap" } },
                { MapFileType.Unpacked, new MapFileTypeInfo { Extension = "", UiLabel = "(unpacked)" } }
            };

            var typeDropdown = widget.Get<DropDownButtonWidget>("TYPE_DROPDOWN");
            {
                Func<KeyValuePair<MapFileType, MapFileTypeInfo>, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
                {
                    var item = ScrollItemWidget.Setup(template,
                        () => fileType == option.Key,
                        () => { typeDropdown.Text = option.Value.UiLabel; fileType = option.Key; });
                    item.Get<LabelWidget>("LABEL").GetText = () => option.Value.UiLabel;
                    return item;
                };

                typeDropdown.Text = fileTypes[fileType].UiLabel;

                typeDropdown.OnClick = () =>
                    typeDropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 210, fileTypes, setupItem);
            }

            var close = widget.Get<ButtonWidget>("BACK_BUTTON");
            close.OnClick = () => { Ui.CloseWindow(); onExit(); };

            var save = widget.Get<ButtonWidget>("SAVE_BUTTON");
            save.OnClick = () =>
            {
                if (string.IsNullOrEmpty(filename.Text))
                    return;

                map.Title = title.Text;
                map.Author = author.Text;
                map.Visibility = (MapVisibility)Enum.Parse(typeof(MapVisibility), visibilityDropdown.Text);

                if (actorDefinitions != null)
                    map.ActorDefinitions = actorDefinitions;

                if (playerDefinitions != null)
                    map.PlayerDefinitions = playerDefinitions;

                map.RequiresMod = modData.Manifest.Mod.Id;

                var combinedPath = Platform.ResolvePath(Path.Combine(selectedDirectory.Folder.Name, filename.Text + fileTypes[fileType].Extension));

                // Invalidate the old map metadata
                if (map.Uid != null && map.Package != null && map.Package.Name == combinedPath)
                    modData.MapCache[map.Uid].Invalidate();

                try
                {
                    var package = map.Package as IReadWritePackage;
                    if (package == null || package.Name != combinedPath)
                    {
                        selectedDirectory.Folder.Delete(combinedPath);
                        if (fileType == MapFileType.OraMap)
                            package = new ZipFile(modData.DefaultFileSystem, combinedPath, true);
                        else
                            package = new Folder(combinedPath);
                    }

                    map.Save(package);
                }
                catch
                {
                    Console.WriteLine("Failed to save map at {0}", combinedPath);
                }

                // Update the map cache so it can be loaded without restarting the game
                modData.MapCache[map.Uid].UpdateFromMap(map.Package, selectedDirectory.Folder, selectedDirectory.Classification, null, map.Grid.Type);

                Console.WriteLine("Saved current map at {0}", combinedPath);
                Ui.CloseWindow();

                onSave(map.Uid);
            };
        }