diff --git a/src/d_player.h b/src/d_player.h
index f1d4d4395f47ac65cb21d6678ea1a27b0e107ed7..620b698c79bbec15504a6e31d2a0fac89c78a4fe 100644
--- a/src/d_player.h
+++ b/src/d_player.h
@@ -150,6 +150,9 @@ typedef enum
 	PF_FORCESTRAFE       = 1<<25, // Turning inputs are translated into strafing inputs
 	PF_ANALOGMODE        = 1<<26, // Analog mode?
 
+	// Can carry another player?
+	PF_CANCARRY          = 1<<27
+
 	// free up to and including 1<<31
 } pflags_t;
 
diff --git a/src/p_map.c b/src/p_map.c
index 63ba258f9dc566e8c0adc3fad6ede0bc5c52d6c9..765f88a7dfb44a41ee31ae9e00f3ac1232e27d1f 100644
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -302,15 +302,17 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails)
 	INT32 p;
 	fixed_t zdist; // z distance between the two players' bottoms
 
-	if (tails->powers[pw_carry])// && tails->mo->tracer == sonic->mo) <-- why was this here?
+	if (tails->powers[pw_carry])
 		return;
 	if (sonic->powers[pw_carry])
 		return;
 
-	if (tails->charability != CA_FLY && tails->charability != CA_SWIM)
+	if (tails->spectator)
+		return;
+	if (sonic->spectator)
 		return;
 
-	if (!tails->powers[pw_tailsfly] && tails->mo->state-states != S_PLAY_FLY_TIRED)
+	if (!(tails->pflags & PF_CANCARRY))
 		return;
 
 	if (tails->bot == 1)
@@ -336,39 +338,35 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails)
 		&& players[p].powers[pw_carry] == CR_PLAYER && players[p].mo->tracer == tails->mo)
 			return;
 
+	// Why block opposing teams from tailsflying each other?
+	// Sneaking into the hands of a flying tails player in Race might be a viable strategy, who knows.
+	/*
+	if (gametype == GT_RACE || gametype == GT_COMPETITION
+		|| (netgame && (tails->spectator || sonic->spectator))
+		|| (G_TagGametype() && (!(tails->pflags & PF_TAGIT) != !(sonic->pflags & PF_TAGIT)))
+		|| (gametype == GT_MATCH)
+		|| (G_GametypeHasTeams() && tails->ctfteam != sonic->ctfteam))
+		return; */
+
 	if (tails->mo->eflags & MFE_VERTICALFLIP)
 		zdist = (sonic->mo->z + sonic->mo->height) - (tails->mo->z + tails->mo->height);
 	else
 		zdist = tails->mo->z - sonic->mo->z;
 
