Merge pull request #701 from alliedmodders/csgo-hashmap

CStrike extension changes for CS:GO
This commit is contained in:
Ruben Gonzalez 2017-11-03 19:48:55 -04:00 committed by GitHub
commit 7507672895
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 761 additions and 781 deletions

View File

@ -36,6 +36,7 @@
#include "iplayerinfo.h"
#include "ISDKTools.h"
#include "forwards.h"
#include "util_cstrike.h"
/**
* @file extension.cpp
@ -126,6 +127,10 @@ void CStrike::SDK_OnUnload()
forwards->ReleaseForward(g_pPriceForward);
forwards->ReleaseForward(g_pTerminateRoundForward);
forwards->ReleaseForward(g_pCSWeaponDropForward);
#if SOURCE_ENGINE == SE_CSGO
ClearHashMaps();
#endif
}
void CStrike::SDK_OnAllLoaded()
@ -146,6 +151,10 @@ void CStrike::SDK_OnAllLoaded()
hooked_everything = true;
SM_GET_LATE_IFACE(BINTOOLS, g_pBinTools);
#if SOURCE_ENGINE == SE_CSGO
CreateHashMaps();
#endif
}
bool CStrike::QueryRunning(char *error, size_t maxlength)

View File

@ -53,15 +53,7 @@ DETOUR_DECL_MEMBER3(DetourHandleBuy, int, int, iLoadoutSlot, void *, pWpnDataRef
}
else
{
const char *underscore = strstr(szClassname, "_");
if (underscore)
{
Q_strncpy(weaponName, (const char *)((intptr_t)underscore + 1), sizeof(weaponName));
}
else
{
Q_strncpy(weaponName, szClassname, sizeof(weaponName));
}
Q_strncpy(weaponName, GetWeaponNameFromClassname(szClassname), sizeof(weaponName));
}
cell_t result = Pl_Continue;

View File

@ -0,0 +1,95 @@
#ifndef _INCLUDE_CSTRIKE_HASH_H_
#define _INCLUDE_CSTRIKE_HASH_H_
#include <amtl/am-string.h>
#include <amtl/am-hashmap.h>
#include <amtl/am-hashtable.h>
#define MAX_WEAPON_NAME_LENGTH 80
class CEconItemDefinition;
struct HashItemDef_Node
{
int key;
CEconItemDefinition *pDef;
int iunknown;
};
class CHashItemDef
{
public:
unsigned char padding[36];
HashItemDef_Node *pMem;
int nAllocatedCount;
int nGrowSize;
int iunknown;
int currentElements;
int maxElements;
};
struct ItemDefHashValue
{
ItemDefHashValue(int iLoadoutSlot, unsigned int iPrice, SMCSWeapon iWeaponID, unsigned int iDefIdx, const char *szClassname)
{
m_iLoadoutSlot = iLoadoutSlot;
m_iPrice = iPrice;
m_iDefIdx = iDefIdx;
m_iWeaponID = iWeaponID;
Q_strncpy(m_szClassname, szClassname, sizeof(m_szClassname));
//Create the item name
Q_strncpy(m_szItemName, GetWeaponNameFromClassname(szClassname), sizeof(m_szItemName));
}
int m_iLoadoutSlot;
SMCSWeapon m_iWeaponID;
unsigned int m_iPrice;
unsigned int m_iDefIdx;
char m_szClassname[MAX_WEAPON_NAME_LENGTH];
char m_szItemName[MAX_WEAPON_NAME_LENGTH];
};
struct StringPolicy
{
static inline uint32_t hash(const char *key)
{
return ke::FastHashCharSequence(key, strlen(key));
}
static inline bool matches(const char *find, const ke::AString &key)
{
return key.compare(find) == 0;
}
};
struct IntegerPolicy
{
static inline uint32_t hash(const int key)
{
return ke::HashInt32(key);
}
static inline bool matches(const int find, const int &key)
{
return (key == find);
}
};
struct WeaponIDPolicy
{
static inline uint32_t hash(const SMCSWeapon key)
{
return ke::HashInt32((int)key);
}
static inline bool matches(const SMCSWeapon find, const SMCSWeapon &key)
{
return (key == find);
}
};
typedef ke::HashMap<ke::AString, ItemDefHashValue, StringPolicy> ClassnameMap;
typedef ke::HashMap<int, ItemDefHashValue, IntegerPolicy> ItemIndexMap;
typedef ke::HashMap<SMCSWeapon, ItemDefHashValue, WeaponIDPolicy> WeaponIDMap;
extern ClassnameMap g_mapClassToDefIdx;
extern ItemIndexMap g_mapDefIdxToClass;
extern WeaponIDMap g_mapWeaponIDToDefIdx;
#endif //_INCLUDE_CSTRIKE_HASH_H_

View File

@ -35,13 +35,17 @@
#include "util_cstrike.h"
#include <server_class.h>
#if SOURCE_ENGINE == SE_CSGO
#include "itemdef-hash.h"
#endif
int g_iPriceOffset = -1;
#define REGISTER_NATIVE_ADDR(name, code) \
void *addr; \
if (!g_pGameConf->GetMemSig(name, &addr) || !addr) \
{ \
return pContext->ThrowNativeError("Failed to locate function"); \
return pContext->ThrowNativeError("Failed to lookup %s signature.", name); \
} \
code; \
g_RegNatives.Register(pWrapper);
@ -49,7 +53,7 @@ int g_iPriceOffset = -1;
#define GET_MEMSIG(name) \
if (!g_pGameConf->GetMemSig(name, &addr) || !addr) \
{ \
return pContext->ThrowNativeError("Failed to locate function"); \
return pContext->ThrowNativeError("Failed to lookup %s signature.", name); \
}
inline CBaseEntity *GetCBaseEntity(int num, bool isplayer)
@ -366,6 +370,10 @@ static cell_t CS_TerminateRound(IPluginContext *pContext, const cell_t *params)
static cell_t CS_WeaponIDToAlias(IPluginContext *pContext, const cell_t *params)
{
#if SOURCE_ENGINE == SE_CSGO
if(g_mapClassToDefIdx.elements() == 0)
return pContext->ThrowNativeError("Failed to create weapon hashmap");
#endif
if (!IsValidWeaponID(params[1]))
return pContext->ThrowNativeError("Invalid WeaponID passed for this game");
@ -409,7 +417,7 @@ static cell_t CS_GetWeaponPrice(IPluginContext *pContext, const cell_t *params)
if (!IsValidWeaponID(params[2]))
return pContext->ThrowNativeError("Invalid WeaponID passed for this game");
int id = GetRealWeaponID(params[2]);
int id = params[2];
//Hard code return values for weapons that dont call GetWeaponPrice and always use default value.
if (id == WEAPON_C4 || id == WEAPON_KNIFE || id == WEAPON_SHIELD)
@ -449,55 +457,26 @@ static cell_t CS_GetWeaponPrice(IPluginContext *pContext, const cell_t *params)
#else
static cell_t CS_GetWeaponPrice(IPluginContext *pContext, const cell_t *params)
{
if (g_mapClassToDefIdx.elements() == 0)
return pContext->ThrowNativeError("Failed to create weapon hashmap");
CBaseEntity *pEntity;
if (!(pEntity = GetCBaseEntity(params[1], true)))
{
return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
}
static const char *pPriceKey = NULL;
if (!pPriceKey)
{
pPriceKey = g_pGameConf->GetKeyValue("PriceKey");
if (!pPriceKey)
{
return pContext->ThrowNativeError("Failed to get PriceKey KeyValue.");
}
}
if (!IsValidWeaponID(params[2]))
return pContext->ThrowNativeError("Invalid WeaponID passed for this game");
int id = GetRealWeaponID(params[2]);
WeaponIDMap::Result res = g_mapWeaponIDToDefIdx.find((SMCSWeapon)params[2]);
char classname[128];
if (id < CSGOWeapon_KEVLAR)
Q_snprintf(classname, sizeof(classname), "weapon_%s", WeaponIDToAlias(params[2]));
else
Q_snprintf(classname, sizeof(classname), "item_%s", WeaponIDToAlias(params[2]));
CEconItemDefinition *pDef = GetItemDefintionByName(classname);
if (!pDef)
{
return pContext->ThrowNativeError("Failed to get CEconItemDefinition for %s", classname);
}
KeyValues *pAttributes = pDef->m_pKv->FindKey("attributes", false);
if (!pAttributes)
{
return pContext->ThrowNativeError("Failed to get item attributes keyvalue for %s", classname);
}
int price = pAttributes->GetInt(pPriceKey, 0);
int price = res->value.m_iPrice;
if (params[3] || weaponNameOffset == -1)
return price;
return CallPriceForward(params[1], WeaponIDToAlias(params[2]), price);
return CallPriceForward(params[1], res->value.m_szClassname, price);
}
#endif
@ -577,30 +556,15 @@ static cell_t CS_SetClientClanTag(IPluginContext *pContext, const cell_t *params
static cell_t CS_AliasToWeaponID(IPluginContext *pContext, const cell_t *params)
{
#if SOURCE_ENGINE == SE_CSGO
if (g_mapClassToDefIdx.elements() == 0)
return pContext->ThrowNativeError("Failed to create weapon hashmap");
#endif
char *weapon;
pContext->LocalToString(params[1], &weapon);
#if SOURCE_ENGINE == SE_CSGO
if (strstr(weapon, "usp_silencer") != NULL)
{
return SMCSWeapon_HKP2000;
}
else if(strstr(weapon, "cz75a") != NULL)
{
return SMCSWeapon_P250;
}
else if (strstr(weapon, "m4a1_silencer") != NULL)
{
return SMCSWeapon_M4A1;
}
else if (strstr(weapon, "revolver") != NULL)
{
return SMCSWeapon_DEAGLE;
}
#endif
int id = GetFakeWeaponID(AliasToWeaponID(weapon));
int id = AliasToWeaponID(weapon);
if (!IsValidWeaponID(id))
return SMCSWeapon_NONE;
@ -843,42 +807,6 @@ static cell_t CS_GetMVPCount(IPluginContext *pContext, const cell_t *params)
return GetPlayerVar<int>(pContext, params, "MVPs");
}
static cell_t CS_SetClientContributionScore(IPluginContext *pContext, const cell_t *params)
{
#if SOURCE_ENGINE == SE_CSGO
return SetPlayerVar<int>(pContext, params, "CScore");
#else
return pContext->ThrowNativeError("SetClientContributionScore is not supported on this game");
#endif
}
static cell_t CS_GetClientContributionScore(IPluginContext *pContext, const cell_t *params)
{
#if SOURCE_ENGINE == SE_CSGO
return GetPlayerVar<int>(pContext, params, "CScore");
#else
return pContext->ThrowNativeError("GetClientContributionScore is not supported on this game");
#endif
}
static cell_t CS_SetClientAssists(IPluginContext *pContext, const cell_t *params)
{
#if SOURCE_ENGINE == SE_CSGO
return SetPlayerVar<int>(pContext, params, "Assists");
#else
return pContext->ThrowNativeError("SetClientAssists is not supported on this game");
#endif
}
static cell_t CS_GetClientAssists(IPluginContext *pContext, const cell_t *params)
{
#if SOURCE_ENGINE == SE_CSGO
return GetPlayerVar<int>(pContext, params, "Assists");
#else
return pContext->ThrowNativeError("GetClientAssists is not supported on this game");
#endif
}
static cell_t CS_UpdateClientModel(IPluginContext *pContext, const cell_t *params)
{
static ICallWrapper *pWrapper = NULL;
@ -898,6 +826,50 @@ static cell_t CS_UpdateClientModel(IPluginContext *pContext, const cell_t *param
return 1;
}
//CS:GO only natives below this.
#if SOURCE_ENGINE == SE_CSGO
static cell_t CS_SetClientContributionScore(IPluginContext *pContext, const cell_t *params)
{
return SetPlayerVar<int>(pContext, params, "CScore");
}
static cell_t CS_GetClientContributionScore(IPluginContext *pContext, const cell_t *params)
{
return GetPlayerVar<int>(pContext, params, "CScore");
}
static cell_t CS_SetClientAssists(IPluginContext *pContext, const cell_t *params)
{
return SetPlayerVar<int>(pContext, params, "Assists");
}
static cell_t CS_GetClientAssists(IPluginContext *pContext, const cell_t *params)
{
return GetPlayerVar<int>(pContext, params, "Assists");
}
static cell_t CS_ItemDefIndexToID(IPluginContext *pContext, const cell_t *params)
{
ItemIndexMap::Result res = g_mapDefIdxToClass.find((uint16_t)params[1]);
if (!res.found())
return pContext->ThrowNativeError("Invalid item definition passed.");
return res->value.m_iWeaponID;
}
static cell_t CS_WeaponIDToItemDefIndex(IPluginContext *pContext, const cell_t *params)
{
WeaponIDMap::Result res = g_mapWeaponIDToDefIdx.find((SMCSWeapon)params[1]);
if (!res.found())
return pContext->ThrowNativeError("Invalid weapon id passed.");
return res->value.m_iDefIdx;
}
#endif
sp_nativeinfo_t g_CSNatives[] =
{
{"CS_RespawnPlayer", CS_RespawnPlayer},
@ -914,12 +886,16 @@ sp_nativeinfo_t g_CSNatives[] =
{"CS_GetMVPCount", CS_GetMVPCount},
{"CS_SetMVPCount", CS_SetMVPCount},
{"CS_WeaponIDToAlias", CS_WeaponIDToAlias},
{"CS_UpdateClientModel", CS_UpdateClientModel},
{"CS_IsValidWeaponID", CS_IsValidWeaponID},
#if SOURCE_ENGINE == SE_CSGO
{"CS_GetClientContributionScore", CS_GetClientContributionScore},
{"CS_SetClientContributionScore", CS_SetClientContributionScore},
{"CS_GetClientAssists", CS_GetClientAssists},
{"CS_SetClientAssists", CS_SetClientAssists},
{"CS_UpdateClientModel", CS_UpdateClientModel},
{"CS_IsValidWeaponID", CS_IsValidWeaponID},
{"CS_ItemDefIndexToID", CS_ItemDefIndexToID},
{"CS_WeaponIDToItemDefIndex", CS_WeaponIDToItemDefIndex},
#endif
{NULL, NULL}
};

File diff suppressed because it is too large Load Diff

View File

@ -31,158 +31,9 @@
#ifndef _INCLUDE_CSTRIKE_UTIL_H_
#define _INCLUDE_CSTRIKE_UTIL_H_
#if SOURCE_ENGINE == SE_CSGO
#include "extension.h"
class CEconItemView;
class CCSWeaponData;
class CEconItemSchema;
class CEconItemDefinition
{
public:
void **m_pVtable;
KeyValues *m_pKv;
uint16_t m_iDefinitionIndex;
int GetDefaultLoadoutSlot()
{
static int iLoadoutSlotOffset = -1;
if (iLoadoutSlotOffset == -1)
{
if (!g_pGameConf->GetOffset("LoadoutSlotOffset", &iLoadoutSlotOffset) || iLoadoutSlotOffset == -1)
{
iLoadoutSlotOffset = -1;
return -1;
}
}
return *(int *)((intptr_t)this + iLoadoutSlotOffset);
}
};
CEconItemView *GetEconItemView(CBaseEntity *pEntity, int iSlot);
CCSWeaponData *GetCCSWeaponData(CEconItemView *view);
CEconItemSchema *GetItemSchema();
CEconItemDefinition *GetItemDefintionByName(const char *classname);
static const char *szWeaponInfo[] =
{
"none",
"deagle",
"elite",
"fiveseven",
"glock",
"p228",
"usp",
"ak47",
"aug",
"awp",
"famas",
"g3sg1",
"galil",
"galilar",
"m249",
"m3",
"m4a1",
"mac10",
"mp5",
"p90",
"scout",
"sg550",
"sg552",
"tmp",
"ump45",
"xm1014",
"bizon",
"mag7",
"negev",
"sawedoff",
"tec9",
"taser",
"hkp2000",
"mp7",
"mp9",
"nova",
"p250",
"scar17",
"scar20",
"sg556",
"ssg08",
"knifegg",
"knife",
"flashbang",
"hegrenade",
"smokegrenade",
"molotov",
"decoy",
"incgrenade",
"c4",
"kevlar",
"assaultsuit",
"nvg",
"defuser"
};
enum CSGOWeapon
{
CSGOWeapon_NONE,
CSGOWeapon_DEAGLE,
CSGOWeapon_ELITE,
CSGOWeapon_FIVESEVEN,
CSGOWeapon_GLOCK,
CSGOWeapon_P228,
CSGOWeapon_USP,
CSGOWeapon_AK47,
CSGOWeapon_AUG,
CSGOWeapon_AWP,
CSGOWeapon_FAMAS,
CSGOWeapon_G3SG1,
CSGOWeapon_GALIL,
CSGOWeapon_GALILAR,
CSGOWeapon_M249,
CSGOWeapon_M3,
CSGOWeapon_M4A1,
CSGOWeapon_MAC10,
CSGOWeapon_MP5NAVY,
CSGOWeapon_P90,
CSGOWeapon_SCOUT,
CSGOWeapon_SG550,
CSGOWeapon_SG552,
CSGOWeapon_TMP,
CSGOWeapon_UMP45,
CSGOWeapon_XM1014,
CSGOWeapon_BIZON,
CSGOWeapon_MAG7,
CSGOWeapon_NEGEV,
CSGOWeapon_SAWEDOFF,
CSGOWeapon_TEC9,
CSGOWeapon_TASER,
CSGOWeapon_HKP2000,
CSGOWeapon_MP7,
CSGOWeapon_MP9,
CSGOWeapon_NOVA,
CSGOWeapon_P250,
CSGOWeapon_SCAR17,
CSGOWeapon_SCAR20,
CSGOWeapon_SG556,
CSGOWeapon_SSG08,
CSGOWeapon_KNIFE_GG,
CSGOWeapon_KNIFE,
CSGOWeapon_FLASHBANG,
CSGOWeapon_HEGRENADE,
CSGOWeapon_SMOKEGRENADE,
CSGOWeapon_MOLOTOV,
CSGOWeapon_DECOY,
CSGOWeapon_INCGRENADE,
CSGOWeapon_C4, //49
CSGOWeapon_KEVLAR = 50,
CSGOWeapon_ASSAULTSUIT,
CSGOWeapon_NVG,
CSGOWeapon_DEFUSER
};
#endif
//THIS IS THE INCLUDE ENUM DO NOT CHANGE ONLY UPDATE THE INCLUDE
//This is used to match to old weaponid's to their correct enum value
//Anything after heavy assault suit will pass the itemdef as they will be the id set in include
enum SMCSWeapon
{
SMCSWeapon_NONE = 0,
@ -239,22 +90,117 @@ enum SMCSWeapon
SMCSWeapon_MOLOTOV,
SMCSWeapon_DECOY,
SMCSWeapon_INCGRENADE,
SMCSWeapon_DEFUSER
SMCSWeapon_DEFUSER,
SMCSWeapon_HEAVYASSAULTSUIT,
SMCSWeapon_MAXWEAPONIDS, //This only exists here... the include has more. This is for easy array construction
};
#if SOURCE_ENGINE != SE_CSGO
#if SOURCE_ENGINE == SE_CSGO
//These are the ItemDefintion indexs they are used as a reference to create GetWeaponIdFromDefIdx
/*
enum CSGOItemDefs
{
CSGOItemDef_NONE = 0,
CSGOItemDef_DEAGLE,
CSGOItemDef_ELITE,
CSGOItemDef_FIVESEVEN,
CSGOItemDef_GLOCK,
CSGOItemDef_P228,
CSGOItemDef_USP,
CSGOItemDef_AK47,
CSGOItemDef_AUG,
CSGOItemDef_AWP,
CSGOItemDef_FAMAS,
CSGOItemDef_G3SG1,
CSGOItemDef_GALIL,
CSGOItemDef_GALILAR,
CSGOItemDef_M249,
CSGOItemDef_M3,
CSGOItemDef_M4A1,
CSGOItemDef_MAC10,
CSGOItemDef_MP5NAVY,
CSGOItemDef_P90,
CSGOItemDef_SCOUT,
CSGOItemDef_SG550,
CSGOItemDef_SG552,
CSGOItemDef_TMP,
CSGOItemDef_UMP45,
CSGOItemDef_XM1014,
CSGOItemDef_BIZON,
CSGOItemDef_MAG7,
CSGOItemDef_NEGEV,
CSGOItemDef_SAWEDOFF,
CSGOItemDef_TEC9,
CSGOItemDef_TASER,
CSGOItemDef_HKP2000,
CSGOItemDef_MP7,
CSGOItemDef_MP9,
CSGOItemDef_NOVA,
CSGOItemDef_P250,
CSGOItemDef_SCAR17,
CSGOItemDef_SCAR20,
CSGOItemDef_SG556,
CSGOItemDef_SSG08,
CSGOItemDef_KNIFE_GG,
CSGOItemDef_KNIFE,
CSGOItemDef_FLASHBANG,
CSGOItemDef_HEGRENADE,
CSGOItemDef_SMOKEGRENADE,
CSGOItemDef_MOLOTOV,
CSGOItemDef_DECOY,
CSGOItemDef_INCGRENADE,
CSGOItemDef_C4,
CSGOItemDef_KEVLAR,
CSGOItemDef_ASSAULTSUIT,
CSGOItemDef_HEAVYASSAULTSUIT,
CSGOItemDef_UNUSED,
CSGOItemDef_NVG,
CSGOItemDef_DEFUSER,
CSGOItemDef_MAXDEFS,
};
*/
struct ItemDefHashValue;
class CEconItemView;
class CCSWeaponData;
class CEconItemSchema;
class CEconItemDefinition
{
public:
void **m_pVtable;
KeyValues *m_pKv;
uint16_t m_iDefinitionIndex;
int GetDefaultLoadoutSlot()
{
static int iLoadoutSlotOffset = -1;
if (iLoadoutSlotOffset == -1)
{
if (!g_pGameConf->GetOffset("LoadoutSlotOffset", &iLoadoutSlotOffset) || iLoadoutSlotOffset == -1)
{
iLoadoutSlotOffset = -1;
return -1;
}
}
return *(int *)((intptr_t)this + iLoadoutSlotOffset);
}
};
CEconItemView *GetEconItemView(CBaseEntity *pEntity, int iSlot);
CCSWeaponData *GetCCSWeaponData(CEconItemView *view);
CEconItemSchema *GetItemSchema();
CEconItemDefinition *GetItemDefintionByName(const char *classname);
void CreateHashMaps();
void ClearHashMaps();
SMCSWeapon GetWeaponIdFromDefIdx(uint16_t iDefIdx);
ItemDefHashValue *GetHashValueFromWeapon(const char *szWeapon);
#else //CS:S ONLY STUFF
void *GetWeaponInfo(int weaponID);
#endif
const char *GetWeaponNameFromClassname(const char *weapon);
const char *GetTranslatedWeaponAlias(const char *weapon);
int AliasToWeaponID(const char *weapon);
const char *WeaponIDToAlias(int weaponID);
int GetRealWeaponID(int weaponId);
int GetFakeWeaponID(int weaponId);
bool IsValidWeaponID(int weaponId);
#endif

