From 1e64b096fd54a6258dd148ae4fc33f95638b26ae Mon Sep 17 00:00:00 2001
From: toasterbabe <rollerorbital@gmail.com>
Date: Mon, 3 Apr 2017 18:28:02 +0100
Subject: [PATCH] Bugfixes and code cleanup.

* Getting hit whilst on a swinging mace doesn't send you off in roll/jump state.
* P_GetJumpFlags replaces a bunch of copypasted code.
* Homing attacking a spring sends you directly on its path, rather than rocketing off in the direction you were preiously hurtling in.
---
 src/lua_baselib.c | 12 +++++++
 src/p_local.h     |  1 +
 src/p_map.c       |  4 +--
 src/p_user.c      | 84 +++++++++++++++++++++++++++--------------------
 src/st_stuff.c    |  2 +-
 5 files changed, 64 insertions(+), 39 deletions(-)

diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index ef8e025b8..71f6a7e65 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -815,6 +815,17 @@ static int lib_pStealPlayerScore(lua_State *L)
 	return 0;
 }
 
+static int lib_pGetJumpFlags(lua_State *L)
+{
+	player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
+	NOHUD
+	INLEVEL
+	if (!player)
+		return LUA_ErrInvalid(L, "player_t");
+	lua_pushinteger(L, P_GetJumpFlags(player));
+	return 1;
+}
+
 static int lib_pPlayerInPain(lua_State *L)
 {
 	player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
@@ -2378,6 +2389,7 @@ static luaL_Reg lib[] = {
 	{"P_GetPlayerControlDirection",lib_pGetPlayerControlDirection},
 	{"P_AddPlayerScore",lib_pAddPlayerScore},
 	{"P_StealPlayerScore",lib_pStealPlayerScore},
+	{"P_GetJumpFlags",lib_pGetJumpFlags},
 	{"P_PlayerInPain",lib_pPlayerInPain},
 	{"P_DoPlayerPain",lib_pDoPlayerPain},
 	{"P_ResetPlayer",lib_pResetPlayer},
diff --git a/src/p_local.h b/src/p_local.h
index 78ef65192..a1b07e952 100644
--- a/src/p_local.h
+++ b/src/p_local.h
@@ -130,6 +130,7 @@ void P_ResetCamera(player_t *player, camera_t *thiscam);
 boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam);
 void P_SlideCameraMove(camera_t *thiscam);
 boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcalled);
+pflags_t P_GetJumpFlags(player_t *player);
 boolean P_PlayerInPain(player_t *player);
 void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor);
 void P_ResetPlayer(player_t *player);
diff --git a/src/p_map.c b/src/p_map.c
index 04858b5df..a74c9f1e2 100644
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -142,7 +142,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
 	object->eflags |= MFE_SPRUNG; // apply this flag asap!
 	spring->flags &= ~(MF_SOLID|MF_SPECIAL); // De-solidify
 
-	if (horizspeed && vertispeed) // Mimic SA
+	if ((horizspeed && vertispeed) || (object->player && object->player->homing)) // Mimic SA
 	{
 		object->momx = object->momy = 0;
 		P_TryMove(object, spring->x, spring->y, true);
@@ -214,7 +214,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
 
 		if (spring->info->painchance)
 		{
-			object->player->pflags |= (PF_JUMPED|((object->player->charflags & SF_NOJUMPDAMAGE) ? PF_NOJUMPDAMAGE : 0));
+			object->player->pflags |= P_GetJumpFlags(object->player);
 			P_SetPlayerMobjState(object, S_PLAY_JUMP);
 		}
 		else if (!vertispeed || (pflags & PF_BOUNCING)) // horizontal spring or bouncing
diff --git a/src/p_user.c b/src/p_user.c
index 7a72f360c..b17466991 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -769,6 +769,13 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
 	player->powers[pw_carry] = CR_NIGHTSMODE;
 }
 
+pflags_t P_GetJumpFlags(player_t *player)
+{
+	if (player->charflags & SF_NOJUMPDAMAGE)
+		return (PF_JUMPED|PF_NOJUMPDAMAGE);
+	return PF_JUMPED;
+}
+
 //
 // P_PlayerInPain
 //
