diff --git a/src/doomdata.h b/src/doomdata.h
index 1dcd8e6b4..c08714f46 100644
--- a/src/doomdata.h
+++ b/src/doomdata.h
@@ -337,6 +337,7 @@ struct mapthinghexen_t
 };
 
 class FArchive;
+struct FDoomEdEntry;
 
 // Internal representation of a mapthing
 struct FMapThing
@@ -346,7 +347,8 @@ struct FMapThing
 	fixed_t		y;
 	fixed_t		z;
 	short		angle;
-	short		type;
+	FDoomEdEntry *info;
+	short		EdNum;
 	WORD		SkillFilter;
 	WORD		ClassFilter;
 	DWORD		flags;
@@ -364,7 +366,7 @@ struct FMapThing
 	short		roll;
 	DWORD		RenderStyle;
 
-	void Serialize (FArchive &);
+	//void Serialize (FArchive &);
 };
 
 
diff --git a/src/g_doomedmap.cpp b/src/g_doomedmap.cpp
index c3e586bc2..131ddd076 100644
--- a/src/g_doomedmap.cpp
+++ b/src/g_doomedmap.cpp
@@ -45,20 +45,31 @@
 
 
 const char *SpecialMapthingNames[] = {
-	"$PLAYER1START",
-	"$PLAYER2START",
-	"$PLAYER3START",
-	"$PLAYER4START",
-	"$PLAYER5START",
-	"$PLAYER6START",
-	"$PLAYER7START",
-	"$PLAYER8START",
-	"$DEATHMATCHSTART",
-	"$SSEQOVERRIDE",
-	"$POLYANCHOR",
-	"$POLYSPAWN",
-	"$POLYSPAWNCRUSH",
-	"$POLYSPAWNHURT"
+	"$Player1Start",
+	"$Player2Start",
+	"$Player3Start",
+	"$Player4Start",
+	"$Player5Start",
+	"$Player6Start",
+	"$Player7Start",
+	"$Player8Start",
+	"$DeathmatchStart",
+	"$SSeqOverride",
+	"$PolyAnchor",
+	"$PolySpawn",
+	"$PolySpawnCrush",
+	"$PolySpawnHurt",
+	"$SlopeFloorPointLine",
+	"$SlopeCeilingPointLine",
+	"$SetFloorSlope",
+	"$SetCeilingSlope",
+	"$VavoomFloor",
+	"$VavoomCeiling",
+	"$CopyFloorPlane",
+	"$CopyCeilingPlane",
+	"$VertexFloorZ",
+	"$VertexCeilingZ",
+
 };
 //==========================================================================
 //
diff --git a/src/info.h b/src/info.h
index 2ab0a82d6..f6750df9e 100644
--- a/src/info.h
+++ b/src/info.h
@@ -287,20 +287,31 @@ struct FDoomEdEntry
 
 enum ESpecialMapthings
 {
-	SMT_PLAYER1START = 1,
-	SMT_PLAYER2START,
-	SMT_PLAYER3START,
-	SMT_PLAYER4START,
-	SMT_PLAYER5START,
-	SMT_PLAYER6START,
-	SMT_PLAYER7START,
-	SMT_PLAYER8START,
-	SMT_DEATHMATCHSTART,
-	SMT_SSEQOVERRIDE,
-	SMT_POLYANCHOR,
-	SMT_POLYSPAWN,
-	SMT_POLYSPAWNCRUSH,
-	SMT_POLYSPAWNHURT,
+	SMT_Player1Start = 1,
+	SMT_Player2Start,
+	SMT_Player3Start,
+	SMT_Player4Start,
+	SMT_Player5Start,
+	SMT_Player6Start,
+	SMT_Player7Start,
+	SMT_Player8Start,
+	SMT_DeathmatchStart,
+	SMT_SSeqOverride,
+	SMT_PolyAnchor,
+	SMT_PolySpawn,
+	SMT_PolySpawnCrush,
+	SMT_PolySpawnHurt,
+	SMT_SlopeFloorPointLine,
+	SMT_SlopeCeilingPointLine,
+	SMT_SetFloorSlope,
+	SMT_SetCeilingSlope,
+	SMT_VavoomFloor,
+	SMT_VavoomCeiling,
+	SMT_CopyFloorPlane,
+	SMT_CopyCeilingPlane,
+	SMT_VertexFloorZ,
+	SMT_VertexCeilingZ,
+
 };
 
 
diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp
index c12c79608..c6fffd87c 100644
--- a/src/p_buildmap.cpp
+++ b/src/p_buildmap.cpp
@@ -716,30 +716,31 @@ static int LoadSprites (spritetype *sprites, Xsprite *xsprites, int numsprites,
 			mapthings[count].args[1] = xsprites[i].Data4;
 			mapthings[count].args[2] = xsprites[i].Data1;
 			mapthings[count].args[3] = xsprites[i].Data2;
-			mapthings[count].type = 14065;
+			mapthings[count].EdNum = 14065;
 		}
 		else if (xsprites != NULL && sprites[i].lotag == 1)
 		{ // Blood player start
 			if (xsprites[i].Data1 < 4)
-				mapthings[count].type = 1 + xsprites[i].Data1;
+				mapthings[count].EdNum= 1 + xsprites[i].Data1;
 			else
-				mapthings[count].type = 4001 + xsprites[i].Data1 - 4;
+				mapthings[count].EdNum = 4001 + xsprites[i].Data1 - 4;
 		}
 		else if (xsprites != NULL && sprites[i].lotag == 2)
 		{ // Bloodbath start
-			mapthings[count].type = 11;
+			mapthings[count].EdNum = 11;
 		}
 		else
 		{
 			if (sprites[i].cstat & 32768) continue;
 			if (sprites[i].xrepeat == 0 || sprites[i].yrepeat == 0) continue;
 
-			mapthings[count].type = 9988;
+			mapthings[count].EdNum = 9988;
 			mapthings[count].args[0] = sprites[i].picnum;
 			mapthings[count].args[2] = sprites[i].xrepeat;
 			mapthings[count].args[3] = sprites[i].yrepeat;
 			mapthings[count].args[4] = sprites[i].cstat;
 		}
+		mapthings[count].info = DoomEdMap.CheckKey(mapthings[count].EdNum);
 		count++;
 	}
 	return count;
@@ -783,7 +784,7 @@ static void CreateStartSpot (fixed_t *pos, FMapThing *start)
 	FMapThing mt =
 	{
 		0, (LittleLong(pos[0])<<12), ((-LittleLong(pos[1]))<<12), 0,// tid, x, y, z
-		short(Scale ((2048-angle)&2047, 360, 2048)), 1,	// angle, type
+		short(Scale ((2048-angle)&2047, 360, 2048)), DoomEdMap.CheckKey(1), 1,	// angle, type
 		0, 0,							// Skillfilter, Classfilter
 		7|MTF_SINGLE|224,				// flags
 		0, {0}, 0 						// special is 0, args and Conversation are 0
diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp
index 5eb806b02..76afec801 100644
--- a/src/p_mobj.cpp
+++ b/src/p_mobj.cpp
@@ -384,11 +384,6 @@ void AActor::Serialize (FArchive &arc)
 	}
 }
 
-void FMapThing::Serialize (FArchive &arc)
-{
-	arc << thingid << x << y << z << angle << type << flags << special
-		<< args[0] << args[1] << args[2] << args[3] << args[4];
-}
 
 AActor::AActor () throw()
 {
@@ -4597,17 +4592,17 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position)
 	AActor *mobj;
 	fixed_t x, y, z;
 
-	if (mthing->type == 0 || mthing->type == -1)
+	if (mthing->EdNum == 0 || mthing->EdNum == -1)
 		return NULL;
 
 	// find which type to spawn
