diff --git a/extras/conf/udb/Includes/SRB222_misc.cfg b/extras/conf/udb/Includes/SRB222_misc.cfg
index 3547266cb2b06179b19d970a5459671e106c571b..57c7c88a329073ec1ed1f97b1e0adb41fef38b62 100644
--- a/extras/conf/udb/Includes/SRB222_misc.cfg
+++ b/extras/conf/udb/Includes/SRB222_misc.cfg
@@ -87,10 +87,7 @@ thingflags
 // THING FLAGS
 thingflags_udmf
 {
-	extra = "Extra";
 	flip = "Flip";
-	special = "Special";
-	ambush = "Ambush";
 }
 
 
diff --git a/extras/conf/udb/Includes/SRB222_things.cfg b/extras/conf/udb/Includes/SRB222_things.cfg
index ab1ce5ad5a3bb4648b278a29f1c43867e215eb61..328cf767344d8e2e16ac9e890487711e58ddb3b5 100644
--- a/extras/conf/udb/Includes/SRB222_things.cfg
+++ b/extras/conf/udb/Includes/SRB222_things.cfg
@@ -3985,16 +3985,22 @@ udmf
 				title = "Boss ID";
 			}
 			arg1
+			{
+				title = "End level on death?";
+				type = 11;
+				enum = "noyes";
+			}
+			arg2
 			{
 				title = "Death trigger tag";
 				type = 15;
 			}
-			arg2
+			arg3
 			{
 				title = "Victory trigger tag";
 				type = 15;
 			}
-			arg3
+			arg4
 			{
 				title = "Pinch trigger tag";
 				type = 15;
@@ -4011,20 +4017,32 @@ udmf
 				title = "Boss ID";
 			}
 			arg1
+			{
+				title = "End level on death?";
+				type = 11;
+				enum = "noyes";
+			}
+			arg2
 			{
 				title = "Death trigger tag";
 				type = 15;
 			}
-			arg2
+			arg3
 			{
 				title = "Victory trigger tag";
 				type = 15;
 			}
-			arg3
+			arg4
 			{
 				title = "Pinch trigger tag";
 				type = 15;
 			}
+			arg5
+			{
+				title = "Speed up when hit?";
+				type = 11;
+				enum = "noyes";
+			}
 		}
 		202
 		{
@@ -4037,16 +4055,22 @@ udmf
 				title = "Boss ID";
 			}
 			arg1
+			{
+				title = "End level on death?";
+				type = 11;
+				enum = "noyes";
+			}
+			arg2
 			{
 				title = "Death trigger tag";
 				type = 15;
 			}
-			arg2
+			arg3
 			{
 				title = "Victory trigger tag";
 				type = 15;
 			}
-			arg3
+			arg4
 			{
 				title = "Pinch trigger tag";
 				type = 15;
@@ -4063,21 +4087,27 @@ udmf
 				title = "Boss ID";
 			}
 			arg1
+			{
+				title = "End level on death?";
+				type = 11;
+				enum = "noyes";
+			}
+			arg2
 			{
 				title = "Death trigger tag";
 				type = 15;
 			}
-			arg2
+			arg3
 			{
 				title = "Victory trigger tag";
 				type = 15;
 			}
-			arg3
+			arg4
 			{
 				title = "Pinch trigger tag";
 				type = 15;
 			}
-			arg4
+			arg5
 			{
 				title = "Cage drop trigger tag";
 				type = 15;
@@ -4094,20 +4124,36 @@ udmf
 				title = "Boss ID";
 			}
 			arg1
+			{
+				title = "End level on death?";
+				type = 11;
+				enum = "noyes";
+			}
+			arg2
 			{
 				title = "Death trigger tag";
 				type = 15;
 			}
-			arg2
+			arg3
 			{
 				title = "Victory trigger tag";
 				type = 15;
 			}
-			arg3
+			arg4
 			{
 				title = "Pinch trigger tag";
 				type = 15;
 			}
+			arg5
+			{
+				title = "Flags";
+				type = 12;
+				enum
+				{
+					1 = "Grayscale";
+					2 = "Skip intro";
+				}
+			}
 		}
 		206
 		{
@@ -4120,21 +4166,27 @@ udmf
 				title = "Boss ID";
 			}
 			arg1