View File

@ -82,6 +82,14 @@
"linux" "588"
"mac" "588"
}
// Offset into CEconItemSchema * to a hashmap of all itemdefs
// Offset can be found in... GetItemDefinitionMutable (easy to get offset on windows should be the same)
"ItemDefHashOffset"
{
"windows" "172"
"linux" "172"
"mac" "172"
}
}
"Signatures"
{

View File

@ -109,7 +109,7 @@ enum CSWeaponID
CSWeapon_SHIELD,
CSWeapon_KEVLAR,
CSWeapon_ASSAULTSUIT,
CSWeapon_NIGHTVISION,
CSWeapon_NIGHTVISION, //Anything below is CS:GO ONLY
CSWeapon_GALILAR,
CSWeapon_BIZON,
CSWeapon_MAG7,
@ -130,7 +130,29 @@ enum CSWeaponID
CSWeapon_MOLOTOV,
CSWeapon_DECOY,
CSWeapon_INCGRENADE,
CSWeapon_DEFUSER
CSWeapon_DEFUSER,
CSWeapon_HEAVYASSAULTSUIT,
//The rest are actual item definition indexes for CS:GO
CSWeapon_CUTTERS = 56,
CSWeapon_HEALTHSHOT = 57,
CSWeapon_KNIFE_T = 59,
CSWeapon_M4A1_SILENCER = 60,
CSWeapon_USP_SILENCER = 61,
CSWeapon_CZ75A = 63,
CSWeapon_REVOLVER = 64,
CSWeapon_TAGGRENADE = 68,
CSWeapon_MAX_WEAPONS_NO_KNIFES, // Max without the knife item defs, useful when treating all knives as a regular knife.
CSWeapon_BAYONET = 500,
CSWeapon_KNIFE_FLIP = 505,
CSWeapon_KNIFE_GUT = 506,
CSWeapon_KNIFE_KARAMBIT = 507,
CSWeapon_KNIFE_M9_BAYONET = 508,
CSWeapon_KNIFE_TATICAL = 509,
CSWeapon_KNIFE_FALCHION = 512,
CSWeapon_KNIFE_SURVIVAL_BOWIE = 514,
CSWeapon_KNIFE_BUTTERFLY = 515,
CSWeapon_KNIFE_PUSH = 516,
CSWeapon_MAX_WEAPONS //THIS MUST BE LAST, EASY WAY TO CREATE LOOPS. When looping, do CS_IsValidWeaponID(i), to check.
};
/**
@ -358,7 +380,7 @@ native int CS_WeaponIDToAlias(CSWeaponID weaponID, char[] destination, int len);
* @param weaponID WeaponID to check
* @return Returns true if its a valid WeaponID false otherwise.
*
* @note This will return false always for CSWeapon_NONE
* @note This will return false always for CSWeapon_NONE. Should only be called after OnMapStart since weapon info isnt intialized before.
*/
native bool CS_IsValidWeaponID(CSWeaponID id);
@ -370,6 +392,28 @@ native bool CS_IsValidWeaponID(CSWeaponID id);
*/
native void CS_UpdateClientModel(int client);
/**
* Returns a CSWeaponID equivalent based on the item definition index.
*
* @param iDefIndex Definition index to get the CSWeaponID value for.
* @return Returns CSWeaponID value for the definition index.
*
* @error Invalid definition index.
* @note In most cases the id will be the item definition index. Works for CS:GO ONLY.
*/
native CSWeaponID CS_ItemDefIndexToID(int iDefIndex);
/**
* Returns a item definition index equivalent based on the CSWeaponID.
*
* @param id CSWeaponID to get the item definition for.
* @return Returns item definition index value for the weapon id.
*
* @error Invalid weapon id.
* @note In most cases the item deinition index will be the id. Works for CS:GO ONLY.
*/
native int CS_WeaponIDToItemDefIndex(CSWeaponID id);
/**
* Do not edit below this line!
*/
@ -408,5 +452,7 @@ public void __ext_cstrike_SetNTVOptional()
MarkNativeAsOptional("CS_WeaponIDToAlias");
MarkNativeAsOptional("CS_IsValidWeaponID");
MarkNativeAsOptional("CS_UpdateClientModel");
MarkNativeAsOptional("CS_ItemDefIndexToID");
MarkNativeAsOptional("CS_WeaponIDToItemDefIndex");
}
#endif