From 8891395b3a5588925478049a6f8a8ea3fb6c6523 Mon Sep 17 00:00:00 2001
From: MaxED <j.maxed@gmail.com>
Date: Thu, 12 Jul 2012 22:34:12 +0000
Subject: [PATCH] Fixed incorrect dragging of floor/ceiling textures with
 "rotationfloor" / "rotationceiling" UDMF property set in GZDoom Visual Mode.
 Replaced all doubles with floats. Script Editor: Navigator drop-down now
 updates automatically. Navigator drop-down now also works for external files.
 Added Navigator drop-down support for Decorate and Modeldef.

---
 .../Configurations/Includes/ZDoom_common.cfg  |   8 +-
 Build/Scripting/ZDoom_DECORATE.cfg            | 238 ++++++++++++++++++
 Help/gz_cfg_settings.html                     |   2 +-
 Source/Core/Builder.csproj                    |   4 +-
 Source/Core/Compilers/Compiler.cs             |   2 +-
 Source/Core/Controls/ScriptDocumentTab.cs     | 140 +++++++++++
 Source/Core/Controls/ScriptFileDocumentTab.cs |   5 +
 Source/Core/Controls/ScriptLumpDocumentTab.cs |  55 +---
 Source/Core/Data/DataManager.cs               |  14 +-
 Source/Core/Editing/ClassicMode.cs            |   6 +-
 Source/Core/Editing/EditMode.cs               |   2 +-
 Source/Core/GZBuilder/Data/GameType.cs        |  12 +-
 Source/Core/GZBuilder/Data/ModelDefEntry.cs   |  22 +-
 Source/Core/GZBuilder/Data/ScriptItem.cs      |  26 +-
 .../AcsParser.cs => GZDoom/AcsParserSE.cs}    |  11 +-
 .../Core/GZBuilder/GZDoom/DecorateParserSE.cs |  56 +++++
 Source/Core/GZBuilder/GZDoom/GldefsParser.cs  |   2 +-
 Source/Core/GZBuilder/GZDoom/MapinfoParser.cs |   2 +-
 .../Core/GZBuilder/GZDoom/ModeldefParser.cs   |   8 +-
 .../Core/GZBuilder/GZDoom/ModeldefParserSE.cs |  49 ++++
 .../GZBuilder/GZDoom/ModeldefStructure.cs     |   4 +-
 Source/Core/General/Clock.cs                  |   2 +-
 Source/Core/General/MapManager.cs             |   8 +-
 Source/Core/Geometry/Vector2D.cs              |  10 +-
 Source/Core/IO/DoomMapSetIO.cs                |   4 +-
 Source/Core/IO/HexenMapSetIO.cs               |   4 +-
 Source/Core/IO/IMapSetIO.cs                   |   4 +-
 Source/Core/IO/MapSetIO.cs                    |   4 +-
 Source/Core/IO/UniversalMapSetIO.cs           |   4 +-
 Source/Core/Map/MapSet.cs                     |   6 +-
 Source/Core/Rendering/Renderer3D.cs           |   2 +-
 Source/Core/VisualModes/VisualMode.cs         |  18 +-
 Source/Core/VisualModes/VisualThing.cs        |   2 +-
 Source/Core/Windows/MainForm.cs               |   6 +-
 .../ClassicModes/CurveLinedefsMode.cs         |  20 +-
 .../ClassicModes/MakeSectorMode.cs            |  12 +-
 .../VisualModes/BaseVisualGeometrySector.cs   |   2 +-
 .../VisualModes/BaseVisualGeometrySidedef.cs  |   2 +-
 .../VisualModes/BaseVisualMode.cs             |   6 +-
 .../VisualModes/BaseVisualThing.cs            |   2 +-
 .../VisualModes/IVisualEventReceiver.cs       |   2 +-
 .../VisualModes/NullVisualEventReceiver.cs    |   2 +-
 Source/Plugins/ColorPicker/ColorHandler.cs    |  46 ++--
 Source/Plugins/ColorPicker/ColorWheel.cs      |  26 +-
 .../VisualModes/BaseVisualGeometrySector.cs   |  17 +-
 .../VisualModes/BaseVisualGeometrySidedef.cs  |   2 +-
 .../VisualModes/BaseVisualMode.cs             |   8 +-
 .../VisualModes/BaseVisualThing.cs            |   2 +-
 .../VisualModes/IVisualEventReceiver.cs       |   2 +-
 .../VisualModes/NullVisualEventReceiver.cs    |   2 +-
 .../UMDFControls/Controls/AngleControl.cs     |   2 +-
 .../UMDFControls/Windows/UDMFControlsForm.cs  |   2 +-
 52 files changed, 681 insertions(+), 218 deletions(-)
 create mode 100644 Build/Scripting/ZDoom_DECORATE.cfg
 rename Source/Core/GZBuilder/{ZDoom/AcsParser.cs => GZDoom/AcsParserSE.cs} (85%)
 create mode 100644 Source/Core/GZBuilder/GZDoom/DecorateParserSE.cs
 create mode 100644 Source/Core/GZBuilder/GZDoom/ModeldefParserSE.cs

