diff --git a/src/d_netcmd.c b/src/d_netcmd.c
index 8fa4b2e0b9cdf5a47c6a8712dc27de3b4f6fe371..10133da2b052445129c6ae84504b4be2020eaf4c 100644
--- a/src/d_netcmd.c
+++ b/src/d_netcmd.c
@@ -3809,11 +3809,19 @@ static void CoopLives_OnChange(void)
 
 static void ExitMove_OnChange(void)
 {
+	UINT8 i;
+
 	if (!(netgame || multiplayer) || gametype != GT_COOP)
 		return;
 
 	if (cv_exitmove.value)
+	{
+		for (i = 0; i < MAXPLAYERS; ++i)
+			if (playeringame[i] && players[i].mo
+				&& players[i].mo->target && players[i].mo->target->type == MT_SIGN)
+				P_SetTarget(&players[i].mo->target, NULL);
 		CONS_Printf(M_GetText("Players can now move after completing the level.\n"));
+	}
 	else
 		CONS_Printf(M_GetText("Players can no longer move after completing the level.\n"));
 }
diff --git a/src/p_spec.c b/src/p_spec.c
index cf5ac0afd096cc830d2d180d54bd96b032d7c9ed..2433264561b006933f559f64802927ba60828a22 100644
--- a/src/p_spec.c
+++ b/src/p_spec.c
@@ -4087,8 +4087,10 @@ void P_SetupSignExit(player_t *player)
 		if (thing->type != MT_SIGN)
 			continue;
 
-		if (!player->mo->target || player->mo->target->type != MT_SIGN)
-			P_SetTarget(&player->mo->target, thing);
+		if (!numfound
+			&& !(player->mo->target && player->mo->target->type == MT_SIGN)
+			&& !(gametype == GT_COOP && (netgame || multiplayer) && cv_exitmove.value))
+				P_SetTarget(&player->mo->target, thing);
 
 		if (thing->state != &states[thing->info->spawnstate])
 			continue;
@@ -4116,8 +4118,10 @@ void P_SetupSignExit(player_t *player)
 		if (thing->type != MT_SIGN)
 			continue;
 
-		if (!player->mo->target || player->mo->target->type != MT_SIGN)
-			P_SetTarget(&player->mo->target, thing);
+		if (!numfound
+			&& !(player->mo->target && player->mo->target->type == MT_SIGN)
+			&& !(gametype == GT_COOP && (netgame || multiplayer) && cv_exitmove.value))
+				P_SetTarget(&player->mo->target, thing);
 
 		if (thing->state != &states[thing->info->spawnstate])
 			continue;
diff --git a/src/p_user.c b/src/p_user.c
index fc569ada74ced2ef8d0ff7c6eec04d81d36d9fc2..ac2ba9e53d5411be3d9620c52062871df5e3d143 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -9681,7 +9681,8 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
 	if (player->exiting)
 	{
 		if (mo->target && mo->target->type == MT_SIGN && mo->target->spawnpoint
-		&& !(gametype == GT_COOP && (netgame || multiplayer) && cv_exitmove.value))
+		&& !(gametype == GT_COOP && (netgame || multiplayer) && cv_exitmove.value)
+		&& !(twodlevel || (mo->flags2 & MF2_TWOD)))
 			sign = mo->target;
 		else if ((player->powers[pw_carry] == CR_NIGHTSMODE)
 		&& !(player->mo->state >= &states[S_PLAY_NIGHTS_TRANS1]
@@ -9692,7 +9693,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
 		}
 	}
 
-	cameranoclip = (player->powers[pw_carry] == CR_NIGHTSMODE || player->pflags & PF_NOCLIP) || (mo->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)); // Noclipping player camera noclips too!!
+	cameranoclip = (sign || player->powers[pw_carry] == CR_NIGHTSMODE || player->pflags & PF_NOCLIP) || (mo->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)); // Noclipping player camera noclips too!!
 
 	if (!(player->climbing || (player->powers[pw_carry] == CR_NIGHTSMODE) || player->playerstate == PST_DEAD || tutorialmode))
 	{
@@ -9825,7 +9826,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
 				angle = R_PointToAngle2(mo->x, mo->y, mo->target->x, mo->target->y);
 		}
 	}
-	else if (P_AnalogMove(player)) // Analog
+	else if (P_AnalogMove(player) && !sign) // Analog
 		angle = R_PointToAngle2(thiscam->x, thiscam->y, mo->x, mo->y);
 	else if (demoplayback)
 	{
@@ -9849,7 +9850,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
 		thiscam->angle = angle;
 	}
 
-	if ((((thiscam == &camera) && cv_analog.value) || ((thiscam != &camera) && cv_analog2.value) || demoplayback) && !objectplacing && !(twodlevel || (mo->flags2 & MF2_TWOD)) && (player->powers[pw_carry] != CR_NIGHTSMODE) && displayplayer == consoleplayer)
+	if ((((thiscam == &camera) && cv_analog.value) || ((thiscam != &camera) && cv_analog2.value) || demoplayback) && !sign && !objectplacing && !(twodlevel || (mo->flags2 & MF2_TWOD)) && (player->powers[pw_carry] != CR_NIGHTSMODE) && displayplayer == consoleplayer)
 	{
 #ifdef REDSANALOG
 		if ((player->cmd.buttons & (BT_CAMLEFT|BT_CAMRIGHT)) == (BT_CAMLEFT|BT_CAMRIGHT)); else
@@ -9887,24 +9888,22 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
 			camheight = FixedMul(camheight, 3*FRACUNIT/2);
 		}
 
-		// x1.2 dist for analog
-		if (P_AnalogMove(player))
-		{
-			dist = FixedMul(dist, 6*FRACUNIT/5);
-			camheight = FixedMul(camheight, 6*FRACUNIT/5);
-		}
-
-		if (sign)
+		if (sign) // signpost camera has specific placement
 		{
 			camheight = mo->scale << 7;
 			camspeed = FRACUNIT/12;
 		}
+		else if (P_AnalogMove(player)) // x1.2 dist for analog
+		{
+			dist = FixedMul(dist, 6*FRACUNIT/5);
+			camheight = FixedMul(camheight, 6*FRACUNIT/5);
+		}
 
 		if (player->climbing || player->exiting || player->playerstate == PST_DEAD || (player->powers[pw_carry] == CR_ROPEHANG || player->powers[pw_carry] == CR_GENERIC || player->powers[pw_carry] == CR_MACESPIN))
 			dist <<= 1;
 	}
 
-	if (!(twodlevel || (mo->flags2 & MF2_TWOD)) && !(player->powers[pw_carry] == CR_NIGHTSMODE))
+	if (!sign && !(twodlevel || (mo->flags2 & MF2_TWOD)) && !(player->powers[pw_carry] == CR_NIGHTSMODE))
 		dist = FixedMul(dist, player->camerascale);
 
 	checkdist = dist;
@@ -9994,7 +9993,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
 
 	if (sign)
 	{
-		if (mo->eflags & MFE_VERTICALFLIP)
+		if (sign->eflags & MFE_VERTICALFLIP)
 			z = sign->ceilingz - pviewheight - camheight;
 		else
 			z = sign->floorz + pviewheight + camheight;