+			{
+				title = "End level on death?";
+				type = 11;
+				enum = "noyes";
+			}
+			arg2
 			{
 				title = "Death trigger tag";
 				type = 15;
 			}
-			arg2
+			arg3
 			{
 				title = "Victory trigger tag";
 				type = 15;
 			}
-			arg3
+			arg4
 			{
 				title = "Pinch trigger tag";
 				type = 15;
 			}
-			arg4
+			arg5
 			{
 				title = "Platform trigger tag";
 				type = 15;
@@ -4146,6 +4198,12 @@ udmf
 			sprite = "METLI1";
 			width = 16;
 			height = 48;
+			arg0
+			{
+				title = "Grayscale?";
+				type = 11;
+				enum = "noyes";
+			}
 		}
 		208
 		{
@@ -4158,20 +4216,32 @@ udmf
 				title = "Boss ID";
 			}
 			arg1
+			{
+				title = "End level on death?";
+				type = 11;
+				enum = "noyes";
+			}
+			arg2
 			{
 				title = "Death trigger tag";
 				type = 15;
 			}
-			arg2
+			arg3
 			{
 				title = "Victory trigger tag";
 				type = 15;
 			}
-			arg3
+			arg4
 			{
 				title = "Pinch trigger tag";
 				type = 15;
 			}
+			arg5
+			{
+				title = "Grayscale?";
+				type = 11;
+				enum = "noyes";
+			}
 		}
 		209
 		{
@@ -4184,25 +4254,41 @@ udmf
 				title = "Boss ID";
 			}
 			arg1
+			{
+				title = "End level on death?";
+				type = 11;
+				enum = "noyes";
+			}
+			arg2
 			{
 				title = "Death trigger tag";
 				type = 15;
 			}
-			arg2
+			arg3
 			{
 				title = "Victory trigger tag";
 				type = 15;
 			}
-			arg3
+			arg4
 			{
 				title = "Pinch trigger tag";
 				type = 15;
 			}
-			arg4
+			arg5
 			{
 				title = "Attack trigger tag";
 				type = 15;
 			}
