diff --git a/src/p_inter.c b/src/p_inter.c
index f9dc3c34274a3f294ceaae1fb29f29ab30b8956d..e49d89eb4fb92b21601dce92f995b7ca33f73a37 100644
--- a/src/p_inter.c
+++ b/src/p_inter.c
@@ -1648,11 +1648,126 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour
 		CONS_Printf(str, targetname, deadtarget ? M_GetText("killed") : M_GetText("hit"));
 }
 
+/** Checks if the level timer is over the timelimit and the round should end,
+  * unless you are in overtime. In which case leveltime may stretch out beyond
+  * timelimitintics and overtime's status will be checked here each tick.
+  * Verify that the value of ::cv_timelimit is greater than zero before
+  * calling this function.
+  *
+  * \sa cv_timelimit, P_CheckPointLimit, P_UpdateSpecials
+  */
+void P_CheckTimeLimit(void)
+{
+	INT32 i, k;
+
+	if (!cv_timelimit.value)
+		return;
+
+	if (!(multiplayer || netgame))
+		return;
+
+	if (G_PlatformGametype())
+		return;
+
+	if (leveltime < timelimitintics)
+		return;
+
+	if (gameaction == ga_completed)
+		return;
+
+	//Tagmode round end but only on the tic before the
+	//XD_EXITLEVEL packet is recieved by all players.
+	if (G_TagGametype())
+	{
+		if (leveltime == (timelimitintics + 1))
+		{
+			for (i = 0; i < MAXPLAYERS; i++)
+			{
+				if (!playeringame[i] || players[i].spectator
+				 || (players[i].pflags & PF_TAGGED) || (players[i].pflags & PF_TAGIT))
+					continue;
+
+				CONS_Printf(M_GetText("%s recieved double points for surviving the round.\n"), player_names[i]);
+				P_AddPlayerScore(&players[i], players[i].score);
+			}
+		}
+
+		if (server)
+			SendNetXCmd(XD_EXITLEVEL, NULL, 0);
+	}
+
+	//Optional tie-breaker for Match/CTF
+	else if (cv_overtime.value)
+	{
+		INT32 playerarray[MAXPLAYERS];
+		INT32 tempplayer = 0;
+		INT32 spectators = 0;
+		INT32 playercount = 0;
+
+		//Figure out if we have enough participating players to care.
+		for (i = 0; i < MAXPLAYERS; i++)
+		{
+			if (playeringame[i] && players[i].spectator)
+				spectators++;
+		}
+
+		if ((D_NumPlayers() - spectators) > 1)
+		{
+			// Play the starpost sfx after the first second of overtime.
+			if (gamestate == GS_LEVEL && (leveltime == (timelimitintics + TICRATE)))
+				S_StartSound(NULL, sfx_strpst);
+
+			// Normal Match
+			if (!G_GametypeHasTeams())
+			{
+				//Store the nodes of participating players in an array.
+				for (i = 0; i < MAXPLAYERS; i++)
+				{
+					if (playeringame[i] && !players[i].spectator)
+					{
+						playerarray[playercount] = i;
+						playercount++;
+					}
+				}
+
+				//Sort 'em.
+				for (i = 1; i < playercount; i++)
+				{
+					for (k = i; k < playercount; k++)
+					{
+						if (players[playerarray[i-1]].score < players[playerarray[k]].score)
+						{
+							tempplayer = playerarray[i-1];
+							playerarray[i-1] = playerarray[k];
+							playerarray[k] = tempplayer;
+						}
+					}
+				}
+
+				//End the round if the top players aren't tied.
+				if (players[playerarray[0]].score == players[playerarray[1]].score)
+					return;
+			}
+			else
+			{
+				//In team match and CTF, determining a tie is much simpler. =P
+				if (redscore == bluescore)
+					return;
+			}
+		}
+		if (server)
+			SendNetXCmd(XD_EXITLEVEL, NULL, 0);
+	}
+
+	if (server)
+		SendNetXCmd(XD_EXITLEVEL, NULL, 0);
+}
+
 /** Checks if a player's score is over the pointlimit and the round should end.
   * Verify that the value of ::cv_pointlimit is greater than zero before
   * calling this function.
   *
-  * \sa cv_pointlimit, P_UpdateSpecials
+  * \sa cv_pointlimit, P_CheckTimeLimit, P_UpdateSpecials
   */
 void P_CheckPointLimit(void)
 {
diff --git a/src/p_local.h b/src/p_local.h
index 498bf0828bab288b188163ea361bbfaa3356173f..6bd40291288457425d2ba97548e0f9a4da5320a7 100644
--- a/src/p_local.h
+++ b/src/p_local.h
@@ -397,6 +397,7 @@ void P_PlayerEmeraldBurst(player_t *player, boolean toss);
 
 void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck);
 void P_PlayerFlagBurst(player_t *player, boolean toss);