@@ -1677,7 +1684,7 @@ void P_DoPlayerExit(player_t *player)
 	if (player->climbing)
 	{
 		player->climbing = 0;
-		player->pflags |= (PF_JUMPED|((player->charflags & SF_NOJUMPDAMAGE) ? PF_NOJUMPDAMAGE : 0));
+		player->pflags |= P_GetJumpFlags(player);
 		P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
 	}
 	player->powers[pw_underwater] = 0;
@@ -2012,7 +2019,7 @@ static void P_CheckBouncySectors(player_t *player)
 						if (player->pflags & PF_SPINNING)
 						{
 							player->pflags &= ~PF_SPINNING;
-							player->pflags |= (PF_JUMPED|((player->charflags & SF_NOJUMPDAMAGE) ? PF_NOJUMPDAMAGE : 0));
+							player->pflags |= P_GetJumpFlags(player);
 							player->pflags |= PF_THOKKED;
 						}
 					}
@@ -2024,7 +2031,7 @@ static void P_CheckBouncySectors(player_t *player)
 						if (player->pflags & PF_SPINNING)
 						{
 							player->pflags &= ~PF_SPINNING;
-							player->pflags |= (PF_JUMPED|((player->charflags & SF_NOJUMPDAMAGE) ? PF_NOJUMPDAMAGE : 0));
+							player->pflags |= P_GetJumpFlags(player);
 							player->pflags |= PF_THOKKED;
 						}
 					}
@@ -2032,7 +2039,7 @@ static void P_CheckBouncySectors(player_t *player)
 					if ((player->pflags & PF_SPINNING) && player->speed < FixedMul(1<<FRACBITS, player->mo->scale) && player->mo->momz)
 					{
 						player->pflags &= ~PF_SPINNING;
-						player->pflags |= (PF_JUMPED|((player->charflags & SF_NOJUMPDAMAGE) ? PF_NOJUMPDAMAGE : 0));
+						player->pflags |= P_GetJumpFlags(player);
 					}
 
 					goto bouncydone;
@@ -2769,21 +2776,21 @@ static void P_DoClimbing(player_t *player)
 				P_InstaThrust(player->mo, player->mo->angle, FixedMul(4*FRACUNIT, player->mo->scale)); // Lil' boost up.
 
 			player->climbing = 0;
-			player->pflags |= (PF_JUMPED|((player->charflags & SF_NOJUMPDAMAGE) ? PF_NOJUMPDAMAGE : 0));
+			player->pflags |= P_GetJumpFlags(player);
 			P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
 		}
 
 		if (skyclimber)
 		{
 			player->climbing = 0;
-			player->pflags |= (PF_JUMPED|((player->charflags & SF_NOJUMPDAMAGE) ? PF_NOJUMPDAMAGE : 0));
+			player->pflags |= P_GetJumpFlags(player);
 			P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
 		}
 	}
 	else
 	{
 		player->climbing = 0;
-		player->pflags |= (PF_JUMPED|((player->charflags & SF_NOJUMPDAMAGE) ? PF_NOJUMPDAMAGE : 0));
+		player->pflags |= P_GetJumpFlags(player);
 		P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
 	}
 
@@ -2801,7 +2808,7 @@ static void P_DoClimbing(player_t *player)
 	if (cmd->buttons & BT_USE && !(player->pflags & PF_JUMPSTASIS))
 	{
 		player->climbing = 0;
-		player->pflags |= (PF_JUMPED|((player->charflags & SF_NOJUMPDAMAGE) ? PF_NOJUMPDAMAGE : 0));
+		player->pflags |= P_GetJumpFlags(player);
 		P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
 		P_SetObjectMomZ(player->mo, 4*FRACUNIT, false);
 		P_InstaThrust(player->mo, player->mo->angle, FixedMul(-4*FRACUNIT, player->mo->scale));
@@ -3697,7 +3704,7 @@ void P_DoJump(player_t *player, boolean soundandstate)
 	}
 	player->mo->eflags &= ~MFE_APPLYPMOMZ;
 
