Recoded weapon restrictions, and made new way of storing data. (Arrays)

* Removed ZMarket as an external plugin (to be integrated next commit)
* Updated weapon configs, removed weapongroups.txt and moved weapons.txt to root zr config folder.
* Moved offset finding to respective module, made new forward *OnOffsetsFound.
* Updated weapons&hitgroups config file format to match playerclass.txt
* Updated translations.
* Recoded weapon restrict menu, commented out all zadmin options that don't quite work.
* Added weaponammo module (not finished but existent)
* Started zmarket module.
This commit is contained in:
Greyscale 2009-05-28 23:43:15 -07:00
parent b1f8de9526
commit 0f8206596a
34 changed files with 2565 additions and 2673 deletions

View File

@ -4,7 +4,7 @@
//
// "hitgroup index" // Index of the hitgroup (listed below)
// {
// "name" "name of hitgroup" // Redundant as of now, used for readability.
// "index" "name of hitgroup" // Redundant as of now, used for readability.
// "knockback" "1.0" (default) // The knockback multiplier for the hitgroup.
// "damage" "yes" (default // Toggle damage on and off for this hitgroup.
// }
@ -13,68 +13,130 @@
//
// A missing config setting will be assumed to be its default value (documented above).
// ============================================================================
//
// ZOMBIE:RELOADED
// Hitgroup configurations
//
// Check the hitgroup configuration section in the manual for detailed info.
//
// ============================================================================
//
// SHORT DESCRIPTIONS
//
// Attribute: Values: Description:
// ----------------------------------------------------------------------------
// index number The hitgroup index
// damage yes/no Allow damage to be done on this hitgroup for zombies.
// knockback decimal The knockback multiplier for this hitgroup.
"hitgroups" // Counter-Strike: Source hitgroups
{
"0"
"Generic"
{
"name" "Generic"
"knockback" "1.0"
// General
"index" "0"
// Damage
"damage" "yes"
// Knockback
"knockback" "1.0"
}
"1"
"Head"
{
"name" "Head"
// General
"index" "1"
// Damage
"damage" "yes"
// Knockback
"knockback" "2.0"
"damage" "yes"
}
"2"
"Chest"
{
"name" "Chest"
// General
"index" "2"
// Damage
"damage" "yes"
// Knockback
"knockback" "1.3"
"damage" "yes"
}
"3"
"Stomach"
{
"name" "Stomach"
// General
"index" "3"
// Damage
"damage" "yes"
// Knockback
"knockback" "1.2"
"damage" "yes"
}
"4"
"Left Arm"
{
"name" "Left Arm"
// General
"index" "4"
// Damage
"damage" "yes"
// Knockback
"knockback" "1.0"
"damage" "yes"
}
"5"
"Right Arm"
{
"name" "Right Arm"
// General
"index" "5"
// Damage
"damage" "yes"
// Knockback
"knockback" "1.0"
"damage" "yes"
}
"6"
"Left Leg"
{
"name" "Left Leg"
// General
"index" "6"
// Damage
"damage" "yes"
// Knockback
"knockback" "0.9"
"damage" "yes"
}
"7"
"Right Leg"
{
"name" "Right Leg"
// General
"index" "7"
// Damage
"damage" "yes"
// Knockback
"knockback" "0.9"
"damage" "yes"
}
"10"
"Gear"
{
"name" "Gear"
"knockback" "1.0"
// General
"index" "8"
// Damage
"damage" "yes"
// Knockback
"knockback" "1.0"
}
}

View File

@ -0,0 +1,713 @@
// ============================================================================
//
// ZOMBIE:RELOADED
// Weapon configurations
//
// Check the weapon configuration section in the manual for detailed info.
//
// ============================================================================
//
// SHORT DESCRIPTIONS
//
// Attribute: Values: Description:
// ----------------------------------------------------------------------------
// weapontype text The type of weapon it is. (List types, separate by ", "
// restrictdefault yes/no The default restricted status of the weapon on map start.
// toggleable yes/no Enable weapon to have restrictions toggled mid-game.
// ammotype text Ammo entity that belongs to weapons. (Don't change this)
// ammoprice number Price of ammo for this weapon.
// knockback decimal The knockback multiplier for the weapon. ['0.5' = half knockback | 2.0 = double]
// zmarketprice number The price of the weapon in ZMarket. (Defaulted to CS:S buymenu price)
"weapons" // Counter-Strike: Source weapons
{
"Glock"
{
// General
"weapontype" "All, Pistol"
// Restrict (core)
"restrictdefault" "no"
"toggleable" "yes"
// Weapon Ammo (core)
"ammotype" "ammo_9mm"
"ammoprice" "100"
// Knockback (module)
"knockback" "0.8"
// ZMarket (module)
"zmarketprice" "400"
}
"USP"
{
// General
"weapontype" "All, Pistol"
// Restrict (core)
"restrictdefault" "no"
"toggleable" "yes"
// Weapon Ammo (core)
"ammotype" "ammo_45acp"
"ammoprice" "100"
// Knockback (module)
"knockback" "0.8"
// ZMarket (module)
"zmarketprice" "500"
}
"P228"
{
// General
"weapontype" "All, Pistol"
// Restrict (core)
"restrictdefault" "no"
"toggleable" "yes"
// Weapon Ammo (core)
"ammotype" "ammo_357sig"
"ammoprice" "100"
// Knockback (module)
"knockback" "1.0"
// ZMarket (module)
"zmarketprice" "600"
}
"Deagle"
{
// General
"weapontype" "All, Pistol"
// Restrict (core)
"restrictdefault" "no"
"toggleable" "yes"
// Weapon Ammo (core)
"ammotype" "ammo_50ae"
"ammoprice" "100"
// Knockback (module)
"knockback" "1.2"
// ZMarket (module)
"zmarketprice" "650"
}
"Elite"
{
// General
"weapontype" "All, Pistol"
// Restrict (core)
"restrictdefault" "no"
"toggleable" "yes"
// Weapon Ammo (core)
"ammotype" "ammo_9mm"
"ammoprice" "100"
// Knockback (module)
"knockback" "1.0"
// ZMarket (module)
"zmarketprice" "800"
}
"Fiveseven"
{
// General
"weapontype" "All, Pistol"
// Restrict (core)
"restrictdefault" "no"
"toggleable" "yes"
// Weapon Ammo (core)
"ammotype" "ammo_57mm"
"ammoprice" "100"
// Knockback (module)
"knockback" "1.0"
// ZMarket (module)
"zmarketprice" "750"
}
"M3"
{
// General
"weapontype" "All, Shotgun"
// Restrict (core)
"restrictdefault" "no"
"toggleable" "yes"
// Weapon Ammo (core)
"ammotype" "ammo_buckshot"
"ammoprice" "300"
// Knockback (module)
"knockback" "0.9" // Remember that there are 8 pellets in 1 shot.
// ZMarket (module)
"zmarketprice" "1700"
}
"XM1014"
{
// General
"weapontype" "All, Shotgun"
// Restrict (core)
"restrictdefault" "no"
"toggleable" "yes"
// Weapon Ammo (core)
"ammotype" "ammo_buckshot"
"ammoprice" "300"
// Knockback (module)
"knockback" "0.8" // See above comment.
// ZMarket (module)
"zmarketprice" "3000"
}
"Mac10"
{
// General
"weapontype" "All, SMG"
// Restrict (core)
"restrictdefault" "no"
"toggleable" "yes"
// Weapon Ammo (core)
"ammotype" "ammo_45acp"
"ammoprice" "300"
// Knockback (module)
"knockback" "1.0"
// ZMarket (module)
"zmarketprice" "1400"
}
"TMP"
{
// General
"weapontype" "All, SMG"
// Restrict (core)
"restrictdefault" "no"
"toggleable" "yes"
// Weapon Ammo (core)
"ammotype" "ammo_9mm"
"ammoprice" "300"
// Knockback (module)
"knockback" "1.0"
// ZMarket (module)
"zmarketprice" "1250"
}
"MP5Navy"
{
// General
"weapontype" "All, SMG"
// Restrict (core)
"restrictdefault" "no"
"toggleable" "yes"
// Weapon Ammo (core)
"ammotype" "ammo_9mm"
"ammoprice" "300"
// Knockback (module)
"knockback" "1.0"
// ZMarket (module)
"zmarketprice" "1500"
}
"UMP45"
{
// General
"weapontype" "All, SMG"
// Restrict (core)
"restrictdefault" "no"
"toggleable" "yes"
// Weapon Ammo (core)
"ammotype" "ammo_45acp"
"ammoprice" "300"
// Knockback (module)
"knockback" "1.0"
// ZMarket (module)
"zmarketprice" "1700"
}
"P90"
{
// General
"weapontype" "All, SMG"
// Restrict (core)
"restrictdefault" "no"
"toggleable" "yes"
// Weapon Ammo (core)
"ammotype" "ammo_57mm"
"ammoprice" "300"
// Knockback (module)
"knockback" "1.0"
// ZMarket (module)
"zmarketprice" "2350"
}
"Galil"
{
// General
"weapontype" "All, Rifle"
// Restrict (core)
"restrictdefault" "no"
"toggleable" "yes"
// Weapon Ammo (core)
"ammotype" "ammo_556mm"
"ammoprice" "500"
// Knockback (module)
"knockback" "1.0"
// ZMarket (module)
"zmarketprice" "2000"
}
"Famas"
{
// General
"weapontype" "All, Rifle"
// Restrict (core)
"restrictdefault" "no"
"toggleable" "yes"
// Weapon Ammo (core)
"ammotype" "ammo_556mm"
"ammoprice" "500"
// Knockback (module)
"knockback" "1.0"
// ZMarket (module)
"zmarketprice" "2250"
}
"AK47"
{
// General
"weapontype" "All, Rifle"
// Restrict (core)
"restrictdefault" "no"
"toggleable" "yes"
// Weapon Ammo (core)
"ammotype" "ammo_762mm"
"ammoprice" "500"
// Knockback (module)
"knockback" "1.2"
// ZMarket (module)
"zmarketprice" "2500"
}
"M4A1"
{
// General
"weapontype" "All, Rifle"
// Restrict (core)
"restrictdefault" "no"
"toggleable" "yes"
// Weapon Ammo (core)
"ammotype" "ammo_556mm"
"ammoprice" "500"
// Knockback (module)
"knockback" "1.1"
// ZMarket (module)
"zmarketprice" "3100"
}
"SG552"
{
// General
"weapontype" "All, Rifle"
// Restrict (core)
"restrictdefault" "no"
"toggleable" "yes"
// Weapon Ammo (core)
"ammotype" "ammo_556mm"
"ammoprice" "500"
// Knockback (module)
"knockback" "1.0"
// ZMarket (module)
"zmarketprice" "3500"
}
"AUG"
{
// General
"weapontype" "All, Rifle"
// Restrict (core)
"restrictdefault" "no"
"toggleable" "yes"
// Weapon Ammo (core)
"ammotype" "ammo_762mm"
"ammoprice" "500"
// Knockback (module)
"knockback" "1.1"
// ZMarket (module)
"zmarketprice" "3500"
}
"Scout"
{
// General
"weapontype" "All, Sniper"
// Restrict (core)
"restrictdefault" "no"
"toggleable" "yes"
// Weapon Ammo (core)
"ammotype" "ammo_762mm"
"ammoprice" "750"
// Knockback (module)
"knockback" "1.5"
// ZMarket (module)
"zmarketprice" "2750"
}
"SG550"
{
// General
"weapontype" "All, Sniper"
// Restrict (core)
"restrictdefault" "no"
"toggleable" "yes"
// Weapon Ammo (core)
"ammotype" "ammo_556mm"
"ammoprice" "1000"
// Knockback (module)
"knockback" "1.3"
// ZMarket (module)
"zmarketprice" "4200"
}
"G3SG1"
{
// General
"weapontype" "All, Sniper"
// Restrict (core)
"restrictdefault" "no"
"toggleable" "yes"
// Weapon Ammo (core)
"ammotype" "ammo_762mm"
"ammoprice" "1000"
// Knockback (module)
"knockback" "1.3"
// ZMarket (module)
"zmarketprice" "5000"
}
"AWP"
{
// General
"weapontype" "All, Sniper"
// Restrict (core)
"restrictdefault" "no"
"toggleable" "yes"
// Weapon Ammo (core)
"ammotype" "ammo_338mag"
"ammoprice" "1000"
// Knockback (module)
"knockback" "1.8"
// ZMarket (module)
"zmarketprice" "4750"
}
"M249"
{
// General
"weapontype" "All, Machine Gun"
// Restrict (core)
"restrictdefault" "no"
"toggleable" "yes"
// Weapon Ammo (core)
"ammotype" "ammo_556mm_box"
"ammoprice" "1500"
// Knockback (module)
"knockback" "1.2"
// ZMarket (module)
"zmarketprice" "5750"
}
"Knife"
{
// General
"weapontype" "All, Melee"
// Restrict (core)
"restrictdefault" "no"
"toggleable" "no"
// Knockback (module)
"knockback" "10.0"
}
"HEGrenade"
{
// General
"weapontype" "All, Projectile"
// Restrict (core)
"restrictdefault" "no"
"toggleable" "yes"
// Knockback (module)
"knockback" "6.0"
// ZMarket (module)
"zmarketprice" "300"
}
"Flashbang"
{
// General
"weapontype" "All, Projectile"
// Restrict (core)
"restrictdefault" "yes"
"toggleable" "yes"
// ZMarket (module)
"zmarketprice" "300"
}
"Smokegrenade"
{
// General
"weapontype" "All, Projectile"
// Restrict (core)
"restrictdefault" "yes"
"toggleable" "yes"
// ZMarket (module)
"zmarketprice" "300"
}
"NVGs"
{
// General
"weapontype" "All, Equipment"
// Restrict (core)
"restrictdefault" "yes"
"toggleable" "yes"
// ZMarket (module)
"zmarketprice" "1000"
}
}

View File

@ -1,69 +0,0 @@
// Weapon Groups
// (See list of weapons in weapons.txt)
// Format
//
//
// "weapon group name" (how it appears in chat messages)
// {
// "weaponname" {} <-- To satisfy the standard format of a keyvalues file,
// without these brackets the weapon will be skipped.
// Invalid weapons are logged and skipped.
// }
//
// Notes:
//
// Invalid weapons (not in weapons.txt) will be logged in the error logs and ignored in-game
"weapongroups"
{
"Pistols"
{
"Glock" {}
"USP" {}
"P228" {}
"Deagle" {}
"Elite" {}
"Fiveseven" {}
}
"Shotguns"
{
"M3" {}
"XM1014" {}
}
"SMGs"
{
"Mac10" {}
"TMP" {}
"MP5Navy" {}
"UMP45" {}
"P90" {}
}
"Rifles"
{
"Galil" {}
"Famas" {}
"AK47" {}
"M4A1" {}
"SG552" {}
"AUG" {}
}
"Snipers"
{
"Scout" {}
"SG550" {}
"G3SG1" {}
"AWP" {}
}
"Grenades"
{
"hegrenade" {}
"flashbang" {}
"smokegrenade" {}
}
}

View File

@ -1,225 +0,0 @@
// Weapons
//
// Format
//
// "weaponname" // Name of the weapon (without weapon_ prefix)
// {
// "restrict" "no" (default) // Restricts the weapon on each map start
// "menu" "yes" (default) // Allows admins to toggle restriction with the menu
// "knockback" "1.0" (default) // The knockback multiplier for the weapon
// }
//
// Notes:
//
// This is a list of valid weapons for your server, unlisted weapons will
// be seen as invalid by the weapon restrict module.
//
// A config setting set to something other than "yes" or "no" will be assumed as "no."
//
// A missing config setting will be assumed to be its default value (documented above).
//
// Duplicate weapon entries will show up separately in restrict menu, but
// only the first one's options are used.
"weapons" // Counter-Strike: Source weapons
{
"Glock"
{
"restrict" "no"
"menu" "yes"
"knockback" "0.8"
}
"USP"
{
"restrict" "no"
"menu" "yes"
"knockback" "0.8"
}
"P228"
{
"restrict" "no"
"menu" "yes"
"knockback" "1.0"
}
"Deagle"
{
"restrict" "no"
"menu" "yes"
"knockback" "1.2"
}
"Elite"
{
"restrict" "no"
"menu" "yes"
"knockback" "1.0"
}
"Fiveseven"
{
"restrict" "no"
"menu" "yes"
"knockback" "1.0"
}
"M3"
{
"restrict" "no"
"menu" "yes"
"knockback" "0.8" // Remember that there are 8 pellets in 1 shot.
}
"XM1014"
{
"restrict" "no"
"menu" "yes"
"knockback" "0.8" // See above comment.
}
"Mac10"
{
"restrict" "no"
"menu" "yes"
"knockback" "1.0"
}
"TMP"
{
"restrict" "no"
"menu" "yes"
"knockback" "1.0"
}
"MP5Navy"
{
"restrict" "no"
"menu" "yes"
"knockback" "1.0"
}
"UMP45"
{
"restrict" "no"
"menu" "yes"
"knockback" "1.0"
}
"P90"
{
"restrict" "no"
"menu" "yes"
"knockback" "1.0"
}
"Galil"
{
"restrict" "no"
"menu" "yes"
"knockback" "1.0"
}
"Famas"
{
"restrict" "no"
"menu" "yes"
"knockback" "1.0"
}
"AK47"
{
"restrict" "no"
"menu" "yes"
"knockback" "1.2"
}
"M4A1"
{
"restrict" "no"
"menu" "yes"
"knockback" "1.1"
}
"SG552"
{
"restrict" "no"
"menu" "yes"
"knockback" "1.0"
}
"AUG"
{
"restrict" "no"
"menu" "yes"
"knockback" "1.1"
}
"Scout"
{
"restrict" "no"
"menu" "yes"
"knockback" "1.5"
}
"SG550"
{
"restrict" "yes"
"menu" "yes"
"knockback" "1.3"
}
"G3SG1"
{
"restrict" "yes"
"menu" "yes"
"knockback" "1.3"
}
"AWP"
{
"restrict" "yes"
"menu" "yes"
"knockback" "1.8"
}
"M249"
{
"restrict" "yes"
"menu" "yes"
"knockback" "1.2"
}
"hegrenade"
{
"restrict" "no"
"menu" "yes"
"knockback" "6.0"
}
"flashbang"
{
"restrict" "yes"
"menu" "no"
}
"smokegrenade"
{
"restrict" "yes"
"menu" "no"
}
"Knife"
{
"restrict" "no"
"menu" "no"
"knockback" "15.0"
}
"NVGs"
{
"restrict" "yes"
"menu" "no"
}
}

View File

