diff --git a/Source/Core/General/General.cs b/Source/Core/General/General.cs index 4c8a716ed5ed5edf350d68069373c0cf04d1eb91..b36cc5494e2d4af7a65e1aea1b0531ae3976672d 100644 --- a/Source/Core/General/General.cs +++ b/Source/Core/General/General.cs @@ -1048,9 +1048,9 @@ namespace CodeImp.DoomBuilder // Clean up if(map != null) { map.Dispose(); map = null; } if(editing != null) { editing.Dispose(); editing = null; } + if(plugins != null) { plugins.Dispose(); plugins = null; } if(mainwindow != null) { mainwindow.Dispose(); mainwindow = null; } if(actions != null) { actions.Dispose(); actions = null; } - if(plugins != null) { plugins.Dispose(); plugins = null; } if(types != null) { types.Dispose(); types = null; } try { D3DDevice.Terminate(); } catch(Exception) { } diff --git a/Source/Core/General/MurmurHash2.cs b/Source/Core/General/MurmurHash2.cs index da5e7e48d129c7e0457bcae5a626477e995df985..98c1e560741e7f5ecbcc4fb02911ce96835c65ba 100644 --- a/Source/Core/General/MurmurHash2.cs +++ b/Source/Core/General/MurmurHash2.cs @@ -44,7 +44,7 @@ using System.Text; namespace CodeImp.DoomBuilder { - internal static class MurmurHash2 + public static class MurmurHash2 { private const UInt32 m = 0x5bd1e995; private const Int32 r = 24; diff --git a/Source/Core/Plugins/Plugin.cs b/Source/Core/Plugins/Plugin.cs index 6c7d58a5e386dc74270ba36ddf6fe6545c73eb2e..02934e344d1a38e816a445780fafb4fbaf051399 100644 --- a/Source/Core/Plugins/Plugin.cs +++ b/Source/Core/Plugins/Plugin.cs @@ -42,7 +42,7 @@ namespace CodeImp.DoomBuilder.Plugins private Plug plug; // Unique name used to refer to this assembly - private string name; + private readonly string name; // Disposing private bool isdisposed; @@ -122,6 +122,8 @@ namespace CodeImp.DoomBuilder.Plugins if(!isdisposed) { // Clean up + plug.Dispose(); //mxd + plug = null; //mxd asm = null; // Done diff --git a/Source/Core/Plugins/PluginManager.cs b/Source/Core/Plugins/PluginManager.cs index 440507b8a1131f2088c70e40b500acf5564cdc87..cfc6a2776099862e38c54487fe332fd70ac3fbb4 100644 --- a/Source/Core/Plugins/PluginManager.cs +++ b/Source/Core/Plugins/PluginManager.cs @@ -217,7 +217,7 @@ namespace CodeImp.DoomBuilder.Plugins // Go for all plugins the find the one with matching assembly foreach(Plugin p in plugins) { - if(p.Assembly == assembly) return p; + if(Equals(p.Assembly, assembly)) return p; } // Nothing found diff --git a/Source/Core/Properties/AssemblyInfo.cs b/Source/Core/Properties/AssemblyInfo.cs index ba444623bfff97074cf69e66a6bf5982e56dee3b..ce6ac15f3944b0239a213f9bde28e789b2008216 100644 --- a/Source/Core/Properties/AssemblyInfo.cs +++ b/Source/Core/Properties/AssemblyInfo.cs @@ -28,4 +28,4 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("2.3.0.2201")] \ No newline at end of file +[assembly: AssemblyVersion("2.3.0.2411")] \ No newline at end of file diff --git a/Source/Core/VisualModes/VisualCamera.cs b/Source/Core/VisualModes/VisualCamera.cs index 66af0f51853be3d947ae75374171486384c8d70e..cdd649b4f822ddda72347ed64ebd8cdafc00b241 100644 --- a/Source/Core/VisualModes/VisualCamera.cs +++ b/Source/Core/VisualModes/VisualCamera.cs @@ -30,7 +30,6 @@ namespace CodeImp.DoomBuilder.VisualModes private float anglexy, anglez; private Sector sector; private float gravity = 1.0f; //mxd - private bool udmf; //mxd #endregion @@ -56,7 +55,6 @@ namespace CodeImp.DoomBuilder.VisualModes anglexy = 0.0f; anglez = Angle2D.PI; sector = null; - udmf = General.Map.UDMF; //mxd PositionAtThing(); } @@ -101,12 +99,18 @@ namespace CodeImp.DoomBuilder.VisualModes // Returns false when it couldn't find a 3D Camera Thing public virtual bool PositionAtThing() { + if(General.Settings.GZSynchCameras) return true; //mxd Thing modething = null; - Vector3D delta; - + // Find a 3D Mode thing foreach(Thing t in General.Map.Map.Things) - if(t.Type == General.Map.Config.Start3DModeThingType) modething = t; + { + if(t.Type == General.Map.Config.Start3DModeThingType) + { + modething = t; + break; //mxd + } + } // Found one? if(modething != null) @@ -118,7 +122,7 @@ namespace CodeImp.DoomBuilder.VisualModes // Position camera here Vector3D wantedposition = new Vector3D(modething.Position.x, modething.Position.y, z + THING_Z_OFFSET); - delta = position - wantedposition; + Vector3D delta = position - wantedposition; if(delta.GetLength() > 1.0f) position = wantedposition; // Change angle @@ -138,11 +142,18 @@ namespace CodeImp.DoomBuilder.VisualModes // Returns false when it couldn't find a 3D Camera Thing public virtual bool ApplyToThing() { + if(General.Settings.GZSynchCameras) return true; //mxd Thing modething = null; // Find a 3D Mode thing foreach(Thing t in General.Map.Map.Things) - if(t.Type == General.Map.Config.Start3DModeThingType) modething = t; + { + if(t.Type == General.Map.Config.Start3DModeThingType) + { + modething = t; + break; //mxd + } + } // Found one? if(modething != null) @@ -162,7 +173,7 @@ namespace CodeImp.DoomBuilder.VisualModes //mxd private void UpdateGravity() { - if(!udmf || sector == null) return; + if(!General.Map.UDMF || sector == null) return; gravity = sector.Fields.GetValue("gravity", 1.0f); } diff --git a/Source/Core/VisualModes/VisualThing.cs b/Source/Core/VisualModes/VisualThing.cs index d2d89fde67e19c9fc70637629aea976a3a624462..6873d3293d65d9bd77cbde0989d968bca894f69f 100644 --- a/Source/Core/VisualModes/VisualThing.cs +++ b/Source/Core/VisualModes/VisualThing.cs @@ -227,11 +227,85 @@ namespace CodeImp.DoomBuilder.VisualModes } /// <summary> - /// Sets the color of the cage around the thing geometry. + /// Sets the color of the cage around the thing geometry and rebuilds the thing cage. /// </summary> - protected void SetCageColor(PixelColor color) + protected void UpdateThingCage(PixelColor color) { cagecolor = color.ToColorValue(); + + // Trash cage buffer + if(cagebuffer != null) cagebuffer.Dispose(); + cagebuffer = null; + + // Make a new cage + List<WorldVertex> cageverts; + if(sizeless) + { + WorldVertex v0 = new WorldVertex(-info.Radius + position_v3.X, -info.Radius + position_v3.Y, position_v3.Z); + WorldVertex v1 = new WorldVertex(info.Radius + position_v3.X, info.Radius + position_v3.Y, position_v3.Z); + WorldVertex v2 = new WorldVertex(info.Radius + position_v3.X, -info.Radius + position_v3.Y, position_v3.Z); + WorldVertex v3 = new WorldVertex(-info.Radius + position_v3.X, info.Radius + position_v3.Y, position_v3.Z); + WorldVertex v4 = new WorldVertex(position_v3.X, position_v3.Y, info.Radius + position_v3.Z); + WorldVertex v5 = new WorldVertex(position_v3.X, position_v3.Y, -info.Radius + position_v3.Z); + + cageverts = new List<WorldVertex>(new[] { v0, v1, v2, v3, v4, v5 }); + } + else + { + float top = position_v3.Z + info.Height; + float bottom = position_v3.Z; + + WorldVertex v0 = new WorldVertex(-info.Radius + position_v3.X, -info.Radius + position_v3.Y, bottom); + WorldVertex v1 = new WorldVertex(-info.Radius + position_v3.X, info.Radius + position_v3.Y, bottom); + WorldVertex v2 = new WorldVertex(info.Radius + position_v3.X, info.Radius + position_v3.Y, bottom); + WorldVertex v3 = new WorldVertex(info.Radius + position_v3.X, -info.Radius + position_v3.Y, bottom); + + WorldVertex v4 = new WorldVertex(-info.Radius + position_v3.X, -info.Radius + position_v3.Y, top); + WorldVertex v5 = new WorldVertex(-info.Radius + position_v3.X, info.Radius + position_v3.Y, top); + WorldVertex v6 = new WorldVertex(info.Radius + position_v3.X, info.Radius + position_v3.Y, top); + WorldVertex v7 = new WorldVertex(info.Radius + position_v3.X, -info.Radius + position_v3.Y, top); + + cageverts = new List<WorldVertex>(new[] { v0, v1, + v1, v2, + v2, v3, + v3, v0, + v4, v5, + v5, v6, + v6, v7, + v7, v4, + v0, v4, + v1, v5, + v2, v6, + v3, v7 }); + } + + // Make new arrow + if(Thing.IsDirectional) + { + Matrix transform = Matrix.Scaling(info.Radius, info.Radius, info.Radius) + * (Matrix.RotationY(-Thing.RollRad) * Matrix.RotationX(-Thing.PitchRad) * Matrix.RotationZ(Thing.Angle)) + * (sizeless ? position : position * Matrix.Translation(0.0f, 0.0f, thingheight / 2f)); + + WorldVertex a0 = new WorldVertex(Vector3D.Transform(0.0f, 0.0f, 0.0f, transform)); //start + WorldVertex a1 = new WorldVertex(Vector3D.Transform(0.0f, -1.5f, 0.0f, transform)); //end + WorldVertex a2 = new WorldVertex(Vector3D.Transform(0.2f, -1.1f, 0.2f, transform)); + WorldVertex a3 = new WorldVertex(Vector3D.Transform(-0.2f, -1.1f, 0.2f, transform)); + WorldVertex a4 = new WorldVertex(Vector3D.Transform(0.2f, -1.1f, -0.2f, transform)); + WorldVertex a5 = new WorldVertex(Vector3D.Transform(-0.2f, -1.1f, -0.2f, transform)); + + cageverts.AddRange(new[] { a0, a1, + a1, a2, + a1, a3, + a1, a4, + a1, a5 }); + } + + // Create buffer + WorldVertex[] cv = cageverts.ToArray(); + cagelength = cv.Length / 2; + cagebuffer = new VertexBuffer(General.Map.Graphics.Device, WorldVertex.Stride * cv.Length, Usage.WriteOnly | Usage.Dynamic, VertexFormat.None, Pool.Default); + cagebuffer.Lock(0, WorldVertex.Stride * cv.Length, LockFlags.None).WriteRange(cv); + cagebuffer.Unlock(); } /// <summary> @@ -387,7 +461,7 @@ namespace CodeImp.DoomBuilder.VisualModes if(updategeo) { // Trash geometry buffer - if (geobuffer != null) geobuffer.Dispose(); + if(geobuffer != null) geobuffer.Dispose(); geobuffer = null; // Any vertics? @@ -403,80 +477,6 @@ namespace CodeImp.DoomBuilder.VisualModes geobuffer.Unlock(); bufferstream.Dispose(); } - - // Trash cage buffer - if(cagebuffer != null) cagebuffer.Dispose(); - cagebuffer = null; - - // Make a new cage - List<WorldVertex> cageverts; - if(sizeless) - { - WorldVertex v0 = new WorldVertex(-info.Radius + position_v3.X, -info.Radius + position_v3.Y, position_v3.Z); - WorldVertex v1 = new WorldVertex( info.Radius + position_v3.X, info.Radius + position_v3.Y, position_v3.Z); - WorldVertex v2 = new WorldVertex( info.Radius + position_v3.X, -info.Radius + position_v3.Y, position_v3.Z); - WorldVertex v3 = new WorldVertex(-info.Radius + position_v3.X, info.Radius + position_v3.Y, position_v3.Z); - WorldVertex v4 = new WorldVertex(position_v3.X, position_v3.Y, info.Radius + position_v3.Z); - WorldVertex v5 = new WorldVertex(position_v3.X, position_v3.Y, -info.Radius + position_v3.Z); - - cageverts = new List<WorldVertex>(new[] { v0, v1, v2, v3, v4, v5 }); - } - else - { - float top = position_v3.Z + info.Height; - float bottom = position_v3.Z; - - WorldVertex v0 = new WorldVertex(-info.Radius + position_v3.X, -info.Radius + position_v3.Y, bottom); - WorldVertex v1 = new WorldVertex(-info.Radius + position_v3.X, info.Radius + position_v3.Y, bottom); - WorldVertex v2 = new WorldVertex( info.Radius + position_v3.X, info.Radius + position_v3.Y, bottom); - WorldVertex v3 = new WorldVertex( info.Radius + position_v3.X, -info.Radius + position_v3.Y, bottom); - - WorldVertex v4 = new WorldVertex(-info.Radius + position_v3.X, -info.Radius + position_v3.Y, top); - WorldVertex v5 = new WorldVertex(-info.Radius + position_v3.X, info.Radius + position_v3.Y, top); - WorldVertex v6 = new WorldVertex( info.Radius + position_v3.X, info.Radius + position_v3.Y, top); - WorldVertex v7 = new WorldVertex( info.Radius + position_v3.X, -info.Radius + position_v3.Y, top); - - cageverts = new List<WorldVertex>(new[] { v0, v1, - v1, v2, - v2, v3, - v3, v0, - v4, v5, - v5, v6, - v6, v7, - v7, v4, - v0, v4, - v1, v5, - v2, v6, - v3, v7 }); - } - - // Make new arrow - if(Thing.IsDirectional) - { - Matrix transform = Matrix.Scaling(info.Radius, info.Radius, info.Radius) - * (Matrix.RotationY(-Thing.RollRad) * Matrix.RotationX(-Thing.PitchRad) * Matrix.RotationZ(Thing.Angle)) - * (sizeless ? position : position * Matrix.Translation(0.0f, 0.0f, thingheight / 2f)); - - WorldVertex a0 = new WorldVertex(Vector3D.Transform( 0.0f, 0.0f, 0.0f, transform)); //start - WorldVertex a1 = new WorldVertex(Vector3D.Transform( 0.0f, -1.5f, 0.0f, transform)); //end - WorldVertex a2 = new WorldVertex(Vector3D.Transform( 0.2f, -1.1f, 0.2f, transform)); - WorldVertex a3 = new WorldVertex(Vector3D.Transform(-0.2f, -1.1f, 0.2f, transform)); - WorldVertex a4 = new WorldVertex(Vector3D.Transform( 0.2f, -1.1f, -0.2f, transform)); - WorldVertex a5 = new WorldVertex(Vector3D.Transform(-0.2f, -1.1f, -0.2f, transform)); - - cageverts.AddRange(new[] {a0, a1, - a1, a2, - a1, a3, - a1, a4, - a1, a5}); - } - - // Create buffer - WorldVertex[] cv = cageverts.ToArray(); - cagelength = cv.Length / 2; - cagebuffer = new VertexBuffer(General.Map.Graphics.Device, WorldVertex.Stride * cv.Length, Usage.WriteOnly | Usage.Dynamic, VertexFormat.None, Pool.Default); - cagebuffer.Lock(0, WorldVertex.Stride * cv.Length, LockFlags.None).WriteRange(cv); - cagebuffer.Unlock(); //mxd. Check if thing is light CheckLightState(); diff --git a/Source/Core/Windows/MainForm.cs b/Source/Core/Windows/MainForm.cs index d78d2e0ce34fcaeb5d6d4ba6e3efb70b4bc742d4..0a58b8b24095fddc5fa7c9af31d7a8a19876732b 100644 --- a/Source/Core/Windows/MainForm.cs +++ b/Source/Core/Windows/MainForm.cs @@ -4018,6 +4018,7 @@ namespace CodeImp.DoomBuilder.Windows #endregion #region ================== Dockers + // This adds a docker public void AddDocker(Docker d) { @@ -4033,9 +4034,11 @@ namespace CodeImp.DoomBuilder.Windows // This removes a docker public bool RemoveDocker(Docker d) { + if(!dockerspanel.Contains(d)) return true; //mxd. Already removed/never added + // Make sure the full name is set with the plugin name as prefix - Plugin plugin = General.Plugins.FindPluginByAssembly(Assembly.GetCallingAssembly()); - d.MakeFullName(plugin.Name.ToLowerInvariant()); + //Plugin plugin = General.Plugins.FindPluginByAssembly(Assembly.GetCallingAssembly()); + //d.MakeFullName(plugin.Name.ToLowerInvariant()); // We must release all keys because the focus may be stolen when // this was the selected docker (the previous docker is automatically selected) @@ -4047,6 +4050,8 @@ namespace CodeImp.DoomBuilder.Windows // This selects a docker public bool SelectDocker(Docker d) { + if(!dockerspanel.Contains(d)) return false; //mxd + // Make sure the full name is set with the plugin name as prefix Plugin plugin = General.Plugins.FindPluginByAssembly(Assembly.GetCallingAssembly()); d.MakeFullName(plugin.Name.ToLowerInvariant()); diff --git a/Source/Plugins/BuilderModes/General/BuilderPlug.cs b/Source/Plugins/BuilderModes/General/BuilderPlug.cs index a505f693a53b6909e873c2b9d7a831058974aa20..cfd9f3103d6e6f7f0a0607c4a97c83ebe42dd477 100644 --- a/Source/Plugins/BuilderModes/General/BuilderPlug.cs +++ b/Source/Plugins/BuilderModes/General/BuilderPlug.cs @@ -220,12 +220,23 @@ namespace CodeImp.DoomBuilder.BuilderModes menusform.Unregister(); menusform.Dispose(); menusform = null; - curvelinedefsform.Dispose(); - curvelinedefsform = null; - findreplaceform.Dispose(); - findreplaceform = null; - errorcheckform.Dispose(); - errorcheckform = null; + + //mxd. These are created on demand, so they may be nulls. + if(curvelinedefsform != null) + { + curvelinedefsform.Dispose(); + curvelinedefsform = null; + } + if(findreplaceform != null) + { + findreplaceform.Dispose(); + findreplaceform = null; + } + if(errorcheckform != null) + { + errorcheckform.Dispose(); + errorcheckform = null; + } // Done me = null; diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs index c2e61ae7511f313d73f033ad73e0cd3bb003ca13..ab92a700355d6e6ea307066ad0762475bbd74b5d 100644 --- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs +++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs @@ -414,7 +414,7 @@ namespace CodeImp.DoomBuilder.BuilderModes // Apply settings SetPosition(pos); - SetCageColor(Thing.Color); + UpdateThingCage(Thing.Color); // Keep info for object picking cageradius2 = thingradius * Angle2D.SQRT2; diff --git a/Source/Plugins/VisplaneExplorer/BuilderPlug.cs b/Source/Plugins/VisplaneExplorer/BuilderPlug.cs index 5c7cb56aaba8f91f7b565769deb4650fe0b7535b..bdc6f28c4262e450b9bb1b1a547e0cafcd86fd9f 100644 --- a/Source/Plugins/VisplaneExplorer/BuilderPlug.cs +++ b/Source/Plugins/VisplaneExplorer/BuilderPlug.cs @@ -17,6 +17,7 @@ #region ================== Namespaces using System; +using System.Globalization; using System.IO; using CodeImp.DoomBuilder.Plugins.VisplaneExplorer.Properties; using CodeImp.DoomBuilder.Windows; @@ -33,6 +34,7 @@ namespace CodeImp.DoomBuilder.Plugins.VisplaneExplorer private static BuilderPlug me; private VPOManager vpo; private InterfaceForm interfaceform; + private bool enabled; //mxd // Palettes private Palette[] palettes; @@ -42,55 +44,31 @@ namespace CodeImp.DoomBuilder.Plugins.VisplaneExplorer #region ================== Properties // Properties - public static BuilderPlug Me { get { return me; } } public override string Name { get { return "VisplaneExplorer"; } } internal static VPOManager VPO { get { return me.vpo; } } internal static InterfaceForm InterfaceForm { get { return me.interfaceform; } } - internal static Palette[] Palettes { get { return me.palettes; } } - public override int MinimumRevision { get { return 1545; } } + internal static Palette[] Palettes { get { return me.GetPalettes(); } } + public override int MinimumRevision { get { return 2411; } } #endregion #region ================== Initialize / Dispose - // This event is called when the plugin is initialized - public override void OnInitialize() + //mxd. Initialize when we can check the map format + public override void OnMapNewEnd() { OnMapOpenEnd(); } + public override void OnMapOpenEnd() { - base.OnInitialize(); - - //General.Actions.BindMethods(this); //mxd. But... we have no methods to bind! - - // Load interface controls - interfaceform = new InterfaceForm(); - - // Load VPO manager (manages multithreading and communication with vpo.dll) - vpo = new VPOManager(); - - // Keep a static reference - me = this; - } + enabled = (General.Map.DOOM || General.Map.HEXEN); + if(enabled) + { + // Load interface controls + interfaceform = new InterfaceForm(); - //mxd. This, actually, can also happen - public override void OnMapNewBegin() - { - OnMapOpenBegin(); - } + // Load VPO manager (manages multithreading and communication with vpo.dll) + vpo = new VPOManager(); - // Some things cannot be initialized at plugin start, so we do them here - public override void OnMapOpenBegin() - { - base.OnMapOpenBegin(); - - if (palettes == null) - { - // Load palettes - palettes = new Palette[(int)ViewStats.NumStats]; - palettes[(int)ViewStats.Visplanes] = new Palette(Resources.Visplanes_pal); - palettes[(int)ViewStats.Drawsegs] = new Palette(Resources.Drawsegs_pal); - palettes[(int)ViewStats.Solidsegs] = new Palette(Resources.Solidsegs_pal); - palettes[(int)ViewStats.Openings] = new Palette(Resources.Openings_pal); - palettes[(int)ViewStats.Heatmap] = new Palette(Resources.Heatmap_pal); //mxd - ApplyUserColors(); + // Keep a static reference + me = this; } } @@ -104,45 +82,69 @@ namespace CodeImp.DoomBuilder.Plugins.VisplaneExplorer // This is called when the plugin is terminated public override void Dispose() { - // Clean up - interfaceform.Dispose(); - interfaceform = null; - vpo.Dispose(); - vpo = null; - base.Dispose(); + //mxd. Active and not already disposed? + if(!IsDisposed) + { + if(enabled) + { + // Clean up + interfaceform.Dispose(); + interfaceform = null; + vpo.Dispose(); + vpo = null; + + // Done + me = null; + } + + base.Dispose(); + } } #endregion #region ================== Methods + //mxd + private Palette[] GetPalettes() + { + if(palettes == null) + { + // Load palettes + palettes = new Palette[(int)ViewStats.NumStats]; + palettes[(int)ViewStats.Visplanes] = new Palette(Resources.Visplanes_pal); + palettes[(int)ViewStats.Drawsegs] = new Palette(Resources.Drawsegs_pal); + palettes[(int)ViewStats.Solidsegs] = new Palette(Resources.Solidsegs_pal); + palettes[(int)ViewStats.Openings] = new Palette(Resources.Openings_pal); + palettes[(int)ViewStats.Heatmap] = new Palette(Resources.Heatmap_pal); //mxd + ApplyUserColors(); + } + return palettes; + } + // This applies user-defined appearance colors to the palettes private void ApplyUserColors() { - if(palettes != null) + //mxd + if(palettes == null) { - // Override special palette indices with user-defined colors - for(int i = 0; i < palettes.Length; i++) - { - palettes[i].SetColor(Tile.POINT_VOID_B, General.Colors.Background.WithAlpha(0).ToInt()); - } + GetPalettes(); + return; } + + // Override special palette indices with user-defined colors + foreach(Palette p in palettes) p.SetColor(Tile.POINT_VOID_B, General.Colors.Background.WithAlpha(0).ToInt()); } // This returns a unique temp filename public static string MakeTempFilename(string extension) { string filename; - string chars = "abcdefghijklmnopqrstuvwxyz1234567890"; - Random rnd = new Random(); - int i; do { - // Generate a filename - filename = ""; - for(i = 0; i < 8; i++) filename += chars[rnd.Next(chars.Length)]; - filename = Path.Combine(General.TempPath, filename + extension); + //mxd. Generate a filename + filename = Path.Combine(General.TempPath, MurmurHash2.Hash(DateTime.Now.Ticks.ToString(CultureInfo.InvariantCulture)) + extension); } // Continue while file is not unique while(File.Exists(filename) || Directory.Exists(filename));