diff --git a/src/d_main.c b/src/d_main.c
index 14a8a06e1356f2e7270927d6de9c126f5a26a3b4..b61ec41435f08f991d1d5bcaf82f0bbfadb2a620 100644
--- a/src/d_main.c
+++ b/src/d_main.c
@@ -1060,10 +1060,11 @@ void D_SRB2Main(void)
 	if (M_CheckParm("-warp") && M_IsNextParm())
 	{
 		const char *word = M_GetNextParm();
-		if (fastncmp(word, "MAP", 3))
+		char ch; // use this with sscanf to catch non-digits with
+		if (fastncmp(word, "MAP", 3)) // MAPxx name
 			pstartmap = M_MapNumber(word[3], word[4]);
-		else
-			pstartmap = atoi(word);
+		else if (sscanf(word, "%d%c", &pstartmap, &ch) != 1) // a plain number
+			I_Error("Cannot warp to map %s (invalid map name)\n", word);
 		// Don't check if lump exists just yet because the wads haven't been loaded!
 		// Just do a basic range check here.
 		if (pstartmap < 1 || pstartmap > NUMMAPS)
diff --git a/src/doomdef.h b/src/doomdef.h
index 66e649ee0f14be7d4cf3e609760dc23f77b11595..fb8ab1ca270aa10d6adc856665f79f762ccfa79c 100644
--- a/src/doomdef.h
+++ b/src/doomdef.h
@@ -60,6 +60,7 @@
 #endif
 
 #ifdef _WINDOWS
+#define NONET
 #if !defined (HWRENDER) && !defined (NOHW)
 #define HWRENDER
 #endif
diff --git a/src/f_finale.c b/src/f_finale.c
index 784d820478af38b429a8ac8b70ee94ea683db1f3..2245a534fdad2b6cf98c64c9a634380f0688dbe8 100644
--- a/src/f_finale.c
+++ b/src/f_finale.c
@@ -1725,6 +1725,7 @@ static void F_AdvanceToNextScene(void)
 
 void F_EndCutScene(void)
 {
+	cutsceneover = true; // do this first, just in case Y_EndGame or something wants to turn it back false later
 	if (runningprecutscene)
 	{
 		if (server)
@@ -1741,7 +1742,6 @@ void F_EndCutScene(void)
 		else
 			Y_EndGame();
 	}
-	cutsceneover = true;
 }
 
 void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean resetplayer)
diff --git a/src/g_game.c b/src/g_game.c
index 8931f8b6b23ff57decef67ce57c9aaf4a8b3b0ae..f891b010591cccd4d5b23188d32902a84751956e 100644
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -711,6 +711,10 @@ void G_SetGameModified(boolean silent)
 
 	if (!silent)
 		CONS_Alert(CONS_NOTICE, M_GetText("Game must be restarted to record statistics.\n"));
