diff --git a/src/am_map.c b/src/am_map.c
index 331d1a5e0db4c669791b71f2984dfe208598b8f4..df3a45cfff504e046ddaa6ecc03cf9f9d548e45f 100644
--- a/src/am_map.c
+++ b/src/am_map.c
@@ -1071,7 +1071,6 @@ static inline void AM_drawPlayers(void)
 		return;
 	}
 
-	// multiplayer (how??)
 	for (i = 0; i < MAXPLAYERS; i++)
 	{
 		if (!playeringame[i] || players[i].spectator)
diff --git a/src/d_netcmd.c b/src/d_netcmd.c
index ede51e84ae77d79e704dac6043914f63de0415ea..2478e1f12ed3fce5630de7bdc9ff3683ff757352 100644
--- a/src/d_netcmd.c
+++ b/src/d_netcmd.c
@@ -1221,13 +1221,6 @@ static void SendNameAndColor(void)
 
 	p = buf;
 
-	// normal player colors
-	if (G_GametypeHasTeams())
-	{
-		if (players[consoleplayer].ctfteam != 0 && cv_playercolor.value != G_GetTeamColor(players[consoleplayer].ctfteam))
-			CV_StealthSetValue(&cv_playercolor, G_GetTeamColor(players[consoleplayer].ctfteam));
-	}
-
 	// don't allow inaccessible colors
 	if (!skincolors[cv_playercolor.value].accessible)
 	{
@@ -1353,13 +1346,6 @@ static void SendNameAndColor2(void)
 	else // HACK
 		secondplaya = 1;
 
-	// normal player colors
-	if (G_GametypeHasTeams())
-	{
-		if (players[secondplaya].ctfteam != 0 && cv_playercolor2.value != G_GetTeamColor(players[secondplaya].ctfteam))
-			CV_StealthSetValue(&cv_playercolor2, G_GetTeamColor(players[secondplaya].ctfteam));
-	}
-
 	// don't allow inaccessible colors
 	if (!skincolors[cv_playercolor2.value].accessible)
 	{
@@ -1482,7 +1468,7 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
 	// set color
 	p->skincolor = color % numskincolors;
 	if (p->mo)
-		p->mo->color = (UINT16)p->skincolor;
+		p->mo->color = P_GetPlayerColor(p);
 
 	// normal player colors
 	if (server && (p != &players[consoleplayer] && p != &players[secondarydisplayplayer]))
@@ -1491,13 +1477,6 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
 		UINT32 unlockShift = 0;
 		UINT32 i;
 
-		// team colors
-		if (G_GametypeHasTeams())
-		{
-			if (p->ctfteam != 0 && p->skincolor != G_GetTeamColor(p->ctfteam))
-				kick = true;
-		}
-
 		// don't allow inaccessible colors
 		if (skincolors[p->skincolor].accessible == false)
 			kick = true;
@@ -2962,17 +2941,6 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
 		displayplayer = consoleplayer;
 	}
 
-	if (G_GametypeHasTeams())
-	{
-		if (players[playernum].ctfteam)
-		{
-			if (playernum == consoleplayer) //CTF and Team Match colors.
-				CV_SetValue(&cv_playercolor, G_GetTeamColor(players[playernum].ctfteam));
-			else if (playernum == secondarydisplayplayer)
-				CV_SetValue(&cv_playercolor2, G_GetTeamColor(players[playernum].ctfteam));
-		}
-	}
-
 	// In tag, check to see if you still have a game.
 	if (G_TagGametype())
 		P_CheckSurvivors();
diff --git a/src/g_game.c b/src/g_game.c
index 66123176763b01e16289c566711166ff36de7bab..cc9767bed4e9c4c698df49364a64dcd84debe643 100644
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -2745,18 +2745,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
 	//if ((netgame || multiplayer) && !p->spectator) -- moved into P_SpawnPlayer to account for forced changes there
 		//p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent
 
-	// Check to make sure their color didn't change somehow...
-	if (G_GametypeHasTeams())
-	{
-		if (p->ctfteam != 0 && p->skincolor != G_GetTeamColor(p->ctfteam))
-		{
-			if (p == &players[consoleplayer])
-				CV_SetValue(&cv_playercolor, G_GetTeamColor(p->ctfteam));
-			else if (p == &players[secondarydisplayplayer])
-				CV_SetValue(&cv_playercolor2, G_GetTeamColor(p->ctfteam));
-		}
-	}
-
 	if (betweenmaps)
 		return;
 
diff --git a/src/p_enemy.c b/src/p_enemy.c
index a9669371a048bcb5dd670a62ecccd6f3c5e068e8..318a9e974618f534650a269a279a8036a9161894 100644
--- a/src/p_enemy.c
+++ b/src/p_enemy.c
@@ -5248,7 +5248,7 @@ void A_SignPlayer(mobj_t *actor)
 			return;
 
 		skin = &skins[actor->target->player->skin];
-		facecolor = actor->target->player->skincolor;
+		facecolor = P_GetPlayerColor(actor->target->player);
 
 		if (signcolor)
 			;
@@ -9059,7 +9059,7 @@ void A_Dye(mobj_t *actor)
 	if (!color)
 	{
 		target->colorized = false;
-		target->color = target->player ? target->player->skincolor : SKINCOLOR_NONE;
+		target->color = target->player ? P_GetPlayerColor(target->player) : SKINCOLOR_NONE;
 	}
 	else if (!(target->player))
 	{
diff --git a/src/p_inter.c b/src/p_inter.c
index d2087c5b23ae1a203f2dc54a7f197a0055b1b02e..1959595ecdac57159cd7cd270805850c299104bc 100644
--- a/src/p_inter.c
+++ b/src/p_inter.c
@@ -2632,7 +2632,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
 			}
 		}
 
-		target->color = target->player->skincolor;
+		target->color = P_GetPlayerColor(target->player);
 		target->colorized = false;
 		G_GhostAddColor(GHC_NORMAL);
 
@@ -3325,7 +3325,7 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
 
 	// Get rid of shield
 	player->powers[pw_shield] = SH_NONE;
-	player->mo->color = player->skincolor;
+	player->mo->color = P_GetPlayerColor(player);
 
 	// Get rid of emeralds
 	player->powers[pw_emeralds] = 0;
@@ -3442,7 +3442,7 @@ void P_RemoveShield(player_t *player)
 	{ // Second layer shields
 		if (((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER) && !(player->powers[pw_super] || (mariomode && player->powers[pw_invulnerability])))
 		{
-			player->mo->color = player->skincolor;
+			player->mo->color = P_GetPlayerColor(player);
 			G_GhostAddColor(GHC_NORMAL);
 		}
 		player->powers[pw_shield] = SH_NONE;
diff --git a/src/p_local.h b/src/p_local.h
index 3bc35e50d935ca7616a9cba1d0838654feb9a800..f0b0a86e24efd92c503901f678dd216e52d8d65e 100644
--- a/src/p_local.h
+++ b/src/p_local.h
@@ -147,6 +147,7 @@ boolean P_PlayerFullbright(player_t *player);
 boolean P_PlayerCanEnterSpinGaps(player_t *player);
 boolean P_PlayerShouldUseSpinHeight(player_t *player);
 boolean P_PlayerHasTeamFlag(player_t *player, UINT8 team);
+UINT16 P_GetPlayerColor(player_t *player);
 
 boolean P_IsObjectInGoop(mobj_t *mo);
 boolean P_IsObjectOnGround(mobj_t *mo);
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 3461395355744adaa77e64b676c9f87b4de93171..336e7759332bebc02c4e57a364ac7cd802bb1d5f 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -11557,7 +11557,6 @@ void P_SpawnPlayer(INT32 playernum)
 				// Spawn as a spectator,
 				// yes even in splitscreen mode
 				p->spectator = true;
-				p->skincolor = teams[newteam].color;
 
 				// but immediately send a team change packet.
 				NetPacket.packet.playernum = playernum;
@@ -11582,11 +11581,6 @@ void P_SpawnPlayer(INT32 playernum)
 			else
 				p->ctfteam = 1;
 		}
-
-		// Fix team colors.
-		// This code isn't being done right somewhere else. Oh well.
-		if (p->ctfteam != 0)
-			p->skincolor = G_GetTeamColor(p->ctfteam);
 	}
 
 	if ((netgame || multiplayer) && ((gametyperules & GTR_SPAWNINVUL) || leveltime) && !p->spectator && !(maptol & TOL_NIGHTS))
@@ -11598,7 +11592,7 @@ void P_SpawnPlayer(INT32 playernum)
 	mobj->angle = 0;
 
 	// set color translations for player sprites
-	mobj->color = p->skincolor;
+	mobj->color = P_GetPlayerColor(p);
 
 	// set 'spritedef' override in mobj for player skins.. (see ProjectSprite)
 	// (usefulness: when body mobj is detached from player (who respawns),
diff --git a/src/p_user.c b/src/p_user.c
index e92fb15f22336b1e379e68f5aac7cbcfa63faade..74c3cf898470c627aefe40ba05e663c9d045384a 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -686,7 +686,7 @@ static void P_DeNightserizePlayer(player_t *player)
 
 	player->mo->skin = &skins[player->skin];
 	player->followitem = skins[player->skin].followitem;
-	player->mo->color = player->skincolor;
+	player->mo->color = P_GetPlayerColor(player);
 	G_GhostAddColor(GHC_RETURNSKIN);
 
 	// Restore aiming angle
@@ -3023,7 +3023,7 @@ static void P_CheckInvincibilityTimer(player_t *player)
 				}
 				else
 				{
-					player->mo->color = player->skincolor;
+					player->mo->color = P_GetPlayerColor(player);
 					G_GhostAddColor(GHC_NORMAL);
 				}
 			}
