Cstrike: Fix CS_OnBuy called only on the first buying of primary/secondary ammos and not when game loops to give until max amount

When game gives ammos, it loops until the max amount is reached, but it sill calls GiveNamedItem and AddAcount, so forward should be called for each of these ones.

Code logic is simplified and more understandable.
This commit is contained in:
Arkshine 2015-07-25 13:07:42 +02:00
parent e6a2434887
commit cf2f753660

View File

@ -92,14 +92,13 @@ DETOUR_DECL_STATIC1(C_ClientCommand, void, edict_t*, pEdict) // void ClientComma
{ {
const char *command = CMD_ARGV(0); const char *command = CMD_ARGV(0);
// A new command is triggered, reset variable, always. CurrentItemId = CSI_NONE;
CurrentItemId = 0;
// Purpose is to retrieve an item id based on alias name or selected item from menu, // Purpose is to retrieve an item id based on alias name or selected item from menu,
// to be used in OnBuy* forwards. // to be used in OnBuy* forwards.
if ((ForwardOnBuyAttempt != -1 || ForwardOnBuy != -1) && command && *command) if ((ForwardOnBuyAttempt != -1 || ForwardOnBuy != -1) && command && *command)
{ {
int itemId = 0; int itemId = CSI_NONE;
// Handling buy via menu. // Handling buy via menu.
if (!strcmp(command, "menuselect")) if (!strcmp(command, "menuselect"))
@ -108,7 +107,7 @@ DETOUR_DECL_STATIC1(C_ClientCommand, void, edict_t*, pEdict) // void ClientComma
if (slot > 0 && slot < 9) if (slot > 0 && slot < 9)
{ {
static const int menuItemsTe[][9] = static const int menuItemsTe[][9] =
{ {
/* Menu_Buy */ { 0, 0, 0, 0, 0, 0, CSI_PRIAMMO, CSI_SECAMMO, 0 }, /* Menu_Buy */ { 0, 0, 0, 0, 0, 0, CSI_PRIAMMO, CSI_SECAMMO, 0 },
/* Menu_BuyPistol */ { 0, CSI_GLOCK18, CSI_USP, CSI_P228, CSI_DEAGLE, CSI_ELITE, 0, 0, 0 }, /* Menu_BuyPistol */ { 0, CSI_GLOCK18, CSI_USP, CSI_P228, CSI_DEAGLE, CSI_ELITE, 0, 0, 0 },
@ -172,13 +171,17 @@ DETOUR_DECL_STATIC1(C_ClientCommand, void, edict_t*, pEdict) // void ClientComma
if (ForwardOnBuyAttempt != -1 && if (ForwardOnBuyAttempt != -1 &&
CurrentItemId && CurrentItemId &&
MF_IsPlayerAlive(client) && MF_IsPlayerAlive(client) &&
MF_ExecuteForward(ForwardOnBuyAttempt, static_cast<cell>(client), static_cast<cell>(CurrentItemId)) > 0) MF_ExecuteForward(ForwardOnBuyAttempt, static_cast<cell>(client), static_cast<cell>(CurrentItemId)) > 0)
{ {
return; return;
} }
TriggeredFromCommand = CurrentItemId != CSI_NONE;
DETOUR_STATIC_CALL(C_ClientCommand)(pEdict); DETOUR_STATIC_CALL(C_ClientCommand)(pEdict);
TriggeredFromCommand = false;
} }
edict_s* OnCreateNamedEntity(int classname) edict_s* OnCreateNamedEntity(int classname)
@ -212,63 +215,52 @@ DETOUR_DECL_MEMBER0(GiveDefaultItems, void) // void CBasePlayer::GiveDefaultIte
DETOUR_DECL_MEMBER1(GiveNamedItem, void, const char*, pszName) // void CBasePlayer::GiveNamedItem(const char *pszName) DETOUR_DECL_MEMBER1(GiveNamedItem, void, const char*, pszName) // void CBasePlayer::GiveNamedItem(const char *pszName)
{ {
// If the current item id is not null, this means player has triggers a buy command. if (TriggeredFromCommand)
if (CurrentItemId)
{ {
int client = TypeConversion.cbase_to_id(this); int client = TypeConversion.cbase_to_id(this);
if (MF_IsPlayerAlive(client) && MF_ExecuteForward(ForwardOnBuy, static_cast<cell>(client), static_cast<cell>(CurrentItemId)) > 0) if (MF_IsPlayerAlive(client) && MF_ExecuteForward(ForwardOnBuy, static_cast<cell>(client), static_cast<cell>(CurrentItemId)) > 0)
{ {
// Reset this to not call AddAccount() called right after.
CurrentItemId = CSI_NONE;
return; return;
} }
} }
// From here, forward is not blocked, resetting this
// to ignore code in AddAccount which is called right after.
CurrentItemId = 0;
// Give me my item!
DETOUR_MEMBER_CALL(GiveNamedItem)(pszName); DETOUR_MEMBER_CALL(GiveNamedItem)(pszName);
} }
DETOUR_DECL_MEMBER1(GiveShield, void, bool, bRetire) // void CBasePlayer::GiveShield(bool bRetire) DETOUR_DECL_MEMBER1(GiveShield, void, bool, bRetire) // void CBasePlayer::GiveShield(bool bRetire)
{ {
// Special case for shield. Game doesn't use GiveNamedItem() to give a shield. if (TriggeredFromCommand && CurrentItemId == CSI_SHIELDGUN)
if (CurrentItemId == CSI_SHIELDGUN)
{ {
int client = TypeConversion.cbase_to_id(this); int client = TypeConversion.cbase_to_id(this);
if (MF_IsPlayerAlive(client) && MF_ExecuteForward(ForwardOnBuy, static_cast<cell>(client), CSI_SHIELDGUN) > 0) if (MF_IsPlayerAlive(client) && MF_ExecuteForward(ForwardOnBuy, static_cast<cell>(client), CSI_SHIELDGUN) > 0)
{ {
// If shield blocked, we need to hook EmitSound to block pickup sound played right after.
g_pengfuncsTable->pfnEmitSound = OnEmitSound;
// Reset this to not call AddAccount() called right after.
CurrentItemId = CSI_NONE;
return; return;
} }
} }
// From here, forward is not blocked, resetting this
// to ignore code in AddAccount which is called right after.
CurrentItemId = 0;
// Give me my shield!
DETOUR_MEMBER_CALL(GiveShield)(bRetire); DETOUR_MEMBER_CALL(GiveShield)(bRetire);
} }
DETOUR_DECL_MEMBER2(AddAccount, void, int, amount, bool, bTrackChange) // void CBasePlayer::AddAccount(int amount, bool bTrackChange) DETOUR_DECL_MEMBER2(AddAccount, void, int, amount, bool, bTrackChange) // void CBasePlayer::AddAccount(int amount, bool bTrackChange)
{ {
// No buy command or forward not blocked. if (TriggeredFromCommand)
// Resuming game flow.
if (!CurrentItemId)
{ {
DETOUR_MEMBER_CALL(AddAccount)(amount, bTrackChange); if (CurrentItemId == CSI_NONE)
} {
// Shield is blocked. return;
// We need to hook EmitSound to block pickup sound played right after. }
else if (CurrentItemId == CSI_SHIELDGUN)
{
g_pengfuncsTable->pfnEmitSound = OnEmitSound;
} }
// Let's reset this right away to avoid issues. DETOUR_MEMBER_CALL(AddAccount)(amount, bTrackChange);
CurrentItemId = 0;
} }