diff --git a/src/dehacked.c b/src/dehacked.c
index 6093d6fd6e92250d0103f3dbd2fa781544bd3101..4d114727627d672eaa1adce3f4c21e272fcaaacf 100644
--- a/src/dehacked.c
+++ b/src/dehacked.c
@@ -585,21 +585,30 @@ static void readfreeslots(MYFILE *f)
 					continue;
 				// Copy in the spr2 name and increment free_spr2.
 				if (free_spr2 < NUMPLAYERSPRITES) {
-					CONS_Printf("Sprite SPR2_%s allocated.\n",word);
 					strncpy(spr2names[free_spr2],word,4);
 					spr2defaults[free_spr2] = 0;
 					spr2names[free_spr2++][4] = 0;
 				} else
-					CONS_Alert(CONS_WARNING, "Ran out of free SPR2 slots!\n");
+					deh_warning("Ran out of free SPR2 slots!\n");
 			}
 			else if (fastcmp(type, "TOL"))
 			{
-				if (lastcustomtol > 31)
-					CONS_Alert(CONS_WARNING, "Ran out of free typeoflevel slots!\n");
+				// Search if we already have a typeoflevel by that name...
+				for (i = 0; TYPEOFLEVEL[i].name; i++)
+					if (fastcmp(word, TYPEOFLEVEL[i].name))
+						break;
+
+				// We found it? Then don't allocate another one.
+				if (TYPEOFLEVEL[i].name)
+					continue;
+
+				// We don't, so freeslot it.
+				if (lastcustomtol == (UINT32)MAXTOL) // Unless you have way too many, since they're flags.
+					deh_warning("Ran out of free typeoflevel slots!\n");
 				else
 				{
-					G_AddTOL((1<<lastcustomtol), word);
-					lastcustomtol++;
+					G_AddTOL(lastcustomtol, word);
+					lastcustomtol <<= 1;
 				}
 			}
 			else
@@ -1105,38 +1114,7 @@ static void readsprite2(MYFILE *f, INT32 num)
 	Z_Free(s);
 }
 