@ -84,8 +84,8 @@
"Config command reload syntax"
{
"#format" "{1:s},{2:s},{3:s},{4:s},{5:s},{6:s}"
"en" "Syntax: zr_reloadconfig <file alias> - Reloads a config file.\n File Aliases:\n * \"{1}\"\n * \"{2}\"\n * \"{3}\"\n * \"{4}\"\n * \"{5}\"\n * \"{6}\""
"#format" "{1:s},{2:s},{3:s},{4:s},{5:s}"
"en" "Syntax: zr_reloadconfig <file alias> - Reloads a config file.\n File Aliases:\n * \"{1}\"\n * \"{2}\"\n * \"{3}\"\n * \"{4}\"\n * \"{5}\""
}
"Config command reload invalid"
@ -289,46 +289,52 @@
"en" "Weapon @green\"{1}\" @defaulthas been unrestricted."
}
"Restrict weapon failed"
"Restrict weapon stopped"
{
"#format" "{1:s}"
"en" "Weapon @green\"{1}\" @defaultis already restricted."
}
"Unrestrict weapon failed"
"Unrestrict weapon stopped"
{
"#format" "{1:s}"
"en" "Weapon @green\"{1}\" @default has no restrictions set."
}
"Restrict custom weapon group"
"Restrict weapon type"
{
"#format" "{1:s},{2:s}"
"en" "Weapon group @green\"{1}\" ({2}) @defaulthas been restricted."
"#format" "{1:s}"
"en" "Weapons of type @green\"{1}\" @defaulthave been restricted."
}
"Unrestrict custom weapon group"
"Unrestrict weapon type"
{
"#format" "{1:s},{2:s}"
"en" "Weapon group @green\"{1}\" ({2}) @defaulthas been unrestricted."
"#format" "{1:s}"
"en" "Weapons of type @green\"{1}\" @defaulthave been unrestricted."
}
"Restrict custom weapon group failed"
"Restrict weapon type stopped"
{
"#format" "{1:s},{2:s}"
"en" "Weapon group @green\"{1}\" ({2}) @defaultis already restricted."
"#format" "{1:s}"
"en" "Weapons of type @green\"{1}\" @defaultare all already restricted."
}
"Unrestrict custom weapon group failed"
"Unrestrict weapon type stopped"
{
"#format" "{1:s},{2:s}"
"en" "Weapon group @green\"{1}\" ({2}) @defaulthas no restrictions set."
"#format" "{1:s}"
"en" "Weapons of type @green\"{1}\" @defaulthave no restrictions set."
}
"Restrict weapon untoggleable"
{
"#format" "{1:s}"
"en" "Weapon @green\"{1}\" @defaultmay not have its restrictions toggled."
}
"Weapon invalid"
{
"#format" "{1:s}"
"en" "Weapon @green\"{1}\" @defaultis an invalid weapon name."
"en" "Weapon @green\"{1}\" @defaultis an invalid weapon (type) name."
}
"Weapon is restricted"
@ -338,29 +344,28 @@
"ru" "Оружие @green{1} @default запрещено."
}
// Market
// ZMarket
"Market title"
{
"en" "Available Weapons:"
"en" ""
}
"Market rebuy"
{
"en" "Rebuy"
"ru" "Купить снова"
"en" ""
}
// Commands
"Weapons command restrict syntax"
{
"en" "Syntax: zr_restrict <weapon> (\"weapon_\" prefix is ignored)"
"en" "Restricts a weapon or a weapon type. Usage: zr_restrict <weapon|weapon type> [weapon2|weapontype2] ..."
}
"Weapons command unrestrict syntax"
{
"en" "Syntax: zr_unrestrict <weapon> (\"weapon_\" prefix is ignored)"
"en" "Unrestricts a weapon or a weapon type. Usage: zr_unrestrict <weapon|weapon type> [weapon2|weapontype2] ..."
}
// Menu
@ -370,56 +375,48 @@
"en" "Weapons Management"
}
"Weapons menu main toggle weapon restrict"
"Weapons menu main restrict"
{
"en" "Toggle Weapon Restriction"
"en" "Weapon Restrictions"
}
"Weapons menu main toggle weapon group restrict"
"Weapons menu main market"
{
"en" "Toggle Weapon Group Restriction"
"en" "ZMarket"
}
"Weapons menu main market" // Option disabled if ZMarket isn't installed
"Weapons menu types title"
{
"en" "ZMarket Options"
"en" "Weapon Restrictions\nSelect Weapon Type:"
}
"Weapons menu weapons weapon title"
{
"en" "Toggle Restrictions:\n * = restricted"
}
"Weapons menu weapons group title"
{
"en" "Access Weapon Group:\n * = Partially restricted\n ** = Fully restricted"
}
"Weapons menu weapon group title"
"Weapons menu types type title"
{
"#format" "{1:s}"
"en" "Modify Restrictions:\n Current Weapon Group: {1}\n * = restricted"
"en" "Weapon Restrictions\nWeapon Type: {1}\n[] = Restricted"
}
"Weapons menu market title"
{
"en" "Toggle Market Settings:"
}
"Weapons menu market toggle buyzone"
"Weapons menu types restrict all"
{
"#format" "{1:s}"
"en" "Buyzone Only (Current: {1})"
"en" "Restrict weapon type {1}"
}
"Weapons menu weapon group restrict all"
"Weapons menu types unrestrict all"
{
"en" "Restrict All Group Weapons"
"#format" "{1:s}"
"en" "Unrestrict weapon type {1}\n "
}
"Weapons menu weapon group unrestrict all"
"Weapons menu zmarket title"
{
"en" "Unrestrict All Group Weapons"
"en" "ZMarket\nSelect Setting:"
}
"Weapons menu zmarket buyzone"
{
"#format" "{1:s}"
"en" "Buyzone Only - {1}"
}
// ===========================
@ -556,37 +553,7 @@
"!zadmin main title"
{
"en" "ZAdmin Menu:"
}
"!zadmin main knockbackm"
{
"en" "Modify Knockback Multiplier"
}
"!zadmin main knockback"
{
"en" "Modify Class Knockback"
}
"!zadmin main nvgs"
{
"en" "Modify Nightvision Options"
}
"!zadmin main infect"
{
"en" "Infect a Player"
}
"!zadmin main spawn"
{
"en" "Spawn All Players"
}
"!zadmin main tele"
{
"en" "ZTele Commands"
"en" "ZAdmin\n Select Category:"
}
"!zadmin main weapons"

View File

@ -4,7 +4,7 @@
// * Zombie:Reloaded
// *
// * File: zombiereloaded.cfg
// * Type: Core
// * Type: Config
// * Description: Plugin cvar configuration.
// *
// * ============================================================================

View File

@ -16,9 +16,6 @@
#include <cstrike>
#include <zrtools>
#undef REQUIRE_PLUGIN
#include <market>
#define VERSION "3.0-dev"
// Core includes.
@ -103,35 +100,7 @@ public OnPluginStart()
WeaponsInit();
SayHooksInit();
EventInit();
MarketInit();
}
/**
* Library is being removed.
*
* @param name The name of the library.
*/
public OnLibraryRemoved(const String:name[])
{
// If market is being removed, then set variable to false.
if (StrEqual(name, "market", false))
{
g_bMarket = false;
}
}
/**
* Library is being added.
*
* @param name The name of the library.
*/
public OnLibraryAdded(const String:name[])
{
// If market is being added, then set variable to true.
if (StrEqual(name, "market", false))
{
g_bMarket = true;
}
ZMarketInit();
}
/**
@ -162,7 +131,7 @@ public OnMapEnd()
*/
public OnConfigsExecuted()
{
// Forward event to modules.
// Forward event to modules. (OnConfigsExecuted)
ConfigLoad();
ModelsLoad();
DownloadsLoad();
@ -173,6 +142,7 @@ public OnConfigsExecuted()
SEffectsLoad();
ClassLoad();
// Forward event to modules. (OnModulesLoaded)
ConfigOnModulesLoaded();
ClassOnModulesLoaded();
}

View File

@ -15,6 +15,24 @@
*/
#define ACCOUNT_CASH_MAX 16000
/**
* Variable to store account offset value.
*/
new g_iToolsAccount;
/**
* Find account-specific offsets here.
*/
AccountOnOffsetsFound()
{
// If offset "m_iAccount" can't be found, then stop the plugin.
g_iToolsAccount = FindSendPropInfo("CCSPlayer", "m_iAccount");
if (g_iToolsAccount == -1)
{
LogPrintToLog(LOG_FORMAT_TYPE_FATALERROR, "Account", "Offsets", "Offset \"CCSPlayer::m_iAccount\" was not found.");
}
}
/**
* Client is spawning into the game.
*

View File

@ -29,11 +29,29 @@
* @endsection
*/
/**
* Variable to store antistick offset value.
*/
new g_iToolsCollisionGroup;
/**
* Handle to keep track of AntiStickTimer.
*/
new Handle:tAntiStick = INVALID_HANDLE;
/**
* Find antistick-specific offsets here.
*/
AntiStickOnOffsetsFound()
{
// If offset "m_CollisionGroup" can't be found, then stop the plugin.
g_iToolsCollisionGroup = FindSendPropInfo("CBaseEntity", "m_CollisionGroup");
if (g_iToolsCollisionGroup == -1)
{
LogPrintToLog(LOG_FORMAT_TYPE_FATALERROR, "Tools", "Offsets", "Offset \"CBaseEntity::m_CollisionGroup\" was not found.");
}
}
/**
* Map is starting.
*/
@ -191,4 +209,4 @@ AntiStickClientCollisionGroup(client, bool:apply = true, collisiongroup = 0)
}
return GetEntData(client, g_iToolsCollisionGroup, 1);
}
}

View File

