From a1c67e7e67c10b5825cc8df23c90ad27cdcb2d36 Mon Sep 17 00:00:00 2001
From: Yukita Mayako <catgirl@goddess.moe>
Date: Fri, 29 May 2015 13:53:06 -0400
Subject: [PATCH] Add MFE_APPLYPMOMZ to fix camera movement.

Here's how it works: When a player walks off the
moving platform, it applies their pmomz once, and
then _keeps pmomz set_ so that the camera still
adds pmomz to its movements until they hit another
floor. This way, the camera doesn't jerk around.
---
 src/dehacked.c    |  4 ++--
 src/lua_mobjlib.c |  1 +
 src/p_map.c       |  9 +------
 src/p_mobj.c      | 60 +++++++++++++++++++++++------------------------
 src/p_mobj.h      |  3 ++-
 src/p_user.c      |  6 ++++-
 6 files changed, 41 insertions(+), 42 deletions(-)

diff --git a/src/dehacked.c b/src/dehacked.c
index a332da5df..3b463f7f2 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 f455edf1f..b5bf25d82 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 4b2ea52cc..ca11ae2e1 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 4796e18b0..bbd5d3fe1 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 6d120c473..c07b96211 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 c5c5ab73b..d6fc5b35a 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;
 
-- 
GitLab