-	FDoomEdEntry *mentry = DoomEdMap.CheckKey(mthing->type);
+	FDoomEdEntry *mentry = mthing->info;
 
 	if (mentry == NULL)
 	{
 		// [RH] Don't die if the map tries to spawn an unknown thing
 		Printf ("Unknown type %i at (%i, %i)\n",
-				 mthing->type,
+				 mthing->EdNum,
 				 mthing->x>>FRACBITS, mthing->y>>FRACBITS);
 		mentry = DoomEdMap.CheckKey(0);
 		if (mentry == NULL)	// we need a valid entry for the rest of this function so if we can't find a default, let's exit right away.
@@ -4634,7 +4629,7 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position)
 
 		switch (mentry->Special)
 		{
-		case SMT_DEATHMATCHSTART:
+		case SMT_DeathmatchStart:
 		{
 			// count deathmatch start positions
 			FPlayerStart start(mthing, 0);
@@ -4642,10 +4637,10 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position)
 			return NULL;
 		}
 
-		case SMT_POLYANCHOR:
-		case SMT_POLYSPAWN:
-		case SMT_POLYSPAWNCRUSH:
-		case SMT_POLYSPAWNHURT:
+		case SMT_PolyAnchor:
+		case SMT_PolySpawn:
+		case SMT_PolySpawnCrush:
+		case SMT_PolySpawnHurt:
 		{
 			polyspawns_t *polyspawn = new polyspawns_t;
 			polyspawn->next = polyspawns;
@@ -4654,20 +4649,20 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position)
 			polyspawn->angle = mthing->angle;
 			polyspawn->type = mentry->Special;
 			polyspawns = polyspawn;
-			if (mentry->Special != SMT_POLYANCHOR)
+			if (mentry->Special != SMT_PolyAnchor)
 				po_NumPolyobjs++;
 			return NULL;
 		}
 
-		case SMT_PLAYER1START:
-		case SMT_PLAYER2START:
-		case SMT_PLAYER3START:
-		case SMT_PLAYER4START:
-		case SMT_PLAYER5START:
-		case SMT_PLAYER6START:
-		case SMT_PLAYER7START:
-		case SMT_PLAYER8START:
-			pnum = mentry->Special - SMT_PLAYER1START;
+		case SMT_Player1Start:
+		case SMT_Player2Start:
+		case SMT_Player3Start:
+		case SMT_Player4Start:
+		case SMT_Player5Start:
+		case SMT_Player6Start:
+		case SMT_Player7Start:
+		case SMT_Player8Start:
+			pnum = mentry->Special - SMT_Player1Start;
 			break;
 
 		// Sound sequence override will be handled later
@@ -4752,7 +4747,7 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position)
 	}
 
 	// [RH] sound sequence overriders
-	if (mentry->Type == NULL && mentry->Special == SMT_SSEQOVERRIDE)
+	if (mentry->Type == NULL && mentry->Special == SMT_SSeqOverride)
 	{
 		int type = mentry->Args[0];
 		if (type == 255) type = -1;
diff --git a/src/p_setup.cpp b/src/p_setup.cpp
index eaa0d4027..80c84ffde 100644
--- a/src/p_setup.cpp
+++ b/src/p_setup.cpp
@@ -1665,7 +1665,7 @@ AActor *SpawnMapThing(int index, FMapThing *mt, int position)
 	if (dumpspawnedthings)
 	{
 		Printf("%5d: (%5d, %5d, %5d), doomednum = %5d, flags = %04x, type = %s\n",
-			index, mt->x>>FRACBITS, mt->y>>FRACBITS, mt->z>>FRACBITS, mt->type, mt->flags, 
+			index, mt->x>>FRACBITS, mt->y>>FRACBITS, mt->z>>FRACBITS, mt->EdNum, mt->flags, 
 			spawned? spawned->GetClass()->TypeName.GetChars() : "(none)");
 	}
 	T_AddSpawnedThing(spawned);
@@ -1785,7 +1785,8 @@ void P_LoadThings (MapData * map)
 		mti[i].x = LittleShort(mt->x) << FRACBITS;
 		mti[i].y = LittleShort(mt->y) << FRACBITS;
 		mti[i].angle = LittleShort(mt->angle);
-		mti[i].type = LittleShort(mt->type);
+		mti[i].EdNum = LittleShort(mt->type);
+		mti[i].info = DoomEdMap.CheckKey(mti[i].EdNum);
 	}
 	delete [] mtp;
 }
