From b281588ddf8f68bba67498f9dc8a6cca1f7a44fb Mon Sep 17 00:00:00 2001 From: Javekson <132286351+Javekson@users.noreply.github.com> Date: Sun, 26 Nov 2023 07:54:11 +0400 Subject: [PATCH] fix(rg_transfer_c4): prevent C4 destruction on arg receiver = 0 (#291) --- .../scripting/include/reapi_gamedll.inc | 2 +- reapi/include/cssdk/dlls/gamerules.h | 2 +- reapi/src/natives/natives_misc.cpp | 46 ++++++++++++++----- 3 files changed, 36 insertions(+), 14 deletions(-) diff --git a/reapi/extra/amxmodx/scripting/include/reapi_gamedll.inc b/reapi/extra/amxmodx/scripting/include/reapi_gamedll.inc index 198c3a7..4728960 100644 --- a/reapi/extra/amxmodx/scripting/include/reapi_gamedll.inc +++ b/reapi/extra/amxmodx/scripting/include/reapi_gamedll.inc @@ -697,7 +697,7 @@ native rg_get_user_footsteps(const index); * @param index Client index * @param receiver Receiver index, if 0 it will transfer to a random player * -* @return 1 on success, 0 otherwise +* @return Index of player entity if successfull, 0 otherwise */ native rg_transfer_c4(const index, const receiver = 0); diff --git a/reapi/include/cssdk/dlls/gamerules.h b/reapi/include/cssdk/dlls/gamerules.h index 6778601..d0781be 100644 --- a/reapi/include/cssdk/dlls/gamerules.h +++ b/reapi/include/cssdk/dlls/gamerules.h @@ -531,7 +531,7 @@ public: // check if the scenario has been won/lost virtual void CheckWinConditions() = 0; virtual void RemoveGuns() = 0; - virtual void GiveC4() = 0; + virtual CBasePlayer *GiveC4() = 0; virtual void ChangeLevel() = 0; virtual void GoToIntermission() = 0; diff --git a/reapi/src/natives/natives_misc.cpp b/reapi/src/natives/natives_misc.cpp index 3b53665..cf803a7 100644 --- a/reapi/src/natives/natives_misc.cpp +++ b/reapi/src/natives/natives_misc.cpp @@ -1575,10 +1575,11 @@ cell AMX_NATIVE_CALL rg_get_user_footsteps(AMX *amx, cell *params) * @param index Client index * @param receiver Receiver index, if 0 it will transfer to a random player * -* @return 1 on success, 0 otherwise +* @return Index of player entity if successfull, 0 otherwise * * native rg_transfer_c4(const index, const receiver = 0); */ + cell AMX_NATIVE_CALL rg_transfer_c4(AMX *amx, cell *params) { enum args_e { arg_count, arg_index, arg_receiver }; @@ -1589,29 +1590,50 @@ cell AMX_NATIVE_CALL rg_transfer_c4(AMX *amx, cell *params) CBasePlayer *pPlayer = UTIL_PlayerByIndex(params[arg_index]); CHECK_CONNECTED(pPlayer, arg_index); - if (!pPlayer->m_bHasC4 || !pPlayer->CSPlayer()->RemovePlayerItem("weapon_c4")) + if (!pPlayer->m_bHasC4) { return FALSE; + } - pPlayer->pev->body = 0; - pPlayer->m_bHasC4 = false; - pPlayer->CSPlayer()->SetBombIcon(); - pPlayer->CSPlayer()->SetProgressBarTime(0); + CBasePlayer *pReceiver = nullptr; - if (params[arg_receiver] != 0 && params[arg_receiver] <= gpGlobals->maxClients) { - CBasePlayer *pReceiver = UTIL_PlayerByIndex(params[arg_receiver]); + if (params[arg_receiver] > 0 && params[arg_receiver] <= gpGlobals->maxClients) { + pReceiver = UTIL_PlayerByIndex(params[arg_receiver]); CHECK_CONNECTED(pReceiver, arg_receiver); - if (!pReceiver->CSPlayer()->MakeBomber()) + if (!pPlayer->CSPlayer()->RemovePlayerItemEx("weapon_c4", true)) { return FALSE; + } + + if (!pReceiver->CSPlayer()->MakeBomber()) { + return FALSE; + } + } + else { + int NumDeadCT, NumDeadTerrorist, NumAliveTerrorist, NumAliveCT; + CSGameRules()->InitializePlayerCounts(NumAliveTerrorist, NumAliveCT, NumDeadTerrorist, NumDeadCT); + + if (pPlayer->m_iTeam == CT && NumAliveTerrorist < 1) { + return FALSE; + } + + if (pPlayer->m_iTeam == TERRORIST && NumAliveTerrorist < 2) { + return FALSE; + } + + if (!pPlayer->CSPlayer()->RemovePlayerItemEx("weapon_c4", true)) { + return FALSE; + } - } else { auto flags = pPlayer->pev->flags; pPlayer->pev->flags |= FL_DORMANT; - CSGameRules()->GiveC4(); + pReceiver = CSGameRules()->GiveC4(); pPlayer->pev->flags = flags; } - return TRUE; + if (pReceiver) + return indexOfPDataAmx(pReceiver); + + return FALSE; } /*