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."); }
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; }
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."); }
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); }; }