2009-04-20 02:56:26 +02:00
/*
* ============================================================================
*
2009-07-05 08:49:23 +02:00
* Zombie : Reloaded
2009-04-20 02:56:26 +02:00
*
2009-06-12 05:51:26 +02:00
* File : weapons . inc
2016-02-06 00:47:47 +01:00
* Type : Core
2009-06-12 05:51:26 +02:00
* Description : API for all weapon - related functions .
*
2013-01-12 08:47:36 +01:00
* Copyright ( C ) 2009 - 2013 Greyscale , Richard Helgeby
2009-06-12 05:51:26 +02:00
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http :// www . gnu . org / licenses />.
2009-04-20 02:56:26 +02:00
*
* ============================================================================
2009-04-12 08:04:00 +02:00
*/
/**
* Maximum length of a weapon name string
*/
#define WEAPONS_MAX_LENGTH 32
2009-05-29 08:43:15 +02:00
/**
2009-07-07 06:32:34 +02:00
* Number of REAL weapon slots ( For CS : S )
2009-05-29 08:43:15 +02:00
*/
#define WEAPONS_SLOTS_MAX 5
2009-06-27 03:33:09 +02:00
/**
2017-08-07 23:50:39 +02:00
* @ section start weapons .
2009-06-27 03:33:09 +02:00
*/
2017-08-07 23:50:39 +02:00
#define WEAPONS_SPAWN_CSS_T_WEAPON "weapon_glock"
#define WEAPONS_SPAWN_CSS_CT_WEAPON "weapon_usp"
#define WEAPONS_SPAWN_CSGO_T_WEAPON "weapon_glock"
2017-10-06 13:49:40 +02:00
#define WEAPONS_SPAWN_CSGO_CT_WEAPON "weapon_hkp2000"
2009-06-27 03:33:09 +02:00
/**
* @ endsection
*/
2009-05-29 08:43:15 +02:00
/**
* Weapon config data indexes .
*/
enum WeaponsData
{
WEAPONS_DATA_NAME = 0 ,
2009-08-25 22:07:10 +02:00
WEAPONS_DATA_ENTITY ,
2009-05-29 08:43:15 +02:00
WEAPONS_DATA_TYPE ,
2009-06-05 05:58:48 +02:00
WEAPONS_DATA_SLOT ,
2009-05-29 08:43:15 +02:00
WEAPONS_DATA_RESTRICTDEFAULT ,
WEAPONS_DATA_TOGGLEABLE ,
WEAPONS_DATA_AMMOTYPE ,
WEAPONS_DATA_AMMOPRICE ,
WEAPONS_DATA_KNOCKBACK ,
WEAPONS_DATA_ZMARKETPRICE ,
2009-06-05 05:58:48 +02:00
WEAPONS_DATA_ZMARKETPURCHASEMAX ,
2016-02-12 04:16:59 +01:00
WEAPONS_DATA_ZMARKETCOMMAND ,
2009-05-29 08:43:15 +02:00
WEAPONS_DATA_RESTRICTED ,
}
2009-04-12 08:04:00 +02:00
/**
* @ endsection
*/
2009-04-20 05:43:20 +02:00
/**
2009-05-29 08:43:15 +02:00
* Variable to store active weapon offset value .
2009-04-20 05:43:20 +02:00
*/
2009-05-29 08:43:15 +02:00
new g_iToolsActiveWeapon ;
2009-04-20 05:43:20 +02:00
/**
2009-05-29 08:43:15 +02:00
* Weapon slots .
2009-04-20 05:43:20 +02:00
*/
2009-05-29 08:43:15 +02:00
enum WeaponsSlot
2009-04-20 05:43:20 +02:00
{
2009-05-29 08:43:15 +02:00
Slot_Invalid = - 1 , /** Invalid weapon (slot). */
Slot_Primary = 0 , /** Primary weapon slot. */
Slot_Secondary = 1 , /** Secondary weapon slot. */
Slot_Melee = 2 , /** Melee (knife) weapon slot. */
Slot_Projectile = 3 , /** Projectile (grenades, flashbangs, etc) weapon slot. */
Slot_Explosive = 4 , /** Explosive (c4) weapon slot. */
2009-07-07 06:32:34 +02:00
Slot_NVGs = 5 , /** NVGs (fake) equipment slot. */
2009-04-20 05:43:20 +02:00
}
2009-05-01 07:09:18 +02:00
2009-04-12 08:04:00 +02:00
/**
2009-05-29 08:43:15 +02:00
* Array handle to store weapon config data .
2009-04-12 08:04:00 +02:00
*/
2009-05-29 08:43:15 +02:00
new Handle : arrayWeapons = INVALID_HANDLE ;
2009-04-12 08:04:00 +02:00
#include "zr/weapons/restrict"
2009-05-29 08:43:15 +02:00
#include "zr/weapons/weaponammo"
#include "zr/weapons/zmarket"
2009-04-12 08:04:00 +02:00
#include "zr/weapons/menu_weapons"
2009-04-14 04:58:05 +02:00
/**
2009-04-15 09:42:12 +02:00
* Weapons module init function .
2009-06-20 09:15:43 +02:00
*/
2009-04-13 20:33:13 +02:00
WeaponsInit ()
{
2009-05-29 08:43:15 +02:00
// Forward event to sub-modules.
2009-04-13 20:33:13 +02:00
RestrictInit ();
}
2009-08-25 22:07:10 +02:00
/**
* All plugins have finished loading .
*/
WeaponsOnAllPluginsLoaded ()
{
// Forward event to sub-modules.
2009-08-26 09:07:01 +02:00
WeaponAmmoOnAllPluginsLoaded ();
2009-08-25 22:07:10 +02:00
}
2009-05-18 06:26:13 +02:00
/**
2009-05-29 08:43:15 +02:00
* Find active weapon - specific offsets here .
2009-05-18 06:26:13 +02:00
*/
2009-05-29 08:43:15 +02:00
WeaponsOnOffsetsFound ()
2009-05-18 06:26:13 +02:00
{
2009-05-29 08:43:15 +02:00
// If offset "m_hActiveWeapon" can't be found, then stop the plugin.
g_iToolsActiveWeapon = FindSendPropInfo ( " CBasePlayer " , " m_hActiveWeapon " );
if ( g_iToolsActiveWeapon == - 1 )
{
2009-06-01 23:29:26 +02:00
LogEvent ( false , LogType_Fatal , LOG_CORE_EVENTS , LogModule_Weapons , " Offsets " , " Offset \" CBasePlayer::m_hActiveWeapon \" was not found. " );
2009-05-29 08:43:15 +02:00
}
2016-02-06 00:47:47 +01:00
2010-02-14 17:03:19 +01:00
// If offset "m_bInBuyZone" can't be found, then stop the plugin.
g_iToolsInBuyZone = FindSendPropInfo ( " CCSPlayer " , " m_bInBuyZone " );
if ( g_iToolsInBuyZone == - 1 )
{
LogEvent ( false , LogType_Fatal , LOG_CORE_EVENTS , LogModule_Weapons , " Offsets " , " Offset \" CCSPlayer::m_bInBuyZone \" was not found. " );
}
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
// Forward event to sub-modules
WeaponAmmoOnOffsetsFound ();
2009-05-18 06:26:13 +02:00
}
2009-04-12 08:04:00 +02:00
/**
2009-05-29 08:43:15 +02:00
* Create commands related to weapons here .
2009-04-12 08:04:00 +02:00
*/
2009-05-29 08:43:15 +02:00
WeaponsOnCommandsCreate ()
2009-04-12 08:04:00 +02:00
{
2009-05-29 08:43:15 +02:00
// Forward event to sub-modules.
RestrictOnCommandsCreate ();
2009-06-17 23:32:46 +02:00
ZMarketOnCommandsCreate ();
2009-04-14 04:58:05 +02:00
}
2009-06-21 21:24:24 +02:00
/**
* Create weapon - related cookies here .
*/
WeaponsOnCookiesCreate ()
{
// Forward event to sub-modules.
ZMarketOnCookiesCreate ();
}
2009-04-14 04:58:05 +02:00
/**
* Loads weapon data from file .
*/
2009-04-15 03:24:02 +02:00
WeaponsLoad ()
2009-04-14 04:58:05 +02:00
{
2009-05-29 08:43:15 +02:00
// Register config file.
ConfigRegisterConfig ( File_Weapons , Structure_Keyvalue , CONFIG_FILE_ALIAS_WEAPONS );
2016-02-06 00:47:47 +01:00
2009-04-20 02:56:26 +02:00
// If module is disabled, then stop.
new bool : weapons = GetConVarBool ( g_hCvarsList [ CVAR_WEAPONS ]);
if ( ! weapons )
{
return ;
}
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
// Get weapons config path.
decl String : pathweapons [ PLATFORM_MAX_PATH ];
new bool : exists = ConfigGetCvarFilePath ( CVAR_CONFIG_PATH_WEAPONS , pathweapons );
2016-02-06 00:47:47 +01:00
2009-04-30 07:36:57 +02:00
// If file doesn't exist, then log and stop.
if ( ! exists )
2009-04-12 08:04:00 +02:00
{
2009-04-30 07:36:57 +02:00
// Log failure.
2009-06-01 23:29:26 +02:00
LogEvent ( false , LogType_Error , LOG_CORE_EVENTS , LogModule_Weapons , " Config Validation " , " Missing weapons config file: %s " , pathweapons );
2016-02-06 00:47:47 +01:00
2009-04-14 04:58:05 +02:00
return ;
2009-04-12 08:04:00 +02:00
}
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
// Set the path to the config file.
ConfigSetConfigPath ( File_Weapons , pathweapons );
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
// Load config from file and create array structure.
new bool : success = ConfigLoadConfig ( File_Weapons , arrayWeapons );
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
// Unexpected error, stop plugin.
if ( ! success )
{
2009-12-31 20:04:03 +01:00
LogEvent ( false , LogType_Fatal , LOG_CORE_EVENTS , LogModule_Weapons , " Config Validation " , " Unexpected error encountered loading: %s " , pathweapons );
2009-05-29 08:43:15 +02:00
}
2016-02-06 00:47:47 +01:00
2009-04-15 09:42:12 +02:00
// Validate weapons config.
2009-05-29 08:43:15 +02:00
new size = GetArraySize ( arrayWeapons );
if ( ! size )
{
2009-06-01 23:29:26 +02:00
LogEvent ( false , LogType_Error , LOG_CORE_EVENTS , LogModule_Weapons , " Config Validation " , " No usable data found in weapons config file: %s " , pathweapons );
2009-05-29 08:43:15 +02:00
}
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
// Now copy data to array structure.
WeaponsCacheData ();
2016-02-06 00:47:47 +01:00
2009-05-18 06:26:13 +02:00
// Set config data.
2009-05-29 08:43:15 +02:00
ConfigSetConfigLoaded ( File_Weapons , true );
ConfigSetConfigReloadFunc ( File_Weapons , GetFunctionByName ( GetMyHandle (), " WeaponsOnConfigReload " ));
ConfigSetConfigHandle ( File_Weapons , arrayWeapons );
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
// Forward event to sub-modules
2009-05-18 06:26:13 +02:00
RestrictLoad ();
2016-02-12 04:16:59 +01:00
ZMarketLoad ();
2009-05-18 06:26:13 +02:00
}
/**
2009-05-29 08:43:15 +02:00
* Caches weapon data from file into arrays .
* Make sure the file is loaded before ( ConfigLoadConfig ) to prep array structure .
2009-05-18 06:26:13 +02:00
*/
2009-05-29 08:43:15 +02:00
WeaponsCacheData ()
2009-05-18 06:26:13 +02:00
{
2009-05-29 08:43:15 +02:00
// Get config's file path.
decl String : pathweapons [ PLATFORM_MAX_PATH ];
ConfigGetConfigPath ( File_Weapons , pathweapons , sizeof ( pathweapons ));
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
new Handle : kvWeapons ;
new bool : success = ConfigOpenConfigFile ( File_Weapons , kvWeapons );
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
if ( ! success )
2009-05-18 06:26:13 +02:00
{
2009-12-31 20:04:03 +01:00
LogEvent ( false , LogType_Fatal , LOG_CORE_EVENTS , LogModule_Weapons , " Config Validation " , " Unexpected error caching data from weapons config file: %s " , pathweapons );
2009-05-29 08:43:15 +02:00
}
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
decl String : weaponname [ WEAPONS_MAX_LENGTH ];
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
// x = array index
new size = GetArraySize ( arrayWeapons );
for ( new x = 0 ; x < size ; x ++ )
{
WeaponsGetName ( x , weaponname , sizeof ( weaponname ));
KvRewind ( kvWeapons );
if ( ! KvJumpToKey ( kvWeapons , weaponname ))
{
2009-06-01 23:29:26 +02:00
LogEvent ( false , LogType_Error , LOG_CORE_EVENTS , LogModule_Weapons , " Config Validation " , " Couldn't cache weapon data for: %s (check weapons config) " , weaponname );
2009-05-29 08:43:15 +02:00
continue ;
}
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
// Get config data.
2016-02-06 00:47:47 +01:00
2009-08-25 22:07:10 +02:00
decl String : weaponentity [ CONFIG_MAX_LENGTH ];
2009-05-29 08:43:15 +02:00
decl String : weapontype [ CONFIG_MAX_LENGTH ];
decl String : ammotype [ CONFIG_MAX_LENGTH ];
2016-02-12 04:16:59 +01:00
decl String : zmarketcommand [ CONFIG_MAX_LENGTH ];
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
// General
2009-08-25 22:07:10 +02:00
KvGetString ( kvWeapons , " weaponentity " , weaponentity , sizeof ( weaponentity ));
2009-05-29 08:43:15 +02:00
KvGetString ( kvWeapons , " weapontype " , weapontype , sizeof ( weapontype ));
2009-06-05 05:58:48 +02:00
new WeaponsSlot : weaponslot = WeaponsSlot : KvGetNum ( kvWeapons , " weaponslot " , - 1 );
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
// Restrict (core)
new bool : restrictdefault = ConfigKvGetStringBool ( kvWeapons , " restrictdefault " , " no " );
new bool : toggleable = ConfigKvGetStringBool ( kvWeapons , " toggleable " , " yes " );
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
// Weapon Ammo (core)
KvGetString ( kvWeapons , " ammotype " , ammotype , sizeof ( ammotype ));
2009-06-05 05:58:48 +02:00
new ammoprice = KvGetNum ( kvWeapons , " ammoprice " , - 1 );
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
// Knockback (module)
new Float : knockback = KvGetFloat ( kvWeapons , " knockback " , 1.0 );
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
// ZMarket (module)
new zmarketprice = KvGetNum ( kvWeapons , " zmarketprice " , - 1 );
2018-01-15 00:37:00 +01:00
new zmarketpurchasemax = KvGetNum ( kvWeapons , " zmarketpurchasemax " , - 1 );
2016-02-12 04:16:59 +01:00
KvGetString ( kvWeapons , " zmarketcommand " , zmarketcommand , sizeof ( zmarketcommand ), " " );
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
new Handle : arrayWeapon = GetArrayCell ( arrayWeapons , x );
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
// Push data into array.
2009-08-25 22:07:10 +02:00
PushArrayString ( arrayWeapon , weaponentity ); // Index: 1
PushArrayString ( arrayWeapon , weapontype ); // Index: 2
PushArrayCell ( arrayWeapon , weaponslot ); // Index: 3
PushArrayCell ( arrayWeapon , restrictdefault ); // Index: 4
PushArrayCell ( arrayWeapon , toggleable ); // Index: 5
PushArrayString ( arrayWeapon , ammotype ); // Index: 6
PushArrayCell ( arrayWeapon , ammoprice ); // Index: 7
PushArrayCell ( arrayWeapon , knockback ); // Index: 8
PushArrayCell ( arrayWeapon , zmarketprice ); // Index: 9
2016-02-12 04:16:59 +01:00
PushArrayCell ( arrayWeapon , zmarketpurchasemax ); // Index: 10
PushArrayString ( arrayWeapon , zmarketcommand ); // Index: 11
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
// Initialize other stored weapon info here.
2016-02-12 04:16:59 +01:00
PushArrayCell ( arrayWeapon , restrictdefault ); // Index: 12
2009-05-18 06:26:13 +02:00
}
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
// We're done with this file now, so we can close it.
CloseHandle ( kvWeapons );
2009-04-13 20:33:13 +02:00
}
2009-04-15 09:42:12 +02:00
/**
2009-05-29 08:43:15 +02:00
* Called when config is being reloaded .
2009-04-17 01:09:52 +02:00
*/
2009-05-29 08:43:15 +02:00
public WeaponsOnConfigReload ()
2009-04-13 20:33:13 +02:00
{
2009-05-29 08:43:15 +02:00
// Reload weapons config.
WeaponsLoad ();
2009-04-13 20:33:13 +02:00
}
2016-02-06 00:47:47 +01:00
2009-04-15 09:42:12 +02:00
/**
* Client is joining the server .
2016-02-06 00:47:47 +01:00
*
* @ param client The client index .
2009-04-19 19:54:21 +02:00
*/
2009-04-13 20:33:13 +02:00
WeaponsClientInit ( client )
{
2009-06-05 05:58:48 +02:00
// Forward event to sub-modules.
2009-04-13 20:33:13 +02:00
RestrictClientInit ( client );
2009-06-05 05:58:48 +02:00
ZMarketClientInit ( client );
2009-04-13 20:33:13 +02:00
}
2010-02-20 02:41:24 +01:00
/**
* Called once a client ' s saved cookies have been loaded from the database .
2016-02-06 00:47:47 +01:00
*
2010-02-20 02:41:24 +01:00
* @ param client Client index .
*/
WeaponsOnCookiesCached ( client )
{
// Forward event to sub-modules.
ZMarketOnCookiesCached ( client );
}
2009-04-15 09:42:12 +02:00
/**
* Client is leaving the server .
2016-02-06 00:47:47 +01:00
*
2009-04-15 09:42:12 +02:00
* @ param client The client index .
2009-06-05 05:58:48 +02:00
*/
2009-04-13 20:33:13 +02:00
WeaponsOnClientDisconnect ( client )
{
2009-06-05 05:58:48 +02:00
// Forward event to sub-modules.
2009-04-13 20:33:13 +02:00
RestrictOnClientDisconnect ( client );
2009-06-05 05:58:48 +02:00
ZMarketOnClientDisconnect ( client );
}
/**
* Client is spawning into the game .
2016-02-06 00:47:47 +01:00
*
2009-06-05 05:58:48 +02:00
* @ param client The client index .
*/
WeaponsOnClientSpawn ( client )
{
// Forward event to sub-modules.
RestrictOnClientSpawn ( client );
2009-04-12 08:04:00 +02:00
}
2009-05-19 08:14:18 +02:00
/**
2009-06-21 21:24:24 +02:00
* Client is spawning into the game . * Post
2016-02-06 00:47:47 +01:00
*
2009-06-21 21:24:24 +02:00
* @ param client The client index .
2009-05-19 08:14:18 +02:00
*/
2009-06-21 21:24:24 +02:00
WeaponsOnClientSpawnPost ( client )
2009-05-19 08:14:18 +02:00
{
2010-01-04 08:25:35 +01:00
// Refresh all weapons on clients to cleanup any rendering errors.
WeaponsRefreshAllClientWeapons ( client );
2016-02-06 00:47:47 +01:00
2009-06-21 21:24:24 +02:00
// Forward event to sub-modules.
ZMarketOnClientSpawnPost ( client );
2009-05-19 08:14:18 +02:00
}
2009-06-27 03:33:09 +02:00
/**
* The round is ending .
*/
WeaponsOnRoundEnd ()
{
// Forward event to sub-modules.
RestrictOnRoundEnd ();
}
2009-04-12 08:04:00 +02:00
/**
2009-05-29 08:43:15 +02:00
* Weapon data reading API .
*/
/**
* Clear cache for a given weapon .
2016-02-06 00:47:47 +01:00
*
2009-05-29 08:43:15 +02:00
* @ param index The weapon index .
*/
2009-06-19 00:53:22 +02:00
stock WeaponsClearCache ( index )
2009-05-29 08:43:15 +02:00
{
// Get array handle of weapon at given index.
new Handle : hWeapon = GetArrayCell ( arrayWeapons , index );
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
// Clear array.
ClearArray ( hWeapon );
}
/**
* Find the index at which the weapon ' s name is at .
2016-02-06 00:47:47 +01:00
*
2009-05-29 08:43:15 +02:00
* @ param weapon The weapon name .
* @ return The array index containing the given weapon name .
2009-04-12 08:04:00 +02:00
*/
2009-05-29 08:43:15 +02:00
stock WeaponsNameToIndex ( const String : weapon [])
2009-04-12 08:04:00 +02:00
{
2009-05-29 08:43:15 +02:00
decl String : weaponname [ WEAPONS_MAX_LENGTH ];
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
// x = Array index.
new size = GetArraySize ( arrayWeapons );
for ( new x = 0 ; x < size ; x ++ )
2009-04-12 08:04:00 +02:00
{
2009-05-29 08:43:15 +02:00
WeaponsGetName ( x , weaponname , sizeof ( weaponname ));
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
// If names match, then return index.
if ( StrEqual ( weapon , weaponname , false ))
2009-04-12 08:04:00 +02:00
{
2009-05-29 08:43:15 +02:00
return x ;
}
2009-04-12 08:04:00 +02:00
}
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
// Name doesn't exist.
return - 1 ;
2009-04-12 08:04:00 +02:00
}
2009-06-19 05:41:54 +02:00
/**
2009-08-25 22:07:10 +02:00
* Takes a weapon ' s entity name and returns the display name in weapons config file .
2016-02-06 00:47:47 +01:00
*
2009-08-25 22:07:10 +02:00
* @ param entityname The entity to find the display of .
* @ param display Buffer to store display name in .
* @ param displaymaxlen The max length of the display name .
* @ param noprefix If this is true , the entity name will be compared without the weapon_ / item_ prefix .
2016-02-06 00:47:47 +01:00
* @ return The index of the weapon found .
2009-06-19 05:41:54 +02:00
*/
2009-08-25 22:07:10 +02:00
stock WeaponsEntityToDisplay ( const String : entityname [], String : display [], displaymaxlen , noprefix = false )
2009-06-19 05:41:54 +02:00
{
2010-08-06 14:49:38 +02:00
// Check if weapon data is loaded.
if ( arrayWeapons == INVALID_HANDLE )
{
return - 1 ;
}
2016-02-06 00:47:47 +01:00
2009-08-25 22:07:10 +02:00
decl String : weaponentity [ WEAPONS_MAX_LENGTH ];
2016-02-06 00:47:47 +01:00
2009-08-25 22:07:10 +02:00
// Initialize string to null.
strcopy ( display , sizeof ( displaymaxlen ), " " );
2016-02-06 00:47:47 +01:00
2009-08-25 22:07:10 +02:00
// x = Array index.
new size = GetArraySize ( arrayWeapons );
for ( new x = 0 ; x < size ; x ++ )
2009-06-19 05:41:54 +02:00
{
2009-08-25 22:07:10 +02:00
// If entity names don't match, then stop.
WeaponsGetEntity ( x , weaponentity , sizeof ( weaponentity ));
2016-02-06 00:47:47 +01:00
2009-08-25 22:07:10 +02:00
// If noprefix is true, then strip the weapon_/item_ prefix.
if ( noprefix )
{
ReplaceString ( weaponentity , sizeof ( weaponentity ), " weapon_ " , " " );
ReplaceString ( weaponentity , sizeof ( weaponentity ), " item_ " , " " );
}
2016-02-06 00:47:47 +01:00
2009-08-25 22:07:10 +02:00
if ( ! StrEqual ( entityname , weaponentity , false ))
{
continue ;
}
2016-02-06 00:47:47 +01:00
2009-08-25 22:07:10 +02:00
// The entity names match, so return display.
WeaponsGetName ( x , display , displaymaxlen );
2016-02-06 00:47:47 +01:00
2009-08-25 22:07:10 +02:00
// Return the weapon index.
return x ;
2009-06-19 05:41:54 +02:00
}
2016-02-06 00:47:47 +01:00
2009-08-25 22:07:10 +02:00
// Nothing was found.
return - 1 ;
2009-06-19 05:41:54 +02:00
}
2009-04-12 08:04:00 +02:00
/**
2009-05-29 08:43:15 +02:00
* Checks if a weapon is valid . ( E . G . listed in weapons . txt )
2009-04-13 20:33:13 +02:00
* @ param weapon The weapon name .
* @ return Returns true if valid , false it not .
2009-04-12 08:04:00 +02:00
*/
2009-05-29 08:43:15 +02:00
stock bool : WeaponsIsWeaponValid ( const String : weapon [])
2009-04-12 08:04:00 +02:00
{
2009-05-29 08:43:15 +02:00
return ( WeaponsNameToIndex ( weapon ) != - 1 );
}
/**
* Gets the name of a weapon at a given index .
* @ param index The weapon index .
* @ param weapon The string to return name in .
* @ param maxlen The max length of the string .
*/
stock WeaponsGetName ( index , String : weapon [], maxlen )
{
// Get array handle of weapon at given index.
new Handle : arrayWeapon = GetArrayCell ( arrayWeapons , index );
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
// Get weapon name.
GetArrayString ( arrayWeapon , _ : WEAPONS_DATA_NAME , weapon , maxlen );
2009-04-12 08:04:00 +02:00
}
2009-08-25 22:07:10 +02:00
/**
* Gets the entity of a weapon at a given index .
* @ param index The weapon index .
* @ param type The string to return entity in .
* @ param maxlen The max length of the string .
*/
stock WeaponsGetEntity ( index , String : type [], maxlen )
{
// Get array handle of weapon at given index.
new Handle : arrayWeapon = GetArrayCell ( arrayWeapons , index );
2016-02-06 00:47:47 +01:00
2009-08-25 22:07:10 +02:00
// Get weapon type.
GetArrayString ( arrayWeapon , _ : WEAPONS_DATA_ENTITY , type , maxlen );
}
2009-04-12 08:04:00 +02:00
/**
2009-05-29 08:43:15 +02:00
* Gets the type of a weapon at a given index .
* @ param index The weapon index .
* @ param type The string to return type in .
* @ param maxlen The max length of the string .
2009-04-12 08:04:00 +02:00
*/
2009-05-29 08:43:15 +02:00
stock WeaponsGetType ( index , String : type [], maxlen )
2009-04-12 08:04:00 +02:00
{
2009-05-29 08:43:15 +02:00
// Get array handle of weapon at given index.
new Handle : arrayWeapon = GetArrayCell ( arrayWeapons , index );
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
// Get weapon type.
GetArrayString ( arrayWeapon , _ : WEAPONS_DATA_TYPE , type , maxlen );
2009-04-12 08:04:00 +02:00
}
2009-06-05 05:58:48 +02:00
/**
* Gets the slot index of a weapon at a given index .
* @ param index The weapon index .
* @ return The slot index of the weapon .
*/
stock WeaponsSlot : WeaponsGetSlot ( index )
{
// Get array handle of weapon at given index.
new Handle : arrayWeapon = GetArrayCell ( arrayWeapons , index );
2016-02-06 00:47:47 +01:00
2009-06-05 05:58:48 +02:00
// Return default restriction status.
return WeaponsSlot : GetArrayCell ( arrayWeapon , _ : WEAPONS_DATA_SLOT );
}
2009-04-12 08:04:00 +02:00
/**
2009-05-29 08:43:15 +02:00
* Gets if a weapon is restricted by default .
* @ param index The weapon index .
* @ return True if the weapon is restricted by default , false if not .
2009-04-12 08:04:00 +02:00
*/
2009-05-29 08:43:15 +02:00
stock bool : WeaponsGetRestrictDefault ( index )
2009-04-12 08:04:00 +02:00
{
2009-05-29 08:43:15 +02:00
// Get array handle of weapon at given index.
new Handle : arrayWeapon = GetArrayCell ( arrayWeapons , index );
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
// Return default restriction status.
return bool : GetArrayCell ( arrayWeapon , _ : WEAPONS_DATA_RESTRICTDEFAULT );
2009-04-14 22:05:20 +02:00
}
/**
2009-05-29 08:43:15 +02:00
* Gets if a weapon ' s restriction status is toggleable .
* @ param index The weapon index .
* @ return True if the weapon restriction can be toggled , false if not .
2009-04-14 22:05:20 +02:00
*/
2009-05-29 08:43:15 +02:00
stock bool : WeaponsGetToggleable ( index )
2009-04-14 22:05:20 +02:00
{
2009-05-29 08:43:15 +02:00
// Get array handle of weapon at given index.
new Handle : arrayWeapon = GetArrayCell ( arrayWeapons , index );
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
// Return if weapon is toggleable.
return bool : GetArrayCell ( arrayWeapon , _ : WEAPONS_DATA_TOGGLEABLE );
}
/**
* Gets the ammo type of a weapon at a given index .
* @ param index The weapon index .
* @ param ammotype The string to return ammotype in .
* @ param maxlen The max length of the string .
*/
stock WeaponsGetAmmoType ( index , String : ammotype [], maxlen )
{
// Get array handle of weapon at given index.
new Handle : arrayWeapon = GetArrayCell ( arrayWeapons , index );
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
// Get ammo type of the weapon.
2009-06-05 05:58:48 +02:00
GetArrayString ( arrayWeapon , _ : WEAPONS_DATA_AMMOTYPE , ammotype , maxlen );
2009-05-29 08:43:15 +02:00
}
/**
* Gets the price of ammo for the weapon .
* @ param index The weapon index .
* @ return The ammo price .
*/
stock WeaponsGetAmmoPrice ( index )
{
// Get array handle of weapon at given index.
new Handle : arrayWeapon = GetArrayCell ( arrayWeapons , index );
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
// Return ammo price of the weapon.
return GetArrayCell ( arrayWeapon , _ : WEAPONS_DATA_AMMOPRICE );
}
/**
* Gets the knockback multiplier for the weapon .
* @ param index The weapon index .
* @ return The weapon knockback multiplier .
*/
stock Float : WeaponsGetKnockback ( index )
{
// Get array handle of weapon at given index.
new Handle : arrayWeapon = GetArrayCell ( arrayWeapons , index );
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
// Return knockback multiplier of the weapon.
return Float : GetArrayCell ( arrayWeapon , _ : WEAPONS_DATA_KNOCKBACK );
}
/**
* Gets the ZMarket price for the weapon .
* @ param index The weapon index .
* @ return The ZMarket price .
*/
stock WeaponsGetZMarketPrice ( index )
{
// Get array handle of weapon at given index.
new Handle : arrayWeapon = GetArrayCell ( arrayWeapons , index );
2016-02-06 00:47:47 +01:00
2009-05-29 08:43:15 +02:00
// Return the ZMarket price of the weapon.
return GetArrayCell ( arrayWeapon , _ : WEAPONS_DATA_ZMARKETPRICE );
2009-04-20 05:43:20 +02:00
}
2009-06-05 05:58:48 +02:00
/**
* Gets the max purchases from ZMarket per round per client of a weapon .
* @ param index The weapon index .
* @ return The max purchases of the weapon .
*/
stock WeaponsGetZMarketPurchaseMax ( index )
{
// Get array handle of weapon at given index.
new Handle : arrayWeapon = GetArrayCell ( arrayWeapons , index );
2016-02-06 00:47:47 +01:00
2009-06-05 05:58:48 +02:00
// Return the ZMarket price of the weapon.
return GetArrayCell ( arrayWeapon , _ : WEAPONS_DATA_ZMARKETPURCHASEMAX );
}
2016-02-12 04:16:59 +01:00
/**
* Gets the name of the command to purchase this weapon through zmarket .
* @ param index The weapon index .
* @ param command The string to return zmarketcommand in .
* @ param maxlen The max length of the string .
* @ return The max purchases of the weapon .
*/
stock WeaponsGetZMarketCommand ( index , String : command [], maxlen )
{
// Get array handle of weapon at given index.
new Handle : arrayWeapon = GetArrayCell ( arrayWeapons , index );
// Return the ZMarket price of the weapon.
GetArrayString ( arrayWeapon , _ : WEAPONS_DATA_ZMARKETCOMMAND , command , maxlen );
}
2009-04-20 05:43:20 +02:00
/**
* General weapon API .
*/
2009-04-22 04:53:19 +02:00
2009-06-05 05:58:48 +02:00
/**
* Checks if a client has a specific weapon .
2016-02-06 00:47:47 +01:00
*
2009-06-05 05:58:48 +02:00
* @ param client The client index .
* @ param weapon The weapon classname .
*/
stock bool : WeaponsClientHasWeapon ( client , const String : weapon [])
{
// Get all of client's current weapons.
new weapons [ WeaponsSlot ];
WeaponsGetClientWeapons ( client , weapons );
2016-02-06 00:47:47 +01:00
2009-06-05 05:58:48 +02:00
decl String : classname [ 64 ];
2016-02-06 00:47:47 +01:00
2009-06-05 05:58:48 +02:00
// x = slot index
for ( new x = 0 ; x < WEAPONS_SLOTS_MAX ; x ++ )
{
// If slot is empty, then stop.
if ( weapons [ x ] == - 1 )
{
continue ;
}
2016-02-06 00:47:47 +01:00
2009-06-05 05:58:48 +02:00
// If the weapon's classname matches, then return true.
GetEdictClassname ( weapons [ x ], classname , sizeof ( classname ));
if ( StrEqual ( weapon , classname , false ))
{
return true ;
}
}
2016-02-06 00:47:47 +01:00
2009-06-05 05:58:48 +02:00
return false ;
}
2009-04-20 05:43:20 +02:00
/**
* Return an array that contains all client ' s weapon indexes .
2016-02-06 00:47:47 +01:00
*
2009-04-20 05:43:20 +02:00
* @ param client The client index .
* @ param weapons The weapon index array .
2016-02-06 00:47:47 +01:00
* - 1 if no weapon in slot .
2009-04-20 05:43:20 +02:00
*/
2009-05-29 08:43:15 +02:00
stock WeaponsGetClientWeapons ( client , weapons [ WeaponsSlot ])
2009-04-20 05:43:20 +02:00
{
2009-06-05 05:58:48 +02:00
// x = Weapon slot.
2009-04-20 05:43:20 +02:00
for ( new x = 0 ; x < WEAPONS_SLOTS_MAX ; x ++ )
{
weapons [ x ] = GetPlayerWeaponSlot ( client , x );
}
}
/**
* Returns weapon index of the client ' s deployed weapon .
2016-02-06 00:47:47 +01:00
*
2009-04-20 05:43:20 +02:00
* @ param client The client index .
* @ return The weapon index of the deployed weapon .
2016-02-06 00:47:47 +01:00
* - 1 if no weapon is deployed .
2009-04-20 05:43:20 +02:00
*/
2009-05-18 06:26:13 +02:00
stock WeaponsGetDeployedWeaponIndex ( client )
2009-04-20 05:43:20 +02:00
{
// Return the client's active weapon.
return GetEntDataEnt2 ( client , offsActiveWeapon );
}
/**
* Returns slot of client ' s deployed weapon .
*
* @ param client The client index .
* @ return The slot number of deployed weapon .
*/
2009-05-29 08:43:15 +02:00
stock WeaponsSlot : WeaponsGetDeployedWeaponSlot ( client )
2009-04-20 05:43:20 +02:00
{
// Get all client's weapon indexes.
2009-05-29 08:43:15 +02:00
new weapons [ WeaponsSlot ];
2009-04-20 05:43:20 +02:00
WeaponsGetClientWeapons ( client , weapons );
2016-02-06 00:47:47 +01:00
2009-04-20 05:43:20 +02:00
// Get client's deployed weapon.
new deployedweapon = WeaponsGetDeployedWeaponIndex ( client );
2016-02-06 00:47:47 +01:00
2009-04-20 05:43:20 +02:00
// If client has no deployed weapon, then stop.
if ( deployedweapon == - 1 )
{
return Type_Invalid ;
}
2016-02-06 00:47:47 +01:00
2009-04-20 05:43:20 +02:00
// x = weapon slot.
for ( new x = 0 ; x < WEAPONS_SLOTS_MAX ; x ++ )
{
if ( weapons [ x ] == deployedweapon )
{
2009-05-29 08:43:15 +02:00
return WeaponsSlot : x ;
2009-04-20 05:43:20 +02:00
}
}
2016-02-06 00:47:47 +01:00
2009-04-20 05:43:20 +02:00
return Type_Invalid ;
2009-04-22 04:53:19 +02:00
}
/**
2012-01-28 19:12:33 +01:00
* Forces player to drop weapon index . ( Simplified wrapper )
2016-02-06 00:47:47 +01:00
*
2009-04-22 04:53:19 +02:00
* @ param client The client index .
* @ param weapon The weapon index to force client to drop .
*/
2009-05-18 06:26:13 +02:00
stock WeaponsForceClientDrop ( client , weapon )
2009-04-22 04:53:19 +02:00
{
// Force client to drop weapon.
2012-01-28 19:12:33 +01:00
CS_DropWeapon ( client , weapon , true , false );
2009-05-01 11:22:45 +02:00
}
2009-08-27 21:56:29 +02:00
/**
* Used to explicitly remove projectile weapons from a client .
2016-02-06 00:47:47 +01:00
*
2009-08-27 21:56:29 +02:00
* @ param client The client index .
2016-02-06 00:47:47 +01:00
* @ param weaponsdrop True to force drop on all weapons , false to strip .
2009-08-27 21:56:29 +02:00
*/
2018-07-29 15:13:31 +02:00
stock WeaponsClearClientWeaponSlot ( client , WeaponsSlot : slot , bool : weaponsdrop )
2009-08-27 21:56:29 +02:00
{
2018-07-29 15:13:31 +02:00
// This while-structure is a stupid sloppy annoying workaround to stop the "unintended assignment" warning. I hate those.
// While GetPlayerWeaponSlot returns a valid weapon, remove it and then test again.
new weapon = GetPlayerWeaponSlot ( client , _ : slot );
while ( weapon != - 1 )
2009-08-27 21:56:29 +02:00
{
2018-07-29 15:13:31 +02:00
// Check if we drop or strip the weapon.
2009-08-27 21:56:29 +02:00
if ( weaponsdrop )
{
2018-07-29 15:13:31 +02:00
WeaponsForceClientDrop ( client , weapon );
2009-08-27 21:56:29 +02:00
}
else
{
2018-07-29 15:13:31 +02:00
RemovePlayerItem ( client , weapon );
AcceptEntityInput ( weapon , " Kill " );
2009-08-27 21:56:29 +02:00
}
2016-02-06 00:47:47 +01:00
2018-07-29 15:13:31 +02:00
// Find next weapon.
weapon = GetPlayerWeaponSlot ( client , _ : slot );
2009-08-27 21:56:29 +02:00
}
}
2010-01-04 08:25:35 +01:00
/**
* Refresh a weapon by taking it and giving it back .
2016-02-06 00:47:47 +01:00
*
2010-01-04 08:25:35 +01:00
* @ param client The client index .
* @ param slot The weapon slot to refresh . ( see enum WeaponsSlot )
*/
stock WeaponsRefreshClientWeapon ( client , WeaponsSlot : slot )
{
new weaponindex = GetPlayerWeaponSlot ( client , _ : slot );
2016-02-06 00:47:47 +01:00
2010-01-04 08:25:35 +01:00
// If weapon is invalid, then stop.
if ( weaponindex == - 1 )
{
return ;
}
2016-02-06 00:47:47 +01:00
2010-01-04 08:25:35 +01:00
// Get the classname of the weapon to re-give.
decl String : entityname [ WEAPONS_MAX_LENGTH ];
GetEdictClassname ( weaponindex , entityname , sizeof ( entityname ));
2016-02-06 00:47:47 +01:00
2010-01-04 08:25:35 +01:00
// Refresh weapon.
RemovePlayerItem ( client , weaponindex );
2012-07-01 21:12:43 +02:00
AcceptEntityInput ( weaponindex , " Kill " );
2010-01-04 08:25:35 +01:00
GivePlayerItem ( client , entityname );
}
2009-08-27 21:56:29 +02:00
/**
* Remove all weapons , except knife , on a client , with options .
2016-02-06 00:47:47 +01:00
*
2009-08-27 21:56:29 +02:00
* @ param client The client index .
* @ param weaponsdrop True to force drop on all weapons , false to strip .
*/
stock WeaponsRemoveAllClientWeapons ( client , bool : weaponsdrop )
{
// Get a list of all client's weapon indexes.
new weapons [ WeaponsSlot ];
WeaponsGetClientWeapons ( client , weapons );
2016-02-06 00:47:47 +01:00
2009-08-27 21:56:29 +02:00
// Loop through array slots and force drop.
// x = weapon slot.
for ( new x = 0 ; x < WEAPONS_SLOTS_MAX ; x ++ )
{
// If weapon is invalid, then stop.
if ( weapons [ x ] == - 1 )
{
continue ;
}
2016-02-06 00:47:47 +01:00
2009-08-27 21:56:29 +02:00
// If this is the knife slot, then strip it and stop.
if ( WeaponsSlot : x == Slot_Melee )
{
// Strip knife.
RemovePlayerItem ( client , weapons [ x ]);
2012-07-01 21:12:43 +02:00
AcceptEntityInput ( weapons [ x ], " Kill " );
2009-08-27 21:56:29 +02:00
continue ;
}
2016-02-06 00:47:47 +01:00
2009-08-27 21:56:29 +02:00
if ( weaponsdrop )
{
// Force client to drop weapon.
WeaponsForceClientDrop ( client , weapons [ x ]);
}
else
{
// Strip weapon.
RemovePlayerItem ( client , weapons [ x ]);
2012-07-01 21:12:43 +02:00
AcceptEntityInput ( weapons [ x ], " Kill " );
2009-08-27 21:56:29 +02:00
}
}
2016-02-06 00:47:47 +01:00
2018-07-29 15:13:31 +02:00
// Remove left-over knifes.
WeaponsClearClientWeaponSlot ( client , Slot_Melee , false );
2009-08-27 21:56:29 +02:00
// Remove left-over projectiles.
2018-07-29 15:13:31 +02:00
WeaponsClearClientWeaponSlot ( client , Slot_Projectile , weaponsdrop );
2016-02-06 00:47:47 +01:00
2009-08-27 21:56:29 +02:00
// Give zombie a new knife. (If you leave the old one there will be glitches with the knife positioning)
GivePlayerItem ( client , " weapon_knife " );
}
2010-01-04 08:25:35 +01:00
/**
* Refresh a weapon by taking it and giving it back .
2016-02-06 00:47:47 +01:00
*
2010-01-04 08:25:35 +01:00
* @ param client The client index .
*/
stock WeaponsRefreshAllClientWeapons ( client )
{
// Get a list of all client's weapon indexes.
new weapons [ WeaponsSlot ];
WeaponsGetClientWeapons ( client , weapons );
2016-02-06 00:47:47 +01:00
2010-01-04 08:25:35 +01:00
// Loop through array slots and force drop.
// x = weapon slot.
for ( new x = 0 ; x < WEAPONS_SLOTS_MAX ; x ++ )
{
// If weapon is invalid, then stop.
if ( weapons [ x ] == - 1 )
{
continue ;
}
2016-02-06 00:47:47 +01:00
2010-01-04 08:25:35 +01:00
WeaponsRefreshClientWeapon ( client , WeaponsSlot : x );
}
}
2010-02-14 17:03:19 +01:00
/**
* Checks if a client is in a buyzone .
2016-02-06 00:47:47 +01:00
*
2010-02-14 17:03:19 +01:00
* @ param client The client index .
*/
stock bool : WeaponsIsClientInBuyZone ( client )
{
// Return if client is in buyzone.
return bool : GetEntData ( client , g_iToolsInBuyZone );
}