diff --git a/src/dehacked.c b/src/dehacked.c
index a332da5df1fc85d8c4d58b93b4a1755dd5c7b72e..3b463f7f28780712559d4ff9aef925f1b9006961 100644
--- a/src/dehacked.c
+++ b/src/dehacked.c
@@ -7193,7 +7193,7 @@ static const char *const MOBJFLAG2_LIST[] = {
 	NULL
 };
 
-static const char *const MOBJEFLAG_LIST[] = {
+static const char *const MOBJEFLAG_LIST[8] = {
 	"ONGROUND", // The mobj stands on solid floor (not on another mobj or in air)
 	"JUSTHITFLOOR", // The mobj just hit the floor while falling, this is cleared on next frame
 	"TOUCHWATER", // The mobj stands in a sector with water, and touches the surface
@@ -7201,7 +7201,7 @@ static const char *const MOBJEFLAG_LIST[] = {
 	"JUSTSTEPPEDDOWN", // used for ramp sectors
 	"VERTICALFLIP", // Vertically flip sprite/allow upside-down physics
 	"GOOWATER", // Goo water
-	NULL
+	"APPLYPMOMZ" // Platform movement
 };
 
 static const char *const MAPTHINGFLAG_LIST[4] = {
diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c
index f455edf1fe79ded82228a4b3b03e859b4986e3ce..b5bf25d82e57a60c78b5eb806de60b461bba491e 100644
--- a/src/lua_mobjlib.c
+++ b/src/lua_mobjlib.c
@@ -449,6 +449,7 @@ static int mobj_set(lua_State *L)
 		break;
 	case mobj_pmomz:
 		mo->pmomz = (fixed_t)luaL_checkinteger(L, 3);
+		mo->eflags |= MFE_APPLYPMOMZ;
 		break;
 	case mobj_tics:
 		mo->tics = luaL_checkinteger(L, 3);
diff --git a/src/p_map.c b/src/p_map.c
index 4b2ea52cc6c09500451ccb6af54835d81007f77d..ca11ae2e1d5b07179f508384bdf12f00e88c3582 100644
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -2076,14 +2076,7 @@ static boolean P_ThingHeightClip(mobj_t *thing)
 			thing->pmomz = thing->ceilingz - (thing->z + thing->height);
 		else
 			thing->pmomz = thing->floorz - thing->z;
-
-		if (thing->player)
-		{
-			if (splitscreen && camera2.chase && thing->player == &players[secondarydisplayplayer])
-				camera2.z += thing->pmomz;
-			else if (camera.chase && thing->player == &players[displayplayer])
-				camera.z += thing->pmomz;
-		}
+		thing->eflags |= MFE_APPLYPMOMZ;
 
 		if (thing->eflags & MFE_VERTICALFLIP)
 			thing->z = thing->ceilingz - thing->height;
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 4796e18b09c7bb13a9d200ce94106b9a8c399e49..bbd5d3fe1ed96ab7ee7696f07af25dbb81aa2be7 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -1493,12 +1493,13 @@ static void P_RingZMovement(mobj_t *mo)
 		P_AdjustMobjFloorZ_PolyObjs(mo, mo->subsector);
 
 	// adjust height
-	if (mo->pmomz && mo->z != mo->floorz)
+	mo->z += mo->momz;
+
+	if (mo->eflags & MFE_APPLYPMOMZ && !P_IsObjectOnGround(mo))
 	{
 		mo->momz += mo->pmomz;
-		mo->pmomz = 0;
+		mo->eflags &= ~MFE_APPLYPMOMZ;
 	}
-	mo->z += mo->momz;
 
 	// clip movement
 	if (mo->z <= mo->floorz && !(mo->flags & MF_NOCLIPHEIGHT))
@@ -1562,12 +1563,13 @@ static boolean P_ZMovement(mobj_t *mo)
 		P_AdjustMobjFloorZ_PolyObjs(mo, mo->subsector);
 
 	// adjust height
-	if (mo->pmomz && mo->z != mo->floorz)
+	mo->z += mo->momz;
+
+	if (mo->eflags & MFE_APPLYPMOMZ && !P_IsObjectOnGround(mo))
 	{
 		mo->momz += mo->pmomz;
-		mo->pmomz = 0;
+		mo->eflags &= ~MFE_APPLYPMOMZ;
 	}
-	mo->z += mo->momz;
 
 	switch (mo->type)
 	{
@@ -1987,16 +1989,14 @@ static void P_PlayerZMovement(mobj_t *mo)
 	}
 
 	// adjust height
-	if (mo->pmomz && !P_IsObjectOnGround(mo))
+	mo->z += mo->momz;
+
+	if (mo->eflags & MFE_APPLYPMOMZ && !P_IsObjectOnGround(mo))
 	{
-		if ((mo->eflags & MFE_VERTICALFLIP && mo->pmomz < 0)
-		|| (!(mo->eflags & MFE_VERTICALFLIP) && mo->pmomz > 0))
-			mo->momz += mo->pmomz;
-		mo->pmomz = 0;
+		mo->momz += mo->pmomz;
+		mo->eflags &= ~MFE_APPLYPMOMZ;
 	}
 
-	mo->z += mo->momz;
-
 	// Have player fall through floor?
 	if (mo->player->playerstate == PST_DEAD
 	|| mo->player->playerstate == PST_REBORN)
@@ -2010,7 +2010,7 @@ static void P_PlayerZMovement(mobj_t *mo)
 		else
 			mo->z = mo->floorz;
 
-		if (mo->player && (mo->player->pflags & PF_NIGHTSMODE))
+		if (mo->player->pflags & PF_NIGHTSMODE)
 		{
 			if (mo->player->flyangle < 90 || mo->player->flyangle >= 270)
 				mo->player->flyangle += P_MobjFlip(mo)*90;
@@ -2025,12 +2025,11 @@ static void P_PlayerZMovement(mobj_t *mo)
 
 		if (P_MobjFlip(mo)*mo->momz < 0) // falling
 		{
+			mo->pmomz = 0; // We're on a new floor, don't keep doing platform movement.
+
 			// Squat down. Decrease viewheight for a moment after hitting the ground (hard),
-			if (mo->player)
-			{
-				if (P_MobjFlip(mo)*mo->momz < -FixedMul(8*FRACUNIT, mo->scale))
-					mo->player->deltaviewheight = (P_MobjFlip(mo)*mo->momz)>>3; // make sure momz is negative
-			}
+			if (P_MobjFlip(mo)*mo->momz < -FixedMul(8*FRACUNIT, mo->scale))
+				mo->player->deltaviewheight = (P_MobjFlip(mo)*mo->momz)>>3; // make sure momz is negative
 
 			if (!tmfloorthing || tmfloorthing->flags & (MF_PUSHABLE|MF_MONITOR)
 				|| tmfloorthing->flags2 & MF2_STANDONME || tmfloorthing->type == MT_PLAYER) // Spin Attack
@@ -2103,14 +2102,14 @@ static void P_PlayerZMovement(mobj_t *mo)
 
 					// Cut momentum in half when you hit the ground and
 					// aren't pressing any controls.
-					if (!mo->player || (!(mo->player->cmd.forwardmove || mo->player->cmd.sidemove) && !mo->player->cmomx && !mo->player->cmomy && !(mo->player->pflags & PF_SPINNING)))
+					if (!(mo->player->cmd.forwardmove || mo->player->cmd.sidemove) && !mo->player->cmomx && !mo->player->cmomy && !(mo->player->pflags & PF_SPINNING))
 					{
 						mo->momx = mo->momx/2;
 						mo->momy = mo->momy/2;
 					}
 				}
 
-				if (mo->health && mo->player)
+				if (mo->health)
 				{
 					if (mo->player->pflags & PF_GLIDING) // ground gliding
 					{
@@ -2156,7 +2155,7 @@ static void P_PlayerZMovement(mobj_t *mo)
 					mo->player->powers[pw_tailsfly] = 0;
 				}
 			}
-			if (mo->player && !(mo->player->pflags & PF_SPINNING))
+			if (!(mo->player->pflags & PF_SPINNING))
 				mo->player->pflags &= ~PF_STARTDASH;
 
 			if (tmfloorthing && (tmfloorthing->flags & (MF_PUSHABLE|MF_MONITOR)
@@ -2199,7 +2198,7 @@ nightsdone:
 		else
 			mo->z = mo->ceilingz - mo->height;
 
-		if (mo->player && (mo->player->pflags & PF_NIGHTSMODE))
+		if (mo->player->pflags & PF_NIGHTSMODE)
 		{
 			if (mo->player->flyangle < 90 || mo->player->flyangle >= 270)
 				mo->player->flyangle -= P_MobjFlip(mo)*90;
@@ -2214,7 +2213,7 @@ nightsdone:
 		{
 			msecnode_t *node;
 
-			if (CheckForMarioBlocks && mo->player && !(netgame && mo->player->spectator)) // Only let the player punch
+			if (CheckForMarioBlocks && !(netgame && mo->player->spectator)) // Only let the player punch
 			{
 				// Search the touching sectors, from side-to-side...
 				for (node = mo->touching_sectorlist; node; node = node->m_snext)
@@ -2242,7 +2241,7 @@ nightsdone:
 			if (mariomode)
 				S_StartSound(mo, sfx_mario1);
 
-			if (!(mo->player && mo->player->climbing))
+			if (!mo->player->climbing)
 				mo->momz = 0;
 		}
 	}
@@ -2257,12 +2256,13 @@ static boolean P_SceneryZMovement(mobj_t *mo)
 		P_AdjustMobjFloorZ_PolyObjs(mo, mo->subsector);
 
 	// adjust height
-	if (mo->pmomz && mo->z != mo->floorz)
+	mo->z += mo->momz;
+
+	if (mo->eflags & MFE_APPLYPMOMZ && !P_IsObjectOnGround(mo))
 	{
 		mo->momz += mo->pmomz;
-		mo->pmomz = 0;
+		mo->eflags &= ~MFE_APPLYPMOMZ;
 	}
-	mo->z += mo->momz;
 
 	switch (mo->type)
 	{
@@ -2840,10 +2840,10 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
 	thiscam->floorz = tmfloorz;
 	thiscam->ceilingz = tmceilingz;
 
-	if (thiscam->momz)
+	if (thiscam->momz || player->mo->pmomz)
 	{
 		// adjust height
-		thiscam->z += thiscam->momz;
+		thiscam->z += thiscam->momz + player->mo->pmomz;
 
 		if (!itsatwodlevel && !(player->pflags & PF_NOCLIP))
 		{
diff --git a/src/p_mobj.h b/src/p_mobj.h
index 6d120c4733b1f54ff25cbeab05b691891722c108..c07b9621129a8a87e7bded5c9d941176837e85f9 100644
--- a/src/p_mobj.h
+++ b/src/p_mobj.h
@@ -232,7 +232,8 @@ typedef enum
 	MFE_VERTICALFLIP      = 1<<5,
 	// Goo water
 	MFE_GOOWATER          = 1<<6,
-	// free: to and including 1<<7
+	// Platform movement
+	MFE_APPLYPMOMZ        = 1<<7
 } mobjeflag_t;
 
 //
diff --git a/src/p_user.c b/src/p_user.c
index c5c5ab73b65c271dfb9f70cc16b65b1507b1ce62..d6fc5b35adf6afc790f9d0ab45a52255399749bb 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -3623,14 +3623,18 @@ void P_DoJump(player_t *player, boolean soundandstate)
 		player->mo->z--;
 		if (player->mo->pmomz < 0)
 			player->mo->momz += player->mo->pmomz; // Add the platform's momentum to your jump.
+		else
+			player->mo->pmomz = 0;
 	}
 	else
 	{
 		player->mo->z++;
 		if (player->mo->pmomz > 0)
 			player->mo->momz += player->mo->pmomz; // Add the platform's momentum to your jump.
+		else
+			player->mo->pmomz = 0;
 	}
-	player->mo->pmomz = 0;
+	player->mo->eflags &= ~MFE_APPLYPMOMZ;
 
 	player->pflags |= PF_JUMPED;