diff --git a/src/config.h.in b/src/config.h.in
index 1b67b1f75f9a30cb3331dae95b992865bd1fbf32..fc32aef823e27f61abf1e22859073112646158ef 100644
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -13,7 +13,6 @@
 
 #define ASSET_HASH_SRB2_PK3   "${SRB2_ASSET_srb2.pk3_HASH}"
 #define ASSET_HASH_PLAYER_DTA "${SRB2_ASSET_player.dta_HASH}"
-#define ASSET_HASH_RINGS_DTA  "${SRB2_ASSET_rings.dta_HASH}"
 #define ASSET_HASH_ZONES_DTA  "${SRB2_ASSET_zones.dta_HASH}"
 #ifdef USE_PATCH_DTA
 #define ASSET_HASH_PATCH_PK3  "${SRB2_ASSET_patch.pk3_HASH}"
@@ -33,7 +32,6 @@
 #define ASSET_HASH_SRB2_PK3   "c1b9577687f8a795104aef4600720ea7"
 #define ASSET_HASH_ZONES_DTA  "303838c6c534d9540288360fa49cca60"
 #define ASSET_HASH_PLAYER_DTA "cfca0f1c73023cbbd8f844f45480f799"
-#define ASSET_HASH_RINGS_DTA  "85901ad4bf94637e5753d2ac2c03ea26"
 #ifdef USE_PATCH_DTA
 #define ASSET_HASH_PATCH_PK3  "dbbf8bc6121618ee3be2d5b14650429b"
 #endif
diff --git a/src/d_main.c b/src/d_main.c
index c13a712dffd745016888032e45e7d0b8eb76a258..94aa0f2d1bd9c35ccba3dac53173ad07625283a0 100644
--- a/src/d_main.c
+++ b/src/d_main.c
@@ -803,7 +803,7 @@ static void IdentifyVersion(void)
 	const char *srb2waddir = NULL;
 
 #if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)
-	// change to the directory where 'srb2.srb' is found
+	// change to the directory where 'srb2.pk3' is found
 	srb2waddir = I_LocateWad();
 #endif
 
@@ -1124,28 +1124,14 @@ void D_SRB2Main(void)
 	// Make backups of some SOCcable tables.
 	P_BackupTables();
 
-	// Setup default unlockable conditions
-	M_SetupDefaultConditionSets();
-
-	// load wad, including the main wad file
-	CONS_Printf("W_InitMultipleFiles(): Adding IWAD and main PWADs.\n");
-	if (!W_InitMultipleFiles(startupwadfiles))
-#ifdef _DEBUG
-		CONS_Error("A WAD file was not found or not valid.\nCheck the log to see which ones.\n");
-#else
-		I_Error("A WAD file was not found or not valid.\nCheck the log to see which ones.\n");
-#endif
-	D_CleanFile();
-
 	mainwads = 0;
 
 #ifndef DEVELOP // md5s last updated 12/14/14
 
 	// Check MD5s of autoloaded files
-	W_VerifyFileMD5(mainwads++, ASSET_HASH_SRB2_SRB); // srb2.srb/srb2.wad
+	W_VerifyFileMD5(mainwads++, ASSET_HASH_SRB2_PK3); // srb2.pk3
 	W_VerifyFileMD5(mainwads++, ASSET_HASH_ZONES_DTA); // zones.dta
 	W_VerifyFileMD5(mainwads++, ASSET_HASH_PLAYER_DTA); // player.dta
-	W_VerifyFileMD5(mainwads++, ASSET_HASH_RINGS_DTA); // rings.dta
 #ifdef USE_PATCH_DTA
 	W_VerifyFileMD5(mainwads++, ASSET_HASH_PATCH_DTA); // patch.dta
 #endif
@@ -1155,16 +1141,25 @@ void D_SRB2Main(void)
 	//mainwads++; // neither does music_new.dta
 #else
 
-	mainwads++;	// srb2.srb/srb2.wad
+	mainwads++;	// srb2.pk3
 	mainwads++; // zones.dta
 	mainwads++; // player.dta
-	mainwads++; // rings.dta
 #ifdef USE_PATCH_DTA
 	mainwads++; // patch.dta
 #endif
 	//mainwads++; // music.dta does not increment mainwads (see <= 2.1.21)
 	//mainwads++; // neither does music_new.dta
 
+	// load wad, including the main wad file
+	CONS_Printf("W_InitMultipleFiles(): Adding IWAD and main PWADs.\n");
+	if (!W_InitMultipleFiles(startupwadfiles, mainwads))
+#ifdef _DEBUG
+		CONS_Error("A WAD file was not found or not valid.\nCheck the log to see which ones.\n");
+#else
+		I_Error("A WAD file was not found or not valid.\nCheck the log to see which ones.\n");
+#endif
+	D_CleanFile();
+
 #endif //ifndef DEVELOP
 
 	mainwadstally = packetsizetally;
diff --git a/src/dehacked.c b/src/dehacked.c
index badcd45a46816f76918b1216e47e8e8e6601c0ff..69d172fc4e92feb5d19db3dcc0b073fe732d1ff7 100644
--- a/src/dehacked.c
+++ b/src/dehacked.c
@@ -2491,12 +2491,8 @@ static void reademblemdata(MYFILE *f, INT32 num)
 				else
 					emblemlocations[num-1].type = (UINT8)value;
 			}
-			else if (fastcmp(word, "X"))
-				emblemlocations[num-1].x = (INT16)value;
-			else if (fastcmp(word, "Y"))
-				emblemlocations[num-1].y = (INT16)value;
-			else if (fastcmp(word, "Z"))
-				emblemlocations[num-1].z = (INT16)value;
+			else if (fastcmp(word, "TAG"))
+				emblemlocations[num-1].tag = (INT16)value;
 			else if (fastcmp(word, "MAPNUM"))
 			{
 				// Support using the actual map name,
@@ -3455,7 +3451,7 @@ static void ignorelines(MYFILE *f)
 	Z_Free(s);
 }
 
-static void DEH_LoadDehackedFile(MYFILE *f)
+static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
 {
 	char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
 	char *word;
@@ -3515,15 +3511,16 @@ static void DEH_LoadDehackedFile(MYFILE *f)
 				continue;
 			}
 			word2 = strtok(NULL, " ");
+			if (word2) {
+				strupr(word2);
+				if (word2[strlen(word2) - 1] == '\n')
+					word2[strlen(word2) - 1] = '\0';
+				i = atoi(word2);
+			}
+			else
+				i = 0;
 			if (fastcmp(word, "CHARACTER"))
 			{
-				if (word2) {
-					strupr(word2);
-					if (word2[strlen(word2)-1] == '\n')
-						word2[strlen(word2)-1] = '\0';
-					i = atoi(word2);
-				} else
-					i = 0;
 				if (i >= 0 && i < 32)
 					readPlayer(f, i);
 				else
@@ -3533,13 +3530,60 @@ static void DEH_LoadDehackedFile(MYFILE *f)
 				}
 				continue;
 			}
-			if (word2)
+			else if (fastcmp(word, "EMBLEM"))
 			{
-				strupr(word2);
-				if (word2[strlen(word2)-1] == '\n')
-					word2[strlen(word2)-1] = '\0';
-				i = atoi(word2);
+				if (!mainfile && !gamedataadded)
+				{
+					deh_warning("You must define a custom gamedata to use \"%s\"", word);
+					ignorelines(f);
+				}
+				else
+				{
+					if (!word2)
+						i = numemblems + 1;
 
+					if (i > 0 && i <= MAXEMBLEMS)
+					{
+						if (numemblems < i)
+							numemblems = i;
+						reademblemdata(f, i);
+					}
+					else
+					{
+						deh_warning("Emblem number %d out of range (1 - %d)", i, MAXEMBLEMS);
+						ignorelines(f);
+					}
+				}
+				continue;
+			}
+			else if (fastcmp(word, "EXTRAEMBLEM"))
+			{
+				if (!mainfile && !gamedataadded)
+				{
+					deh_warning("You must define a custom gamedata to use \"%s\"", word);
+					ignorelines(f);
+				}
+				else
+				{
+					if (!word2)
+						i = numextraemblems + 1;
+
+					if (i > 0 && i <= MAXEXTRAEMBLEMS)
+					{
+						if (numextraemblems < i)
+							numextraemblems = i;
+						readextraemblemdata(f, i);
+					}
+					else
+					{
+						deh_warning("Extra emblem number %d out of range (1 - %d)", i, MAXEXTRAEMBLEMS);
+						ignorelines(f);
+					}
+				}
+				continue;
+			}
+			if (word2)
+			{
 				if (fastcmp(word, "THING") || fastcmp(word, "MOBJ") || fastcmp(word, "OBJECT"))
 				{
 					if (i == 0 && word2[0] != '0') // If word2 isn't a number
@@ -3662,47 +3706,9 @@ static void DEH_LoadDehackedFile(MYFILE *f)
 						ignorelines(f);
 					}
 				}
