diff --git a/extras/conf/udb/Includes/SRB222_linedefs.cfg b/extras/conf/udb/Includes/SRB222_linedefs.cfg
index 76d65e663324f71ee421407bc6068d796b8daebf..2ec7691ab2c8d173b572d2052d093508f002892d 100644
--- a/extras/conf/udb/Includes/SRB222_linedefs.cfg
+++ b/extras/conf/udb/Includes/SRB222_linedefs.cfg
@@ -2550,6 +2550,101 @@ udmf
 			}
 		}
 
+		416
+		{
+			title = "Start Adjustable Flickering Light";
+			prefix = "(416)";
+			arg0
+			{
+				title = "Target sector tag";
+				type = 13;
+			}
+			arg1
+			{
+				title = "Speed";
+			}
+			arg2
+			{
+				title = "Brightness 1";
+			}
+			arg3
+			{
+				title = "Use target brightness?";
+				type = 11;
+				enum = "noyes";
+			}
+			arg4
+			{
+				title = "Brightness 2";
+			}
+		}
+
+		417
+		{
+			title = "Start Adjustable Pulsating Light";
+			prefix = "(417)";
+			arg0
+			{
+				title = "Target sector tag";
+				type = 13;
+			}
+			arg1
+			{
+				title = "Speed";
+			}
+			arg2
+			{
+				title = "Brightness 1";
+			}
+			arg3
+			{
+				title = "Use target brightness?";
+				type = 11;
+				enum = "noyes";
+			}
+			arg4
+			{
+				title = "Brightness 2";
+			}
+		}
+
+		418
+		{
+			title = "Start Adjustable Blinking Light";
+			prefix = "(418)";
+			arg0
+			{
+				title = "Target sector tag";
+				type = 13;
+			}
+			arg1
+			{
+				title = "Brightness 1 tics";
+			}
+			arg2
+			{
+				title = "Brightness 2 tics";
+			}
+			arg3
+			{
+				title = "Brightness 1";
+			}
+			arg4
+			{
+				title = "Flags";
+				type = 12;
+				enum
+				{
+					1 = "Use target brightness";
+					2 = "Synchronized";
+				}
+			}
+			arg5
+			{
+				title = "Brightness 2";
+			}
+		}
+
 		420
 		{
 			title = "Fade Light Level";
@@ -3238,6 +3333,101 @@ udmf
 
 	light
 	{
+		602
+		{
+			title = "Start Adjustable Pulsating Light";
+			prefix = "(602)";
+			arg0
+			{
+				title = "Target sector tag";
+				type = 13;
+			}
+			arg1
+			{
+				title = "Speed";
+			}
+			arg2
+			{
+				title = "Brightness 1";
+			}
+			arg3
+			{
+				title = "Use target brightness?";
+				type = 11;
+				enum = "noyes";
+			}
+			arg4
+			{
+				title = "Brightness 2";
+			}
+		}
+
+		603
+		{
+			title = "Adjustable Flickering Light";
+			prefix = "(603)";
+			arg0
+			{
+				title = "Target sector tag";
+				type = 13;
+			}
+			arg1
+			{
+				title = "Speed";
+			}
+			arg2
+			{
+				title = "Brightness 1";
+			}
+			arg3
+			{
+				title = "Use target brightness?";
+				type = 11;
+				enum = "noyes";
+			}
+			arg4
+			{
+				title = "Brightness 2";
+			}
+		}
+
+		604
+		{
+			title = "Start Adjustable Blinking Light";
+			prefix = "(604)";
+			arg0
+			{
+				title = "Target sector tag";
+				type = 13;
+			}
+			arg1
+			{
+				title = "Brightness 1 tics";
+			}
+			arg2
+			{
+				title = "Brightness 2 tics";
+			}
+			arg3
+			{
+				title = "Brightness 1";
+			}
+			arg4
+			{
+				title = "Flags";
+				type = 12;
+				enum
+				{
+					1 = "Use target brightness";
+					2 = "Synchronized";
+				}
+			}
+			arg5
+			{
+				title = "Brightness 2";
+			}
+		}
+
 		606
 		{
 			title = "Copy Colormap";
diff --git a/src/p_setup.c b/src/p_setup.c
index ffa81f3fb1e5773f739a9e36745bf9267586bb3b..b87df40904b80e567099bd7206d87f3728c9b516 100644
--- a/src/p_setup.c
+++ b/src/p_setup.c
@@ -3696,6 +3696,36 @@ static void P_ConvertBinaryMap(void)
 		case 411: //Stop plane movement
 			lines[i].args[0] = tag;
 			break;
+		case 416: //Start adjustable flickering light
+		case 417: //Start adjustable pulsating light
+		case 602: //Adjustable pulsating light
+		case 603: //Adjustable flickering light
+			lines[i].args[0] = tag;
+			lines[i].args[1] = P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS;
+			lines[i].args[2] = lines[i].frontsector->lightlevel;
+			if ((lines[i].flags & ML_NOCLIMB) && lines[i].backsector)
+				lines[i].args[4] = lines[i].backsector->lightlevel;
+			else
+				lines[i].args[3] = 1;
+			break;
+		case 418: //Start adjustable blinking light (unsynchronized)
+		case 419: //Start adjustable blinking light (synchronized)
+		case 604: //Adjustable blinking light (unsynchronized)
+		case 605: //Adjustable blinking light (synchronized)
+			lines[i].args[0] = tag;
+			lines[i].args[1] = abs(lines[i].dx) >> FRACBITS;
+			lines[i].args[2] = abs(lines[i].dy) >> FRACBITS;
+			lines[i].args[3] = lines[i].frontsector->lightlevel;
+			if ((lines[i].flags & ML_NOCLIMB) && lines[i].backsector)
+				lines[i].args[5] = lines[i].backsector->lightlevel;
+			else
+				lines[i].args[4] |= TMB_USETARGET;
+			if (lines[i].special % 2 == 1)
+			{
+				lines[i].args[4] |= TMB_SYNC;
+				lines[i].special--;
+			}
+			break;
 		case 420: //Fade light level
 			lines[i].args[0] = tag;
 			if (lines[i].flags & ML_DONTPEGBOTTOM)
diff --git a/src/p_spec.c b/src/p_spec.c
index 17aa767eb729d18f2c5b408fb08a7f6af8ed6f0e..2737c4d2445349395eaaec9abe755669ac283c21 100644
--- a/src/p_spec.c
+++ b/src/p_spec.c
@@ -2508,79 +2508,22 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
 			break;
 
 		case 416: // Spawn adjustable fire flicker
-			TAG_ITER_SECTORS(tag, secnum)
-			{
-				if (line->flags & ML_NOCLIMB && line->backsector)
-				{
-					// Use front sector for min light level, back sector for max.
-					P_SpawnAdjustableFireFlicker(&sectors[secnum], line->frontsector->lightlevel, line->backsector->lightlevel,
-						P_AproxDistance(line->dx, line->dy)>>FRACBITS);
-				}
-				else
-				{
-					// Use front sector for min, target sector for max,
-					// the same way linetype 61 does it.
-					P_SpawnAdjustableFireFlicker(&sectors[secnum], line->frontsector->lightlevel, sectors[secnum].lightlevel,
-						P_AproxDistance(line->dx, line->dy)>>FRACBITS);
-				}
-			}
+			TAG_ITER_SECTORS(line->args[0], secnum)
+				P_SpawnAdjustableFireFlicker(&sectors[secnum], line->args[2],
+					line->args[3] ? sectors[secnum].lightlevel : line->args[4], line->args[1]);
 			break;
 
 		case 417: // Spawn adjustable glowing light
-			TAG_ITER_SECTORS(tag, secnum)
-			{
-				if (line->flags & ML_NOCLIMB && line->backsector)
-				{
-					// Use front sector for min light level, back sector for max.
-					P_SpawnAdjustableGlowingLight(&sectors[secnum], line->frontsector->lightlevel, line->backsector->lightlevel,
-						P_AproxDistance(line->dx, line->dy)>>FRACBITS);
-				}
-				else
-				{
-					// Use front sector for min, target sector for max,
-					// the same way linetype 602 does it.
-					P_SpawnAdjustableGlowingLight(&sectors[secnum], line->frontsector->lightlevel, sectors[secnum].lightlevel,
-						P_AproxDistance(line->dx, line->dy)>>FRACBITS);
-				}
-			}
-			break;
-
-		case 418: // Spawn adjustable strobe flash (unsynchronized)
-			TAG_ITER_SECTORS(tag, secnum)
-			{
-				if (line->flags & ML_NOCLIMB && line->backsector)
-				{
-					// Use front sector for min light level, back sector for max.
-					P_SpawnAdjustableStrobeFlash(&sectors[secnum], line->frontsector->lightlevel, line->backsector->lightlevel,
-						abs(line->dx)>>FRACBITS, abs(line->dy)>>FRACBITS, false);
-				}
-				else
-				{
-					// Use front sector for min, target sector for max,
-					// the same way linetype 602 does it.
-					P_SpawnAdjustableStrobeFlash(&sectors[secnum], line->frontsector->lightlevel, sectors[secnum].lightlevel,
-						abs(line->dx)>>FRACBITS, abs(line->dy)>>FRACBITS, false);
-				}
-			}
+			TAG_ITER_SECTORS(line->args[0], secnum)
+				P_SpawnAdjustableGlowingLight(&sectors[secnum], line->args[2],
+					line->args[3] ? sectors[secnum].lightlevel : line->args[4], line->args[1]);
 			break;
 
-		case 419: // Spawn adjustable strobe flash (synchronized)
-			TAG_ITER_SECTORS(tag, secnum)
-			{
-				if (line->flags & ML_NOCLIMB && line->backsector)
-				{
-					// Use front sector for min light level, back sector for max.
-					P_SpawnAdjustableStrobeFlash(&sectors[secnum], line->frontsector->lightlevel, line->backsector->lightlevel,
-						abs(line->dx)>>FRACBITS, abs(line->dy)>>FRACBITS, true);
-				}
-				else
-				{
-					// Use front sector for min, target sector for max,
-					// the same way linetype 602 does it.
-					P_SpawnAdjustableStrobeFlash(&sectors[secnum], line->frontsector->lightlevel, sectors[secnum].lightlevel,
-						abs(line->dx)>>FRACBITS, abs(line->dy)>>FRACBITS, true);
-				}
-			}
+		case 418: // Spawn adjustable strobe flash
+			TAG_ITER_SECTORS(line->args[0], secnum)
+				P_SpawnAdjustableStrobeFlash(&sectors[secnum], line->args[3],
+					(line->args[4] & TMB_USETARGET) ? sectors[secnum].lightlevel : line->args[5],
+					line->args[1], line->args[2], line->args[4] & TMB_SYNC);
 			break;
 
 		case 420: // Fade light levels in tagged sectors to new value
@@ -6899,30 +6842,24 @@ void P_SpawnSpecials(boolean fromnetsave)
 
 			case 602: // Adjustable pulsating light
 				sec = sides[*lines[i].sidenum].sector - sectors;
-				TAG_ITER_SECTORS(tag, s)
-					P_SpawnAdjustableGlowingLight(&sectors[s], sectors[sec].lightlevel, sectors[s].lightlevel,
-						P_AproxDistance(lines[i].dx, lines[i].dy)>>FRACBITS);
+				TAG_ITER_SECTORS(lines[i].args[0], s)
+					P_SpawnAdjustableGlowingLight(&sectors[s], lines[i].args[2],
+						lines[i].args[3] ? sectors[s].lightlevel : lines[i].args[4], lines[i].args[1]);
 				break;
 
 			case 603: // Adjustable flickering light
 				sec = sides[*lines[i].sidenum].sector - sectors;
-				TAG_ITER_SECTORS(tag, s)
-					P_SpawnAdjustableFireFlicker(&sectors[s], sectors[sec].lightlevel, sectors[s].lightlevel,
-						P_AproxDistance(lines[i].dx, lines[i].dy)>>FRACBITS);
-				break;
-
-			case 604: // Adjustable Blinking Light (unsynchronized)
-				sec = sides[*lines[i].sidenum].sector - sectors;
-				TAG_ITER_SECTORS(tag, s)
-					P_SpawnAdjustableStrobeFlash(&sectors[s], sectors[sec].lightlevel, sectors[s].lightlevel,
-						abs(lines[i].dx)>>FRACBITS, abs(lines[i].dy)>>FRACBITS, false);
+				TAG_ITER_SECTORS(lines[i].args[0], s)
+					P_SpawnAdjustableFireFlicker(&sectors[s], lines[i].args[2],
+						lines[i].args[3] ? sectors[s].lightlevel : lines[i].args[4], lines[i].args[1]);
 				break;
 
-			case 605: // Adjustable Blinking Light (synchronized)
+			case 604: // Adjustable Blinking Light
 				sec = sides[*lines[i].sidenum].sector - sectors;
 				TAG_ITER_SECTORS(tag, s)
-					P_SpawnAdjustableStrobeFlash(&sectors[s], sectors[sec].lightlevel, sectors[s].lightlevel,
-						abs(lines[i].dx)>>FRACBITS, abs(lines[i].dy)>>FRACBITS, true);
+					P_SpawnAdjustableStrobeFlash(&sectors[s], lines[i].args[3],
+						(lines[i].args[4] & TMB_USETARGET) ? sectors[s].lightlevel : lines[i].args[5],
+						lines[i].args[1], lines[i].args[2], lines[i].args[4] & TMB_SYNC);
 				break;
 
 			case 606: // HACK! Copy colormaps. Just plain colormaps.
diff --git a/src/p_spec.h b/src/p_spec.h
index 17e10d75bfa241fd43c77b1c005f90a471f281c5..d759b701b8801de79ba0242b68f6c5f4fc59e190 100644
--- a/src/p_spec.h
+++ b/src/p_spec.h
@@ -125,6 +125,12 @@ typedef enum
 	TMF_FORCE    = 1<<1,
 } textmapfadeflags_t;
 
+typedef enum
+{
+	TMB_USETARGET = 1,
+	TMB_SYNC      = 1<<1,
+} textmapblinkinglightflags_t;
+
 typedef enum
 {
 	TMSD_FRONT = 0,