@ -22,23 +22,31 @@
#define CONFIG_FILE_ALIAS_DOWNLOADS "downloads"
#define CONFIG_FILE_ALIAS_CLASSES "classes"
#define CONFIG_FILE_ALIAS_WEAPONS "weapons"
#define CONFIG_FILE_ALIAS_WEAPONGROUPS "weapongroups"
#define CONFIG_FILE_ALIAS_HITGROUPS "hitgroups"
/**
* @endsection
*/
/**
* List of config formats used by the plugin.
*/
enum ConfigStructure
{
Structure_List, /** Config is structured as a simple list of strings. */
Structure_Keyvalue, /** Config is a keyvalue structure */
}
/**
* List of config files used by the plugin.
*/
enum ConfigFile
{
ConfigInvalid = -1, /** Invalid config file. */
ConfigModels, /** <sourcemod root>/configs/zr/models.txt (default) */
ConfigDownloads, /** <sourcemod root>/configs/zr/downloads.txt (default) */
ConfigClasses, /** <sourcemod root>/configs/zr/playerclasses.txt (default) */
ConfigWeapons, /** <sourcemod root>/configs/zr/weapons/weapons.txt/weapongroups.txt (default) */
ConfigHitgroups, /** <sourcemod root>/configs/zr/hitgroups.txt (default) */
File_Invalid = -1, /** Invalid config file. */
File_Models, /** <sourcemod root>/configs/zr/models.txt (default) */
File_Downloads, /** <sourcemod root>/configs/zr/downloads.txt (default) */
File_Classes, /** <sourcemod root>/configs/zr/playerclasses.txt (default) */
File_Weapons, /** <sourcemod root>/configs/zr/weapons.txt (default) */
File_Hitgroups, /** <sourcemod root>/configs/zr/hitgroups.txt (default) */
}
/**
@ -46,11 +54,12 @@ enum ConfigFile
*/
enum ConfigData
{
bool:ConfigLoaded, /** True if config is loaded, false if not. */
Function:ConfigReloadFunc, /** Function to call to reload config. */
Handle:ConfigHandle, /** Handle of the config file. */
String:ConfigPath[PLATFORM_MAX_PATH], /** Full path to config file. */
String:ConfigAlias[CONFIG_MAX_LENGTH], /** Config file alias, used for client interaction. */
bool: Data_Loaded, /** True if config is loaded, false if not. */
ConfigStructure: Data_Structure, /** Format of the config */
Function: Data_ReloadFunc, /** Function to call to reload config. */
Handle: Data_Handle, /** Handle of the config file. */
String: Data_Path[PLATFORM_MAX_PATH], /** Full path to config file. */
String: Data_Alias[CONFIG_MAX_LENGTH], /** Config file alias, used for client interaction. */
}
/**
@ -61,24 +70,14 @@ new g_ConfigData[ConfigFile][ConfigData];
/**
* Actions to use when working on key/values.
*/
enum ConfigKeyvalueAction
enum ConfigKvAction
{
ConfigKVCreate, /** Create a key. */
ConfigKVDelete, /** Delete a key. */
ConfigKVSet, /** Modify setting of a key. */
ConfigKVGet, /** Get setting of a key. */
KvAction_Create, /** Create a key. */
KvAction_KVDelete, /** Delete a key. */
KvAction_KVSet, /** Modify setting of a key. */
KvAction_KVGet, /** Get setting of a key. */
}
/**
* @section Global data handle initializations.
*/
new Handle:arrayModelsList = INVALID_HANDLE;
new Handle:arrayDownloadsList = INVALID_HANDLE;
new Handle:kvClassData = INVALID_HANDLE;
new Handle:kvWeapons = INVALID_HANDLE;
new Handle:kvWeaponGroups = INVALID_HANDLE;
new Handle:kvHitgroups = INVALID_HANDLE;
/**
* Create commands related to config here.
*/
@ -157,20 +156,20 @@ ConfigOnModulesLoaded()
/**
* Used by modules that rely on configs to register their config file info.
* (Don't forget to set 'loaded' to 'true' (ConfigSetConfigLoaded) in config load function)
*
* @param file Config file entry to register.
* @param loaded True if the config should be loaded, false if not.
* @param path (Optional) Full path to config file.
* @param alias (Optional) Config file alias, used for client interaction.
* @param alias Config file alias, used for client interaction.
*/
stock ConfigRegisterConfig(ConfigFile:file, bool:loaded, Function:reloadfunc, Handle:filehandle = INVALID_HANDLE, const String:path[] = "", const String:alias[] = "")
stock ConfigRegisterConfig(ConfigFile:file, ConfigStructure:structure, const String:alias[] = "")
{
// Copy file info to data container.
g_ConfigData[file][ConfigLoaded] = loaded;
g_ConfigData[file][ConfigHandle] = filehandle;
g_ConfigData[file][ConfigReloadFunc] = reloadfunc;
strcopy(g_ConfigData[file][ConfigPath], PLATFORM_MAX_PATH, path);
strcopy(g_ConfigData[file][ConfigAlias], CONFIG_MAX_LENGTH, alias);
g_ConfigData[file][Data_Loaded] = false;
g_ConfigData[file][Data_Structure] = structure;
g_ConfigData[file][Data_Handle] = INVALID_HANDLE;
g_ConfigData[file][Data_ReloadFunc] = INVALID_FUNCTION;
strcopy(g_ConfigData[file][Data_Path], PLATFORM_MAX_PATH, "");
strcopy(g_ConfigData[file][Data_Alias], CONFIG_MAX_LENGTH, alias);
}
/**
@ -182,7 +181,19 @@ stock ConfigRegisterConfig(ConfigFile:file, bool:loaded, Function:reloadfunc, Ha
stock ConfigSetConfigLoaded(ConfigFile:config, bool:loaded)
{
// Set load state.
g_ConfigData[config][ConfigLoaded] = loaded;
g_ConfigData[config][Data_Loaded] = loaded;
}
/**
* Set the structure type of a config file entry.
*
* @param config Config file to set structure type of.
* @param structure Structure to set as.
*/
stock ConfigSetConfigStructure(ConfigFile:config, ConfigStructure:structure)
{
// Set load state.
g_ConfigData[config][Data_Structure] = structure;
}
/**
@ -194,7 +205,7 @@ stock ConfigSetConfigLoaded(ConfigFile:config, bool:loaded)
stock ConfigSetConfigReloadFunc(ConfigFile:config, Function:reloadfunc)
{
// Set reload function.
g_ConfigData[config][ConfigReloadFunc] = reloadfunc;
g_ConfigData[config][Data_ReloadFunc] = reloadfunc;
}
/**
@ -206,7 +217,7 @@ stock ConfigSetConfigReloadFunc(ConfigFile:config, Function:reloadfunc)
stock ConfigSetConfigHandle(ConfigFile:config, Handle:file)
{
// Set file handle.
g_ConfigData[config][ConfigHandle] = file;
g_ConfigData[config][Data_Handle] = file;
}
/**
@ -218,7 +229,7 @@ stock ConfigSetConfigHandle(ConfigFile:config, Handle:file)
stock ConfigSetConfigPath(ConfigFile:config, const String:path[])
{
// Set config file path.
strcopy(g_ConfigData[config][ConfigPath], PLATFORM_MAX_PATH, path);
strcopy(g_ConfigData[config][Data_Path], PLATFORM_MAX_PATH, path);
}
/**
@ -230,7 +241,7 @@ stock ConfigSetConfigPath(ConfigFile:config, const String:path[])
stock ConfigSetConfigAlias(ConfigFile:config, const String:alias[])
{
// Set config alias.
strcopy(g_ConfigData[config][ConfigAlias], CONFIG_MAX_LENGTH, alias);
strcopy(g_ConfigData[config][Data_Alias], CONFIG_MAX_LENGTH, alias);
}
/**
@ -242,7 +253,19 @@ stock ConfigSetConfigAlias(ConfigFile:config, const String:alias[])
stock bool:ConfigIsConfigLoaded(ConfigFile:config)
{
// Return load status.
return g_ConfigData[config][ConfigLoaded];
return g_ConfigData[config][Data_Loaded];
}
/**
* Returns config's structure type.
*
* @param config Config file to get structure type of.
* @return Config structure type.
*/
stock ConfigStructure:ConfigGetConfigStructure(ConfigFile:config)
{
// Return load status.
return g_ConfigData[config][Data_Structure];
}
/**
@ -254,7 +277,7 @@ stock bool:ConfigIsConfigLoaded(ConfigFile:config)
stock Function:ConfigGetConfigReloadFunc(ConfigFile:config)
{
// Return load status.
return g_ConfigData[config][ConfigReloadFunc];
return g_ConfigData[config][Data_ReloadFunc];
}
/**
@ -266,7 +289,7 @@ stock Function:ConfigGetConfigReloadFunc(ConfigFile:config)
stock Handle:ConfigGetConfigHandle(ConfigFile:config)
{
// Return load status.
return g_ConfigData[config][ConfigHandle];
return g_ConfigData[config][Data_Handle];
}
/**
@ -277,7 +300,7 @@ stock Handle:ConfigGetConfigHandle(ConfigFile:config)
stock ConfigGetConfigPath(ConfigFile:config, String:path[], maxlen)
{
// Copy path to return string.
strcopy(path, maxlen, g_ConfigData[config][ConfigPath]);
strcopy(path, maxlen, g_ConfigData[config][Data_Path]);
}
/**
@ -288,7 +311,133 @@ stock ConfigGetConfigPath(ConfigFile:config, String:path[], maxlen)
stock ConfigGetConfigAlias(ConfigFile:config, String:alias[], maxlen)
{
// Copy alias to return string.
strcopy(alias, maxlen, g_ConfigData[config][ConfigAlias]);
strcopy(alias, maxlen, g_ConfigData[config][Data_Alias]);
}
/**
* Loads a config file and sets up a nested array type data storage.
*
* @param config The config file to load.
* @param arrayConfig Handle of the main array containing file data.
* @return True if file was loaded successfuly, false otherwise.
*/
stock bool:ConfigLoadConfig(ConfigFile:config, &Handle:arrayConfig)
{
// Get config's structure.
new ConfigStructure:structure = ConfigGetConfigStructure(config);
// Get config's alias
decl String:configalias[CONFIG_MAX_LENGTH];
ConfigGetConfigAlias(config, configalias, sizeof(configalias));
// Get config's file path.
decl String:configpath[PLATFORM_MAX_PATH];
ConfigGetConfigPath(config, configpath, sizeof(configpath));
// If handle is still open, then close it before creating a new one.
if (arrayConfig != INVALID_HANDLE)
{
CloseHandle(arrayConfig);
}
// Create array in handle.
arrayConfig = CreateArray(CONFIG_MAX_LENGTH);
switch(structure)
{
case Structure_List:
{
// Open file.
new Handle:hFile;
new success = ConfigOpenConfigFile(config, hFile);
// If config file failed to open, then stop.
if (!success)
{
return false;
}
// Clear out array.
ClearArray(arrayConfig);
decl String:line[PLATFORM_MAX_PATH];
while(!IsEndOfFile(hFile))
{
// Get current line text.
ReadFileLine(hFile, line, sizeof(line));
// If line contains a ";", then stop.
if (StrContains(line, ";") > -1)
{
continue;
}
// Cut out comments at the end of a line.
if (StrContains(line, "//") > -1)
{
SplitString(line, "//", line, sizeof(line));
}
// Trim off whitespace.
TrimString(line);
// If line is empty, then stop.
if (!line[0])
{
continue;
}
// Push line into array.
PushArrayString(arrayConfig, line);
}
// We're done this file, so now we can destory it from memory.
CloseHandle(hFile);
return true;
}
case Structure_Keyvalue:
{
// Open file.
new Handle:hKeyvalue;
new success = ConfigOpenConfigFile(config, hKeyvalue);
// If config file failed to open, then stop.
if (!success)
{
return false;
}
// Destroy all old data.
ConfigClearKvArray(arrayConfig);
if (KvGotoFirstSubKey(hKeyvalue))
{
do
{
// Create new array to store information for config entry.
new Handle:arrayConfigEntry = CreateArray(CONFIG_MAX_LENGTH);
// Push the key name into the config entry's array.
decl String:keyname[CONFIG_MAX_LENGTH];
KvGetSectionName(hKeyvalue, keyname, sizeof(keyname));
PushArrayString(arrayConfigEntry, keyname); // Index: 0
// Store this handle in the main array.
PushArrayCell(arrayConfig, arrayConfigEntry);
} while(KvGotoNextKey(hKeyvalue));
}
// We're done this file for now, so now we can destory it from memory.
CloseHandle(hKeyvalue);
return true;
}
}
return false;
}
/**
@ -297,7 +446,7 @@ stock ConfigGetConfigAlias(ConfigFile:config, String:alias[], maxlen)
* @param config The config file entry to reload.
* @return True if the config is loaded, false if not.
*/
stock bool:ConfigReloadFile(ConfigFile:config)
stock bool:ConfigReloadConfig(ConfigFile:config)
{
// If file isn't loaded, then stop.
new bool:loaded = ConfigIsConfigLoaded(config);
@ -309,6 +458,7 @@ stock bool:ConfigReloadFile(ConfigFile:config)
// Call reload function
new Function:reloadfunc = ConfigGetConfigReloadFunc(config);
// This should never be true unless someone has tampered with the code.
if (reloadfunc == INVALID_FUNCTION)
{
// Get config alias.
@ -323,12 +473,169 @@ stock bool:ConfigReloadFile(ConfigFile:config)
// Call reload function.
Call_StartFunction(GetMyHandle(), reloadfunc);
Call_PushCell(config);
Call_Finish();
return true;
}
/**
* Opens a config file with appropriate method.
*
* @param config The config file.
* @param structure The structure of the config file.
* @param hConfig The handle of the opened file.
*/
stock bool:ConfigOpenConfigFile(ConfigFile:config, &Handle:hConfig)
{
// Get config's structure
new ConfigStructure:structure = ConfigGetConfigStructure(config);
// Get config's file path.
decl String:configpath[PLATFORM_MAX_PATH];
ConfigGetConfigPath(config, configpath, sizeof(configpath));
// Get config's alias
decl String:configalias[CONFIG_MAX_LENGTH];
ConfigGetConfigAlias(config, configalias, sizeof(configalias));
switch(structure)
{
case Structure_List:
{
// Open file.
hConfig = OpenFile(configpath, "r");
// If file couldn't be opened, then stop.
if (hConfig == INVALID_HANDLE)
{
return false;
}
return true;
}
case Structure_Keyvalue:
{
hConfig = CreateKeyValues(configalias);
return FileToKeyValues(hConfig, configpath);
}
}
return false;
}
/**
* Creates, deletes, sets, or gets any key/setting of any ZR config keyvalue file in memory.
* Only use when interacting with a command or manipulating single keys/values,
* using this function everywhere would be EXTREMELY inefficient.
*
* @param config Config file to modify.
* @param action Action to perform on keyvalue tree. (see enum ConfigKeyvalueAction)
* @param keys Array containing keys to traverse into.
* @param keysMax The size of the 'keys' array.
* @param setting (Optional) The name of the setting to modify.
* @param value (Optional) The new value to set.
* @param maxlen (Optional) The maxlength of the retrieved value.
* @return True if the change was made successfully, false otherwise.
*/
stock bool:ConfigKeyvalueTreeSetting(ConfigFile:config, ConfigKvAction:action = KvAction_Create, const String:keys[][], keysMax, const String:setting[] = "", String:value[] = "", maxlen = 0)
{
// Get config file's structure.
new ConfigStructure:structure = ConfigGetConfigStructure(config);
// If the config is any other structure beside keyvalue, then stop.
if (structure != Structure_Keyvalue)
{
return false;
}
// Retrieve handle of the keyvalue tree.
new Handle:hConfig;
new bool:success = ConfigOpenConfigFile(config, hConfig);
// If the file couldn't be opened, then stop.
if (!success)
{
return false;
}
// Rewind keyvalue tree.
KvRewind(hConfig);
// x = keys index.
// Traverse into the keygroup, stop if it fails.
for (new x = 0; x < keysMax; x++)
{
// If key is empty, then break the loop.
if (!keys[x][0])
{
break;
}
// Try to jump to next level in the transversal stack, create key if specified.
new bool:exists = KvJumpToKey(hConfig, keys[x], (action == KvAction_Create));
// If exists is false, then stop.
if (!exists)
{
// Key doesn't exist.
return false;
}
}
switch(action)
{
case KvAction_Create:
{
if (!setting[0] || !value[0])
{
// We created the key already, so return true.
return true;
}
// Set new value.
KvSetString(hConfig, setting, value);
}
case KvAction_Delete:
{
// Return deletion result.
return KvDeleteKey(hConfig, setting);
}
case KvAction_Set:
{
// Set new value.
KvSetString(hConfig, setting, value);
}
case KvAction_Get:
{
// Get current value.
KvGetString(hConfig, setting, value, maxlen);
}
}
// We successfully set or got the value.
return true;
}
/**
* Destroy all array handles within an array, and clear main array.
*
* @param arrayKv The array converted from a keyvalue structure.
*/
ConfigClearKvArray(Handle:arrayKv)
{
// x = array index
new size = GetArraySize(arrayKv);
for (new x = 0; x < size; x++)
{
// Destroy nested arrays.
new Handle:arrayKvKey = GetArrayCell(arrayKv, x);
CloseHandle(arrayKvKey);
}
// Now that all data within has been destroyed, we can clear the main array.
ClearArray(arrayKv);
}
/**
* Load config file.
*
@ -374,94 +681,11 @@ stock ConfigFile:ConfigAliasToConfigFile(const String:alias[])
}
// Invalid config file.
return ConfigInvalid;
return File_Invalid;
}
/**
* Creates, deletes, sets, or gets any key/setting of any ZR config keyvalue file in memory.
* Only use when interacting with a command or manipulating single keys/values,
* using this function everywhere would be EXTREMELY inefficient.
*
* @param config Config index of config to modify. (see CONFIG_FILE_* defines)
* @param action Action to perform on keyvalue tree. (see enum ConfigKeyvalueAction)
* @param keys Array containing keys to traverse into.
* @param keysMax The size of the 'keys' array.
* @param setting (Optional) The name of the setting to modify.
* @param value (Optional) The new value to set.
* @param maxlen (Optional) The maxlength of the gotten value.
* @return True if the change was made successfully, false otherwise.
*/
stock bool:ConfigKeyvalueTreeSetting(config, ConfigKeyvalueAction:action = ConfigKVCreate, const String:keys[][], keysMax, const String:setting[] = "", String:value[] = "", maxlen = 0)
{
// Retrieve handle of the keyvalue tree.
new Handle:hConfig = ConfigGetConfigHandle(config);
// If handle is invalid, then stop.
if (hConfig == INVALID_HANDLE)
{
return false;
}
// Rewind keyvalue tree.
KvRewind(hConfig);
// x = keys index.
// Traverse into the keygroup, stop if it fails.
for (new x = 0; x < keysMax; x++)
{
// If key is empty, then break the loop.
if (!keys[x][0])
{
break;
}
// Try to jump to next level in the transversal stack, create key if specified.
new bool:exists = KvJumpToKey(hConfig, keys[x], (action == Create));
// If exists is false, then stop.
if (!exists)
{
// Key doesn't exist.
return false;
}
}
switch(action)
{
case ConfigKVCreate:
{
if (!setting[0] || !value[0])
{
// We created the key already, so return true.
return true;
}
// Set new value.
KvSetString(hConfig, setting, value);
}
case ConfigKVDelete:
{
// Return deletion result.
return KvDeleteKey(hConfig, setting);
}
case ConfigKVSet:
{
// Set new value.
KvSetString(hConfig, setting, value);
}
case ConfigKVGet:
{
// Get current value.
KvGetString(hConfig, setting, value, maxlen);
}
}
// We successfully set or got the value.
return true;
}
/**
* Command callback (zr_reloadconfig)
* Command callback (zr_config_reload)
* Reloads a config file and forwards event to modules.
*
* @param client The client index.
@ -472,7 +696,7 @@ public Action:ConfigReloadCommand(client, argc)
// If not enough arguments given, then stop.
if (argc < 1)
{
TranslationReplyToCommand(client, "Config command reload syntax", CONFIG_FILE_ALIAS_MODELS, CONFIG_FILE_ALIAS_DOWNLOADS, CONFIG_FILE_ALIAS_CLASSES, CONFIG_FILE_ALIAS_WEAPONS, CONFIG_FILE_ALIAS_WEAPONGROUPS, CONFIG_FILE_ALIAS_HITGROUPS);
TranslationReplyToCommand(client, "Config command reload syntax", CONFIG_FILE_ALIAS_MODELS, CONFIG_FILE_ALIAS_DOWNLOADS, CONFIG_FILE_ALIAS_CLASSES, CONFIG_FILE_ALIAS_WEAPONS, CONFIG_FILE_ALIAS_HITGROUPS);
return Plugin_Handled;
}
@ -482,14 +706,14 @@ public Action:ConfigReloadCommand(client, argc)
// If alias is invalid, then stop.
new ConfigFile:config = ConfigAliasToConfigFile(arg1);
if (config == ConfigInvalid)
if (config == File_Invalid)
{
TranslationReplyToCommand(client, "Config command reload invalid", arg1);
return Plugin_Handled;
}
// Reload config file.
new bool:loaded = ConfigReloadFile(config);
new bool:loaded = ConfigReloadConfig(config);
// Get config file path.
decl String:path[PLATFORM_MAX_PATH];
@ -506,7 +730,7 @@ public Action:ConfigReloadCommand(client, argc)
}
/**
* Command callback (zr_reloadconfigall)
* Command callback (zr_config_reloadall)
* Reloads all config files and forwards event to all modules.
*
* @param client The client index.
@ -523,7 +747,7 @@ public Action:ConfigReloadAllCommand(client, argc)
for (new x = 0; x < sizeof(g_ConfigData); x++)
{
// Reload config file.
new bool:successful = ConfigReloadFile(ConfigFile:x);
new bool:successful = ConfigReloadConfig(ConfigFile:x);
// Get config's alias.
ConfigGetConfigAlias(ConfigFile:x, configalias, sizeof(configalias));
@ -539,71 +763,13 @@ public Action:ConfigReloadAllCommand(client, argc)
}
}
/**
* Iterate through a file and store each line in an array.
*
* @param path Path to the file to iterate through.
* @return The handle of the array, don't forget to call CloseHandle
* on it when finished!
*/
Handle:ConfigLinesToArray(const String:path[])
{
new Handle:arrayLines = CreateArray(PLATFORM_MAX_PATH);
decl String:line[PLATFORM_MAX_PATH];
// Open file.
new Handle:hFile = OpenFile(path, "r");
// If file couldn't be opened, then stop.
if (hFile == INVALID_HANDLE)
{
return INVALID_HANDLE;
}
while(!IsEndOfFile(hFile))
{
// Get current line text.
ReadFileLine(hFile, line, sizeof(line));
// If line contains a ";", then stop.
if (StrContains(line, ";") > -1)
{
continue;
}
// Cut out comments at the end of a line.
if (StrContains(line, "//") > -1)
{
SplitString(line, "//", line, sizeof(line));
}
// Trim off whitespace.
TrimString(line);
// If line is empty, then stop.
if (!line[0])
{
continue;
}
// Push line into array.
PushArrayString(arrayLines, line);
}
// Close file handle.
CloseHandle(hFile);
// Return array handle.
return arrayLines;
}
/**
* Converts string of "yes" or "no" to a boolean value.
*
* @param option "yes" or "no" string to be converted.
* @return True if string is "yes", false otherwise.
*/
bool:ConfigSettingToBool(const String:option[])
stock bool:ConfigSettingToBool(const String:option[])
{
// If option is equal to "yes," then return true.
if (StrEqual(option, "yes", false))
@ -620,9 +786,9 @@ bool:ConfigSettingToBool(const String:option[])
*
* @param bOption True/false value to be converted to "yes"/"no", respectively.
* @param option Destination string buffer to store "yes" or "no" in.
* @param maxlen Length of destination string buffer (can't be more than 4).
* @param maxlen Length of destination string buffer (wont't be more than 4).
*/
ConfigBoolToSetting(bool:bOption, String:option[], maxlen)
stock ConfigBoolToSetting(bool:bOption, String:option[], maxlen)
{
// If option is true, then copy "yes" to return string.
if (bOption)
@ -635,3 +801,11 @@ ConfigBoolToSetting(bool:bOption, String:option[], maxlen)
strcopy(option, maxlen, "no");
}
}
stock bool:ConfigKvGetStringBool(Handle:kv, const String:key[], const String:defaultvalue[] = "yes")
{
decl String:value[CONFIG_MAX_LENGTH];
KvGetString(kv, key, value, sizeof(value), defaultvalue);
return ConfigSettingToBool(value);
}

View File

@ -38,7 +38,6 @@ enum CvarsList
Handle:CVAR_CONFIG_PATH_DOWNLOADS,
Handle:CVAR_CONFIG_PATH_CLASSES,
Handle:CVAR_CONFIG_PATH_WEAPONS,
Handle:CVAR_CONFIG_PATH_WEAPONGROUPS,
Handle:CVAR_CONFIG_PATH_HITGROUPS,
Handle:CVAR_CLASSES_SPAWN,
Handle:CVAR_CLASSES_RANDOM,
@ -51,6 +50,7 @@ enum CvarsList
Handle:CVAR_CLASSES_OVERLAY_DEFAULT,
Handle:CVAR_WEAPONS,
Handle:CVAR_WEAPONS_RESTRICT,
Handle:CVAR_WEAPONS_ZMARKET,
Handle:CVAR_WEAPONS_ZMARKET_BUYZONE,
Handle:CVAR_HITGROUPS,
Handle:CVAR_DAMAGE_HITGROUPS,
@ -207,9 +207,8 @@ CvarsCreate()
g_hCvarsList[CVAR_CONFIG_PATH_MODELS] = CreateConVar("zr_config_path_models", "configs/zr/models.txt", "Path, relative to root sourcemod directory, to models config file.");
g_hCvarsList[CVAR_CONFIG_PATH_DOWNLOADS] = CreateConVar("zr_config_path_downloads", "configs/zr/downloads.txt", "Path, relative to root sourcemod directory, to downloads file.");
g_hCvarsList[CVAR_CONFIG_PATH_CLASSES] = CreateConVar("zr_config_path_playerclasses", "configs/zr/playerclasses.txt", "Path, relative to root sourcemod directory, to playerclasses config file.");
g_hCvarsList[CVAR_CONFIG_PATH_WEAPONS] = CreateConVar("zr_config_path_weapons", "configs/zr/weapons/weapons.txt", "Path, relative to root sourcemod directory, to weapons config file.");
g_hCvarsList[CVAR_CONFIG_PATH_WEAPONGROUPS] = CreateConVar("zr_config_path_weapongroups", "configs/zr/weapons/weapongroups.txt", "Path, relative to root sourcemod directory, to weapongroups config file.");
g_hCvarsList[CVAR_CONFIG_PATH_CLASSES] = CreateConVar("zr_config_path_playerclasses", "configs/zr/playerclasses.txt", "Path, relative to root sourcemod directory, to playerclasses config file.");
g_hCvarsList[CVAR_CONFIG_PATH_WEAPONS] = CreateConVar("zr_config_path_weapons", "configs/zr/weapons.txt", "Path, relative to root sourcemod directory, to weapons config file.");
g_hCvarsList[CVAR_CONFIG_PATH_HITGROUPS] = CreateConVar("zr_config_path_hitgroups", "configs/zr/hitgroups.txt", "Path, relative to root sourcemod directory, to hitgroups config file.");
// ===========================
@ -258,9 +257,10 @@ CvarsCreate()
g_hCvarsList[CVAR_WEAPONS_RESTRICT] = CreateConVar("zr_weapons_restrict", "1", "Enable weapon restriction module, disabling this will disable weapon restriction commands.");
// Market Handler
// ZMarket
g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE] = CreateConVar("zr_weapons_zmarket_buyzone", "1", "Requires player to be inside a buyzone to use ZMarket.");
g_hCvarsList[CVAR_WEAPONS_ZMARKET] = CreateConVar("zr_weapons_zmarket", "1", "Allow player to buy from a list of weapons in the weapons config.");
g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE] = CreateConVar("zr_weapons_zmarket_buyzone", "1", "Requires player to be inside a buyzone to use ZMarket. [Dependency: zr_weapons_zmarket]");
// ===========================
// Hitgroups (core)

View File

@ -48,7 +48,7 @@ DamageOnCommandsHook()
// Explode string into array indexes.
new cmdcount = ExplodeString(suicidecmds, ", ", arrayCmds, DAMAGE_SUICIDE_MAX_CMDS, DAMAGE_SUICIDE_MAX_LENGTH);
// x = array index.
// x = Array index.
// arrayCmds[x] = suicide command.
for (new x = 0; x <= cmdcount - 1; x++)
{
@ -147,7 +147,16 @@ public ZRTools_Action:DamageTraceAttack(client, inflictor, attacker, Float:damag
}
// If damage is disabled for this hitgroup, then stop.
new bool:candamage = HitgroupsCanDamageHitgroup(hitgroup);
new index = HitgroupToIndex(hitgroup);
// If index can't be found, then allow damage.
if (index == -1)
{
// Allow damage.
return ZRTools_Continue;
}
new bool:candamage = HitgroupsCanDamage(index);
if (!candamage)
{
// Stop bullet from hurting client.

View File

@ -12,43 +12,38 @@
/**
* Array that stores a list of downloadable files.
*
* @redir config.inc
*/
new Handle:arrayDownloads = INVALID_HANDLE;
/**
* Prepare all model/download data.
*/
DownloadsLoad()
{
// Register config file.
ConfigRegisterConfig(File_Downloads, Structure_List, CONFIG_FILE_ALIAS_DOWNLOADS);
// Get downloads file path.
decl String:pathdownloads[PLATFORM_MAX_PATH];
new bool:exists = ConfigGetCvarFilePath(CVAR_CONFIG_PATH_DOWNLOADS, pathdownloads);
// Register config info.
ConfigRegisterConfig(ConfigDownloads, false, GetFunctionByName(GetMyHandle(), "DownloadsOnConfigReload"), _, pathdownloads, CONFIG_FILE_ALIAS_DOWNLOADS);
// If file doesn't exist, then log.
// If file doesn't exist, then log and stop.
if (!exists)
{
// Log error, then stop.
LogPrintToLog(LOG_FORMAT_TYPE_ERROR, "Downloads", "Config Validation", "Missing downloads file: \"%s\"", pathdownloads);
return;
// Log failure and stop plugin.
LogPrintToLog(LOG_FORMAT_TYPE_FATALERROR, "Downloads", "Config Validation", "Fatal Error: Missing downloads file: \"%s\"", pathdownloads);
}
// If download array exists, then destroy it.
if (arrayDownloadsList != INVALID_HANDLE)
{
CloseHandle(arrayDownloadsList);
}
// Set the path to the config file.
ConfigSetConfigPath(File_Downloads, pathdownloads);
arrayDownloadsList = ConfigLinesToArray(pathdownloads);
// Load config from file and create array structure.
new bool:success = ConfigLoadConfig(File_Downloads, arrayDownloads);
// If array couldn't be created, then fail.
if (arrayDownloadsList == INVALID_HANDLE)
// Unexpected error, stop plugin.
if (!success)
{
LogPrintToLog(LOG_FORMAT_TYPE_ERROR, "Downloads", "Config Validation", "Error parsing \"%s\"", pathdownloads);
LogPrintToLog(LOG_FORMAT_TYPE_FATALERROR, "Downloads", "Config Validation", "Fatal Error: Unexpected error encountered loading: %s", pathdownloads);
}
new downloadcount;
@ -56,19 +51,19 @@ DownloadsLoad()
decl String:downloadpath[PLATFORM_MAX_PATH];
new downloads = downloadcount = GetArraySize(arrayDownloadsList);
new downloads = downloadcount = GetArraySize(arrayDownloads);
// x = download array index.
for (new x = 0; x < downloads; x++)
{
// Get base model path (rawline in models.txt)
GetArrayString(arrayDownloadsList, x, downloadpath, sizeof(downloadpath));
// Get download path
GetArrayString(arrayDownloads, x, downloadpath, sizeof(downloadpath));
// If file doesn't exist, then remove, log, and stop.
if (!FileExists(downloadpath))
{
// Remove client from array.
RemoveFromArray(arrayDownloadsList, x);
RemoveFromArray(arrayDownloads, x);
// Subtract one from count.
downloads--;
@ -91,8 +86,9 @@ DownloadsLoad()
LogPrintToLog(LOG_FORMAT_TYPE_NORMAL, "Downloads", "Config Validation", "Total: %d | Successful: %d | Unsuccessful: %d", downloadcount, downloadvalidcount, downloadcount - downloadvalidcount);
// Set config data.
ConfigSetConfigLoaded(ConfigDownloads, true);
ConfigSetConfigHandle(ConfigDownloads, arrayDownloadsList);
ConfigSetConfigLoaded(File_Downloads, true);
ConfigSetConfigReloadFunc(File_Downloads, GetFunctionByName(GetMyHandle(), "DownloadsOnConfigReload"));
ConfigSetConfigHandle(File_Downloads, arrayDownloads);
}
/**
@ -103,8 +99,5 @@ DownloadsLoad()
public DownloadsOnConfigReload(ConfigFile:config)
{
// Reload download config.
if (config == ConfigDownloads)
{
DownloadsLoad();
}
DownloadsLoad();
}

View File

@ -11,10 +11,9 @@
*/
/**
* Keyvalue handle to store hitgroups data.
*
* @redir config.inc
* Maximum length for a hitgroup name
*/
#define HITGROUPS_MAX_LENGTH 32
/**
* @section Player hitgroup values.
@ -33,33 +32,28 @@
*/
/**
* Clears hitgroup data.
*/
HitgroupsClearData()
* Hitgroup config data indexes.
*/
enum HitgroupsData
{
// Load hitgroup data.
if (kvHitgroups != INVALID_HANDLE)
{
CloseHandle(kvHitgroups);
}
kvHitgroups = CreateKeyValues("hitgroups");
HITGROUPS_DATA_NAME = 0,
HITGROUPS_DATA_INDEX,
HITGROUPS_DATA_DAMAGE,
HITGROUPS_DATA_KNOCKBACK,
}
/**
* Array handle to store hitgroups data.
*/
new Handle:arrayHitgroups = INVALID_HANDLE;
/**
* Loads hitgroup data from file.
*/
HitgroupsLoad()
{
// Clear hitgroup data
HitgroupsClearData();
// Get hitgroups config path.
decl String:pathhitgroups[PLATFORM_MAX_PATH];
new bool:exists = ConfigGetCvarFilePath(CVAR_CONFIG_PATH_HITGROUPS, pathhitgroups);
// Register config info.
ConfigRegisterConfig(ConfigHitgroups, false, GetFunctionByName(GetMyHandle(), "HitgroupsOnConfigReload"), _, pathhitgroups, CONFIG_FILE_ALIAS_HITGROUPS);
// Register config file.
ConfigRegisterConfig(File_Hitgroups, Structure_Keyvalue, CONFIG_FILE_ALIAS_HITGROUPS);
// If module is disabled, then stop.
new bool:hitgroups = GetConVarBool(g_hCvarsList[CVAR_HITGROUPS]);
@ -68,23 +62,101 @@ HitgroupsLoad()
return;
}
// Get hitgroups config path.
decl String:pathhitgroups[PLATFORM_MAX_PATH];
new bool:exists = ConfigGetCvarFilePath(CVAR_CONFIG_PATH_HITGROUPS, pathhitgroups);
// If file doesn't exist, then log and stop.
if (!exists)
{
// Log failure.
LogPrintToLog(LOG_FORMAT_TYPE_ERROR, "Hitgroups", "Config Validation", "Missing hitgroups config file: %s", pathhitgroups);
return;
}
// Put file data into memory.
FileToKeyValues(kvHitgroups, pathhitgroups);
// Set the path to the config file.
ConfigSetConfigPath(File_Hitgroups, pathhitgroups);
// Load config from file and create array structure.
new bool:success = ConfigLoadConfig(File_Hitgroups, arrayHitgroups);
// Unexpected error, stop plugin.
if (!success)
{
LogPrintToLog(LOG_FORMAT_TYPE_ERROR, "Hitgroups", "Config Validation", "Unexpected error encountered loading: %s", pathhitgroups);
return;
}
// Validate hitgroups config.
HitgroupsValidateConfig();
new size = GetArraySize(arrayHitgroups);
if (!size)
{
LogPrintToLog(LOG_FORMAT_TYPE_ERROR, "Hitgroups", "Config Validation", "No usable data found in hitgroups config file: %s", pathhitgroups);
}
// Now copy data to array structure.
HitgroupsCacheData();
// Set config data.
ConfigSetConfigLoaded(ConfigHitgroups, true);
ConfigSetConfigHandle(ConfigHitgroups, kvHitgroups);
ConfigSetConfigLoaded(File_Hitgroups, true);
ConfigSetConfigReloadFunc(File_Hitgroups, GetFunctionByName(GetMyHandle(), "HitgroupsOnConfigReload"));
ConfigSetConfigHandle(File_Hitgroups, arrayHitgroups);
}
/**
* Caches hitgroup data from file into arrays.
* Make sure the file is loaded before (ConfigLoadConfig) to prep array structure.
*/
HitgroupsCacheData()
{
// Get config's file path.
decl String:pathhitgroups[PLATFORM_MAX_PATH];
ConfigGetConfigPath(File_Hitgroups, pathhitgroups, sizeof(pathhitgroups));
new Handle:kvHitgroups;
new bool:success = ConfigOpenConfigFile(File_Hitgroups, kvHitgroups);
if (!success)
{
LogPrintToLog(LOG_FORMAT_TYPE_ERROR, "Hitgroups", "Config Validation", "Unexpected error caching data from hitgroups config file: %s", pathhitgroups);
}
decl String:hitgroupname[HITGROUPS_MAX_LENGTH];
// x = array index
new size = GetArraySize(arrayHitgroups);
for (new x = 0; x < size; x++)
{
HitgroupsGetName(x, hitgroupname, sizeof(hitgroupname));
KvRewind(kvHitgroups);
if (!KvJumpToKey(kvHitgroups, hitgroupname))
{
LogPrintToLog(LOG_FORMAT_TYPE_ERROR, "Hitgroups", "Config Validation", "Couldn't cache hitgroup data for: %s (check hitgroup config)", hitgroupname);
continue;
}
// General
new index = KvGetNum(kvHitgroups, "index", -1);
// Damage
new bool:damage = ConfigKvGetStringBool(kvHitgroups, "damage", "yes");
// Knockback (module)
new Float:knockback = KvGetFloat(kvHitgroups, "knockback", 1.0);
new Handle:arrayHitgroup = GetArrayCell(arrayHitgroups, x);
// Push data into array.
PushArrayCell(arrayHitgroup, index); // Index: 1
PushArrayCell(arrayHitgroup, damage); // Index: 2
PushArrayCell(arrayHitgroup, knockback); // Index: 3
}
// We're done with this file now, so we can close it.
CloseHandle(kvHitgroups);
}
/**
@ -95,85 +167,91 @@ HitgroupsLoad()
public HitgroupsOnConfigReload(ConfigFile:config)
{
// Reload hitgroups config.
if (config == ConfigHitgroups)
{
HitgroupsLoad();
}
HitgroupsLoad();
}
/**
* Validate hitgroup config file and settings.
*/
HitgroupsValidateConfig()
{
KvRewind(kvHitgroups);
if (!KvGotoFirstSubKey(kvHitgroups))
{
// Log that no data was loaded from hitgroup file.
LogPrintToLog(LOG_FORMAT_TYPE_NORMAL, "Hitgroups", "Config Validation", "No hitgroups listed in hitgroups.txt, disabling hitgroup-based modules.");
}
}
/**
* Retrieve hitgroup knockback value.
* Find the array index at which the hitgroup index is at.
*
* @param hitgroup The hitgroup index.
* @return The knockback multiplier of the hitgroup.
* @param hitgroup The hitgroup index to search for.
* @return The array index that contains the given hitgroup index.
*/
Float:HitgroupsGetHitgroupKnockback(hitgroup)
stock HitgroupToIndex(hitgroup)
{
// Reset keyvalue's traversal stack.
KvRewind(kvHitgroups);
if (KvGotoFirstSubKey(kvHitgroups))
// x = Array index.
new size = GetArraySize(arrayHitgroups);
for (new x = 0; x < size; x++)
{
decl String:sHitgroup[4];
// Get hitgroup index at this array index.
new index = HitgroupsGetIndex(x);
do
// If hitgroup indexes match, then return array index.
if (hitgroup == index)
{
KvGetSectionName(kvHitgroups, sHitgroup, sizeof(sHitgroup));
// If this is the right hitgroup, then return knockback for it.
if (hitgroup == StringToInt(sHitgroup))
{
return KvGetFloat(kvHitgroups, "knockback", 1.0);
}
} while (KvGotoNextKey(kvHitgroups));
return x;
}
}
return 1.0;
// Hitgroup index doesn't exist.
return -1;
}
/**
* Gets the name of a hitgroup at a given index.
* @param index The hitgroup index.
* @param hitgroup The string to return name in.
* @param maxlen The max length of the string.
*/
stock HitgroupsGetName(index, String:hitgroup[], maxlen)
{
// Get array handle of hitgroup at given index.
new Handle:arrayHitgroup = GetArrayCell(arrayHitgroups, index);
// Get hitgroup name.
GetArrayString(arrayHitgroup, _:HITGROUPS_DATA_NAME, hitgroup, maxlen);
}
/**
* Retrieve hitgroup index.
*
* @param index The array index.
* @return The hitgroup index.
*/
stock HitgroupsGetIndex(index)
{
// Get array handle of hitgroup at given index.
new Handle:arrayHitgroup = GetArrayCell(arrayHitgroups, index);
// Return hitgroup index of the hitgroup.
return GetArrayCell(arrayHitgroup, _:HITGROUPS_DATA_INDEX);
}
/**
* Retrieve hitgroup damage value.
*
* @param hitgroup The hitgroup index.
* @param index The array index.
* @return True if hitgroup can be damaged, false if not.
*/
bool:HitgroupsCanDamageHitgroup(hitgroup)
stock bool:HitgroupsCanDamage(index)
{
// Reset keyvalue's traversal stack.
KvRewind(kvHitgroups);
if (KvGotoFirstSubKey(kvHitgroups))
{
decl String:sHitgroup[4];
decl String:damage[8];
do
{
KvGetSectionName(kvHitgroups, sHitgroup, sizeof(sHitgroup));
// If this is the right hitgroup, then return knockback for it.
if (hitgroup == StringToInt(sHitgroup))
{
// Get config setting string.
KvGetString(kvHitgroups, "damage", damage, sizeof(damage), "yes");
// Return hitgroup's damage setting.
return ConfigSettingToBool(damage);
}
} while (KvGotoNextKey(kvHitgroups));
}
// Get array handle of hitgroup at given index.
new Handle:arrayHitgroup = GetArrayCell(arrayHitgroups, index);
// If hitgroup is missing, then default to "yes."
return true;
// Return true if hitgroup can be damaged, false if not.
return bool:GetArrayCell(arrayHitgroup, _:HITGROUPS_DATA_DAMAGE);
}
/**
* Retrieve hitgroup knockback value.
*
* @param index The array index.
* @return The knockback multiplier of the hitgroup.
*/
stock Float:HitgroupsGetKnockback(index)
{
// Get array handle of hitgroup at given index.
new Handle:arrayHitgroup = GetArrayCell(arrayHitgroups, index);
// Return the knockback multiplier for the hitgroup.
return Float:GetArrayCell(arrayHitgroup, _:HITGROUPS_DATA_KNOCKBACK);
}

View File

@ -390,7 +390,7 @@ public Action:InfectMotherZombie(Handle:timer)
new client;
// Prune list of immune clients.
// x = array index.
// x = Array index.
// client = client index.
for (new x = 0; x < eligibleclients; x++)
{
@ -522,7 +522,7 @@ InfectClient(client, attacker = -1, bool:motherinfect = false)
bZombie[client] = true;
// Get a list of all client's weapon indexes.
new weapons[WeaponsType];
new weapons[WeaponsSlot];
WeaponsGetClientWeapons(client, weapons);
// Check if weapons drop is enabled.
@ -541,7 +541,7 @@ InfectClient(client, attacker = -1, bool:motherinfect = false)
if (weaponsdrop)
{
// If this is the knife slot, then stop.
if (WeaponsType:x == Type_Melee)
if (WeaponsSlot:x == Slot_Melee)
{
continue;
}
@ -557,7 +557,7 @@ InfectClient(client, attacker = -1, bool:motherinfect = false)
}
// If client has no knife, give them one.
if (GetPlayerWeaponSlot(client, _:Type_Melee) == -1)
if (GetPlayerWeaponSlot(client, _:Slot_Melee) == -1)
{
GivePlayerItem(client, "weapon_knife");
}

View File

@ -70,14 +70,22 @@ KnockbackOnClientHurt(client, attacker, const String:weapon[], hitgroup, dmg_hea
TR_GetEndPosition(clientloc);
}
// Retrieve weapon knockback boost.
new Float:boostWeapon = WeaponGetWeaponKnockback(weapon);
new weaponindex = WeaponsNameToIndex(weapon);
if (weaponindex != -1)
{
// Apply weapon knockback multiplier.
knockback *= WeaponsGetKnockback(weaponindex);
}
// Retrieve hitgroup knockback boost.
new Float:boostHitgroup = HitgroupsGetHitgroupKnockback(hitgroup);
new hitgroupindex = HitgroupToIndex(hitgroup);
if (hitgroupindex != -1)
{
// Apply hitgroup knockback multiplier.
knockback *= HitgroupsGetKnockback(hitgroupindex);
}
// Apply all knockback multipliers.
knockback *= float(dmg_health) * boostWeapon * boostHitgroup;
// Apply damage knockback multiplier.
knockback *= float(dmg_health);
// Apply knockback.
KnockbackSetVelocity(client, attackerloc, clientloc, knockback);

View File

@ -52,7 +52,7 @@ MenuMain(client)
AddMenuItem(menu_main, "zspawn", zspawn);
AddMenuItem(menu_main, "ztele", ztele);
AddMenuItem(menu_main, "zhp", zhp);
AddMenuItem(menu_main, "zmarket", zmarket, MenuGetItemDraw(g_bMarket));
AddMenuItem(menu_main, "zmarket", zmarket);
// Display menu to client.
DisplayMenu(menu_main, client, MENU_TIME_FOREVER);
@ -113,8 +113,6 @@ public MenuMainHandle(Handle:menu, MenuAction:action, client, slot)
// Select zmarket.
case 5:
{
// Copy return to resend variable.
resend = !ZMarketMenu(client);
}
}

View File

@ -22,22 +22,21 @@
/**
* Array that stores a list of validated models.
*
* @redir config.inc
*/
new Handle:arrayModels = INVALID_HANDLE;
/**
* Prepare all model/download data.
*/
ModelsLoad()
{
// Register config file.
ConfigRegisterConfig(File_Models, Structure_List, CONFIG_FILE_ALIAS_MODELS);
// Get models file path.
decl String:pathmodels[PLATFORM_MAX_PATH];
new bool:exists = ConfigGetCvarFilePath(CVAR_CONFIG_PATH_MODELS, pathmodels);
// Register config info.
ConfigRegisterConfig(ConfigModels, false, GetFunctionByName(GetMyHandle(), "ModelsOnConfigReload"), _, pathmodels, CONFIG_FILE_ALIAS_MODELS);
// If file doesn't exist, then log and stop.
if (!exists)
{
@ -45,18 +44,16 @@ ModelsLoad()
LogPrintToLog(LOG_FORMAT_TYPE_FATALERROR, "Models", "Config Validation", "Fatal Error: Missing models file: \"%s\"", pathmodels);
}
// If model array exists, then destroy it.
if (arrayModelsList != INVALID_HANDLE)
{
CloseHandle(arrayModelsList);
}
// Set the path to the config file.
ConfigSetConfigPath(File_Models, pathmodels);
arrayModelsList = ConfigLinesToArray(pathmodels);
// Load config from file and create array structure.
new bool:success = ConfigLoadConfig(File_Models, arrayModels);
// If array couldn't be created, then fail.
if (arrayModelsList == INVALID_HANDLE)
// Unexpected error, stop plugin.
if (!success)
{
LogPrintToLog(LOG_FORMAT_TYPE_FATALERROR, "Models", "Config Validation", "Fatal Error: Error parsing \"%s\"", pathmodels);
LogPrintToLog(LOG_FORMAT_TYPE_FATALERROR, "Models", "Config Validation", "Fatal Error: Unexpected error encountered loading: %s", pathmodels);
}
new modelcount;
@ -74,13 +71,13 @@ ModelsLoad()
new FileType:type;
new models = modelcount = GetArraySize(arrayModelsList);
new models = modelcount = GetArraySize(arrayModels);
// x = model array index.
for (new x = 0; x < models; x++)
{
// Get base model path (rawline in models.txt)
GetArrayString(arrayModelsList, x, modelbase, sizeof(modelbase));
GetArrayString(arrayModels, x, modelbase, sizeof(modelbase));
// Explode path into pieces. (separated by "/")
new strings = ExplodeString(modelbase, "/", baseexploded, MODELS_PATH_MAX_DEPTH, MODELS_PATH_DIR_MAX_LENGTH);
@ -137,7 +134,7 @@ ModelsLoad()
else
{
// Remove client from array.
RemoveFromArray(arrayModelsList, x);
RemoveFromArray(arrayModels, x);
// Subtract one from count.
models--;
@ -160,20 +157,16 @@ ModelsLoad()
}
// Set config data.
ConfigSetConfigLoaded(ConfigModels, true);
ConfigSetConfigHandle(ConfigModels, arrayModelsList);
ConfigSetConfigLoaded(File_Models, true);
ConfigSetConfigReloadFunc(File_Models, GetFunctionByName(GetMyHandle(), "ModelsOnConfigReload"));
ConfigSetConfigHandle(File_Models, arrayModels);
}
/**
* Called when configs are being reloaded.
*
* @param config The config being reloaded. (only if 'all' is false)
* Called when config is being reloaded.
*/
public ModelsOnConfigReload(ConfigFile:config)
{
// Reload model config.
if (config == ConfigModels)
{
ModelsLoad();
}
// Reload models config.
ModelsLoad();
}

View File

@ -71,8 +71,8 @@ bool:ClassApplyModel(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER)
if (strcmp(modelpath, "random", false) == 0)
{
// TODO: Make a function that gets a random model from the specified team.
new randmodel = GetRandomInt(0, GetArraySize(arrayModelsList) - 1);
GetArrayString(arrayModelsList, randmodel, modelpath, sizeof(modelpath));
new randmodel = GetRandomInt(0, GetArraySize(arrayModels) - 1);
GetArrayString(arrayModels, randmodel, modelpath, sizeof(modelpath));
Format(modelpath, sizeof(modelpath), "%s.mdl", modelpath);
}

View File

@ -209,14 +209,6 @@ ClassMenuSelect(client, teamid)
AddMenuItem(menu, classname, menuitem);
}
}
else
{
// No classes found. Display message. The main class menu should
// prevent this from happening, but we print a message just in case.
// THIS TRANSLATION PHRASES IS NOT IN FILE.
Format(menuitem, sizeof(menuitem), "%t\n", "Classes menu not found");
AddMenuItem(menu, classname, menuitem, ITEMDRAW_RAWLINE);
}
SetMenuExitBackButton(menu, true);
DisplayMenu(menu, client, MENU_TIME_FOREVER);

View File

@ -54,7 +54,7 @@ ClassOverlayOnCommandsHook()
// Explode string into array indexes.
new cmdcount = ExplodeString(togglecmds, ", ", arrayCmds, CLASSOVERLAY_TOGGLE_MAX_CMDS, CLASSOVERLAY_TOGGLE_MAX_LENGTH);
// x = array index.
// x = Array index.
// arrayCmds[x] = suicide command.
for (new x = 0; x <= cmdcount - 1; x++)
{

View File

@ -252,9 +252,8 @@ enum ClassDataTypes
/**
* Keyvalue handle to store class data.
*
* @redir config.inc
*/
new Handle:kvClassData = INVALID_HANDLE;
/**
* The original class data. This array only changed when class data is loaded.
@ -322,20 +321,20 @@ new ClassPlayerNextAdminClass[MAXPLAYERS + 1];
*/
ClassLoad()
{
// Register config file.
ConfigRegisterConfig(File_Classes, Structure_Keyvalue, CONFIG_FILE_ALIAS_CLASSES);
// Make sure kvClassData is ready to use.
if (kvClassData != INVALID_HANDLE)
{
CloseHandle(kvClassData);
}
kvClassData = CreateKeyValues("classes");
kvClassData = CreateKeyValues(CONFIG_FILE_ALIAS_CLASSES);
// Get weapons config path.
decl String:pathclasses[PLATFORM_MAX_PATH];
new bool:exists = ConfigGetCvarFilePath(CVAR_CONFIG_PATH_CLASSES, pathclasses);
// Register config info.
ConfigRegisterConfig(ConfigClasses, false, GetFunctionByName(GetMyHandle(), "ClassOnConfigReload"), _, pathclasses, CONFIG_FILE_ALIAS_CLASSES);
// If file doesn't exist, then log and stop.
if (!exists)
{
@ -463,8 +462,10 @@ ClassLoad()
LogPrintToLog(LOG_FORMAT_TYPE_NORMAL, "Classes", "Config Validation", "Total: %d | Successful: %d | Unsuccessful: %d", ClassCount, ClassCount - failedcount, failedcount);
// Set config data.
ConfigSetConfigLoaded(ConfigClasses, true);
ConfigSetConfigHandle(ConfigClasses, kvClassData);
ConfigSetConfigLoaded(File_Classes, true);
ConfigSetConfigReloadFunc(File_Classes, GetFunctionByName(GetMyHandle(), "ClassOnConfigReload"));
// ConfigSetConfigHandle(File_Classes, INVALID_HANDLE);
ConfigSetConfigPath(File_Classes, pathclasses);
}
/**
@ -475,9 +476,6 @@ ClassLoad()
public ClassOnConfigReload(ConfigFile:config)
{
// Reload class config.
if (config == ConfigClasses)
{
}
}
/**

View File

@ -306,7 +306,7 @@ RoundEndBalanceTeams()
// Move all clients to T
// x = array index.
// x = Array index.
// client = client index.
for (new x = 0; x < eligibleclients; x++)
{

View File

@ -121,8 +121,6 @@ public Action:SayHooksCmdSay(client, argc)
// Client triggered ZMarket flag.
case SAYHOOKS_KEYWORD_FLAG_ZMARKET:
{
// Send market menu.
success = ZMarketMenu(client);
}
}

View File

@ -18,11 +18,8 @@ new g_iToolsBaseVelocity;
new g_iToolsLMV;
new g_iToolsHasNightVision;
new g_iToolsNightVisionOn;
new g_iToolsCollisionGroup;
new g_iToolsAccount;
new g_iToolsDefaultFOV;
new g_iToolsInBuyZone;
new g_iToolsActiveWeapon;
/**
* @endsection
*/
@ -93,20 +90,6 @@ ToolsFindOffsets()
LogPrintToLog(LOG_FORMAT_TYPE_FATALERROR, "Tools", "Offsets", "Offset \"CCSPlayer::m_bNightVisionOn\" was not found.");
}
// If offset "m_CollisionGroup" can't be found, then stop the plugin.
g_iToolsCollisionGroup = FindSendPropInfo("CBaseEntity", "m_CollisionGroup");
if (g_iToolsCollisionGroup == -1)
{
LogPrintToLog(LOG_FORMAT_TYPE_FATALERROR, "Tools", "Offsets", "Offset \"CBaseEntity::m_CollisionGroup\" was not found.");
}
// If offset "m_iAccount" can't be found, then stop the plugin.
g_iToolsAccount = FindSendPropInfo("CCSPlayer", "m_iAccount");
if (g_iToolsAccount == -1)
{
LogPrintToLog(LOG_FORMAT_TYPE_FATALERROR, "Tools", "Offsets", "Offset \"CCSPlayer::m_iAccount\" was not found.");
}
// If offset "m_iDefaultFOV" can't be found, then stop the plugin.
g_iToolsDefaultFOV = FindSendPropInfo("CBasePlayer", "m_iDefaultFOV");
if (g_iToolsDefaultFOV == -1)
@ -114,19 +97,11 @@ ToolsFindOffsets()
LogPrintToLog(LOG_FORMAT_TYPE_FATALERROR, "Tools", "Offsets", "Offset \"CBasePlayer::m_iDefaultFOV\" was not found.");
}
// If offset "m_bInBuyZone" can't be found, then stop the plugin.
g_iToolsInBuyZone = FindSendPropInfo("CCSPlayer", "m_bInBuyZone");
if (g_iToolsInBuyZone == -1)
{
LogPrintToLog(LOG_FORMAT_TYPE_FATALERROR, "Tools", "Offsets", "Offset \"CCSPlayer::m_bInBuyZone\" was not found.");
}
// If offset "m_hActiveWeapon" can't be found, then stop the plugin.
g_iToolsActiveWeapon = FindSendPropInfo("CBasePlayer", "m_hActiveWeapon");
if (g_iToolsActiveWeapon == -1)
{
LogPrintToLog(LOG_FORMAT_TYPE_FATALERROR, "Tools", "Offsets", "Offset \"CBasePlayer::m_hActiveWeapon\" was not found.");
}
// Forward event to modules.
WeaponsOnOffsetsFound();
AccountOnOffsetsFound();
AntiStickOnOffsetsFound();
ZMarketOnOffsetsFound();
}
/**

View File

@ -153,8 +153,8 @@ stock TranslationPrintToChatAll(bool:server, bool:admin, any:...)
continue;
}
// Set translation target
SetGlobalTransTarget(LANG_SERVER);
// Set translation target to client.
SetGlobalTransTarget(x);
// Translate phrase.
VFormat(translation, sizeof(translation), "%t", 3);
@ -327,9 +327,20 @@ stock TranslationReplyToCommand(client, any:...)
decl String:translation[TRANSLATION_MAX_LENGTH_CHAT];
VFormat(translation, sizeof(translation), "%t", 2);
// Format string to create plugin style.
TranslationPluginFormatString(translation, sizeof(translation));
// Print translated phrase to client.
ReplyToCommand(client, translation);
if (ZRIsClientValid(client))
{
// Format string to create plugin style. (color)
TranslationPluginFormatString(translation, sizeof(translation));
// Print translated phrase to client's chat/console.
PrintToChat(client, translation);
}
else
{
// Format string to create plugin style. (no color)
TranslationPluginFormatString(translation, sizeof(translation), false);
// Print to server.
PrintToServer(translation);
}
}

View File

@ -1,165 +0,0 @@
/*
* ============================================================================
*
* Zombie:Reloaded
*
* File: markethandler.inc
* Type: Core
* Description: Handles market (optional plugin) API, natives, and forwards.
*
* ============================================================================
*/
/**
* Global variable set to true if market plugin is installed
*/
new bool:g_bMarket;
/**
* Set global market flag variable
*/
MarketInit()
{
// Set market variable to true if market is installed.
g_bMarket = LibraryExists("market");
}
/**
* Sends market menu to client.
*
* @param client The client index.
*/
bool:ZMarketMenu(client)
{
// If market is disabled, then stop.
if (!g_bMarket)
{
// Tell client market is disabled.
TranslationPrintToChat(client, "Feature is disabled");
return false;
}
// If player is dead, then stop.
if (!IsPlayerAlive(client))
{
// Tell player they must be alive.
TranslationPrintToChat(client, "Must be alive");
return false;
}
// Check buyzone cvar to see if client has to be in a buyzone to use.
new bool:buyzone = GetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE]);
if (!ZMarketIsClientInBuyZone(client) && buyzone)
{
// Tell client they must be in a buyzone.
TranslationPrintCenterText(client, "Market out of buyzone");
return false;
}
// Set translate target to client.
SetGlobalTransTarget(client);
// Format title and rebuy lines.
decl String:title[64];
decl String:rebuy[64];
Format(title, sizeof(title), "%t\n ", "Market title");
Format(rebuy, sizeof(rebuy), "%t\n ", "Market rebuy");
// Send market menu.
Market_Send(client, title, rebuy);
// Successfully sent the market menu.
return true;
}
/**
* Checks if a client is in a buyzone.
*
* @param client The client index.
*/
bool:ZMarketIsClientInBuyZone(client)
{
// Return if client is in buyzone.
return bool:GetEntData(client, g_iToolsInBuyZone);
}
/**
* (Market) Forward called when a client selects a weapon from the market.
*
* @param client The client index.
* @param weaponid The unique weapon ID used for market natives.
* @return True to allow market to take over, false to block purchase.
*/
public bool:Market_OnWeaponSelected(client, String:weaponid[])
{
// If player is dead or weaponid is invalid, then stop.
if (!weaponid[0] || !IsPlayerAlive(client))
{
return false;
}
// If player is a zombie, then stop.
if (InfectIsClientInfected(client))
{
TranslationPrintToChat(client, "Zombie cant use weapon");
return false;
}
// If player is using the rebuy option then allow.
if (StrEqual(weaponid, "rebuy"))
{
return true;
}
decl String:display[64];
decl String:weapon[WEAPONS_MAX_LENGTH];
new price;
// If the market plugin can't find info about the weapon, then stop.
if (!Market_GetWeaponIDInfo(weaponid, display, weapon, price))
{
return false;
}
// Strip "weapon_" from entity name.
ReplaceString(weapon, sizeof(weapon), "weapon_", "");
// If the weapon is restricted, then stop.
if (RestrictIsWeaponRestricted(weapon))
{
TranslationPrintToChat(client, "Weapon is restricted", weapon);
return false;
}
// Check if buyzone cvar is enabled, and if the client is in a buyzone.
new bool:buyzone = GetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE]);
if (!ZMarketIsClientInBuyZone(client) && buyzone)
{
TranslationPrintCenterText(client, "Market out of buyzone");
return false;
}
return true;
}
/**
* (Market) Forward called one frame after a client selects a weapon from the market.
*
* @param client The client index.
* @param allowed True when the weapon was purchased successfully, false otherwise.
*/
public Market_PostOnWeaponSelected(client, &bool:allowed)
{
// If the purchase wasn't allowed, then stop.
if (!allowed)
{
return;
}
// Resend market menu.
ZMarketMenu(client);
}