-	player->pflags |= (PF_JUMPED|((player->charflags & SF_NOJUMPDAMAGE) ? PF_NOJUMPDAMAGE : 0));;
+	player->pflags |= P_GetJumpFlags(player);;
 
 	if (soundandstate)
 	{
@@ -6848,7 +6855,7 @@ static void P_MovePlayer(player_t *player)
 			P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
 		else
 		{
-			player->pflags |= (PF_JUMPED|((player->charflags & SF_NOJUMPDAMAGE) ? PF_NOJUMPDAMAGE : 0));
+			player->pflags |= P_GetJumpFlags(player);
 			P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
 		}
 		player->pflags &= ~PF_GLIDING;
@@ -6863,7 +6870,7 @@ static void P_MovePlayer(player_t *player)
 			P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
 		else
 		{
-			player->pflags |= (PF_JUMPED|((player->charflags & SF_NOJUMPDAMAGE) ? PF_NOJUMPDAMAGE : 0));
+			player->pflags |= P_GetJumpFlags(player);
 			P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
 		}
 		player->pflags &= ~PF_BOUNCING;
@@ -6917,7 +6924,7 @@ static void P_MovePlayer(player_t *player)
 				P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
 			else if (player->charflags & SF_MULTIABILITY)
 			{
-				player->pflags |= (PF_JUMPED|((player->charflags & SF_NOJUMPDAMAGE) ? PF_NOJUMPDAMAGE : 0));
+				player->pflags |= P_GetJumpFlags(player);
 				P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
 			}
 			else
@@ -6954,7 +6961,7 @@ static void P_MovePlayer(player_t *player)
 				P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
 			else if (player->charflags & SF_MULTIABILITY)
 			{
-				player->pflags |= (PF_JUMPED|((player->charflags & SF_NOJUMPDAMAGE) ? PF_NOJUMPDAMAGE : 0));
+				player->pflags |= P_GetJumpFlags(player);
 				P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
 			}
 			else
@@ -7011,7 +7018,7 @@ static void P_MovePlayer(player_t *player)
 				P_SetPlayerMobjState(player->mo, S_PLAY_WALK);
 			else
 			{
-				player->pflags |= (PF_JUMPED|((player->charflags & SF_NOJUMPDAMAGE) ? PF_NOJUMPDAMAGE : 0));
+				player->pflags |= P_GetJumpFlags(player);
 				P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
 			}
 		}
@@ -7681,7 +7688,7 @@ static void P_DoRopeHang(player_t *player)
 	{
 		P_SetTarget(&player->mo->tracer, NULL);
 
-		player->pflags |= (PF_JUMPED|((player->charflags & SF_NOJUMPDAMAGE) ? PF_NOJUMPDAMAGE : 0));
+		player->pflags |= P_GetJumpFlags(player);
 		player->powers[pw_carry] = CR_NONE;
 
 		if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED)
@@ -7779,7 +7786,7 @@ static void P_DoRopeHang(player_t *player)
 		{
 			if (player->mo->tracer->flags & MF_SLIDEME)
 			{
-				player->pflags |= (PF_JUMPED|((player->charflags & SF_NOJUMPDAMAGE) ? PF_NOJUMPDAMAGE : 0));
+				player->pflags |= P_GetJumpFlags(player);
 
 				if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED)
 				&& !(player->panim == PA_JUMP))
@@ -9134,7 +9141,9 @@ void P_PlayerThink(player_t *player)
 		}
 	}
 #endif
-	if (player->pflags & PF_GLIDING)
+	if (!player->mo->health)
+		;
+	else if (player->pflags & PF_GLIDING)
 	{
 		if (player->panim != PA_ABILITY)
 			P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE);
