Fix SendDeathMessage kill rarity flags and transform to VFUNC (#943)

* 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
This commit is contained in:
Federico Matías 2024-05-08 12:59:40 -03:00 committed by GitHub
parent 4ecf42799d
commit 8ec5b6cd0f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 17 additions and 22 deletions

View File

@ -741,7 +741,7 @@ public:
VFUNC bool HasRoundTimeExpired(); VFUNC bool HasRoundTimeExpired();
VFUNC bool IsBombPlanted(); 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); int GetRarityOfKill(CBaseEntity *pKiller, CBasePlayer *pVictim, CBasePlayer *pAssister, const char *killerWeaponName, bool bFlashAssist);
CBasePlayer *CheckAssistsToKill(CBaseEntity *pKiller, CBasePlayer *pVictim, bool &bFlashAssist); CBasePlayer *CheckAssistsToKill(CBaseEntity *pKiller, CBasePlayer *pVictim, bool &bFlashAssist);

View File

@ -4130,6 +4130,16 @@ void EXT_FUNC CHalfLifeMultiplay::__API_HOOK(DeathNotice)(CBasePlayer *pVictim,
iDeathMessageFlags |= PLAYERDEATH_KILLRARITY; 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); SendDeathMessage(pKiller, pVictim, pAssister, pevInflictor, killer_weapon_name, iDeathMessageFlags, iRarityOfKill);
// Updates the stats of who has killed whom // Updates the stats of who has killed whom
@ -5317,6 +5327,10 @@ int CHalfLifeMultiplay::GetRarityOfKill(CBaseEntity *pKiller, CBasePlayer *pVict
int iKillsUnanswered = pVictim->CSPlayer()->m_iNumKilledByUnanswered[iAttackerEntityIndex - 1] + 1; int iKillsUnanswered = pVictim->CSPlayer()->m_iNumKilledByUnanswered[iAttackerEntityIndex - 1] + 1;
if (iKillsUnanswered == CS_KILLS_FOR_DOMINATION || pKillerPlayer->CSPlayer()->IsPlayerDominated(pVictim->entindex() - 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 // this is the Nth unanswered kill between killer and victim, killer is now dominating victim
iRarity |= KILLRARITY_DOMINATION; iRarity |= KILLRARITY_DOMINATION;
@ -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) 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); MESSAGE_BEGIN(MSG_ALL, gmsgDeathMsg);
WRITE_BYTE((pKiller && pKiller->IsPlayer()) ? pKiller->entindex() : 0); // the killer WRITE_BYTE((pKiller && pKiller->IsPlayer()) ? pKiller->entindex() : 0); // the killer
WRITE_BYTE(pVictim->entindex()); // the victim 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?) WRITE_STRING(killerWeaponName); // what they were killed by (should this be a string?)
#ifdef REGAMEDLL_ADD #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) if (iDeathMessageFlags > 0)
{ {
WRITE_LONG(iDeathMessageFlags); WRITE_LONG(iDeathMessageFlags);
@ -5393,7 +5388,7 @@ void EXT_FUNC CHalfLifeMultiplay::__API_HOOK(SendDeathMessage)(CBaseEntity *pKil
// Writes the index of the teammate who assisted in the kill // Writes the index of the teammate who assisted in the kill
if (iDeathMessageFlags & PLAYERDEATH_ASSISTANT) if (iDeathMessageFlags & PLAYERDEATH_ASSISTANT)
WRITE_BYTE(pAssister->entindex()); WRITE_BYTE((pAssister && pAssister->IsPlayer()) ? pAssister->entindex() : 0);
// Writes the rarity classification of the kill // Writes the rarity classification of the kill
if (iDeathMessageFlags & PLAYERDEATH_KILLRARITY) if (iDeathMessageFlags & PLAYERDEATH_KILLRARITY)