diff --git a/Build/Configurations/Includes/ZDoom_common.cfg b/Build/Configurations/Includes/ZDoom_common.cfg
index d8cf825c7..5e0a0a047 100644
--- a/Build/Configurations/Includes/ZDoom_common.cfg
+++ b/Build/Configurations/Includes/ZDoom_common.cfg
@@ -381,7 +381,7 @@ game_doom
 {
 	// Default lump name for new map
 	defaultlumpname = "MAP01";
-	basegame = 0; //mxd: 0 - DOOM, 1 - HERETIC, 2 - HEXEN, 3 - STRIFE, 4 - UNKNOWN
+	basegame = 1; //mxd: 0 - UNKNOWN, 1 - DOOM, 2 - HERETIC, 3 - HEXEN, 4 - STRIFE, 
 
 	// Decorate actors to include depending on actor game property
 	decorategames = "doom";
@@ -420,7 +420,7 @@ game_heretic
 {
 	// Default lump name for new map
 	defaultlumpname = "MAP01";
-	basegame = 1;
+	basegame = 2;
 
 	// Decorate actors to include depending on actor game property
 	decorategames = "heretic raven";
@@ -460,7 +460,7 @@ game_hexen
 	// Default lump name for new map
 	defaultlumpname = "MAP01";
 	skyflatname = "F_SKY";
-	basegame = 2;
+	basegame = 3;
 
 	// Decorate actors to include depending on actor game property
 	decorategames = "hexen raven";
@@ -500,7 +500,7 @@ game_strife
 	// Default lump name for new map
 	defaultlumpname = "MAP01";
 	skyflatname = "F_SKY001";
-	basegame = 3;
+	basegame = 4;
 
 	// Decorate actors to include depending on actor game property
 	decorategames = "strife";
diff --git a/Build/Scripting/ZDoom_DECORATE.cfg b/Build/Scripting/ZDoom_DECORATE.cfg
new file mode 100644
index 000000000..1a74e3a58
--- /dev/null
+++ b/Build/Scripting/ZDoom_DECORATE.cfg
@@ -0,0 +1,238 @@
+/*******************************************************************\
+	GZDoom Builder Script highlighting definitions for DECORATE
+\*******************************************************************/
+
+// Editor settings
+description = "ZDoom DECORATE";
+codepage = 0;
+extensions = "txt";
+casesensitive = false;
+insertcase = 1;				// 0=Normal, 1=Lowercase, 2=Uppercase
+lexer = 35;					// CPP-style, case-insensitive
+terminator = ";";
+keywordhelp = "http://www.zdoom.org/wiki/index.php?title=%K";
+
+keywords
+{
+	#Include = "#Include";
+//Monster AI
+  A_AlertMonsters = "A_AlertMonsters(float maxrange)";
+	A_Burst = "A_Burst(string classname)";
+	A_CentaurDefend = "A_CentaurDefend";
+	A_Chase = "A_Chase[(str \"MeleeState\"[, str \"RangedState\"[, int Flags]])]";
+	A_ClearLastHeard = "A_ClearLastHeard";
+	A_ClearSoundTarget = "A_ClearSoundTarget";
+	A_ClearTarget = "A_ClearTarget";
+	A_DamageChildren = "A_DamageChildren(int amount, [string type])";
+	A_DamageMaster = "A_DamageMaster(int amount, [string type])";
+	A_DamageSiblings = "A_DamageSiblings(int amount, [string type])";
+	A_Die = "A_Die[(str DamageType)]";
+	A_FaceTarget = "A_FaceTarget[(float angle)[, float pitch]]";
+	A_FaceMaster = "A_FaceMaster[(float angle)[, float pitch]]";
+	A_KillChildren = "A_KillChildren(string damagetype)";
+  A_KillMaster = "A_KillMaster(string damagetype)";
+  A_KillSiblings = "A_KillSiblings(string damagetype)";
+  A_Look2 = "A_Look2";
+  A_LookEx = "A_LookEx(int flags, fixed minseedist, fixed maxseedist, fixed maxheardist, fixed fov, state seestate)";
+  A_RaiseChildren = "A_RaiseChildren";
+  A_RaiseMaster = "A_RaiseMaster";
+  A_RaiseSiblings = "A_RaiseSiblings";
+  A_RemoveChildren = "A_RemoveChildren[(bool all)]";
+  A_RemoveMaster = "A_RemoveMaster";
+  A_RemoveSiblings = "A_RemoveSiblings[(bool all)]";
+  A_SentinelBob = "A_SentinelBob";
+  A_Teleport = "A_Teleport[(string teleportstate[, string targettype[, string fogtype[, int flags[, float mindist[, float maxdist]]]]])]";
+  A_VileChase = "A_VileChase";
+  A_Wander = "A_Wander";
+}
+
+constants
+{
+//combo flags
+  Monster;
+  Projectile;
+//physics
+  SOLID;
+  SHOOTABLE;
+  FLOAT;
+  NOGRAVITY;
+  WINDTHRUST;
+  PUSHABLE;
+  DONTFALL;
+  CANPASS;
+  ACTLIKEBRIDGE;
+  NOBLOCKMAP;
+  MOVEWITHSECTOR;
+  NOLIFTDROP;
+  SLIDESONWALLS;
+  NODROPOFF;
+  NOTRIGGER;
+  BLOCKEDBYSOLIDACTORS;
+//Behavior
+  ALWAYSRESPAWN;
+  AMBUSH;
+  AVOIDMELEE;
+  BOSS;
+  DONTCORPSE;
+  DORMANT;
+  FRIENDLY;
+  JUMPDOWN;
+  LOOKALLAROUND;
+  MISSILEEVENMORE;
+  MISSILEMORE;
+  NEVERRESPAWN;
+  NOSPLASHALERT;
+  NOTARGETSWITCH;
+  NOVERTICALMELEERANGE;
+  QUICKTORETALIATE;
+  STANDSTILL;
+//(In)Abilities
+  CANNOTPUSH;
+  NOTELEPORT;
+  ACTIVATEIMPACT;
+  CANPUSHWALLS;
+  CANUSEWALLS;
+  ACTIVATEPCROSS;
+  CANTLEAVEFLOORPIC;
+  TELESTOMP;
+  STAYMORPHED;
+  CANBLAST;
+  NOBLOCKMONST;
+  THRUGHOST;
+  THRUACTORS;
+  THRUSPECIES;
+  MTHRUSPECIES;
+  SPECTRAL;
+  FRIGHTENED;
+  NOTARGET;
+  NOINFIGHTING;
+  NOTIMEFREEZE;
+  NOFEAR;
+  CANTSEEK;
+  SEEINVISIBLE;
+//Defenses
+  INVULNERABLE;
+  REFLECTIVE;
+  SHIELDREFLECT;
+  DEFLECT;
+  NORADIUSDMG;
+  DONTBLAST;
+  GHOST;
+  DONTMORPH;
+  DONTSQUASH;
+  NOTELEOTHER;
+  DOHARMSPECIES;
+  DONTHARMCLASS;
+  DONTHARMSPECIES;
+  NODAMAGE;
+  DONTRIP;
+  NOTELEFRAG;
+//Appearance & Sound
+  BRIGHT;
+  INVISIBLE;
+  SHADOW;
+  NOBLOOD;
+  NOBLOODDECALS;
+  STEALTH;
+  FLOORCLIP;
+  SPAWNFLOAT;
+  SPAWNCEILING;
+  FLOATBOB;
+  NOICEDEATH;
+  DONTGIB;
+  DONTSPLASH;
+  DONTOVERLAP;
+  RANDOMIZE;
+  FIXMAPTHINGPOS;
+  FULLVOLACTIVE;
+  FULLVOLDEATH;
+  NOWALLBOUNCESND;
+  VISIBILITYPULSE;
+  ROCKETTRAIL;
+  GRENADETRAIL;
+  NOBOUNCESOUND;
+  NOSKIN;
+  DONTTRANSLATE;
+  NOPAIN;
+  FORCEYBILLBOARD;
+  FORCEXYBILLBOARD;
+//Projectile
+  MISSILE;
+  RIPPER;
+  NOBOSSRIP;
+  NODAMAGETHRUST;
+  DONTREFLECT;
+  FLOORHUGGER;
+  CEILINGHUGGER;
+  BLOODLESSIMPACT;
+  BLOODSPLATTER;
+  FOILINVUL;
+  SEEKERMISSILE;
+  SCREENSEEKER;
+  SKYEXPLODE;
+  NOEXPLODEFLOOR;
+  STRIFEDAMAGE;
+  EXTREMEDEATH;
+  NOEXTREMEDEATH;
+  DEHEXPLOSION;
+  PIERCEARMOR;
+  FORCERADIUSDMG;
+  SPAWNSOUNDSOURCE;
+  PAINLESS;
+  FORCEPAIN;
+  DONTSEEKINVISIBLE;
+  STEPMISSILE;
+  ADDITIVEPOISONDAMAGE;
+  ADDITIVEPOISONDURATION;
+//Bouncing
+  BOUNCEONWALLS;
+  BOUNCEONFLOORS;
+  BOUNCEONCEILINGS;
+  ALLOWBOUNCEONACTORS;
+  BOUNCEAUTOOFF;
+  BOUNCEAUTOOFFFLOORONLY;
+  BOUNCELIKEHERETIC;
+  BOUNCEONACTORS;
+  NOWALLBOUNCESND;
+  EXPLODEONWATER;
+  CANBOUNCEWATER;
+  MBFBOUNCER;
+//Miscellaneous
+  DROPPED;
+  ISMONSTER;
+  CORPSE;
+  COUNTITEM;
+  COUNTKILL;
+  COUNTSECRET;
+  NOTDMATCH;
+  NONSHOOTABLE;
+  DROPOFF;
+  PUFFONACTORS;
+  ALLOWPARTICLES;
+  ALWAYSPUFF;
+  PUFFGETSOWNER;
+  SYNCHRONIZED;
+  ALWAYSFAST;
+  NEVERFAST;
+  OLDRADIUSDMG;
+  USESPECIAL;
+  BUMPSPECIAL;
+  BOSSDEATH;
+  NOINTERACTION;
+  NOTAUTOAIMED;
+  PICKUP;
+  TOUCHY;
+  VULNERABLE;
+//Limited Use
+  SEESDAGGERS;
+  INCOMBAT;
+  NOCLIP;
+  NOSECTOR;
+  ICECORPSE;
+  JUSTHIT;
+  JUSTATTACKED;
+  TELEPORT;
+  BLASTED;
+  EXPLOCOUNT;
+  SKULLFLY;
+}
diff --git a/Help/gz_cfg_settings.html b/Help/gz_cfg_settings.html
index d5479d81a..0b682c1bc 100644
--- a/Help/gz_cfg_settings.html
+++ b/Help/gz_cfg_settings.html
@@ -20,7 +20,7 @@
 	<div id="contents">
 
 	<p><h3>General settings:</h3></br><b>basegame</b> - indicates on which game current configuration is based. Used to load game-specific GLDEFS lumps (DOOMDEFS, HTICDEFS, HEXNDEFS or STRFDEFS)</br>
-<b>Possile values:</b> 0 (DOOM), 1 (HERETIC), 2 (HEXEN) or 3 (STRIFE).</br>
+<b>Possile values:</b> 1 (DOOM), 2 (HERETIC), 3 (HEXEN) or 4 (STRIFE).</br>
 <b>Example:</b> <code>basegame = 0;</code></p>
 
 <h3>Thing and linedef definition:</h3>
diff --git a/Source/Core/Builder.csproj b/Source/Core/Builder.csproj
index becb6f140..a3c601cda 100644
--- a/Source/Core/Builder.csproj
+++ b/Source/Core/Builder.csproj
@@ -721,14 +721,16 @@
     <Compile Include="GZBuilder\Data\ScriptItem.cs" />
     <Compile Include="GZBuilder\Data\TextureData.cs" />
     <Compile Include="GZBuilder\Data\ThingBoundingBox.cs" />
+    <Compile Include="GZBuilder\GZDoom\DecorateParserSE.cs" />
     <Compile Include="GZBuilder\GZDoom\GldefsParser.cs" />
     <Compile Include="GZBuilder\GZDoom\MapinfoParser.cs" />
     <Compile Include="GZBuilder\GZDoom\ModeldefParser.cs" />
+    <Compile Include="GZBuilder\GZDoom\ModeldefParserSE.cs" />
     <Compile Include="GZBuilder\GZDoom\ModeldefStructure.cs" />
     <Compile Include="GZBuilder\GZGeneral.cs" />
     <Compile Include="GZBuilder\md3\GZModel.cs" />
     <Compile Include="GZBuilder\md3\ModelReader.cs" />
-    <Compile Include="GZBuilder\ZDoom\AcsParser.cs" />
+    <Compile Include="GZBuilder\GZDoom\AcsParserSE.cs" />
     <Compile Include="IO\DoomColormapReader.cs" />
     <Compile Include="Map\SelectionType.cs" />
     <Compile Include="Map\MapElementCollection.cs" />
diff --git a/Source/Core/Compilers/Compiler.cs b/Source/Core/Compilers/Compiler.cs
index 71d86af55..182c25480 100644
--- a/Source/Core/Compilers/Compiler.cs
+++ b/Source/Core/Compilers/Compiler.cs
@@ -94,7 +94,7 @@ namespace CodeImp.DoomBuilder.Compilers
 			if(!isdisposed)
 			{
 				Exception deleteerror = null;
-				double starttime = General.Clock.CurrentTime;
+				float starttime = General.Clock.CurrentTime;
 				
 				do
 				{
diff --git a/Source/Core/Controls/ScriptDocumentTab.cs b/Source/Core/Controls/ScriptDocumentTab.cs
index c687cb1f5..5abbd12e8 100644
--- a/Source/Core/Controls/ScriptDocumentTab.cs
+++ b/Source/Core/Controls/ScriptDocumentTab.cs
@@ -17,6 +17,7 @@
 #region ================== Namespaces
 
 using System;
+using System.IO;
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.Drawing;
@@ -31,6 +32,9 @@ using CodeImp.DoomBuilder.Config;
 using CodeImp.DoomBuilder.Types;
 using CodeImp.DoomBuilder.IO;
 using CodeImp.DoomBuilder.Compilers;
+//mxd
+using CodeImp.DoomBuilder.GZBuilder.Data;
+using CodeImp.DoomBuilder.GZBuilder.GZDoom;
 
 #endregion
 
@@ -54,6 +58,14 @@ namespace CodeImp.DoomBuilder.Controls
 		protected ScriptEditorControl editor;
         //mxd
         protected ComboBox navigator;
+        protected enum ScriptTypes : int
+        {
+            ACS = 0,
+            MODELDEF = 1,
+            DECORATE = 2,
+        }
+        private string[] knownScriptTypes = { "ZDoom ACS script", "GZDoom MODELDEF", "ZDoom DECORATE" };
+        protected string[] KNOWN_SCRIPT_TYPES { get { return knownScriptTypes; } } 
 
 		// Derived classes must set this!
 		protected ScriptConfiguration config;
@@ -95,6 +107,7 @@ namespace CodeImp.DoomBuilder.Controls
             navigator.Name = "navigator";
             navigator.TabStop = true;
             navigator.TabIndex = 0;
+            navigator.DropDown += new EventHandler(navigator_DropDown);
             this.Controls.Add(navigator);
 			
 			// Make the script control
@@ -200,6 +213,7 @@ namespace CodeImp.DoomBuilder.Controls
 		// This changes the script configurations
 		public virtual void ChangeScriptConfig(ScriptConfiguration newconfig)
 		{
+            updateNavigator(); //mxd
 		}
 
 		// Call this to set the tab title
@@ -307,6 +321,113 @@ namespace CodeImp.DoomBuilder.Controls
 			else
 				return "";
 		}
+
+        //mxd
+        protected void updateNavigator() {
+            //mxd. known script type?
+            if (Array.IndexOf(KNOWN_SCRIPT_TYPES, config.Description) != -1)
+                navigator.Enabled = updateNavigator(new MemoryStream(editor.GetText()), config.Description);
+            if(navigator.Enabled)
+                navigator.SelectedIndexChanged += new EventHandler(navigator_SelectedIndexChanged);
+        }
+
+        //mxd
+        private bool updateNavigator(MemoryStream stream, string scriptType) {
+            if (scriptType == KNOWN_SCRIPT_TYPES[(int)ScriptTypes.ACS])      //ZDoom ACS script
+                return updateNavigatorAcs();
+            if (scriptType == KNOWN_SCRIPT_TYPES[(int)ScriptTypes.MODELDEF]) //GZDoom MODELDEF
+                return updateNavigatorModeldef(stream);
+            if (scriptType == KNOWN_SCRIPT_TYPES[(int)ScriptTypes.DECORATE])
+                return updateNavigatorDecorate(stream);
+            return false;
+        }
+
+        //mxd
+        private bool updateNavigatorDecorate(MemoryStream stream) {
+            if (stream == null) return false;
+
+            string selectedItem = "";
+            int selectedIndex = 0;
+            if (navigator.SelectedIndex != -1) selectedItem = navigator.Text;
+
+            navigator.Items.Clear();
+
+            DecorateParserSE parser = new DecorateParserSE();
+            parser.Parse(stream, "DECORATE");
+
+            if (parser.Actors.Count == 0)
+                return false;
+
+            ScriptItem[] models = new ScriptItem[parser.Actors.Count];
+            int i = 0;
+            foreach (ScriptItem si in parser.Actors) {
+                models[i++] = si;
+                if (si.Name == selectedItem) selectedIndex = i - 1;
+            }
+            navigator.Items.AddRange(models);
+            return true;
+        }
+
+        //mxd
+        private bool updateNavigatorModeldef(MemoryStream stream) {
+            if (stream == null) return false;
+
+            string selectedItem = "";
+            int selectedIndex = 0;
+            if (navigator.SelectedIndex != -1) selectedItem = navigator.Text;
+
+            navigator.Items.Clear();
+
+            ModeldefParserSE parser = new ModeldefParserSE();
+            parser.Parse(stream, "MODELDEF");
+
+            if (parser.Models.Count == 0)
+                return false;
+
+            ScriptItem[] models = new ScriptItem[parser.Models.Count];
+            int i = 0;
+            foreach (ScriptItem si in parser.Models) {
+                models[i++] = si;
+                if (si.Name == selectedItem) selectedIndex = i - 1;
+            }
+            navigator.Items.AddRange(models);
+            return true;
+        }
+
+        //mxd
+        private bool updateNavigatorAcs() {
+            string selectedItem = "";
+            int selectedIndex = 0;
+            if (navigator.SelectedIndex != -1) selectedItem = navigator.Text;
+
+            navigator.Items.Clear();
+
+            //add named scripts
+            int i = 0;
+            if (General.Map.UDMF) {
+                ScriptItem[] namedScripts = new ScriptItem[General.Map.NamedScripts.Count];
+                foreach (ScriptItem si in General.Map.NamedScripts) {
+                    namedScripts[i++] = si;
+                    if (si.Name == selectedItem) selectedIndex = i - 1;
+                }
+                navigator.Items.AddRange(namedScripts);
+            }
+
+            //add numbered scripts
+            ScriptItem[] numberedScripts = new ScriptItem[General.Map.NumberedScripts.Count];
+            int c = 0;
+            foreach (ScriptItem si in General.Map.NumberedScripts) {
+                numberedScripts[c++] = si;
+                if (si.Name == selectedItem) selectedIndex = i - 1 + c;
+            }
+            navigator.Items.AddRange(numberedScripts);
+
+            if (navigator.Items.Count > 0) {
+                navigator.SelectedIndex = selectedIndex;
+                return true;
+            }
+            return false;
+        }
 		
 		#endregion
 		
@@ -331,6 +452,25 @@ namespace CodeImp.DoomBuilder.Controls
 			editor.Focus();
 			editor.GrabFocus();
 		}
+
+        //mxd
+        protected void navigator_SelectedIndexChanged(object sender, EventArgs e) {
+            if (navigator.SelectedItem is ScriptItem) {
+                ScriptItem si = navigator.SelectedItem as ScriptItem;
+                editor.EnsureLineVisible(editor.LineFromPosition(si.SelectionStart));
+                editor.SelectionStart = si.SelectionStart;
+                editor.SelectionEnd = si.SelectionEnd;
+                
+                // Focus to the editor!
+                editor.Focus();
+                editor.GrabFocus();
+            }
+        }
+
+        //mxd
+        protected void navigator_DropDown(object sender, EventArgs e) {
+            if(editor.IsChanged) updateNavigator();
+        }
 		
 		#endregion
 	}
diff --git a/Source/Core/Controls/ScriptFileDocumentTab.cs b/Source/Core/Controls/ScriptFileDocumentTab.cs
index e0eadcf6d..e171f6e99 100644
--- a/Source/Core/Controls/ScriptFileDocumentTab.cs
+++ b/Source/Core/Controls/ScriptFileDocumentTab.cs
@@ -69,6 +69,8 @@ namespace CodeImp.DoomBuilder.Controls
 			if(config.Extensions.Length > 0) ext = "." + config.Extensions[0];
 			SetTitle("Untitled" + ext);
 			editor.ClearUndoRedo();
+            //mxd
+            navigator.Enabled = Array.IndexOf(KNOWN_SCRIPT_TYPES, config.Description) != -1;
 		}
 		
 		// Disposer