@@ -9918,28 +9927,31 @@ void P_PlayerAfterThink(player_t *player)
 		player->mo->momy = (player->mo->tracer->y - player->mo->y)*2;
 		player->mo->momz = (player->mo->tracer->z - (player->mo->height-player->mo->tracer->height/2) - player->mo->z)*2;
 		P_TeleportMove(player->mo, player->mo->tracer->x, player->mo->tracer->y, player->mo->tracer->z - (player->mo->height-player->mo->tracer->height/2));
-		player->pflags |= PF_JUMPED;
-		player->pflags &= ~PF_NOJUMPDAMAGE;
-		player->secondjump = 0;
-		player->pflags &= ~PF_THOKKED;
-
-		if (cmd->forwardmove > 0)
-			player->mo->tracer->target->lastlook += 2;
-		else if (cmd->forwardmove < 0 && player->mo->tracer->target->lastlook > player->mo->tracer->target->movecount)
-			player->mo->tracer->target->lastlook -= 2;
-
-		if (!(player->mo->tracer->target->flags & MF_SLIDEME) // Noclimb on chain parameters gives this
-		&& !(twodlevel || player->mo->flags2 & MF2_TWOD)) // why on earth would you want to turn them in 2D mode?
+		if (!player->powers[pw_flashing]) // handle getting hurt
 		{
-			player->mo->tracer->target->health += cmd->sidemove;
-			player->mo->angle += cmd->sidemove<<ANGLETOFINESHIFT; // 2048 --> ANGLE_MAX
+			player->pflags |= PF_JUMPED;
+			player->pflags &= ~PF_NOJUMPDAMAGE;
+			player->secondjump = 0;
+			player->pflags &= ~PF_THOKKED;
 
-			if (!demoplayback || P_AnalogMove(player))
+			if (cmd->forwardmove > 0)
+				player->mo->tracer->target->lastlook += 2;
+			else if (cmd->forwardmove < 0 && player->mo->tracer->target->lastlook > player->mo->tracer->target->movecount)
+				player->mo->tracer->target->lastlook -= 2;
+
+			if (!(player->mo->tracer->target->flags & MF_SLIDEME) // Noclimb on chain parameters gives this
+			&& !(twodlevel || player->mo->flags2 & MF2_TWOD)) // why on earth would you want to turn them in 2D mode?
 			{
-				if (player == &players[consoleplayer])
-					localangle = player->mo->angle; // Adjust the local control angle.
-				else if (player == &players[secondarydisplayplayer])
-					localangle2 = player->mo->angle;
+				player->mo->tracer->target->health += cmd->sidemove;
+				player->mo->angle += cmd->sidemove<<ANGLETOFINESHIFT; // 2048 --> ANGLE_MAX
+
+				if (!demoplayback || P_AnalogMove(player))
+				{
+					if (player == &players[consoleplayer])
+						localangle = player->mo->angle; // Adjust the local control angle.
+					else if (player == &players[secondarydisplayplayer])
+						localangle2 = player->mo->angle;
+				}
 			}
 		}
 	}
diff --git a/src/st_stuff.c b/src/st_stuff.c
index e5d005b23..315dcd068 100644
--- a/src/st_stuff.c
+++ b/src/st_stuff.c
@@ -581,7 +581,7 @@ static void ST_drawDebugInfo(void)
 	{
 		V_DrawRightAlignedString(320, height - 104, V_MONOSPACE, va("SHIELD: %5x", stplyr->powers[pw_shield]));
 		V_DrawRightAlignedString(320, height - 96,  V_MONOSPACE, va("SCALE: %5d%%", (stplyr->mo->scale*100)/FRACUNIT));
-		V_DrawRightAlignedString(320, height - 88,  V_MONOSPACE, va("DASH: %3d/%3d", stplyr->dashspeed>>FRACBITS, stplyr->maxdash>>FRACBITS));
+		V_DrawRightAlignedString(320, height - 88,  V_MONOSPACE, va("CARRY: %5x", stplyr->powers[pw_carry]));
 		V_DrawRightAlignedString(320, height - 80,  V_MONOSPACE, va("AIR: %4d, %3d", stplyr->powers[pw_underwater], stplyr->powers[pw_spacetime]));
 
 		// Flags