From 36349268e271f5e272223ac47fadb2119536d5e4 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 25 Jan 2016 17:04:07 +0100 Subject: [PATCH] Merged in GZDB r2484. --- Source/Core/General/MapManager.cs | 218 +++++++++++------- Source/Core/Plugins/Plug.cs | 11 +- Source/Core/Plugins/PluginManager.cs | 5 +- Source/Plugins/NodesViewer/NodesForm.cs | 8 +- Source/Plugins/NodesViewer/NodesViewerMode.cs | 30 +-- 5 files changed, 151 insertions(+), 121 deletions(-) diff --git a/Source/Core/General/MapManager.cs b/Source/Core/General/MapManager.cs index b88b58f..5260800 100644 --- a/Source/Core/General/MapManager.cs +++ b/Source/Core/General/MapManager.cs @@ -635,15 +635,100 @@ namespace CodeImp.DoomBuilder /// public bool ExportToFile(string filepathname) { - return SaveMap(filepathname, SavePurpose.Testing); - } + General.Plugins.OnMapSaveBegin(SavePurpose.Testing); + bool result = SaveMap(filepathname, SavePurpose.Testing); + General.Plugins.OnMapSaveEnd(SavePurpose.Testing); + return result; + } - // Initializes for an existing map - internal bool SaveMap(string newfilepathname, SavePurpose purpose) + /// + /// This writes the map structures to the temporary file. + /// + private bool WriteMapToTempFile() + { + StatusInfo oldstatus = General.MainWindow.Status; + + // Make a copy of the map data + MapSet outputset = map.Clone(); + + // Remove all flags from all 3D Start things + foreach (Thing t in outputset.Things) + { + if (t.Type == config.Start3DModeThingType) + { + // We're not using SetFlag here, this doesn't have to be undone. + // Please note that this is totally exceptional! + List flagkeys = new List(t.Flags.Keys); + foreach (string k in flagkeys) t.Flags[k] = false; + } + } + + // Do we need sidedefs compression? + if (map.Sidedefs.Count > io.MaxSidedefs) + { + // Compress sidedefs + General.MainWindow.DisplayStatus(StatusType.Busy, "Compressing sidedefs..."); + outputset.CompressSidedefs(); + + // Check if it still doesnt fit + if (outputset.Sidedefs.Count > io.MaxSidedefs) + { + // Problem! Can't save the map like this! + General.ShowErrorMessage("Unable to save the map: There are too many unique sidedefs!", MessageBoxButtons.OK); + General.MainWindow.DisplayStatus(oldstatus); + return false; + } + } + + // Check things + if (map.Things.Count > io.MaxThings) + { + General.ShowErrorMessage("Unable to save the map: There are too many things!", MessageBoxButtons.OK); + General.MainWindow.DisplayStatus(oldstatus); + return false; + } + + // Check sectors + if (map.Sectors.Count > io.MaxSectors) + { + General.ShowErrorMessage("Unable to save the map: There are too many sectors!", MessageBoxButtons.OK); + General.MainWindow.DisplayStatus(oldstatus); + return false; + } + + // Check linedefs + if (map.Linedefs.Count > io.MaxLinedefs) + { + General.ShowErrorMessage("Unable to save the map: There are too many linedefs!", MessageBoxButtons.OK); + General.MainWindow.DisplayStatus(oldstatus); + return false; + } + + // Check vertices + if (map.Vertices.Count > io.MaxVertices) + { + General.ShowErrorMessage("Unable to save the map: There are too many vertices!", MessageBoxButtons.OK); + General.MainWindow.DisplayStatus(oldstatus); + return false; + } + + // TODO: Check for more limitations + + // Write to temporary file + General.WriteLogLine("Writing map data structures to file..."); + int index = Math.Max(0, tempwad.FindLumpIndex(TEMP_MAP_HEADER)); + io.Write(outputset, TEMP_MAP_HEADER, index); + outputset.Dispose(); + + General.MainWindow.DisplayStatus(oldstatus); + return true; + } + + // Initializes for an existing map + internal bool SaveMap(string newfilepathname, SavePurpose purpose) { string settingsfile; WAD targetwad; - int index; bool includenodes; General.WriteLogLine("Saving map to file: " + newfilepathname); @@ -674,83 +759,15 @@ namespace CodeImp.DoomBuilder // (not when only scripts have changed) if(changed) { - // Make a copy of the map data - MapSet outputset = map.Clone(); + // Write the current map structures to the temp file + if (!WriteMapToTempFile()) return false; - // Remove all flags from all 3D Start things - foreach(Thing t in outputset.Things) - { - if(t.Type == config.Start3DModeThingType) - { - // We're not using SetFlag here, this doesn't have to be undone. - // Please note that this is totally exceptional! - List flagkeys = new List(t.Flags.Keys); - foreach(string k in flagkeys) t.Flags[k] = false; - } - } + // Get the corresponding nodebuilder + string nodebuildername = (purpose == SavePurpose.Testing) ? configinfo.NodebuilderTest : configinfo.NodebuilderSave; - // Do we need sidedefs compression? - StatusInfo oldstatus; - if(map.Sidedefs.Count > io.MaxSidedefs) - { - // Compress sidedefs - oldstatus = General.MainWindow.Status; - General.MainWindow.DisplayStatus(StatusType.Busy, "Compressing sidedefs..."); - outputset.CompressSidedefs(); - General.MainWindow.DisplayStatus(oldstatus); - - // Check if it still doesnt fit - if(outputset.Sidedefs.Count > io.MaxSidedefs) - { - // Problem! Can't save the map like this! - General.ShowErrorMessage("Unable to save the map: There are too many unique sidedefs!", MessageBoxButtons.OK); - return false; - } - } - - // Check things - if(map.Things.Count > io.MaxThings) - { - General.ShowErrorMessage("Unable to save the map: There are too many things!", MessageBoxButtons.OK); - return false; - } - - // Check sectors - if(map.Sectors.Count > io.MaxSectors) - { - General.ShowErrorMessage("Unable to save the map: There are too many sectors!", MessageBoxButtons.OK); - return false; - } - - // Check linedefs - if(map.Linedefs.Count > io.MaxLinedefs) - { - General.ShowErrorMessage("Unable to save the map: There are too many linedefs!", MessageBoxButtons.OK); - return false; - } - - // Check vertices - if(map.Vertices.Count > io.MaxVertices) - { - General.ShowErrorMessage("Unable to save the map: There are too many vertices!", MessageBoxButtons.OK); - return false; - } - - // TODO: Check for more limitations - - // Write to temporary file - General.WriteLogLine("Writing map data structures to file..."); - index = tempwad.FindLumpIndex(TEMP_MAP_HEADER); - if(index == -1) index = 0; - io.Write(outputset, TEMP_MAP_HEADER, index); - outputset.Dispose(); - - // Get the corresponding nodebuilder - string nodebuildername = (purpose == SavePurpose.Testing) ? configinfo.NodebuilderTest : configinfo.NodebuilderSave; - - // Build the nodes - oldstatus = General.MainWindow.Status; - General.MainWindow.DisplayStatus(StatusType.Busy, "Building map nodes..."); + // Build the nodes + StatusInfo oldstatus = General.MainWindow.Status; + General.MainWindow.DisplayStatus(StatusType.Busy, "Building map nodes..."); includenodes = (!string.IsNullOrEmpty(nodebuildername) && BuildNodes(nodebuildername, true)); General.MainWindow.DisplayStatus(oldstatus); } @@ -931,7 +948,7 @@ namespace CodeImp.DoomBuilder General.WriteLogLine("Changing map name from '" + options.PreviousName + "' to '" + options.CurrentName + "'"); // Find the map header in target - index = targetwad.FindLumpIndex(options.PreviousName); + int index = targetwad.FindLumpIndex(options.PreviousName); if(index > -1) { // Rename the map lump name @@ -1059,12 +1076,36 @@ namespace CodeImp.DoomBuilder #endif } - #endregion + #endregion - #region ================== Nodebuild + #region ================== Nodebuild - // This builds the nodes in the temproary file with the given configuration name - private bool BuildNodes(string nodebuildername, bool failaswarning) + /// + /// This stores the current structures in memory to the temporary file and rebuilds the nodes. + /// The 'nodebuildername' must be a valid nodebuilder configuration profile. + /// Returns True on success, False when failed. + /// + public bool RebuildNodes(string nodebuildername, bool failaswarning) + { + bool result; + + // Write the current map structures to the temp file + if (!WriteMapToTempFile()) return false; + + // Build the nodes + StatusInfo oldstatus = General.MainWindow.Status; + General.MainWindow.DisplayStatus(StatusType.Busy, "Building map nodes..."); + if (!string.IsNullOrEmpty(nodebuildername)) + result = BuildNodes(nodebuildername, failaswarning); + else + result = false; + General.MainWindow.DisplayStatus(oldstatus); + + return result; + } + + // This builds the nodes in the temproary file with the given configuration name + private bool BuildNodes(string nodebuildername, bool failaswarning) { bool lumpscomplete = false; WAD buildwad; @@ -1185,8 +1226,11 @@ namespace CodeImp.DoomBuilder // Clean up compiler.Dispose(); - // Return result - return lumpscomplete; + // Let the plugins know + if (lumpscomplete) General.Plugins.OnMapNodesRebuilt(); + + // Return result + return lumpscomplete; } } diff --git a/Source/Core/Plugins/Plug.cs b/Source/Core/Plugins/Plug.cs index e41594b..36fd798 100644 --- a/Source/Core/Plugins/Plug.cs +++ b/Source/Core/Plugins/Plug.cs @@ -308,8 +308,15 @@ namespace CodeImp.DoomBuilder.Plugins /// public virtual void OnEditAccept() { } - // Interface events - public virtual void OnEditMouseClick(MouseEventArgs e) { } + /// + /// Called just after the nodes have been (re)built. This allows a plugin to intervene with + /// the nodebuilder output using GetLumpData and SetLumpData. If the map is being saved, this + /// is called after the nodes are rebuilt and just before they are stored in the target file. + /// + public virtual void OnMapNodesRebuilt() { } + + // Interface events + public virtual void OnEditMouseClick(MouseEventArgs e) { } public virtual void OnEditMouseDoubleClick(MouseEventArgs e) { } public virtual void OnEditMouseDown(MouseEventArgs e) { } public virtual void OnEditMouseEnter(EventArgs e) { } diff --git a/Source/Core/Plugins/PluginManager.cs b/Source/Core/Plugins/PluginManager.cs index a007330..3be7be1 100644 --- a/Source/Core/Plugins/PluginManager.cs +++ b/Source/Core/Plugins/PluginManager.cs @@ -301,9 +301,10 @@ namespace CodeImp.DoomBuilder.Plugins public void OnEditRedrawDisplayBegin() { foreach(Plugin p in plugins) p.Plug.OnEditRedrawDisplayBegin(); } public void OnEditRedrawDisplayEnd() { foreach(Plugin p in plugins) p.Plug.OnEditRedrawDisplayEnd(); } public void OnPresentDisplayBegin() { foreach(Plugin p in plugins) p.Plug.OnPresentDisplayBegin(); } + public void OnMapNodesRebuilt() { foreach (Plugin p in plugins) p.Plug.OnMapNodesRebuilt(); } - //mxd. Hilight events - public void OnHighlightSector(Sector s) { foreach(Plugin p in plugins) p.Plug.OnHighlightSector(s); } + //mxd. Highlight events + public void OnHighlightSector(Sector s) { foreach(Plugin p in plugins) p.Plug.OnHighlightSector(s); } public void OnHighlightLinedef(Linedef l) { foreach(Plugin p in plugins) p.Plug.OnHighlightLinedef(l); } public void OnHighlightThing(Thing t) { foreach(Plugin p in plugins) p.Plug.OnHighlightThing(t); } public void OnHighlightVertex(Vertex v) { foreach(Plugin p in plugins) p.Plug.OnHighlightVertex(v); } diff --git a/Source/Plugins/NodesViewer/NodesForm.cs b/Source/Plugins/NodesViewer/NodesForm.cs index 236a9c5..4b49d85 100644 --- a/Source/Plugins/NodesViewer/NodesForm.cs +++ b/Source/Plugins/NodesViewer/NodesForm.cs @@ -160,11 +160,11 @@ namespace CodeImp.DoomBuilder.Plugins.NodesViewer // (Re)build the nodes private void buildnodesbutton_Click(object sender, EventArgs e) { - mode.BuildNodes(); + General.Map.RebuildNodes(General.Map.ConfigSettings.NodebuilderSave, true); - // Restart the mode so that the new structures are loaded in. - // This will automatically close and re-open this window. - General.Editing.CancelMode(); + // Restart the mode so that the new structures are loaded in. + // This will automatically close and re-open this window. + General.Editing.CancelMode(); NodesViewerMode newmode = new NodesViewerMode(); General.Editing.ChangeMode(newmode); newmode.Form.showsegsvertices.Checked = this.showsegsvertices.Checked; diff --git a/Source/Plugins/NodesViewer/NodesViewerMode.cs b/Source/Plugins/NodesViewer/NodesViewerMode.cs index 3d798f2..1552d97 100644 --- a/Source/Plugins/NodesViewer/NodesViewerMode.cs +++ b/Source/Plugins/NodesViewer/NodesViewerMode.cs @@ -85,20 +85,6 @@ namespace CodeImp.DoomBuilder.Plugins.NodesViewer #region ================== Methods - /// - /// This (re)builds the nodes for the whole map. - /// - public void BuildNodes() - { - // There is no API available to do this directly, but we export the map which will - // cause the DB core to build the nodes (with testing parameters) - General.Interface.DisplayStatus(StatusType.Busy, "Building map nodes..."); - string tempfile = BuilderPlug.MakeTempFilename(".wad"); - General.Map.IsChanged = true; - General.Map.ExportToFile(tempfile); - File.Delete(tempfile); - } - /// /// This loads all nodes structures data from the lumps /// @@ -810,14 +796,6 @@ namespace CodeImp.DoomBuilder.Plugins.NodesViewer Cursor.Current = Cursors.WaitCursor; base.OnEngage(); - //mxd. General.Map.ExportToFile in BuildNodes() won't do the trick if the map was never saved - if(string.IsNullOrEmpty(General.Map.FilePathName)) - { - MessageBox.Show("Please save the map before running Nodes Viewer mode.", "Nodes Viewer mode", MessageBoxButtons.OK, MessageBoxIcon.Error); - General.Editing.CancelMode(); - return; - } - //mxd bool haveNodes = General.Map.LumpExists("NODES"); bool haveZnodes = General.Map.LumpExists("ZNODES"); @@ -827,11 +805,11 @@ namespace CodeImp.DoomBuilder.Plugins.NodesViewer if(General.Map.IsChanged || !(haveZnodes || (haveNodes || haveSectors || haveSegs || haveVerts))) { - // We need to build the nodes! - BuildNodes(); + // We need to build the nodes! + if (!General.Map.RebuildNodes(General.Map.ConfigSettings.NodebuilderSave, true)) return; - //mxd. Update nodes availability - haveNodes = General.Map.LumpExists("NODES"); + //mxd. Update nodes availability + haveNodes = General.Map.LumpExists("NODES"); haveZnodes = General.Map.LumpExists("ZNODES"); haveSectors = General.Map.LumpExists("SSECTORS"); haveSegs = General.Map.LumpExists("SEGS");