diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg
index 9aeada89b6c470c9986347a7ee4e72136604d1aa..ec568e865ed8d657473cd3d7444ae5e818db2ad9 100644
--- a/extras/conf/SRB2-22.cfg
+++ b/extras/conf/SRB2-22.cfg
@@ -3253,6 +3253,7 @@ linedeftypes
 		{
 			title = "Set Tagged Dynamic Slope Vertex to Front Sector Height";
 			prefix = "(799)";
+			flags64text = "[6] Use relative heights";
 		}
 	}
 
diff --git a/extras/conf/udb/Includes/SRB222_linedefs.cfg b/extras/conf/udb/Includes/SRB222_linedefs.cfg
index c2bcfa3b341016916ac491f515026c20ebc35b27..169709de4be1b335dc56246dfa11868089e49ae5 100644
--- a/extras/conf/udb/Includes/SRB222_linedefs.cfg
+++ b/extras/conf/udb/Includes/SRB222_linedefs.cfg
@@ -5233,5 +5233,21 @@ udmf
 				}
 			}
 		}
+
+		799
+		{
+			title = "Set Tagged Dynamic Slope Vertex to Front Sector Height";
+			prefix = "(799)";
+			arg0
+			{
+				title = "Apply height";
+				type = 11;
+				enum
+				{
+					0 = "Absolute";
+					1 = "Relative";
+				}
+			}
+		}
 	}
 }