+			arg6
+			{
+				title = "Flags";
+				type = 12;
+				enum
+				{
+					1 = "No origin-fling death";
+					2 = "Electric barrier";
+				}
+			}
 		}
 		290
 		{
@@ -6561,6 +6647,16 @@ udmf
 			{
 				title = "Strength";
 			}
+			arg3
+			{
+				title = "Waving direction";
+				type = 11;
+				enum
+				{
+					0 = "Horizontal";
+					1 = "Vertical";
+				}
+			}
 		}
 		1301
 		{
@@ -6580,6 +6676,16 @@ udmf
 			{
 				title = "Strength";
 			}
+			arg3
+			{
+				title = "Shooting direction";
+				type = 11;
+				enum
+				{
+					0 = "Upwards";
+					1 = "Downwards";
+				}
+			}
 		}
 		1302
 		{
@@ -7714,6 +7820,12 @@ udmf
 			sprite = "ROSYA1";
 			width = 16;
 			height = 48;
+			arg0
+			{
+				title = "Grayscale?";
+				type = 11;
+				enum = "noyes";
+			}
 		}
 		2105
 		{
diff --git a/src/info.c b/src/info.c
index 51f9ea8e643b8f1dc1f41ee0a521f6234644c6c0..c9443700c661e375d3c9914ac8e9043277a30c6e 100644
--- a/src/info.c
+++ b/src/info.c
@@ -1452,7 +1452,7 @@ state_t states[NUMSTATES] =
 	{SPR_FANG, 18, 16, {A_FaceTarget}, 3, 0, S_FANG_PINCHLOBSHOT1}, // S_FANG_PINCHLOBSHOT0
 	{SPR_FANG, 19,  2, {A_FaceTarget}, 3, 0, S_FANG_PINCHLOBSHOT2}, // S_FANG_PINCHLOBSHOT1
 	{SPR_FANG, 20, 30, {A_Boss5MakeItRain}, MT_FBOMB, -16, S_FANG_PINCHLOBSHOT3}, // S_FANG_PINCHLOBSHOT2
-	{SPR_FANG, 20, 18, {A_LinedefExecuteFromArg}, 3, 0, S_FANG_PINCHLOBSHOT4}, // S_FANG_PINCHLOBSHOT3
+	{SPR_FANG, 20, 18, {A_LinedefExecuteFromArg}, 4, 0, S_FANG_PINCHLOBSHOT4}, // S_FANG_PINCHLOBSHOT3
 	{SPR_FANG,  0,  0, {A_Boss5Calm}, 0, 0, S_FANG_PATHINGSTART1}, // S_FANG_PINCHLOBSHOT4
 
 	{SPR_FANG, 21, 0, {A_DoNPCPain},                    0, 0, S_FANG_DIE2}, // S_FANG_DIE1
@@ -1584,7 +1584,7 @@ state_t states[NUMSTATES] =
 
 	{SPR_BRAK, 21, 3*TICRATE, {NULL}, 0, 0, S_BLACKEGG_DESTROYPLAT2}, // S_BLACKEGG_DESTROYPLAT1
 	{SPR_BRAK, 21, 1, {A_PlaySound}, sfx_s3k54, 0, S_BLACKEGG_DESTROYPLAT3}, // S_BLACKEGG_DESTROYPLAT2
-	{SPR_BRAK, 21, 14, {A_LinedefExecuteFromArg}, 4, 0, S_BLACKEGG_STND}, // S_BLACKEGG_DESTROYPLAT3
+	{SPR_BRAK, 21, 14, {A_LinedefExecuteFromArg}, 5, 0, S_BLACKEGG_STND}, // S_BLACKEGG_DESTROYPLAT3
 
 	{SPR_NULL, 0, 1, {A_CapeChase}, (160 - 20) << 16, 0, S_BLACKEGG_HELPER}, // S_BLACKEGG_HELPER
 
@@ -1618,7 +1618,7 @@ state_t states[NUMSTATES] =
 	{SPR_BRAK, 26 + FF_FULLBRIGHT, 2, {A_BrakFireShot}, MT_CYBRAKDEMON_FLAMESHOT, 128, S_CYBRAKDEMON_FLAME_ATTACK4}, // S_CYBRAKDEMON_FLAME_ATTACK3 // Fire
 	{SPR_BRAK, 7, 1, {A_Repeat}, 30, S_CYBRAKDEMON_FLAME_ATTACK3, S_CYBRAKDEMON_FINISH_ATTACK1}, // S_CYBRAKDEMON_FLAME_ATTACK4 // Loop
 	{SPR_BRAK, 0, 6, {A_RandomState}, S_CYBRAKDEMON_VILE_ATTACK1, S_CYBRAKDEMON_NAPALM_ATTACK1, S_CYBRAKDEMON_MISSILE_ATTACK1}, // S_CYBRAKDEMON_CHOOSE_ATTACK2
-	{SPR_BRAK, 20, 0, {A_LinedefExecuteFromArg}, 4, 0, S_CYBRAKDEMON_VILE_ATTACK2}, // S_CYBRAKDEMON_VILE_ATTACK1
+	{SPR_BRAK, 20, 0, {A_LinedefExecuteFromArg}, 5, 0, S_CYBRAKDEMON_VILE_ATTACK2}, // S_CYBRAKDEMON_VILE_ATTACK1
 	{SPR_BRAK, 20, 24, {A_VileTarget}, MT_CYBRAKDEMON_TARGET_RETICULE, 1, S_CYBRAKDEMON_VILE_ATTACK3}, // S_CYBRAKDEMON_VILE_ATTACK2
 	{SPR_BRAK, 19, 8, {A_FaceTarget}, 0, 0, S_CYBRAKDEMON_VILE_ATTACK4}, // S_CYBRAKDEMON_VILE_ATTACK3
 	{SPR_BRAK, 18, 8, {A_FaceTarget}, 0, 0, S_CYBRAKDEMON_VILE_ATTACK5}, // S_CYBRAKDEMON_VILE_ATTACK4
@@ -1631,7 +1631,7 @@ state_t states[NUMSTATES] =
 	{SPR_BRAK, 0, 0, {A_SetReactionTime}, 0, 0, S_CYBRAKDEMON_WALK1}, // S_CYBRAKDEMON_FINISH_ATTACK2 // If just attacked, remove MF2_FRET w/out going back to spawnstate
 	{SPR_BRAK, 18, 24, {A_Pain}, 0, 0, S_CYBRAKDEMON_PAIN2}, // S_CYBRAKDEMON_PAIN1
 	{SPR_BRAK, 18, 0, {A_CheckHealth}, 3, S_CYBRAKDEMON_PAIN3, S_CYBRAKDEMON_CHOOSE_ATTACK1}, // S_CYBRAKDEMON_PAIN2
-	{SPR_BRAK, 18, 0, {A_LinedefExecuteFromArg}, 3, 0, S_CYBRAKDEMON_CHOOSE_ATTACK1}, // S_CYBRAKDEMON_PAIN3
+	{SPR_BRAK, 18, 0, {A_LinedefExecuteFromArg}, 4, 0, S_CYBRAKDEMON_CHOOSE_ATTACK1}, // S_CYBRAKDEMON_PAIN3
 	{SPR_BRAK, 18, 1, {A_Repeat}, 1, S_CYBRAKDEMON_DIE1, S_CYBRAKDEMON_DIE2}, // S_CYBRAKDEMON_DIE1
 	{SPR_BRAK, 18, 2, {A_BossScream}, 2, 0, S_CYBRAKDEMON_DIE3}, // S_CYBRAKDEMON_DIE2
 	{SPR_BRAK, 18, 0, {A_Repeat}, 52, S_CYBRAKDEMON_DIE2, S_CYBRAKDEMON_DIE4}, // S_CYBRAKDEMON_DIE3
diff --git a/src/p_enemy.c b/src/p_enemy.c
index bbbb9495f3833b3c907449f4e5afa587cb2475ee..f7e8e65651b4304c1eb105557bf1bbf9626cd22f 100644
--- a/src/p_enemy.c
+++ b/src/p_enemy.c
@@ -3912,7 +3912,7 @@ static void P_DoBossVictory(mobj_t *mo)
 
 	// victory!
 	if (mo->spawnpoint)
-		P_LinedefExecute(mo->spawnpoint->args[1], mo, NULL);
+		P_LinedefExecute(mo->spawnpoint->args[3], mo, NULL);
 
 	if (stoppedclock && modeattacking) // if you're just time attacking, skip making the capsule appear since you don't need to step on it anyways.
 		return;
@@ -4025,7 +4025,7 @@ static void P_DoCybrakdemonDeath(mobj_t *mo)
 	mo->z += P_MobjFlip(mo);
 	P_SetObjectMomZ(mo, 12*FRACUNIT, false);
 	S_StartSound(mo, sfx_bgxpld);
-	if (mo->spawnpoint && !(mo->spawnpoint->options & MTF_EXTRA))
+	if (mo->spawnpoint && !(mo->spawnpoint->args[6] & TMB_NODEATHFLING))
 		P_InstaThrust(mo, R_PointToAngle2(0, 0, mo->x, mo->y), 14*FRACUNIT);
 }
 
