P_PlayerCanHurtPlayer()

This commit is contained in:
Arthur 2024-02-15 23:00:35 -05:00
parent 2db0dc3ad9
commit 398b5a1840
3 changed files with 63 additions and 1 deletions

View file

@ -3279,6 +3279,67 @@ static boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, IN
return true;
}
//
// P_PlayerCanHurtPlayer
//
// Is it permissible for a player to hurt another player?
// This should be the definitive global function to determine if pain is allowed. :)
//
boolean P_PlayerCanHurtPlayer(player_t *target, mobj_t *inflictor, player_t *source, UINT8 damagetype)
{
if (!(damagetype & DMG_CANHURTSELF))
{
// You can't kill yourself, idiot...
if (source == target)
return false;
// In COOP/RACE, you can't hurt other players unless cv_friendlyfire is on
if (!(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE)) && (gametyperules & GTR_FRIENDLY))
return false;
}
// Tag handling
if (G_TagGametype())
{
// If flashing or invulnerable, ignore the tag,
if (target->powers[pw_flashing] || target->powers[pw_invulnerability])
return false;
// Don't allow any damage before the round starts.
if (leveltime <= hidetime * TICRATE)
return false;
// Ignore IT players shooting each other, unless friendlyfire is on.
if ((target->pflags & PF_TAGIT && !((cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE) || (damagetype & DMG_CANHURTSELF))
&& source->pflags & PF_TAGIT)))
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)) && (target->pflags & PF_TAGIT) == (source->pflags & PF_TAGIT))
return false;
if (inflictor->type == MT_LHRT)
return false;
return true;
}
else if (damagetype & DMG_CANHURTSELF)
return true;
else if (G_GametypeHasTeams()) // CTF + Team Match
{
// 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->ctfteam == source->ctfteam)
return false;
}
if (inflictor->type == MT_LHRT)
return false;
return true;
}
static boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype)
{
player_t *player = target->player;

View file

@ -506,6 +506,7 @@ void P_RemoveShield(player_t *player);
void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source);
boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype);
void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype);
boolean P_PlayerCanHurtPlayer(player_t *target, mobj_t *inflictor, player_t *source, UINT8 damagetype);
void P_PlayerRingBurst(player_t *player, INT32 num_rings); /// \todo better fit in p_user.c
void P_PlayerWeaponPanelBurst(player_t *player);
void P_PlayerWeaponAmmoBurst(player_t *player);

View file

@ -1279,7 +1279,7 @@ static unsigned PIT_DoCheckThing(mobj_t *thing)
if (tmthing->type != MT_SHELL && tmthing->target && tmthing->target->type == thing->type)
{
// Don't hit yourself, and if a player, don't hit bots
if (thing == tmthing->target || (thing->player && gametype == GT_COOP && (thing->player->bot == BOT_2PAI || thing->player->bot == BOT_2PHUMAN)))
if (thing->player && tmthing->target->player && !P_PlayerCanHurtPlayer(thing->player, tmthing, tmthing->target->player, 0))
return CHECKTHING_IGNORE;
if (thing->type != MT_PLAYER)