From 9499d162219fa4b247ab7707df7d3053daf19341 Mon Sep 17 00:00:00 2001
From: spherallic <spherallic@gmail.com>
Date: Mon, 12 Sep 2022 11:27:28 +0200
Subject: [PATCH] Fix quicksand in reverse gravity

---
 src/p_map.c  | 10 +++++++++-
 src/p_mobj.c |  9 +++++++--
 src/p_user.c |  4 +++-
 3 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/src/p_map.c b/src/p_map.c
index aee13ae7e..ebefeb939 100644
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -2127,7 +2127,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
 
 			if (rover->flags & FF_QUICKSAND)
 			{
-				if (thing->z < topheight && bottomheight < thingtop)
+				if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z < topheight && bottomheight < thingtop)
 				{
 					if (tmfloorz < thing->z) {
 						tmfloorz = thing->z;
@@ -2135,6 +2135,14 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
 						tmfloorslope = NULL;
 					}
 				}
+				else if (thing->eflags & MFE_VERTICALFLIP && thingtop < topheight && bottomheight < thing->z)
+				{
+					if (tmceilingz < thingtop) {
+						tmceilingz = thingtop;
+						tmceilingrover = rover;
+						tmceilingslope = NULL;
+					}
+				}
 				// Quicksand blocks never change heights otherwise.
 				continue;
 			}
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 4586be6a2..97974da57 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -2172,15 +2172,20 @@ void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motype)
 				case 2: // scenery does things differently for some reason
 					if (mo->z < topheight && bottomheight < thingtop)
 					{
-						mo->floorz = mo->z;
+						if (!(mo->eflags & MFE_VERTICALFLIP))
+							mo->floorz = mo->z;
+						else if (mo->eflags & MFE_VERTICALFLIP)
+							mo->ceilingz = thingtop;
 						continue;
 					}
 					break;
 				default:
 					if (mo->z < topheight && bottomheight < thingtop)
 					{
-						if (mo->floorz < mo->z)
+						if (!(mo->eflags & MFE_VERTICALFLIP) && mo->floorz < mo->z)
 							mo->floorz = mo->z;
+						else if (mo->eflags & MFE_VERTICALFLIP && mo->ceilingz > thingtop)
+							mo->ceilingz = thingtop;
 					}
 					continue; // This is so you can jump/spring up through quicksand from below.
 			}
diff --git a/src/p_user.c b/src/p_user.c
index 112367dc7..3dd36a49c 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -2814,7 +2814,9 @@ static void P_CheckQuicksand(player_t *player)
 	fixed_t sinkspeed;
 	fixed_t topheight, bottomheight;
 
-	if (!(player->mo->subsector->sector->ffloors && player->mo->momz <= 0))
+	if (!(player->mo->subsector->sector->ffloors &&
+		((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->momz <= 0) ||
+			(player->mo->eflags & MFE_VERTICALFLIP && player->mo->momz >= 0))))
 		return;
 
 	for (rover = player->mo->subsector->sector->ffloors; rover; rover = rover->next)