@@ -4128,7 +4128,7 @@ void A_BossDeath(mobj_t *mo)
 		return;
 
 	if (mo->spawnpoint)
-		P_LinedefExecute(mo->spawnpoint->args[1], mo, NULL);
+		P_LinedefExecute(mo->spawnpoint->args[2], mo, NULL);
 	mo->health = 0;
 
 	// Boss is dead (but not necessarily fleeing...)
@@ -7072,7 +7072,7 @@ void A_Boss1Chase(mobj_t *actor)
 		else
 		{
 			if (actor->spawnpoint)
-				P_LinedefExecute(actor->spawnpoint->args[3], actor, NULL);
+				P_LinedefExecute(actor->spawnpoint->args[4], actor, NULL);
 			P_SetMobjState(actor, actor->info->raisestate);
 		}
 
@@ -7196,7 +7196,7 @@ void A_Boss2Chase(mobj_t *actor)
 	}
 	else
 	{
-		// Only speed up if you have the 'Deaf' flag.
+		// Only speed up if you have the ambush flag.
 		if (actor->flags2 & MF2_AMBUSH)
 			speedvar = actor->health;
 		else
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 09c518fe787afe722463afd03674c03fd8e5450f..3de85fa2ba0b767dbc84cbc7c1025c81e6c6f5c5 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -4348,7 +4348,7 @@ static void P_Boss2Thinker(mobj_t *mobj)
 		mobj->flags &= ~MF_NOGRAVITY;
 		A_Boss2Pogo(mobj);
 		if (mobj->spawnpoint)
-			P_LinedefExecute(mobj->spawnpoint->args[3], mobj, NULL);
+			P_LinedefExecute(mobj->spawnpoint->args[4], mobj, NULL);
 	}
 }
 