-				else if (fastcmp(word, "EMBLEM"))
-				{
-					if (!gamedataadded)
-					{
-						deh_warning("You must define a custom gamedata to use \"%s\"", word);
-						ignorelines(f);
-					}
-					else if (i > 0 && i <= MAXEMBLEMS)
-					{
-						if (numemblems < i)
-							numemblems = i;
-						reademblemdata(f, i);
-					}
-					else
-					{
-						deh_warning("Emblem number %d out of range (1 - %d)", i, MAXEMBLEMS);
-						ignorelines(f);
-					}
-				}
-				else if (fastcmp(word, "EXTRAEMBLEM"))
-				{
-					if (!gamedataadded)
-					{
-						deh_warning("You must define a custom gamedata to use \"%s\"", word);
-						ignorelines(f);
-					}
-					else if (i > 0 && i <= MAXEXTRAEMBLEMS)
-					{
-						if (numextraemblems < i)
-							numextraemblems = i;
-						readextraemblemdata(f, i);
-					}
-					else
-					{
-						deh_warning("Extra emblem number %d out of range (1 - %d)", i, MAXEXTRAEMBLEMS);
-						ignorelines(f);
-					}
-				}
 				else if (fastcmp(word, "UNLOCKABLE"))
 				{
-					if (!gamedataadded)
+					if (!mainfile && !gamedataadded)
 					{
 						deh_warning("You must define a custom gamedata to use \"%s\"", word);
 						ignorelines(f);
@@ -3717,7 +3723,7 @@ static void DEH_LoadDehackedFile(MYFILE *f)
 				}
 				else if (fastcmp(word, "CONDITIONSET"))
 				{
-					if (!gamedataadded)
+					if (!mainfile && !gamedataadded)
 					{
 						deh_warning("You must define a custom gamedata to use \"%s\"", word);
 						ignorelines(f);
@@ -3748,7 +3754,7 @@ static void DEH_LoadDehackedFile(MYFILE *f)
 				{
 					boolean clearall = (fastcmp(word2, "ALL"));
 
-					if (!gamedataadded)
+					if (!mainfile && !gamedataadded)
 					{
 						deh_warning("You must define a custom gamedata to use \"%s\"", word);
 						continue;
@@ -3819,7 +3825,7 @@ static void DEH_LoadDehackedFile(MYFILE *f)
 
 // read dehacked lump in a wad (there is special trick for for deh
 // file that are converted to wad in w_wad.c)
-void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump)
+void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump, boolean mainfile)
 {
 	MYFILE f;
 	f.wad = wad;
@@ -3828,13 +3834,13 @@ void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump)
 	W_ReadLumpPwad(wad, lump, f.data);
 	f.curpos = f.data;
 	f.data[f.size] = 0;
-	DEH_LoadDehackedFile(&f);
+	DEH_LoadDehackedFile(&f, mainfile);
 	Z_Free(f.data);
 }
 
 void DEH_LoadDehackedLump(lumpnum_t lumpnum)
 {
-	DEH_LoadDehackedLumpPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum));
+	DEH_LoadDehackedLumpPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum), false);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/src/dehacked.h b/src/dehacked.h
index 93d39aee262888c4db03595a6e121bb2a07fdcc7..31f7f220dceb37654af225bf8113928922ac78f7 100644
--- a/src/dehacked.h
+++ b/src/dehacked.h
@@ -28,7 +28,7 @@ typedef enum
 } undotype_f;
 
 void DEH_LoadDehackedLump(lumpnum_t lumpnum);
-void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump);
+void DEH_LoadDehackedLumpPwad(UINT16 wad, UINT16 lump, boolean mainfile);
 
 void DEH_Check(void);
 
