From 8ec5b6cd0f1a02c3f6a2fdf4c4458e3220604906 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Federico=20Mat=C3=ADas?= <41979395+FEDERICOMB96@users.noreply.github.com> Date: Wed, 8 May 2024 12:59:40 -0300 Subject: [PATCH] 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 --- regamedll/dlls/gamerules.h | 2 +- regamedll/dlls/multiplay_gamerules.cpp | 37 +++++++++++--------------- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/regamedll/dlls/gamerules.h b/regamedll/dlls/gamerules.h index e7dc35085..8d15e9ee4 100644 --- a/regamedll/dlls/gamerules.h +++ b/regamedll/dlls/gamerules.h @@ -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); diff --git a/regamedll/dlls/multiplay_gamerules.cpp b/regamedll/dlls/multiplay_gamerules.cpp index c70a86526..724dab34f 100644 --- a/regamedll/dlls/multiplay_gamerules.cpp +++ b/regamedll/dlls/multiplay_gamerules.cpp @@ -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 @@ -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; @@ -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(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); @@ -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)