Cstrike: Make CS_OnBuy forward more reliable - part 2
Purpose is to have the forward be called only on actual buying. This has been requested on the forum.
This commit is contained in:
parent
6e50a0effd
commit
0cf39307e0
@ -3,6 +3,10 @@ import os.path
|
||||
|
||||
binary = AMXX.MetaModule(builder, 'cstrike')
|
||||
|
||||
binary.compiler.defines += [
|
||||
'HAVE_STDINT_H',
|
||||
]
|
||||
|
||||
binary.sources = [
|
||||
'sdk/amxxmodule.cpp',
|
||||
'amxx_api.cpp',
|
||||
|
@ -64,6 +64,7 @@
|
||||
#define OFFSET_INTERNALMODEL 126 + EXTRAOFFSET
|
||||
#define OFFSET_NVGOGGLES 129 + EXTRAOFFSET
|
||||
#define OFFSET_DEFUSE_PLANT 193 + EXTRAOFFSET
|
||||
#define OFFSET_MENU 205 + EXTRAOFFSET
|
||||
#define OFFSET_VIP 209 + EXTRAOFFSET
|
||||
#define OFFSET_TK 216 + EXTRAOFFSET // 040926
|
||||
#define OFFSET_HOSTAGEKILLS 217 + EXTRAOFFSET
|
||||
@ -353,4 +354,24 @@ enum
|
||||
CS_SET_AUGSG552_ZOOM,
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
Menu_OFF,
|
||||
Menu_ChooseTeam,
|
||||
Menu_IGChooseTeam,
|
||||
Menu_ChooseAppearance,
|
||||
Menu_Buy,
|
||||
Menu_BuyPistol,
|
||||
Menu_BuyRifle,
|
||||
Menu_BuyMachineGun,
|
||||
Menu_BuyShotgun,
|
||||
Menu_BuySubMachineGun,
|
||||
Menu_BuyItem,
|
||||
Menu_Radio1,
|
||||
Menu_Radio2,
|
||||
Menu_Radio3,
|
||||
Menu_ClientBuy
|
||||
|
||||
} Menu;
|
||||
|
||||
#endif // CSTRIKE_DATA_H
|
@ -33,6 +33,9 @@
|
||||
#include "CstrikeDatas.h"
|
||||
#include "CstrikeUtils.h"
|
||||
#include "CDetour/detours.h"
|
||||
#include <sm_stringhashmap.h>
|
||||
|
||||
using namespace SourceMod; // hashmap
|
||||
|
||||
void CtrlDetours_ClientCommand(bool set);
|
||||
void CtrlDetours_BuyCommands(bool set);
|
||||
@ -50,6 +53,9 @@ CDetour *g_BuyGunAmmoDetour = NULL;
|
||||
CDetour *g_GiveNamedItemDetour = NULL;
|
||||
CDetour *g_AddAccountDetour = NULL;
|
||||
|
||||
int g_CurrentItemId = 0;
|
||||
StringHashMap<int> g_ItemAliasList;
|
||||
|
||||
void InitializeHacks()
|
||||
{
|
||||
#if defined AMD64
|
||||
@ -66,9 +72,92 @@ void ShutdownHacks()
|
||||
CtrlDetours_BuyCommands(false);
|
||||
}
|
||||
|
||||
#undef CMD_ARGV
|
||||
|
||||
const char *CMD_ARGV(int i)
|
||||
{
|
||||
if (*g_UseBotArgs)
|
||||
{
|
||||
if (i < 4)
|
||||
{
|
||||
return g_BotArgs[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return g_engfuncs.pfnCmd_Argv(i);
|
||||
}
|
||||
|
||||
DETOUR_DECL_STATIC1(C_ClientCommand, void, edict_t*, pEdict) // void ClientCommand(edict_t *pEntity)
|
||||
{
|
||||
const char *command = CMD_ARGV(0);
|
||||
|
||||
// A new command is triggered, reset current item.
|
||||
g_CurrentItemId = 0;
|
||||
|
||||
// Purpose is to retrieve an item id based on alias name or selected item from menu,
|
||||
// to be used in OnBuy* forwards.
|
||||
if (command && *command)
|
||||
{
|
||||
int itemId = 0;
|
||||
|
||||
// Handling via menu.
|
||||
if (!strcmp(command, "menuselect"))
|
||||
{
|
||||
int slot = atoi(CMD_ARGV(1));
|
||||
|
||||
if (slot > 0 && slot < 9)
|
||||
{
|
||||
static const int menuItemsTe[][9] =
|
||||
{
|
||||
/* Menu_Buy */ { 0, 0, 0, 0, 0, 0, CSI_PRIMAMMO, CSI_SECAMMO, 0 },
|
||||
/* Menu_BuyPistol */ { 0, CSI_GLOCK18, CSI_USP, CSI_P228, CSI_DEAGLE, CSI_ELITE, 0, 0, 0 },
|
||||
/* Menu_BuyRifle */ { 0, CSI_GALI, CSI_AK47, CSI_SCOUT, CSI_SG552, CSI_AWP, CSI_G3SG1, 0, 0 },
|
||||
/* Menu_BuyMachineGun */ { 0, CSI_M249, 0, 0, 0, 0, 0, 0, 0 },
|
||||
/* Menu_BuyShotgun */ { 0, CSI_M3, CSI_XM1014, 0, 0, 0, 0, 0, 0 },
|
||||
/* Menu_BuySubMachineGun */ { 0, CSI_MAC10, CSI_MP5NAVY, CSI_UMP45, CSI_P90, 0, 0, 0, 0 },
|
||||
/* Menu_BuyItem */ { 0, CSI_VEST, CSI_VESTHELM, CSI_FLASHBANG, CSI_HEGRENADE, CSI_SMOKEGRENADE, CSI_NVGS, 0, 0 }
|
||||
};
|
||||
|
||||
static const int menuItemsCt[][9] =
|
||||
{
|
||||
/* Menu_Buy */ { 0, 0, 0, 0, 0, 0, CSI_PRIMAMMO, CSI_SECAMMO, 0 },
|
||||
/* Menu_BuyPistol */ { 0, CSI_GLOCK18, CSI_USP, CSI_P228, CSI_DEAGLE, CSI_FIVESEVEN, 0, 0, 0 },
|
||||
/* Menu_BuyRifle */ { 0, CSI_FAMAS, CSI_SCOUT, CSI_M4A1, CSI_AUG, CSI_SG550, CSI_AWP, 0, 0 },
|
||||
/* Menu_BuyMachineGun */ { 0, CSI_M249, 0, 0, 0, 0, 0, 0, 0 },
|
||||
/* Menu_BuyShotgun */ { 0, CSI_M3, CSI_XM1014, 0, 0, 0, 0, 0, 0 },
|
||||
/* Menu_BuySubMachineGun */ { 0, CSI_TMP, CSI_MP5NAVY, CSI_UMP45, CSI_P90, 0, 0, 0, 0 },
|
||||
/* Menu_BuyItem */ { 0, CSI_VEST, CSI_VESTHELM, CSI_FLASHBANG, CSI_HEGRENADE, CSI_SMOKEGRENADE, CSI_NVGS, CSI_DEFUSER, CSI_SHIELDGUN }
|
||||
};
|
||||
|
||||
int menuId = *((int *)pEdict->pvPrivateData + OFFSET_MENU);
|
||||
if (menuId >= Menu_Buy && menuId <= Menu_BuyItem)
|
||||
{
|
||||
int team = *((int *)pEdict->pvPrivateData + OFFSET_TEAM);
|
||||
switch (team)
|
||||
{
|
||||
case TEAM_T: itemId = menuItemsTe[menuId - 4][slot]; break; // -4 because array is zero-based and Menu_Buy* constants starts from 4.
|
||||
case TEAM_CT:itemId = menuItemsCt[menuId - 4][slot]; break;
|
||||
}
|
||||
|
||||
if (itemId)
|
||||
{
|
||||
g_CurrentItemId = itemId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Handling via alias
|
||||
else
|
||||
{
|
||||
if (g_ItemAliasList.retrieve(command, &itemId))
|
||||
{
|
||||
g_CurrentItemId = itemId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (*g_UseBotArgs)
|
||||
{
|
||||
int client = ENTINDEX(pEdict);
|
||||
@ -89,9 +178,9 @@ DETOUR_DECL_STATIC2(CanBuyThis, bool, void*, pvPlayer, int, weaponId) // bool Ca
|
||||
{
|
||||
int player = PrivateToIndex(pvPlayer);
|
||||
|
||||
if (MF_IsPlayerAlive(player) && MF_ExecuteForward(g_CSBuyCmdFwd, static_cast<cell>(player), static_cast<cell>(weaponId)) > 0)
|
||||
if (MF_IsPlayerAlive(player))
|
||||
{
|
||||
return false;
|
||||
g_CurrentItemId = weaponId;
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,9 +195,9 @@ DETOUR_DECL_STATIC2(BuyItem, void, void*, pvPlayer, int, iSlot) // void BuyItem(
|
||||
{
|
||||
static const int itemSlotToWeaponId[] = {-1, CSI_VEST, CSI_VESTHELM, CSI_FLASHBANG, CSI_HEGRENADE, CSI_SMOKEGRENADE, CSI_NVGS, CSI_DEFUSER, CSI_SHIELDGUN};
|
||||
|
||||
if (iSlot >= 1 && iSlot <= 8 && MF_ExecuteForward(g_CSBuyCmdFwd, static_cast<cell>(player), static_cast<cell>(itemSlotToWeaponId[iSlot])) > 0)
|
||||
if (iSlot >= 1 && iSlot <= 8)
|
||||
{
|
||||
return;
|
||||
g_CurrentItemId = itemSlotToWeaponId[iSlot];
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,10 +217,7 @@ DETOUR_DECL_STATIC3(BuyGunAmmo, bool, void*, pvPlayer, void*, pvWeapon, bool, bB
|
||||
int weaponId = *((int *)pWeapon->pvPrivateData + OFFSET_WEAPONTYPE);
|
||||
int ammoId = (1<<weaponId & BITS_PISTOLS) ? CSI_SECAMMO : CSI_PRIMAMMO;
|
||||
|
||||
if (MF_ExecuteForward(g_CSBuyCmdFwd, static_cast<cell>(player), static_cast<cell>(ammoId)) > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
g_CurrentItemId = ammoId;
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,12 +226,25 @@ DETOUR_DECL_STATIC3(BuyGunAmmo, bool, void*, pvPlayer, void*, pvWeapon, bool, bB
|
||||
|
||||
DETOUR_DECL_MEMBER1(GiveNamedItem, void, const char*, pszName) // void CBasePlayer::GiveNamedItem(const char *pszName)
|
||||
{
|
||||
if (g_CurrentItemId && MF_ExecuteForward(g_CSBuyCmdFwd, static_cast<cell>(PrivateToIndex(this)), static_cast<cell>(g_CurrentItemId)) > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_CurrentItemId = 0;
|
||||
|
||||
DETOUR_MEMBER_CALL(GiveNamedItem)(pszName);
|
||||
}
|
||||
|
||||
|
||||
DETOUR_DECL_MEMBER2(AddAccount, void, int, amount, bool, bTrackChange) // void CBasePlayer::AddAccount(int amount, bool bTrackChange)
|
||||
{
|
||||
if (g_CurrentItemId)
|
||||
{
|
||||
g_CurrentItemId = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
DETOUR_MEMBER_CALL(AddAccount)(amount, bTrackChange);
|
||||
}
|
||||
|
||||
@ -212,6 +311,52 @@ void CtrlDetours_BuyCommands(bool set)
|
||||
{
|
||||
MF_Log("No Buy Commands detours could be initialized - Disabled Buy forward.");
|
||||
}
|
||||
|
||||
// Build the item alias list.
|
||||
// Used in ClientCommand to check and get fastly item id from aiias name.
|
||||
typedef struct
|
||||
{
|
||||
char *alias;
|
||||
int id;
|
||||
|
||||
} itemBuyAliasInfo;
|
||||
|
||||
itemBuyAliasInfo aliasToId[] =
|
||||
{
|
||||
{ "p228" , CSI_P228 }, { "228compact" , CSI_P228 },
|
||||
{ "scout" , CSI_SCOUT }, { "hegren" , CSI_HEGRENADE },
|
||||
{ "xm1014" , CSI_XM1014 }, { "autoshotgun", CSI_XM1014 },
|
||||
{ "mac10" , CSI_MAC10 }, { "aug" , CSI_AUG },
|
||||
{ "bullpup" , CSI_AUG }, { "sgren" , CSI_SMOKEGRENADE },
|
||||
{ "elites" , CSI_ELITE }, { "fn57" , CSI_FIVESEVEN },
|
||||
{ "fiveseven" , CSI_FIVESEVEN }, { "ump45" , CSI_UMP45 },
|
||||
{ "sg550" , CSI_SG550 }, { "krieg550" , CSI_SG550 },
|
||||
{ "galil" , CSI_GALI }, { "defender" , CSI_GALI },
|
||||
{ "famas" , CSI_FAMAS }, { "clarion" , CSI_FAMAS },
|
||||
{ "usp" , CSI_USP }, { "km45" , CSI_USP },
|
||||
{ "glock" , CSI_GLOCK18 }, { "9x19mm" , CSI_GLOCK18 },
|
||||
{ "awp" , CSI_AWP }, { "magnum" , CSI_AWP },
|
||||
{ "mp5" , CSI_MP5NAVY }, { "smg" , CSI_MP5NAVY },
|
||||
{ "m249" , CSI_M249 }, { "m3" , CSI_M3 },
|
||||
{ "12gauge" , CSI_M3 }, { "m4a1" , CSI_M4A1 },
|
||||
{ "tmp" , CSI_TMP }, { "mp" , CSI_TMP },
|
||||
{ "g3sg1" , CSI_G3SG1 }, { "d3au1" , CSI_G3SG1 },
|
||||
{ "flash" , CSI_FLASHBANG }, { "deagle" , CSI_DEAGLE },
|
||||
{ "nighthawk" , CSI_DEAGLE }, { "sg552" , CSI_SG552 },
|
||||
{ "krieg552" , CSI_SG552 }, { "ak47" , CSI_AK47 },
|
||||
{ "cv47" , CSI_AK47 }, { "p90" , CSI_P90 },
|
||||
{ "c90" , CSI_P90 }, { "vest" , CSI_VEST },
|
||||
{ "vesthelm" , CSI_VESTHELM }, { "defuser" , CSI_DEFUSER },
|
||||
{ "nvgs" , CSI_NVGS }, { "shield" , CSI_SHIELDGUN },
|
||||
{ "buyammo1" , CSI_PRIMAMMO }, { "primammo" , CSI_PRIMAMMO },
|
||||
{ "buyammo2" , CSI_SECAMMO }, { "secammo" , CSI_SECAMMO },
|
||||
{ NULL , 0 }
|
||||
};
|
||||
|
||||
for (size_t i = 0; aliasToId[i].alias != NULL; ++i)
|
||||
{
|
||||
g_ItemAliasList.insert(aliasToId[i].alias, aliasToId[i].id);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -229,6 +374,8 @@ void CtrlDetours_BuyCommands(bool set)
|
||||
|
||||
if (g_AddAccountDetour)
|
||||
g_AddAccountDetour->Destroy();
|
||||
|
||||
g_ItemAliasList.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,14 +3,6 @@
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "CstrikePlayer.h"
|
||||
|
||||
#if defined _MSC_VER
|
||||
#if _MSC_VER >= 1400
|
||||
// MSVC8 - disable deprecation warnings for "unsafe" CRT functions
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <string.h> // strcpy()
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
@ -63,7 +63,7 @@
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\;..\..\..\..\public; ..\..\..\..\public\amtl;..\..\..\..\public\memtools;..\sdk;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CSTRIKE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;HAVE_STDINT_H;_CRT_SECURE_NO_DEPRECATE;CSTRIKE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
@ -106,7 +106,7 @@
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<AdditionalIncludeDirectories>..\;..\..\..\..\public; ..\..\..\..\public\amtl;..\..\..\..\public\memtools;..\sdk;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\pm_shared;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CSTRIKE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;HAVE_STDINT_H;_CRT_SECURE_NO_DEPRECATE;CSTRIKE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
|
Loading…
Reference in New Issue
Block a user