/// <summary> /// Checks for and if found gives user a choice to delete nodes that are /// outside of a Map's x/y/z bounds. /// </summary> /// <param name="child"></param> public static void CheckNodeBounds(MapFileChild child) { if (child != null) { var invalids = new List <RouteNode>(); foreach (RouteNode node in child.Routes) { if (RouteNodeCollection.IsOutsideMap( node, child.MapSize.Cols, child.MapSize.Rows, child.MapSize.Levs)) { invalids.Add(node); } } if (invalids.Count != 0) { string info = String.Format( System.Globalization.CultureInfo.CurrentCulture, "There {0} " + invalids.Count + " route-node{1} outside" + " the bounds of this Map.{3}Do you want {2} deleted ?{3}", (invalids.Count == 1) ? "is" : "are", (invalids.Count == 1) ? "" : "s", (invalids.Count == 1) ? "it" : "them", Environment.NewLine); foreach (var node in invalids) { info += Environment.NewLine + "id " + node.Index + " : " + node.GetLocationString(child.MapSize.Levs); } if (MessageBox.Show( info, "Invalid Nodes", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1, 0) == DialogResult.Yes) { child.RoutesChanged = true; foreach (var node in invalids) { child.Routes.DeleteNode(node); } } } } }
/// <summary> /// Opens a dialog to delete an invalid link-destination node. /// </summary> /// <param name="file"></param> /// <param name="node">the node to delete</param> /// <returns>true if user chooses to delete out-of-bounds node</returns> public static bool ShowInvalid(MapFileChild file, RouteNode node) { using (var f = new RouteCheckInfobox()) { string label = String.Format( System.Globalization.CultureInfo.CurrentCulture, "Destination node is outside the Map's bounds." + "{0}{0}Do you want it deleted?", Environment.NewLine); string text = "id " + node.Index + " : " + node.GetLocationString(file.MapSize.Levs); f.SetText(label, text); if (f.ShowDialog() == DialogResult.Yes) { file.Routes.DeleteNode(node); return(true); } } return(false); }
/// <summary> /// Checks for and if found gives user a choice to delete nodes that are /// outside of a Map's x/y/z bounds. /// </summary> /// <param name="mapFile"></param> public static void CheckNodeBounds(MapFileChild mapFile) { if (mapFile != null) { var invalid = new List <RouteNode>(); foreach (RouteNode node in mapFile.Routes) { if (RouteNodeCollection.IsOutsideMap( node, mapFile.MapSize.Cols, mapFile.MapSize.Rows, mapFile.MapSize.Levs)) { invalid.Add(node); } } if (invalid.Count != 0) { if (MessageBox.Show( "There are route nodes outside the bounds of" + " this Map. Do you want them removed?", "Invalid Nodes", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1, 0) == DialogResult.Yes) { mapFile.RoutesChanged = true; foreach (var node in invalid) { mapFile.Routes.DeleteNode(node); } } } } }
/// <summary> /// Checks for and if found gives user a choice to delete nodes that are /// outside of a Map's x/y/z bounds. /// </summary> /// <param name="file"></param> /// <param name="ludi">true if user-invoked</param> /// <returns>true if user opted to clear invalid nodes</returns> public static bool CheckNodeBounds(MapFileChild file, bool ludi = false) { if ((_file = file) != null) { _invalids.Clear(); if ((_count = GetInvalidNodes()) != 0) { return(ShowInvalids()); } if (ludi) { MessageBox.Show( "There are no Out of Bounds nodes detected.", "Good stuff, Magister Ludi", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, 0); } } return(false); }
/// <summary> /// Checks for and if found gives user a choice to delete nodes that are /// outside of a Map's x/y/z bounds. /// </summary> /// <param name="child"></param> /// <returns>true if node(s) are deleted</returns> public static bool CheckNodeBoundsMenuitem(MapFileChild child) { if (child != null) { var invalids = new List <RouteNode>(); foreach (RouteNode node in child.Routes) { if (RouteNodeCollection.IsOutsideMap( node, child.MapSize.Cols, child.MapSize.Rows, child.MapSize.Levs)) { invalids.Add(node); } } string info, title; MessageBoxIcon icon; MessageBoxButtons btns; if (invalids.Count != 0) { icon = MessageBoxIcon.Warning; btns = MessageBoxButtons.YesNo; title = "Warning"; info = String.Format( System.Globalization.CultureInfo.CurrentCulture, "There {0} " + invalids.Count + " route-node{1} outside" + " the bounds of this Map.{3}Do you want {2} deleted ?{3}", (invalids.Count == 1) ? "is" : "are", (invalids.Count == 1) ? "" : "s", (invalids.Count == 1) ? "it" : "them", Environment.NewLine); foreach (var node in invalids) { info += Environment.NewLine + "id " + node.Index + " : " + node.GetLocationString(child.MapSize.Levs); } } else { icon = MessageBoxIcon.Information; btns = MessageBoxButtons.OK; title = "Good stuff, Magister Ludi"; info = "There are no Out of Bounds nodes detected."; } if (MessageBox.Show( info, title, btns, icon, MessageBoxDefaultButton.Button1, 0) == DialogResult.Yes) { child.RoutesChanged = true; foreach (var node in invalids) { child.Routes.DeleteNode(node); } return(true); } } return(false); }
/// <summary> /// If this inputbox is type AddTileset, the accept click must check to /// see if a descriptor has been created already with the CreateMap /// button first. /// /// If this inputbox is type EditTileset, the accept click will create a /// descriptor if the tileset-label changed and delete the old /// descriptor, and add the new one to the current tilegroup/category. /// If the tileset-label didn't change, nothing more need be done since /// any terrains that were changed have already been changed by changes /// to the Allocated/Available listboxes. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnAcceptClick(object sender, EventArgs e) { //LogFile.WriteLine(""); //LogFile.WriteLine("OnAcceptClick"); //LogFile.WriteLine(". Tileset= " + Tileset); switch (InputBoxType) { case BoxType.EditTileset: //LogFile.WriteLine(". . MODE:EditTileset"); if (String.IsNullOrEmpty(Tileset)) { //LogFile.WriteLine(". The Map label cannot be blank."); ShowErrorDialog("The Map label cannot be blank."); tbTileset.Select(); } else if (lbTerrainsAllocated.Items.Count == 0) { //LogFile.WriteLine(". The Map must have at least one terrain allocated."); ShowErrorDialog("The Map must have at least one terrain allocated."); } else { //foreach (string t in TerrainsOriginal) // LogFile.WriteLine(". terrain original= " + t); //foreach (string t in Descriptor.Terrains) // LogFile.WriteLine(". terrain= " + t); if (Tileset == TilesetOriginal) // label didn't change; check if terrains changed -> { //LogFile.WriteLine(". . label did *not* change"); if (Descriptor.Terrains.SequenceEqual(TerrainsOriginal)) { //LogFile.WriteLine(". . . No changes were made."); ShowInfoDialog("No changes were made."); } else { //LogFile.WriteLine(". . . DialogResult OK"); DialogResult = DialogResult.OK; } // NOTE: a Save of Map-file is *not* required here. } else // label changed; rewrite the descriptor -> { //LogFile.WriteLine(". . change label"); // NOTE: user cannot edit a Map-label to be another already existing file. // There are other ways to do that: either let the user delete the target- // Map-file from his/her disk, or better click Edit on *that* tileset. // NOTE: however, if while editing a tileset the user browses to another // tileset and edits that tileset's terrains, the changes are effective. if (MapFileExists(Tileset)) { //LogFile.WriteLine(". The Map file already exists on disk."); ShowErrorDialog("The Map file already exists on disk. The Tileset Editor is" + " not sophisticated enough to deal with this eventuality." + " Either edit that Map directly if it's already in the Maptree," + " or use Add Tileset to make it editable, or as a last" + " resort delete it from your disk." + Environment.NewLine + Environment.NewLine + GetFullPathMap(Tileset)); // TODO: Ask user if he/she wants to overwrite the Map-file. } else { if (IsTilesetInGroups(Tileset)) { //LogFile.WriteLine(". The tileset already exists in the Maptree."); ShowErrorDialog("The tileset already exists in the Maptree." + Environment.NewLine + Environment.NewLine + Tileset + Environment.NewLine + Environment.NewLine + "Options are to edit that one, delete that one," + " or choose a different label for this one."); } else { //LogFile.WriteLine(". . . tileset Created"); string pfeMap = GetFullPathMap(Tileset); string pfeMapPre = GetFullPathMap(TilesetOriginal); //LogFile.WriteLine(". . . . fileMapPre= " + pfeMapPre); //LogFile.WriteLine(". . . . fileMap= " + pfeMap); File.Move(pfeMapPre, pfeMap); // NOTE: This has to happen now because once the MapTree node // is selected it will try to load the .MAP file etc. if (File.Exists(pfeMap)) // NOTE: do *not* alter the descriptor if File.Move() went bork. { // This is likely redundant: File.Move() should throw. string pfeRoutes = GetFullPathRoutes(Tileset); string pfeRoutesPre = GetFullPathRoutes(TilesetOriginal); //LogFile.WriteLine(". . . . fileRoutesPre= " + pfeRoutesPre); //LogFile.WriteLine(". . . . fileRoutes= " + pfeRoutes); File.Move(pfeRoutesPre, pfeRoutes); var category = TileGroup.Categories[Category]; Descriptor = new Descriptor( Tileset, category[TilesetOriginal].Terrains, BasePath, TileGroup.Pal); TileGroup.AddTileset(Descriptor, Category); // NOTE: This could be done on return to XCMainWindow.OnEditTilesetClick() // but then 'Descriptor' would have to be internal. TileGroup.DeleteTileset(TilesetOriginal, Category); // NOTE: This could be done on return to XCMainWindow.OnEditTilesetClick() // but then 'TilesetOriginal' would have to be internal. DialogResult = DialogResult.OK; } } } } } break; case BoxType.AddTileset: //LogFile.WriteLine(". . MODE:AddTileset"); if (String.IsNullOrEmpty(Tileset)) // NOTE: The tileset-label should already have been { // checked for validity by here before the Create button. //LogFile.WriteLine(". The Map label cannot be blank."); // But these handle the case when user immediately clicks the Ok button. ShowErrorDialog("The Map label cannot be blank."); // ... TODO: so disable the Ok button, unless a descriptor is valid tbTileset.Select(); } else if (lbTerrainsAllocated.Items.Count == 0) { //LogFile.WriteLine(". The Map must have at least one terrain allocated."); ShowErrorDialog("The Map must have at least one terrain allocated."); } else { switch (FileAddType) { case AddType.MapExists: //LogFile.WriteLine(". . Map file EXISTS"); TileGroup.AddTileset(Descriptor, Category); DialogResult = DialogResult.OK; break; case AddType.MapCreate: //LogFile.WriteLine(". . Map file does NOT exist - Create new Map file"); string pfeMap = GetFullPathMap(Tileset); //LogFile.WriteLine(". . . fileMap= " + pfeMap); string pfeRoutes = GetFullPathRoutes(Tileset); //LogFile.WriteLine(". . . fileRoutes= " + pfeRoutes); Directory.CreateDirectory(Path.GetDirectoryName(pfeRoutes)); using (var fs = File.Create(pfeRoutes)) // create a blank Route-file and release its handle. {} Directory.CreateDirectory(Path.GetDirectoryName(pfeMap)); using (var fs = File.Create(pfeMap)) // create the Map-file and release its handle. { // NOTE: This has to happen now because once the MapTree node MapFileChild.CreateMap( // is selected it will try to load the .MAP file etc. fs, 10, 10, 1); // <- default new Map size } if (File.Exists(pfeMap) && File.Exists(pfeRoutes)) // NOTE: The descriptor has already been created with the Create descriptor button. { //LogFile.WriteLine(". tileset Created"); TileGroup.AddTileset(Descriptor, Category); DialogResult = DialogResult.OK; } break; } } break; } }
internal void Analyze(MapFileChild file) { groupInfo.Text = "Map: " + file.Descriptor.Label; lbl2Dimensions.Text = file.MapSize.Cols + "," + file.MapSize.Rows + "," + file.MapSize.Levs; lbl2Tilesets.Text = String.Empty; int recordsTotal = 0; int spritesTotal = 0; bool first = true; for (int i = 0; i != file.Terrains.Count; ++i) { if (first) { first = false; } else { lbl2Tilesets.Text += ";"; } lbl2Tilesets.Text += file.Terrains[i].Item1; spritesTotal += file.Descriptor.GetSpriteCount(i); recordsTotal += file.Descriptor.GetRecordCount(i); } var width = TextRenderer.MeasureText(lbl2Tilesets.Text, lbl2Tilesets.Font).Width; if (width > lbl2Tilesets.Width) { Width += width - lbl2Tilesets.Width; } Refresh(); groupAnalyze.Visible = true; int parts = 0; var recordsTable = new Hashtable(); var spritesTable = new Hashtable(); pBar.Maximum = file.MapSize.Cols * file.MapSize.Rows * file.MapSize.Levs; pBar.Value = 0; for (int col = 0; col != file.MapSize.Cols; ++col) { for (int row = 0; row != file.MapSize.Rows; ++row) { for (int lev = 0; lev != file.MapSize.Levs; ++lev) { var tile = file[row, col, lev] as XCMapTile; if (!tile.Vacant) { if (tile.Ground != null) { ++parts; Count(tile.Ground, recordsTable, spritesTable); var part = tile.Ground as Tilepart; if (part != null) { Count(part.Dead, recordsTable, spritesTable); } } if (tile.West != null) { ++parts; Count(tile.West, recordsTable, spritesTable); var part = tile.West as Tilepart; if (part != null) { Count(part.Dead, recordsTable, spritesTable); } } if (tile.North != null) { ++parts; Count(tile.North, recordsTable, spritesTable); var part = tile.North as Tilepart; if (part != null) { Count(part.Dead, recordsTable, spritesTable); } } if (tile.Content != null) { ++parts; Count(tile.Content, recordsTable, spritesTable); var part = tile.Content as Tilepart; if (part != null) { Count(part.Dead, recordsTable, spritesTable); } } } ++pBar.Value; pBar.Refresh(); } } } var pct = Math.Round(100.0 * (double)recordsTable.Keys.Count / (double)recordsTotal, 2); lbl2McdRecords.Text = recordsTable.Keys.Count + "/" + recordsTotal + " - " + pct + "%"; pct = Math.Round(100.0 * (double)parts / (pBar.Maximum * 4), 2); lbl2PartsFilled.Text = parts + "/" + (pBar.Maximum * 4) + " - " + pct + "%"; pct = Math.Round(100.0 * (double)spritesTable.Keys.Count / (double)spritesTotal, 2); lbl2PckImages.Text = spritesTable.Keys.Count + "/" + spritesTotal + " - " + pct + "%"; groupAnalyze.Text = String.Empty; // hide the progress bar and show the Cancel btn. pBar.Visible = false; btnCancel.Visible = true; Refresh(); }