-INT32 numtolinfo = NUMBASETOL;
-UINT32 lastcustomtol = 13;
-
-tolinfo_t TYPEOFLEVEL[NUMMAXTOL] = {
-	{"SOLO",TOL_SP},
-	{"SP",TOL_SP},
-	{"SINGLEPLAYER",TOL_SP},
-	{"SINGLE",TOL_SP},
-
-	{"COOP",TOL_COOP},
-	{"CO-OP",TOL_COOP},
-
-	{"COMPETITION",TOL_COMPETITION},
-	{"RACE",TOL_RACE},
-
-	{"MATCH",TOL_MATCH},
-	{"TAG",TOL_TAG},
-	{"CTF",TOL_CTF},
-
-	{"2D",TOL_2D},
-	{"MARIO",TOL_MARIO},
-	{"NIGHTS",TOL_NIGHTS},
-	{"OLDBRAK",TOL_ERZ3},
-
-	{"XMAS",TOL_XMAS},
-	{"CHRISTMAS",TOL_XMAS},
-	{"WINTER",TOL_XMAS},
-
-	{NULL, 0}
-};
-
-// copypasted from readPlayer :sleep:
+// copypasted from readPlayer :]
 static const char *const GAMETYPERULE_LIST[];
 static void readgametype(MYFILE *f, char *gtname)
 {
@@ -10468,16 +10446,23 @@ static inline int lib_freeslot(lua_State *L)
 		}
 		else if (fastcmp(type, "TOL"))
 		{
-			if (lastcustomtol > 31)
-				CONS_Alert(CONS_WARNING, "Ran out of free typeoflevel slots!\n");
-			else
-			{
-				UINT32 newtol = (1<<lastcustomtol);
-				CONS_Printf("TypeOfLevel TOL_%s allocated.\n",word);
-				G_AddTOL(newtol, word);
-				lua_pushinteger(L, newtol);
-				lastcustomtol++;
-				r++;
+			// Search if we already have a typeoflevel by that name...
+			int i;
+			for (i = 0; TYPEOFLEVEL[i].name; i++)
+				if (fastcmp(word, TYPEOFLEVEL[i].name))
+					break;
+
+			// We don't, so allocate a new one.
+			if (TYPEOFLEVEL[i].name == NULL) {
+				if (lastcustomtol == (UINT32)MAXTOL) // Unless you have way too many, since they're flags.
+					CONS_Alert(CONS_WARNING, "Ran out of free typeoflevel slots!\n");
+				else {
+					CONS_Printf("TypeOfLevel TOL_%s allocated.\n",word);
+					G_AddTOL(lastcustomtol, word);
+					lua_pushinteger(L, lastcustomtol);
+					lastcustomtol <<= 1;
+					r++;
+				}
 			}
 		}
 		Z_Free(s);
diff --git a/src/doomstat.h b/src/doomstat.h
index c7c12632ab1dcf45c8ab5040ccb5095c91d799dc..cf02e438900c7996ed5a058139f5b6bfc278b8e2 100644
--- a/src/doomstat.h
+++ b/src/doomstat.h
@@ -437,6 +437,7 @@ extern const char *Gametype_ConstantNames[NUMGAMETYPES];
 extern INT32 pointlimits[NUMGAMETYPES];
 extern INT32 timelimits[NUMGAMETYPES];
 
+// TypeOfLevel things
 enum TypeOfLevel
 {
 	TOL_SP          = 0x01, ///< Single Player
@@ -461,16 +462,16 @@ enum TypeOfLevel
 	TOL_XMAS   = 0x1000, ///< Christmas NiGHTS
 };
 
-#define NUMBASETOL 18
-#define NUMMAXTOL (18 + NUMGAMETYPEFREESLOTS)
+#define MAXTOL             (1<<31)
+#define NUMBASETOLNAMES    (19)
+#define NUMTOLNAMES        (NUMBASETOLNAMES + NUMGAMETYPEFREESLOTS)
 
 typedef struct
 {
 	const char *name;
 	UINT32 flag;
 } tolinfo_t;
-extern tolinfo_t TYPEOFLEVEL[NUMMAXTOL];
-extern INT32 numtolinfo;
+extern tolinfo_t TYPEOFLEVEL[NUMTOLNAMES];
 extern UINT32 lastcustomtol;
 
 extern tic_t totalplaytime;
diff --git a/src/g_game.c b/src/g_game.c
index aaab89163cb94b642bba94921342571b80f515c6..9897220105c69b0eab054e3efd4da75936ad47e8 100644
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -3384,6 +3384,36 @@ UINT32 gametypetol[NUMGAMETYPES] =
 	TOL_CTF, // CTF
 };
 
+tolinfo_t TYPEOFLEVEL[NUMTOLNAMES] = {
+	{"SOLO",TOL_SP},
+	{"SP",TOL_SP},
+	{"SINGLEPLAYER",TOL_SP},
+	{"SINGLE",TOL_SP},
+
+	{"COOP",TOL_COOP},
+	{"CO-OP",TOL_COOP},
+
+	{"COMPETITION",TOL_COMPETITION},
+	{"RACE",TOL_RACE},
+
+	{"MATCH",TOL_MATCH},
+	{"TAG",TOL_TAG},
+	{"CTF",TOL_CTF},
+
+	{"2D",TOL_2D},
+	{"MARIO",TOL_MARIO},
+	{"NIGHTS",TOL_NIGHTS},
+	{"OLDBRAK",TOL_ERZ3},
+
+	{"XMAS",TOL_XMAS},
+	{"CHRISTMAS",TOL_XMAS},
+	{"WINTER",TOL_XMAS},
+
+	{NULL, 0}
+};
+
+UINT32 lastcustomtol = (TOL_XMAS<<1);
+
 //
 // G_AddTOL
 //
@@ -3391,16 +3421,16 @@ UINT32 gametypetol[NUMGAMETYPES] =
 //
 void G_AddTOL(UINT32 newtol, const char *tolname)
 {
-	TYPEOFLEVEL[numtolinfo].name = Z_StrDup(tolname);
-	TYPEOFLEVEL[numtolinfo].flag = newtol;
-	numtolinfo++;
+	INT32 i;
+	for (i = 0; TYPEOFLEVEL[i].name; i++)
+		;
 
-	TYPEOFLEVEL[numtolinfo].name = NULL;
-	TYPEOFLEVEL[numtolinfo].flag = 0;
+	TYPEOFLEVEL[i].name = Z_StrDup(tolname);
+	TYPEOFLEVEL[i].flag = newtol;
 }
 
 //
-// G_AddTOL
+// G_AddGametypeTOL
 //
 // Assigns a type of level to a gametype.
 //