diff --git a/src/p_enemy.c b/src/p_enemy.c
index 859702b4c2d207870ea1e66d0adf34601aa13fe1..d96dfac731fab6d62d30bd70ee446b21dcbb7a7a 100644
--- a/src/p_enemy.c
+++ b/src/p_enemy.c
@@ -7062,7 +7062,7 @@ void A_RecyclePowers(mobj_t *actor)
 		players[recv_pl].ringweapons = weapons[send_pl];
 		players[recv_pl].currentweapon = weaponheld[send_pl];
 
-		if (((players[recv_pl].powers[pw_shield] & SH_NOSTACK) == SH_PINK) && (players[recv_pl].revitem == MT_LHRT || players[recv_pl].spinitem == MT_LHRT || players[recv_pl].thokitem == MT_LHRT)) // Healers can't keep their buff.
+		if (((players[recv_pl].powers[pw_shield] & SH_NOSTACK) == SH_PINK) && P_IsPlayerHealer(&players[recv_pl])) // Healers can't keep their buff.
 			players[recv_pl].powers[pw_shield] &= SH_STACK;
 
 		P_SpawnShieldOrb(&players[recv_pl]);
diff --git a/src/p_inter.c b/src/p_inter.c
index 5cf55ce0562b117af1abe20416352f216dd347e3..62eea89798055a5512cc96453553efc469217c5a 100644
--- a/src/p_inter.c
+++ b/src/p_inter.c
@@ -3145,6 +3145,8 @@ static void P_NiGHTSDamage(mobj_t *target, mobj_t *source)
 static boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype)
 {
 	player_t *player = target->player;
+	player_t *other_player = source->player; // Player is assumed to exist
+
 	(void)damage; //unused parm
 
 	// If flashing or invulnerable, ignore the tag,
@@ -3157,31 +3159,19 @@ static boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, IN
 
 	// Ignore IT players shooting each other, unless friendlyfire is on.
 	if ((player->pflags & PF_TAGIT && !((cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE) || (damagetype & DMG_CANHURTSELF)) &&
-		source && source->player && source->player->pflags & PF_TAGIT)))
+		other_player->pflags & PF_TAGIT)))
 	{
-		if (inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK))
-		{
-			if (player->revitem != MT_LHRT && player->spinitem != MT_LHRT && player->thokitem != MT_LHRT) // Healers do not get to heal other healers.
-			{
-				P_SwitchShield(player, SH_PINK);
-				S_StartSound(target, mobjinfo[MT_PITY_ICON].seesound);
-			}
-		}
+		if (P_CanHealPlayer(player, other_player, inflictor))
+			P_DoPlayerHeal(player);
 		return false;
 	}
 
 	// Don't allow players on the same team to hurt one another,
 	// unless cv_friendlyfire is on.
-	if (!(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE) || (damagetype & DMG_CANHURTSELF)) && (player->pflags & PF_TAGIT) == (source->player->pflags & PF_TAGIT))
+	if (!(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE) || (damagetype & DMG_CANHURTSELF)) && (player->pflags & PF_TAGIT) == (other_player->pflags & PF_TAGIT))
 	{
-		if (inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK))
-		{
-			if (player->revitem != MT_LHRT && player->spinitem != MT_LHRT && player->thokitem != MT_LHRT) // Healers do not get to heal other healers.
-			{
-				P_SwitchShield(player, SH_PINK);
-				S_StartSound(target, mobjinfo[MT_PITY_ICON].seesound);
-			}
-		}
+		if (P_CanHealPlayer(player, other_player, inflictor))
+			P_DoPlayerHeal(player);
 		else if (!(inflictor->flags & MF_FIRE))
 			P_GivePlayerRings(player, 1);
 		if (inflictor->flags2 & MF2_BOUNCERING)
@@ -3193,9 +3183,9 @@ static boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, IN
 		return false;
 
 	// The tag occurs so long as you aren't shooting another tagger with friendlyfire on.
-	if (source->player->pflags & PF_TAGIT && !(player->pflags & PF_TAGIT))
+	if (other_player->pflags & PF_TAGIT && !(player->pflags & PF_TAGIT))
 	{
-		P_AddPlayerScore(source->player, 100); //award points to tagger.
+		P_AddPlayerScore(other_player, 100); //award points to tagger.
 		P_HitDeathMessages(player, inflictor, source, 0);
 
 		if (!(gametyperules & GTR_HIDEFROZEN)) //survivor
@@ -3249,24 +3239,20 @@ static boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, IN
 static boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype)
 {
 	player_t *player = target->player;
+	player_t *other_player = source->player; // Player is assumed to exist
 
 	if (!(damagetype & DMG_CANHURTSELF))
 	{
-		// You can't kill yourself, idiot...
+		// Can't hurt yourself (or other players in Co-Op) without DMG_CANHURTSELF
 		if (source == target)
 			return false;
 
-		// In COOP/RACE, you can't hurt other players unless cv_friendlyfire is on
+		// In Co-Op/Race, you can't hurt other players unless cv_friendlyfire is on
 		if (!(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE)) && (gametyperules & GTR_FRIENDLY))
 		{
-			if ((gametyperules & GTR_FRIENDLY) && inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK)) // co-op only
-			{
-				if (player->revitem != MT_LHRT && player->spinitem != MT_LHRT && player->thokitem != MT_LHRT) // Healers do not get to heal other healers.
-				{
-					P_SwitchShield(player, SH_PINK);
-					S_StartSound(target, mobjinfo[MT_PITY_ICON].seesound);
-				}
-			}
+			// co-op only
+			if ((gametyperules & GTR_FRIENDLY) && P_CanHealPlayer(player, other_player, inflictor))
+				P_DoPlayerHeal(player);
 			return false;
 		}
 	}