diff --git a/src/p_saveg.c b/src/p_saveg.c
index ffca42cd36c46e045c9a452b3d4c3d0f36e7649a..5e204f9bc0aacc5aac970192d80d97120e3495b1 100644
--- a/src/p_saveg.c
+++ b/src/p_saveg.c
@@ -2294,12 +2294,17 @@ static inline void SaveDynamicLineSlopeThinker(const thinker_t *th, const UINT8
 
 static inline void SaveDynamicVertexSlopeThinker(const thinker_t *th, const UINT8 type)
 {
+	size_t i;
 	const dynvertexplanethink_t* ht = (const void*)th;
 
 	WRITEUINT8(save_p, type);
 	WRITEUINT32(save_p, SaveSlope(ht->slope));
-	WRITEMEM(save_p, ht->tags, sizeof(ht->tags));
-    WRITEMEM(save_p, ht->vex, sizeof(ht->vex));
+	for (i = 0; i < 3; i++)
+		WRITEUINT32(save_p, SaveSector(ht->secs[i]));
+	WRITEMEM(save_p, ht->vex, sizeof(ht->vex));
+	WRITEMEM(save_p, ht->origsecheights, sizeof(ht->origsecheights));
+	WRITEMEM(save_p, ht->origvecheights, sizeof(ht->origvecheights));
+	WRITEUINT8(save_p, ht->relative);
 }
 
 static inline void SavePolyrotatetThinker(const thinker_t *th, const UINT8 type)
@@ -3468,12 +3473,17 @@ static inline thinker_t* LoadDynamicLineSlopeThinker(actionf_p1 thinker)
 
 static inline thinker_t* LoadDynamicVertexSlopeThinker(actionf_p1 thinker)
 {
+	size_t i;
 	dynvertexplanethink_t* ht = Z_Malloc(sizeof(*ht), PU_LEVSPEC, NULL);
 	ht->thinker.function.acp1 = thinker;
 
 	ht->slope = LoadSlope(READUINT32(save_p));
-	READMEM(save_p, ht->tags, sizeof(ht->tags));
+	for (i = 0; i < 3; i++)
+		ht->secs[i] = LoadSector(READUINT32(save_p));
 	READMEM(save_p, ht->vex, sizeof(ht->vex));
+	READMEM(save_p, ht->origsecheights, sizeof(ht->origsecheights));
+	READMEM(save_p, ht->origvecheights, sizeof(ht->origvecheights));
+	ht->relative = READUINT8(save_p);
 	return &ht->thinker;
 }
 
diff --git a/src/p_setup.c b/src/p_setup.c
index 9fe4446a6cbf1550ea064f6c81ba947e52d7efcd..2f815a2288fb6d8c9edcbf96c86af5e810f6c848 100644
--- a/src/p_setup.c
+++ b/src/p_setup.c
@@ -4885,7 +4885,9 @@ static void P_ConvertBinaryMap(void)
 				lines[i].args[4] |= TMSC_BACKTOFRONTCEILING;
 			lines[i].special = 720;
 			break;
-
+		case 799: //Set dynamic slope vertex to front sector height
+			lines[i].args[0] = !!(lines[i].flags & ML_NOCLIMB);
+			break;
 		case 900: //Translucent wall (10%)
 		case 901: //Translucent wall (20%)
 		case 902: //Translucent wall (30%)
diff --git a/src/p_slopes.c b/src/p_slopes.c
index 415642abfc219cdc9dfafa69f39294770ef2f7a2..b9154b89088f9f7b8523eb605183d79866e95986 100644
--- a/src/p_slopes.c
+++ b/src/p_slopes.c
@@ -163,21 +163,17 @@ void T_DynamicSlopeLine (dynlineplanethink_t* th)
 /// Mapthing-defined
 void T_DynamicSlopeVert (dynvertexplanethink_t* th)
 {
-	pslope_t* slope = th->slope;
-
 	size_t i;
-	INT32 l;
 
-	for (i = 0; i < 3; i++) {
-		l = Tag_FindLineSpecial(799, th->tags[i]);
-		if (l != -1) {
-			th->vex[i].z = lines[l].frontsector->floorheight;
-		}
+	for (i = 0; i < 3; i++)
+	{
+		if (th->relative & (1 << i))
+			th->vex[i].z = th->origvecheights[i] + (th->secs[i]->floorheight - th->origsecheights[i]);
 		else
-			th->vex[i].z = 0;
+			th->vex[i].z = th->secs[i]->floorheight;
 	}
 
-	ReconfigureViaVertexes(slope, th->vex[0], th->vex[1], th->vex[2]);
+	ReconfigureViaVertexes(th->slope, th->vex[0], th->vex[1], th->vex[2]);
 }
 
 static inline void P_AddDynLineSlopeThinker (pslope_t* slope, dynplanetype_t type, line_t* sourceline, fixed_t extent)
@@ -194,10 +190,25 @@ static inline void P_AddDynLineSlopeThinker (pslope_t* slope, dynplanetype_t typ
 static inline void P_AddDynVertexSlopeThinker (pslope_t* slope, const INT16 tags[3], const vector3_t vx[3])
 {
 	dynvertexplanethink_t* th = Z_Calloc(sizeof (*th), PU_LEVSPEC, NULL);
+	size_t i;
+	INT32 l;
 	th->thinker.function.acp1 = (actionf_p1)T_DynamicSlopeVert;
 	th->slope = slope;
-	memcpy(th->tags, tags, sizeof(th->tags));
-	memcpy(th->vex, vx, sizeof(th->vex));
+
+	for (i = 0; i < 3; i++) {
+		l = Tag_FindLineSpecial(799, tags[i]);
+		if (l == -1)
+		{
+			Z_Free(th);
+			return;
+		}
+		th->secs[i] = lines[l].frontsector;
+		th->vex[i] = vx[i];
+		th->origsecheights[i] = lines[l].frontsector->floorheight;
+		th->origvecheights[i] = vx[i].z;
+		if (lines[l].args[0])
+			th->relative |= 1<<i;
+	}
 	P_AddThinker(THINK_DYNSLOPE, &th->thinker);
 }
 
diff --git a/src/p_slopes.h b/src/p_slopes.h
index 45588d4639098a2af81801a549d5547809a88b2c..0b3e0b5173ba79bb87e1d5e6b7e5ad82a14fe306 100644
--- a/src/p_slopes.h
+++ b/src/p_slopes.h
@@ -111,8 +111,11 @@ typedef struct
 {
 	thinker_t thinker;
 	pslope_t *slope;
-	INT16 tags[3];
+	sector_t *secs[3];
 	vector3_t vex[3];
+	fixed_t origsecheights[3];
+	fixed_t origvecheights[3];
+	UINT8 relative;
 } dynvertexplanethink_t;
 
 void T_DynamicSlopeLine (dynlineplanethink_t* th);