diff --git a/src/d_main.c b/src/d_main.c
index 65b1c8ccc6f9120ddccc398faa70397214767ef0..e55c65bbbf0e5033c86f9f77f3ec35335ebffa1b 100644
--- a/src/d_main.c
+++ b/src/d_main.c
@@ -1169,26 +1169,6 @@ void D_SRB2Main(void)
 	if (M_CheckParm("-server") || dedicated)
 		netgame = server = true;
 
-	if (M_CheckParm("-warp") && M_IsNextParm())
-	{
-		const char *word = M_GetNextParm();
-		char ch; // use this with sscanf to catch non-digits with
-		if (fastncmp(word, "MAP", 3)) // MAPxx name
-			pstartmap = M_MapNumber(word[3], word[4]);
-		else if (sscanf(word, "%d%c", &pstartmap, &ch) != 1) // a plain number
-			I_Error("Cannot warp to map %s (invalid map name)\n", word);
-		// Don't check if lump exists just yet because the wads haven't been loaded!
-		// Just do a basic range check here.
-		if (pstartmap < 1 || pstartmap > NUMMAPS)
-			I_Error("Cannot warp to map %d (out of range)\n", pstartmap);
-		else
-		{
-			if (!M_CheckParm("-server"))
-				G_SetGameModified(true);
-			autostart = true;
-		}
-	}
-
 	CONS_Printf("Z_Init(): Init zone memory allocation daemon. \n");
 	Z_Init();
 
@@ -1245,6 +1225,20 @@ void D_SRB2Main(void)
 
 	mainwadstally = packetsizetally; // technically not accurate atm, remember to port the two-stage -file process from kart in 2.2.x
 
+	if (M_CheckParm("-warp") && M_IsNextParm())
+	{
+		const char *word = M_GetNextParm();
+		pstartmap = G_FindMapByNameOrCode(word, 0);
+		if (! pstartmap)
+			I_Error("Cannot find a map remotely named '%s'\n", word);
+		else
+		{
+			if (!M_CheckParm("-server"))
+				G_SetGameModified(true);
+			autostart = true;
+		}
+	}
+
 	cht_Init();
 
 	//---------------------------------------------------- READY SCREEN
diff --git a/src/d_netcmd.c b/src/d_netcmd.c
index 28843c0d7be6dd09ee3c60531223f97e2b34a139..aa69836f959227211048f166d159d54386e1cc30 100644
--- a/src/d_netcmd.c
+++ b/src/d_netcmd.c
@@ -1804,18 +1804,15 @@ static void Command_Map_f(void)
 	boolean newresetplayers;
 
 	boolean mustmodifygame;
-	boolean usemapcode = false;
 
 	INT32 newmapnum;
 
 	char   *    mapname;
-	size_t      mapnamelen;
 	char   *realmapname = NULL;
 
 	INT32 newgametype = gametype;
 
 	INT32 d;
-	char *p;
 
 	if (client && !IsPlayerAdmin(consoleplayer))
 	{
@@ -1875,43 +1872,8 @@ static void Command_Map_f(void)
 	}
 
 	mapname = ConcatCommandArgv(1, first_option);
-	mapnamelen = strlen(mapname);
-
-	if (mapnamelen == 2)/* maybe two digit code */
-	{
-		if (( newmapnum = M_MapNumber(mapname[0], mapname[1]) ))
-			usemapcode = true;
-	}
-	else if (mapnamelen == 5 && strnicmp(mapname, "MAP", 3) == 0)
-	{
-		if (( newmapnum = M_MapNumber(mapname[3], mapname[4]) ) == 0)
-		{
-			CONS_Alert(CONS_ERROR, M_GetText("Invalid map code '%s'.\n"), mapname);
-			Z_Free(mapname);
-			return;
-		}
-		usemapcode = true;
-	}
 
