diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg
index 79ed8ff444ce6a200758642877c709344e8dec64..0064304221a205a48016e759802cfaa3a37d6381 100644
--- a/extras/conf/SRB2-22.cfg
+++ b/extras/conf/SRB2-22.cfg
@@ -438,6 +438,7 @@ sectortypes
 	160 = "Special Stage Time/Spheres Parameters <deprecated>";
 	176 = "Custom Global Gravity <deprecated>";
 	1280 = "Speed Pad";
+	1536 = "Flip Gravity on Jump";
 	4096 = "Star Post Activator";
 	8192 = "Exit/Special Stage Pit/Return Flag";
 	12288 = "CTF Red Team Base";
@@ -496,6 +497,7 @@ gen_sectortypes
 	{
 		0 = "Normal";
 		1280 = "Speed Pad";
+		1536 = "Flip Gravity on Jump";
 	}
 
 	fourth
diff --git a/extras/conf/udb/Includes/SRB222_sectors.cfg b/extras/conf/udb/Includes/SRB222_sectors.cfg
index f9df297e76d06a3ed122156379066d3b38136c84..5b3ad4155c176b229eee741b9a1744121b68d4ae 100644
--- a/extras/conf/udb/Includes/SRB222_sectors.cfg
+++ b/extras/conf/udb/Includes/SRB222_sectors.cfg
@@ -28,6 +28,7 @@ sectortypes
 	160 = "Special Stage Time/Spheres Parameters <deprecated>";
 	176 = "Custom Global Gravity <deprecated>";
 	1280 = "Speed Pad";
+	1536 = "Flip Gravity on Jump";
 	4096 = "Star Post Activator";
 	8192 = "Exit/Special Stage Pit/Return Flag";
 	12288 = "CTF Red Team Base";
@@ -84,6 +85,7 @@ gen_sectortypes
 	{
 		0 = "Normal";
 		1280 = "Speed Pad";
+		1536 = "Flip Gravity on Jump";
 	}
 
 	fourth
@@ -102,4 +104,4 @@ gen_sectortypes
 		45056 = "Rope Hang";
 		49152 = "Intangible to the Camera";
 	}
-}
\ No newline at end of file
+}
diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index da36142716c722701b59bb20479ec8e07a6512c4..96500ad689f6573e01dfb0881d39a9faf35680e4 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -1290,6 +1290,17 @@ static int lib_pInSpaceSector(lua_State *L)
 	return 1;
 }
 