@@ -222,6 +224,9 @@ namespace CodeImp.DoomBuilder.Controls
 				if(config.Extensions.Length > 0) ext = "." + config.Extensions[0];
 				SetTitle("Untitled" + ext);
 			}
+
+            //mxd
+            base.ChangeScriptConfig(newconfig);
 		}
 		
 		#endregion
diff --git a/Source/Core/Controls/ScriptLumpDocumentTab.cs b/Source/Core/Controls/ScriptLumpDocumentTab.cs
index 78a881ae2..4c6088ce8 100644
--- a/Source/Core/Controls/ScriptLumpDocumentTab.cs
+++ b/Source/Core/Controls/ScriptLumpDocumentTab.cs
@@ -94,14 +94,6 @@ namespace CodeImp.DoomBuilder.Controls
 				SetTitle(General.Map.Options.CurrentName);
 			else
 				SetTitle(this.lumpname.ToUpper());
-
-            //mxd
-            if (this.Text == "SCRIPTS") {
-                updateNavigator();
-                navigator.SelectedIndexChanged += new EventHandler(navigator_SelectedIndexChanged);
-            }else{
-                navigator.Enabled = false;
-            }
 		}
 		
 		// Disposer
@@ -113,37 +105,6 @@ namespace CodeImp.DoomBuilder.Controls
 		#endregion
 		
 		#region ================== Methods
-
-        //mxd
-        private void updateNavigator() {
-            string selectedItem = "";
-            int selectedIndex = 0;
-            if (navigator.SelectedIndex != -1) selectedItem = navigator.Text;
-            
-            navigator.Items.Clear();
-            
-            //add named scripts
-            int i = 0;
-            if (General.Map.UDMF) {
-                ScriptItem[] namedScripts = new ScriptItem[General.Map.NamedScripts.Count];
-                foreach (ScriptItem si in General.Map.NamedScripts) {
-                    namedScripts[i++] = si;
-                    if (si.Name == selectedItem) selectedIndex = i - 1;
-                }
-                navigator.Items.AddRange(namedScripts);
-            }
-
-            //add numbered scripts
-            ScriptItem[] numberedScripts = new ScriptItem[General.Map.NumberedScripts.Count];
-            int c = 0;
-            foreach (ScriptItem si in General.Map.NumberedScripts) {
-                numberedScripts[c++] = si;
-                if (si.Name == selectedItem) selectedIndex = i - 1 + c;
-            }
-            navigator.Items.AddRange(numberedScripts);
-
-            if (navigator.Items.Count > 0) navigator.SelectedIndex = selectedIndex;
-        }
 		
 		// Compile script
 		public override void Compile()
@@ -158,12 +119,8 @@ namespace CodeImp.DoomBuilder.Controls
 			panel.ShowErrors(General.Map.Errors);
 
             //mxd
-            if (General.Map.Errors.Count == 0) {
+            if (config.Description == KNOWN_SCRIPT_TYPES[(int)ScriptTypes.ACS] && General.Map.Errors.Count == 0)
                 General.Map.UpdateScriptNames();
-                navigator.SelectedIndexChanged -= navigator_SelectedIndexChanged;
-                updateNavigator();
-                navigator.SelectedIndexChanged += new EventHandler(navigator_SelectedIndexChanged);
-            }
 		}
 		
 		// Implicit save
@@ -186,16 +143,6 @@ namespace CodeImp.DoomBuilder.Controls
 		
 		#region ================== Events
 
-        //mxd
-        private void navigator_SelectedIndexChanged(object sender, EventArgs e) {
-            if (navigator.SelectedItem is ScriptItem) {
-                ScriptItem si = navigator.SelectedItem as ScriptItem;
-                editor.EnsureLineVisible(editor.LineFromPosition(si.SelectionStart));
-                editor.SelectionStart = si.SelectionStart;
-                editor.SelectionEnd = si.SelectionEnd;
-            }
-        }
-
 		#endregion
 	}
 }
diff --git a/Source/Core/Data/DataManager.cs b/Source/Core/Data/DataManager.cs
index f57c1e8b1..3a5d5b7c7 100644
--- a/Source/Core/Data/DataManager.cs
+++ b/Source/Core/Data/DataManager.cs
@@ -103,8 +103,8 @@ namespace CodeImp.DoomBuilder.Data
 		private Dictionary<int, ThingTypeInfo> thingtypes;
 		
 		// Timing
-		private double loadstarttime;
-		private double loadfinishtime;
+		private float loadstarttime;
+		private float loadfinishtime;
 		
 		// Disposing
 		private bool isdisposed = false;
@@ -114,9 +114,9 @@ namespace CodeImp.DoomBuilder.Data
 		#region ================== Properties
 
         //mxd
-        public Dictionary<int, ModeldefEntry> ModeldefEntries { get { return modeldefEntries; } }
-        public Dictionary<int, GZDoomLight> GldefsEntries { get { return gldefsEntries; } }
-        public MapInfo MapInfo { get { return mapInfo; } }
+        internal Dictionary<int, ModeldefEntry> ModeldefEntries { get { return modeldefEntries; } }
+        internal Dictionary<int, GZDoomLight> GldefsEntries { get { return gldefsEntries; } }
+        internal MapInfo MapInfo { get { return mapInfo; } }
 
 		public Playpal Palette { get { return palette; } }
 		public PreviewManager Previews { get { return previews; } }
@@ -130,8 +130,6 @@ namespace CodeImp.DoomBuilder.Data
 		public ImageData Hourglass3D { get { return hourglass3d; } }
 		public ImageData Crosshair3D { get { return crosshair; } }
 		public ImageData CrosshairBusy3D { get { return crosshairbusy; } }
-        //mxd
-		//public ImageData ThingBox { get { return thingbox; } }
 		public ImageData WhiteTexture { get { return whitetexture; } }
 		public List<ThingCategory> ThingCategories { get { return thingcategories; } }
 		public ICollection<ThingTypeInfo> ThingTypes { get { return thingtypes.Values; } }
@@ -665,7 +663,7 @@ namespace CodeImp.DoomBuilder.Data
 							if(loadfinishtime == 0)
 							{
 								loadfinishtime = General.Clock.CurrentTime;
-								double deltatimesec = (loadfinishtime - loadstarttime) / 1000.0d;
+								float deltatimesec = (loadfinishtime - loadstarttime) / 1000.0f;
 								General.WriteLogLine("Resources loading took " + deltatimesec.ToString("########0.00") + " seconds");
 							}
 							