View File

@ -11,28 +11,14 @@
*/
/**
* Weapons Menus
* Array to store the client's current weapon type within menu.
*/
enum WeaponsMenu
{
Weapon,
WeaponGroup,
}
/**
* Array to store the client's current weapon menu.
*/
new WeaponsMenu:curMenuWeapons[MAXPLAYERS + 1];
/**
* Array to store the client's current weapon group menu.
*/
new String:curMenuGroup[WEAPONS_MAX_LENGTH][MAXPLAYERS + 1];
new g_iCurWeaponType[MAXPLAYERS + 1];
/**
* Sends main weapon menu to client.
* @param client The client index.
*/
*/
WeaponsMenuMain(client)
{
// Create menu handle.
@ -42,17 +28,15 @@ WeaponsMenuMain(client)
SetMenuTitle(menu_weapons_main, "%t\n ", "Weapons menu main title");
decl String:toggleweaponrestriction[64];
decl String:togglewgrouprestriction[64];
decl String:restrict[64];
decl String:zmarket[64];
Format(toggleweaponrestriction, sizeof(toggleweaponrestriction), "%t", "Weapons menu main toggle weapon restrict");
Format(togglewgrouprestriction, sizeof(togglewgrouprestriction), "%t", "Weapons menu main toggle weapon group restrict");
Format(restrict, sizeof(restrict), "%t", "Weapons menu main restrict");
Format(zmarket, sizeof(zmarket), "%t", "Weapons menu main market");
AddMenuItem(menu_weapons_main, "toggleweaponrestriction", toggleweaponrestriction);
AddMenuItem(menu_weapons_main, "togglewgrouprestriction", togglewgrouprestriction);
AddMenuItem(menu_weapons_main, "zmarket", zmarket, MenuGetItemDraw(g_bMarket));
// Draw items, make unselectable if module is disabled.
AddMenuItem(menu_weapons_main, "restrict", restrict, MenuGetItemDraw(GetConVarBool(g_hCvarsList[CVAR_WEAPONS_RESTRICT])));
AddMenuItem(menu_weapons_main, "zmarket", zmarket, MenuGetItemDraw(GetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET])));
// Create a "Back" button to the weapons main menu.
SetMenuExitBackButton(menu_weapons_main, true);
@ -75,17 +59,15 @@ public WeaponsMenuMainHandle(Handle:menu_weapons_main, MenuAction:action, client
{
switch(slot)
{
// Weapons.
case 0:
{
WeaponsMenuWeapons(client, Weapon);
WeaponsMenuTypes(client);
}
// ZMarket.
case 1:
{
WeaponsMenuWeapons(client, WeaponGroup);
}
case 2:
{
WeaponsMenuMarket(client);
WeaponsMenuZMarket(client);
}
}
}
@ -95,7 +77,7 @@ public WeaponsMenuMainHandle(Handle:menu_weapons_main, MenuAction:action, client
// Client hit "Back" button.
if (slot == MenuCancel_ExitBack)
{
ZRAdminMenu(client);
// Re-open admin menu.
}
}
// Client hit "Exit" button.
@ -106,159 +88,63 @@ public WeaponsMenuMainHandle(Handle:menu_weapons_main, MenuAction:action, client
}
/**
* Sends weapon list menu to client.
* Sends weapon type list to client.
* @param client The client index.
*/
WeaponsMenuWeapons(client, WeaponsMenu:type)
*/
WeaponsMenuTypes(client)
{
// Set the current action client is performing on a weapon. (see enum WeaponsMenu)
curMenuWeapons[client] = type;
// Create menu handle.
new Handle:menu_weapons_weapons = CreateMenu(WeaponsMenuWeaponsHandle);
new Handle:menu_weapons_types = CreateMenu(WeaponsMenuTypesHandle);
SetGlobalTransTarget(client);
// If client wants to perform an action on a single weapon, show weapon list.
switch(curMenuWeapons[client])
SetMenuTitle(menu_weapons_types, "%t\n ", "Weapons menu types title");
decl String:typename[WEAPONS_MAX_LENGTH];
// x = Array index.
new size = GetArraySize(arrayWeaponTypes);
for (new x = 0; x < size; x++)
{
case Weapon:
{
SetMenuTitle(menu_weapons_weapons, "%t\n ", "Weapons menu weapons weapon title");
decl String:weapon[WEAPONS_MAX_LENGTH];
decl String:display[WEAPONS_MAX_LENGTH + 1];
new Handle:arrayWeapons = INVALID_HANDLE;
new size = WeaponsCreateWeaponArray(arrayWeapons);
// x = Array index.
for (new x = 0; x < size; x++)
{
GetArrayString(arrayWeapons, x, weapon, sizeof(weapon));
strcopy(display, sizeof(display), weapon);
if (RestrictIsWeaponRestricted(weapon))
{
Format(display, sizeof(display), "%s*", weapon);
}
// If weapon restriction is blocked for the menu, disable option.
new bool:menu = WeaponsIsWeaponMenu(weapon);
if (menu)
{
AddMenuItem(menu_weapons_weapons, weapon, display);
}
else
{
AddMenuItem(menu_weapons_weapons, weapon, display, ITEMDRAW_DISABLED);
}
}
// If there are no weapons, add an "(Empty)" line.
if (size == 0)
{
decl String:empty[64];
Format(empty, sizeof(empty), "%t", "Menu empty");
AddMenuItem(menu_weapons_weapons, "empty", empty, ITEMDRAW_DISABLED);
}
// Kill the array handle.
CloseHandle(arrayWeapons);
}
// If client wants to perform an action on a weapon group, show custom group list.
case WeaponGroup:
{
SetMenuTitle(menu_weapons_weapons, "%t\n ", "Weapons menu weapons group title");
decl String:weapongroup[WEAPONS_MAX_LENGTH];
decl String:display[WEAPONS_MAX_LENGTH + 2];
new Handle:arrayWeaponGroups = INVALID_HANDLE;
new size = RestrictCreateGroupArray(arrayWeaponGroups);
// x = Array index.
for (new x = 0; x < size; x++)
{
GetArrayString(arrayWeaponGroups, x, weapongroup, sizeof(weapongroup));
strcopy(display, sizeof(display), weapongroup);
if (RestrictIsPartialRestricted(weapongroup))
{
Format(display, sizeof(display), "%s*", weapongroup);
}
else if (RestrictIsGroupRestricted(weapongroup))
{
Format(display, sizeof(display), "%s**", weapongroup);
}
AddMenuItem(menu_weapons_weapons, weapongroup, display);
}
// If there are no weapons, add an "(Empty)" line.
if (size == 0)
{
decl String:empty[64];
Format(empty, sizeof(empty), "%t", "Menu empty");
AddMenuItem(menu_weapons_weapons, "empty", empty, ITEMDRAW_DISABLED);
}
// Kill the array handle
CloseHandle(arrayWeaponGroups);
}
// Get name of type.
RestrictWeaponTypeGetName(x, typename, sizeof(typename));
// Add item to menu.
AddMenuItem(menu_weapons_types, typename, typename);
}
SetMenuExitBackButton(menu_weapons_weapons, true);
// If there are no weapons, add an "(Empty)" line.
if (size == 0)
{
decl String:empty[64];
Format(empty, sizeof(empty), "%t", "Menu empty");
DisplayMenu(menu_weapons_weapons, client, MENU_TIME_FOREVER);
AddMenuItem(menu_weapons_types, "empty", empty, ITEMDRAW_DISABLED);
}
// Set exit back button.
SetMenuExitBackButton(menu_weapons_types, true);
DisplayMenu(menu_weapons_types, client, MENU_TIME_FOREVER);
}
/**
* Called when client selects option in the weapons list menu, and handles it.
* @param menu_weapons_main Handle of the menu being used.
* @param menu_weapons_types Handle of the menu being used.
* @param action The action done on the menu (see menus.inc, enum MenuAction).
* @param client The client index.
* @param slot The slot index selected (starting from 0).
*/
public WeaponsMenuWeaponsHandle(Handle:menu_weapons_weapons, MenuAction:action, client, slot)
public WeaponsMenuTypesHandle(Handle:menu_weapons_types, MenuAction:action, client, slot)
{
// Client selected an option.
if (action == MenuAction_Select)
{
decl String:weapon[WEAPONS_MAX_LENGTH];
GetMenuItem(menu_weapons_weapons, slot, weapon, sizeof(weapon));
// Menu slot index is = weapon type index.
g_iCurWeaponType[client] = slot;
switch(curMenuWeapons[client])
{
// Client is restricting a single weapon.
case Weapon:
{
new WpnRestrictQuery:output;
if (!RestrictIsWeaponRestricted(weapon))
{
output = RestrictRestrict(weapon);
RestrictPrintRestrictOutput(client, output, weapon, false);
}
else
{
output = RestrictUnrestrict(weapon);
RestrictPrintUnrestrictOutput(client, output, weapon, false);
}
// Resend menu.
WeaponsMenuWeapons(client, curMenuWeapons[client]);
}
// Client is accessing a weapon group.
case WeaponGroup:
{
// Send weapon group menu.
WeaponsMenuWeaponGroup(client, weapon);
}
}
// Send weapons of the selected type in a menu to client.
WeaponsMenuTypeWeapons(client);
}
// Client closed the menu.
if (action == MenuAction_Cancel)
@ -272,118 +158,141 @@ public WeaponsMenuWeaponsHandle(Handle:menu_weapons_weapons, MenuAction:action,
// Client hit "Exit" button.
else if (action == MenuAction_End)
{
CloseHandle(menu_weapons_weapons);
CloseHandle(menu_weapons_types);
}
}
WeaponsMenuWeaponGroup(client, const String:weapongroup[])
/**
* Sends a list of weapons of a certain type in a menu to the client.
* @param client The client index.
*/
WeaponsMenuTypeWeapons(client)
{
strcopy(curMenuGroup[client], WEAPONS_MAX_LENGTH, weapongroup);
// Create menu handle.
new Handle:menu_weapons_groupweapon = CreateMenu(WeaponsMenuWeaponGroupHandle);
new Handle:menu_weapons_typeweapons = CreateMenu(WeaponsMenuTypeWeaponsHandle);
SetMenuTitle(menu_weapons_groupweapon, "%t\n ", "Weapons menu weapon group title", weapongroup);
decl String:typename[WEAPONS_MAX_LENGTH];
RestrictWeaponTypeGetName(g_iCurWeaponType[client], typename, sizeof(typename));
SetMenuTitle(menu_weapons_typeweapons, "%t\n ", "Weapons menu types type title", typename);
decl String:restrictall[64];
decl String:unrestrictall[64];
Format(restrictall, sizeof(restrictall), "%t", "Weapons menu weapon group restrict all");
Format(unrestrictall, sizeof(unrestrictall), "%t", "Weapons menu weapon group unrestrict all");
Format(restrictall, sizeof(restrictall), "%t", "Weapons menu types restrict all", typename);
Format(unrestrictall, sizeof(unrestrictall), "%t", "Weapons menu types unrestrict all", typename);
if (RestrictIsGroupRestricted(weapongroup))
{
AddMenuItem(menu_weapons_groupweapon, "restrictall", restrictall, ITEMDRAW_DISABLED);
}
else
{
AddMenuItem(menu_weapons_groupweapon, "restrictall", restrictall);
}
// Draw items as selectable only if not all weapons within the type are restricted or unrestricted.
AddMenuItem(menu_weapons_typeweapons, "restrictall", restrictall, MenuGetItemDraw(!RestrictIsTypeUniform(true, g_iCurWeaponType[client])));
AddMenuItem(menu_weapons_typeweapons, "unrestrictall", unrestrictall, MenuGetItemDraw(!RestrictIsTypeUniform(false, g_iCurWeaponType[client])));
if (RestrictIsGroupUnrestricted(weapongroup))
{
AddMenuItem(menu_weapons_groupweapon, "unrestrictall", unrestrictall, ITEMDRAW_DISABLED);
}
else
{
AddMenuItem(menu_weapons_groupweapon, "unrestrictall", unrestrictall);
}
decl String:typeweapon[WEAPONS_MAX_LENGTH];
decl String:display[WEAPONS_MAX_LENGTH];
decl String:groupweapon[WEAPONS_MAX_LENGTH];
decl String:display[WEAPONS_MAX_LENGTH + 1];
new Handle:arrayGroupWeapons = INVALID_HANDLE;
new size = RestrictCreateGroupWeaponsArray(arrayGroupWeapons, weapongroup);
// Get an array populated with all weapons of the given type.
new Handle:arrayTypeWeapons;
new count = RestrictGetTypeWeapons(g_iCurWeaponType[client], arrayTypeWeapons);
// x = Array index.
for (new x = 0; x < size; x++)
for (new x = 0; x < count; x++)
{
GetArrayString(arrayGroupWeapons, x, groupweapon, sizeof(groupweapon));
// Get weapon index to check restricted status of.
new weaponindex = GetArrayCell(arrayTypeWeapons, x);
strcopy(display, sizeof(display), groupweapon);
// Get name of weapon.
WeaponsGetName(weaponindex, typeweapon, sizeof(typeweapon));
strcopy(display, sizeof(display), typeweapon);
if (RestrictIsWeaponRestricted(groupweapon))
if (RestrictIsWeaponRestricted(weaponindex))
{
Format(display, sizeof(display), "%s*", groupweapon);
Format(display, sizeof(display), "[%s]", typeweapon);
}
AddMenuItem(menu_weapons_groupweapon, groupweapon, display);
// Disable option if it isn't toggleable.
AddMenuItem(menu_weapons_typeweapons, typeweapon, display, MenuGetItemDraw(WeaponsGetToggleable(weaponindex)));
}
// Kill the array handle.
CloseHandle(arrayGroupWeapons);
// Destroy the array handle.
CloseHandle(arrayTypeWeapons);
SetMenuExitBackButton(menu_weapons_groupweapon, true);
DisplayMenu(menu_weapons_groupweapon, client, MENU_TIME_FOREVER);
// Set menu back button.
SetMenuExitBackButton(menu_weapons_typeweapons, true);
// Display menu to client.
DisplayMenu(menu_weapons_typeweapons, client, MENU_TIME_FOREVER);
}
/**
* Called when client selects option in the weapon group menu, and handles it.
* @param menu_weapons_main Handle of the menu being used.
* @param action The action done on the menu (see menus.inc, enum MenuAction).
* @param client The client index.
* @param slot The slot index selected (starting from 0).
* @param menu_weapons_typeweapons Handle of the menu being used.
* @param action The action done on the menu (see menus.inc, enum MenuAction).
* @param client The client index.
* @param slot The slot index selected (starting from 0).
*/
public WeaponsMenuWeaponGroupHandle(Handle:menu_weapons_groupweapon, MenuAction:action, client, slot)
public WeaponsMenuTypeWeaponsHandle(Handle:menu_weapons_typeweapons, MenuAction:action, client, slot)
{
// Client selected an option.
if (action == MenuAction_Select)
{
// Get name of current weapon type.
decl String:typename[WEAPONS_MAX_LENGTH];
RestrictWeaponTypeGetName(g_iCurWeaponType[client], typename, sizeof(typename));
new RestrictQuery:query;
new bool:single;
new bool:restrict;
decl String:returntarget[WEAPONS_MAX_LENGTH];
switch(slot)
{
case 0:
{
new WpnRestrictQuery:output = RestrictRestrict(curMenuGroup[client]);
RestrictPrintRestrictOutput(client, output, curMenuGroup[client], false);
// Restrict all weapons of this type.
restrict = true;
query = RestrictWeapon(true, typename, single, returntarget, sizeof(returntarget));
}
case 1:
{
new WpnRestrictQuery:output = RestrictUnrestrict(curMenuGroup[client]);
RestrictPrintUnrestrictOutput(client, output, curMenuGroup[client], false);
// Unrestrict all weapons of this type.
restrict = false;
query = RestrictWeapon(false, typename, single, returntarget, sizeof(returntarget));
}
default:
{
new WpnRestrictQuery:output;
// Get weappon name.
decl String:typeweapon[WEAPONS_MAX_LENGTH];
GetMenuItem(menu_weapons_typeweapons, slot, typeweapon, sizeof(typeweapon));
decl String:groupweapon[WEAPONS_MAX_LENGTH];
GetMenuItem(menu_weapons_groupweapon, slot, groupweapon, sizeof(groupweapon));
// Get weapon index.
new weaponindex = WeaponsNameToIndex(typeweapon);
if (!RestrictIsWeaponRestricted(groupweapon))
// If weapon index is -1, then something went very wrong.
if (weaponindex == -1)
{
output = RestrictRestrict(groupweapon);
RestrictPrintRestrictOutput(client, output, groupweapon, false);
CloseHandle(menu_weapons_typeweapons);
}
// If weapon isn't restricted, then restrict it.
if (!RestrictIsWeaponRestricted(weaponindex))
{
// Restrict this weapon.
restrict = true;
query = RestrictWeapon(true, typeweapon, single, returntarget, sizeof(returntarget));
}
else
{
output = RestrictUnrestrict(groupweapon);
RestrictPrintUnrestrictOutput(client, output, groupweapon, false);
// Unrestrict this weapon.
restrict = false;
query = RestrictWeapon(false, typeweapon, single, returntarget, sizeof(returntarget));
}
}
}
// Print query response.
RestrictPrintQueryResponse(client, query, single, restrict, returntarget);
// Resend menu.
WeaponsMenuWeaponGroup(client, curMenuGroup[client]);
WeaponsMenuTypeWeapons(client);
}
// Client closed the menu.
if (action == MenuAction_Cancel)
@ -391,37 +300,38 @@ public WeaponsMenuWeaponGroupHandle(Handle:menu_weapons_groupweapon, MenuAction:
// Client hit "Back" button.
if (slot == MenuCancel_ExitBack)
{
WeaponsMenuWeapons(client, curMenuWeapons[client]);
WeaponsMenuTypes(client);
}
}
// Client hit "Exit" button.
else if (action == MenuAction_End)
{
CloseHandle(menu_weapons_groupweapon);
CloseHandle(menu_weapons_typeweapons);
}
}
/**
* Sends market options menu to client.
* Sends ZMarket options menu to client.
* @param client The client index.
*/
WeaponsMenuMarket(client)
*/
WeaponsMenuZMarket(client)
{
// Create menu handle.
new Handle:menu_weapons_market = CreateMenu(WeaponsMenuMarketHandle);
new Handle:menu_weapons_market = CreateMenu(WeaponsMenuZMarketHandle);
SetGlobalTransTarget(client);
SetMenuTitle(menu_weapons_market, "%t\n ", "Weapons menu market title");
SetMenuTitle(menu_weapons_market, "%t\n ", "Weapons menu zmarket title");
decl String:togglebuyzone[64];
decl String:buyzone[64];
decl String:buyzonesetting[8];
decl String:curSetting[8];
ConfigBoolToSetting(GetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE]), curSetting, sizeof(curSetting));
// Get "yes" or "no" settings from respective cvar.
ConfigBoolToSetting(GetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE]), buyzonesetting, sizeof(buyzonesetting));
Format(togglebuyzone, sizeof(togglebuyzone), "%t", "Weapons menu market toggle buyzone", curSetting);
AddMenuItem(menu_weapons_market, "togglebuyzone", togglebuyzone);
// Add options to menu.
Format(buyzone, sizeof(buyzone), "%t", "Weapons menu zmarket buyzone", buyzonesetting);
AddMenuItem(menu_weapons_market, "buyzone", buyzone);
// Create a "Back" button to the weapons main menu.
SetMenuExitBackButton(menu_weapons_market, true);
@ -432,33 +342,29 @@ WeaponsMenuMarket(client)
/**
* Called when client selects option in the weapons main menu, and handles it.
* @param menu_weapons_main Handle of the menu being used.
* @param menu_weapons_market Handle of the menu being used.
* @param action The action done on the menu (see menus.inc, enum MenuAction).
* @param client The client index.
* @param slot The slot index selected (starting from 0).
*/
public WeaponsMenuMarketHandle(Handle:menu_weapons_market, MenuAction:action, client, slot)
public WeaponsMenuZMarketHandle(Handle:menu_weapons_market, MenuAction:action, client, slot)
{
// Client selected an option.
if (action == MenuAction_Select)
{
switch(slot)
{
// Buyzone.
case 0:
{
if (GetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE]))
{
SetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE], false);
}
else
{
SetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE], true);
}
// Toggle cvar.
new bool:zmarketbuyzone = GetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE]);
SetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE], !zmarketbuyzone);
}
}
// Resend menu.
WeaponsMenuMarket(client);
WeaponsMenuZMarket(client);
}
// Client closed the menu.
if (action == MenuAction_Cancel)