+void P_CheckTimeLimit(void);
 void P_CheckPointLimit(void);
 void P_CheckSurvivors(void);
 boolean P_CheckRacers(void);
diff --git a/src/p_spec.c b/src/p_spec.c
index 0d786c695373f9bfa7de638ba4d1e16ed7958a26..88174c2200add2f134f81eb9ef28e446ea7c8fc1 100644
--- a/src/p_spec.c
+++ b/src/p_spec.c
@@ -4648,114 +4648,19 @@ void P_PlayerInSpecialSector(player_t *player)
 
 /** Animate planes, scroll walls, etc. and keeps track of level timelimit and exits if time is up.
   *
-  * \sa cv_timelimit, P_CheckPointLimit
+  * \sa P_CheckTimeLimit, P_CheckPointLimit
   */
 void P_UpdateSpecials(void)
 {
 	anim_t *anim;
-	INT32 i, k;
+	INT32 i;
 	INT32 pic;
 	size_t j;
 
 	levelflat_t *foundflats; // for flat animation
 
 	// LEVEL TIMER
-	// Exit if the timer is equal to or greater the timelimit, unless you are
-	// in overtime. In which case leveltime may stretch out beyond timelimitintics
-	// and overtime's status will be checked here each tick.
-	if (cv_timelimit.value && timelimitintics <= leveltime && (multiplayer || netgame)
-		&& G_RingSlingerGametype() && (gameaction != ga_completed))
-	{
-		boolean pexit = false;
-
-		//Tagmode round end but only on the tic before the
-		//XD_EXITLEVEL packet is recieved by all players.
-		if (G_TagGametype())
-		{
-			if (leveltime == (timelimitintics + 1))
-			{
-				for (i = 0; i < MAXPLAYERS; i++)
-				{
-					if (!playeringame[i] || players[i].spectator
-					 || (players[i].pflags & PF_TAGGED) || (players[i].pflags & PF_TAGIT))
-						continue;
-
-					CONS_Printf(M_GetText("%s recieved double points for surviving the round.\n"), player_names[i]);
-					P_AddPlayerScore(&players[i], players[i].score);
-				}
-			}
-
-			pexit = true;
-		}
-
-		//Optional tie-breaker for Match/CTF
-		else if (G_RingSlingerGametype() && cv_overtime.value)
-		{
-			INT32 playerarray[MAXPLAYERS];
-			INT32 tempplayer = 0;
-			INT32 spectators = 0;
-			INT32 playercount = 0;
-
-			//Figure out if we have enough participating players to care.
-			for (i = 0; i < MAXPLAYERS; i++)
-			{
-				if (playeringame[i] && players[i].spectator)
-					spectators++;
-			}
-
-			if ((D_NumPlayers() - spectators) > 1)
-			{
-				// Play the starpost sfx after the first second of overtime.
-				if (gamestate == GS_LEVEL && (leveltime == (timelimitintics + TICRATE)))
-					S_StartSound(NULL, sfx_strpst);
-
-				// Normal Match
-				if (!G_GametypeHasTeams())
-				{
-					//Store the nodes of participating players in an array.
-					for (i = 0; i < MAXPLAYERS; i++)
-					{
-						if (playeringame[i] && !players[i].spectator)
-						{
-							playerarray[playercount] = i;
-							playercount++;
-						}
-					}
-
-					//Sort 'em.
-					for (i = 1; i < playercount; i++)
-					{
-						for (k = i; k < playercount; k++)
-						{
-							if (players[playerarray[i-1]].score < players[playerarray[k]].score)
-							{
-								tempplayer = playerarray[i-1];
-								playerarray[i-1] = playerarray[k];
-								playerarray[k] = tempplayer;
-							}
-						}
-					}
-
-					//End the round if the top players aren't tied.
-					if (!(players[playerarray[0]].score == players[playerarray[1]].score))
-						pexit = true;
-				}
-				else
-				{
-					//In team match and CTF, determining a tie is much simpler. =P
-					if (!(redscore == bluescore))
-						pexit = true;
-				}
-			}
-			else
-				pexit = true;
-		}
-		else
-			pexit = true;
-
-		if (server && pexit)
-			SendNetXCmd(XD_EXITLEVEL, NULL, 0);
-	}
+	P_CheckTimeLimit();
 
 	// POINT LIMIT
 	P_CheckPointLimit();