From 31184de35882c8427fba3188fcaf4cb8e58919e2 Mon Sep 17 00:00:00 2001 From: codeimp Date: Wed, 31 Dec 2008 16:43:23 +0000 Subject: [PATCH] prefabs support added --- Documents/todo.txt | 2 - Resources/Icons/Prefab.png | Bin 0 -> 514 bytes Resources/Icons/Prefab2.png | Bin 0 -> 552 bytes Source/Builder.csproj | 2 + Source/Editing/CopyPasteManager.cs | 239 +++++++++++++++++++++++- Source/General/MapManager.cs | 1 + Source/Map/UniValue.cs | 9 +- Source/Properties/Resources.Designer.cs | 16 +- Source/Properties/Resources.resx | 6 + Source/Resources/Actions.cfg | 30 +++ Source/Resources/Prefab.png | Bin 0 -> 514 bytes Source/Resources/Prefab2.png | Bin 0 -> 552 bytes Source/Windows/MainForm.Designer.cs | 209 +++++++++++++++------ Source/Windows/MainForm.cs | 18 ++ Source/Windows/MainForm.resx | 3 + 15 files changed, 465 insertions(+), 70 deletions(-) create mode 100644 Resources/Icons/Prefab.png create mode 100644 Resources/Icons/Prefab2.png create mode 100644 Source/Resources/Prefab.png create mode 100644 Source/Resources/Prefab2.png diff --git a/Documents/todo.txt b/Documents/todo.txt index c6fcc16e..f8d4e822 100644 --- a/Documents/todo.txt +++ b/Documents/todo.txt @@ -3,8 +3,6 @@ quality over quantity. It is done when it's done. The order and included items may also change any time. ========================================================= -- Make Prefabs support - - Make Directory Resources support - Make PK3 Resources support diff --git a/Resources/Icons/Prefab.png b/Resources/Icons/Prefab.png new file mode 100644 index 0000000000000000000000000000000000000000..54561df439c29d450fb57b72b55c71a5f4ead086 GIT binary patch literal 514 zcmV+d0{#7oP)u0#O)s=|&6{ z9LJGnP)P?76)hwbDkw^+Rj8DZQA9>Wfh84P7ezrq6fFvRP>aA#i)z~{+O&xN(P_Tx z1C?IZfx~^wch2|SGdf)hY#TNfzK$bu(+9cegpe0t&Y59M8KEE1v)1}Lgf)RVw_ONc z^kC>^0=|=OI96pSTV0&yDKkuyCUm4bU`QM8o5V^<0g3%*5hUMp=)Ft8Rq}EZA{kic zt+32mV42Z4ZGjGqUAwIg-&j2&08TX2;4v} zDsb=k_yqLLnbH1`rmF|(7<1GdL3<(vM&WS-Z7TI3$XBXq64!9cLSR`1)g!*)*QlAK z;>LP0-8G(nM5{?#;zpAOVSD0F4BE%P4O)Zz3x4(f4`R~u)Gbr!i2wiq07*qoM6N<$ Eg4kcxSpWb4 literal 0 HcmV?d00001 diff --git a/Resources/Icons/Prefab2.png b/Resources/Icons/Prefab2.png new file mode 100644 index 0000000000000000000000000000000000000000..c46beb6c2852ea1e826564102191e52fea93b10e GIT binary patch literal 552 zcmV+@0@wYCP)S)o8s_xdA+N|x z--;l0kwMqnFcQa22raA7HtV^(qh5GMJg6P4g=^6DSdpxiG*EK#v=P0ZV`zEEAySHS z2#Emx89#iJKKLdqjr-s#xW2myl)}t7YCz_`9l4JJvd?{p?>6v60@13>2M{1F1T6)i z%qiBH0?)LEN#<1+txvtky%*5&(vQ?hv)#6+&XX5|d?vA-Boaqy#P*V~>O-P`qd`S? z40OH@!8~t;x)J3GR9Pukrg`Wr2IIhlahQg>7WoEHgz_N-mx5@!>_PK=r}ZA@P=C=6 zc~<5CbyY)jJHb1kZ~BmRL)|iyT3)6=B1oCY-$^tu8XgB&T^ai+z6uYoo;b^MfO%)) zmYHA$%?4GIzNOoe=t0TiKtKkvZj^7CpOyEvk7h^W4(Fi*Qjsh?cCrXz68oQ3g=p{e q{T5Kw_kRFq{G7p`08-`ERgEtunl_gs*8EQZ0000 + + diff --git a/Source/Editing/CopyPasteManager.cs b/Source/Editing/CopyPasteManager.cs index 4fdf1621..f2922014 100644 --- a/Source/Editing/CopyPasteManager.cs +++ b/Source/Editing/CopyPasteManager.cs @@ -30,6 +30,7 @@ using CodeImp.DoomBuilder.Map; using CodeImp.DoomBuilder.Rendering; using System.Diagnostics; using CodeImp.DoomBuilder.Actions; +using ICSharpCode.SharpZipLib.BZip2; #endregion @@ -48,12 +49,16 @@ namespace CodeImp.DoomBuilder.Editing // Disposing private bool isdisposed = false; + // Last inserted prefab + private string lastprefabfile; + #endregion #region ================== Properties public bool IsDisposed { get { return isdisposed; } } - + public bool IsPreviousPrefabAvailable { get { return (lastprefabfile != null); } } + #endregion #region ================== Constructor / Disposer @@ -86,13 +91,85 @@ namespace CodeImp.DoomBuilder.Editing #endregion - #region ================== Private Methods + #region ================== Methods + + // This makes a prefab of the selection. Returns null when cancelled. + internal MemoryStream MakePrefab() + { + // Let the plugins know + if(General.Plugins.OnCopyBegin()) + { + // Ask the editing mode to prepare selection for copying. + // The edit mode should mark all vertices, lines and sectors + // that need to be copied. + if(General.Editing.Mode.OnCopyBegin()) + { + // Copy the marked geometry + // This links sidedefs that are not linked to a marked sector to a virtual sector + MapSet copyset = General.Map.Map.CloneMarked(); + + // Convert flags and activations to UDMF fields, if needed + if(!(General.Map.FormatInterface is UniversalMapSetIO)) copyset.TranslateToUDMF(); + + // Write data to stream + MemoryStream memstream = new MemoryStream(); + UniversalStreamWriter writer = new UniversalStreamWriter(); + writer.RememberCustomTypes = false; + writer.Write(copyset, memstream, null); + + // Compress the stream + MemoryStream compressed = new MemoryStream((int)memstream.Length); + memstream.Seek(0, SeekOrigin.Begin); + BZip2.Compress(memstream, compressed, 900000); + + // Done + memstream.Dispose(); + General.Editing.Mode.OnCopyEnd(); + General.Plugins.OnCopyEnd(); + return compressed; + } + } + + // Aborted + return null; + } + + // This pastes a prefab. Returns false when paste was cancelled. + internal void PastePrefab(Stream filedata) + { + // Decompress stream + MemoryStream decompressed = new MemoryStream((int)filedata.Length * 3); + filedata.Seek(0, SeekOrigin.Begin); + BZip2.Decompress(filedata, decompressed); + MemoryStream memstream = new MemoryStream(decompressed.ToArray()); + decompressed.Dispose(); + + // Mark all current geometry + General.Map.Map.ClearAllMarks(true); + + // Read data stream + UniversalStreamReader reader = new UniversalStreamReader(); + reader.StrictChecking = false; + reader.Read(General.Map.Map, memstream); + + // The new geometry is not marked, so invert the marks to get it marked + General.Map.Map.InvertAllMarks(); + + // Convert UDMF fields back to flags and activations, if needed + if(!(General.Map.FormatInterface is UniversalMapSetIO)) General.Map.Map.TranslateFromUDMF(); + + // Done + memstream.Dispose(); + General.Map.Map.UpdateConfiguration(); + General.Editing.Mode.OnPasteEnd(); + General.Plugins.OnPasteEnd(); + } // This performs the copy. Returns false when copy was cancelled. private bool DoCopySelection() { // Let the plugins know - if(General.Plugins.OnPasteBegin()) + if(General.Plugins.OnCopyBegin()) { // Ask the editing mode to prepare selection for copying. // The edit mode should mark all vertices, lines and sectors @@ -162,6 +239,7 @@ namespace CodeImp.DoomBuilder.Editing // Done memstream.Dispose(); + General.Map.Map.UpdateConfiguration(); General.Editing.Mode.OnPasteEnd(); General.Plugins.OnPasteEnd(); return true; @@ -181,7 +259,7 @@ namespace CodeImp.DoomBuilder.Editing #endregion - #region ================== Public Methods + #region ================== Actions // This copies the current selection [BeginAction("copyselection")] @@ -219,6 +297,159 @@ namespace CodeImp.DoomBuilder.Editing { DoPasteSelection(); } + + // This creates a new prefab from selection + [BeginAction("createprefab")] + public void CreatePrefab() + { + Cursor oldcursor = Cursor.Current; + Cursor.Current = Cursors.WaitCursor; + + MemoryStream data = MakePrefab(); + if(data != null) + { + Cursor.Current = oldcursor; + + SaveFileDialog savefile = new SaveFileDialog(); + savefile.Filter = "Doom Builder Prefabs (*.dbprefab)|*.dbprefab"; + savefile.Title = "Save Prefab As"; + savefile.AddExtension = true; + savefile.CheckPathExists = true; + savefile.OverwritePrompt = true; + savefile.ValidateNames = true; + if(savefile.ShowDialog(General.MainWindow) == DialogResult.OK) + { + try + { + Cursor.Current = Cursors.WaitCursor; + if(File.Exists(savefile.FileName)) File.Delete(savefile.FileName); + File.WriteAllBytes(savefile.FileName, data.ToArray()); + } + catch(Exception e) + { + Cursor.Current = oldcursor; + General.WriteLogLine("ERROR: " + e.GetType().Name + " while writing prefab to file: " + e.Message); + General.ShowErrorMessage("Error while writing prefab to file! See log file for error details.", MessageBoxButtons.OK); + } + } + } + else + { + // Can't make a prefab right now + General.MessageBeep(MessageBeepType.Warning); + } + + // Done + data.Dispose(); + General.MainWindow.UpdateInterface(); + Cursor.Current = oldcursor; + } + + // This pastes a prefab from file + [BeginAction("insertprefabfile")] + public void InsertPrefabFile() + { + // Cancel volatile mode + General.DisengageVolatileMode(); + + // Let the plugins know + if(General.Plugins.OnPasteBegin()) + { + // Ask the editing mode to prepare selection for pasting. + if(General.Editing.Mode.OnPasteBegin()) + { + Cursor oldcursor = Cursor.Current; + + OpenFileDialog openfile = new OpenFileDialog(); + openfile.Filter = "Doom Builder Prefabs (*.dbprefab)|*.dbprefab"; + openfile.Title = "Open Prefab"; + openfile.AddExtension = false; + openfile.CheckFileExists = true; + openfile.Multiselect = false; + openfile.ValidateNames = true; + if(openfile.ShowDialog(General.MainWindow) == DialogResult.OK) + { + FileStream stream = null; + + try + { + Cursor.Current = Cursors.WaitCursor; + stream = File.OpenRead(openfile.FileName); + } + catch(Exception e) + { + Cursor.Current = oldcursor; + General.WriteLogLine("ERROR: " + e.GetType().Name + " while reading prefab from file: " + e.Message); + General.ShowErrorMessage("Error while reading prefab from file! See log file for error details.", MessageBoxButtons.OK); + } + + if(stream != null) + { + PastePrefab(stream); + lastprefabfile = openfile.FileName; + } + General.MainWindow.UpdateInterface(); + stream.Dispose(); + } + + Cursor.Current = oldcursor; + } + } + } + + // This pastes the previously inserted prefab + [BeginAction("insertpreviousprefab")] + public void InsertPreviousPrefab() + { + // Is there a previously inserted prefab? + if(IsPreviousPrefabAvailable) + { + // Does the file still exist? + if(File.Exists(lastprefabfile)) + { + // Cancel volatile mode + General.DisengageVolatileMode(); + + // Let the plugins know + if(General.Plugins.OnPasteBegin()) + { + // Ask the editing mode to prepare selection for pasting. + if(General.Editing.Mode.OnPasteBegin()) + { + Cursor oldcursor = Cursor.Current; + FileStream stream = null; + + try + { + Cursor.Current = Cursors.WaitCursor; + stream = File.OpenRead(lastprefabfile); + } + catch(Exception e) + { + Cursor.Current = oldcursor; + General.WriteLogLine("ERROR: " + e.GetType().Name + " while reading prefab from file: " + e.Message); + General.ShowErrorMessage("Error while reading prefab from file! See log file for error details.", MessageBoxButtons.OK); + } + + if(stream != null) PastePrefab(stream); + stream.Dispose(); + General.MainWindow.UpdateInterface(); + Cursor.Current = oldcursor; + } + } + } + else + { + General.MessageBeep(MessageBeepType.Warning); + lastprefabfile = null; + General.MainWindow.UpdateInterface(); + } + } + else + { + General.MessageBeep(MessageBeepType.Warning); + } + } #endregion } diff --git a/Source/General/MapManager.cs b/Source/General/MapManager.cs index d78fab68..a63a6fb9 100644 --- a/Source/General/MapManager.cs +++ b/Source/General/MapManager.cs @@ -111,6 +111,7 @@ namespace CodeImp.DoomBuilder internal ConfigurationInfo ConfigSettings { get { return configinfo; } } public GridSetup Grid { get { return grid; } } public UndoManager UndoRedo { get { return undoredo; } } + internal CopyPasteManager CopyPaste { get { return copypaste; } } public IMapSetIO FormatInterface { get { return io; } } internal Launcher Launcher { get { return launcher; } } public ThingsFilter ThingsFilter { get { return thingsfilter; } } diff --git a/Source/Map/UniValue.cs b/Source/Map/UniValue.cs index fdc8d305..2fd73290 100644 --- a/Source/Map/UniValue.cs +++ b/Source/Map/UniValue.cs @@ -112,7 +112,8 @@ namespace CodeImp.DoomBuilder.Map case UniversalType.AngleDegrees: case UniversalType.Float: { - float v = (float)value; + float v = 0.0f; + try { v = (float)value; } catch(NullReferenceException e) { } s.rwFloat(ref v); value = v; break; @@ -130,7 +131,8 @@ namespace CodeImp.DoomBuilder.Map case UniversalType.SectorTag: case UniversalType.ThingTag: { - int v = (int)value; + int v = 0; + try { v = (int)value; } catch(NullReferenceException e) { } s.rwInt(ref v); value = v; break; @@ -138,7 +140,8 @@ namespace CodeImp.DoomBuilder.Map case UniversalType.Boolean: { - bool v = (bool)value; + bool v = false; + try { v = (bool)value; } catch(NullReferenceException e) { } s.rwBool(ref v); value = v; break; diff --git a/Source/Properties/Resources.Designer.cs b/Source/Properties/Resources.Designer.cs index 255a505b..a8299b04 100644 --- a/Source/Properties/Resources.Designer.cs +++ b/Source/Properties/Resources.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:2.0.50727.1826 +// Runtime Version:2.0.50727.1433 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -214,6 +214,20 @@ namespace CodeImp.DoomBuilder.Properties { } } + internal static System.Drawing.Bitmap Prefab { + get { + object obj = ResourceManager.GetObject("Prefab", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + internal static System.Drawing.Bitmap Prefab2 { + get { + object obj = ResourceManager.GetObject("Prefab2", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + internal static System.Drawing.Bitmap Properties { get { object obj = ResourceManager.GetObject("Properties", resourceCulture); diff --git a/Source/Properties/Resources.resx b/Source/Properties/Resources.resx index 6bbdf7b4..7684137f 100644 --- a/Source/Properties/Resources.resx +++ b/Source/Properties/Resources.resx @@ -271,4 +271,10 @@ ..\Resources\Script2.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\Prefab.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Prefab2.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/Source/Resources/Actions.cfg b/Source/Resources/Actions.cfg index 471b5969..0728726c 100644 --- a/Source/Resources/Actions.cfg +++ b/Source/Resources/Actions.cfg @@ -10,6 +10,7 @@ categories view = "View"; modes = "Modes"; tools = "Tools"; + prefabs = "Prefabs"; classic = "Classic Modes"; visual = "Visual Modes"; selecting = "Selecting"; @@ -749,3 +750,32 @@ visualedit disregardshift = true; } +createprefab +{ + title = "Create Prefab"; + category = "prefabs"; + description = "Creates a prefab from the selected geometry and saves it to a prefab file."; + allowkeys = true; + allowmouse = true; + allowscroll = false; +} + +insertprefabfile +{ + title = "Insert Prefab File"; + category = "prefabs"; + description = "Browses for a Prefab file and inserts theprefab geometry into the map."; + allowkeys = true; + allowmouse = true; + allowscroll = false; +} + +insertpreviousprefab +{ + title = "Insert Previous Prefab"; + category = "prefabs"; + description = "Inserts the previously opened Prefab file again."; + allowkeys = true; + allowmouse = true; + allowscroll = false; +} diff --git a/Source/Resources/Prefab.png b/Source/Resources/Prefab.png new file mode 100644 index 0000000000000000000000000000000000000000..54561df439c29d450fb57b72b55c71a5f4ead086 GIT binary patch literal 514 zcmV+d0{#7oP)u0#O)s=|&6{ z9LJGnP)P?76)hwbDkw^+Rj8DZQA9>Wfh84P7ezrq6fFvRP>aA#i)z~{+O&xN(P_Tx z1C?IZfx~^wch2|SGdf)hY#TNfzK$bu(+9cegpe0t&Y59M8KEE1v)1}Lgf)RVw_ONc z^kC>^0=|=OI96pSTV0&yDKkuyCUm4bU`QM8o5V^<0g3%*5hUMp=)Ft8Rq}EZA{kic zt+32mV42Z4ZGjGqUAwIg-&j2&08TX2;4v} zDsb=k_yqLLnbH1`rmF|(7<1GdL3<(vM&WS-Z7TI3$XBXq64!9cLSR`1)g!*)*QlAK z;>LP0-8G(nM5{?#;zpAOVSD0F4BE%P4O)Zz3x4(f4`R~u)Gbr!i2wiq07*qoM6N<$ Eg4kcxSpWb4 literal 0 HcmV?d00001 diff --git a/Source/Resources/Prefab2.png b/Source/Resources/Prefab2.png new file mode 100644 index 0000000000000000000000000000000000000000..c46beb6c2852ea1e826564102191e52fea93b10e GIT binary patch literal 552 zcmV+@0@wYCP)S)o8s_xdA+N|x z--;l0kwMqnFcQa22raA7HtV^(qh5GMJg6P4g=^6DSdpxiG*EK#v=P0ZV`zEEAySHS z2#Emx89#iJKKLdqjr-s#xW2myl)}t7YCz_`9l4JJvd?{p?>6v60@13>2M{1F1T6)i z%qiBH0?)LEN#<1+txvtky%*5&(vQ?hv)#6+&XX5|d?vA-Boaqy#P*V~>O-P`qd`S? z40OH@!8~t;x)J3GR9Pukrg`Wr2IIhlahQg>7WoEHgz_N-mx5@!>_PK=r}ZA@P=C=6 zc~<5CbyY)jJHb1kZ~BmRL)|iyT3)6=B1oCY-$^tu8XgB&T^ai+z6uYoo;b^MfO%)) zmYHA$%?4GIzNOoe=t0TiKtKkvZj^7CpOyEvk7h^W4(Fi*Qjsh?cCrXz68oQ3g=p{e q{T5Kw_kRFq{G7p`08-`ERgEtunl_gs*8EQZ0000 False + + False + True