+static int lib_pInJumpFlipSector(lua_State *L)
+{
+	mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
+	//HUDSAFE
+	INLEVEL
+	if (!mo)
+		return LUA_ErrInvalid(L, "mobj_t");
+	lua_pushboolean(L, P_InJumpFlipSector(mo));
+	return 1;
+}
+
 static int lib_pInQuicksand(lua_State *L)
 {
 	mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
@@ -4008,6 +4019,7 @@ static luaL_Reg lib[] = {
 	{"P_IsObjectInGoop",lib_pIsObjectInGoop},
 	{"P_IsObjectOnGround",lib_pIsObjectOnGround},
 	{"P_InSpaceSector",lib_pInSpaceSector},
+	{"P_InJumpFlipSector",lib_pInJumpFlipSector},
 	{"P_InQuicksand",lib_pInQuicksand},
 	{"P_SetObjectMomZ",lib_pSetObjectMomZ},
 	{"P_PlayJingle",lib_pPlayJingle},
diff --git a/src/p_local.h b/src/p_local.h
index f50606117cd91566d3a9f2dc46de434efc66c6d2..b4763a7e2e0cdccf68d8d281ffb6c524fd706f43 100644
--- a/src/p_local.h
+++ b/src/p_local.h
@@ -149,6 +149,7 @@ boolean P_PlayerShouldUseSpinHeight(player_t *player);
 boolean P_IsObjectInGoop(mobj_t *mo);
 boolean P_IsObjectOnGround(mobj_t *mo);
 boolean P_InSpaceSector(mobj_t *mo);
+boolean P_InJumpFlipSector(mobj_t *mo);
 boolean P_InQuicksand(mobj_t *mo);
 boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff);
 
diff --git a/src/p_setup.c b/src/p_setup.c
index 50c5ae2a346e0e2916d29bb8c18bb6a7c4ee5d79..e8b5e0f21a1e16405eb0ee79da189c913988571d 100644
--- a/src/p_setup.c
+++ b/src/p_setup.c
@@ -1725,6 +1725,8 @@ static void ParseTextmapSectorParameter(UINT32 i, const char *param, const char
 		sectors[i].specialflags |= SSF_FINISHLINE;
 	else if (fastcmp(param, "ropehang") && fastcmp("true", val))
 		sectors[i].specialflags |= SSF_ROPEHANG;
+	else if (fastcmp(param, "jumpflip") && fastcmp("true", val))
+		sectors[i].specialflags |= SSF_JUMPFLIP;
 	else if (fastcmp(param, "friction"))
 		sectors[i].friction = FLOAT_TO_FIXED(atof(val));
 	else if (fastcmp(param, "gravity"))
@@ -2578,6 +2580,8 @@ static void P_WriteTextmap(void)
 			fprintf(f, "finishline = true;\n");
 		if (wsectors[i].specialflags & SSF_ROPEHANG)
 			fprintf(f, "ropehang = true;\n");
+		if (wsectors[i].specialflags & SSF_JUMPFLIP)
+			fprintf(f, "jumpflip = true;\n");
 		if (wsectors[i].friction != ORIG_FRICTION)
 			fprintf(f, "friction = %f;\n", FIXED_TO_FLOAT(wsectors[i].friction));
 		if (wsectors[i].gravity != FRACUNIT)
@@ -5936,6 +5940,9 @@ static void P_ConvertBinarySectorTypes(void)
 			case 5: //Speed pad
 				sectors[i].specialflags |= SSF_SPEEDPAD;
 				break;
+			case 6: //Gravity flip on jump
+				sectors[i].specialflags |= SSF_JUMPFLIP;
+				break;
 			default:
 				break;
 		}
diff --git a/src/p_user.c b/src/p_user.c
index cc5caedd69a03dc47b667b2ca9056897ca0e12b1..a82704ad91e7ed3dcf99829c2066d7b197b28536 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -1966,22 +1966,22 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
 
 	ghost->angle = (mobj->player ? mobj->player->drawangle : mobj->angle);
 	ghost->rollangle = mobj->rollangle;
-	
+
 	ghost->sprite = mobj->sprite;
 	ghost->sprite2 = mobj->sprite2;
 	ghost->frame = mobj->frame;
 	ghost->tics = -1;
 	ghost->frame &= ~FF_TRANSMASK;
 	ghost->frame |= tr_trans50<<FF_TRANSSHIFT;
-	
+
 	ghost->renderflags = mobj->renderflags;
 	ghost->blendmode = mobj->blendmode;
-	
+
 	ghost->spritexscale = mobj->spritexscale;
 	ghost->spriteyscale = mobj->spriteyscale;
 	ghost->spritexoffset = mobj->spritexoffset;
 	ghost->spriteyoffset = mobj->spriteyoffset;
-	
+
 	ghost->fuse = ghost->info->damage;
 	ghost->skin = mobj->skin;
 
@@ -2484,6 +2484,41 @@ boolean P_InQuicksand(mobj_t *mo) // Returns true if you are in quicksand
 	return false; // No sand here, Captain!
 }
 
+boolean P_InJumpFlipSector(mobj_t *mo) // Returns true if you are in a jumpflip sector
+{
+	sector_t *sector = mo->subsector->sector;
+	fixed_t topheight, bottomheight;
+
+	if (sector->specialflags & SSF_JUMPFLIP)
+		return true;
+
+	if (sector->ffloors)
+	{
+		ffloor_t *rover;
+
+		for (rover = sector->ffloors; rover; rover = rover->next)
+		{
+			if (!(rover->flags & FF_EXISTS))
+				continue;
+
+			if (!(rover->master->frontsector->specialflags & SSF_JUMPFLIP))
+				continue;
+			topheight    = P_GetFFloorTopZAt   (rover, mo->x, mo->y);
+			bottomheight = P_GetFFloorBottomZAt(rover, mo->x, mo->y);
+
+			if (mo->z + (mo->height/2) > topheight)
+				continue;
+
+			if (mo->z + (mo->height/2) < bottomheight)
+				continue;
+
+			return true;
+		}
+	}
+
+	return false; // No jumpflip here, Captain!
+}
+
 static boolean P_PlayerCanBust(player_t *player, ffloor_t *rover)
 {
 	if (!(rover->flags & FF_EXISTS))
@@ -4449,6 +4484,9 @@ void P_DoJump(player_t *player, boolean soundandstate)
 	if (player->charflags & SF_NOJUMPDAMAGE)
 		player->pflags &= ~PF_SPINNING;
 
+	if (P_InJumpFlipSector(player->mo))
+		player->mo->flags2 ^= MF2_OBJECTFLIP;
+
 	if (soundandstate)
 	{
 		if (!player->spectator)
diff --git a/src/r_defs.h b/src/r_defs.h
index 9788e6b58c6d0ebf726a94589dfdaf5540cf008f..e91f864ac309ded2b8e81c4137054dd6c19bf5f1 100644
--- a/src/r_defs.h
+++ b/src/r_defs.h
@@ -314,6 +314,7 @@ typedef enum
 	SSF_ZOOMTUBEEND = 1<<16,
 	SSF_FINISHLINE = 1<<17,
 	SSF_ROPEHANG = 1<<18,
+	SSF_JUMPFLIP = 1<<19,
 } sectorspecialflags_t;
 
 typedef enum