@@ -1825,7 +1826,8 @@ void P_LoadThings2 (MapData * map)
 		mti[i].y = LittleShort(mth[i].y)<<FRACBITS;
 		mti[i].z = LittleShort(mth[i].z)<<FRACBITS;
 		mti[i].angle = LittleShort(mth[i].angle);
-		mti[i].type = LittleShort(mth[i].type);
+		mti[i].EdNum = LittleShort(mth[i].type);
+		mti[i].info = DoomEdMap.CheckKey(mti[i].EdNum);
 		mti[i].flags = LittleShort(mth[i].flags);
 		mti[i].special = mth[i].special;
 		for(int j=0;j<5;j++) mti[i].args[j] = mth[i].args[j];
@@ -3336,14 +3338,14 @@ void P_GetPolySpots (MapData * map, TArray<FNodeBuilder::FPolyStart> &spots, TAr
 	{
 		for (unsigned int i = 0; i < MapThingsConverted.Size(); ++i)
 		{
-			FDoomEdEntry *mentry = DoomEdMap.CheckKey(MapThingsConverted[i].type);
-			if (mentry != NULL && mentry->Type == NULL && mentry->Special >= SMT_POLYANCHOR && mentry->Special <= SMT_POLYSPAWNHURT)
+			FDoomEdEntry *mentry = MapThingsConverted[i].info;
+			if (mentry != NULL && mentry->Type == NULL && mentry->Special >= SMT_PolyAnchor && mentry->Special <= SMT_PolySpawnHurt)
 			{
 				FNodeBuilder::FPolyStart newvert;
 				newvert.x = MapThingsConverted[i].x;
 				newvert.y = MapThingsConverted[i].y;
 				newvert.polynum = MapThingsConverted[i].angle;
-				if (mentry->Special == SMT_POLYANCHOR)
+				if (mentry->Special == SMT_PolyAnchor)
 				{
 					anchors.Push (newvert);
 				}
diff --git a/src/p_slopes.cpp b/src/p_slopes.cpp
index 2cce53a92..41f7a1837 100644
--- a/src/p_slopes.cpp
+++ b/src/p_slopes.cpp
@@ -266,20 +266,6 @@ void P_VavoomSlope(sector_t * sec, int id, fixed_t x, fixed_t y, fixed_t z, int
 	}
 }
 				   
-enum
-{
-	THING_SlopeFloorPointLine = 9500,
-	THING_SlopeCeilingPointLine = 9501,
-	THING_SetFloorSlope = 9502,
-	THING_SetCeilingSlope = 9503,
-	THING_CopyFloorPlane = 9510,
-	THING_CopyCeilingPlane = 9511,
-	THING_VavoomFloor=1500,
-	THING_VavoomCeiling=1501,
-	THING_VertexFloorZ=1504,
-	THING_VertexCeilingZ=1505,
-};
-
 //==========================================================================
 //
 //	P_SetSlopesFromVertexHeights
@@ -294,24 +280,27 @@ static void P_SetSlopesFromVertexHeights(FMapThing *firstmt, FMapThing *lastmt,
 
 	for (mt = firstmt; mt < lastmt; ++mt)
 	{
-		if (mt->type == THING_VertexFloorZ || mt->type == THING_VertexCeilingZ)
+		if (mt->info != NULL && mt->info->Type == NULL)
 		{
-			for(int i=0; i<numvertexes; i++)
+			if (mt->info->Special == SMT_VertexFloorZ || mt->info->Special == SMT_VertexCeilingZ)
 			{
-				if (vertexes[i].x == mt->x && vertexes[i].y == mt->y)
+				for (int i = 0; i < numvertexes; i++)
 				{
-					if (mt->type == THING_VertexFloorZ) 
+					if (vertexes[i].x == mt->x && vertexes[i].y == mt->y)
 					{
-						vt_heights[0][i] = mt->z;
+						if (mt->info->Special == SMT_VertexFloorZ)
+						{
+							vt_heights[0][i] = mt->z;
+						}
+						else
+						{
+							vt_heights[1][i] = mt->z;
+						}
+						vt_found = true;
 					}
-					else 
-					{
-						vt_heights[1][i] = mt->z;
-					}
-					vt_found = true;
 				}
+				mt->EdNum = 0;
 			}
-			mt->type = 0;
 		}
 	}
 
@@ -427,49 +416,51 @@ void P_SpawnSlopeMakers (FMapThing *firstmt, FMapThing *lastmt, const int *oldve
 
 	for (mt = firstmt; mt < lastmt; ++mt)
 	{
-		if ((mt->type >= THING_SlopeFloorPointLine &&
-			 mt->type <= THING_SetCeilingSlope) ||
-			mt->type == THING_VavoomFloor || mt->type == THING_VavoomCeiling)
+		if (mt->info != NULL && mt->info->Type == NULL &&
+		   (mt->info->Special >= SMT_SlopeFloorPointLine && mt->info->Special <= SMT_VavoomCeiling))
 		{
 			fixed_t x, y, z;
 			secplane_t *refplane;
 			sector_t *sec;
+			bool ceiling;
 
 			x = mt->x;
 			y = mt->y;
 			sec = P_PointInSector (x, y);
-			if (mt->type & 1)
+			if (mt->info->Special == SMT_SlopeCeilingPointLine || mt->info->Special == SMT_VavoomCeiling || mt->info->Special == SMT_SetCeilingSlope)
 			{
 				refplane = &sec->ceilingplane;
+				ceiling = true;
 			}
 			else
 			{
 				refplane = &sec->floorplane;
+				ceiling = false;
 			}
 			z = refplane->ZatPoint (x, y) + (mt->z);
-			if (mt->type == THING_VavoomFloor || mt->type == THING_VavoomCeiling)
-			{
-				P_VavoomSlope(sec, mt->thingid, x, y, mt->z, mt->type & 1); 
+			if (mt->info->Special <= SMT_SlopeCeilingPointLine)
+			{ // SlopeFloorPointLine and SlopCeilingPointLine
+				P_SlopeLineToPoint (mt->args[0], x, y, z, ceiling);
 			}
-			else if (mt->type <= THING_SlopeCeilingPointLine)
-			{ // THING_SlopeFloorPointLine and THING_SlopCeilingPointLine
-				P_SlopeLineToPoint (mt->args[0], x, y, z, mt->type & 1);
+			else if (mt->info->Special <= SMT_SetCeilingSlope)
+			{ // SetFloorSlope and SetCeilingSlope
+				P_SetSlope (refplane, ceiling, mt->angle, mt->args[0], x, y, z);
 			}
-			else
-			{ // THING_SetFloorSlope and THING_SetCeilingSlope
-				P_SetSlope (refplane, mt->type & 1, mt->angle, mt->args[0], x, y, z);
+			else 
+			{ // VavoomFloor and VavoomCeiling
+				P_VavoomSlope(sec, mt->thingid, x, y, mt->z, ceiling); 
 			}
-			mt->type = 0;
+			mt->EdNum = 0;
 		}
 	}
 
 	for (mt = firstmt; mt < lastmt; ++mt)
 	{
-		if (mt->type == THING_CopyFloorPlane ||
-			mt->type == THING_CopyCeilingPlane)
+		if (mt->info != NULL && mt->info->Type == NULL &&
+			(mt->info->Special == SMT_CopyFloorPlane || mt->info->Special == SMT_CopyCeilingPlane))
 		{
-			P_CopyPlane (mt->args[0], mt->x, mt->y, mt->type & 1);
-			mt->type = 0;
+			P_CopyPlane (mt->args[0], mt->x, mt->y, mt->info->Special == SMT_CopyCeilingPlane);
+			mt->EdNum = 0;
 		}
 	}
 
diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp
index f0fb79690..31634ee81 100644
--- a/src/p_udmf.cpp
+++ b/src/p_udmf.cpp
@@ -500,7 +500,8 @@ public:
 				break;
 
 			case NAME_Type:
-				th->type = (short)CheckInt(key);
+				th->EdNum = (short)CheckInt(key);
+				th->info = DoomEdMap.CheckKey(th->EdNum);
 				break;
 
 			case NAME_Conversation:
diff --git a/src/po_man.cpp b/src/po_man.cpp
index 9158a7027..60627e4f3 100644
--- a/src/po_man.cpp
+++ b/src/po_man.cpp
@@ -1561,8 +1561,8 @@ static void SpawnPolyobj (int index, int tag, int type)
 			sd->linedef->args[0] = 0;
 			IterFindPolySides(&polyobjs[index], sd);
 			po->MirrorNum = sd->linedef->args[1];
-			po->crush = (type != SMT_POLYSPAWN) ? 3 : 0;
-			po->bHurtOnTouch = (type == SMT_POLYSPAWNHURT);
+			po->crush = (type != SMT_PolySpawn) ? 3 : 0;
+			po->bHurtOnTouch = (type == SMT_PolySpawnHurt);
 			po->tag = tag;
 			po->seqType = sd->linedef->args[2];
 			if (po->seqType < 0 || po->seqType > 63)
@@ -1632,8 +1632,8 @@ static void SpawnPolyobj (int index, int tag, int type)
 		}
 		if (po->Sidedefs.Size() > 0)
 		{
-			po->crush = (type != SMT_POLYSPAWN) ? 3 : 0;
-			po->bHurtOnTouch = (type == SMT_POLYSPAWNHURT);
+			po->crush = (type != SMT_PolySpawn) ? 3 : 0;
+			po->bHurtOnTouch = (type == SMT_PolySpawnHurt);
 			po->tag = tag;
 			po->seqType = po->Sidedefs[0]->linedef->args[3];
 			po->MirrorNum = po->Sidedefs[0]->linedef->args[2];
@@ -1756,7 +1756,7 @@ void PO_Init (void)
 	for (polyspawn = polyspawns, prev = &polyspawns; polyspawn;)
 	{
 		// 9301 (3001) = no crush, 9302 (3002) = crushing, 9303 = hurting touch
-		if (polyspawn->type >= SMT_POLYSPAWN &&	polyspawn->type <= SMT_POLYSPAWNHURT)
+		if (polyspawn->type >= SMT_PolySpawn &&	polyspawn->type <= SMT_PolySpawnHurt)
 		{ 
 			// Polyobj StartSpot Pt.
 			polyobjs[polyIndex].StartSpot.x = polyspawn->x;
@@ -1776,7 +1776,7 @@ void PO_Init (void)
 	for (polyspawn = polyspawns; polyspawn;)
 	{
 		polyspawns_t *next = polyspawn->next;
-		if (polyspawn->type == SMT_POLYANCHOR)
+		if (polyspawn->type == SMT_PolyAnchor)
 		{ 
 			// Polyobj Anchor Pt.
 			TranslateToStartSpot (polyspawn->angle, polyspawn->x, polyspawn->y);
diff --git a/wadsrc/static/mapinfo/common.txt b/wadsrc/static/mapinfo/common.txt
index 5e83ee727..80c14acd0 100644
--- a/wadsrc/static/mapinfo/common.txt
+++ b/wadsrc/static/mapinfo/common.txt
@@ -26,6 +26,10 @@ DoomEdNums
   1408 = "$SSeqOverride", 8
   1409 = "$SSeqOverride", 9
   1411 = "$SSeqOverride"
+  1500 = "$VavoomFloor"
+  1501 = "$VavoomCeiling"
+  1504 = "$VertexFloorZ"
+  1505 = "$VertexCeilingZ"
   5001 = PointPusher
   5002 = PointPuller
   5004 = FS_Mapspot
@@ -73,6 +77,12 @@ DoomEdNums
   9301 = "$PolySpawn"
   9302 = "$PolySpawnCrush"
   9303 = "$PolySpawnHurt"
+  9500 = "$SlopeFloorPointLine"
+  9501 = "$SlopeCeilingPointLine"
+  9502 = "$SetFloorSlope"
+  9503 = "$SetCeilingSlope"
+  9510 = "$CopyFloorPlane"
+  9511 = "$CopyCeilingPlane"
   9982 = SecActEyesAboveC
   9983 = SecActEyesBelowC
   9988 = CustomSprite