diff --git a/src/p_enemy.c b/src/p_enemy.c index 859702b4c..d96dfac73 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 7c45fe06d..14455b926 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3142,6 +3142,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, @@ -3154,31 +3156,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) @@ -3190,9 +3180,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 @@ -3246,24 +3236,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; } } @@ -3277,16 +3263,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) @@ -3539,16 +3519,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 a114d43c6..bcd47b1f8 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -169,6 +169,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 74c3cf898..0d40625c0 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1950,6 +1950,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 9443ad49b..b712975bf 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -326,7 +326,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;