diff --git a/Source/Core/Editing/ClassicMode.cs b/Source/Core/Editing/ClassicMode.cs
index 7beac46e3..0752593e4 100644
--- a/Source/Core/Editing/ClassicMode.cs
+++ b/Source/Core/Editing/ClassicMode.cs
@@ -429,7 +429,7 @@ namespace CodeImp.DoomBuilder.Editing
 		#region ================== Processing
 
 		// Processing
-		public override void OnProcess(double deltatime)
+		public override void OnProcess(float deltatime)
 		{
 			base.OnProcess(deltatime);
 
@@ -457,8 +457,8 @@ namespace CodeImp.DoomBuilder.Editing
 					panamount = (panamount * panamount) * pansign * 0.0001f * (float)General.Settings.AutoScrollSpeed / renderer.Scale;
 					
 					// Multiply by delta time
-					panamount.x = (float)((double)panamount.x * deltatime);
-					panamount.y = (float)((double)panamount.y * deltatime);
+					panamount.x *= deltatime;
+					panamount.y *= deltatime;
 
 					// Pan the view
 					ScrollBy(panamount.x, panamount.y);
diff --git a/Source/Core/Editing/EditMode.cs b/Source/Core/Editing/EditMode.cs
index 95d4b31c7..9d39bae10 100644
--- a/Source/Core/Editing/EditMode.cs
+++ b/Source/Core/Editing/EditMode.cs
@@ -209,7 +209,7 @@ namespace CodeImp.DoomBuilder.Editing
 		public virtual void OnPresentDisplay() { }
 
 		// Processing events
-		public virtual void OnProcess(double deltatime) { }
+		public virtual void OnProcess(float deltatime) { }
 		
 		// Generic events
 		public virtual void OnReloadResources() { }
diff --git a/Source/Core/GZBuilder/Data/GameType.cs b/Source/Core/GZBuilder/Data/GameType.cs
index 2e086c5ea..ed5e4e371 100644
--- a/Source/Core/GZBuilder/Data/GameType.cs
+++ b/Source/Core/GZBuilder/Data/GameType.cs
@@ -5,14 +5,14 @@ using System.Text;
 
 namespace CodeImp.DoomBuilder.GZBuilder.Data {
     public enum GameType : int {
-        DOOM = 0,
-        HERETIC = 1,
-        HEXEN = 2,
-        STRIFE = 3,
-        UNKNOWN = 4,
+        UNKNOWN = 0,
+        DOOM = 1,
+        HERETIC = 2,
+        HEXEN = 3,
+        STRIFE = 4,
     }
 
     public struct Gldefs {
-        public static string[] GLDEFS_LUMPS_PER_GAME = { "DOOMDEFS", "HTICDEFS", "HEXNDEFS", "STRFDEFS" };
+        public static string[] GLDEFS_LUMPS_PER_GAME = { "UNKNOWN_GAME", "DOOMDEFS", "HTICDEFS", "HEXNDEFS", "STRFDEFS" };
     }
 }
diff --git a/Source/Core/GZBuilder/Data/ModelDefEntry.cs b/Source/Core/GZBuilder/Data/ModelDefEntry.cs
index 40e53842d..4fc973870 100644
--- a/Source/Core/GZBuilder/Data/ModelDefEntry.cs
+++ b/Source/Core/GZBuilder/Data/ModelDefEntry.cs
@@ -9,25 +9,25 @@ using CodeImp.DoomBuilder.GZBuilder.MD3;
 
 namespace CodeImp.DoomBuilder.GZBuilder.Data
 {
-    public class ModeldefEntry
+    internal sealed class ModeldefEntry
     {
-        public string ClassName;
-        public string Path; //this holds Path parameter of MODELDEF entry
-        public List<string> ModelNames;
-        public List<string> TextureNames;
-        public string Location; //this holds location of resource, from which modeldef was loaded
+        internal string ClassName;
+        internal string Path; //this holds Path parameter of MODELDEF entry
+        internal List<string> ModelNames;
+        internal List<string> TextureNames;
+        internal string Location; //this holds location of resource, from which modeldef was loaded
 
-        public GZModel Model;
+        internal GZModel Model;
 
-        public Vector3 Scale;
-        public float zOffset;
+        internal Vector3 Scale;
+        internal float zOffset;
 
-        public ModeldefEntry() {
+        internal ModeldefEntry() {
             ModelNames = new List<string>();
             TextureNames = new List<string>();
         }
 
-        public void Dispose() {
+        internal void Dispose() {
             if (Model != null) {
                 foreach (IndexBuffer ib in Model.Indeces2D)
                     ib.Dispose();
diff --git a/Source/Core/GZBuilder/Data/ScriptItem.cs b/Source/Core/GZBuilder/Data/ScriptItem.cs
index 12da8f389..48f2f8ac7 100644
--- a/Source/Core/GZBuilder/Data/ScriptItem.cs
+++ b/Source/Core/GZBuilder/Data/ScriptItem.cs
@@ -4,29 +4,41 @@ using System.Linq;
 using System.Text;
 
 namespace CodeImp.DoomBuilder.GZBuilder.Data {
-    public sealed class ScriptItem : Object {
+    internal sealed class ScriptItem : Object {
         private string name;
         private int index;
         private int selectionStart;
         private int selectionEnd;
 
-        public string Name { get { return name; } }
-        public int Index { get { return index; } }
-        public int SelectionStart { get { return selectionStart; } }
-        public int SelectionEnd { get { return selectionEnd; } }
+        internal string Name { get { return name; } }
+        internal int Index { get { return index; } }
+        internal int SelectionStart { get { return selectionStart; } }
+        internal int SelectionEnd { get { return selectionEnd; } }
 
-        public ScriptItem(int index, string name, int selectionStart, int selectionEnd) {
+        internal ScriptItem(int index, string name, int selectionStart, int selectionEnd) {
             this.name = name;
             this.index = index;
             this.selectionStart = selectionStart;
             this.selectionEnd = selectionEnd;
         }
 
-        public ScriptItem(int index, string name) {
+        internal ScriptItem(int index, string name) {
             this.name = name;
             this.index = index;
         }
 
+        internal static int SortByIndex(ScriptItem i1, ScriptItem i2) {
+            if (i1.Index > i2.Index) return 1;
+            if (i1.Index == i2.Index) return 0;
+            return -1;
+        }
+
+        internal static int SortByName(ScriptItem i1, ScriptItem i2) {
+            if (i1.Name.ToUpper()[0] > i2.Name.ToUpper()[0]) return 1;
+            if (i1.Name.ToUpper()[0] == i2.Name.ToUpper()[0]) return 0;
+            return -1;
+        }
+
         public override string ToString() {
             return name;
         }
diff --git a/Source/Core/GZBuilder/ZDoom/AcsParser.cs b/Source/Core/GZBuilder/GZDoom/AcsParserSE.cs
similarity index 85%
rename from Source/Core/GZBuilder/ZDoom/AcsParser.cs
rename to Source/Core/GZBuilder/GZDoom/AcsParserSE.cs
index cf2dd11db..6fb482162 100644
--- a/Source/Core/GZBuilder/ZDoom/AcsParser.cs
+++ b/Source/Core/GZBuilder/GZDoom/AcsParserSE.cs
@@ -7,17 +7,18 @@ using System.Text;
 using CodeImp.DoomBuilder.ZDoom;
 using CodeImp.DoomBuilder.GZBuilder.Data;
 
-namespace CodeImp.DoomBuilder.GZBuilder.ZDoom
+//mxd. ACS parser used to create ScriptItems for use in script editor's navigator
+namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
 {
-    public class AcsParser : ZDTextParser
+    internal sealed class AcsParserSE : ZDTextParser
     {
         private List<ScriptItem> namedScripts;
         private List<ScriptItem> numberedScripts;
 
-        public List<ScriptItem> NamedScripts { get { return namedScripts; } }
-        public List<ScriptItem> NumberedScripts { get { return numberedScripts; } }
+        internal List<ScriptItem> NamedScripts { get { return namedScripts; } }
+        internal List<ScriptItem> NumberedScripts { get { return numberedScripts; } }
 
-        public AcsParser() {
+        internal AcsParserSE() {
             namedScripts = new List<ScriptItem>();
             numberedScripts = new List<ScriptItem>();
         }
diff --git a/Source/Core/GZBuilder/GZDoom/DecorateParserSE.cs b/Source/Core/GZBuilder/GZDoom/DecorateParserSE.cs
new file mode 100644
index 000000000..d1dcc2064
--- /dev/null
+++ b/Source/Core/GZBuilder/GZDoom/DecorateParserSE.cs
@@ -0,0 +1,56 @@
+using System;
+using System.IO;
+using System.Collections.Generic;
+using System.Text;
+
+using CodeImp.DoomBuilder.ZDoom;
+using CodeImp.DoomBuilder.GZBuilder.Data;
+
+//mxd. Decorate parser used to create ScriptItems for use in script editor's navigator
+namespace CodeImp.DoomBuilder.GZBuilder.GZDoom
+{
+    internal sealed class DecorateParserSE : ZDTextParser
+    {
+        private List<ScriptItem> actors;
+        public List<ScriptItem> Actors { get { return actors; } }
+
+        public DecorateParserSE() {
+            actors = new List<ScriptItem>();
+        }
+
+        public override bool Parse(Stream stream, string sourcefilename) {
+            base.Parse(stream, sourcefilename);
+
+            // Continue until at the end of the stream
+            while (SkipWhitespace(true)) {
+                string token = ReadToken();
+
+                if (!string.IsNullOrEmpty(token)) {
+                    token = token.ToLowerInvariant();
+
+                    if (token == "actor") {
+                        int startPos = (int)stream.Position - 6;
+                        SkipWhitespace(true);
+
+                        List<string> definition = new List<string>();
+
+                        while ((token = ReadToken()) != "{") {
+                            definition.Add(token);
+                            SkipWhitespace(true);
+                        }
+
+                        string name = "";
+                        foreach (string s in definition)
+                            name += s + " ";
+
+                        actors.Add(new ScriptItem(0, name.TrimEnd(), startPos, (int)stream.Position - 2));
+                    }
+                }
+            }
+
+            //sort nodes
+            actors.Sort(ScriptItem.SortByName);
+            return true;
+        }
+    }
+}
diff --git a/Source/Core/GZBuilder/GZDoom/GldefsParser.cs b/Source/Core/GZBuilder/GZDoom/GldefsParser.cs
index 6273c52b3..b06d0e37b 100644
--- a/Source/Core/GZBuilder/GZDoom/GldefsParser.cs
+++ b/Source/Core/GZBuilder/GZDoom/GldefsParser.cs
@@ -11,7 +11,7 @@ using SlimDX;
 using SlimDX.Direct3D9;
 
 namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
-    public class GldefsParser : ZDTextParser {
+    public sealed class GldefsParser : ZDTextParser {
 
         public delegate void IncludeDelegate(GldefsParser parser, string includefile);
         public IncludeDelegate OnInclude;
diff --git a/Source/Core/GZBuilder/GZDoom/MapinfoParser.cs b/Source/Core/GZBuilder/GZDoom/MapinfoParser.cs
index 5b1c1217e..80f1f7836 100644
--- a/Source/Core/GZBuilder/GZDoom/MapinfoParser.cs
+++ b/Source/Core/GZBuilder/GZDoom/MapinfoParser.cs
@@ -12,7 +12,7 @@ using CodeImp.DoomBuilder.ZDoom;
 using CodeImp.DoomBuilder.GZBuilder.Data;
 
 namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
-    public class MapinfoParser : ZDTextParser {
+    public sealed class MapinfoParser : ZDTextParser {
 
         private MapInfo mapInfo;
         public MapInfo MapInfo { get { return mapInfo; } }
diff --git a/Source/Core/GZBuilder/GZDoom/ModeldefParser.cs b/Source/Core/GZBuilder/GZDoom/ModeldefParser.cs
index c10061af8..d78a45e0b 100644
--- a/Source/Core/GZBuilder/GZDoom/ModeldefParser.cs
+++ b/Source/Core/GZBuilder/GZDoom/ModeldefParser.cs
@@ -9,15 +9,15 @@ using CodeImp.DoomBuilder.GZBuilder.GZDoom;
 
 namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
    
-    public class ModeldefParser : ZDTextParser {
+    internal class ModeldefParser : ZDTextParser {
         private Dictionary<string, ModeldefEntry> modelDefEntries; //classname, entry
-        public Dictionary<string, ModeldefEntry> ModelDefEntries { get { return modelDefEntries; } }
+        internal Dictionary<string, ModeldefEntry> ModelDefEntries { get { return modelDefEntries; } }
 
         private List<string> classNames;
 
-        public string Source { get { return sourcename; } }
+        internal string Source { get { return sourcename; } }
 
-        public ModeldefParser() {
+        internal ModeldefParser() {
             modelDefEntries = new Dictionary<string, ModeldefEntry>();
             classNames = new List<string>();
         }
diff --git a/Source/Core/GZBuilder/GZDoom/ModeldefParserSE.cs b/Source/Core/GZBuilder/GZDoom/ModeldefParserSE.cs
new file mode 100644
index 000000000..a4caf66f2
--- /dev/null
+++ b/Source/Core/GZBuilder/GZDoom/ModeldefParserSE.cs
@@ -0,0 +1,49 @@
+using System;
+using System.IO;
+using System.Collections.Generic;
+using System.Text;
+
+using CodeImp.DoomBuilder.ZDoom;
+using CodeImp.DoomBuilder.GZBuilder.Data;
+
+//mxd. Modeldef parser used to create ScriptItems for use in script editor's navigator
+namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
+    internal sealed class ModeldefParserSE : ZDTextParser {
+        private List<ScriptItem> models;
+        internal List<ScriptItem> Models { get { return models; } }
+
+        public ModeldefParserSE() {
+            models = new List<ScriptItem>();
+        }
+
+        public override bool Parse(Stream stream, string sourcefilename) {
+            base.Parse(stream, sourcefilename);
+
+            // Continue until at the end of the stream
+            while (SkipWhitespace(true)) {
+                string token = ReadToken();
+
+                if (!string.IsNullOrEmpty(token)) {
+                    token = token.ToUpperInvariant();
+
+                    if(token == "MODEL"){
+                        int startPos = (int)stream.Position - 6;
+                        SkipWhitespace(true);
+                        string modelName = ReadToken();
+                        SkipWhitespace(true);
+                        token = ReadToken(); //this should be "{"
+
+                        if (token == "{") {
+                            ScriptItem i = new ScriptItem(0, modelName, startPos, (int)stream.Position - 2);
+                            models.Add(i);
+                        }
+                    }
+                }
+            }
+
+            //sort nodes
+            models.Sort(ScriptItem.SortByName);
+            return true;
+        }
+    }
+}
diff --git a/Source/Core/GZBuilder/GZDoom/ModeldefStructure.cs b/Source/Core/GZBuilder/GZDoom/ModeldefStructure.cs
index 40e17ec82..c32ca5139 100644
--- a/Source/Core/GZBuilder/GZDoom/ModeldefStructure.cs
+++ b/Source/Core/GZBuilder/GZDoom/ModeldefStructure.cs
@@ -10,10 +10,10 @@ using SlimDX.Direct3D9;
 using CodeImp.DoomBuilder.GZBuilder.Data;
 
 namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
-    public sealed class ModeldefStructure {
+    internal sealed class ModeldefStructure {
         private const int MAX_MODELS = 4; //maximum models per modeldef entry, zero-based
 
-        public ModeldefEntry Parse(ModeldefParser parser) {
+        internal ModeldefEntry Parse(ModeldefParser parser) {
             string[] textureNames = new string[4];
             string[] modelNames = new string[4];
             string path = "";
diff --git a/Source/Core/General/Clock.cs b/Source/Core/General/Clock.cs
index c5fda619e..ff1651f9f 100644
--- a/Source/Core/General/Clock.cs
+++ b/Source/Core/General/Clock.cs
@@ -22,6 +22,6 @@ namespace CodeImp.DoomBuilder
 	public class Clock
 	{
 		// This queries the system for the current time
-        public double CurrentTime { get { return Configuration.Timer.ElapsedMilliseconds; } }
+        public float CurrentTime { get { return Configuration.Timer.ElapsedMilliseconds; } }
 	}
 }
diff --git a/Source/Core/General/MapManager.cs b/Source/Core/General/MapManager.cs
index 66d06cbea..69970d3b2 100644
--- a/Source/Core/General/MapManager.cs
+++ b/Source/Core/General/MapManager.cs
@@ -40,7 +40,7 @@ using CodeImp.DoomBuilder.VisualModes;
 //mxd
 using CodeImp.DoomBuilder.GZBuilder;
 using CodeImp.DoomBuilder.GZBuilder.Data;
-using CodeImp.DoomBuilder.GZBuilder.ZDoom;
+using CodeImp.DoomBuilder.GZBuilder.GZDoom;
 
 #endregion
 
@@ -125,13 +125,13 @@ namespace CodeImp.DoomBuilder {
 
         //mxd
         public bool UDMF { get { return config.FormatInterface == "UniversalMapSetIO"; } }
-        public List<ScriptItem> NamedScripts { 
+        internal List<ScriptItem> NamedScripts { 
             get {
                 if (!UDMF) throw new Exception("ScriptNames cannot be used in '" + config.FormatInterface + "' format!"); 
                 return namedScripts; 
             } 
         }
-        public List<ScriptItem> NumberedScripts { get { return numberedScripts; } }
+        internal List<ScriptItem> NumberedScripts { get { return numberedScripts; } }
 
         #endregion
 
@@ -1394,7 +1394,7 @@ namespace CodeImp.DoomBuilder {
                     // Load the lump data
                     MemoryStream stream = GetLumpData(maplumpinfo.name);
                     if (stream != null) {
-                        AcsParser parser = new AcsParser();
+                        AcsParserSE parser = new AcsParserSE();
                         parser.Parse(stream, "SCRIPTS");
                         namedScripts.AddRange(parser.NamedScripts);
                         numberedScripts.AddRange(parser.NumberedScripts);
diff --git a/Source/Core/Geometry/Vector2D.cs b/Source/Core/Geometry/Vector2D.cs
index 43e65a1da..5df1aae41 100644
--- a/Source/Core/Geometry/Vector2D.cs
+++ b/Source/Core/Geometry/Vector2D.cs
@@ -338,11 +338,11 @@ namespace CodeImp.DoomBuilder.Geometry
         // Rotate (Added by Anders Åstrand 2008-05-18)
         public unsafe Vector2D GetRotated(float theta)
         {
-			double cos = Math.Cos(theta);
-			double sin = Math.Sin(theta);
-            double rx = cos * x - sin * y;
-            double ry = sin * x + cos * y;
-            return new Vector2D((float)rx, (float)ry);
+            float cos = (float)Math.Cos(theta);
+            float sin = (float)Math.Sin(theta);
+            float rx = cos * x - sin * y;
+            float ry = sin * x + cos * y;
+            return new Vector2D(rx, ry);
         }
 
 		// Checks if the Vector has valid values for x and y
diff --git a/Source/Core/IO/DoomMapSetIO.cs b/Source/Core/IO/DoomMapSetIO.cs
index aa1032a8a..0c96f4090 100644
--- a/Source/Core/IO/DoomMapSetIO.cs
+++ b/Source/Core/IO/DoomMapSetIO.cs
@@ -79,8 +79,8 @@ namespace CodeImp.DoomBuilder.IO
 		public override int MinBrightness { get { return short.MinValue; } }
 		public override int MaxThingType { get { return ushort.MaxValue; } }
 		public override int MinThingType { get { return ushort.MinValue; } }
-		public override double MaxCoordinate { get { return (double)short.MaxValue; } }
-		public override double MinCoordinate { get { return (double)short.MinValue; } }
+		public override float MaxCoordinate { get { return (float)short.MaxValue; } }
+		public override float MinCoordinate { get { return (float)short.MinValue; } }
 		public override int MaxThingAngle { get { return short.MaxValue; } }
 		public override int MinThingAngle { get { return short.MinValue; } }
 		
diff --git a/Source/Core/IO/HexenMapSetIO.cs b/Source/Core/IO/HexenMapSetIO.cs
index 0247ef788..77f4f4c3b 100644
--- a/Source/Core/IO/HexenMapSetIO.cs
+++ b/Source/Core/IO/HexenMapSetIO.cs
@@ -79,8 +79,8 @@ namespace CodeImp.DoomBuilder.IO
 		public override int MinBrightness { get { return short.MinValue; } }
 		public override int MaxThingType { get { return ushort.MaxValue; } }
 		public override int MinThingType { get { return ushort.MinValue; } }
-		public override double MaxCoordinate { get { return (double)short.MaxValue; } }
-		public override double MinCoordinate { get { return (double)short.MinValue; } }
+		public override float MaxCoordinate { get { return (float)short.MaxValue; } }
+		public override float MinCoordinate { get { return (float)short.MinValue; } }
 		public override int MaxThingAngle { get { return short.MaxValue; } }
 		public override int MinThingAngle { get { return short.MinValue; } }
 		
diff --git a/Source/Core/IO/IMapSetIO.cs b/Source/Core/IO/IMapSetIO.cs
index aa1c0b48b..0e4e307eb 100644
--- a/Source/Core/IO/IMapSetIO.cs
+++ b/Source/Core/IO/IMapSetIO.cs
@@ -65,8 +65,8 @@ namespace CodeImp.DoomBuilder.IO
 		int MinBrightness { get; }
 		int MaxThingType { get; }
 		int MinThingType { get; }
-		double MaxCoordinate { get; }
-		double MinCoordinate { get; }
+		float MaxCoordinate { get; }
+		float MinCoordinate { get; }
 		int MaxThingAngle { get; }
 		int MinThingAngle { get; }
 	}
diff --git a/Source/Core/IO/MapSetIO.cs b/Source/Core/IO/MapSetIO.cs
index ed0e19ac5..92ffb524b 100644
--- a/Source/Core/IO/MapSetIO.cs
+++ b/Source/Core/IO/MapSetIO.cs
@@ -81,8 +81,8 @@ namespace CodeImp.DoomBuilder.IO
 		public abstract int MinBrightness { get; }
 		public abstract int MaxThingType { get; }
 		public abstract int MinThingType { get; }
-		public abstract double MaxCoordinate { get; }
-		public abstract double MinCoordinate { get; }
+		public abstract float MaxCoordinate { get; }
+		public abstract float MinCoordinate { get; }
 		public abstract int MaxThingAngle { get; }
 		public abstract int MinThingAngle { get; }
 		
diff --git a/Source/Core/IO/UniversalMapSetIO.cs b/Source/Core/IO/UniversalMapSetIO.cs
index bb8307f4e..4f2244209 100644
--- a/Source/Core/IO/UniversalMapSetIO.cs
+++ b/Source/Core/IO/UniversalMapSetIO.cs
@@ -133,8 +133,8 @@ namespace CodeImp.DoomBuilder.IO
 		public override int MinBrightness { get { return int.MinValue; } }
 		public override int MaxThingType { get { return int.MaxValue; } }
 		public override int MinThingType { get { return int.MinValue; } }
-		public override double MaxCoordinate { get { return (double)float.MaxValue; } }
-		public override double MinCoordinate { get { return (double)float.MinValue; } }
+		public override float MaxCoordinate { get { return float.MaxValue; } }
+		public override float MinCoordinate { get { return float.MinValue; } }
 		public override int MaxThingAngle { get { return int.MaxValue; } }
 		public override int MinThingAngle { get { return int.MinValue; } }
 		
diff --git a/Source/Core/Map/MapSet.cs b/Source/Core/Map/MapSet.cs
index e0f31e517..216540439 100644
--- a/Source/Core/Map/MapSet.cs
+++ b/Source/Core/Map/MapSet.cs
@@ -2805,7 +2805,7 @@ namespace CodeImp.DoomBuilder.Map
 		{
 			Dictionary<uint, List<Sidedef>> storedsides = new Dictionary<uint, List<Sidedef>>(numsidedefs);
 			int originalsidescount = numsidedefs;
-			double starttime = General.Clock.CurrentTime;
+			float starttime = General.Clock.CurrentTime;
 
 			BeginAddRemove();
 			
@@ -2893,8 +2893,8 @@ namespace CodeImp.DoomBuilder.Map
 			EndAddRemove();
 
 			// Output info
-            double endtime = General.Clock.CurrentTime;
-			double deltatimesec = (endtime - starttime) / 1000.0d;
+            float endtime = General.Clock.CurrentTime;
+			float deltatimesec = (endtime - starttime) / 1000.0f;
 			float ratio = 100.0f - (((float)numsidedefs / (float)originalsidescount) * 100.0f);
 			General.WriteLogLine("Sidedefs compressed: " + numsidedefs + " remaining out of " + originalsidescount + " (" + ratio.ToString("########0.00") + "%) in " + deltatimesec.ToString("########0.00") + " seconds");
 		}
diff --git a/Source/Core/Rendering/Renderer3D.cs b/Source/Core/Rendering/Renderer3D.cs
index 33c390e1d..d507c063e 100644
--- a/Source/Core/Rendering/Renderer3D.cs
+++ b/Source/Core/Rendering/Renderer3D.cs
@@ -458,7 +458,7 @@ namespace CodeImp.DoomBuilder.Rendering
 				// Highlight
 				if(General.Settings.AnimateVisualSelection)
 				{
-					double time = General.Clock.CurrentTime;
+					float time = General.Clock.CurrentTime;
 					highlightglow = (float)Math.Sin(time / 100.0f) * 0.1f + 0.4f;
                     //mxd. WHY?!
 					//highlightglowinv = -(float)Math.Sin(time / 100.0f) * 0.1f + 0.4f;
diff --git a/Source/Core/VisualModes/VisualMode.cs b/Source/Core/VisualModes/VisualMode.cs
index ef0c2530e..b22251b20 100644
--- a/Source/Core/VisualModes/VisualMode.cs
+++ b/Source/Core/VisualModes/VisualMode.cs
@@ -45,7 +45,7 @@ namespace CodeImp.DoomBuilder.VisualModes
 	{
 		#region ================== Constants
 
-		private const double MOVE_SPEED_MULTIPLIER = 0.001d;
+		private const float MOVE_SPEED_MULTIPLIER = 0.001f;
 		
 		#endregion
 
@@ -1054,9 +1054,9 @@ namespace CodeImp.DoomBuilder.VisualModes
 		/// <summary>
 		/// While this mode is active, this is called continuously to process whatever needs processing.
 		/// </summary>
-		public override void OnProcess(double deltatime)
+		public override void OnProcess(float deltatime)
 		{
-			double multiplier;
+			float multiplier;
 			
 			base.OnProcess(deltatime);
 			
@@ -1069,12 +1069,12 @@ namespace CodeImp.DoomBuilder.VisualModes
 
 			// Move the camera
 			if(General.Interface.ShiftState) multiplier = MOVE_SPEED_MULTIPLIER * 2.0f; else multiplier = MOVE_SPEED_MULTIPLIER;
-			if(keyforward) camdeltapos += camvec * cammovemul * (float)((double)General.Settings.MoveSpeed * multiplier * deltatime);
-			if(keybackward) camdeltapos -= camvec * cammovemul * (float)((double)General.Settings.MoveSpeed * multiplier * deltatime);
-			if(keyleft) camdeltapos -= camvecstrafe * cammovemul * (float)((double)General.Settings.MoveSpeed * multiplier * deltatime);
-			if(keyright) camdeltapos += camvecstrafe * cammovemul * (float)((double)General.Settings.MoveSpeed * multiplier * deltatime);
-            if(keyup) camdeltapos += upvec * cammovemul * (float)((double)General.Settings.MoveSpeed * multiplier * deltatime);
-            if(keydown) camdeltapos += -upvec * cammovemul * (float)((double)General.Settings.MoveSpeed * multiplier * deltatime);
+			if(keyforward) camdeltapos += camvec * cammovemul * (float)General.Settings.MoveSpeed * multiplier * deltatime;
+			if(keybackward) camdeltapos -= camvec * cammovemul * (float)General.Settings.MoveSpeed * multiplier * deltatime;
+			if(keyleft) camdeltapos -= camvecstrafe * cammovemul * (float)General.Settings.MoveSpeed * multiplier * deltatime;
+			if(keyright) camdeltapos += camvecstrafe * cammovemul * (float)General.Settings.MoveSpeed * multiplier * deltatime;
+            if(keyup) camdeltapos += upvec * cammovemul * (float)General.Settings.MoveSpeed * multiplier * deltatime;
+            if(keydown) camdeltapos += -upvec * cammovemul * (float)General.Settings.MoveSpeed * multiplier * deltatime;
 			
 			// Move the camera
 			General.Map.VisualCamera.ProcessMovement(camdeltapos);
diff --git a/Source/Core/VisualModes/VisualThing.cs b/Source/Core/VisualModes/VisualThing.cs
index f3c5dbb36..fb5d94f2c 100644
--- a/Source/Core/VisualModes/VisualThing.cs
+++ b/Source/Core/VisualModes/VisualThing.cs
@@ -468,7 +468,7 @@ namespace CodeImp.DoomBuilder.VisualModes
                 return;
             }
 
-            double time = General.Clock.CurrentTime;
+            float time = General.Clock.CurrentTime;
             
             float rMin = Math.Min(lightPrimaryRadius, lightSecondaryRadius);
             float rMax = Math.Max(lightPrimaryRadius, lightSecondaryRadius);
diff --git a/Source/Core/Windows/MainForm.cs b/Source/Core/Windows/MainForm.cs
index 4e9b75607..34066ac0a 100644
--- a/Source/Core/Windows/MainForm.cs
+++ b/Source/Core/Windows/MainForm.cs
@@ -152,7 +152,7 @@ namespace CodeImp.DoomBuilder.Windows
 		
 		// Processing
 		private int processingcount;
-		private double lastupdatetime;
+		private float lastupdatetime;
 
 		// Updating
 		private int lockupdatecount;
@@ -2791,8 +2791,8 @@ namespace CodeImp.DoomBuilder.Windows
 		private void processor_Tick(object sender, EventArgs e)
 		{
 			Vector2D deltamouse;
-			double curtime = General.Clock.CurrentTime;
-			double deltatime = curtime - lastupdatetime;
+			float curtime = General.Clock.CurrentTime;
+			float deltatime = curtime - lastupdatetime;
 			lastupdatetime = curtime;
 			
 			// In exclusive mouse mode?
diff --git a/Source/Plugins/BuilderModes/ClassicModes/CurveLinedefsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/CurveLinedefsMode.cs
index d75b76c48..142834dd6 100644
--- a/Source/Plugins/BuilderModes/ClassicModes/CurveLinedefsMode.cs
+++ b/Source/Plugins/BuilderModes/ClassicModes/CurveLinedefsMode.cs
@@ -113,18 +113,18 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			//and lastly they are rotated and moved to fit with the original line
 
 			//calculate some identities of a circle segment (refer to the graph in the url above)
-			double c = line.Length;
-			double theta = angle;
+			float c = line.Length;
+			float theta = angle;
 
-			double d = (c / Math.Tan(theta / 2)) / 2;
-			double R = d / Math.Cos(theta / 2);
-			double h = R - d;
+			float d = (c / (float)Math.Tan(theta / 2)) / 2;
+            float R = d / (float)Math.Cos(theta / 2);
+			float h = R - d;
 
-			double yDeform = fixedcurve ? 1 : distance / h;
+			float yDeform = fixedcurve ? 1 : distance / h;
 			if(backwards)
 				yDeform = -yDeform;
 
-			double a, x, y;
+			float a, x, y;
 			Vector2D vertex;
 
 			for(int v = 1; v <= vertices; v++)
@@ -133,12 +133,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
 				//the curve starts at PI/2 - theta/2 and is segmented into vertices+1 segments
 				//this assumes the line is horisontal and on y = 0, the point is rotated and moved later
 
-				a = (Math.PI - theta) / 2 + v * (theta / (vertices + 1));
+                a = ((float)Math.PI - theta) / 2 + v * (theta / (vertices + 1));
 
 				//calculate the coordinates of the point, and distort the y coordinate
 				//using the deform factor calculated above
-				x = Math.Cos(a) * R;
-				y = (Math.Sin(a) * R - d) * yDeform;
+                x = (float)Math.Cos(a) * R;
+                y = ((float)Math.Sin(a) * R - d) * yDeform;
 
 				//rotate and transform to fit original line
 				vertex = new Vector2D((float)x, (float)y).GetRotated(line.Angle + Angle2D.PIHALF);
diff --git a/Source/Plugins/BuilderModes/ClassicModes/MakeSectorMode.cs b/Source/Plugins/BuilderModes/ClassicModes/MakeSectorMode.cs
index d772840f8..7d7dddce1 100644
--- a/Source/Plugins/BuilderModes/ClassicModes/MakeSectorMode.cs
+++ b/Source/Plugins/BuilderModes/ClassicModes/MakeSectorMode.cs
@@ -48,7 +48,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 	{
 		#region ================== Constants
 
-		private const double FLASH_DURATION = 300.0f;
+		private const float FLASH_DURATION = 300.0f;
 
 		#endregion
 
@@ -63,7 +63,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		// Flash polygon
 		private FlatVertex[] flashpolygon;
 		private float flashintensity;
-		private double flashstarttime;
+		private float flashstarttime;
 		
 		// Interface
 		protected bool selectpressed;
@@ -392,7 +392,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 						flashpolygon = new FlatVertex[s.FlatVertices.Length];
 						s.FlatVertices.CopyTo(flashpolygon, 0);
 						flashintensity = 1.0f;
-						flashstarttime = (double)General.Clock.CurrentTime;
+						flashstarttime = General.Clock.CurrentTime;
 						General.Interface.EnableProcessing();
 					}
 					
@@ -441,7 +441,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 							flashpolygon = new FlatVertex[s.FlatVertices.Length];
 							s.FlatVertices.CopyTo(flashpolygon, 0);
 							flashintensity = 1.0f;
-							flashstarttime = (double)General.Clock.CurrentTime;
+							flashstarttime = General.Clock.CurrentTime;
 							General.Interface.EnableProcessing();
 						}
 						else
@@ -507,7 +507,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		}
 
 		// Processing
-		public override void OnProcess(double deltatime)
+		public override void OnProcess(float deltatime)
 		{
 			base.OnProcess(deltatime);
 
@@ -515,7 +515,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			if(flashpolygon != null)
 			{
 				// Determine the intensity of the flash by time elapsed
-				double curtime = (double)General.Clock.CurrentTime;;
+				float curtime = General.Clock.CurrentTime;
 				flashintensity = 1f - (float)((curtime - flashstarttime) / FLASH_DURATION);
 				if(flashintensity > 0.0f)
 				{
diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySector.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySector.cs
index 3760ea3e6..4a9ee7e35 100644
--- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySector.cs
+++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySector.cs
@@ -115,7 +115,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		}
 		
 		// Processing
-		public virtual void OnProcess(double deltatime)
+		public virtual void OnProcess(float deltatime)
 		{
 			// If the texture was not loaded, but is loaded now, then re-setup geometry
 			if(setuponloadedtexture != 0)
diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs
index 89d6267e4..7ac6e299a 100644
--- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs
+++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualGeometrySidedef.cs
@@ -158,7 +158,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		}
 		
 		// Processing
-		public virtual void OnProcess(double deltatime)
+		public virtual void OnProcess(float deltatime)
 		{
 			// If the texture was not loaded, but is loaded now, then re-setup geometry
 			if(setuponloadedtexture != 0)
diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs
index b00dc81f8..54243578c 100644
--- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs
+++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs
@@ -50,7 +50,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		#region ================== Constants
 		
 		// Object picking
-		private const double PICK_INTERVAL = 80.0d;
+		private const float PICK_INTERVAL = 80.0f;
 		private const float PICK_RANGE = 0.98f;
 
 		// Gravity
@@ -67,7 +67,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		
 		// Object picking
 		private VisualPickResult target;
-		private double lastpicktime;
+		private float lastpicktime;
 		private bool locktarget;
 		
 		// This is true when a selection was made because the action is performed
@@ -508,7 +508,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		}
 		
 		// Processing
-		public override void OnProcess(double deltatime)
+		public override void OnProcess(float deltatime)
 		{
 			// Process things?
 			base.ProcessThings = (BuilderPlug.Me.ShowVisualThings != 0);
diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs
index 1554fd3d3..c4935e05f 100644
--- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs
+++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs
@@ -385,7 +385,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		public virtual void OnToggleUpperUnpegged() { }
 		public virtual void OnToggleLowerUnpegged() { }
 		public virtual void OnResetTextureOffset() { }
-		public virtual void OnProcess(double deltatime) { }
+		public virtual void OnProcess(float deltatime) { }
 		public virtual void OnTextureFloodfill() { }
 		public virtual void OnInsert() { }
 		//public virtual void OnDelete() { }
diff --git a/Source/Plugins/BuilderModes/VisualModes/IVisualEventReceiver.cs b/Source/Plugins/BuilderModes/VisualModes/IVisualEventReceiver.cs
index 89e34a5e8..c71490688 100644
--- a/Source/Plugins/BuilderModes/VisualModes/IVisualEventReceiver.cs
+++ b/Source/Plugins/BuilderModes/VisualModes/IVisualEventReceiver.cs
@@ -59,7 +59,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		void OnTextureFloodfill();
 		void OnToggleUpperUnpegged();
 		void OnToggleLowerUnpegged();
-		void OnProcess(double deltatime);
+		void OnProcess(float deltatime);
 		void OnInsert();
 		void OnDelete();
 
diff --git a/Source/Plugins/BuilderModes/VisualModes/NullVisualEventReceiver.cs b/Source/Plugins/BuilderModes/VisualModes/NullVisualEventReceiver.cs
index 62f0cd6db..6c009e0cd 100644
--- a/Source/Plugins/BuilderModes/VisualModes/NullVisualEventReceiver.cs
+++ b/Source/Plugins/BuilderModes/VisualModes/NullVisualEventReceiver.cs
@@ -123,7 +123,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		{
 		}
 
-		public void OnProcess(double deltatime)
+		public void OnProcess(float deltatime)
 		{
 		}
 
diff --git a/Source/Plugins/ColorPicker/ColorHandler.cs b/Source/Plugins/ColorPicker/ColorHandler.cs
index 5fcd02433..cd0f2e916 100644
--- a/Source/Plugins/ColorPicker/ColorHandler.cs
+++ b/Source/Plugins/ColorPicker/ColorHandler.cs
@@ -64,19 +64,19 @@ namespace CodeImp.DoomBuilder.ColorPicker
             // point within the circle). HSV.Saturation and HSV.value must be 
             // scaled to be between 0 and 1.
 
-            double h;
-            double s;
-            double v;
+            float h;
+            float s;
+            float v;
 
-            double r = 0;
-            double g = 0;
-            double b = 0;
+            float r = 0;
+            float g = 0;
+            float b = 0;
 
             // Scale Hue to be between 0 and 360. Saturation
             // and value scale to be between 0 and 1.
-            h = ((double)HSV.Hue / 255 * 360) % 360;
-            s = (double)HSV.Saturation / 255;
-            v = (double)HSV.value / 255;
+            h = ((float)HSV.Hue / 255 * 360) % 360;
+            s = (float)HSV.Saturation / 255;
+            v = (float)HSV.value / 255;
 
             if (s == 0) {
                 // If s is 0, all colors are the same.
@@ -85,13 +85,13 @@ namespace CodeImp.DoomBuilder.ColorPicker
                 g = v;
                 b = v;
             } else {
-                double p;
-                double q;
-                double t;
+                float p;
+                float q;
+                float t;
 
-                double fractionalSector;
+                float fractionalSector;
                 int sectorNumber;
-                double sectorPos;
+                float sectorPos;
 
                 // The color wheel consists of 6 sectors.
                 // Figure out which sector you//re in.
@@ -162,17 +162,17 @@ namespace CodeImp.DoomBuilder.ColorPicker
             // The code must scale these to be between 0 and 255 for
             // the purposes of this application.
 
-            double min;
-            double max;
-            double delta;
+            float min;
+            float max;
+            float delta;
 
-            double r = (double)RGB.Red / 255;
-            double g = (double)RGB.Green / 255;
-            double b = (double)RGB.Blue / 255;
+            float r = (float)RGB.Red / 255;
+            float g = (float)RGB.Green / 255;
+            float b = (float)RGB.Blue / 255;
 
-            double h;
-            double s;
-            double v;
+            float h;
+            float s;
+            float v;
 
             min = Math.Min(Math.Min(r, g), b);
             max = Math.Max(Math.Max(r, g), b);
diff --git a/Source/Plugins/ColorPicker/ColorWheel.cs b/Source/Plugins/ColorPicker/ColorWheel.cs
index 73799863b..a248d1bab 100644
--- a/Source/Plugins/ColorPicker/ColorWheel.cs
+++ b/Source/Plugins/ColorPicker/ColorWheel.cs
@@ -32,7 +32,7 @@ namespace CodeImp.DoomBuilder.ColorPicker {
         // degrees and radians. There are 2*PI radians in a 
         // full circle, and 360 degrees. This constant allows
         // you to convert back and forth.
-        private const double DEGREES_PER_RADIAN = 180.0 / Math.PI;
+        private const float DEGREES_PER_RADIAN = 180.0f / (float)Math.PI;
 
         // COLOR_COUNT represents the number of distinct colors
         // used to create the circular gradient. Its value 
@@ -51,7 +51,7 @@ namespace CodeImp.DoomBuilder.ColorPicker {
         private Rectangle colorRectangle;
         private Rectangle brightnessRectangle;
         private int brightnessX;
-        private double brightnessScaling;
+        private float brightnessScaling;
 
         // selectedColor is the actual value selected by the user. fullColor is the same color, 
         // with its brightness set to 255.
@@ -121,7 +121,7 @@ namespace CodeImp.DoomBuilder.ColorPicker {
                 // Also calculate the scaling factor, scaling the height
                 // to be between 0 and 255. 
                 brightnessX = brightnessRectangle.Left + brightnessRectangle.Width;
-                brightnessScaling = (double)255 / (brightnessMax - brightnessMin);
+                brightnessScaling = 255.0f / (brightnessMax - brightnessMin);
 
                 // Calculate the location of the brightness
                 // pointer. Assume it's at the highest position.
@@ -166,7 +166,7 @@ namespace CodeImp.DoomBuilder.ColorPicker {
         public void Draw(Graphics g, Point mousePoint) {
             // You've moved the mouse. 
             // Now update the screen to match.
-            double distance;
+            float distance;
             int degrees;
             Point delta;
             Point newColorPoint;
@@ -234,7 +234,7 @@ namespace CodeImp.DoomBuilder.ColorPicker {
                     // Calculate distance from the center to the new point 
                     // as a fraction of the radius. Use your old friend, 
                     // the Pythagorean theorem, to calculate this value.
-                    distance = Math.Sqrt(delta.X * delta.X + delta.Y * delta.Y) / radius;
+                    distance = (float)Math.Sqrt(delta.X * delta.X + delta.Y * delta.Y) / radius;
 
                     if (currentState == MouseState.DragInColor) {
                         if (distance > 1) {
@@ -326,8 +326,8 @@ namespace CodeImp.DoomBuilder.ColorPicker {
             // the center (HSV.Saturation), and the center, 
             // calculate the point corresponding to 
             // the selected color, on the color wheel.
-            colorPoint = GetPoint((double)HSV.Hue / 255 * 360,
-                (double)HSV.Saturation / 255 * radius,
+            colorPoint = GetPoint((float)HSV.Hue / 255 * 360,
+                (float)HSV.Saturation / 255 * radius,
                 centerPoint);
 
             // Given the brightness (HSV.value), calculate the 
@@ -373,7 +373,7 @@ namespace CodeImp.DoomBuilder.ColorPicker {
                 // is opposite from the normal direction here.
                 // That is, a y-coordinate that's "higher" on the form has a lower y-value, in this coordinate
                 // system. So everything's off by a factor of -1 when performing the ratio calculations.
-                degrees = (int)(-Math.Atan((double)pt.Y / pt.X) * DEGREES_PER_RADIAN);
+                degrees = (int)(-Math.Atan((float)pt.Y / pt.X) * DEGREES_PER_RADIAN);
 
                 // If the x-coordinate of the selected point is to the left of the center of the circle, you 
                 // need to add 180 degrees to the angle. ArcTan only gives you a value on the right-hand side 
@@ -421,25 +421,25 @@ namespace CodeImp.DoomBuilder.ColorPicker {
             Color[] Colors = new Color[COLOR_COUNT];
 
             for (int i = 0; i < COLOR_COUNT; i++)
-                Colors[i] = ColorHandler.HSVtoColor((int)((double)(i * 255) / COLOR_COUNT), 255, HSV.value);
+                Colors[i] = ColorHandler.HSVtoColor((int)((float)(i * 255) / COLOR_COUNT), 255, HSV.value);
             return Colors;
         }
 
-        private Point[] GetPoints(double radius, Point centerPoint) {
+        private Point[] GetPoints(float radius, Point centerPoint) {
             // Generate the array of points that describe the locations of the COLOR_COUNT colors to be 
             // displayed on the color wheel.
             Point[] Points = new Point[COLOR_COUNT];
 
             for (int i = 0; i < COLOR_COUNT; i++)
-                Points[i] = GetPoint((double)(i * 360) / COLOR_COUNT, radius, centerPoint);
+                Points[i] = GetPoint((float)(i * 360) / COLOR_COUNT, radius, centerPoint);
             return Points;
         }
 
-        private Point GetPoint(double degrees, double radius, Point centerPoint) {
+        private Point GetPoint(float degrees, float radius, Point centerPoint) {
             // Given the center of a circle and its radius, along
             // with the angle corresponding to the point, find the coordinates. 
             // In other words, conver  t from polar to rectangular coordinates.
-            double radians = degrees / DEGREES_PER_RADIAN;
+            float radians = degrees / DEGREES_PER_RADIAN;
 
             return new Point((int)(centerPoint.X + Math.Floor(radius * Math.Cos(radians))),
                 (int)(centerPoint.Y - Math.Floor(radius * Math.Sin(radians))));
diff --git a/Source/Plugins/GZDoomEditing/VisualModes/BaseVisualGeometrySector.cs b/Source/Plugins/GZDoomEditing/VisualModes/BaseVisualGeometrySector.cs
index 9554d52e1..97fbbc6a6 100644
--- a/Source/Plugins/GZDoomEditing/VisualModes/BaseVisualGeometrySector.cs
+++ b/Source/Plugins/GZDoomEditing/VisualModes/BaseVisualGeometrySector.cs
@@ -128,6 +128,21 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
 			float offsetx = dragdelta.x;
 			float offsety = dragdelta.y;
 
+            //mxd
+            if (General.Map.UDMF) {
+                if (GeometryType == VisualGeometryType.CEILING && level.sector.Fields.ContainsKey("rotationceiling")) {
+                    float angle = (float)level.sector.Fields["rotationceiling"].Value * (float)Math.PI / 180f;
+                    Vector2D v = new Vector2D(offsetx, offsety).GetRotated(angle);
+                    offsetx = v.x;
+                    offsety = v.y;
+                } else if (GeometryType == VisualGeometryType.FLOOR && level.sector.Fields.ContainsKey("rotationfloor")) {
+                    float angle = (float)level.sector.Fields["rotationfloor"].Value * (float)Math.PI / 180f;
+                    Vector2D v = new Vector2D(offsetx, offsety).GetRotated(angle);
+                    offsetx = v.x;
+                    offsety = v.y;
+                }
+            }
+
 			// Apply offsets
 			int newoffsetx = startoffsetx - (int)Math.Round(offsetx);
 			int newoffsety = startoffsety + (int)Math.Round(offsety);
@@ -243,7 +258,7 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
 		}
 		
 		// Processing
-		public virtual void OnProcess(double deltatime)
+		public virtual void OnProcess(float deltatime)
 		{
 			// If the texture was not loaded, but is loaded now, then re-setup geometry
 			if(setuponloadedtexture != 0)
diff --git a/Source/Plugins/GZDoomEditing/VisualModes/BaseVisualGeometrySidedef.cs b/Source/Plugins/GZDoomEditing/VisualModes/BaseVisualGeometrySidedef.cs
index b9f774d62..72cc5ea4f 100644
--- a/Source/Plugins/GZDoomEditing/VisualModes/BaseVisualGeometrySidedef.cs
+++ b/Source/Plugins/GZDoomEditing/VisualModes/BaseVisualGeometrySidedef.cs
@@ -419,7 +419,7 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
 		}
 		
 		// Processing
-		public virtual void OnProcess(double deltatime)
+		public virtual void OnProcess(float deltatime)
 		{
 			// If the texture was not loaded, but is loaded now, then re-setup geometry
 			if(setuponloadedtexture != 0)
diff --git a/Source/Plugins/GZDoomEditing/VisualModes/BaseVisualMode.cs b/Source/Plugins/GZDoomEditing/VisualModes/BaseVisualMode.cs
index d79a0b776..4f56c0fe0 100644
--- a/Source/Plugins/GZDoomEditing/VisualModes/BaseVisualMode.cs
+++ b/Source/Plugins/GZDoomEditing/VisualModes/BaseVisualMode.cs
@@ -51,7 +51,7 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
 		#region ================== Constants
 		
 		// Object picking
-		private const double PICK_INTERVAL = 80.0d;
+		private const float PICK_INTERVAL = 80.0f;
 		private const float PICK_RANGE = 0.98f;
 
 		// Gravity
@@ -68,7 +68,7 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
 		
 		// Object picking
 		private VisualPickResult target;
-		private double lastpicktime;
+		private float lastpicktime;
 		private bool locktarget;
 
 		// This keeps extra element info
@@ -690,7 +690,7 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
 		}
 		
 		// Processing
-		public override void OnProcess(double deltatime)
+		public override void OnProcess(float deltatime)
 		{
 			// Process things?
 			base.ProcessThings = (BuilderPlug.Me.ShowVisualThings != 0);
@@ -721,7 +721,7 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
 				else
 				{
 					// Fall down
-					gravity.z += (float)(GRAVITY * deltatime);
+					gravity.z += GRAVITY * deltatime;
 					if(gravity.z > 3.0f) gravity.z = 3.0f;
 
 					// Test if we don't go through a floor
diff --git a/Source/Plugins/GZDoomEditing/VisualModes/BaseVisualThing.cs b/Source/Plugins/GZDoomEditing/VisualModes/BaseVisualThing.cs
index cb0365bc2..2d69dd979 100644
--- a/Source/Plugins/GZDoomEditing/VisualModes/BaseVisualThing.cs
+++ b/Source/Plugins/GZDoomEditing/VisualModes/BaseVisualThing.cs
@@ -421,7 +421,7 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
 		public virtual void OnToggleUpperUnpegged() { }
 		public virtual void OnToggleLowerUnpegged() { }
 		public virtual void OnResetTextureOffset() { }
-		public virtual void OnProcess(double deltatime) { }
+		public virtual void OnProcess(float deltatime) { }
 		public virtual void OnTextureFloodfill() { }
 		public virtual void OnInsert() { }
 		//public virtual void OnDelete() { }
diff --git a/Source/Plugins/GZDoomEditing/VisualModes/IVisualEventReceiver.cs b/Source/Plugins/GZDoomEditing/VisualModes/IVisualEventReceiver.cs
index 604d371fd..c1eb67c06 100644
--- a/Source/Plugins/GZDoomEditing/VisualModes/IVisualEventReceiver.cs
+++ b/Source/Plugins/GZDoomEditing/VisualModes/IVisualEventReceiver.cs
@@ -59,7 +59,7 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
 		void OnTextureFloodfill();
 		void OnToggleUpperUnpegged();
 		void OnToggleLowerUnpegged();
-		void OnProcess(double deltatime);
+		void OnProcess(float deltatime);
 		void OnInsert();
 		void OnDelete();
 
diff --git a/Source/Plugins/GZDoomEditing/VisualModes/NullVisualEventReceiver.cs b/Source/Plugins/GZDoomEditing/VisualModes/NullVisualEventReceiver.cs
index f0bf5c84a..a337e8ba6 100644
--- a/Source/Plugins/GZDoomEditing/VisualModes/NullVisualEventReceiver.cs
+++ b/Source/Plugins/GZDoomEditing/VisualModes/NullVisualEventReceiver.cs
@@ -123,7 +123,7 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
 		{
 		}
 
-		public void OnProcess(double deltatime)
+		public void OnProcess(float deltatime)
 		{
 		}
 
diff --git a/Source/Plugins/UMDFControls/Controls/AngleControl.cs b/Source/Plugins/UMDFControls/Controls/AngleControl.cs
index 1dfad609c..daef5852a 100644
--- a/Source/Plugins/UMDFControls/Controls/AngleControl.cs
+++ b/Source/Plugins/UMDFControls/Controls/AngleControl.cs
@@ -76,7 +76,7 @@ namespace CodeImp.DoomBuilder.UDMFControls
                 // This value needs to be multiplied by -1 because the y-coordinate is opposite from the normal direction here.
                 // That is, a y-coordinate that's "higher" on the form has a lower y-value, in this coordinate
                 // system. So everything's off by a factor of -1 when performing the ratio calculations.
-                degrees = (int)(-Math.Atan((double)pt.Y / pt.X) * DEGREES_PER_RADIAN);
+                degrees = (int)(-Math.Atan((float)pt.Y / pt.X) * DEGREES_PER_RADIAN);
 
                 // If the x-coordinate of the selected point is to the left of the center of the circle, you 
                 // need to add 180 degrees to the angle. ArcTan only gives you a value on the right-hand side 
diff --git a/Source/Plugins/UMDFControls/Windows/UDMFControlsForm.cs b/Source/Plugins/UMDFControls/Windows/UDMFControlsForm.cs
index 5c5906b05..a1446c4d3 100644
--- a/Source/Plugins/UMDFControls/Windows/UDMFControlsForm.cs
+++ b/Source/Plugins/UMDFControls/Windows/UDMFControlsForm.cs
@@ -16,7 +16,7 @@ using System.Globalization;
 
 namespace CodeImp.DoomBuilder.UDMFControls
 {
-    public partial class UDMFControlsForm : DelayedForm {
+    public sealed partial class UDMFControlsForm : DelayedForm {
         private List<SurfaceProperties> floors;
         private List<SurfaceProperties> ceilings;
 
-- 
GitLab