@@ -3280,16 +3266,10 @@ static boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *sou
 	{
 		// Don't allow players on the same team to hurt one another,
 		// unless cv_friendlyfire is on.
-		if (!(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE)) && target->player->ctfteam == source->player->ctfteam)
+		if (!(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE)) && target->player->ctfteam == other_player->ctfteam)
 		{
-			if (inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK))
-			{
-				if (player->revitem != MT_LHRT && player->spinitem != MT_LHRT && player->thokitem != MT_LHRT) // Healers do not get to heal other healers.
-				{
-					P_SwitchShield(player, SH_PINK);
-					S_StartSound(target, mobjinfo[MT_PITY_ICON].seesound);
-				}
-			}
+			if (P_CanHealPlayer(player, other_player, inflictor))
+				P_DoPlayerHeal(player);
 			else if (!(inflictor->flags & MF_FIRE))
 				P_GivePlayerRings(target->player, 1);
 			if (inflictor->flags2 & MF2_BOUNCERING)
@@ -3542,16 +3522,12 @@ void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source)
 	if (player->powers[pw_invulnerability] || player->powers[pw_flashing] || player->powers[pw_super])
 		return;
 
-	if (!cv_friendlyfire.value && source && source->player)
+	player_t *other_player = (source && source->player) ? source->player : NULL;
+
+	if (!cv_friendlyfire.value && other_player)
 	{
-		if (inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK))
-		{
-			if (player->revitem != MT_LHRT && player->spinitem != MT_LHRT && player->thokitem != MT_LHRT) // Healers do not get to heal other healers.
-			{
-				P_SwitchShield(player, SH_PINK);
-				S_StartSound(player->mo, mobjinfo[MT_PITY_ICON].seesound);
-			}
-		}
+		if (P_CanHealPlayer(player, other_player, inflictor))
+			P_DoPlayerHeal(player);
 
 		if (source->player->ctfteam == player->ctfteam)
 			return;
diff --git a/src/p_local.h b/src/p_local.h
index e6c90b0d1ff3b53b98f74298e4a50b386343c5dd..84e277af2ca13c584542446bb36eb36811ae81a4 100644
--- a/src/p_local.h
+++ b/src/p_local.h
@@ -159,6 +159,10 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff);
 void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative);
 void P_RestoreMusic(player_t *player);
 void P_SetPower(player_t *player, powertype_t power, UINT16 value);
+boolean P_IsPlayerHealer(player_t *player);
+boolean P_IsHealerProjectile(player_t *healer, mobj_t *projectile);
+boolean P_CanHealPlayer(player_t *player, player_t *healer, mobj_t *projectile);
+void P_DoPlayerHeal(player_t *player);
 void P_SpawnShieldOrb(player_t *player);
 void P_SwitchShield(player_t *player, UINT16 shieldtype);
 mobj_t *P_SpawnGhostMobj(mobj_t *mobj);
diff --git a/src/p_user.c b/src/p_user.c
index d0b983a84e4a45b1cb3b644c8ee700b05184c960..f7b12f4ae19719c7bc33cb034118183a67f29cc4 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -1952,6 +1952,32 @@ void P_SetPower(player_t *player, powertype_t power, UINT16 value)
 		P_SpawnShieldOrb(player);
 }
 
+boolean P_IsPlayerHealer(player_t *player)
+{
+	return player->revitem == MT_LHRT || player->spinitem == MT_LHRT || player->thokitem == MT_LHRT;
+}
+
+boolean P_IsHealerProjectile(player_t *healer, mobj_t *projectile)
+{
+	(void)healer;
+	return projectile->type == MT_LHRT;
+}
+
+boolean P_CanHealPlayer(player_t *player, player_t *healer, mobj_t *projectile)
+{
+	return P_IsHealerProjectile(healer, projectile) && !(player->powers[pw_shield] & SH_NOSTACK);
+}
+
+void P_DoPlayerHeal(player_t *player)
+{
+	// Healers do not get to heal other healers.
+	if (P_IsPlayerHealer(player))
+		return;
+
+	P_SwitchShield(player, SH_PINK);
+	S_StartSound(player->mo, mobjinfo[MT_PITY_ICON].seesound);
+}
+
 //
 // P_SpawnGhostMobj
 //
diff --git a/src/r_skins.c b/src/r_skins.c
index 308cee8d6050496b361385c0595334b647927ee1..b15d7df318ad4bb54aff64f5828d3b5d9d832650 100644
--- a/src/r_skins.c
+++ b/src/r_skins.c
@@ -342,7 +342,7 @@ static void SetSkin(player_t *player, INT32 skinnum)
 	player->revitem = skin->revitem < 0 ? (mobjtype_t)mobjinfo[MT_PLAYER].raisestate : (UINT32)skin->revitem;
 	player->followitem = skin->followitem;
 
-	if (((player->powers[pw_shield] & SH_NOSTACK) == SH_PINK) && (player->revitem == MT_LHRT || player->spinitem == MT_LHRT || player->thokitem == MT_LHRT)) // Healers can't keep their buff.
+	if (((player->powers[pw_shield] & SH_NOSTACK) == SH_PINK) && P_IsPlayerHealer(player)) // Healers can't keep their buff.
 		player->powers[pw_shield] &= SH_STACK;
 
 	player->actionspd = skin->actionspd;