diff --git a/extras/conf/udb/Includes/SRB222_linedefs.cfg b/extras/conf/udb/Includes/SRB222_linedefs.cfg
index 08a31297ab6f1ac4540746eb116d3d60e2461da0..25f53ca9b5fbf871bdf6412810c52360634bbfe5 100644
--- a/extras/conf/udb/Includes/SRB222_linedefs.cfg
+++ b/extras/conf/udb/Includes/SRB222_linedefs.cfg
@@ -2462,6 +2462,21 @@ udmf
 				enum = "floorceiling";
 			}
 		}
+
+		435
+		{
+			title = "Change Plane Scroller Direction";
+			prefix = "(435)";
+			arg0
+			{
+				title = "Target sector tag";
+				type = 13;
+			}
+			arg1
+			{
+				title = "Speed";
+			}
+		}
 	}
 
 	linedefexecplane
diff --git a/src/p_setup.c b/src/p_setup.c
index 1dd172f1aa92f3a4a976ad2046377423ed2e8d8a..ca122fa62440570aa740eea60fdf3b357c7bda77 100644
--- a/src/p_setup.c
+++ b/src/p_setup.c
@@ -3611,6 +3611,10 @@ static void P_ConvertBinaryMap(void)
 			}
 			lines[i].special = 429;
 			break;
+		case 435: //Change plane scroller direction
+			lines[i].args[0] = tag;
+			lines[i].args[1] = R_PointToDist2(lines[i].v2->x, lines[i].v2->y, lines[i].v1->x, lines[i].v1->y) >> FRACBITS;
+			break;
 		case 443: //Call Lua function
 			if (lines[i].text)
 			{
diff --git a/src/p_spec.c b/src/p_spec.c
index a9262782f86e1d2260b8b28cd1b361f286e3ba67..59353e835a10614ce44b5c85973e58c2cd75d4c1 100644
--- a/src/p_spec.c
+++ b/src/p_spec.c
@@ -2945,17 +2945,22 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
 				scroll_t *scroller;
 				thinker_t *th;
 
+				fixed_t length = R_PointToDist2(line->v2->x, line->v2->y, line->v1->x, line->v1->y);
+				fixed_t speed = line->args[1] << FRACBITS;
+				fixed_t dx = FixedMul(FixedMul(FixedDiv(line->dx, length), speed) >> SCROLL_SHIFT, CARRYFACTOR);
+				fixed_t dy = FixedMul(FixedMul(FixedDiv(line->dy, length), speed) >> SCROLL_SHIFT, CARRYFACTOR);
+
 				for (th = thlist[THINK_MAIN].next; th != &thlist[THINK_MAIN]; th = th->next)
 				{
 					if (th->function.acp1 != (actionf_p1)T_Scroll)
 						continue;
 
 					scroller = (scroll_t *)th;
-					if (!Tag_Find(&sectors[scroller->affectee].tags, tag))
+					if (!Tag_Find(&sectors[scroller->affectee].tags, line->args[0]))
 						continue;
 
-					scroller->dx = FixedMul(line->dx>>SCROLL_SHIFT, CARRYFACTOR);
-					scroller->dy = FixedMul(line->dy>>SCROLL_SHIFT, CARRYFACTOR);
+					scroller->dx = dx;
+					scroller->dy = dy;
 				}
 			}
 			break;