-	if (!usemapcode)
-	{
-		/* Now detect map number in base 10, which no one asked for. */
-		newmapnum = strtol(mapname, &p, 10);
-		if (*p == '\0')/* we got it */
-		{
-			if (newmapnum < 1 || newmapnum > NUMMAPS)
-			{
-				CONS_Alert(CONS_ERROR, M_GetText("Invalid map number %d.\n"), newmapnum);
-				Z_Free(mapname);
-				return;
-			}
-			usemapcode = true;
-		}
-		else
-		{
-			newmapnum = G_FindMap(mapname, &realmapname, NULL, NULL);
-		}
-	}
+	newmapnum = G_FindMapByNameOrCode(mapname, &realmapname);
 
 	if (newmapnum == 0)
 	{
@@ -1920,11 +1882,6 @@ static void Command_Map_f(void)
 		return;
 	}
 
-	if (usemapcode)
-	{
-		realmapname = G_BuildMapTitle(newmapnum);
-	}
-
 	if (mustmodifygame && option_force)
 	{
 		G_SetGameModified(false);
diff --git a/src/g_game.c b/src/g_game.c
index e4caa3a36aa4c373880985ade533bf1b50def01a..95aa1ae0084d8fc17c50eafc2ee1564965a160fa 100644
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -4536,6 +4536,61 @@ void G_FreeMapSearch(mapsearchfreq_t *freq, INT32 freqc)
 	Z_Free(freq);
 }
 
+INT32 G_FindMapByNameOrCode(const char *mapname, char **realmapnamep)
+{
+	boolean usemapcode = false;
+
+	INT32 newmapnum;
+
+	size_t mapnamelen;
+
+	char *p;
+
+	mapnamelen = strlen(mapname);
+
+	if (mapnamelen == 2)/* maybe two digit code */
+	{
+		if (( newmapnum = M_MapNumber(mapname[0], mapname[1]) ))
+			usemapcode = true;
+	}
+	else if (mapnamelen == 5 && strnicmp(mapname, "MAP", 3) == 0)
+	{
+		if (( newmapnum = M_MapNumber(mapname[3], mapname[4]) ))
+			usemapcode = true;
+	}
+
+	if (!usemapcode)
+	{
+		/* Now detect map number in base 10, which no one asked for. */
+		newmapnum = strtol(mapname, &p, 10);
+		if (*p == '\0')/* we got it */
+		{
+			if (newmapnum < 1 || newmapnum > NUMMAPS)
+			{
+				CONS_Alert(CONS_ERROR, M_GetText("Invalid map number %d.\n"), newmapnum);
+				return 0;
+			}
+			usemapcode = true;
+		}
+		else
+		{
+			newmapnum = G_FindMap(mapname, realmapnamep, NULL, NULL);
+		}
+	}
+
+	if (usemapcode)
+	{
+		/* we can't check mapheaderinfo for this hahahaha */
+		if (W_CheckNumForName(G_BuildMapName(newmapnum)) == LUMPERROR)
+			return 0;
+
+		if (realmapnamep)
+			(*realmapnamep) = G_BuildMapTitle(newmapnum);
+	}
+
+	return newmapnum;
+}
+
 //
 // DEMO RECORDING
 //
diff --git a/src/g_game.h b/src/g_game.h
index c19faebe4721bd4ea2ad25177e350c0f61af300b..5965550712416b2fbaf1a3de994a1d672e75579f 100644
--- a/src/g_game.h
+++ b/src/g_game.h
@@ -130,6 +130,9 @@ INT32 G_FindMap(const char *query, char **foundmapnamep,
 		mapsearchfreq_t **freqp, INT32 *freqc);
 void G_FreeMapSearch(mapsearchfreq_t *freq, INT32 freqc);
 
+/* Match map name by search + 2 digit map code or map number. */
+INT32 G_FindMapByNameOrCode(const char *query, char **foundmapnamep);
+
 // XMOD spawning
 mapthing_t *G_FindCTFStart(INT32 playernum);
 mapthing_t *G_FindMatchStart(INT32 playernum);