diff --git a/src/info.c b/src/info.c
index dc36747c78dab9631a172695c1601b683408652c..86e40c38896a303a737720027ee49c91833877e7 100644
--- a/src/info.c
+++ b/src/info.c
@@ -6033,7 +6033,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
 	},
 
 	{           // MT_EMBLEM
-		-1,             // doomednum
+		322,            // doomednum
 		S_EMBLEM1,      // spawnstate
 		1000,           // spawnhealth
 		S_NULL,         // seestate
@@ -6270,7 +6270,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
 	},
 
 	{           // MT_EMERALDSPAWN
-		323,            // doomednum
+		321,            // doomednum
 		S_INVISIBLE,    // spawnstate
 		1000,           // spawnhealth
 		S_NULL,         // seestate
diff --git a/src/m_cond.c b/src/m_cond.c
index b6d571fccb93ae438b8e19fbe656c3c3be487c6c..e03542bf36c00beec606d0d340c10b690effb809 100644
--- a/src/m_cond.c
+++ b/src/m_cond.c
@@ -28,649 +28,18 @@ UINT32 unlocktriggers;
 // The meat of this system lies in condition sets
 conditionset_t conditionSets[MAXCONDITIONSETS];
 
-// Default Emblem locations
-emblem_t emblemlocations[MAXEMBLEMS] =
-{
-	// GREEN FLOWER 1
-	// ---
-	{0,  8156,  6936,   129, 1, 'A', SKINCOLOR_BLUE, 0,
-		"Go get your feet wet\n"
-		"to find this, the first emblem.\n"
-		"Yes, it's very deep.", 0},
-	{0,  3184,  1812,   928, 1, 'B', SKINCOLOR_LAVENDER, 0,
-		"There are many rings,\n"
-		"but this one's not what you think.\n"
-		"There lies the emblem.", 0},
-	{0,  9024,  6716,   769, 1, 'C', SKINCOLOR_RED, 0,
-		"Right next to a lake,\n"
-		"a ledge has been constructed.\n"
-		"Near there is the goal.", 0},
-	{0,  2080,  -384,   512, 1, 'D', SKINCOLOR_ORANGE, 0,
-		"Streams come to an end\n"
-		"where they can no longer fall.\n"
-		"But if you went up...", 0},
-	{0,  -336,  2064,   195, 1, 'E', SKINCOLOR_EMERALD, 0,
-		"This one's in plain sight.\n"
-		"Why haven't you claimed it?\n"
-		"Surely you saw it.", 0},
-
-	{ET_SCORE, 0,0,0,  1, 'S', SKINCOLOR_BROWN,      125000, "", 0},
-	{ET_TIME,  0,0,0,  1, 'T', SKINCOLOR_GREY,   20*TICRATE, "", 0},
-	{ET_RINGS, 0,0,0,  1, 'R', SKINCOLOR_GOLD,          200, "", 0},
-
-
-	// GREEN FLOWER 2
-	// ---
-	{0,  2624, -6816,  1332, 2, 'A', SKINCOLOR_BLUE, 0,
-		"Near the giant lake\n"
-		"lies a cave with a 1-Up.\n"
-		"An emblem's there, too!", 0},
-	{0, -5728, -2848,  2848, 2, 'B', SKINCOLOR_LAVENDER, 0,
-		"Near the final lake,\n"
-		"a higher lake falls on in.\n"
-		"Three platforms await.", 0},
-	{0,  3648,  6464,  2576, 2, 'C', SKINCOLOR_RED, 0,
-		"Near the level's start,\n"
-		"a bridge crosses a river.\n"
-		"What's that river's source?", 0},
-	{0, -2032,-10048,   986, 2, 'D', SKINCOLOR_ORANGE, 0,
-		"Near the level's end,\n"
-		"another bridge spans a lake.\n"
-		"What could be under...?", 0},
-	{0,  -170,   491,  3821, 2, 'E', SKINCOLOR_EMERALD, 0,
-		"An ivied tunnel\n"
-		"has a corner that's sunlit.\n"
-		"Go reach for the sky!", 0},
-
-	{ET_SCORE, 0,0,0,  2, 'S', SKINCOLOR_BROWN,      150000, "", 0},
-	{ET_TIME,  0,0,0,  2, 'T', SKINCOLOR_GREY,   40*TICRATE, "", 0},
-	{ET_RINGS, 0,0,0,  2, 'R', SKINCOLOR_GOLD,          200, "", 0},
-
-
-	// GREEN FLOWER 3
-	// ---
-	{ET_TIME,  0,0,0,  3, 'T', SKINCOLOR_GREY,   30*TICRATE, "", 0},
-
-
-	// TECHNO HILL 1
-	// ---
-	{0, -5664, -5072,  2396, 4, 'A', SKINCOLOR_BLUE, 0,
-		"Three pipes reside near\n"
-		"where our heroes' paths split off.\n"
-		"You'll have to look up!", 0},
-	{0,  -784,-13968,  2888, 4, 'B', SKINCOLOR_LAVENDER, 0,
-		"Climbing yields great range.\n"
-		"Yet, on a path for climbers,\n"
-		"flying is the key.", 0},
-	{0,  4160, -5824,  3776, 4, 'C', SKINCOLOR_RED, 0,
-		"That's sure lots of slime.\n"
-		"Say, do you ever wonder\n"
-		"what's dumping it all?", 0},
-	{0,  6400, -8352,  1764, 4, 'D', SKINCOLOR_ORANGE, 0,
-		"Spinning through small gaps\n"
-		"can slip you into a cave.\n"
-		"In that cave's first stretch...", 0},
-	{0,  2848, -9088,   488, 4, 'E', SKINCOLOR_EMERALD, 0,
-		"The slime lake is deep,\n"
-		"but reaching the floor takes height.\n"
-		"Scream \"Geronimo!\"...", 0},
-
-	{ET_SCORE, 0,0,0,  4, 'S', SKINCOLOR_BROWN,       75000, "", 0},
-	{ET_TIME,  0,0,0,  4, 'T', SKINCOLOR_GREY,   75*TICRATE, "", 0},
-	{ET_RINGS, 0,0,0,  4, 'R', SKINCOLOR_GOLD,          300, "", 0},
-
-
-	// TECHNO HILL 2
-	// ---
-	{0,-19138, -2692,   688, 5, 'A', SKINCOLOR_BLUE, 0,
-		"Near the first checkpoint,\n"
-		"a bridge crosses a slime pool.\n"
-		"(Sensing a pattern?)", 0},
-	{0,-13120,  8062,  1248, 5, 'B', SKINCOLOR_LAVENDER, 0,
-		"Behind the windows,\n"
-		"near crushers, ever smashing\n"
-		"a conveyor belt.", 0},
-	{0,   580,  4552,  1344, 5, 'C', SKINCOLOR_RED, 0,
-		"A pipe drops onto\n"
-		"a half-outdoors conveyor.\n"
-		"But is it empty?", 0},
-	{0,   192, -8768,    24, 5, 'D', SKINCOLOR_ORANGE, 0,
-		"There is a hallway\n"
-		"that a button floods with slime.\n"
-		"Go through it again!", 0},
-	{0, -2468,-12128,  1312, 5, 'E', SKINCOLOR_EMERALD, 0,
-		"Jumping on turtles\n"
-		"will send you springing skyward.\n"
-		"Now, do that six times...", 0},
-
-	{ET_SCORE, 0,0,0,  5, 'S', SKINCOLOR_BROWN,      100000, "", 0},
-	{ET_TIME,  0,0,0,  5, 'T', SKINCOLOR_GREY,  120*TICRATE, "", 0},
-	{ET_RINGS, 0,0,0,  5, 'R', SKINCOLOR_GOLD,          600, "", 0},
-
-
-	// TECHNO HILL 3
-	// ---
-	{ET_TIME,  0,0,0,  6, 'T', SKINCOLOR_GREY,   40*TICRATE, "", 0},
-
-
-	// DEEP SEA 1
-	// ---
-	{0,-16224, -2880,  3530, 7, 'A', SKINCOLOR_BLUE, 0,
-		"Climb up two maze walls.\n"
-		"Break the roof, then a corner.\n"
-		"There, glide, but stay dry.", 0},
-	{0, -8224,   896,  1056, 7, 'B', SKINCOLOR_LAVENDER, 0,
-		"Follow the left path.\n"
-		"A square green button lurks deep.\n"
-		"Weight it down, somehow.", 0},
-	{0,  4992, -5072,  4136, 7, 'C', SKINCOLOR_RED, 0,
-		"A certain path holds\n"
-		"many gargoyle puzzles.\n"
-		"Victors reach a \"V\".", 0},
-	{0,  4576,  5168,  2660, 7, 'D', SKINCOLOR_ORANGE, 0,
-		"A caved-in hallway?\n"
-		"The floor falls; the path goes down.\n"
-		"But those rocks looked weak...", 0},
-	{0, 12576, 16096,  -992, 7, 'E', SKINCOLOR_EMERALD, 0,
-		"The end is quite dry.\n"
-		"Some rocks dam the water in.\n"
-		"Knuckles can fix that...", 0},
-
-	{ET_SCORE, 0,0,0,  7, 'S', SKINCOLOR_BROWN,       75000, "", 0},
-	{ET_TIME,  0,0,0,  7, 'T', SKINCOLOR_GREY,  120*TICRATE, "", 0},
-	{ET_RINGS, 0,0,0,  7, 'R', SKINCOLOR_GOLD,          400, "", 0},
-
-
-	// DEEP SEA 2
-	// ---
-	{0,-15040,  6976,  2016, 8, 'A', SKINCOLOR_BLUE, 0,
-		"A waterfall lands\n"
-		"near a starpost in a cave.\n"
-		"It's dark up there, but...", 0},
-	{0,  4288,  2912,   544, 8, 'B', SKINCOLOR_LAVENDER, 0,
-		"So many blocks here!\n"
-		"Take five; bathe in the fountain.\n"
-		"Hmmm? A hidden path...?", 0},
-	{0, -5696, 16992,   791, 8, 'C', SKINCOLOR_RED, 0,
-		"An ornate dragon\n"
-		"faces a secret passage.\n"
-		"Knuckles! Don't get crushed!", 0},
-	{0,-13344, 18688,  1034, 8, 'D', SKINCOLOR_ORANGE, 0,
-		"In the current maze\n"
-		"hides a dark room of columns.\n"
-		"Find it, then look up.", 0},
-	{0,  3104, 16192,  2408, 8, 'E', SKINCOLOR_EMERALD,  0,
-		"That same dragon's eye\n"
-		"hides another secret room.\n"
-		"There, solve its riddle.", 0},
-
-	{ET_SCORE, 0,0,0,  8, 'S', SKINCOLOR_BROWN,       50000, "", 0},
-	{ET_TIME,  0,0,0,  8, 'T', SKINCOLOR_GREY,  150*TICRATE, "", 0},
-	{ET_RINGS, 0,0,0,  8, 'R', SKINCOLOR_GOLD,          250, "", 0},
-
-
-	// DEEP SEA 3
-	// ---
-	{ET_TIME,  0,0,0,  9, 'T', SKINCOLOR_GREY,   90*TICRATE, "", 0},
-
-
-	// CASTLE EGGMAN 1
-	// ---
-	{0, -6176, -5184,  -128, 10, 'A', SKINCOLOR_BLUE, 0,
-		"A drain feeds the lake.\n"
-		"Water rushes quickly through.\n"
-		"Go against the flow.", 0},
-	{0,  3648,-15296,  -992, 10, 'B', SKINCOLOR_LAVENDER, 0,
-		"The left starting path\n"
-		"goes atop a large wood deck.\n"
-		"Checked underneath yet?", 0},
-	{0, 11712, 21312,  5472, 10, 'C', SKINCOLOR_RED, 0,
-		"At last, the castle!\n"
-		"Hold up! Don't just barge right in!\n"
-		"What's the facade hold...?", 0},
-	{0, 20224, 13344,  3104, 10, 'D', SKINCOLOR_ORANGE, 0,
-		"The final approach!\n"
-		"A tower holds the emblem\n"
-		"near a ring arrow.", 0},
-	{0,  9472, -5890,   710, 10, 'E', SKINCOLOR_EMERALD, 0,
-		"The right starting path\n"
-		"hides this near a canopy,\n"
-		"high, where two trees meet.", 0},
-
-	{ET_SCORE, 0,0,0, 10, 'S', SKINCOLOR_BROWN,       50000, "", 0},
-	{ET_TIME,  0,0,0, 10, 'T', SKINCOLOR_GREY,  120*TICRATE, "", 0},
-	{ET_RINGS, 0,0,0, 10, 'R', SKINCOLOR_GOLD,          200, "", 0},
-
-
-	// CASTLE EGGMAN 2
-	// ---
-	{0,   832,-15168,  7808, 11, 'A', SKINCOLOR_BLUE, 0,
-		"Find a trick bookcase\n"
-		"that hides a darkened hallway.\n"
-		"There, climb a tower.", 0},
-	{0,-18460,-22180,  2416, 11, 'B', SKINCOLOR_LAVENDER, 0,
-		"Down in the dungeon,\n"
-		"a cracked wall hides secret paths.\n"
-		"Echidnas only!", 0},
-	{0, -6144,-11792,  3232, 11, 'C', SKINCOLOR_RED, 0,
-		"A room you can flood!\n"
-		"A brown grate's near its exit.\n"
-		"Knuckles can break it...", 0},
-	{0,  4608, -7024,  4256, 11, 'D', SKINCOLOR_ORANGE, 0,
-		"Some of these bookshelves\n"
-		"are not flush against the walls.\n"
-		"Wonder why that is?", 0},
-	{0, 12708,-13536,  4768, 11, 'E', SKINCOLOR_EMERALD, 0,
-		"The ending's towers\n"
-		"are hiding a small alcove.\n"
-		"Check around outside.", 0},
-
-	{ET_SCORE, 0,0,0, 11, 'S', SKINCOLOR_BROWN,      400000, "", 0},
-	{ET_TIME,  0,0,0, 11, 'T', SKINCOLOR_GREY,  210*TICRATE, "", 0},
-	{ET_RINGS, 0,0,0, 11, 'R', SKINCOLOR_GOLD,          600, "", 0},
-
-
-	// CASTLE EGGMAN 3
-	// ---
-	{ET_TIME,  0,0,0, 12, 'T', SKINCOLOR_GREY,  120*TICRATE, "", 0},
-
-
-	// ARID CANYON 1
-	// ---
-	{0,  3488,  2208,  3072, 13, 'A', SKINCOLOR_BLUE, 0,
-		"A rather large gap\n"
-		"must be crossed by way of tram.\n"
-		"At its end, jump left.", 0},
-	{0, -7552, 10464,  4094, 13, 'B', SKINCOLOR_LAVENDER, 0,
-		"Crushers that go up!\n"
-		"Mind your step; if they're triggered,\n"
-		"they'll block this emblem.", 0},
-	{0,-12093, 14575,  5752, 13, 'C', SKINCOLOR_RED, 0,
-		"There's an oil lake\n"
-		"that you can sink deep into.\n"
-		"Drain it, and explore.", 0},
-	{0,   512, -7136,  4640, 13, 'D', SKINCOLOR_ORANGE, 0,
-		"Not far from the start,\n"
-		"if you climb toward the sky,\n"
-		"the cliffs hide something.", 0},
-	{0, 12504,  6848,  3424, 13, 'E', SKINCOLOR_EMERALD, 0,
-		"Right by the exit,\n"
-		"an emblem lies on a cliff.\n"
-		"Ride ropes to reach it.", 0},
-
-	{ET_SCORE, 0,0,0, 13, 'S', SKINCOLOR_BROWN,       50000, "", 0},
-	{ET_TIME,  0,0,0, 13, 'T', SKINCOLOR_GREY,  120*TICRATE, "", 0},
-	{ET_RINGS, 0,0,0, 13, 'R', SKINCOLOR_GOLD,          300, "", 0},
-
-
-	// RED VOLCANO 1
-	// ---
-	{0,-13184, 11424,  3080, 16, 'A', SKINCOLOR_BLUE, 0,
-		"Look around the room,\n"
-		"just before you clear the stage;\n"
-		"something's hidden there!", 0},
-	{0, -2816,  3120,  3044, 16, 'B', SKINCOLOR_LAVENDER, 0,
-		"Ever look upwards\n"
-		"when you're traversing across\n"
-		"collapsing platforms?", 0},
-	{0,  6720,  6784,  1452, 16, 'C', SKINCOLOR_RED, 0,
-		"Check out a corner\n"
-		"of a lake of magma near\n"
-		"spinning jets of flame.", 0},
-	{0, -5504,  9824,   800, 16, 'D', SKINCOLOR_ORANGE, 0,
-		"Where once a bridge stood,\n"
-		"now magma falls from above.\n"
-		"The bridge dropped something...", 0},
-	{0,  8287,-11043,  1328, 16, 'E', SKINCOLOR_EMERALD, 0,
-		"A lake of magma\n"
-		"ebbs and flows unendingly.\n"
-		"Wait for its nadir.", 0},
-
-	{ET_SCORE, 0,0,0, 16, 'S', SKINCOLOR_BROWN,       30000, "", 0},
-	{ET_TIME,  0,0,0, 16, 'T', SKINCOLOR_GREY,  120*TICRATE, "", 0},
-	{ET_RINGS, 0,0,0, 16, 'R', SKINCOLOR_GOLD,          100, "", 0},
-
-
-	// EGG ROCK 1
-	// ---
-	{0,-10976, -7328,  1584, 22, 'A', SKINCOLOR_BLUE, 0,
-		"Vanishing platforms,\n"
-		"then collapsing ones herald\n"
-		"a last-second jump.", 0},
-	{0, -6592,-11200,  2208, 22, 'B', SKINCOLOR_LAVENDER, 0,
-		"What is this red stuff?\n"
-		"You can't breathe it in, but look!\n"
-		"It can't reach up there...", 0},
-	{0,  6816,   832,   936, 22, 'C', SKINCOLOR_RED, 0,
-		"The team's paths diverge.\n"
-		"Should Tails run the crusher path?\n"
-		"No! Fly outside it!", 0},
-	{0,  6942, -8902,  2080, 22, 'D', SKINCOLOR_ORANGE, 0,
-		"Don't jump too high here!\n"
-		"No conveyor will catch you;\n"
-		"you'd fall to your death.", 0},
-	{0, -6432, -6192,   584, 22, 'E', SKINCOLOR_EMERALD, 0,
-		"Conveyors! Magma!\n"
-		"What an intense room this is!\n"
-		"But, what brought you here?", 0},
-
-	{ET_SCORE, 0,0,0, 22, 'S', SKINCOLOR_BROWN,       25000, "", 0},
-	{ET_TIME,  0,0,0, 22, 'T', SKINCOLOR_GREY,  120*TICRATE, "", 0},
-	{ET_RINGS, 0,0,0, 22, 'R', SKINCOLOR_GOLD,          150, "", 0},
-
-
-	// EGG ROCK 2
-	// ---
-	{0, -6672,  7792,   352, 23, 'A', SKINCOLOR_BLUE, 0,
-		"Walk on the ceiling;\n"
-		"resist the urge to flip back!\n"
-		"Find the cyan path...", 0},
-	{0,-12256, 15136,  -288, 23, 'B', SKINCOLOR_LAVENDER, 0,
-		"X marks the spot? Nope!\n"
-		"Try standing further away\n"
-		"when the timer flips.", 0},
-	{0,  1536, 16224,  1144, 23, 'C', SKINCOLOR_RED, 0,
-		"There is more than one\n"
-		"elevator inside the\n"
-		"elevator shaft...", 0},
-	{0,-15968, 14192,  3152, 23, 'D', SKINCOLOR_ORANGE, 0,
-		"Gears with missing teeth\n"
-		"can hide a clever secret!\n"
-		"Think Green Hill Zone boss.", 0},
-	{0,  1920, 20608,  1064, 23, 'E', SKINCOLOR_EMERALD, 0,
-		"Just before you reach\n"
-		"the defective cargo bay,\n"
-		"fly under a bridge.", 0},
-
-	{ET_SCORE, 0,0,0, 23, 'S', SKINCOLOR_BROWN,       60000, "", 0},
-	{ET_TIME,  0,0,0, 23, 'T', SKINCOLOR_GREY,  300*TICRATE, "", 0},
-	{ET_RINGS, 0,0,0, 23, 'R', SKINCOLOR_GOLD,          250, "", 0},
-
-
-	// EGG ROCK 3
-	// ---
-/* Just in case, I'll leave these here in the source.
-	{0,   848, -3584,   592, 24, 'A', SKINCOLOR_BLUE, 0,
-		"[PH] Hiding at the end of the first hallway.", 0},
-	{0,-10368, -2816,   144, 24, 'B', SKINCOLOR_LAVENDER, 0,
-		"Directions are meaningless.", 0},
-	{0, -8160, -5952,   560, 24, 'C', SKINCOLOR_RED, 0,
-		"[PH] In the ceiling of the conveyor belt + laser hallway.", 0},
-	{0,-13728,-13728,  1552, 24, 'D', SKINCOLOR_ORANGE, 0,
-		"[PH] On top of the platform with rows of spikes in reverse gravity.", 0},
-	{0,-14944,   768,  1232, 24, 'E', SKINCOLOR_EMERALD, 0,
-		"Follow the leader.", 0},
-*/
-
-	{ET_SCORE, 0,0,0, 24, 'S', SKINCOLOR_BROWN,       14000, "", 0},
-	{ET_TIME,  0,0,0, 24, 'T', SKINCOLOR_GREY,  210*TICRATE, "", 0},
-	{ET_RINGS, 0,0,0, 24, 'R', SKINCOLOR_GOLD,          100, "", 0},
-
-
-	// EGG ROCK CORE
-	// ---
-	{ET_TIME,  0,0,0, 25, 'T', SKINCOLOR_GREY,  100*TICRATE, "", 0},
-
-
-	// PIPE TOWERS
-	// ---
-	{0,  3182,  5040,  3008, 30, 'A', SKINCOLOR_BLUE, 0,
-		"A pipe in the roof\n"
-		"eternally drops water.\n"
-		"Something's stuck up there.", 0},
-	{0, -2400,  5984,  2752, 30, 'B', SKINCOLOR_LAVENDER, 0,
-		"Pushing a red switch\n"
-		"raises the water level;\n"
-		"from there, can't miss it.", 0},
-	{0,  6112,  7008,  4032, 30, 'C', SKINCOLOR_RED, 0,
-		"A high-up passage\n"
-		"hides near the second checkpoint.\n"
-		"Climb in; then, climb more.", 0},
-	{0, 11424, -4832,  1376, 30, 'D', SKINCOLOR_ORANGE, 0,
-		"The underground room\n"
-		"with platforms that fall and rise\n"
-		"only LOOKS empty...", 0},
-	{0 , 4960, -6112,  1312, 30, 'E', SKINCOLOR_EMERALD, 0,
-		"This one's straightforward.\n"
-		"What comes to mind when I say:\n"
-		"\"WELCOME TO WARP ZONE!\"?", 0},
-
-	{ET_SCORE, 0,0,0, 30, 'S', SKINCOLOR_BROWN,       75000, "", 0},
-	{ET_TIME,  0,0,0, 30, 'T', SKINCOLOR_GREY,  100*TICRATE, "", 0},
-	{ET_RINGS, 0,0,0, 30, 'R', SKINCOLOR_GOLD,          300, "", 0},
-
-
-	// AERIAL GARDEN
-	// ---
-	{0, 10176,-14304,  1796, 40, 'A', SKINCOLOR_BLUE, 0,
-		"A central tower,\n"
-		"one with many waterfalls,\n"
-		"hides a secret room.", 0},
-	{0,   480, 17696,  6496, 40, 'B', SKINCOLOR_LAVENDER, 0,
-		"Hidden off the path\n"
-		"lies a skyscraping tower.\n"
-		"A lake's at the top.", 0},
-	{0, -8896, 13248,  3362, 40, 'C', SKINCOLOR_RED, 0,
-		"Find all four buttons\n"
-		"that sink when you stand on them.\n"
-		"They'll open a door...", 0},
-	{0, -8896, -9952,  2480, 40, 'D', SKINCOLOR_ORANGE, 0,
-		"Much like the last one,\n"
-		"you need to find some switches.\n"
-		"Only two, this time.", 0},
-	{0, 13184, 18880,  6672, 40, 'E', SKINCOLOR_EMERALD, 0,
-		"The inner sanctum!\n"
-		"Teleport to its switches;\n"
-		"then, check near the goal.", 0},
-
-	{ET_SCORE, 0,0,0, 40, 'S', SKINCOLOR_BROWN,      300000, "", 0},
-	{ET_TIME,  0,0,0, 40, 'T', SKINCOLOR_GREY,  240*TICRATE, "", 0},
-	{ET_RINGS, 0,0,0, 40, 'R', SKINCOLOR_GOLD,         1200, "", 0},
-
-
-	// AZURE TEMPLE
-	// ---
-	{0, -2400,  7552,  1120, 41, 'A', SKINCOLOR_BLUE, 0,
-		"For those who can swim,\n"
-		"a long tunnel hides rewards.\n"
-		"Do mind the Buzzes!", 0},
-	{0,   -64, 14016,  2072, 41, 'B', SKINCOLOR_LAVENDER, 0,
-		"So many skylights!\n"
-		"A markedly large one hides\n"
-		"behind a starpost...", 0},
-	{0,  2976, 13920,   -32, 41, 'C', SKINCOLOR_RED, 0,
-		"When you reach gauntlets\n"
-		"of diagonal fire,\n"
-		"check out the corners.", 0},
-	{0,  2176, 22592,  1376, 41, 'D', SKINCOLOR_ORANGE, 0,
-		"A room of currents;\n"
-		"most of them are marked by spikes.\n"
-		"This one? A corner.", 0},
-	{0, -4128, 21344,  1120, 41, 'E', SKINCOLOR_EMERALD, 0,
-		"The only way to hit\n"
-		"all those gems at once is with\n"
-		"a radial blast.", 0},
-
-	{ET_SCORE, 0,0,0, 41, 'S', SKINCOLOR_BROWN,      425000, "", 0},
-	{ET_TIME,  0,0,0, 41, 'T', SKINCOLOR_GREY,  240*TICRATE, "", 0},
-	{ET_RINGS, 0,0,0, 41, 'R', SKINCOLOR_GOLD,          300, "", 0},
-
-
-	// FLORAL FIELD
-	// ---
-	{0, 5394, -996, 160, 50, 'N', SKINCOLOR_RUST, 0, "", 0},
-	{ET_NGRADE, 0,0,0,   50, 'Q', SKINCOLOR_CYAN,     GRADE_A, "", 0},
-	{ET_NTIME,  0,0,0,   50, 'T', SKINCOLOR_GREY,  40*TICRATE, "", 0},
-
-
-	// TOXIC PLATEAU
-	// ---
-	{0, 780, -1664, 32, 51, 'N', SKINCOLOR_RUST, 0, "", 0},
-	{ET_NGRADE, 0,0,0,  51, 'Q', SKINCOLOR_CYAN,     GRADE_A, "", 0},
-	{ET_NTIME,  0,0,0,  51, 'T', SKINCOLOR_GREY,  50*TICRATE, "", 0},
-
-
-	// FLOODED COVE
-	// ---
-	{0, 1824, -1888, 2448, 52, 'N', SKINCOLOR_RUST, 0, "", 0},
-	{ET_NGRADE, 0,0,0,     52, 'Q', SKINCOLOR_CYAN,     GRADE_A, "", 0},
-	{ET_NTIME,  0,0,0,     52, 'T', SKINCOLOR_GREY,  90*TICRATE, "", 0},
-
-
-	// CAVERN FORTRESS
-	// ---
-	{0, -3089, -431, 1328, 53, 'N', SKINCOLOR_RUST, 0, "", 0},
-	{ET_NGRADE, 0,0,0,     53, 'Q', SKINCOLOR_CYAN,     GRADE_A, "", 0},
-	{ET_NTIME,  0,0,0,     53, 'T', SKINCOLOR_GREY,  75*TICRATE, "", 0},
-
-
-	// DUSTY WASTELAND
-	// ---
-	{0, 957, 924, 2956, 54, 'N', SKINCOLOR_RUST, 0, "", 0},
-	{ET_NGRADE, 0,0,0,  54, 'Q', SKINCOLOR_CYAN,     GRADE_A, "", 0},
-	{ET_NTIME,  0,0,0,  54, 'T', SKINCOLOR_GREY,  65*TICRATE, "", 0},
-
-
-	// MAGMA CAVES
-	// ---
-	{0, -2752, 3104, 1800, 55, 'N', SKINCOLOR_RUST, 0, "", 0},
-	{ET_NGRADE, 0,0,0,     55, 'Q', SKINCOLOR_CYAN,     GRADE_A, "", 0},
-	{ET_NTIME,  0,0,0,     55, 'T', SKINCOLOR_GREY,  80*TICRATE, "", 0},
-
-
-	// EGG SATELLITE
-	// ---
-	{0, 5334, -609, 3426, 56, 'N', SKINCOLOR_RUST, 0, "", 0},
-	{ET_NGRADE, 0,0,0,    56, 'Q', SKINCOLOR_CYAN,     GRADE_A, "", 0},
-	{ET_NTIME,  0,0,0,    56, 'T', SKINCOLOR_GREY, 120*TICRATE, "", 0},
-
-
-	// BLACK HOLE
-	// ---
-	{0, 2108, 3776, 32, 57, 'N', SKINCOLOR_RUST, 0, "", 0},
-	{ET_NGRADE, 0,0,0,  57, 'Q', SKINCOLOR_CYAN,     GRADE_A, "", 0},
-	{ET_NTIME,  0,0,0,  57, 'T', SKINCOLOR_GREY, 150*TICRATE, "", 0},
-
-
-	// SPRING HILL
-	// ---
-	{0, -1840, -1024, 1644, 58, 'N', SKINCOLOR_RUST, 0, "", 0},
-	{ET_NGRADE, 0,0,0,      58, 'Q', SKINCOLOR_CYAN,     GRADE_A, "", 0},
-	{ET_NTIME,  0,0,0,      58, 'T', SKINCOLOR_GREY,  60*TICRATE, "", 0},
-};
-
-// Default Extra Emblems
-extraemblem_t extraemblems[MAXEXTRAEMBLEMS] =
-{
-	{"Game Complete",  "Complete 1P Mode",                    10, 'X', SKINCOLOR_BLUE, 0},
-	{"All Emeralds",   "Complete 1P Mode with all Emeralds",  11, 'V', SKINCOLOR_GREY, 0},
-	{"Perfect Bonus",  "Perfect Bonus on a non-secret stage", 30, 'P', SKINCOLOR_GOLD, 0},
-	{"PLACEHOLDER", "PLACEHOLDER", 0, 'O', SKINCOLOR_RUST, 0},
-	{"NiGHTS Mastery", "Show your mastery of NiGHTS!",        22, 'W', SKINCOLOR_CYAN, 0},
-};
-
-// Default Unlockables
-unlockable_t unlockables[MAXUNLOCKABLES] =
-{
-	// Name, Objective, Menu Height, ConditionSet, Unlock Type, Variable, NoCecho, NoChecklist
-	/* 01 */ {"Record Attack",     "/", 0, 1, SECRET_RECORDATTACK,  0,  true,  true, 0},
-	/* 02 */ {"NiGHTS Mode",       "/",            0, 2, SECRET_NIGHTSMODE,    0,  true,  true, 0},
-
-	/* 03 */ {"Play Credits",      "/", 30, 10, SECRET_CREDITS,   0,  true,  true, 0},
-	/* 04 */ {"Sound Test",        "/", 40, 10, SECRET_SOUNDTEST, 0, false, false, 0},
-
-	/* 05 */ {"EXTRA LEVELS", "/", 58, 0, SECRET_HEADER, 0, true, true, 0},
-
-	/* 06 */ {"Aerial Garden Zone", "/", 70, 11, SECRET_WARP, 40, false, false, 0},
-	/* 07 */ {"Azure Temple Zone",  "/",      80, 20, SECRET_WARP, 41, false, false, 0},
+// Emblem locations
+emblem_t emblemlocations[MAXEMBLEMS];
 
-	/* 08 */ {"BONUS LEVELS", "/", 98, 0, SECRET_HEADER, 0, true, true, 0},
+// Extra emblems
+extraemblem_t extraemblems[MAXEXTRAEMBLEMS];
 
-	/* 09 */ {"PLACEHOLDER", "/", 0, 0, SECRET_NONE, 0, true, true, 0},
-	/* 10 */ {"Mario Koopa Blast", "/",   110, 42, SECRET_WARP,         30, false, false, 0},
-	/* 11 */ {"PLACEHOLDER", "/", 0, 0, SECRET_NONE, 0, true, true, 0},
+// Unlockables
+unlockable_t unlockables[MAXUNLOCKABLES];
 
-	/* 12 */ {"Spring Hill Zone", "/",          0, 44, SECRET_NONE, 0, false, false, 0},
-	/* 13 */ {"Black Hole",       "Get grade A in all Special Stages", 0, 50, SECRET_NONE, 0, false, true, 0},
-
-	/* 14 */ {"Emblem Hints", "/", 0, 41, SECRET_EMBLEMHINTS, 0, false,  true, 0},
-	/* 15 */ {"Emblem Radar", "/", 0, 43, SECRET_ITEMFINDER,  0, false,  true, 0},
-
-	/* 16 */ {"Pandora's Box", "/",  0, 45, SECRET_PANDORA,     0, false, false, 0},
-	/* 17 */ {"Level Select",  "/", 20, 45, SECRET_LEVELSELECT, 1, false,  true, 0},
-};
-
-// Default number of emblems and extra emblems
-INT32 numemblems = 155;
-INT32 numextraemblems = 5;
-
-// DEFAULT CONDITION SETS FOR SRB2 2.1:
-void M_SetupDefaultConditionSets(void)
-{
-	memset(conditionSets, 0, sizeof(conditionSets));
-
-	// --   1: Complete GFZ1
-	M_AddRawCondition(1, 1, UC_MAPBEATEN, 1, 0, 0);
-
-	// --   2: Complete SS1
-	M_AddRawCondition(2, 1, UC_MAPBEATEN, 50, 0, 0);
-
-	// --  10: Complete the game
-	M_AddRawCondition(10, 1, UC_GAMECLEAR, 1, 0, 0);
-
-	// --  11: Complete the game with all emeralds
-	M_AddRawCondition(11, 1, UC_ALLEMERALDS, 1, 0, 0);
-
-	// --  20: Beat AGZ
-	M_AddRawCondition(20, 1, UC_MAPBEATEN, 40, 0, 0);
-
-	// --  22: Beat Black Hole
-	M_AddRawCondition(22, 1, UC_MAPBEATEN, 57, 0, 0);
-
-	// --  30: Perfect Bonus
-	M_AddRawCondition(30, 1,  UC_MAPPERFECT,  1, 0, 0);
-	M_AddRawCondition(30, 2,  UC_MAPPERFECT,  2, 0, 0);
-	M_AddRawCondition(30, 3,  UC_MAPPERFECT,  4, 0, 0);
-	M_AddRawCondition(30, 4,  UC_MAPPERFECT,  5, 0, 0);
-	M_AddRawCondition(30, 5,  UC_MAPPERFECT,  7, 0, 0);
-	M_AddRawCondition(30, 6,  UC_MAPPERFECT,  8, 0, 0);
-	M_AddRawCondition(30, 7,  UC_MAPPERFECT, 10, 0, 0);
-	M_AddRawCondition(30, 8,  UC_MAPPERFECT, 11, 0, 0);
-	M_AddRawCondition(30, 9,  UC_MAPPERFECT, 13, 0, 0);
-	M_AddRawCondition(30, 10, UC_MAPPERFECT, 16, 0, 0);
-	M_AddRawCondition(30, 11, UC_MAPPERFECT, 22, 0, 0);
-	M_AddRawCondition(30, 12, UC_MAPPERFECT, 23, 0, 0);
-	M_AddRawCondition(30, 13, UC_MAPPERFECT, 24, 0, 0);
-	M_AddRawCondition(30, 14, UC_MAPPERFECT, 40, 0, 0);
-	M_AddRawCondition(30, 15, UC_MAPPERFECT, 41, 0, 0);
-
-	// --  40: Find 20 emblems
-	M_AddRawCondition(40, 1, UC_TOTALEMBLEMS, 20, 0, 0);
-
-	// --  41: Find 40 emblems
-	M_AddRawCondition(41, 1, UC_TOTALEMBLEMS, 40, 0, 0);
-
-	// --  42: Find 60 emblems
-	M_AddRawCondition(42, 1, UC_TOTALEMBLEMS, 60, 0, 0);
-
-	// --  43: Find 80 emblems
-	M_AddRawCondition(43, 1, UC_TOTALEMBLEMS, 80, 0, 0);
-
-	// --  44: Find 100 emblems
-	M_AddRawCondition(44, 1, UC_TOTALEMBLEMS, 100, 0, 0);
-
-	// --  45: Find 160 (all) emblems
-	M_AddRawCondition(45, 1, UC_TOTALEMBLEMS, 160, 0, 0);
-
-	// --  50: A rank all NiGHTS special stages
-	M_AddRawCondition(50, 1, UC_NIGHTSGRADE, GRADE_A, 50, 0);
-	M_AddRawCondition(50, 1, UC_NIGHTSGRADE, GRADE_A, 51, 0);
-	M_AddRawCondition(50, 1, UC_NIGHTSGRADE, GRADE_A, 52, 0);
-	M_AddRawCondition(50, 1, UC_NIGHTSGRADE, GRADE_A, 53, 0);
-	M_AddRawCondition(50, 1, UC_NIGHTSGRADE, GRADE_A, 54, 0);
-	M_AddRawCondition(50, 1, UC_NIGHTSGRADE, GRADE_A, 55, 0);
-	M_AddRawCondition(50, 1, UC_NIGHTSGRADE, GRADE_A, 56, 0);
-}
+// Number of emblems and extra emblems
+INT32 numemblems = 0;
+INT32 numextraemblems = 0;
 
 void M_AddRawCondition(UINT8 set, UINT8 id, conditiontype_t c, INT32 r, INT16 x1, INT16 x2)
 {
diff --git a/src/m_cond.h b/src/m_cond.h
index dac98b2841a980d6cecb2f5461137ce0c37bfb22..f82e49372ed0120da76cdd2bd8d8c0a7f2a128c5 100644
--- a/src/m_cond.h
+++ b/src/m_cond.h
@@ -87,9 +87,7 @@ typedef struct
 typedef struct
 {
 	UINT8 type;      ///< Emblem type
-	INT16 x;         ///< X coordinate.
-	INT16 y;         ///< Y coordinate.
-	INT16 z;         ///< Z coordinate.
+	INT16 tag;       ///< Tag of emblem mapthing
 	INT16 level;     ///< Level on which this emblem can be found.
 	UINT8 sprite;    ///< emblem sprite to use, 0 - 25
 	UINT8 color;     ///< skincolor to use
@@ -150,8 +148,7 @@ extern INT32 numextraemblems;
 
 extern UINT32 unlocktriggers;
 
-// Condition Set Setup
-void M_SetupDefaultConditionSets(void);
+// Condition set setup
 void M_AddRawCondition(UINT8 set, UINT8 id, conditiontype_t c, INT32 r, INT16 x1, INT16 x2);
 
 // Clearing secrets
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 044f2942b735a0d3b0555f5503ea52c5ffac5a78..e97471743af1a92e6c3c880b95c4b35d7ebdc8e1 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -35,6 +35,7 @@
 #include "p_slopes.h"
 #endif
 #include "f_finale.h"
+#include "m_cond.h"
 
 static CV_PossibleValue_t CV_BobSpeed[] = {{0, "MIN"}, {4*FRACUNIT, "MAX"}, {0, NULL}};
 consvar_t cv_movebob = {"movebob", "1.0", CV_FLOAT|CV_SAVE, CV_BobSpeed, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -10174,6 +10175,9 @@ You should think about modifying the deathmatch starts to take full advantage of
 	if (i == MT_TOKEN && ((gametype != GT_COOP && gametype != GT_COMPETITION) || ultimatemode || tokenbits == 30 || tokenlist & (1 << tokenbits++)))
 		return; // you already got this token, or there are too many, or the gametype's not right
 
+	if (i == MT_EMBLEM && (netgame || multiplayer || (modifiedgame && !savemoddata))) // No cheating!!
+		return;
+
 	// Objectplace landing point
 	noreturns:
 
@@ -10190,7 +10194,7 @@ You should think about modifying the deathmatch starts to take full advantage of
 			ss->sector->floorheight) + ((mthing->options >> ZSHIFT) << FRACBITS);
 	else if (i == MT_AXIS || i == MT_AXISTRANSFER || i == MT_AXISTRANSFERLINE)
 		z = ONFLOORZ;
-	else if (i == MT_SPIKEBALL || P_WeaponOrPanel(i) || i == MT_EMERALDSPAWN || i == MT_TOKEN)
+	else if (i == MT_SPIKEBALL || P_WeaponOrPanel(i) || i == MT_EMERALDSPAWN || i == MT_TOKEN || i == MT_EMBLEM)
 	{
 		if (mthing->options & MTF_OBJECTFLIP)
 		{
@@ -10292,6 +10296,60 @@ You should think about modifying the deathmatch starts to take full advantage of
 #endif
 	switch(mobj->type)
 	{
+	case MT_EMBLEM:
+	{
+		INT32 i;
+		emblem_t *emblem = M_GetLevelEmblems(gamemap);
+
+		while (emblem)
+		{
+			if ((emblem->type == ET_GLOBAL || emblem->type == ET_SKIN) && emblem->tag == mthing->angle)
+				break;
+
+			emblem = M_GetLevelEmblems(-1);
+		}
+
+		if (!emblem)
+		{
+			CONS_Debug(DBG_GAMELOGIC, "No map emblem for map %d with tag %d found!\n", gamemap, mthing->angle);
+			break;
+		}
+
+		i = emblem - emblemlocations;
+
+		I_Assert(emblemlocations[i].sprite >= 'A' && emblemlocations[i].sprite <= 'Z');
+		P_SetMobjState(mobj, mobj->info->spawnstate + (emblemlocations[i].sprite - 'A'));
+
+		mobj->health = i + 1;
+		mobj->color = (UINT8)M_GetEmblemColor(&emblemlocations[i]);
+
+		if (emblemlocations[i].collected
+			|| (emblemlocations[i].type == ET_SKIN && emblemlocations[i].var != players[0].skin))
+		{
+			P_UnsetThingPosition(mobj);
+			mobj->flags |= MF_NOCLIP;
+			mobj->flags &= ~MF_SPECIAL;
+			mobj->flags |= MF_NOBLOCKMAP;
+			mobj->frame |= (tr_trans50 << FF_TRANSSHIFT);
+			P_SetThingPosition(mobj);
+		}
+		else
+		{
+			mobj->frame &= ~FF_TRANSMASK;
+
+			if (emblemlocations[i].type == ET_GLOBAL)
+			{
+				mobj->reactiontime = emblemlocations[i].var;
+				if (emblemlocations[i].var & GE_NIGHTSITEM)
+				{
+					mobj->flags |= MF_NIGHTSITEM;
+					mobj->flags &= ~MF_SPECIAL;
+					mobj->flags2 |= MF2_DONTDRAW;
+				}
+			}
+		}
+		break;
+	}
 	case MT_SKYBOX:
 		if (mthing->options & MTF_OBJECTSPECIAL)
 			skyboxcenterpnts[mthing->extrainfo] = mobj;
diff --git a/src/p_setup.c b/src/p_setup.c
index 2298f432891735457d736c2031e088af2fe8c5a3..b17199eb16d7b78c3e0b63eabc396e9aa44a550b 100644
--- a/src/p_setup.c
+++ b/src/p_setup.c
@@ -961,10 +961,6 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum)
 }
 #endif
 
-//
-// P_LoadThings
-//
-
 static void P_PrepareRawThings(UINT8 *data, size_t i)
 {
 	mapthing_t *mt;
@@ -1007,7 +1003,7 @@ static void P_PrepareThings(lumpnum_t lumpnum)
 	Z_Free(data);
 }
 
-static void P_LoadThings(void)
+static void P_LoadThings(boolean loademblems)
 {
 	size_t i;
 	mapthing_t *mt;
@@ -1032,6 +1028,9 @@ static void P_LoadThings(void)
 			|| mt->type == 1702) // MT_AXISTRANSFERLINE
 			continue; // These were already spawned
 
+		if (!loademblems && mt->type == mobjinfo[MT_EMBLEM].doomednum)
+			continue;
+
 		mt->mobj = NULL;
 		P_SpawnMapThing(mt);
 	}
@@ -1106,65 +1105,6 @@ static void P_LoadThings(void)
 	}
 }
 
-static inline void P_SpawnEmblems(void)
-{
-	INT32 i, color;
-	mobj_t *emblemmobj;
-
-	for (i = 0; i < numemblems; i++)
-	{
-		if (emblemlocations[i].level != gamemap || emblemlocations[i].type > ET_SKIN)
-			continue;
-
-		emblemmobj = P_SpawnMobj(emblemlocations[i].x<<FRACBITS, emblemlocations[i].y<<FRACBITS,
-			emblemlocations[i].z<<FRACBITS, MT_EMBLEM);
-
-		I_Assert(emblemlocations[i].sprite >= 'A' && emblemlocations[i].sprite <= 'Z');
-		P_SetMobjStateNF(emblemmobj, emblemmobj->info->spawnstate + (emblemlocations[i].sprite - 'A'));
-
-		emblemmobj->health = i+1;
-		color = M_GetEmblemColor(&emblemlocations[i]);
-
-		emblemmobj->color = (UINT8)color;
-
-		if (emblemlocations[i].collected
-			|| (emblemlocations[i].type == ET_SKIN && emblemlocations[i].var != players[0].skin))
-		{
-			P_UnsetThingPosition(emblemmobj);
-			emblemmobj->flags |= MF_NOCLIP;
-			emblemmobj->flags &= ~MF_SPECIAL;
-			emblemmobj->flags |= MF_NOBLOCKMAP;
-			emblemmobj->frame |= (tr_trans50<<FF_TRANSSHIFT);
-			P_SetThingPosition(emblemmobj);
-		}
-		else
-		{
-			emblemmobj->frame &= ~FF_TRANSMASK;
-
-			if (emblemlocations[i].type == ET_GLOBAL)
-			{
-				emblemmobj->reactiontime = emblemlocations[i].var;
-				if (emblemlocations[i].var & GE_NIGHTSITEM)
-				{
-					emblemmobj->flags |= MF_NIGHTSITEM;
-					emblemmobj->flags &= ~MF_SPECIAL;
-					emblemmobj->flags2 |= MF2_DONTDRAW;
-				}
-			}
-		}
-	}
-}
-
-static void P_SpawnSecretItems(boolean loademblems)
-{
-	// Now let's spawn those funky emblem things! Tails 12-08-2002
-	if (netgame || multiplayer || (modifiedgame && !savemoddata)) // No cheating!!
-		return;
-
-	if (loademblems)
-		P_SpawnEmblems();
-}
-
 // Experimental groovy write function!
 void P_WriteThings(lumpnum_t lumpnum)
 {
@@ -2364,13 +2304,11 @@ void P_LoadThingsOnly(void)
 	}
 	else // phew it's just a WAD
 		P_PrepareThings(lastloadedmaplumpnum + ML_THINGS);
-	P_LoadThings();
-
+	P_LoadThings(true);
 
 	// restore skybox viewpoint/centerpoint if necessary, set them to defaults if we can't do that
 	skyboxmo[0] = skyboxviewpnts[(viewid >= 0) ? viewid : 0];
 	skyboxmo[1] = skyboxcenterpnts[(centerid >= 0) ? centerid : 0];
-	P_SpawnSecretItems(true);
 }
 
 /** Compute MD5 message digest for bytes read from memory source
@@ -2959,12 +2897,10 @@ boolean P_SetupLevel(boolean skipprecip)
 	P_ResetDynamicSlopes();
 #endif
 
-	P_LoadThings();
+	P_LoadThings(loademblems);
 	skyboxmo[0] = skyboxviewpnts[0];
 	skyboxmo[1] = skyboxcenterpnts[0];
 
-	P_SpawnSecretItems(loademblems);
-
 	for (numcoopstarts = 0; numcoopstarts < MAXPLAYERS; numcoopstarts++)
 		if (!playerstarts[numcoopstarts])
 			break;
@@ -3359,7 +3295,7 @@ boolean P_AddWadFile(const char *wadfilename)
 //	UINT16 mapPos, mapNum = 0;
 
 	// Init file.
-	if ((numlumps = W_InitFile(wadfilename)) == INT16_MAX)
+	if ((numlumps = W_InitFile(wadfilename, false)) == INT16_MAX)
 	{
 		refreshdirmenu |= REFRESHDIR_NOTLOADED;
 		CONS_Printf(M_GetText("Errors occurred while loading %s; not added.\n"), wadfilename);
diff --git a/src/w_wad.c b/src/w_wad.c
index 4db991c9471c9d27e15f436e1bd3c2e635498767..881320f388e9b708939decddc88422e8818459b7 100644
--- a/src/w_wad.c
+++ b/src/w_wad.c
@@ -195,7 +195,7 @@ FILE *W_OpenWadFile(const char **filename, boolean useerrors)
 }
 
 // Look for all DEHACKED and Lua scripts inside a PK3 archive.
-static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum)
+static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum, boolean mainfile)
 {
 	UINT16 posStart, posEnd;
 	posStart = W_CheckNumForFolderStartPK3("Lua/", wadnum, 0);
@@ -220,14 +220,14 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum)
 			sprintf(name, "%s|%s", wadfiles[wadnum]->filename, lump_p->name2);
 			name[length] = '\0';
 			CONS_Printf(M_GetText("Loading SOC from %s\n"), name);
-			DEH_LoadDehackedLumpPwad(wadnum, posStart);
+			DEH_LoadDehackedLumpPwad(wadnum, posStart, mainfile);
 			free(name);
 		}
 	}
 }
 
 // search for all DEHACKED lump in all wads and load it
-static inline void W_LoadDehackedLumps(UINT16 wadnum)
+static inline void W_LoadDehackedLumps(UINT16 wadnum, boolean mainfile)
 {
 	UINT16 lump;
 
@@ -252,18 +252,18 @@ static inline void W_LoadDehackedLumps(UINT16 wadnum)
 				name[length] = '\0';
 
 				CONS_Printf(M_GetText("Loading SOC from %s\n"), name);
-				DEH_LoadDehackedLumpPwad(wadnum, lump);
+				DEH_LoadDehackedLumpPwad(wadnum, lump, mainfile);
 				free(name);
 			}
 			else if (memcmp(lump_p->name,"MAINCFG",8)==0) // Check for MAINCFG
 			{
 				CONS_Printf(M_GetText("Loading main config from %s\n"), wadfiles[wadnum]->filename);
-				DEH_LoadDehackedLumpPwad(wadnum, lump);
+				DEH_LoadDehackedLumpPwad(wadnum, lump, mainfile);
 			}
 			else if (memcmp(lump_p->name,"OBJCTCFG",8)==0) // Check for OBJCTCFG
 			{
 				CONS_Printf(M_GetText("Loading object config from %s\n"), wadfiles[wadnum]->filename);
-				DEH_LoadDehackedLumpPwad(wadnum, lump);
+				DEH_LoadDehackedLumpPwad(wadnum, lump, mainfile);
 			}
 	}
 
@@ -654,7 +654,7 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
 //
 // Can now load dehacked files (.soc)
 //
-UINT16 W_InitFile(const char *filename)
+UINT16 W_InitFile(const char *filename, boolean mainfile)
 {
 	FILE *handle;
 	lumpinfo_t *lumpinfo = NULL;
@@ -797,14 +797,14 @@ UINT16 W_InitFile(const char *filename)
 	switch (wadfile->type)
 	{
 	case RET_WAD:
-		W_LoadDehackedLumps(numwadfiles - 1);
+		W_LoadDehackedLumps(numwadfiles - 1, mainfile);
 		break;
 	case RET_PK3:
-		W_LoadDehackedLumpsPK3(numwadfiles - 1);
+		W_LoadDehackedLumpsPK3(numwadfiles - 1, mainfile);
 		break;
 	case RET_SOC:
 		CONS_Printf(M_GetText("Loading SOC from %s\n"), wadfile->filename);
-		DEH_LoadDehackedLumpPwad(numwadfiles - 1, 0);
+		DEH_LoadDehackedLumpPwad(numwadfiles - 1, 0, mainfile);
 		break;
 	case RET_LUA:
 		LUA_LoadLump(numwadfiles - 1, 0);
@@ -828,7 +828,7 @@ UINT16 W_InitFile(const char *filename)
   * \return 1 if all files were loaded, 0 if at least one was missing or
   *           invalid.
   */