@@ -4300,7 +4300,7 @@ static void P_DoSuperStuff(player_t *player)
 			}
 			else
 			{
-				player->mo->color = player->skincolor;
+				player->mo->color = P_GetPlayerColor(player);
 				G_GhostAddColor(GHC_NORMAL);
 			}
 
@@ -4350,7 +4350,7 @@ static void P_DoSuperStuff(player_t *player)
 			}
 			else
 			{
-				player->mo->color = player->skincolor;
+				player->mo->color = P_GetPlayerColor(player);
 				G_GhostAddColor(GHC_NORMAL);
 			}
 
@@ -13094,3 +13094,15 @@ boolean P_PlayerHasTeamFlag(player_t *player, UINT8 team)
 
 	return player->gotflag & teams[team].flag;
 }
+
+UINT16 P_GetPlayerColor(player_t *player)
+{
+	if (G_GametypeHasTeams() && player->ctfteam)
+	{
+		UINT16 skincolor = G_GetTeamColor(player->ctfteam);
+		if (skincolor != SKINCOLOR_NONE)
+			return skincolor;
+	}
+
+	return player->skincolor;
+}
diff --git a/src/st_stuff.c b/src/st_stuff.c
index 42bfda9d1affabae001ef71f8cdd39ad5c521c64..aad5b506d7267bbcb524aeb5b662c69f7d6e7408 100644
--- a/src/st_stuff.c
+++ b/src/st_stuff.c
@@ -843,6 +843,8 @@ static void ST_drawLivesArea(void)
 	V_DrawSmallScaledPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y,
 		hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, livesback);
 
+	UINT16 facecolor = P_GetPlayerColor(stplyr);
+
 	// face
 	if (stplyr->spectator)
 	{
@@ -872,10 +874,10 @@ static void ST_drawLivesArea(void)
 			}
 		}
 	}
-	else if (stplyr->skincolor)
+	else if (facecolor)
 	{
 		// skincolor face
-		UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, stplyr->skincolor, GTC_CACHE);
+		UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, facecolor, GTC_CACHE);
 		V_DrawSmallMappedPatch(hudinfo[HUD_LIVES].x, hudinfo[HUD_LIVES].y,
 			hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, faceprefix[stplyr->skin], colormap);
 	}
@@ -1038,7 +1040,8 @@ static void ST_drawLivesArea(void)
 
 static void ST_drawInput(void)
 {
-	const INT32 accent = V_SNAPTOLEFT|V_SNAPTOBOTTOM|(stplyr->skincolor ? skincolors[stplyr->skincolor].ramp[4] : 0);
+	UINT16 color = P_GetPlayerColor(stplyr);
+	const INT32 accent = V_SNAPTOLEFT|V_SNAPTOBOTTOM|(color ? skincolors[color].ramp[4] : 0);
 	INT32 col;
 	UINT8 offs;