+
+	// If in record attack recording, cancel it.
+	if (modeattacking)
+		M_EndModeAttackRun();
 }
 
 /** Builds an original game map name from a map number.
diff --git a/src/i_tcp.c b/src/i_tcp.c
index eca218c804dde4eabf59963d6a752d2c3aed0fa6..f6212458b889f9ff3a70321e54bd9aa7c8951f42 100644
--- a/src/i_tcp.c
+++ b/src/i_tcp.c
@@ -56,7 +56,9 @@
 //#define NONET
 #endif
 
-#ifndef NONET
+#ifdef NONET
+#undef HAVE_MINIUPNPC
+#else
 #ifdef USE_WINSOCK1
 #include <winsock.h>
 #elif !defined (SCOUW2) && !defined (SCOUW7) && !defined (__OS2__)
diff --git a/src/lua_hud.h b/src/lua_hud.h
index 799ce2fbf54ca60a83b39b02ed599f16cc2cb6e4..ba0a1d8941deff4c5b19e40cae1368c19ad86b18 100644
--- a/src/lua_hud.h
+++ b/src/lua_hud.h
@@ -18,6 +18,9 @@ enum hud {
 	hud_time,
 	hud_rings,
 	hud_lives,
+	// Match / CTF / Tag / Ringslinger
+	hud_weaponrings,
+	hud_powerstones,
 	// NiGHTS mode
 	hud_nightslink,
 	hud_nightsdrill,
diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c
index 31549afa7680564d4001ae6273611ffb1c239c90..7aadd9c0e871f9297d64bf1385637eb81a45be5b 100644
--- a/src/lua_hudlib.c
+++ b/src/lua_hudlib.c
@@ -44,6 +44,9 @@ static const char *const hud_disable_options[] = {
 	"rings",
 	"lives",
 
+	"weaponrings",
+	"powerstones",
+
 	"nightslink",
 	"nightsdrill",
 	"nightsrings",
diff --git a/src/m_menu.c b/src/m_menu.c
index 6c12944444983cebec788b92f5afce699f35eda8..78c3812730669acde16add9452c143c3c74bc0e1 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -705,7 +705,7 @@ static menuitem_t SP_TimeAttackMenu[] =
 	{IT_DISABLED,              NULL, "Guest Option...", &SP_GuestReplayDef, 100},
 	{IT_DISABLED,              NULL, "Replay...",     &SP_ReplayDef,        110},
 	{IT_DISABLED,              NULL, "Ghosts...",     &SP_GhostDef,         120},
-	{IT_WHITESTRING|IT_CALL,   NULL, "Start",         M_ChooseTimeAttack,   130},
+	{IT_WHITESTRING|IT_CALL|IT_CALL_NOTMODIFIED,   NULL, "Start",         M_ChooseTimeAttack,   130},
 };
 
 enum
@@ -797,7 +797,7 @@ static menuitem_t SP_NightsAttackMenu[] =
 	{IT_DISABLED,              NULL, "Guest Option...",  &SP_NightsGuestReplayDef,   108},
 	{IT_DISABLED,              NULL, "Replay...",        &SP_NightsReplayDef,        118},
 	{IT_DISABLED,              NULL, "Ghosts...",        &SP_NightsGhostDef,         128},
-	{IT_WHITESTRING|IT_CALL,   NULL, "Start",            M_ChooseNightsAttack, 138},
+	{IT_WHITESTRING|IT_CALL|IT_CALL_NOTMODIFIED,   NULL, "Start",            M_ChooseNightsAttack, 138},
 };
 
 enum
@@ -3702,6 +3702,11 @@ static void M_DrawMessageMenu(void)
 
 	mlines = currentMenu->lastOn>>8;
 	max = (INT16)((UINT8)(currentMenu->lastOn & 0xFF)*8);
+
+	// hack: draw RA background in RA menus
+	if (gamestate == GS_TIMEATTACK)
+		V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE));
+
 	M_DrawTextBox(currentMenu->x, y - 8, (max+7)>>3, mlines);
 
 	while (*(msg+start))
@@ -4310,9 +4315,9 @@ static void M_SinglePlayerMenu(INT32 choice)
 {
 	(void)choice;
 	SP_MainMenu[sprecordattack].status =
-		(M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING|IT_CALL_NOTMODIFIED : IT_SECRET;
+		(M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING : IT_SECRET;
 	SP_MainMenu[spnightsmode].status =
-		(M_SecretUnlocked(SECRET_NIGHTSMODE)) ? IT_CALL|IT_STRING|IT_CALL_NOTMODIFIED : IT_SECRET;
+		(M_SecretUnlocked(SECRET_NIGHTSMODE)) ? IT_CALL|IT_STRING : IT_SECRET;
 
 	M_SetupNextMenu(&SP_MainDef);
 }
diff --git a/src/p_map.c b/src/p_map.c
index 48f4cca23f70002ab266c3d69b00862e48518aee..c4616db489601cc6584c0b0ec0dd8239bf9d2b1a 100644
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -1153,7 +1153,7 @@ static boolean PIT_CheckLine(line_t *ld)
 	}
 
 	// set openrange, opentop, openbottom
-	P_LineOpening(ld);
+	P_LineOpening(ld, tmthing);
 
 	// adjust floor / ceiling heights
 	if (opentop < tmceilingz)
@@ -1271,7 +1271,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
 			topheight = P_GetFOFTopZ(thing, newsubsec->sector, rover, x, y, NULL);
 			bottomheight = P_GetFOFBottomZ(thing, newsubsec->sector, rover, x, y, NULL);
 
-			if (rover->flags & FF_GOOWATER && !(thing->flags & MF_NOGRAVITY))
+			if ((rover->flags & (FF_SWIMMABLE|FF_GOOWATER)) == (FF_SWIMMABLE|FF_GOOWATER) && !(thing->flags & MF_NOGRAVITY))
 			{
 				// If you're inside goowater and slowing down
 				fixed_t sinklevel = FixedMul(thing->info->height/6, thing->scale);
@@ -1970,8 +1970,12 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
 			}
 
 			// Ramp test
-			if (thing->player && maxstep > 0
-			&& !(P_PlayerTouchingSectorSpecial(thing->player, 1, 14) || GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 14))
+			if (maxstep > 0 && !(
+				thing->player && (
+				P_PlayerTouchingSectorSpecial(thing->player, 1, 14)
+				|| GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 14)
+				)
+			)
 			{
 				// If the floor difference is MAXSTEPMOVE or less, and the sector isn't Section1:14, ALWAYS
 				// step down! Formerly required a Section1:13 sector for the full MAXSTEPMOVE, but no more.
@@ -2581,7 +2585,7 @@ static boolean PTR_SlideTraverse(intercept_t *in)
 	}
 
 	// set openrange, opentop, openbottom
-	P_LineOpening(li);
+	P_LineOpening(li, slidemo);
 
 	if (openrange < slidemo->height)
 		goto isblocking; // doesn't fit
diff --git a/src/p_maputl.c b/src/p_maputl.c
index c3a6fa842b08a12267d7904368fd6e49120816fc..fea8530a125bf3a5d001d87507f5513a85bb1e06 100644
--- a/src/p_maputl.c
+++ b/src/p_maputl.c
@@ -489,7 +489,7 @@ void P_CameraLineOpening(line_t *linedef)
 	}
 }
 
-void P_LineOpening(line_t *linedef)
+void P_LineOpening(line_t *linedef, mobj_t *mobj)
 {
 	sector_t *front, *back;
 
@@ -520,8 +520,8 @@ void P_LineOpening(line_t *linedef)
 	{ // Set open and high/low values here
 		fixed_t frontheight, backheight;
 
-		frontheight = P_GetCeilingZ(tmthing, front, tmx, tmy, linedef);
-		backheight = P_GetCeilingZ(tmthing, back, tmx, tmy, linedef);
+		frontheight = P_GetCeilingZ(mobj, front, tmx, tmy, linedef);
+		backheight = P_GetCeilingZ(mobj, back, tmx, tmy, linedef);
 
 		if (frontheight < backheight)
 		{
@@ -540,8 +540,8 @@ void P_LineOpening(line_t *linedef)
 #endif
 		}
 
-		frontheight = P_GetFloorZ(tmthing, front, tmx, tmy, linedef);
-		backheight = P_GetFloorZ(tmthing, back, tmx, tmy, linedef);
+		frontheight = P_GetFloorZ(mobj, front, tmx, tmy, linedef);
+		backheight = P_GetFloorZ(mobj, back, tmx, tmy, linedef);
 
 		if (frontheight > backheight)
 		{
@@ -561,12 +561,14 @@ void P_LineOpening(line_t *linedef)
 		}
 	}
 
-	if (tmthing)
+	if (mobj)
 	{
-		fixed_t thingtop = tmthing->z + tmthing->height;
+		fixed_t thingtop = mobj->z + mobj->height;
 
 		// Check for collision with front side's midtexture if Effect 4 is set
-		if (linedef->flags & ML_EFFECT4) {
+		if (linedef->flags & ML_EFFECT4
+			&& !linedef->polyobj // don't do anything for polyobjects! ...for now
+			) {
 			side_t *side = &sides[linedef->sidenum[0]];
 			fixed_t textop, texbottom, texheight;
 			fixed_t texmid, delta1, delta2;
@@ -575,30 +577,38 @@ void P_LineOpening(line_t *linedef)
 			texheight = textures[texturetranslation[side->midtexture]]->height << FRACBITS;
 
 			// Set texbottom and textop to the Z coordinates of the texture's boundaries
-#ifdef POLYOBJECTS
+#if 0 // #ifdef POLYOBJECTS
+			// don't remove this code unless solid midtextures
+			// on non-solid polyobjects should NEVER happen in the future
 			if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT)) {
-				if (linedef->flags & ML_DONTPEGBOTTOM) {
+				if (linedef->flags & ML_EFFECT5 && !side->repeatcnt) { // "infinite" repeat
+					texbottom = back->floorheight + side->rowoffset;
+					textop = back->ceilingheight + side->rowoffset;
+				} else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) {
 					texbottom = back->floorheight + side->rowoffset;
 					textop = texbottom + texheight*(side->repeatcnt+1);
 				} else {
-					textop = back->ceilingheight - side->rowoffset;
+					textop = back->ceilingheight + side->rowoffset;
 					texbottom = textop - texheight*(side->repeatcnt+1);
 				}
 			} else
 #endif
 			{
-				if (linedef->flags & ML_DONTPEGBOTTOM) {
+				if (linedef->flags & ML_EFFECT5 && !side->repeatcnt) { // "infinite" repeat
+					texbottom = openbottom + side->rowoffset;
+					textop = opentop + side->rowoffset;
+				} else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) {
 					texbottom = openbottom + side->rowoffset;
 					textop = texbottom + texheight*(side->repeatcnt+1);
 				} else {
-					textop = opentop - side->rowoffset;
+					textop = opentop + side->rowoffset;
 					texbottom = textop - texheight*(side->repeatcnt+1);
 				}
 			}
 
 			texmid = texbottom+(textop-texbottom)/2;
 
-			delta1 = abs(tmthing->z - texmid);
+			delta1 = abs(mobj->z - texmid);
 			delta2 = abs(thingtop - texmid);
 
 			if (delta1 > delta2) { // Below
@@ -636,16 +646,16 @@ void P_LineOpening(line_t *linedef)
 				if (!(rover->flags & FF_EXISTS))
 					continue;
 
-				if (tmthing->player && (P_CheckSolidLava(tmthing, rover) || P_CanRunOnWater(tmthing->player, rover)))
+				if (mobj->player && (P_CheckSolidLava(mobj, rover) || P_CanRunOnWater(mobj->player, rover)))
 					;
-				else if (!((rover->flags & FF_BLOCKPLAYER && tmthing->player)
-					|| (rover->flags & FF_BLOCKOTHERS && !tmthing->player)))
+				else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
+					|| (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
 					continue;
 
-				topheight = P_GetFOFTopZ(tmthing, front, rover, tmx, tmy, linedef);
-				bottomheight = P_GetFOFBottomZ(tmthing, front, rover, tmx, tmy, linedef);
+				topheight = P_GetFOFTopZ(mobj, front, rover, tmx, tmy, linedef);
+				bottomheight = P_GetFOFBottomZ(mobj, front, rover, tmx, tmy, linedef);
 
-				delta1 = abs(tmthing->z - (bottomheight + ((topheight - bottomheight)/2)));
+				delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
 				delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
 
 				if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
@@ -680,16 +690,16 @@ void P_LineOpening(line_t *linedef)
 				if (!(rover->flags & FF_EXISTS))
 					continue;
 
-				if (tmthing->player && (P_CheckSolidLava(tmthing, rover) || P_CanRunOnWater(tmthing->player, rover)))
+				if (mobj->player && (P_CheckSolidLava(mobj, rover) || P_CanRunOnWater(mobj->player, rover)))
 					;
-				else if (!((rover->flags & FF_BLOCKPLAYER && tmthing->player)
-					|| (rover->flags & FF_BLOCKOTHERS && !tmthing->player)))
+				else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
+					|| (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
 					continue;
 
-				topheight = P_GetFOFTopZ(tmthing, back, rover, tmx, tmy, linedef);
-				bottomheight = P_GetFOFBottomZ(tmthing, back, rover, tmx, tmy, linedef);
+				topheight = P_GetFOFTopZ(mobj, back, rover, tmx, tmy, linedef);
+				bottomheight = P_GetFOFBottomZ(mobj, back, rover, tmx, tmy, linedef);
 
-				delta1 = abs(tmthing->z - (bottomheight + ((topheight - bottomheight)/2)));
+				delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
 				delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
 
 				if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
@@ -723,7 +733,7 @@ void P_LineOpening(line_t *linedef)
 			{
 				const sector_t *polysec = linedef->backsector;
 
-				delta1 = abs(tmthing->z - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2)));
+				delta1 = abs(mobj->z - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2)));
 				delta2 = abs(thingtop - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2)));
 				if (polysec->floorheight < lowestceiling && delta1 >= delta2) {
 					lowestceiling = polysec->floorheight;
diff --git a/src/p_maputl.h b/src/p_maputl.h
index c160bfa288f7ed5ca36275ee9eb0cc9ff8385583..3d74e927b3ba44c76585c513dcbd941369c76377 100644
--- a/src/p_maputl.h
+++ b/src/p_maputl.h
@@ -59,7 +59,7 @@ extern fixed_t opentop, openbottom, openrange, lowfloor, highceiling;
 extern pslope_t *opentopslope, *openbottomslope;
 #endif
 
-void P_LineOpening(line_t *plinedef);
+void P_LineOpening(line_t *plinedef, mobj_t *mobj);
 
 boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean(*func)(line_t *));
 boolean P_BlockThingsIterator(INT32 x, INT32 y, boolean(*func)(mobj_t *));
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 0d7f8884642294d06f308b8db7d569740553d470..5e5961d41d1d617371bb341352b5abb0e060e497 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -1540,6 +1540,7 @@ static void P_PushableCheckBustables(mobj_t *mo)
 		if (node->m_sector->ffloors)
 		{
 			ffloor_t *rover;
+			fixed_t topheight, bottomheight;
 
 			for (rover = node->m_sector->ffloors; rover; rover = rover->next)
 			{
@@ -1552,37 +1553,39 @@ static void P_PushableCheckBustables(mobj_t *mo)
 
 				if (!rover->master->frontsector->crumblestate)
 				{
+					topheight = P_GetFOFTopZ(mo, node->m_sector, rover, mo->x, mo->y, NULL);
+					bottomheight = P_GetFOFBottomZ(mo, node->m_sector, rover, mo->x, mo->y, NULL);
 					// Height checks
 					if (rover->flags & FF_SHATTERBOTTOM)
 					{
-						if (mo->z+mo->momz + mo->height < *rover->bottomheight)
+						if (mo->z+mo->momz + mo->height < bottomheight)
 							continue;
 
-						if (mo->z+mo->height > *rover->bottomheight)
+						if (mo->z+mo->height > bottomheight)
 							continue;
 					}
 					else if (rover->flags & FF_SPINBUST)
 					{
-						if (mo->z+mo->momz > *rover->topheight)
+						if (mo->z+mo->momz > topheight)
 							continue;
 
-						if (mo->z+mo->height < *rover->bottomheight)
+						if (mo->z+mo->height < bottomheight)
 							continue;
 					}
 					else if (rover->flags & FF_SHATTER)
 					{
-						if (mo->z+mo->momz > *rover->topheight)
+						if (mo->z+mo->momz > topheight)
 							continue;
 
-						if (mo->z+mo->momz + mo->height < *rover->bottomheight)
+						if (mo->z+mo->momz + mo->height < bottomheight)
 							continue;
 					}
 					else
 					{
-						if (mo->z >= *rover->topheight)
+						if (mo->z >= topheight)
 							continue;
 
-						if (mo->z+mo->height < *rover->bottomheight)
+						if (mo->z+mo->height < bottomheight)
 							continue;
 					}
 
@@ -1637,8 +1640,6 @@ void P_XYMovement(mobj_t *mo)
 	I_Assert(mo != NULL);
 	I_Assert(!P_MobjWasRemoved(mo));
 
-	moved = true;
-
 	// if it's stopped
 	if (!mo->momx && !mo->momy)
 	{
@@ -1695,9 +1696,9 @@ void P_XYMovement(mobj_t *mo)
 	if (!P_TryMove(mo, mo->x + xmove, mo->y + ymove, true) && !(mo->eflags & MFE_SPRUNG))
 	{
 		// blocked move
+		moved = false;
 
 		if (player) {
-			moved = false;
 			if (player->bot)
 				B_MoveBlocked(player);
 		}
@@ -1802,7 +1803,7 @@ void P_XYMovement(mobj_t *mo)
 		else
 			mo->momx = mo->momy = 0;
 	}
-	else if (player)
+	else
 		moved = true;
 
 	if (P_MobjWasRemoved(mo)) // MF_SPECIAL touched a player! O_o;;
@@ -2362,6 +2363,12 @@ static boolean P_ZMovement(mobj_t *mo)
 			mo->z = mo->floorz;
 
 #ifdef ESLOPE
+		if (mo->standingslope) // You're still on the ground; why are we here?
+		{
+			mo->momz = 0;
+			return true;
+		}
+
 		P_CheckPosition(mo, mo->x, mo->y); // Sets mo->standingslope correctly
 		if (((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) && (mo->type != MT_STEAM))
 		{
@@ -6918,6 +6925,7 @@ void P_MobjThinker(mobj_t *mobj)
 					{
 						mobj->flags &= ~MF_NOGRAVITY;
 						P_SetMobjState(mobj, S_NIGHTSDRONE1);
+						mobj->flags2 |= MF2_DONTDRAW;
 					}
 				}
 				else if (mobj->tracer && mobj->tracer->player)
diff --git a/src/p_spec.c b/src/p_spec.c
index 0bd530279c720aa36254d0f0a49bb1298e8e05a0..30b08ebb1d1ae880978f8de6fa3a09b98718d599 100644
--- a/src/p_spec.c
+++ b/src/p_spec.c
@@ -1188,7 +1188,12 @@ INT32 P_FindSpecialLineFromTag(INT16 special, INT16 tag, INT32 start)
 	{
 		start++;
 
-		while (lines[start].special != special)
+		// This redundant check stops the compiler from complaining about function expansion
+		// elsewhere for some reason and everything is awful
+		if (start >= (INT32)numlines)
+			return -1;
+
+		while (start < (INT32)numlines && lines[start].special != special)
 			start++;
 
 		if (start >= (INT32)numlines)
diff --git a/src/p_user.c b/src/p_user.c
index f390650f43d31101f1431c07331cc3e635f44b93..3867137adf75d4f09e5ec59138ec302d1e3d319b 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -1692,6 +1692,7 @@ static void P_CheckBustableBlocks(player_t *player)
 		if (node->m_sector->ffloors)
 		{
 			ffloor_t *rover;
+			fixed_t topheight, bottomheight;
 
 			for (rover = node->m_sector->ffloors; rover; rover = rover->next)
 			{
@@ -1717,42 +1718,45 @@ static void P_CheckBustableBlocks(player_t *player)
 					if (!(rover->flags & FF_SHATTER) && (rover->flags & FF_ONLYKNUX) && !(player->charability == CA_GLIDEANDCLIMB))
 						continue;
 
+					topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
+					bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
+
 					// Height checks
 					if (rover->flags & FF_SHATTERBOTTOM)
 					{
-						if (player->mo->z+player->mo->momz + player->mo->height < *rover->bottomheight)
+						if (player->mo->z+player->mo->momz + player->mo->height < bottomheight)
 							continue;
 
-						if (player->mo->z+player->mo->height > *rover->bottomheight)
+						if (player->mo->z+player->mo->height > bottomheight)
 							continue;
 					}
 					else if (rover->flags & FF_SPINBUST)
 					{
-						if (player->mo->z+player->mo->momz > *rover->topheight)
+						if (player->mo->z+player->mo->momz > topheight)
 							continue;
 
-						if (player->mo->z + player->mo->height < *rover->bottomheight)
+						if (player->mo->z + player->mo->height < bottomheight)
 							continue;
 					}
 					else if (rover->flags & FF_SHATTER)
 					{
-						if (player->mo->z + player->mo->momz > *rover->topheight)
+						if (player->mo->z + player->mo->momz > topheight)
 							continue;
 
-						if (player->mo->z+player->mo->momz + player->mo->height < *rover->bottomheight)
+						if (player->mo->z+player->mo->momz + player->mo->height < bottomheight)
 							continue;
 					}
 					else
 					{
-						if (player->mo->z >= *rover->topheight)
+						if (player->mo->z >= topheight)
 							continue;
 
-						if (player->mo->z + player->mo->height < *rover->bottomheight)
+						if (player->mo->z + player->mo->height < bottomheight)
 							continue;
 					}
 
 					// Impede the player's fall a bit
-					if (((rover->flags & FF_SPINBUST) || (rover->flags & FF_SHATTER)) && player->mo->z >= *rover->topheight)
+					if (((rover->flags & FF_SPINBUST) || (rover->flags & FF_SHATTER)) && player->mo->z >= topheight)
 						player->mo->momz >>= 1;
 					else if (rover->flags & FF_SHATTER)
 					{
@@ -6976,6 +6980,7 @@ static void P_MovePlayer(player_t *player)
 		msecnode_t *node; // only place it's being used in P_MovePlayer now
 		fixed_t oldx;
 		fixed_t oldy;
+		fixed_t floorz, ceilingz;
 
 		oldx = player->mo->x;
 		oldy = player->mo->y;
@@ -6993,31 +6998,34 @@ static void P_MovePlayer(player_t *player)
 			if (node->m_sector->ffloors)
 			{
 				ffloor_t *rover;
+				fixed_t topheight, bottomheight;
 
 				for (rover = node->m_sector->ffloors; rover; rover = rover->next)
 				{
-					if (!(rover->flags & FF_EXISTS)) continue;
+					if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER))
+						continue;
 
-					if ((rover->flags & FF_BLOCKPLAYER))
+					topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
+					bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
+					if (topheight > player->mo->z && bottomheight < player->mo->z)
 					{
-						if (*rover->topheight > player->mo->z && *rover->bottomheight < player->mo->z)
-						{
-							P_ResetPlayer(player);
-							S_StartSound(player->mo, sfx_s3k4a);
-							player->climbing = 5;
-							player->mo->momx = player->mo->momy = player->mo->momz = 0;
-							break;
-						}
+						P_ResetPlayer(player);
+						S_StartSound(player->mo, sfx_s3k4a);
+						player->climbing = 5;
+						player->mo->momx = player->mo->momy = player->mo->momz = 0;
+						break;
 					}
 				}
 			}
 
-			if (player->mo->z+player->mo->height > node->m_sector->ceilingheight
+			floorz = P_GetFloorZ(player->mo, node->m_sector, player->mo->x, player->mo->y, NULL);
+			ceilingz = P_GetCeilingZ(player->mo, node->m_sector, player->mo->x, player->mo->y, NULL);
+
+			if (player->mo->z+player->mo->height > ceilingz
 				&& node->m_sector->ceilingpic == skyflatnum)
 				continue;
 
-			if (node->m_sector->floorheight > player->mo->z
-				|| node->m_sector->ceilingheight < player->mo->z)
+			if (floorz > player->mo->z || ceilingz < player->mo->z)
 			{
 				P_ResetPlayer(player);
 				S_StartSound(player->mo, sfx_s3k4a);
diff --git a/src/st_stuff.c b/src/st_stuff.c
index aac6b09d2e4fc33fd347b47cbffac0b6eb843ed3..3562a9b713ef11bfec43436917ca56afbfa700bb 100644
--- a/src/st_stuff.c
+++ b/src/st_stuff.c
@@ -974,7 +974,7 @@ static void ST_drawNiGHTSHUD(void)
 	if (cv_debug & DBG_NIGHTSBASIC)
 		minlink = 0;
 
-	// Cheap hack: don't display when the score is showing
+	// Cheap hack: don't display when the score is showing (it popping up for a split second when exiting a map is intentional)
 	if (stplyr->texttimer && stplyr->textvar == 4)
 		minlink = INT32_MAX;
 
@@ -1385,6 +1385,10 @@ static void ST_drawMatchHUD(void)
 	if (G_TagGametype() && !(stplyr->pflags & PF_TAGIT))
 		return;
 
+#ifdef HAVE_BLUA
+	if (LUA_HudEnabled(hud_weaponrings)) {
+#endif
+
 	if (stplyr->powers[pw_infinityring])
 		ST_drawWeaponRing(pw_infinityring, 0, 0, offset, infinityring);
 	else if (stplyr->health > 1)
@@ -1408,6 +1412,12 @@ static void ST_drawMatchHUD(void)
 	offset += 20;
 	ST_drawWeaponRing(pw_railring, RW_RAIL, WEP_RAIL, offset, railring);
 
+#ifdef HAVE_BLUA
+	}
+
+	if (LUA_HudEnabled(hud_powerstones)) {
+#endif
+
 	// Power Stones collected
 	offset = 136; // Used for Y now
 
@@ -1439,6 +1449,10 @@ static void ST_drawMatchHUD(void)
 
 	if (stplyr->powers[pw_emeralds] & EMERALD7)
 		V_DrawScaledPatch(28, STRINGY(offset), V_SNAPTOLEFT, tinyemeraldpics[6]);
+
+#ifdef HAVE_BLUA
+	}
+#endif
 }
 
 static inline void ST_drawRaceHUD(void)