-	if (zdist <= sonic->mo->height + FixedMul(FRACUNIT, sonic->mo->scale)
+	if (zdist <= sonic->mo->height + sonic->mo->scale // FixedMul(FRACUNIT, sonic->mo->scale), but scale == FRACUNIT by default
 		&& zdist > sonic->mo->height*2/3
 		&& P_MobjFlip(tails->mo)*sonic->mo->momz <= 0)
 	{
-	// Why block opposing teams from tailsflying each other?
-		// Sneaking into the hands of a flying tails player in Race might be a viable strategy, who knows.
-		/*
-		if (gametype == GT_RACE || gametype == GT_COMPETITION
-			|| (netgame && (tails->spectator || sonic->spectator))
-			|| (G_TagGametype() && (!(tails->pflags & PF_TAGIT) != !(sonic->pflags & PF_TAGIT)))
-			|| (gametype == GT_MATCH)
-			|| (G_GametypeHasTeams() && tails->ctfteam != sonic->ctfteam))
-			sonic->powers[pw_carry] = CR_NONE; */
-		if (tails->spectator || sonic->spectator)
-			sonic->powers[pw_carry] = CR_NONE;
-		else
-		{
-			if (sonic-players == consoleplayer && botingame)
-				CV_SetValue(&cv_analog2, false);
-			P_ResetPlayer(sonic);
-			P_SetTarget(&sonic->mo->tracer, tails->mo);
-			sonic->powers[pw_carry] = CR_PLAYER;
-			S_StartSound(sonic->mo, sfx_s3k4a);
-			P_UnsetThingPosition(sonic->mo);
-			sonic->mo->x = tails->mo->x;
-			sonic->mo->y = tails->mo->y;
-			P_SetThingPosition(sonic->mo);
-		}
+		if (sonic-players == consoleplayer && botingame)
+			CV_SetValue(&cv_analog2, false);
+		P_ResetPlayer(sonic);
+		P_SetTarget(&sonic->mo->tracer, tails->mo);
+		sonic->powers[pw_carry] = CR_PLAYER;
+		S_StartSound(sonic->mo, sfx_s3k4a);
+		P_UnsetThingPosition(sonic->mo);
+		sonic->mo->x = tails->mo->x;
+		sonic->mo->y = tails->mo->y;
+		P_SetThingPosition(sonic->mo);
 	}
 	else {
 		if (sonic-players == consoleplayer && botingame)
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 86001388b0ffca86e0762458de21575c2cb46601..f2ef4dc0da7379e9211371be39adfada343f2cc0 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -3188,8 +3188,7 @@ static void P_PlayerZMovement(mobj_t *mo)
 
 					if (!(mo->player->pflags & PF_GLIDING))
 						mo->player->pflags &= ~PF_JUMPED;
-					mo->player->pflags &= ~PF_THOKKED;
-					//mo->player->pflags &= ~PF_GLIDING;
+					mo->player->pflags &= ~(PF_THOKKED|PF_CANCARRY/*|PF_GLIDING*/);
 					mo->player->jumping = 0;
 					mo->player->secondjump = 0;
 					mo->player->glidetime = 0;
diff --git a/src/p_spec.c b/src/p_spec.c
index 9fc20b83f2a66c82fbf6c463829901fb9867d03d..ed2ff055cc1d2b2f98148dfcae64a601cc7cfe56 100644
--- a/src/p_spec.c
+++ b/src/p_spec.c
@@ -3941,8 +3941,7 @@ DoneSection2:
 				player->powers[pw_carry] = CR_ZOOMTUBE;
 				player->speed = speed;
 				player->pflags |= PF_SPINNING;
-				player->pflags &= ~PF_JUMPED;
-				player->pflags &= ~PF_GLIDING;
+				player->pflags &= ~(PF_JUMPED|PF_GLIDING|PF_SLIDING|PF_CANCARRY);
 				player->climbing = 0;
 
 				if (player->mo->state-states != S_PLAY_SPIN)
@@ -4016,7 +4015,7 @@ DoneSection2:
 				player->powers[pw_carry] = CR_ZOOMTUBE;
 				player->speed = speed;
 				player->pflags |= PF_SPINNING;
-				player->pflags &= ~PF_JUMPED;
+				player->pflags &= ~(PF_JUMPED|PF_GLIDING|PF_SLIDING|PF_CANCARRY);
 
 				if (player->mo->state-states != S_PLAY_SPIN)
 				{
@@ -4317,9 +4316,7 @@ DoneSection2:
 
 				S_StartSound(player->mo, sfx_s3k4a);
 
-				player->pflags &= ~PF_JUMPED;
-				player->pflags &= ~PF_GLIDING;
-				player->pflags &= ~PF_SLIDING;
+				player->pflags &= ~(PF_JUMPED|PF_GLIDING|PF_SLIDING|PF_CANCARRY);
 				player->climbing = 0;
 				P_SetThingPosition(player->mo);
 				P_SetPlayerMobjState(player->mo, S_PLAY_RIDE);
diff --git a/src/p_user.c b/src/p_user.c
index 53c59d072663b0f5f906393608fd82ef496325bf..0b653b24c8f7959e88fc0d4d85e8caa0f5632f87 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -900,7 +900,7 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor)
 // Useful when you want to kill everything the player is doing.
 void P_ResetPlayer(player_t *player)
 {
-	player->pflags &= ~(PF_SPINNING|PF_STARTDASH|PF_JUMPED|PF_GLIDING|PF_THOKKED);
+	player->pflags &= ~(PF_SPINNING|PF_STARTDASH|PF_JUMPED|PF_GLIDING|PF_THOKKED|PF_CANCARRY);
 	player->powers[pw_carry] = CR_NONE;
 	player->jumping = 0;
 	player->secondjump = 0;
@@ -4107,7 +4107,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
 						player->powers[pw_tailsfly] = tailsflytics + 1; // Set the fly timer
 
 						player->pflags &= ~(PF_JUMPED|PF_SPINNING|PF_STARTDASH);
-						player->pflags |= PF_THOKKED;
+						player->pflags |= PF_THOKKED|PF_CANCARRY;
 					}
 					break;
 				case CA_GLIDEANDCLIMB:
@@ -7253,7 +7253,7 @@ static void P_DoZoomTube(player_t *player)
 		}
 		else
 		{
-			P_SetTarget(&player->mo->tracer, NULL); // Else, we just let him fly.
+			P_SetTarget(&player->mo->tracer, NULL); // Else, we just let them fly.
 			player->powers[pw_carry] = CR_NONE;
 
 			CONS_Debug(DBG_GAMELOGIC, "Next waypoint not found, releasing from track...\n");
@@ -9420,11 +9420,7 @@ void P_PlayerAfterThink(player_t *player)
 	{
 		player->mo->height = FixedDiv(P_GetPlayerHeight(player), FixedDiv(14*FRACUNIT,10*FRACUNIT));
 
-		if (player->mo->tracer->player
-			// && !player->mo->tracer->player->powers[pw_tailsfly] -- race hazard - pw_tailsfly gets set to 0 a tic before the state switch to S_PLAY_FLY_TIRED...
-			&& player->mo->tracer->state-states != S_PLAY_FLY
-			&& player->mo->tracer->state-states != S_PLAY_SWIM
-			&& player->mo->tracer->state-states != S_PLAY_FLY_TIRED)
+		if (player->mo->tracer->player && !(player->mo->tracer->player->pflags & PF_CANCARRY))
 				player->powers[pw_carry] = CR_NONE;
 
 		if (player->mo->eflags & MFE_VERTICALFLIP)