diff --git a/src/p_inter.c b/src/p_inter.c
index ce8bba6b6e7cc9a33c3d1e664b4846914be545ae..21f580a99c1e4a015abeba96c3e4d59fb290fdb8 100644
--- a/src/p_inter.c
+++ b/src/p_inter.c
@@ -1005,13 +1005,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
 						player->flyangle = special->threshold;
 
 					player->speed = FixedMul(special->info->speed, special->scale);
-					// Potentially causes axis transfer failures.
-					// Also rarely worked properly anyway.
-					//P_UnsetThingPosition(player->mo);
-					//player->mo->x = special->x;
-					//player->mo->y = special->y;
-					//P_SetThingPosition(player->mo);
-					toucher->z = special->z+(special->height/4);
+					P_SetTarget(&player->mo->hnext, special); // Reference bumper for position correction on next tic
 				}
 				else // More like a spring
 				{
diff --git a/src/p_user.c b/src/p_user.c
index fd09b084755a07215b8487ee56716f9e5b3da787..595e9566e3388cfdc02d22acb64790281ac675af 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -6175,6 +6175,15 @@ static void P_NiGHTSMovement(player_t *player)
 		S_ChangeMusicInternal((((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)) ? "_ntime" : "_drown"), false);
 
 
+	if (player->bumpertime == TICRATE/2)
+	{
+		// Center player to bumper here because if you try to set player's position in P_TouchSpecialThing case MT_NIGHTSBUMPER,
+		// that position is fudged in the time between that routine in the previous tic
+		// and reaching here in the current tic
+		P_TeleportMove(player->mo, player->mo->hnext->x, player->mo->hnext->y, player->mo->hnext->z + (player->mo->hnext->height/4));
+		P_SetTarget(&player->mo->hnext, NULL);
+	}
+
 	if (player->mo->z < player->mo->floorz)
 		player->mo->z = player->mo->floorz;