diff --git a/cstrike/addons/sourcemod/configs/zr/weapons.txt b/cstrike/addons/sourcemod/configs/zr/weapons.txt index 3548374..8e38b3d 100644 --- a/cstrike/addons/sourcemod/configs/zr/weapons.txt +++ b/cstrike/addons/sourcemod/configs/zr/weapons.txt @@ -11,6 +11,7 @@ // // Attribute: Values: Description: // ---------------------------------------------------------------------------- +// weaponentity text The entity name of the weapon refered to. (Don't change this) // weapontype text The type of weapon it is. [List types, separate by ", "] // weaponslot number The slot index the weapon resides in. (Don't change this) // restrictdefault yes/no The default restricted status of the weapon on map start. @@ -26,10 +27,11 @@ "weapons" // Counter-Strike: Source weapons { - "Glock" + "Gangsta Glock" { // General + "weaponentity" "weapon_glock" "weapontype" "All, Pistol" "weaponslot" "1" @@ -56,6 +58,7 @@ { // General + "weaponentity" "weapon_usp" "weapontype" "All, Pistol" "weaponslot" "1" @@ -82,6 +85,7 @@ { // General + "weaponentity" "weapon_p228" "weapontype" "All, Pistol" "weaponslot" "1" @@ -109,6 +113,7 @@ { // General + "weaponentity" "weapon_deagle" "weapontype" "All, Pistol" "weaponslot" "1" @@ -136,6 +141,7 @@ { // General + "weaponentity" "weapon_elite" "weapontype" "All, Pistol" "weaponslot" "1" @@ -163,6 +169,7 @@ { // General + "weaponentity" "weapon_fiveseven" "weapontype" "All, Pistol" "weaponslot" "1" @@ -190,6 +197,7 @@ { // General + "weaponentity" "weapon_m3" "weapontype" "All, Shotgun" "weaponslot" "0" @@ -217,6 +225,7 @@ { // General + "weaponentity" "weapon_xm1014" "weapontype" "All, Shotgun" "weaponslot" "0" @@ -244,6 +253,7 @@ { // General + "weaponentity" "weapon_mac10" "weapontype" "All, SMG" "weaponslot" "0" @@ -270,6 +280,7 @@ { // General + "weaponentity" "weapon_tmp" "weapontype" "All, SMG" "weaponslot" "0" @@ -296,6 +307,7 @@ { // General + "weaponentity" "weapon_mp5navy" "weapontype" "All, SMG" "weaponslot" "0" @@ -322,6 +334,7 @@ { // General + "weaponentity" "weapon_ump45" "weapontype" "All, SMG" "weaponslot" "0" @@ -348,6 +361,7 @@ { // General + "weaponentity" "weapon_p90" "weapontype" "All, SMG" "weaponslot" "0" @@ -374,6 +388,7 @@ { // General + "weaponentity" "weapon_galil" "weapontype" "All, Rifle" "weaponslot" "0" @@ -400,6 +415,7 @@ { // General + "weaponentity" "weapon_famas" "weapontype" "All, Rifle" "weaponslot" "0" @@ -426,6 +442,7 @@ { // General + "weaponentity" "weapon_ak47" "weapontype" "All, Rifle" "weaponslot" "0" @@ -452,6 +469,7 @@ { // General + "weaponentity" "weapon_m4a1" "weapontype" "All, Rifle" "weaponslot" "0" @@ -478,6 +496,7 @@ { // General + "weaponentity" "weapon_sg552" "weapontype" "All, Rifle" "weaponslot" "0" @@ -504,6 +523,7 @@ { // General + "weaponentity" "weapon_aug" "weapontype" "All, Rifle" "weaponslot" "0" @@ -530,6 +550,7 @@ { // General + "weaponentity" "weapon_scout" "weapontype" "All, Sniper" "weaponslot" "0" @@ -556,6 +577,7 @@ { // General + "weaponentity" "weapon_sg550" "weapontype" "All, Sniper" "weaponslot" "0" @@ -582,6 +604,7 @@ { // General + "weaponentity" "weapon_g3sg1" "weapontype" "All, Sniper" "weaponslot" "0" @@ -608,6 +631,7 @@ { // General + "weaponentity" "weapon_awp" "weapontype" "All, Sniper" "weaponslot" "0" @@ -634,6 +658,7 @@ { // General + "weaponentity" "weapon_m249" "weapontype" "All, Machine Gun" "weaponslot" "0" @@ -660,6 +685,7 @@ { // General + "weaponentity" "weapon_knife" "weapontype" "All, Melee" "weaponslot" "2" @@ -677,6 +703,7 @@ { // General + "weaponentity" "weapon_hegrenade" "weapontype" "All, Projectile" "weaponslot" "3" @@ -699,6 +726,7 @@ { // General + "weaponentity" "weapon_flashbang" "weapontype" "All, Projectile" "weaponslot" "3" @@ -717,6 +745,7 @@ { // General + "weaponentity" "weapon_smokegrenade" "weapontype" "All, Projectile" "weaponslot" "3" @@ -735,6 +764,7 @@ { // General + "weaponentity" "item_nvgs" "weapontype" "All, Equipment" "weaponslot" "5" diff --git a/src/zombiereloaded.sp b/src/zombiereloaded.sp index 8c63409..164d7b8 100644 --- a/src/zombiereloaded.sp +++ b/src/zombiereloaded.sp @@ -36,7 +36,7 @@ // Comment this line to exclude version info command. Temporary solution until // there is a windows script for updating hgversion.h.inc. -#define ADD_VERSION_INFO 1 +//#define ADD_VERSION_INFO // Header includes. #include "zr/log.h" @@ -141,6 +141,15 @@ public OnPluginStart() EventInit(); } +/** + * All plugins have finished loading. + */ +public OnAllPluginsLoaded() +{ + // Forward event to modules. + WeaponsOnAllPluginsLoaded(); +} + /** * The map is starting. */ diff --git a/src/zr/weapons/restrict.inc b/src/zr/weapons/restrict.inc index 60146e1..bf63c33 100644 --- a/src/zr/weapons/restrict.inc +++ b/src/zr/weapons/restrict.inc @@ -240,26 +240,21 @@ public Action:RestrictBuyCommand(client, argc) decl String:weapon[WEAPONS_MAX_LENGTH]; GetCmdArg(1, weapon, sizeof(weapon)); - ReplaceString(weapon, sizeof(weapon), "weapon_", ""); - // If the weapon is restricted, then prevent pickup. - new index = WeaponsNameToIndex(weapon); + decl String:weaponname[WEAPONS_MAX_LENGTH]; + new weaponindex = WeaponsEntityToDisplay(weapon, weaponname, sizeof(weaponname), true); // If weapon isn't configged, then allow pickup. - if (index == -1) + if (weaponindex == -1) { // Allow command. return Plugin_Continue; } // If weapon is restricted, then stop. - if (RestrictIsWeaponRestricted(index)) + if (RestrictIsWeaponRestricted(weaponindex)) { - // Get display name. - decl String:weapondisplay[WEAPONS_MAX_LENGTH]; - WeaponsGetName(index, weapondisplay, sizeof(weapondisplay)); - - TranslationPrintToChat(client, "Weapon is restricted", weapondisplay); + TranslationPrintToChat(client, "Weapon is restricted", weaponname); // Block command. return Plugin_Handled; @@ -284,9 +279,6 @@ RestrictQuery:RestrictWeapon(bool:restrict, const String:target[], &bool:single // Copy 'target' to 'returntarget' to be possibly changed later. strcopy(returntarget, maxlen, target); - // Strip "weapon_" from target. - ReplaceString(returntarget, maxlen, "weapon_", ""); - // Find index of the given weapon type. new typeindex = RestrictTypeToIndex(returntarget); @@ -593,14 +585,11 @@ stock bool:RestrictIsTypeUniform(bool:restricted, index) */ public ZRTools_Action:RestrictCanUse(client, weapon) { - new String:weaponname[WEAPONS_MAX_LENGTH]; - GetEdictClassname(weapon, weaponname, sizeof(weaponname)); - - // Strip "weapon_" from entity name. - ReplaceString(weaponname, sizeof(weaponname), "weapon_", ""); + new String:weaponentity[WEAPONS_MAX_LENGTH]; + GetEdictClassname(weapon, weaponentity, sizeof(weaponentity)); // If weapon is a knife, then allow pickup. - if (StrEqual(weaponname, "knife")) + if (StrEqual(weaponentity, "weapon_knife")) { return ZRTools_Continue; } @@ -632,17 +621,18 @@ public ZRTools_Action:RestrictCanUse(client, weapon) } // If the weapon is restricted, then prevent pickup. - new index = WeaponsNameToIndex(weaponname); + decl String:weaponname[WEAPONS_MAX_LENGTH]; + new weaponindex = WeaponsEntityToDisplay(weaponentity, weaponname, sizeof(weaponname)); // If weapon isn't configged, then allow pickup. - if (index == -1) + if (weaponindex == -1) { // Allow pickup. return ZRTools_Continue; } // If weapon is restricted, then stop. - if (RestrictIsWeaponRestricted(index)) + if (RestrictIsWeaponRestricted(weaponindex)) { return ZRTools_Handled; } diff --git a/src/zr/weapons/weaponammo.inc b/src/zr/weapons/weaponammo.inc index f4a6edd..001f701 100644 --- a/src/zr/weapons/weaponammo.inc +++ b/src/zr/weapons/weaponammo.inc @@ -30,10 +30,21 @@ */ new g_iToolsClip1; new g_iToolsClip2; +new g_iToolsAmmo; /** * @endsection */ +/** + * Grenade slots. + */ +enum WeaponAmmoGrenadeType +{ + GrenadeType_HEGrenade = 11, /** HEGrenade slot */ + GrenadeType_Flashbang = 12, /** Flashbang slot. */ + GrenadeType_Smokegrenade = 13, /** Smokegrenade slot. */ +} + /** * Find ammo-reserve-specific offsets here. */ @@ -52,6 +63,13 @@ WeaponAmmoOnOffsetsFound() { LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Weapons, "Offsets", "Offset \"CBaseCombatWeapon::m_iClip2\" was not found."); } + + // If offset "m_iClip2" can't be found, then stop the plugin. + g_iToolsAmmo = FindSendPropInfo("CBasePlayer", "m_iAmmo"); + if (g_iToolsAmmo == -1) + { + LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Weapons, "Offsets", "Offset \"CBasePlayer::m_iAmmo\" was not found."); + } } /** @@ -94,3 +112,36 @@ stock WeaponAmmoGetAmmo(weapon, bool:clip) // Return ammo offset value. return GetEntData(weapon, ammooffset); } + +/** + * Set the count of any grenade-type a client has. + * + * @param client The client index. + * @param slot The type of + * @param value The amount of ammo to set to. + * @param add (Optional) If true, the value is added to the grenades' current ammo count. + */ +stock WeaponAmmoSetGrenadeCount(client, WeaponAmmoGrenadeType:type, value, bool:add) +{ + // Initialize variable (value is 0) + new ammovalue; + + // If we are adding, then update variable with current ammo value. + if (add) + { + ammovalue = WeaponAmmoGetGrenadeCount(client, type); + } + + SetEntData(client, g_iToolsAmmo + (_:type * 4), ammovalue + value, _, true); +} + +/** + * Get the count of any grenade-type a client has. + * + * @param client The client index. + * @param slot The type of + */ +stock WeaponAmmoGetGrenadeCount(client, WeaponAmmoGrenadeType:type) +{ + return GetEntData(client, g_iToolsAmmo + (_:type * 4)); +} \ No newline at end of file diff --git a/src/zr/weapons/weapons.inc b/src/zr/weapons/weapons.inc index b6ff945..1e84f4d 100644 --- a/src/zr/weapons/weapons.inc +++ b/src/zr/weapons/weapons.inc @@ -50,6 +50,7 @@ enum WeaponsData { WEAPONS_DATA_NAME = 0, + WEAPONS_DATA_ENTITY, WEAPONS_DATA_TYPE, WEAPONS_DATA_SLOT, WEAPONS_DATA_RESTRICTDEFAULT, @@ -105,6 +106,15 @@ WeaponsInit() RestrictInit(); } +/** + * All plugins have finished loading. + */ +WeaponsOnAllPluginsLoaded() +{ + // Forward event to sub-modules. + ZMarketOnAllPluginsLoaded(); +} + /** * Find active weapon-specific offsets here. */ @@ -236,10 +246,12 @@ WeaponsCacheData() // Get config data. + decl String:weaponentity[CONFIG_MAX_LENGTH]; decl String:weapontype[CONFIG_MAX_LENGTH]; decl String:ammotype[CONFIG_MAX_LENGTH]; // General + KvGetString(kvWeapons, "weaponentity", weaponentity, sizeof(weaponentity)); KvGetString(kvWeapons, "weapontype", weapontype, sizeof(weapontype)); new WeaponsSlot:weaponslot = WeaponsSlot:KvGetNum(kvWeapons, "weaponslot", -1); @@ -261,18 +273,19 @@ WeaponsCacheData() new Handle:arrayWeapon = GetArrayCell(arrayWeapons, x); // Push data into array. - PushArrayString(arrayWeapon, weapontype); // Index: 1 - PushArrayCell(arrayWeapon, weaponslot); // Index: 2 - PushArrayCell(arrayWeapon, restrictdefault); // Index: 3 - PushArrayCell(arrayWeapon, toggleable); // Index: 4 - PushArrayString(arrayWeapon, ammotype); // Index: 5 - PushArrayCell(arrayWeapon, ammoprice); // Index: 6 - PushArrayCell(arrayWeapon, knockback); // Index: 7 - PushArrayCell(arrayWeapon, zmarketprice); // Index: 8 - PushArrayCell(arrayWeapon, zmarketpurchasemax); // Index: 9 + 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 + PushArrayCell(arrayWeapon, zmarketpurchasemax); // Index: 10 // Initialize other stored weapon info here. - PushArrayCell(arrayWeapon, restrictdefault); // Index: 10 + PushArrayCell(arrayWeapon, restrictdefault); // Index: 11 } // We're done with this file now, so we can close it. @@ -441,29 +454,49 @@ stock WeaponsNameToIndex(const String:weapon[]) } /** - * Takes a weapon's classname and returns the display name in weapons config file. + * Takes a weapon's entity name and returns the display name in weapons config file. * - * @param + * @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. + * @return The index of the weapon found. */ -stock WeaponsClassnameToDisplay(String:classname[], classnamemaxlen, String:display[], displaymaxlen) +stock WeaponsEntityToDisplay(const String:entityname[], String:display[], displaymaxlen, noprefix = false) { - // Strip off classnames' weapon prefix. - ReplaceString(classname, classnamemaxlen, "weapon_", ""); - ReplaceString(classname, classnamemaxlen, "item_", ""); + decl String:weaponentity[WEAPONS_MAX_LENGTH]; - // Get the index of the weapon. - new weaponindex = WeaponsNameToIndex(classname); + // Initialize string to null. + strcopy(display, sizeof(displaymaxlen), ""); - // If weapon index is invalid, then return an empty string. - if (weaponindex == -1) + // x = Array index. + new size = GetArraySize(arrayWeapons); + for (new x = 0; x < size; x++) { - // Return an empty string. - strcopy(display, displaymaxlen, ""); - return; + // If entity names don't match, then stop. + WeaponsGetEntity(x, weaponentity, sizeof(weaponentity)); + + // If noprefix is true, then strip the weapon_/item_ prefix. + if (noprefix) + { + ReplaceString(weaponentity, sizeof(weaponentity), "weapon_", ""); + ReplaceString(weaponentity, sizeof(weaponentity), "item_", ""); + } + + if (!StrEqual(entityname, weaponentity, false)) + { + continue; + } + + // The entity names match, so return display. + WeaponsGetName(x, display, displaymaxlen); + + // Return the weapon index. + return x; } - // Return the display name. - WeaponsGetName(weaponindex, display, displaymaxlen); + // Nothing was found. + return -1; } /** @@ -491,6 +524,21 @@ stock WeaponsGetName(index, String:weapon[], maxlen) GetArrayString(arrayWeapon, _:WEAPONS_DATA_NAME, weapon, maxlen); } +/** + * 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); + + // Get weapon type. + GetArrayString(arrayWeapon, _:WEAPONS_DATA_ENTITY, type, maxlen); +} + /** * Gets the type of a weapon at a given index. * @param index The weapon index. @@ -648,7 +696,6 @@ stock bool:WeaponsClientHasWeapon(client, const String:weapon[]) // If the weapon's classname matches, then return true. GetEdictClassname(weapons[x], classname, sizeof(classname)); - ReplaceString(classname, sizeof(classname), "weapon_", ""); if (StrEqual(weapon, classname, false)) { return true; diff --git a/src/zr/weapons/zmarket.inc b/src/zr/weapons/zmarket.inc index b4b4ee8..3bc4364 100644 --- a/src/zr/weapons/zmarket.inc +++ b/src/zr/weapons/zmarket.inc @@ -34,6 +34,18 @@ * @endsection */ +/** + * @section Defines for ZMarket grenade limits, supporting the Grenade Pack plugin. + */ +#define GRENADE_PACK_FILENAME "grenadepack.smx" +#define GRENADE_PACK_LIMIT "gp_limit" +#define GRENADE_CSS_LIMIT 1 + +/** + * Variable to store if Grenade Pack is loaded and running. + */ +new bool:g_bGrenadePack; + /** * Variable to store buyzone offset value. */ @@ -54,6 +66,21 @@ new Handle:g_hZMarketPurchaseCount[MAXPLAYERS + 1]; */ new Handle:g_hZMarketAutoRebuyCookie = INVALID_HANDLE; +/** + * All plugins have finished loading. + */ +ZMarketOnAllPluginsLoaded() +{ + // Check if "Grenade Pack" is loaded + g_bGrenadePack = ZMarketIsGPLoaded(); + + // DEBUG + if (g_bGrenadePack) + { + PrintToServer("GRENADE PACK IS LOADEDDD!!!!!!!!!"); + } +} + /** * Create commands specific to ZMarket. */ @@ -380,56 +407,35 @@ bool:ZMarketMenuLoadout(client) // Create menu handle. new Handle:menu_zmarket_loadout = CreateMenu(ZMarketMenuLoadoutHandle); - decl String:primaryweapon[WEAPONS_MAX_LENGTH]; - decl String:secondaryweapon[WEAPONS_MAX_LENGTH]; - decl String:meleeweapon[WEAPONS_MAX_LENGTH]; - decl String:projectileweapon[WEAPONS_MAX_LENGTH]; - decl String:explosiveweapon[WEAPONS_MAX_LENGTH]; - decl String:nvgsweapon[WEAPONS_MAX_LENGTH]; - // Transfer cookie values into an array. new String:rebuyweapons[WeaponsSlot][WEAPONS_MAX_LENGTH]; ZMarketCookiesToArray(client, rebuyweapons, WEAPONS_SLOTS_MAX + 1, sizeof(rebuyweapons[])); - // Return the display name for all the client's weapon classname's. - WeaponsClassnameToDisplay(rebuyweapons[Slot_Primary], sizeof(rebuyweapons[]), primaryweapon, sizeof(primaryweapon)); - WeaponsClassnameToDisplay(rebuyweapons[Slot_Secondary], sizeof(rebuyweapons[]), secondaryweapon, sizeof(secondaryweapon)); - WeaponsClassnameToDisplay(rebuyweapons[Slot_Melee], sizeof(rebuyweapons[]), meleeweapon, sizeof(meleeweapon)); - WeaponsClassnameToDisplay(rebuyweapons[Slot_Projectile], sizeof(rebuyweapons[]), projectileweapon, sizeof(projectileweapon)); - WeaponsClassnameToDisplay(rebuyweapons[Slot_Explosive], sizeof(rebuyweapons[]), explosiveweapon, sizeof(explosiveweapon)); - WeaponsClassnameToDisplay(rebuyweapons[Slot_NVGs], sizeof(rebuyweapons[]), nvgsweapon, sizeof(nvgsweapon)); - SetGlobalTransTarget(client); // Get the empty translation. decl String:empty[MENU_LINE_SMALL_LENGTH]; Format(empty, sizeof(empty), "%t", "Weapons menu zmarket loadout empty"); - // If the client doesn't have a weapon in this slot, then set the weapon to the empty translation. - if (!primaryweapon[0]) + // x = Rebuy weapon slot. + for (new x = 0; x < sizeof(rebuyweapons); x++) { - strcopy(primaryweapon, sizeof(primaryweapon), empty); - } - if (!secondaryweapon[0]) - { - strcopy(secondaryweapon, sizeof(secondaryweapon), empty); - } - if (!meleeweapon[0]) - { - strcopy(meleeweapon, sizeof(meleeweapon), empty); - } - if (!projectileweapon[0]) - { - strcopy(projectileweapon, sizeof(projectileweapon), empty); - } - if (!explosiveweapon[0]) - { - strcopy(explosiveweapon, sizeof(explosiveweapon), empty); + // Ignore the NVG slot, we handle this separately. + if (WeaponsSlot:x == Slot_NVGs) + { + continue; + } + + // If the client doesn't have a weapon in this slot, then set the weapon to the empty translation. + if (!rebuyweapons[x][0]) + { + strcopy(rebuyweapons[x], sizeof(rebuyweapons[]), empty); + } } // Copy "Yes/No" to NVGs string. decl String:nvgsbool[8]; - ConfigBoolToSetting(bool:nvgsweapon[0], nvgsbool, sizeof(nvgsbool), true, client); + ConfigBoolToSetting(bool:rebuyweapons[Slot_NVGs][0], nvgsbool, sizeof(nvgsbool), true, client); decl String:title[MENU_LINE_HUGE_LENGTH]; decl String:primary[MENU_LINE_REG_LENGTH]; @@ -441,21 +447,21 @@ bool:ZMarketMenuLoadout(client) // Format all the lines of the menu. Format(title, sizeof(title), "%t\n ", "Weapons menu zmarket loadout title"); - Format(primary, sizeof(primary), "%t", "Weapons menu zmarket loadout primary", primaryweapon); - Format(secondary, sizeof(secondary), "%t", "Weapons menu zmarket loadout secondary", secondaryweapon); - Format(melee, sizeof(melee), "%t", "Weapons menu zmarket loadout melee", meleeweapon); - Format(projectile, sizeof(projectile), "%t", "Weapons menu zmarket loadout projectile", projectileweapon); - Format(explosive, sizeof(explosive), "%t", "Weapons menu zmarket loadout explosive", explosiveweapon); + Format(primary, sizeof(primary), "%t", "Weapons menu zmarket loadout primary", rebuyweapons[Slot_Primary]); + Format(secondary, sizeof(secondary), "%t", "Weapons menu zmarket loadout secondary", rebuyweapons[Slot_Secondary]); + Format(melee, sizeof(melee), "%t", "Weapons menu zmarket loadout melee", rebuyweapons[Slot_Melee]); + Format(projectile, sizeof(projectile), "%t", "Weapons menu zmarket loadout projectile", rebuyweapons[Slot_Projectile]); + Format(explosive, sizeof(explosive), "%t", "Weapons menu zmarket loadout explosive", rebuyweapons[Slot_Explosive]); Format(nvgs, sizeof(nvgs), "%t", "Weapons menu zmarket loadout nvgs", nvgsbool); // Add formatted options to menu. SetMenuTitle(menu_zmarket_loadout, title); - AddMenuItem(menu_zmarket_loadout, "0", primary, MenuGetItemDraw(!StrEqual(primaryweapon, empty))); - AddMenuItem(menu_zmarket_loadout, "1", secondary, MenuGetItemDraw(!StrEqual(secondaryweapon, empty))); - AddMenuItem(menu_zmarket_loadout, "2", melee, MenuGetItemDraw(!StrEqual(meleeweapon, empty))); - AddMenuItem(menu_zmarket_loadout, "3", projectile, MenuGetItemDraw(!StrEqual(projectileweapon, empty))); - AddMenuItem(menu_zmarket_loadout, "4", explosive, MenuGetItemDraw(!StrEqual(explosiveweapon, empty))); - AddMenuItem(menu_zmarket_loadout, "5", nvgs, MenuGetItemDraw(bool:nvgsweapon[0])); + AddMenuItem(menu_zmarket_loadout, "0", primary, MenuGetItemDraw(!StrEqual(rebuyweapons[Slot_Primary], empty))); + AddMenuItem(menu_zmarket_loadout, "1", secondary, MenuGetItemDraw(!StrEqual(rebuyweapons[Slot_Secondary], empty))); + AddMenuItem(menu_zmarket_loadout, "2", melee, MenuGetItemDraw(!StrEqual(rebuyweapons[Slot_Melee], empty))); + AddMenuItem(menu_zmarket_loadout, "3", projectile, MenuGetItemDraw(!StrEqual(rebuyweapons[Slot_Projectile], empty))); + AddMenuItem(menu_zmarket_loadout, "4", explosive, MenuGetItemDraw(!StrEqual(rebuyweapons[Slot_Explosive], empty))); + AddMenuItem(menu_zmarket_loadout, "5", nvgs, MenuGetItemDraw(bool:rebuyweapons[Slot_NVGs][0])); // Set exit back button. SetMenuExitBackButton(menu_zmarket_loadout, true); @@ -613,6 +619,7 @@ ZMarketMenuTypeWeapons(client) decl String:title[MENU_LINE_TITLE_LENGTH]; decl String:typeweapon[WEAPONS_MAX_LENGTH]; decl String:typeweapondisplay[MENU_LINE_REG_LENGTH]; + decl String:typeweaponentity[WEAPONS_MAX_LENGTH]; decl String:display[MENU_LINE_BIG_LENGTH]; // Get an array populated with all weapons of the given type. @@ -630,8 +637,11 @@ ZMarketMenuTypeWeapons(client) // Get name of weapon. WeaponsGetName(weaponindex, typeweapon, sizeof(typeweapon)); + // Get entity name of weapon. + WeaponsGetEntity(weaponindex, typeweaponentity, sizeof(typeweaponentity)); + // Check if client is buying the weapon or ammo for it, and get the price of the item. - new bool:hasweapon = WeaponsClientHasWeapon(client, typeweapon); + new bool:hasweapon = WeaponsClientHasWeapon(client, typeweaponentity); // DO ITEM PRICE STUFF HERE. @@ -801,8 +811,12 @@ stock bool:ZMarketEquip(client, const String:weapon[], bool:rebuy = false) return false; } + // Get entity name of the weapon. + decl String:weaponentity[WEAPONS_MAX_LENGTH]; + WeaponsGetEntity(weaponindex, weaponentity, sizeof(weaponentity)); + // Get the appropriate price of the item being purchased. - new bool:hasweapon = WeaponsClientHasWeapon(client, weapon); + new bool:hasweapon = WeaponsClientHasWeapon(client, weaponentity); new itemprice = (hasweapon && slot != Slot_Projectile) ? WeaponsGetAmmoPrice(weaponindex) : WeaponsGetZMarketPrice(weaponindex); // If the weapon price is below 0, then something went wrong. @@ -811,13 +825,9 @@ stock bool:ZMarketEquip(client, const String:weapon[], bool:rebuy = false) return false; } - // Copy the 'weapon' variable into a local variable for indexing. - decl String:weaponname[WEAPONS_MAX_LENGTH]; - strcopy(weaponname, sizeof(weaponname), weapon); - // Get the display name for the weapon. decl String:weapondisplay[WEAPONS_MAX_LENGTH]; - WeaponsClassnameToDisplay(weaponname, sizeof(weaponname), weapondisplay, sizeof(weapondisplay)); + WeaponsGetName(weaponindex, weapondisplay, sizeof(weapondisplay)); // Check to make sure the weapon isn't restricted. new bool:restricted = RestrictIsWeaponRestricted(weaponindex); @@ -837,6 +847,24 @@ stock bool:ZMarketEquip(client, const String:weapon[], bool:rebuy = false) return false; } + // If the slot is a projectile, then get information we need to compare later. + if (slot == Slot_Projectile) + { + // How many grenades does the client currently have? + new grenadecount = WeaponAmmoGetGrenadeCount(client, GrenadeType_HEGrenade); + + // What is the current grenade limit? + new Handle:gplimit = FindConVar(GRENADE_PACK_LIMIT); + new grenadelimit = (gplimit != INVALID_HANDLE) ? GetConVarInt(gplimit) : GRENADE_CSS_LIMIT; + + // If client is at, or exceeds the grenade limit, then stop. + if (grenadecount >= grenadelimit) + { + // TRANSLATION HERE + return false; + } + } + // Get client's current money. new cash = AccountGetClientCash(client); @@ -860,7 +888,6 @@ stock bool:ZMarketEquip(client, const String:weapon[], bool:rebuy = false) // Check if client is buying the weapon or ammo for it. if (!hasweapon || slot == Slot_Projectile || slot == Slot_NVGs) { - // If the item is a projectile or NVGs, then skip. if (slot != Slot_Projectile && slot != Slot_NVGs) { @@ -872,19 +899,6 @@ stock bool:ZMarketEquip(client, const String:weapon[], bool:rebuy = false) } } - // Format name into entity name. - decl String:weaponentity[WEAPONS_MAX_LENGTH]; - - // If this is the NVGs slot, then format "item_" in front instead of "weapon_". - if (slot == Slot_NVGs) - { - Format(weaponentity, sizeof(weaponentity), "item_%s", weapon); - } - else - { - Format(weaponentity, sizeof(weaponentity), "weapon_%s", weapon); - } - // Give client the weapon. GivePlayerItem(client, weaponentity); @@ -894,7 +908,8 @@ stock bool:ZMarketEquip(client, const String:weapon[], bool:rebuy = false) // Add 1 to the client's purchase count. ZMarketSetPurchaseCount(client, weapon, 1, true); - if (slot != Slot_Projectile && slot != Slot_NVGs) + // If client isn't rebuying the weapon, then tell them the weapon has been purchased. + if (!rebuy) { // Tell client they bought a weapon. TranslationPrintToChat(client, "Weapons zmarket purchase", weapondisplay); @@ -946,6 +961,7 @@ bool:ZMarketGetCurrentLoadout(client) WeaponsGetClientWeapons(client, weapons); decl String:weaponname[WEAPONS_MAX_LENGTH]; + decl String:weaponentity[WEAPONS_MAX_LENGTH]; // x = Weapon slot. for (new x = 0; x < WEAPONS_SLOTS_MAX; x++) @@ -959,8 +975,10 @@ bool:ZMarketGetCurrentLoadout(client) } // Get the name of the weapon. - GetEdictClassname(weapons[x], weaponname, sizeof(weaponname)); - ReplaceString(weaponname, sizeof(weaponname), "weapon_", ""); + GetEdictClassname(weapons[x], weaponentity, sizeof(weaponentity)); + + // Get the entity name of the weapon. + WeaponsEntityToDisplay(weaponentity, weaponname, sizeof(weaponname)); // Copy the name to the rebuy cache. ZMarketSetRebuyCookie(client, WeaponsSlot:x, weaponname); @@ -1161,3 +1179,34 @@ stock bool:ZMarketIsClientInBuyZone(client) // Return if client is in buyzone. return bool:GetEntData(client, g_iToolsInBuyZone); } + +/** + * Returns true if plugin "Grenade Pack" is found and running. + */ +stock bool:ZMarketIsGPLoaded() +{ + new Handle:hPlugins = GetPluginIterator(); + new Handle:hPlugin; + decl String:strPlugin[PLATFORM_MAX_PATH]; + + while (MorePlugins(hPlugins)) + { + // Read the next plugin. + hPlugin = ReadPlugin(hPlugins); + + GetPluginFilename(hPlugin, strPlugin, sizeof(strPlugin)); + if (!StrEqual(strPlugin, GRENADE_PACK_FILENAME, false)) + { + continue; + } + + // Plugin was found, now return true only if it is running. + return (GetPluginStatus(hPlugin) == Plugin_Running); + } + + // Done iterating, close handle. + CloseHandle(hPlugins); + + // Plugin wasn't found. + return false; +} \ No newline at end of file