File diff suppressed because it is too large Load Diff

View File

@ -150,7 +150,7 @@ WeaponAlphaApplyWeaponAlpha(entity, alpha)
}
// Get client's list of weapons.
new weapons[WeaponsType];
new weapons[WeaponsSlot];
WeaponsGetClientWeapons(entity, weapons);
// Loop through array slots and set alpha.

View File

@ -0,0 +1,81 @@
/*
* ============================================================================
*
* Zombie:Reloaded
*
* File: weaponammo.inc
* Type: Core
* Description: API for all weaponammo-related functions.
*
* ============================================================================
*/
/**
* @section Variables to store ammo offset values.
*/
new g_iToolsClip1;
new g_iToolsClip2;
/**
* @endsection
*/
/**
* Find ammo-reserve-specific offsets here.
*/
WeaponAmmoOnOffsetsFound()
{
// If offset "m_iClip1" can't be found, then stop the plugin.
g_iToolsClip1 = FindSendPropInfo("CBaseCombatWeapon", "m_iClip1");
if (g_iToolsClip1 == -1)
{
LogPrintToLog(LOG_FORMAT_TYPE_FATALERROR, "Tools", "Offsets", "Offset \"CBaseCombatWeapon::m_iClip1\" was not found.");
}
// If offset "m_iClip2" can't be found, then stop the plugin.
g_iToolsClip2 = FindSendPropInfo("CBaseCombatWeapon", "m_iClip2");
if (g_iToolsClip2 == -1)
{
LogPrintToLog(LOG_FORMAT_TYPE_FATALERROR, "Tools", "Offsets", "Offset \"CBaseCombatWeapon::m_iClip2\" was not found.");
}
}
/**
* Set clip/reserve ammo on a weapon.
*
* @param weapon The weapon index.
* @param clip True sets clip ammo, false sets reserve.
* @param value The amount of ammo to set to.
* @param add (Optional) If true, the value is added to the weapon's current ammo count.
*/
stock WeaponAmmoSetClientAmmo(weapon, bool:clip, value, bool:add = false)
{
// Set variable to offset we are changing.
new ammooffset = clip ? g_iToolsClip1 : g_iToolsClip2;
// Initialize variable (value is 0)
new ammovalue;
// If we are adding, then update variable with current ammo value.
if (add)
{
ammovalue = WeaponAmmoGetClientAmmo(weapon, clip);
}
// Return ammo offset value.
SetEntData(weapon, ammooffset, ammovalue + value, _, true);
}
/**
* Get clip/reserve ammo on a weapon.
*
* @param weapon The weapon index.
* @param clip True gets clip ammo, false gets reserve.
*/
stock WeaponAmmoGetClientAmmo(weapon, bool:clip)
{
// Set variable to offset we are changing.
new ammooffset = clip ? g_iToolsClip1 : g_iToolsClip2;
// Return ammo offset value.
return GetEntData(weapon, ammooffset);
}

