diff --git a/src/doomdata.h b/src/doomdata.h
index 439cb22b1555ac003b8e440f444d14d736893e9c..634458cd450daa9ba89e520bdc483084c84c2e31 100644
--- a/src/doomdata.h
+++ b/src/doomdata.h
@@ -217,6 +217,13 @@ typedef struct
 	struct mobj_s *mobj;
 } mapthing_t;
 
+#define THING_TYPE_SPAWNPOINT_COOP_START 1
+#define THING_TYPE_SPAWNPOINT_COOP_END 32
+#define THING_TYPE_SPAWNPOINT_MATCH 33
+#define THING_TYPE_SPAWNPOINT_RED_TEAM 34
+#define THING_TYPE_SPAWNPOINT_BLUE_TEAM 35
+#define THING_TYPE_SPAWNPOINT_TEAM 36
+
 #define THING_TYPE_CTF_TEAM_FLAG 324
 
 #define ZSHIFT 4
diff --git a/src/g_game.c b/src/g_game.c
index f950a6b198979fce8934a5af50853a6b98b52aa3..5b06381ffd93c5614984792cf706281e246075a8 100644
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -2979,7 +2979,11 @@ void G_CountPlayerStarts(void)
 
 boolean G_IsSpawnPointThingType(UINT16 mthingtype)
 {
-	return mthingtype >= 1 && mthingtype <= 35;
+	return (mthingtype >= THING_TYPE_SPAWNPOINT_COOP_START && mthingtype <= THING_TYPE_SPAWNPOINT_COOP_END)
+	|| mthingtype == THING_TYPE_SPAWNPOINT_MATCH
+	|| mthingtype == THING_TYPE_SPAWNPOINT_RED_TEAM
+	|| mthingtype == THING_TYPE_SPAWNPOINT_BLUE_TEAM
+	|| mthingtype == THING_TYPE_SPAWNPOINT_TEAM;
 }
 
 static boolean G_AreTeamStartsAvailableForPlayer(INT32 playernum)
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 57170fd202595ce3e57de07178f527d19237da81..2fbb7511a34084a3ff65232ff953c34db6348fe6 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -11937,42 +11937,50 @@ fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mt
 
 static boolean P_SpawnNonMobjMapThing(mapthing_t *mthing)
 {
-#if MAXPLAYERS > 32
+#if ((THING_TYPE_SPAWNPOINT_COOP_END - THING_TYPE_SPAWNPOINT_COOP_START) + 1) > MAXPLAYERS
 	You should think about modifying the deathmatch starts to take full advantage of this!
 #endif
-	if (mthing->type <= MAXPLAYERS) // Player starts
+
+	UINT16 type = mthing->type;
+
+	if (type >= THING_TYPE_SPAWNPOINT_COOP_START && type <= THING_TYPE_SPAWNPOINT_COOP_END) // Player starts
 	{
 		// save spots for respawning in network games
 		if (!metalrecording)
-			G_AddPlayerStart(mthing->type - 1, mthing);
+			G_AddPlayerStart(type - THING_TYPE_SPAWNPOINT_COOP_START, mthing);
 		return true;
 	}
-	else if (mthing->type == 33) // Match starts
+	else if (type == THING_TYPE_SPAWNPOINT_MATCH) // Match starts
 	{
 		G_AddMatchPlayerStart(mthing);
 		return true;
 	}
-	else if (mthing->type == 34) // Red CTF starts
+	else if (type == THING_TYPE_SPAWNPOINT_RED_TEAM) // Red Team starts
 	{
 		G_AddTeamPlayerStart(G_GetTeam(TEAM_RED), mthing);
 		return true;
 	}
-	else if (mthing->type == 35) // Blue CTF starts
+	else if (type == THING_TYPE_SPAWNPOINT_BLUE_TEAM) // Blue Team starts
 	{
 		G_AddTeamPlayerStart(G_GetTeam(TEAM_BLUE), mthing);
 		return true;
 	}
-	else if (metalrecording && mthing->type == mobjinfo[MT_METALSONIC_RACE].doomednum)
+	else if (type == THING_TYPE_SPAWNPOINT_TEAM) // Team starts
+	{
+		G_AddTeamPlayerStart(G_GetTeamByName(mthing->stringargs[0]), mthing);
+		return true;
+	}
+	else if (metalrecording && type == mobjinfo[MT_METALSONIC_RACE].doomednum)
 	{
 		// If recording, you ARE Metal Sonic. Do not spawn it, do not save normal spawnpoints.
 		G_AddPlayerStart(0, mthing);
 		return true;
 	}
-	else if (mthing->type == 750 // Slope vertex point (formerly chaos spawn)
-		     || (mthing->type >= 600 && mthing->type <= 611) // Special placement patterns
-		     || mthing->type == 1713) // Hoops
+	else if (type == 750 // Slope vertex point (formerly chaos spawn)
+		     || (type >= 600 && type <= 611) // Special placement patterns
+		     || type == 1713) // Hoops
 		return true; // These are handled elsewhere.
-	else if (mthing->type == mobjinfo[MT_EMERHUNT].doomednum)
+	else if (type == mobjinfo[MT_EMERHUNT].doomednum)
 	{
 		// Emerald Hunt is Coop only. Don't spawn the emerald yet, but save the spawnpoint for later.
 		if ((gametyperules & GTR_EMERALDHUNT) && numhuntemeralds < MAXHUNTEMERALDS)