@@ -4645,7 +4645,7 @@ static boolean P_Boss4MoveCage(mobj_t *mobj, fixed_t delta)
 	if (!mobj->spawnpoint)
 		return false;
 
-	TAG_ITER_SECTORS(mobj->spawnpoint->args[3], snum)
+	TAG_ITER_SECTORS(mobj->spawnpoint->args[4], snum)
 	{
 		sector = &sectors[snum];
 		sector->floorheight += delta;
@@ -4732,7 +4732,7 @@ static void P_Boss4DestroyCage(mobj_t *mobj)
 	if (!mobj->spawnpoint)
 		return;
 
-	TAG_ITER_SECTORS(mobj->spawnpoint->args[3], snum)
+	TAG_ITER_SECTORS(mobj->spawnpoint->args[4], snum)
 	{
 		sector = &sectors[snum];
 
@@ -5006,14 +5006,14 @@ static void P_Boss4Thinker(mobj_t *mobj)
 				P_Boss4DestroyCage(mobj);
 				mobj->movedir = 3;
 				if (mobj->spawnpoint)
-					P_LinedefExecute(mobj->spawnpoint->args[3], mobj, NULL);
+					P_LinedefExecute(mobj->spawnpoint->args[4], mobj, NULL);
 				P_Boss4MoveSpikeballs(mobj, FixedAngle(mobj->movecount), 0);
 				var1 = 3;
 				A_BossJetFume(mobj);
 				return;
 			}
 			if (mobj->spawnpoint)
-				P_LinedefExecute(mobj->spawnpoint->args[4] - (mobj->info->spawnhealth-mobj->health), mobj, NULL);
+				P_LinedefExecute(mobj->spawnpoint->args[5] - (mobj->info->spawnhealth-mobj->health), mobj, NULL);
 			// 1 -> 1.5 second timer
 			mobj->threshold = TICRATE+(TICRATE*(mobj->info->spawnhealth-mobj->health)/10);
 			if (mobj->threshold < 1)
@@ -5046,7 +5046,7 @@ static void P_Boss4Thinker(mobj_t *mobj)
 		P_Boss4DestroyCage(mobj);
 		mobj->movedir = 3;
 		if (mobj->spawnpoint)
-			P_LinedefExecute(mobj->spawnpoint->args[3], mobj, NULL);
+			P_LinedefExecute(mobj->spawnpoint->args[4], mobj, NULL);
 		var1 = 3;
 		A_BossJetFume(mobj);
 		return;
@@ -5187,7 +5187,7 @@ static void P_Boss7Thinker(mobj_t *mobj)
 			mobj->flags2 |= MF2_FRET;
 			P_SetMobjState(mobj, mobj->info->raisestate);
 			if (mobj->spawnpoint)
-				P_LinedefExecute(mobj->spawnpoint->args[3], mobj, NULL);
+				P_LinedefExecute(mobj->spawnpoint->args[4], mobj, NULL);
 		}
 	}
 	else if (mobj->state == &states[S_BLACKEGG_HITFACE4] && mobj->tics == mobj->state->tics)
@@ -6037,7 +6037,7 @@ static void P_Boss9Thinker(mobj_t *mobj)
 					else
 						mobj->watertop = mobj->target->floorz + 16*FRACUNIT;
 					if (mobj->spawnpoint)
