Skip to content

Commit

Permalink
Fix SendDeathMessage kill rarity flags and transform to VFUNC (#943)
Browse files Browse the repository at this point in the history
* implement VFUNC to `SendDeathMessage`
* fix use KILLRARITY_HEADSHOT flag instead of member
* fix rare crash when pAssister is nullptr
* fix KILLRARITY_DOMINATION_BEGAN flag
This flag was never valid in "SendDeathMessage" hook
* set iDeathMessageFlags before call function
  • Loading branch information
FEDERICOMB96 authored May 8, 2024
1 parent 4ecf427 commit 8ec5b6c
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 22 deletions.
2 changes: 1 addition & 1 deletion regamedll/dlls/gamerules.h
Original file line number Diff line number Diff line change
Expand Up @@ -741,7 +741,7 @@ class CHalfLifeMultiplay: public CGameRules
VFUNC bool HasRoundTimeExpired();
VFUNC bool IsBombPlanted();

void SendDeathMessage(CBaseEntity *pKiller, CBasePlayer *pVictim, CBasePlayer *pAssister, entvars_t *pevInflictor, const char *killerWeaponName, int iDeathMessageFlags, int iRarityOfKill);
VFUNC void SendDeathMessage(CBaseEntity *pKiller, CBasePlayer *pVictim, CBasePlayer *pAssister, entvars_t *pevInflictor, const char *killerWeaponName, int iDeathMessageFlags, int iRarityOfKill);
int GetRarityOfKill(CBaseEntity *pKiller, CBasePlayer *pVictim, CBasePlayer *pAssister, const char *killerWeaponName, bool bFlashAssist);
CBasePlayer *CheckAssistsToKill(CBaseEntity *pKiller, CBasePlayer *pVictim, bool &bFlashAssist);

Expand Down
37 changes: 16 additions & 21 deletions regamedll/dlls/multiplay_gamerules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4130,6 +4130,16 @@ void EXT_FUNC CHalfLifeMultiplay::__API_HOOK(DeathNotice)(CBasePlayer *pVictim,
iDeathMessageFlags |= PLAYERDEATH_KILLRARITY;
}

#ifdef REGAMEDLL_ADD
iDeathMessageFlags &= UTIL_ReadFlags(deathmsg_flags.string); // leave only allowed bitsums for extra info

// Send the victim's death position only
// 1. if it is not a free for all mode
// 2. if the attacker is a player and they are not teammates
if (IsFreeForAll() || !pKiller || PlayerRelationship(pKiller, pVictim) == GR_TEAMMATE)
iDeathMessageFlags &= ~PLAYERDEATH_POSITION; // do not send a position
#endif

SendDeathMessage(pKiller, pVictim, pAssister, pevInflictor, killer_weapon_name, iDeathMessageFlags, iRarityOfKill);

// Updates the stats of who has killed whom
Expand Down Expand Up @@ -5317,6 +5327,10 @@ int CHalfLifeMultiplay::GetRarityOfKill(CBaseEntity *pKiller, CBasePlayer *pVict
int iKillsUnanswered = pVictim->CSPlayer()->m_iNumKilledByUnanswered[iAttackerEntityIndex - 1] + 1;
if (iKillsUnanswered == CS_KILLS_FOR_DOMINATION || pKillerPlayer->CSPlayer()->IsPlayerDominated(pVictim->entindex() - 1))
{
// Sets the beginning of domination over the victim until he takes revenge
if (iKillsUnanswered == CS_KILLS_FOR_DOMINATION)
iRarity |= KILLRARITY_DOMINATION_BEGAN;

// this is the Nth unanswered kill between killer and victim, killer is now dominating victim
iRarity |= KILLRARITY_DOMINATION;

Expand Down Expand Up @@ -5352,32 +5366,13 @@ LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN(CHalfLifeMultiplay, CSGameRules, SendDeathMess
//
void EXT_FUNC CHalfLifeMultiplay::__API_HOOK(SendDeathMessage)(CBaseEntity *pKiller, CBasePlayer *pVictim, CBasePlayer *pAssister, entvars_t *pevInflictor, const char *killerWeaponName, int iDeathMessageFlags, int iRarityOfKill)
{
CBasePlayer *pKillerPlayer = (pKiller && pKiller->IsPlayer()) ? static_cast<CBasePlayer *>(pKiller) : nullptr;

// Only the player can dominate the victim
if ((iRarityOfKill & KILLRARITY_DOMINATION) && pKillerPlayer && pVictim != pKillerPlayer)
{
// Sets the beginning of domination over the victim until he takes revenge
int iKillsUnanswered = pVictim->CSPlayer()->m_iNumKilledByUnanswered[pKillerPlayer->entindex() - 1] + 1;
if (iKillsUnanswered == CS_KILLS_FOR_DOMINATION)
iRarityOfKill |= KILLRARITY_DOMINATION_BEGAN;
}

MESSAGE_BEGIN(MSG_ALL, gmsgDeathMsg);
WRITE_BYTE((pKiller && pKiller->IsPlayer()) ? pKiller->entindex() : 0); // the killer
WRITE_BYTE(pVictim->entindex()); // the victim
WRITE_BYTE(pVictim->m_bHeadshotKilled); // is killed headshot
WRITE_BYTE((iRarityOfKill & KILLRARITY_HEADSHOT)); // is killed headshot
WRITE_STRING(killerWeaponName); // what they were killed by (should this be a string?)

#ifdef REGAMEDLL_ADD
iDeathMessageFlags &= UTIL_ReadFlags(deathmsg_flags.string); // leave only allowed bitsums for extra info

// Send the victim's death position only
// 1. if it is not a free for all mode
// 2. if the attacker is a player and they are not teammates
if (IsFreeForAll() || !pKillerPlayer || PlayerRelationship(pKillerPlayer, pVictim) == GR_TEAMMATE)
iDeathMessageFlags &= ~PLAYERDEATH_POSITION; // do not send a position

if (iDeathMessageFlags > 0)
{
WRITE_LONG(iDeathMessageFlags);
Expand All @@ -5393,7 +5388,7 @@ void EXT_FUNC CHalfLifeMultiplay::__API_HOOK(SendDeathMessage)(CBaseEntity *pKil

// Writes the index of the teammate who assisted in the kill
if (iDeathMessageFlags & PLAYERDEATH_ASSISTANT)
WRITE_BYTE(pAssister->entindex());
WRITE_BYTE((pAssister && pAssister->IsPlayer()) ? pAssister->entindex() : 0);

// Writes the rarity classification of the kill
if (iDeathMessageFlags & PLAYERDEATH_KILLRARITY)
Expand Down

0 comments on commit 8ec5b6c

Please sign in to comment.