-INT32 W_InitMultipleFiles(char **filenames)
+INT32 W_InitMultipleFiles(char **filenames, UINT16 mainfiles)
 {
 	INT32 rc = 1;
 
@@ -839,7 +839,7 @@ INT32 W_InitMultipleFiles(char **filenames)
 	for (; *filenames; filenames++)
 	{
 		//CONS_Debug(DBG_SETUP, "Loading %s\n", *filenames);
-		rc &= (W_InitFile(*filenames) != INT16_MAX) ? 1 : 0;
+		rc &= (W_InitFile(*filenames, numwadfiles < mainfiles) != INT16_MAX) ? 1 : 0;
 	}
 
 	if (!numwadfiles)
diff --git a/src/w_wad.h b/src/w_wad.h
index 441bb9a35938ebc787b1ec50962710c4aba691b0..8ffcc1d03ce42f01f67cd6ebbce649f2ffd38b4b 100644
--- a/src/w_wad.h
+++ b/src/w_wad.h
@@ -126,11 +126,11 @@ void W_Shutdown(void);
 // Opens a WAD file. Returns the FILE * handle for the file, or NULL if not found or could not be opened
 FILE *W_OpenWadFile(const char **filename, boolean useerrors);
 // Load and add a wadfile to the active wad files, returns numbers of lumps, INT16_MAX on error
-UINT16 W_InitFile(const char *filename);
+UINT16 W_InitFile(const char *filename, boolean mainfile);
 
 // W_InitMultipleFiles returns 1 if all is okay, 0 otherwise,
 // so that it stops with a message if a file was not found, but not if all is okay.
-INT32 W_InitMultipleFiles(char **filenames);
+INT32 W_InitMultipleFiles(char **filenames, UINT16 mainfiles);
 
 const char *W_CheckNameForNumPwad(UINT16 wad, UINT16 lump);
 const char *W_CheckNameForNum(lumpnum_t lumpnum);