View File

@ -14,9 +14,6 @@
* Maximum length of a weapon name string
*/
#define WEAPONS_MAX_LENGTH 32
/**
* @endsection
*/
/**
* Number of weapon slots (For CS:S)
@ -24,27 +21,52 @@
#define WEAPONS_SLOTS_MAX 5
/**
* Weapon types.
* Weapon config data indexes.
*/
enum WeaponsType
enum WeaponsData
{
Type_Invalid = -1, /** Invalid weapon (slot). */
Type_Primary = 0, /** Primary weapon slot. */
Type_Secondary = 1, /** Secondary weapon slot. */
Type_Melee = 2, /** Melee (knife) weapon slot. */
Type_Projectile = 3, /** Projectile (grenades, flashbangs, etc) weapon slot. */
Type_Explosive = 4, /** Explosive (c4) weapon slot. */
WEAPONS_DATA_NAME = 0,
WEAPONS_DATA_TYPE,
WEAPONS_DATA_RESTRICTDEFAULT,
WEAPONS_DATA_TOGGLEABLE,
WEAPONS_DATA_AMMOTYPE,
WEAPONS_DATA_AMMOPRICE,
WEAPONS_DATA_KNOCKBACK,
WEAPONS_DATA_ZMARKETPRICE,
WEAPONS_DATA_RESTRICTED,
}
/**
* Keyvalue handle to store weapon data.
*
* @redir config.inc
* @endsection
*/
/**
* Variable to store active weapon offset value.
*/
new g_iToolsActiveWeapon;
/**
* Weapon slots.
*/
enum WeaponsSlot
{
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. */
}
/**
* Array handle to store weapon config data.
*/
new Handle:arrayWeapons = INVALID_HANDLE;
#include "zr/weapons/restrict"
#include "zr/weapons/weaponammo"
#include "zr/weapons/weaponalpha"
#include "zr/weapons/markethandler"
#include "zr/weapons/zmarket"
#include "zr/weapons/menu_weapons"
/**
@ -52,10 +74,26 @@ enum WeaponsType
*/
WeaponsInit()
{
// Forward event to sub-module
// Forward event to sub-modules.
RestrictInit();
}
/**
* Find active weapon-specific offsets here.
*/
WeaponsOnOffsetsFound()
{
// If offset "m_hActiveWeapon" can't be found, then stop the plugin.
g_iToolsActiveWeapon = FindSendPropInfo("CBasePlayer", "m_hActiveWeapon");
if (g_iToolsActiveWeapon == -1)
{
LogPrintToLog(LOG_FORMAT_TYPE_FATALERROR, "Tools", "Offsets", "Offset \"CBasePlayer::m_hActiveWeapon\" was not found.");
}
// Forward event to sub-modules
WeaponAmmoOnOffsetsFound();
}
/**
* Create commands related to weapons here.
*/
@ -65,34 +103,13 @@ WeaponsOnCommandsCreate()
RestrictOnCommandsCreate();
}
/**
* Clears weapon data.
*/
WeaponsClearData()
{
// Load weapon data
if (kvWeapons != INVALID_HANDLE)
{
CloseHandle(kvWeapons);
}
kvWeapons = CreateKeyValues("weapons");
}
/**
* Loads weapon data from file.
*/
WeaponsLoad()
{
// Clear weapon data.
WeaponsClearData();
// Get weapons config path.
decl String:pathweapons[PLATFORM_MAX_PATH];
new bool:exists = ConfigGetCvarFilePath(CVAR_CONFIG_PATH_WEAPONS, pathweapons);
// Register config info.
ConfigRegisterConfig(ConfigWeapons, false, GetFunctionByName(GetMyHandle(), "WeaponsOnConfigReload"), _, pathweapons, CONFIG_FILE_ALIAS_WEAPONS);
// Register config file.
ConfigRegisterConfig(File_Weapons, Structure_Keyvalue, CONFIG_FILE_ALIAS_WEAPONS);
// If module is disabled, then stop.
new bool:weapons = GetConVarBool(g_hCvarsList[CVAR_WEAPONS]);
@ -101,6 +118,10 @@ WeaponsLoad()
return;
}
// Get weapons config path.
decl String:pathweapons[PLATFORM_MAX_PATH];
new bool:exists = ConfigGetCvarFilePath(CVAR_CONFIG_PATH_WEAPONS, pathweapons);
// If file doesn't exist, then log and stop.
if (!exists)
{
@ -110,46 +131,121 @@ WeaponsLoad()
return;
}
// Put file data into memory.
FileToKeyValues(kvWeapons, pathweapons);
// Set the path to the config file.
ConfigSetConfigPath(File_Weapons, pathweapons);
// Load config from file and create array structure.
new bool:success = ConfigLoadConfig(File_Weapons, arrayWeapons);
// Unexpected error, stop plugin.
if (!success)
{
LogPrintToLog(LOG_FORMAT_TYPE_ERROR, "Weapons", "Config Validation", "Unexpected error encountered loading: %s", pathweapons);
return;
}
// Validate weapons config.
WeaponsValidateConfig();
new size = GetArraySize(arrayWeapons);
if (!size)
{
LogPrintToLog(LOG_FORMAT_TYPE_ERROR, "Weapons", "Config Validation", "No usable data found in weapons config file: %s", pathweapons);
}
// Now copy data to array structure.
WeaponsCacheData();
// Set config data.
ConfigSetConfigLoaded(ConfigWeapons, true);
ConfigSetConfigHandle(ConfigWeapons, kvWeapons);
ConfigSetConfigLoaded(File_Weapons, true);
ConfigSetConfigReloadFunc(File_Weapons, GetFunctionByName(GetMyHandle(), "WeaponsOnConfigReload"));
ConfigSetConfigHandle(File_Weapons, arrayWeapons);
// Forward event to sub-module.
// Forward event to sub-modules
RestrictLoad();
}
/**
* Called when configs are being reloaded.
*
* @param config The config being reloaded. (only if 'all' is false)
* Caches weapon data from file into arrays.
* Make sure the file is loaded before (ConfigLoadConfig) to prep array structure.
*/
public WeaponsOnConfigReload(ConfigFile:config)
WeaponsCacheData()
{
// Reload weapons config.
if (config == ConfigWeapons)
// Get config's file path.
decl String:pathweapons[PLATFORM_MAX_PATH];
ConfigGetConfigPath(File_Weapons, pathweapons, sizeof(pathweapons));
new Handle:kvWeapons;
new bool:success = ConfigOpenConfigFile(File_Weapons, kvWeapons);
if (!success)
{
WeaponsLoad();
LogPrintToLog(LOG_FORMAT_TYPE_ERROR, "Weapons", "Config Validation", "Unexpected error caching data from weapons config file: %s", pathweapons);
}
decl String:weaponname[WEAPONS_MAX_LENGTH];
// 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))
{
LogPrintToLog(LOG_FORMAT_TYPE_ERROR, "Weapons", "Config Validation", "Couldn't cache weapon data for: %s (check weapons config)", weaponname);
continue;
}
// Get config data.
decl String:weapontype[CONFIG_MAX_LENGTH];
decl String:ammotype[CONFIG_MAX_LENGTH];
// General
KvGetString(kvWeapons, "weapontype", weapontype, sizeof(weapontype));
// Restrict (core)
new bool:restrictdefault = ConfigKvGetStringBool(kvWeapons, "restrictdefault", "no");
new bool:toggleable = ConfigKvGetStringBool(kvWeapons, "toggleable", "yes");
// Weapon Ammo (core)
KvGetString(kvWeapons, "ammotype", ammotype, sizeof(ammotype));
new ammoprice = KvGetNum(kvWeapons, "ammoprice");
// Knockback (module)
new Float:knockback = KvGetFloat(kvWeapons, "knockback", 1.0);
// ZMarket (module)
new zmarketprice = KvGetNum(kvWeapons, "zmarketprice", -1);
new Handle:arrayWeapon = GetArrayCell(arrayWeapons, x);
// Push data into array.
PushArrayString(arrayWeapon, weapontype); // Index: 1
PushArrayCell(arrayWeapon, restrictdefault); // Index: 2
PushArrayCell(arrayWeapon, toggleable); // Index: 3
PushArrayString(arrayWeapon, ammotype); // Index: 4
PushArrayCell(arrayWeapon, ammoprice); // Index: 5
PushArrayCell(arrayWeapon, knockback); // Index: 6
PushArrayCell(arrayWeapon, zmarketprice); // Index: 7
// Initialize other stored weapon info here.
PushArrayCell(arrayWeapon, restrictdefault); // Index: 8
}
// We're done with this file now, so we can close it.
CloseHandle(kvWeapons);
}
/**
* Validate weapon config file and settings.
* Called when config is being reloaded.
*/
WeaponsValidateConfig()
public WeaponsOnConfigReload()
{
KvRewind(kvWeapons);
if (!KvGotoFirstSubKey(kvWeapons))
{
LogPrintToLog(LOG_FORMAT_TYPE_ERROR, "Weapons", "Config Validation", "No weapons listed in weapons.txt.");
}
// Reload weapons config.
WeaponsLoad();
}
/**
* Client is joining the server.
*
@ -195,154 +291,173 @@ WeaponsOnRoundEnd()
}
/**
* Creates an array of all listed weapons in weapons.txt.
* @param arrayWeapons The handle of the array, don't forget to call CloseHandle
* on it when finished!
* @return The size of the array.
* Weapon data reading API.
*/
stock WeaponsCreateWeaponArray(&Handle:arrayWeapons, maxlen = WEAPONS_MAX_LENGTH)
/**
* Clear cache for a given weapon.
*
* @param index The weapon index.
*/
WeaponsClearCache(index)
{
// Initialize array handle.
arrayWeapons = CreateArray(maxlen);
new count = 0;
// Get array handle of weapon at given index.
new Handle:hWeapon = GetArrayCell(arrayWeapons, index);
// Reset keyvalue's traveral stack.
KvRewind(kvWeapons);
if (KvGotoFirstSubKey(kvWeapons))
{
decl String:weapon[maxlen];
do
{
KvGetSectionName(kvWeapons, weapon, maxlen);
// Push weapon name into the array.
PushArrayString(arrayWeapons, weapon);
// Increment count.
count++;
} while (KvGotoNextKey(kvWeapons));
}
// Return the count
return count;
// Clear array.
ClearArray(hWeapon);
}
/**
* Checks if a weapon is valid. (aka listed in weapons.txt)
* Find the index at which the weapon's name is at.
*
* @param weapon The weapon name.
* @return The array index containing the given weapon name.
*/
stock WeaponsNameToIndex(const String:weapon[])
{
decl String:weaponname[WEAPONS_MAX_LENGTH];
// x = Array index.
new size = GetArraySize(arrayWeapons);
for (new x = 0; x < size; x++)
{
WeaponsGetName(x, weaponname, sizeof(weaponname));
// If names match, then return index.
if (StrEqual(weapon, weaponname, false))
{
return x;
}
}
// Name doesn't exist.
return -1;
}
/**
* Checks if a weapon is valid. (E.G. listed in weapons.txt)
* @param weapon The weapon name.
* @return Returns true if valid, false it not.
*/
stock bool:WeaponsIsValidWeapon(const String:weapon[])
stock bool:WeaponsIsWeaponValid(const String:weapon[])
{
// Reset keyvalue's traversal stack.
KvRewind(kvWeapons);
if (KvGotoFirstSubKey(kvWeapons))
{
decl String:validweapon[WEAPONS_MAX_LENGTH];
do
{
KvGetSectionName(kvWeapons, validweapon, sizeof(validweapon));
// If weaponname matches a valid weapon, then return true.
if (StrEqual(validweapon, weapon, false))
{
return true;
}
} while (KvGotoNextKey(kvWeapons));
}
// Weapon is invalid.
return false;
return (WeaponsNameToIndex(weapon) != -1);
}
/**
* Looks up a weapon in weapons.txt and returns exact display name.
* @param weapon The weapon name.
* @param display Returns with the display name, is not changed if weapon is invalid.
* 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 WeaponsGetDisplayName(const String:weapon[], String:display[])
stock WeaponsGetName(index, String:weapon[], maxlen)
{
// Reset keyvalue's traversal stack.
KvRewind(kvWeapons);
if (KvGotoFirstSubKey(kvWeapons))
{
decl String:validweapon[WEAPONS_MAX_LENGTH];
do
{
KvGetSectionName(kvWeapons, validweapon, sizeof(validweapon));
// If weapon matches a valid weapon (case-insensitive), then return display name.
if (StrEqual(validweapon, weapon, false))
{
strcopy(display, WEAPONS_MAX_LENGTH, validweapon);
}
} while (KvGotoNextKey(kvWeapons));
}
// Get array handle of weapon at given index.
new Handle:arrayWeapon = GetArrayCell(arrayWeapons, index);
// Get weapon name.
GetArrayString(arrayWeapon, _:WEAPONS_DATA_NAME, weapon, maxlen);
}
/**
* Checks if a weapon restriction can be toggled by the admin menu.
* @param weapon The weapon name.
* @return Returns true if restricted, false it not.
* 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.
*/
stock bool:WeaponsIsWeaponMenu(const String:weapon[])
stock WeaponsGetType(index, String:type[], maxlen)
{
// Reset keyvalue's traversal stack.
KvRewind(kvWeapons);
if (KvGotoFirstSubKey(kvWeapons))
{
decl String:validweapon[WEAPONS_MAX_LENGTH];
decl String:menu[8];
do
{
KvGetSectionName(kvWeapons, validweapon, sizeof(validweapon));
// If this is the right weapon, then return setting for it.
if (StrEqual(validweapon, weapon, false))
{
KvGetString(kvWeapons, "menu", menu, sizeof(menu), "yes");
// Return weapon's setting.
return ConfigSettingToBool(menu);
}
} while (KvGotoNextKey(kvWeapons));
}
// Get array handle of weapon at given index.
new Handle:arrayWeapon = GetArrayCell(arrayWeapons, index);
return false;
// Get weapon type.
GetArrayString(arrayWeapon, _:WEAPONS_DATA_TYPE, type, maxlen);
}
/**
* Returns knockback multiplier of the weapon.
* @param weapon The weapon name.
* @return The float value of the knockback multiplier, 1.0 if not found.
* 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.
*/
stock Float:WeaponGetWeaponKnockback(const String:weapon[])
stock bool:WeaponsGetRestrictDefault(index)
{
// Reset keyvalue's traversal stack.
KvRewind(kvWeapons);
if (KvGotoFirstSubKey(kvWeapons))
{
decl String:validweapon[WEAPONS_MAX_LENGTH];
do
{
KvGetSectionName(kvWeapons, validweapon, sizeof(validweapon));
// If this is the right weapon, then return setting for it.
if (StrEqual(validweapon, weapon, false))
{
return KvGetFloat(kvWeapons, "knockback", 1.0);
}
} while (KvGotoNextKey(kvWeapons));
}
// Get array handle of weapon at given index.
new Handle:arrayWeapon = GetArrayCell(arrayWeapons, index);
return 1.0;
// Return default restriction status.
return bool:GetArrayCell(arrayWeapon, _:WEAPONS_DATA_RESTRICTDEFAULT);
}
/**
* 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.
*/
stock bool:WeaponsGetToggleable(index)
{
// Get array handle of weapon at given index.
new Handle:arrayWeapon = GetArrayCell(arrayWeapons, index);
// 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);
// Get ammo type of the weapon.
GetArrayString(arrayWeapon, _:WEAPONS_DATA_AMMOTYPE, type, maxlen);
}
/**
* 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);
// 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);
// 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);
// Return the ZMarket price of the weapon.
return GetArrayCell(arrayWeapon, _:WEAPONS_DATA_ZMARKETPRICE);
}
/**
@ -356,7 +471,7 @@ stock Float:WeaponGetWeaponKnockback(const String:weapon[])
* @param weapons The weapon index array.
* -1 if no weapon in slot.
*/
stock WeaponsGetClientWeapons(client, weapons[WeaponsType])
stock WeaponsGetClientWeapons(client, weapons[WeaponsSlot])
{
// x = weapon slot.
for (new x = 0; x < WEAPONS_SLOTS_MAX; x++)
@ -384,10 +499,10 @@ stock WeaponsGetDeployedWeaponIndex(client)
* @param client The client index.
* @return The slot number of deployed weapon.
*/
stock WeaponsType:WeaponsGetDeployedWeaponSlot(client)
stock WeaponsSlot:WeaponsGetDeployedWeaponSlot(client)
{
// Get all client's weapon indexes.
new weapons[WeaponsType];
new weapons[WeaponsSlot];
WeaponsGetClientWeapons(client, weapons);
// Get client's deployed weapon.
@ -404,7 +519,7 @@ stock WeaponsType:WeaponsGetDeployedWeaponSlot(client)
{
if (weapons[x] == deployedweapon)
{
return x;
return WeaponsSlot:x;
}
}

View File

@ -0,0 +1,47 @@
/*
* ============================================================================
*
* Zombie:Reloaded
*
* File:
* Type: Module
* Description:
*
* ============================================================================
*/
/**
* Variable to store buyzone offset value.
*/
new g_iToolsInBuyZone;
/**
* Initialize market data.
*/
ZMarketInit()
{
}
/**
* Find ZMarket-specific offsets here.
*/
ZMarketOnOffsetsFound()
{
// If offset "m_bInBuyZone" can't be found, then stop the plugin.
g_iToolsInBuyZone = FindSendPropInfo("CCSPlayer", "m_bInBuyZone");
if (g_iToolsInBuyZone == -1)
{
LogPrintToLog(LOG_FORMAT_TYPE_FATALERROR, "Tools", "Offsets", "Offset \"CCSPlayer::m_bInBuyZone\" was not found.");
}
}
/**
* Checks if a client is in a buyzone.
*
* @param client The client index.
*/
stock bool:ZMarketIsClientInBuyZone(client)
{
// Return if client is in buyzone.
return bool:GetEntData(client, g_iToolsInBuyZone);
}

View File

@ -10,9 +10,6 @@
* ============================================================================
*/
#include "include/adminmenu.inc"
//new curMenuClass[MAXPLAYERS + 1];
bool:ZRAdminMenu(client)
{
if (!ZRIsClientAdmin(client))
@ -27,35 +24,37 @@ bool:ZRAdminMenu(client)
SetMenuTitle(menu_zadmin, "%t\n ", "!zadmin main title");
decl String:knockbackm[64];
decl String:knockback[64];
decl String:nvgs[64];
decl String:infect[64];
decl String:zspawn[64];
decl String:ztele[64];
//decl String:knockbackm[64];
//decl String:knockback[64];
//decl String:nvgs[64];
//decl String:infect[64];
//decl String:zspawn[64];
//decl String:ztele[64];
decl String:weapons[64];
decl String:logflags[64];
//decl String:logflags[64];
Format(knockbackm, sizeof(knockbackm), "%t", "!zadmin main knockbackm");
Format(knockback, sizeof(knockback), "%t", "!zadmin main knockback");
Format(nvgs, sizeof(nvgs), "%t", "!zadmin main nvgs");
Format(infect, sizeof(infect), "%t", "!zadmin main infect");
Format(zspawn, sizeof(zspawn), "%t", "!zadmin main spawn");
Format(ztele, sizeof(ztele), "%t", "!zadmin main tele");
//Format(knockbackm, sizeof(knockbackm), "%t", "!zadmin main knockbackm");
//Format(knockback, sizeof(knockback), "%t", "!zadmin main knockback");
//Format(nvgs, sizeof(nvgs), "%t", "!zadmin main nvgs");
//Format(infect, sizeof(infect), "%t", "!zadmin main infect");
//Format(zspawn, sizeof(zspawn), "%t", "!zadmin main spawn");
//Format(ztele, sizeof(ztele), "%t", "!zadmin main tele");
Format(weapons, sizeof(weapons), "%t", "!zadmin main weapons");
Format(logflags, sizeof(logflags), "%t", "!zadmin main logflags");
//Format(logflags, sizeof(logflags), "%t", "!zadmin main logflags");
AddMenuItem(menu_zadmin, "knockbackm", knockbackm, ITEMDRAW_DISABLED);
AddMenuItem(menu_zadmin, "knockback", knockback, ITEMDRAW_DISABLED);
AddMenuItem(menu_zadmin, "nvgs", nvgs, ITEMDRAW_DISABLED);
AddMenuItem(menu_zadmin, "infect", infect);
AddMenuItem(menu_zadmin, "zspawn", zspawn);
AddMenuItem(menu_zadmin, "ztele", ztele, ITEMDRAW_DISABLED);
//AddMenuItem(menu_zadmin, "knockbackm", knockbackm, ITEMDRAW_DISABLED);
//AddMenuItem(menu_zadmin, "knockback", knockback, ITEMDRAW_DISABLED);
//AddMenuItem(menu_zadmin, "nvgs", nvgs, ITEMDRAW_DISABLED);
//AddMenuItem(menu_zadmin, "infect", infect);
//AddMenuItem(menu_zadmin, "zspawn", zspawn);
//AddMenuItem(menu_zadmin, "ztele", ztele, ITEMDRAW_DISABLED);
AddMenuItem(menu_zadmin, "weapons", weapons);
AddMenuItem(menu_zadmin, "logflags", logflags);
//AddMenuItem(menu_zadmin, "logflags", logflags);
// Set "Back" button.
SetMenuExitBackButton(menu_zadmin, true);
// Send menu to client.
DisplayMenu(menu_zadmin, client, MENU_TIME_FOREVER);
return true;
@ -67,45 +66,21 @@ public ZRAdminMenuHandle(Handle:menu_admin, MenuAction:action, client, slot)
{
switch(slot)
{
// Weapon management.
case 0:
{
//ZRKnockbackMMenu(client);
}
case 1:
{
//ZRClassSelectMenu(client);
}
case 2:
{
//ZRNVGSMenu(client);
}
case 3:
{
ZRInfectMenu(client);
}
case 4:
{
ZRSpawnAll(client);
}
case 5:
{
ZRZTeleMenu(client);
}
case 6:
{
WeaponsMenuMain(client);
}
case 7:
{
ZRLogFlagsMenu(client);
}
}
// TODO: Resend menu if feature is disabled or unopenable.
}
if (action == MenuAction_Cancel)
{
if (slot == MenuCancel_ExitBack)
{
// Exit back to main menu.
MenuMain(client);
}
}
@ -113,438 +88,4 @@ public ZRAdminMenuHandle(Handle:menu_admin, MenuAction:action, client, slot)
{
CloseHandle(menu_admin);
}
}
/**
* Needs to be recoded to support new modules.
*/
/*ZRKnockbackMMenu(client)
{
new Handle:menu_knockbackm = CreateMenu(ZRKnockbackMHandle);
new Float:curknockback = GetConVarFloat(g_hCvarsList[CVAR_ZOMBIE_KNOCKBACK]);
SetGlobalTransTarget(client);
SetMenuTitle(menu_knockbackm, "%t\n ", "!zadmin knockbackm title", curknockback);
decl String:knockbackmincrease1[64];
decl String:knockbackmdecrease1[64];
decl String:knockbackmincrease2[64];
decl String:knockbackmdecrease2[64];
Format(knockbackmincrease1, sizeof(knockbackmincrease1), "%t", "!zadmin knockbackm increase", "0.1");
Format(knockbackmdecrease1, sizeof(knockbackmdecrease1), "%t", "!zadmin knockbackm decrease", "0.1");
Format(knockbackmincrease2, sizeof(knockbackmincrease2), "%t", "!zadmin knockbackm increase", "0.5");
Format(knockbackmdecrease2, sizeof(knockbackmdecrease2), "%t", "!zadmin knockbackm decrease", "0.5");
AddMenuItem(menu_knockbackm, "knockbackmincrease1", knockbackmincrease1);
AddMenuItem(menu_knockbackm, "knockbackmdecrease1", knockbackmdecrease1);
AddMenuItem(menu_knockbackm, "knockbackmincrease2", knockbackmincrease2);
AddMenuItem(menu_knockbackm, "knockbackmdecrease2", knockbackmdecrease2);
SetMenuExitBackButton(menu_knockbackm, true);
DisplayMenu(menu_knockbackm, client, MENU_TIME_FOREVER);
}
public ZRKnockbackMHandle(Handle:menu_knockbackm, MenuAction:action, client, slot)
{
if (action == MenuAction_Select)
{
switch(slot)
{
case 0:
{
AddToKnockbackMultiplier(0.1);
ZRKnockbackMMenu(client);
}
case 1:
{
AddToKnockbackMultiplier(-0.1);
ZRKnockbackMMenu(client);
}
case 2:
{
AddToKnockbackMultiplier(0.5);
ZRKnockbackMMenu(client);
}
case 3:
{
AddToKnockbackMultiplier(-0.5);
ZRKnockbackMMenu(client);
}
}
}
if (action == MenuAction_Cancel)
{
if (slot == MenuCancel_ExitBack)
{
ZRAdminMenu(client);
}
}
if (action == MenuAction_End)
{
CloseHandle(menu_knockbackm);
}
}
ZRClassSelectMenu(client)
{
new Handle:menu_class = CreateMenu(ZRClassSelectHandle);
SetGlobalTransTarget(client);
SetMenuTitle(menu_class, "%t\n ", "!zadmin class title");
// x = index of class
for (new x = 0; x < classCount; x++)
{
AddMenuItem(menu_class, arrayClasses[x][data_name], arrayClasses[x][data_name]);
}
SetMenuExitBackButton(menu_class, true);
DisplayMenu(menu_class, client, MENU_TIME_FOREVER);
}
public ZRClassSelectHandle(Handle:menu_class, MenuAction:action, client, slot)
{
if (action == MenuAction_Select)
{
curMenuClass[client] = slot;
ZRClassKnockbackMenu(client, slot);
}
if (action == MenuAction_Cancel)
{
if (slot == MenuCancel_ExitBack)
{
ZRAdminMenu(client);
}
}
if (action == MenuAction_End)
{
CloseHandle(menu_class);
}
}
ZRClassKnockbackMenu(client, classindex)
{
new Handle:menu_knockback = CreateMenu(ZRClassKnockbackHandle);
new Float:curknockback = arrayClasses[classindex][data_knockback];
new String:classname[64];
GetClassName(classindex, classname, sizeof(classname));
SetGlobalTransTarget(client);
SetMenuTitle(menu_knockback, "%t\n ", "!zadmin knockback title", classname, curknockback);
decl String:knockbackincrease1[64];
decl String:knockbackdecrease1[64];
decl String:knockbackincrease2[64];
decl String:knockbackdecrease2[64];
Format(knockbackincrease1, sizeof(knockbackincrease1), "%t", "!zadmin knockback increase", "0.1");
Format(knockbackdecrease1, sizeof(knockbackdecrease1), "%t", "!zadmin knockback decrease", "0.1");
Format(knockbackincrease2, sizeof(knockbackincrease2), "%t", "!zadmin knockback increase", "0.5");
Format(knockbackdecrease2, sizeof(knockbackdecrease2), "%t", "!zadmin knockback decrease", "0.5");
AddMenuItem(menu_knockback, "knockbackincrease1", knockbackincrease1);
AddMenuItem(menu_knockback, "knockbackdecrease1", knockbackdecrease1);
AddMenuItem(menu_knockback, "knockbackincrease2", knockbackincrease2);
AddMenuItem(menu_knockback, "knockbackdecrease2", knockbackdecrease2);
SetMenuExitBackButton(menu_knockback, true);
DisplayMenu(menu_knockback, client, MENU_TIME_FOREVER);
}
public ZRClassKnockbackHandle(Handle:menu_knockback, MenuAction:action, client, slot)
{
if (action == MenuAction_Select)
{
switch(slot)
{
case 0:
{
AddToClassKnockback(curMenuClass[client], 0.1);
}
case 1:
{
AddToClassKnockback(curMenuClass[client], -0.1);
}
case 2:
{
AddToClassKnockback(curMenuClass[client], 0.5);
}
case 3:
{
AddToClassKnockback(curMenuClass[client], -0.5);
}
}
ZRClassKnockbackMenu(client, curMenuClass[client]);
}
if (action == MenuAction_Cancel)
{
if (slot == MenuCancel_ExitBack)
{
ZRClassSelectMenu(client);
}
}
if (action == MenuAction_End)
{
CloseHandle(menu_knockback);
}
}
ZRNVGSMenu(client)
{
new Handle:menu_nvgs = CreateMenu(ZRNVGSHandle);
new curnvgs = GetConVarInt(g_hCvarsList[CVAR_ZOMBIE_NVGS]);
SetGlobalTransTarget(client);
SetMenuTitle(menu_nvgs, "%t\n ", "!zadmin nvgs title", curnvgs);
decl String:nooverride[64];
decl String:disable[64];
decl String:enable[64];
Format(nooverride, sizeof(nooverride), "%t", "!zadmin nvgs no override");
Format(disable, sizeof(disable), "%t", "!zadmin nvgs disable");
Format(enable, sizeof(enable), "%t", "!zadmin nvgs enable");
AddMenuItem(menu_nvgs, "nooverride", nooverride);
AddMenuItem(menu_nvgs, "disable", disable);
AddMenuItem(menu_nvgs, "enable", enable);
SetMenuExitBackButton(menu_nvgs, true);
DisplayMenu(menu_nvgs, client, MENU_TIME_FOREVER);
}
public ZRNVGSHandle(Handle:menu_nvgs, MenuAction:action, client, slot)
{
if (action == MenuAction_Select)
{
switch(slot)
{
case 0:
{
SetConVarInt(g_hCvarsList[CVAR_ZOMBIE_NVGS], -1);
ZRNVGSMenu(client);
}
case 1:
{
SetConVarInt(g_hCvarsList[CVAR_ZOMBIE_NVGS], 0);
ZRNVGSMenu(client);
}
case 2:
{
SetConVarInt(g_hCvarsList[CVAR_ZOMBIE_NVGS], 1);
ZRNVGSMenu(client);
}
}
}
if (action == MenuAction_Cancel)
{
if (slot == MenuCancel_ExitBack)
{
ZRAdminMenu(client);
}
}
if (action == MenuAction_End)
{
CloseHandle(menu_nvgs);
}
}*/
ZRInfectMenu(client)
{
new Handle:menu_infect = CreateMenu(ZRInfectHandle);
SetGlobalTransTarget(client);
SetMenuTitle(menu_infect, "%t\n ", "!zadmin infect title");
AddTargetsToMenu(menu_infect, client, true, true);
SetMenuExitBackButton(menu_infect, true);
DisplayMenu(menu_infect, client, MENU_TIME_FOREVER);
}
public ZRInfectHandle(Handle:menu_infect, MenuAction:action, client, slot)
{
if (action == MenuAction_Select)
{
decl String:info[32];
new userid, target;
GetMenuItem(menu_infect, slot, info, sizeof(info));
userid = StringToInt(info);
if ((target = GetClientOfUserId(userid)) == 0)
{
ReplyToCommand(client, "[ZR] Player no longer available");
}
else if (!CanUserTarget(client, target))
{
ReplyToCommand(client, "[ZR] Unable to target player");
}
else if (!IsPlayerAlive(target))
{
ReplyToCommand(client, "[ZR] Player is dead");
}
else
{
decl String:name[64];
GetClientName(target, name, sizeof(name));
InfectClient(target);
ShowActivity2(client, "[ZR] ", "Infected %s", name);
ZRInfectMenu(client);
}
}
if (action == MenuAction_Cancel)
{
if (slot == MenuCancel_ExitBack)
{
ZRAdminMenu(client);
}
}
if (action == MenuAction_End)
{
CloseHandle(menu_infect);
}
}
ZRSpawnAll(client)
{
// x = client index.
for (new x = 1; x < MaxClients; x++)
{
if (IsClientInGame(x))
{
ZSpawnClient(x);
}
}
ZRAdminMenu(client);
}
ZRZTeleMenu(client)
{
new Handle:menu_ztele = CreateMenu(ZRTeleHandle);
SetGlobalTransTarget(client);
SetMenuTitle(menu_ztele, "%t\n ", "!zadmin ztele title");
decl String:ztele_spawntele[64];
decl String:ztele_abort[64];
decl String:ztele_save[64];
decl String:ztele_tele[64];
Format(ztele_spawntele, sizeof(ztele_spawntele), "%t", "!zadmin ztele spawn tele");
Format(ztele_abort, sizeof(ztele_abort), "%t", "!zadmin ztele abort");
Format(ztele_save, sizeof(ztele_save), "%t", "!zadmin ztele save");
Format(ztele_tele, sizeof(ztele_tele), "%t", "!zadmin ztele tele");
AddMenuItem(menu_ztele, "ztele_spawntele", ztele_spawntele);
AddMenuItem(menu_ztele, "ztele_abort", ztele_abort);
AddMenuItem(menu_ztele, "ztele_save", ztele_save);
AddMenuItem(menu_ztele, "ztele_tele", ztele_tele);
SetMenuExitBackButton(menu_ztele, true);
DisplayMenu(menu_ztele, client, MENU_TIME_FOREVER);
}
public ZRTeleHandle(Handle:menu_ztele , MenuAction:action, client, slot)
{
if (action == MenuAction_Select)
{
switch(slot)
{
case 0:
{
// Teleport player.
}
case 1:
{
// Abort teleport.
}
case 2:
{
// Save location.
}
case 3:
{
// Teleport to location.
}
}
}
if (action == MenuAction_Cancel)
{
if (slot == MenuCancel_ExitBack)
{
ZRAdminMenu(client);
}
}
if (action == MenuAction_End)
{
CloseHandle(menu_ztele);
}
}
ZRLogFlagsMenu(client)
{
new Handle:menu_log_flags = CreateMenu(ZRLogFlagsMenuHandle);
SetGlobalTransTarget(client);
SetMenuTitle(menu_log_flags, "%t\n ", "!zadmin log flags title");
//new client_flags = GetUserFlagBits(client);
//new item_state = (client_flags & ADMFLAG_ROOT) ? ITEMDRAW_DEFAULT : ITEMDRAW_DISABLED;
//decl String:z_log_core[64];
//Format(z_log_core, sizeof(z_log_core), "Log core events (%d)", LogCheckFlag(LOG_CORE_EVENTS));
//AddMenuItem(menu_log_flags, z_log_core, z_log_core, item_state);
SetMenuExitBackButton(menu_log_flags, true);
DisplayMenu(menu_log_flags, client, MENU_TIME_FOREVER);
}
public ZRLogFlagsMenuHandle(Handle:menu_log_flags, MenuAction:action, client, slot)
{
if (action == MenuAction_Select)
{
switch(slot)
{
}
}
if (action == MenuAction_Cancel)
{
if (slot == MenuCancel_ExitBack)
{
ZRAdminMenu(client);
}
}
if (action == MenuAction_End)
{
CloseHandle(menu_log_flags);
}
}
AddToKnockbackMultiplier(Float:value)
{
new Float:current_val = GetConVarFloat(g_hCvarsList[CVAR_ZOMBIE_KNOCKBACK]);
SetConVarFloat(g_hCvarsList[CVAR_ZOMBIE_KNOCKBACK], current_val + value);
}
AddToClassKnockback(classindex, Float:value)
{
arrayClasses[classindex][data_knockback] = arrayClasses[classindex][data_knockback] + value;
}
}