-						P_LinedefExecute(mobj->spawnpoint->args[3], mobj, NULL);
+						P_LinedefExecute(mobj->spawnpoint->args[4], mobj, NULL);
 
 #if 0
 					whoosh = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_GHOST); // done here so the offset is correct
@@ -11909,7 +11909,7 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i)
 		runemeraldmanager = true;
 		break;
 	case MT_ROSY:
-		if (!(G_CoopGametype() || (mthing->options & MTF_EXTRA)))
+		if (!(G_CoopGametype() || mthing->args[0]))
 			return false; // she doesn't hang out here
 
 		if (!(netgame || multiplayer) && players[consoleplayer].skin == 3)
@@ -12722,6 +12722,10 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
 			mobj->colorized = true;
 		}
 		break;
+	case MT_EGGMOBILE2:
+		if (mthing->args[5])
+			mobj->flags2 |= MF2_AMBUSH;
+		break;
 	case MT_EGGMOBILE3:
 		mobj->cusval = mthing->args[0];
 		break;
@@ -12748,11 +12752,27 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
 		else
 			mobj->health = FixedMul(mobj->subsector->sector->ceilingheight - mobj->subsector->sector->floorheight, 3*(FRACUNIT/4)) >> FRACBITS;
 		break;
-	case MT_METALSONIC_RACE:
-	case MT_METALSONIC_BATTLE:
 	case MT_FANG:
+		if (mthing->args[5] & TMF_GRAYSCALE)
+		{
+			mobj->color = SKINCOLOR_SILVER;
+			mobj->colorized = true;
+			mobj->flags2 |= MF2_SLIDEPUSH;
+		}
+		if (mthing->args[5] & TMF_SKIPINTRO)
+			mobj->flags2 |= MF2_AMBUSH;
+		break;
+	case MT_METALSONIC_BATTLE:
+		if (mthing->args[5])
+		{
+			mobj->color = SKINCOLOR_SILVER;
+			mobj->colorized = true;
+			mobj->flags2 |= MF2_SLIDEPUSH;
+		}
+		break;
+	case MT_METALSONIC_RACE:
 	case MT_ROSY:
-		if (mthing->options & MTF_EXTRA)
+		if (mthing->args[0])
 		{
 			mobj->color = SKINCOLOR_SILVER;
 			mobj->colorized = true;
@@ -12810,6 +12830,8 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
 		mobj->movecount = mthing->args[0];
 		mobj->threshold = mthing->args[1];
 		mobj->movedir = mthing->args[2];
+		if (mthing->args[3])
+			mobj->flags2 |= MF2_AMBUSH;
 		break;
 	case MT_MACEPOINT:
 	case MT_CHAINMACEPOINT:
@@ -12971,7 +12993,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
 		mobj->health = 1 << (tokenbits - 1);
 		break;
 	case MT_CYBRAKDEMON:
-		if (mthing->options & MTF_AMBUSH)
+		if (mthing->args[6] & TMB_BARRIER)
 		{
 			mobj_t* elecmobj;
 			elecmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_CYBRAKDEMON_ELECTRIC_BARRIER);
@@ -13117,7 +13139,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
 
 	if (mobj->flags & MF_BOSS)
 	{
-		if (mthing->options & MTF_OBJECTSPECIAL) // No egg trap for this boss
+		if (mthing->args[1]) // No egg trap for this boss
 			mobj->flags2 |= MF2_BOSSNOTRAP;
 	}
 	if (mobj->flags & MF_NIGHTSITEM)
@@ -13174,39 +13196,6 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
 	return true;
 }
 
