diff --git a/src/p_polyobj.c b/src/p_polyobj.c
index 8ba5fadacda4303d10d84d6d3606c347d8a9b892..ea8a3d5cb763ff837fcefb09c19e8a21aea54ea0 100644
--- a/src/p_polyobj.c
+++ b/src/p_polyobj.c
@@ -1569,15 +1569,42 @@ void T_PolyObjMove(polymove_t *th)
 	}
 }
 
+static void T_MovePolyObj(polyobj_t *po, fixed_t distx, fixed_t disty, fixed_t distz)
+{
+	polyobj_t *child;
+	INT32 start;
+
+	Polyobj_moveXY(po, distx, disty, true);
+	// TODO: use T_MovePlane
+	po->lines[0]->backsector->floorheight += distz;
+	po->lines[0]->backsector->ceilingheight += distz;
+	// Sal: Remember to check your sectors!
+	// Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap
+	//  updating objects in the front one too just added teleporting to ground bugs
+	P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage));
+	// Apply action to mirroring polyobjects as well
+	start = 0;
+	while ((child = Polyobj_GetChild(po, &start)))
+	{
+		if (child->isBad)
+			continue;
+
+		Polyobj_moveXY(child, distx, disty, true);
+		// TODO: use T_MovePlane
+		child->lines[0]->backsector->floorheight += distz;
+		child->lines[0]->backsector->ceilingheight += distz;
+		P_CheckSector(child->lines[0]->backsector, (boolean)(child->damage));
+	}
+}
+
 void T_PolyObjWaypoint(polywaypoint_t *th)
 {
 	mobj_t *target = NULL;
 	mobj_t *waypoint = NULL;
 	fixed_t pox, poy, poz;
-	fixed_t momx, momy, momz, dist;
-	INT32 start;
+	fixed_t distx, disty, distz, dist;
+	fixed_t momx, momy, momz;
 	polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
-	polyobj_t *oldpo = po;
 
 	if (!po)
 #ifdef RANGECHECK
@@ -1607,7 +1634,10 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
 	poz = (po->lines[0]->backsector->floorheight + po->lines[0]->backsector->ceilingheight)/2;
 
 	// Calculate the distance between the polyobject and the waypoint
-	dist = P_AproxDistance(P_AproxDistance(target->x - pox, target->y - poy), target->z - poz);
+	distx = target->x - pox;
+	disty = target->y - poy;
+	distz = target->z - poz;
+	dist = P_AproxDistance(P_AproxDistance(distx, disty), distz);
 
 	if (dist < 1)
 		dist = 1;
@@ -1621,38 +1651,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
 	if (dist>>FRACBITS <= P_AproxDistance(P_AproxDistance(target->x - pox - momx, target->y - poy - momy), target->z - poz - momz)>>FRACBITS)
 	{
 		// If further away, set XYZ of polyobject to waypoint location
-		fixed_t amtx, amty, amtz;
-		fixed_t diffz;
-		amtx = target->x - po->centerPt.x;
-		amty = target->y - po->centerPt.y;
-		Polyobj_moveXY(po, amtx, amty, true);
-		// TODO: use T_MovePlane
-		amtz = (po->lines[0]->backsector->ceilingheight - po->lines[0]->backsector->floorheight)/2;
-		diffz = po->lines[0]->backsector->floorheight - (target->z - amtz);
-		po->lines[0]->backsector->floorheight = target->z - amtz;
-		po->lines[0]->backsector->ceilingheight = target->z + amtz;
-		// Sal: Remember to check your sectors!
-		// Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap
-		//  updating objects in the front one too just added teleporting to ground bugs
-		P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage));
-		// Apply action to mirroring polyobjects as well
-		start = 0;
-		while ((po = Polyobj_GetChild(oldpo, &start)))
-		{
-			if (po->isBad)
-				continue;
-
-			Polyobj_moveXY(po, amtx, amty, true);
-			// TODO: use T_MovePlane
-			po->lines[0]->backsector->floorheight += diffz; // move up/down by same amount as the parent did
-			po->lines[0]->backsector->ceilingheight += diffz;
-			// Sal: Remember to check your sectors!
-			// Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap
-			//  updating objects in the front one too just added teleporting to ground bugs
-			P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage));
-		}
-
-		po = oldpo;
+		T_MovePolyObj(po, distx, disty, distz);
 
 		if (!th->stophere)
 		{
@@ -1720,31 +1719,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
 	}
 
 	// Move the polyobject
-	Polyobj_moveXY(po, momx, momy, true);
-	// TODO: use T_MovePlane
-	po->lines[0]->backsector->floorheight += momz;
-	po->lines[0]->backsector->ceilingheight += momz;
-	// Sal: Remember to check your sectors!
-	// Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap
-	//  updating objects in the front one too just added teleporting to ground bugs
-	P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage));
-
-	// Apply action to mirroring polyobjects as well
-	start = 0;
-	while ((po = Polyobj_GetChild(oldpo, &start)))
-	{
-		if (po->isBad)
-			continue;
-
-		Polyobj_moveXY(po, momx, momy, true);
-		// TODO: use T_MovePlane
-		po->lines[0]->backsector->floorheight += momz;
-		po->lines[0]->backsector->ceilingheight += momz;
-		// Sal: Remember to check your sectors!
-		// Monster Iestyn: we only need to bother with the back sector, now that P_CheckSector automatically checks the blockmap
-		//  updating objects in the front one too just added teleporting to ground bugs
-		P_CheckSector(po->lines[0]->backsector, (boolean)(po->damage));
-	}
+	T_MovePolyObj(po, momx, momy, momz);
 }
 
 void T_PolyDoorSlide(polyslidedoor_t *th)