-static void P_SetAmbush(mobj_t *mobj)
-{
-	if (mobj->type != MT_AXIS &&
-		mobj->type != MT_AXISTRANSFER &&
-		mobj->type != MT_AXISTRANSFERLINE &&
-		mobj->type != MT_NIGHTSBUMPER &&
-		mobj->type != MT_NIGHTSDRONE &&
-		mobj->type != MT_BALLOON &&
-		mobj->type != MT_BIGTUMBLEWEED &&
-		mobj->type != MT_LITTLETUMBLEWEED &&
-		mobj->type != MT_BUBBLES &&
-		mobj->type != MT_FAN &&
-		mobj->type != MT_ROBOHOOD &&
-		mobj->type != MT_CRUSHSTACEAN &&
-		mobj->type != MT_BANPYURA &&
-		mobj->type != MT_GOLDBUZZ &&
-		mobj->type != MT_REDBUZZ &&
-		mobj->type != MT_JETTBOMBER &&
-		mobj->type != MT_JETTGUNNER &&
-		mobj->type != MT_BUMBLEBORE &&
-		mobj->type != MT_CACOLANTERN &&
-		mobj->type != MT_PIAN &&
-		mobj->type != MT_EGGGUARD &&
-		mobj->type != MT_STEAM &&
-		mobj->type != MT_SALOONDOORCENTER &&
-		mobj->type != MT_MINECARTSWITCHPOINT &&
-		mobj->type != MT_ROLLOUTSPAWN &&
-		mobj->type != MT_STARPOST &&
-		!((mobj->flags & MF_SPRING) && mobj->info->painchance == 3) &&
-		!((mobj->flags & MF_MONITOR) && mobj->info->speed != 0))
-		mobj->flags2 |= MF2_AMBUSH;
-}
-
 static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y, fixed_t z, mobjtype_t i)
 {
 	mobj_t *mobj = NULL;
@@ -13229,13 +13218,6 @@ static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y,
 
 	mthing->mobj = mobj;
 
-	// ignore MTF_ flags and return early
-	if (i == MT_NIGHTSBUMPER)
-		return mobj;
-
-	if (mthing->options & MTF_AMBUSH)
-		P_SetAmbush(mobj);
-
 	// Generic reverse gravity for individual objects flag.
 	if (mthing->options & MTF_OBJECTFLIP)
 	{
diff --git a/src/p_setup.c b/src/p_setup.c
index 0f92347677d38617573612d5354ef5649b9d8f17..1a063bc2c817509c28f95de89b0dd0663c3a53f7 100644
--- a/src/p_setup.c
+++ b/src/p_setup.c
@@ -1791,14 +1791,8 @@ static void ParseTextmapThingParameter(UINT32 i, char *param, char *val)
 	else if (fastcmp(param, "scale") || fastcmp(param, "scalex") || fastcmp(param, "scaley"))
 		mapthings[i].scale = FLOAT_TO_FIXED(atof(val));
 	// Flags
-	else if (fastcmp(param, "extra") && fastcmp("true", val))
-		mapthings[i].options |= MTF_EXTRA;
 	else if (fastcmp(param, "flip") && fastcmp("true", val))
 		mapthings[i].options |= MTF_OBJECTFLIP;
-	else if (fastcmp(param, "objectspecial") && fastcmp("true", val))
-		mapthings[i].options |= MTF_OBJECTSPECIAL;
-	else if (fastcmp(param, "ambush") && fastcmp("true", val))
-		mapthings[i].options |= MTF_AMBUSH;
 
 	else if (fastncmp(param, "stringarg", 9) && strlen(param) > 9)
 	{
@@ -4892,9 +4886,10 @@ static void P_ConvertBinaryMap(void)
 			{
 				INT32 paramoffset = mapthings[i].extrainfo*LE_PARAMWIDTH;
 				mapthings[i].args[0] = mapthings[i].extrainfo;
-				mapthings[i].args[1] = LE_BOSSDEAD + paramoffset;
-				mapthings[i].args[2] = LE_ALLBOSSESDEAD + paramoffset;
-				mapthings[i].args[3] = LE_PINCHPHASE + paramoffset;
+				mapthings[i].args[1] = !!(mapthings[i].options & MTF_OBJECTSPECIAL);
+				mapthings[i].args[2] = LE_BOSSDEAD + paramoffset;
+				mapthings[i].args[3] = LE_ALLBOSSESDEAD + paramoffset;
+				mapthings[i].args[4] = LE_PINCHPHASE + paramoffset;
 			}
 			if (mobjinfo[mobjtype].flags & MF_NIGHTSITEM)
 			{
@@ -4994,17 +4989,35 @@ static void P_ConvertBinaryMap(void)
 		case 136: //Pyre Fly
 			mapthings[i].args[0] = !!(mapthings[i].options & MTF_AMBUSH);
 			break;
+		case 202: //Egg Slimer
+			mapthings[i].args[5] = !!(mapthings[i].options & MTF_AMBUSH);
+			break;
 		case 203: //Egg Colosseum
-			mapthings[i].args[4] = LE_BOSS4DROP + mapthings[i].extrainfo * LE_PARAMWIDTH;
+			mapthings[i].args[5] = LE_BOSS4DROP + mapthings[i].extrainfo * LE_PARAMWIDTH;
 			break;
 		case 204: //Fang
-			mapthings[i].args[3] = LE_BOSS4DROP + mapthings[i].extrainfo*LE_PARAMWIDTH;
+			mapthings[i].args[4] = LE_BOSS4DROP + mapthings[i].extrainfo*LE_PARAMWIDTH;
+			if (mapthings[i].options & MTF_EXTRA)
+				mapthings[i].args[5] |= TMF_GRAYSCALE;
+			if (mapthings[i].options & MTF_AMBUSH)
+				mapthings[i].args[5] |= TMF_SKIPINTRO;
 			break;
 		case 206: //Brak Eggman (Old)
-			mapthings[i].args[4] = LE_BRAKPLATFORM + mapthings[i].extrainfo*LE_PARAMWIDTH;
+			mapthings[i].args[5] = LE_BRAKPLATFORM + mapthings[i].extrainfo*LE_PARAMWIDTH;
+			break;
+		case 207: //Metal Sonic (Race)
+		case 2104: //Amy Cameo
+			mapthings[i].args[0] = !!(mapthings[i].options & MTF_EXTRA);
+			break;
+		case 208: //Metal Sonic (Battle)
+			mapthings[i].args[5] = !!(mapthings[i].options & MTF_EXTRA);
 			break;
 		case 209: //Brak Eggman
-			mapthings[i].args[4] = LE_BRAKVILEATACK + mapthings[i].extrainfo*LE_PARAMWIDTH;
+			mapthings[i].args[5] = LE_BRAKVILEATACK + mapthings[i].extrainfo*LE_PARAMWIDTH;
+			if (mapthings[i].options & MTF_EXTRA)
+				mapthings[i].args[6] |= TMB_NODEATHFLING;
+			if (mapthings[i].options & MTF_AMBUSH)
+				mapthings[i].args[6] |= TMB_BARRIER;
 			break;
 		case 292: //Boss waypoint
 			mapthings[i].args[0] = mapthings[i].angle;
@@ -5336,6 +5349,7 @@ static void P_ConvertBinaryMap(void)
 			mapthings[i].args[0] = (mapthings[i].angle >> 13)*TICRATE/2;
 			mapthings[i].args[1] = ((mapthings[i].angle >> 10) & 7)*TICRATE/2;
 			mapthings[i].args[2] = 80 - 5*mapthings[i].extrainfo;
+			mapthings[i].args[3] = !!(mapthings[i].options & MTF_AMBUSH);
 			break;
 		case 1304: //Lavafall
 			mapthings[i].args[0] = mapthings[i].angle;
diff --git a/src/p_spec.h b/src/p_spec.h
index 994db8cf462cfca9921d52d7ed1df4a2654476ea..f77af5a0d88605482eb27adf27b5e23b15e31b94 100644
--- a/src/p_spec.h
+++ b/src/p_spec.h
@@ -110,6 +110,18 @@ typedef enum
 	TMMR_STRONG = 2,
 } textmapmonitorrespawn_t;
 
+typedef enum
+{
+	TMF_GRAYSCALE = 1,
+	TMF_SKIPINTRO = 1<<1,
+} textmapfangflags_t;
+
+typedef enum
+{
+	TMB_NODEATHFLING = 1,
+	TMB_BARRIER      = 1<<1,
+} textmapbrakflags_t;
+
 //FOF flags
 typedef enum
 {