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) // "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. // "knockback" "1.0" (default) // The knockback multiplier for the hitgroup.
// "damage" "yes" (default // Toggle damage on and off for this 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). // 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 "hitgroups" // Counter-Strike: Source hitgroups
{ {
"0" "Generic"
{ {
"name" "Generic" // General
"knockback" "1.0" "index" "0"
// Damage
"damage" "yes" "damage" "yes"
// Knockback
"knockback" "1.0"
} }
"1" "Head"
{ {
"name" "Head" // General
"index" "1"
// Damage
"damage" "yes"
// Knockback
"knockback" "2.0" "knockback" "2.0"
"damage" "yes"
} }
"2" "Chest"
{ {
"name" "Chest" // General
"index" "2"
// Damage
"damage" "yes"
// Knockback
"knockback" "1.3" "knockback" "1.3"
"damage" "yes"
} }
"3" "Stomach"
{ {
"name" "Stomach" // General
"index" "3"
// Damage
"damage" "yes"
// Knockback
"knockback" "1.2" "knockback" "1.2"
"damage" "yes"
} }
"4" "Left Arm"
{ {
"name" "Left Arm" // General
"index" "4"
// Damage
"damage" "yes"
// Knockback
"knockback" "1.0" "knockback" "1.0"
"damage" "yes"
} }
"5" "Right Arm"
{ {
"name" "Right Arm" // General
"index" "5"
// Damage
"damage" "yes"
// Knockback
"knockback" "1.0" "knockback" "1.0"
"damage" "yes"
} }
"6" "Left Leg"
{ {
"name" "Left Leg" // General
"index" "6"
// Damage
"damage" "yes"
// Knockback
"knockback" "0.9" "knockback" "0.9"
"damage" "yes"
} }
"7" "Right Leg"
{ {
"name" "Right Leg" // General
"index" "7"
// Damage
"damage" "yes"
// Knockback
"knockback" "0.9" "knockback" "0.9"
"damage" "yes"
} }
"10" "Gear"
{ {
"name" "Gear" // General
"knockback" "1.0" "index" "8"
// Damage
"damage" "yes" "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" "Config command reload syntax"
{ {
"#format" "{1:s},{2:s},{3:s},{4:s},{5:s},{6:s}" "#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}\"\n * \"{6}\"" "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" "Config command reload invalid"
@ -289,46 +289,52 @@
"en" "Weapon @green\"{1}\" @defaulthas been unrestricted." "en" "Weapon @green\"{1}\" @defaulthas been unrestricted."
} }
"Restrict weapon failed" "Restrict weapon stopped"
{ {
"#format" "{1:s}" "#format" "{1:s}"
"en" "Weapon @green\"{1}\" @defaultis already restricted." "en" "Weapon @green\"{1}\" @defaultis already restricted."
} }
"Unrestrict weapon failed" "Unrestrict weapon stopped"
{ {
"#format" "{1:s}" "#format" "{1:s}"
"en" "Weapon @green\"{1}\" @default has no restrictions set." "en" "Weapon @green\"{1}\" @default has no restrictions set."
} }
"Restrict custom weapon group" "Restrict weapon type"
{ {
"#format" "{1:s},{2:s}" "#format" "{1:s}"
"en" "Weapon group @green\"{1}\" ({2}) @defaulthas been restricted." "en" "Weapons of type @green\"{1}\" @defaulthave been restricted."
} }
"Unrestrict custom weapon group" "Unrestrict weapon type"
{ {
"#format" "{1:s},{2:s}" "#format" "{1:s}"
"en" "Weapon group @green\"{1}\" ({2}) @defaulthas been unrestricted." "en" "Weapons of type @green\"{1}\" @defaulthave been unrestricted."
} }
"Restrict custom weapon group failed" "Restrict weapon type stopped"
{ {
"#format" "{1:s},{2:s}" "#format" "{1:s}"
"en" "Weapon group @green\"{1}\" ({2}) @defaultis already restricted." "en" "Weapons of type @green\"{1}\" @defaultare all already restricted."
} }
"Unrestrict custom weapon group failed" "Unrestrict weapon type stopped"
{ {
"#format" "{1:s},{2:s}" "#format" "{1:s}"
"en" "Weapon group @green\"{1}\" ({2}) @defaulthas no restrictions set." "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" "Weapon invalid"
{ {
"#format" "{1:s}" "#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" "Weapon is restricted"
@ -338,29 +344,28 @@
"ru" "Оружие @green{1} @default запрещено." "ru" "Оружие @green{1} @default запрещено."
} }
// Market // ZMarket
"Market title" "Market title"
{ {
"en" "Available Weapons:" "en" ""
} }
"Market rebuy" "Market rebuy"
{ {
"en" "Rebuy" "en" ""
"ru" "Купить снова"
} }
// Commands // Commands
"Weapons command restrict syntax" "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" "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 // Menu
@ -370,56 +375,48 @@
"en" "Weapons Management" "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" "Weapons menu types type 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"
{ {
"#format" "{1:s}" "#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" "Weapons menu types restrict all"
{
"en" "Toggle Market Settings:"
}
"Weapons menu market toggle buyzone"
{ {
"#format" "{1:s}" "#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" "!zadmin main title"
{ {
"en" "ZAdmin Menu:" "en" "ZAdmin\n Select Category:"
}
"!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"
} }
"!zadmin main weapons" "!zadmin main weapons"

View File

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

View File

@ -16,9 +16,6 @@
#include <cstrike> #include <cstrike>
#include <zrtools> #include <zrtools>
#undef REQUIRE_PLUGIN
#include <market>
#define VERSION "3.0-dev" #define VERSION "3.0-dev"
// Core includes. // Core includes.
@ -103,35 +100,7 @@ public OnPluginStart()
WeaponsInit(); WeaponsInit();
SayHooksInit(); SayHooksInit();
EventInit(); EventInit();
MarketInit(); ZMarketInit();
}
/**
* 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;
}
} }
/** /**
@ -162,7 +131,7 @@ public OnMapEnd()
*/ */
public OnConfigsExecuted() public OnConfigsExecuted()
{ {
// Forward event to modules. // Forward event to modules. (OnConfigsExecuted)
ConfigLoad(); ConfigLoad();
ModelsLoad(); ModelsLoad();
DownloadsLoad(); DownloadsLoad();
@ -173,6 +142,7 @@ public OnConfigsExecuted()
SEffectsLoad(); SEffectsLoad();
ClassLoad(); ClassLoad();
// Forward event to modules. (OnModulesLoaded)
ConfigOnModulesLoaded(); ConfigOnModulesLoaded();
ClassOnModulesLoaded(); ClassOnModulesLoaded();
} }

View File

@ -15,6 +15,24 @@
*/ */
#define ACCOUNT_CASH_MAX 16000 #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. * Client is spawning into the game.
* *

View File

@ -29,11 +29,29 @@
* @endsection * @endsection
*/ */
/**
* Variable to store antistick offset value.
*/
new g_iToolsCollisionGroup;
/** /**
* Handle to keep track of AntiStickTimer. * Handle to keep track of AntiStickTimer.
*/ */
new Handle:tAntiStick = INVALID_HANDLE; 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. * Map is starting.
*/ */
@ -191,4 +209,4 @@ AntiStickClientCollisionGroup(client, bool:apply = true, collisiongroup = 0)
} }
return GetEntData(client, g_iToolsCollisionGroup, 1); return GetEntData(client, g_iToolsCollisionGroup, 1);
} }

View File

@ -22,23 +22,31 @@
#define CONFIG_FILE_ALIAS_DOWNLOADS "downloads" #define CONFIG_FILE_ALIAS_DOWNLOADS "downloads"
#define CONFIG_FILE_ALIAS_CLASSES "classes" #define CONFIG_FILE_ALIAS_CLASSES "classes"
#define CONFIG_FILE_ALIAS_WEAPONS "weapons" #define CONFIG_FILE_ALIAS_WEAPONS "weapons"
#define CONFIG_FILE_ALIAS_WEAPONGROUPS "weapongroups"
#define CONFIG_FILE_ALIAS_HITGROUPS "hitgroups" #define CONFIG_FILE_ALIAS_HITGROUPS "hitgroups"
/** /**
* @endsection * @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. * List of config files used by the plugin.
*/ */
enum ConfigFile enum ConfigFile
{ {
ConfigInvalid = -1, /** Invalid config file. */ File_Invalid = -1, /** Invalid config file. */
ConfigModels, /** <sourcemod root>/configs/zr/models.txt (default) */ File_Models, /** <sourcemod root>/configs/zr/models.txt (default) */
ConfigDownloads, /** <sourcemod root>/configs/zr/downloads.txt (default) */ File_Downloads, /** <sourcemod root>/configs/zr/downloads.txt (default) */
ConfigClasses, /** <sourcemod root>/configs/zr/playerclasses.txt (default) */ File_Classes, /** <sourcemod root>/configs/zr/playerclasses.txt (default) */
ConfigWeapons, /** <sourcemod root>/configs/zr/weapons/weapons.txt/weapongroups.txt (default) */ File_Weapons, /** <sourcemod root>/configs/zr/weapons.txt (default) */
ConfigHitgroups, /** <sourcemod root>/configs/zr/hitgroups.txt (default) */ File_Hitgroups, /** <sourcemod root>/configs/zr/hitgroups.txt (default) */
} }
/** /**
@ -46,11 +54,12 @@ enum ConfigFile
*/ */
enum ConfigData enum ConfigData
{ {
bool:ConfigLoaded, /** True if config is loaded, false if not. */ bool: Data_Loaded, /** True if config is loaded, false if not. */
Function:ConfigReloadFunc, /** Function to call to reload config. */ ConfigStructure: Data_Structure, /** Format of the config */
Handle:ConfigHandle, /** Handle of the config file. */ Function: Data_ReloadFunc, /** Function to call to reload config. */
String:ConfigPath[PLATFORM_MAX_PATH], /** Full path to config file. */ Handle: Data_Handle, /** Handle of the config file. */
String:ConfigAlias[CONFIG_MAX_LENGTH], /** Config file alias, used for client interaction. */ 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. * Actions to use when working on key/values.
*/ */
enum ConfigKeyvalueAction enum ConfigKvAction
{ {
ConfigKVCreate, /** Create a key. */ KvAction_Create, /** Create a key. */
ConfigKVDelete, /** Delete a key. */ KvAction_KVDelete, /** Delete a key. */
ConfigKVSet, /** Modify setting of a key. */ KvAction_KVSet, /** Modify setting of a key. */
ConfigKVGet, /** Get 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. * Create commands related to config here.
*/ */
@ -157,20 +156,20 @@ ConfigOnModulesLoaded()
/** /**
* Used by modules that rely on configs to register their config file info. * 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 file Config file entry to register.
* @param loaded True if the config should be loaded, false if not. * @param alias Config file alias, used for client interaction.
* @param path (Optional) Full path to config file.
* @param alias (Optional) 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. // Copy file info to data container.
g_ConfigData[file][ConfigLoaded] = loaded; g_ConfigData[file][Data_Loaded] = false;
g_ConfigData[file][ConfigHandle] = filehandle; g_ConfigData[file][Data_Structure] = structure;
g_ConfigData[file][ConfigReloadFunc] = reloadfunc; g_ConfigData[file][Data_Handle] = INVALID_HANDLE;
strcopy(g_ConfigData[file][ConfigPath], PLATFORM_MAX_PATH, path); g_ConfigData[file][Data_ReloadFunc] = INVALID_FUNCTION;
strcopy(g_ConfigData[file][ConfigAlias], CONFIG_MAX_LENGTH, alias); 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) stock ConfigSetConfigLoaded(ConfigFile:config, bool:loaded)
{ {
// Set load state. // 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) stock ConfigSetConfigReloadFunc(ConfigFile:config, Function:reloadfunc)
{ {
// Set reload function. // 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) stock ConfigSetConfigHandle(ConfigFile:config, Handle:file)
{ {
// Set file handle. // 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[]) stock ConfigSetConfigPath(ConfigFile:config, const String:path[])
{ {
// Set config file 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[]) stock ConfigSetConfigAlias(ConfigFile:config, const String:alias[])
{ {
// Set config 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) stock bool:ConfigIsConfigLoaded(ConfigFile:config)
{ {
// Return load status. // 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) stock Function:ConfigGetConfigReloadFunc(ConfigFile:config)
{ {
// Return load status. // 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) stock Handle:ConfigGetConfigHandle(ConfigFile:config)
{ {
// Return load status. // 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) stock ConfigGetConfigPath(ConfigFile:config, String:path[], maxlen)
{ {
// Copy path to return string. // 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) stock ConfigGetConfigAlias(ConfigFile:config, String:alias[], maxlen)
{ {
// Copy alias to return string. // 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. * @param config The config file entry to reload.
* @return True if the config is loaded, false if not. * @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. // If file isn't loaded, then stop.
new bool:loaded = ConfigIsConfigLoaded(config); new bool:loaded = ConfigIsConfigLoaded(config);
@ -309,6 +458,7 @@ stock bool:ConfigReloadFile(ConfigFile:config)
// Call reload function // Call reload function
new Function:reloadfunc = ConfigGetConfigReloadFunc(config); new Function:reloadfunc = ConfigGetConfigReloadFunc(config);
// This should never be true unless someone has tampered with the code.
if (reloadfunc == INVALID_FUNCTION) if (reloadfunc == INVALID_FUNCTION)
{ {
// Get config alias. // Get config alias.
@ -323,12 +473,169 @@ stock bool:ConfigReloadFile(ConfigFile:config)
// Call reload function. // Call reload function.
Call_StartFunction(GetMyHandle(), reloadfunc); Call_StartFunction(GetMyHandle(), reloadfunc);
Call_PushCell(config);
Call_Finish(); Call_Finish();
return true; 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. * Load config file.
* *
@ -374,94 +681,11 @@ stock ConfigFile:ConfigAliasToConfigFile(const String:alias[])
} }
// Invalid config file. // Invalid config file.
return ConfigInvalid; return File_Invalid;
} }
/** /**
* Creates, deletes, sets, or gets any key/setting of any ZR config keyvalue file in memory. * Command callback (zr_config_reload)
* 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)
* Reloads a config file and forwards event to modules. * Reloads a config file and forwards event to modules.
* *
* @param client The client index. * @param client The client index.
@ -472,7 +696,7 @@ public Action:ConfigReloadCommand(client, argc)
// If not enough arguments given, then stop. // If not enough arguments given, then stop.
if (argc < 1) 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; return Plugin_Handled;
} }
@ -482,14 +706,14 @@ public Action:ConfigReloadCommand(client, argc)
// If alias is invalid, then stop. // If alias is invalid, then stop.
new ConfigFile:config = ConfigAliasToConfigFile(arg1); new ConfigFile:config = ConfigAliasToConfigFile(arg1);
if (config == ConfigInvalid) if (config == File_Invalid)
{ {
TranslationReplyToCommand(client, "Config command reload invalid", arg1); TranslationReplyToCommand(client, "Config command reload invalid", arg1);
return Plugin_Handled; return Plugin_Handled;
} }
// Reload config file. // Reload config file.
new bool:loaded = ConfigReloadFile(config); new bool:loaded = ConfigReloadConfig(config);
// Get config file path. // Get config file path.
decl String:path[PLATFORM_MAX_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. * Reloads all config files and forwards event to all modules.
* *
* @param client The client index. * @param client The client index.
@ -523,7 +747,7 @@ public Action:ConfigReloadAllCommand(client, argc)
for (new x = 0; x < sizeof(g_ConfigData); x++) for (new x = 0; x < sizeof(g_ConfigData); x++)
{ {
// Reload config file. // Reload config file.
new bool:successful = ConfigReloadFile(ConfigFile:x); new bool:successful = ConfigReloadConfig(ConfigFile:x);
// Get config's alias. // Get config's alias.
ConfigGetConfigAlias(ConfigFile:x, configalias, sizeof(configalias)); 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. * Converts string of "yes" or "no" to a boolean value.
* *
* @param option "yes" or "no" string to be converted. * @param option "yes" or "no" string to be converted.
* @return True if string is "yes", false otherwise. * @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 option is equal to "yes," then return true.
if (StrEqual(option, "yes", false)) 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 bOption True/false value to be converted to "yes"/"no", respectively.
* @param option Destination string buffer to store "yes" or "no" in. * @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 option is true, then copy "yes" to return string.
if (bOption) if (bOption)
@ -635,3 +801,11 @@ ConfigBoolToSetting(bool:bOption, String:option[], maxlen)
strcopy(option, maxlen, "no"); 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_DOWNLOADS,
Handle:CVAR_CONFIG_PATH_CLASSES, Handle:CVAR_CONFIG_PATH_CLASSES,
Handle:CVAR_CONFIG_PATH_WEAPONS, Handle:CVAR_CONFIG_PATH_WEAPONS,
Handle:CVAR_CONFIG_PATH_WEAPONGROUPS,
Handle:CVAR_CONFIG_PATH_HITGROUPS, Handle:CVAR_CONFIG_PATH_HITGROUPS,
Handle:CVAR_CLASSES_SPAWN, Handle:CVAR_CLASSES_SPAWN,
Handle:CVAR_CLASSES_RANDOM, Handle:CVAR_CLASSES_RANDOM,
@ -51,6 +50,7 @@ enum CvarsList
Handle:CVAR_CLASSES_OVERLAY_DEFAULT, Handle:CVAR_CLASSES_OVERLAY_DEFAULT,
Handle:CVAR_WEAPONS, Handle:CVAR_WEAPONS,
Handle:CVAR_WEAPONS_RESTRICT, Handle:CVAR_WEAPONS_RESTRICT,
Handle:CVAR_WEAPONS_ZMARKET,
Handle:CVAR_WEAPONS_ZMARKET_BUYZONE, Handle:CVAR_WEAPONS_ZMARKET_BUYZONE,
Handle:CVAR_HITGROUPS, Handle:CVAR_HITGROUPS,
Handle:CVAR_DAMAGE_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_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_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_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_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_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_HITGROUPS] = CreateConVar("zr_config_path_hitgroups", "configs/zr/hitgroups.txt", "Path, relative to root sourcemod directory, to hitgroups 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."); 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) // Hitgroups (core)

View File

@ -48,7 +48,7 @@ DamageOnCommandsHook()
// Explode string into array indexes. // Explode string into array indexes.
new cmdcount = ExplodeString(suicidecmds, ", ", arrayCmds, DAMAGE_SUICIDE_MAX_CMDS, DAMAGE_SUICIDE_MAX_LENGTH); new cmdcount = ExplodeString(suicidecmds, ", ", arrayCmds, DAMAGE_SUICIDE_MAX_CMDS, DAMAGE_SUICIDE_MAX_LENGTH);
// x = array index. // x = Array index.
// arrayCmds[x] = suicide command. // arrayCmds[x] = suicide command.
for (new x = 0; x <= cmdcount - 1; x++) 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. // 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) if (!candamage)
{ {
// Stop bullet from hurting client. // Stop bullet from hurting client.

View File

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

View File

@ -11,10 +11,9 @@
*/ */
/** /**
* Keyvalue handle to store hitgroups data. * Maximum length for a hitgroup name
*
* @redir config.inc
*/ */
#define HITGROUPS_MAX_LENGTH 32
/** /**
* @section Player hitgroup values. * @section Player hitgroup values.
@ -33,33 +32,28 @@
*/ */
/** /**
* Clears hitgroup data. * Hitgroup config data indexes.
*/ */
HitgroupsClearData() enum HitgroupsData
{ {
// Load hitgroup data. HITGROUPS_DATA_NAME = 0,
if (kvHitgroups != INVALID_HANDLE) HITGROUPS_DATA_INDEX,
{ HITGROUPS_DATA_DAMAGE,
CloseHandle(kvHitgroups); HITGROUPS_DATA_KNOCKBACK,
}
kvHitgroups = CreateKeyValues("hitgroups");
} }
/**
* Array handle to store hitgroups data.
*/
new Handle:arrayHitgroups = INVALID_HANDLE;
/** /**
* Loads hitgroup data from file. * Loads hitgroup data from file.
*/ */
HitgroupsLoad() HitgroupsLoad()
{ {
// Clear hitgroup data // Register config file.
HitgroupsClearData(); ConfigRegisterConfig(File_Hitgroups, Structure_Keyvalue, CONFIG_FILE_ALIAS_HITGROUPS);
// 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);
// If module is disabled, then stop. // If module is disabled, then stop.
new bool:hitgroups = GetConVarBool(g_hCvarsList[CVAR_HITGROUPS]); new bool:hitgroups = GetConVarBool(g_hCvarsList[CVAR_HITGROUPS]);
@ -68,23 +62,101 @@ HitgroupsLoad()
return; 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 file doesn't exist, then log and stop.
if (!exists) if (!exists)
{ {
// Log failure. // Log failure.
LogPrintToLog(LOG_FORMAT_TYPE_ERROR, "Hitgroups", "Config Validation", "Missing hitgroups config file: %s", pathhitgroups); LogPrintToLog(LOG_FORMAT_TYPE_ERROR, "Hitgroups", "Config Validation", "Missing hitgroups config file: %s", pathhitgroups);
return; return;
} }
// Put file data into memory. // Set the path to the config file.
FileToKeyValues(kvHitgroups, pathhitgroups); 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. // 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. // Set config data.
ConfigSetConfigLoaded(ConfigHitgroups, true); ConfigSetConfigLoaded(File_Hitgroups, true);
ConfigSetConfigHandle(ConfigHitgroups, kvHitgroups); 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) public HitgroupsOnConfigReload(ConfigFile:config)
{ {
// Reload hitgroups config. // Reload hitgroups config.
if (config == ConfigHitgroups) HitgroupsLoad();
{
HitgroupsLoad();
}
} }
/** /**
* Validate hitgroup config file and settings. * Find the array index at which the hitgroup index is at.
*/
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.
* *
* @param hitgroup The hitgroup index. * @param hitgroup The hitgroup index to search for.
* @return The knockback multiplier of the hitgroup. * @return The array index that contains the given hitgroup index.
*/ */
Float:HitgroupsGetHitgroupKnockback(hitgroup) stock HitgroupToIndex(hitgroup)
{ {
// Reset keyvalue's traversal stack. // x = Array index.
KvRewind(kvHitgroups); new size = GetArraySize(arrayHitgroups);
if (KvGotoFirstSubKey(kvHitgroups)) 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)); return x;
}
// 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 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. * Retrieve hitgroup damage value.
* *
* @param hitgroup The hitgroup index. * @param index The array index.
* @return True if hitgroup can be damaged, false if not. * @return True if hitgroup can be damaged, false if not.
*/ */
bool:HitgroupsCanDamageHitgroup(hitgroup) stock bool:HitgroupsCanDamage(index)
{ {
// Reset keyvalue's traversal stack. // Get array handle of hitgroup at given index.
KvRewind(kvHitgroups); new Handle:arrayHitgroup = GetArrayCell(arrayHitgroups, index);
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));
}
// If hitgroup is missing, then default to "yes." // Return true if hitgroup can be damaged, false if not.
return true; 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; new client;
// Prune list of immune clients. // Prune list of immune clients.
// x = array index. // x = Array index.
// client = client index. // client = client index.
for (new x = 0; x < eligibleclients; x++) for (new x = 0; x < eligibleclients; x++)
{ {
@ -522,7 +522,7 @@ InfectClient(client, attacker = -1, bool:motherinfect = false)
bZombie[client] = true; bZombie[client] = true;
// Get a list of all client's weapon indexes. // Get a list of all client's weapon indexes.
new weapons[WeaponsType]; new weapons[WeaponsSlot];
WeaponsGetClientWeapons(client, weapons); WeaponsGetClientWeapons(client, weapons);
// Check if weapons drop is enabled. // Check if weapons drop is enabled.
@ -541,7 +541,7 @@ InfectClient(client, attacker = -1, bool:motherinfect = false)
if (weaponsdrop) if (weaponsdrop)
{ {
// If this is the knife slot, then stop. // If this is the knife slot, then stop.
if (WeaponsType:x == Type_Melee) if (WeaponsSlot:x == Slot_Melee)
{ {
continue; continue;
} }
@ -557,7 +557,7 @@ InfectClient(client, attacker = -1, bool:motherinfect = false)
} }
// If client has no knife, give them one. // If client has no knife, give them one.
if (GetPlayerWeaponSlot(client, _:Type_Melee) == -1) if (GetPlayerWeaponSlot(client, _:Slot_Melee) == -1)
{ {
GivePlayerItem(client, "weapon_knife"); GivePlayerItem(client, "weapon_knife");
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -209,14 +209,6 @@ ClassMenuSelect(client, teamid)
AddMenuItem(menu, classname, menuitem); 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); SetMenuExitBackButton(menu, true);
DisplayMenu(menu, client, MENU_TIME_FOREVER); DisplayMenu(menu, client, MENU_TIME_FOREVER);

View File

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

View File

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

View File

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

View File

@ -121,8 +121,6 @@ public Action:SayHooksCmdSay(client, argc)
// Client triggered ZMarket flag. // Client triggered ZMarket flag.
case SAYHOOKS_KEYWORD_FLAG_ZMARKET: 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_iToolsLMV;
new g_iToolsHasNightVision; new g_iToolsHasNightVision;
new g_iToolsNightVisionOn; new g_iToolsNightVisionOn;
new g_iToolsCollisionGroup;
new g_iToolsAccount;
new g_iToolsDefaultFOV; new g_iToolsDefaultFOV;
new g_iToolsInBuyZone;
new g_iToolsActiveWeapon;
/** /**
* @endsection * @endsection
*/ */
@ -93,20 +90,6 @@ ToolsFindOffsets()
LogPrintToLog(LOG_FORMAT_TYPE_FATALERROR, "Tools", "Offsets", "Offset \"CCSPlayer::m_bNightVisionOn\" was not found."); 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. // If offset "m_iDefaultFOV" can't be found, then stop the plugin.
g_iToolsDefaultFOV = FindSendPropInfo("CBasePlayer", "m_iDefaultFOV"); g_iToolsDefaultFOV = FindSendPropInfo("CBasePlayer", "m_iDefaultFOV");
if (g_iToolsDefaultFOV == -1) if (g_iToolsDefaultFOV == -1)
@ -114,19 +97,11 @@ ToolsFindOffsets()
LogPrintToLog(LOG_FORMAT_TYPE_FATALERROR, "Tools", "Offsets", "Offset \"CBasePlayer::m_iDefaultFOV\" was not found."); 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. // Forward event to modules.
g_iToolsInBuyZone = FindSendPropInfo("CCSPlayer", "m_bInBuyZone"); WeaponsOnOffsetsFound();
if (g_iToolsInBuyZone == -1) AccountOnOffsetsFound();
{ AntiStickOnOffsetsFound();
LogPrintToLog(LOG_FORMAT_TYPE_FATALERROR, "Tools", "Offsets", "Offset \"CCSPlayer::m_bInBuyZone\" was not found."); ZMarketOnOffsetsFound();
}
// 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.");
}
} }
/** /**

View File

@ -153,8 +153,8 @@ stock TranslationPrintToChatAll(bool:server, bool:admin, any:...)
continue; continue;
} }
// Set translation target // Set translation target to client.
SetGlobalTransTarget(LANG_SERVER); SetGlobalTransTarget(x);
// Translate phrase. // Translate phrase.
VFormat(translation, sizeof(translation), "%t", 3); VFormat(translation, sizeof(translation), "%t", 3);
@ -327,9 +327,20 @@ stock TranslationReplyToCommand(client, any:...)
decl String:translation[TRANSLATION_MAX_LENGTH_CHAT]; decl String:translation[TRANSLATION_MAX_LENGTH_CHAT];
VFormat(translation, sizeof(translation), "%t", 2); VFormat(translation, sizeof(translation), "%t", 2);
// Format string to create plugin style. if (ZRIsClientValid(client))
TranslationPluginFormatString(translation, sizeof(translation)); {
// Format string to create plugin style. (color)
// Print translated phrase to client. TranslationPluginFormatString(translation, sizeof(translation));
ReplyToCommand(client, 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 new g_iCurWeaponType[MAXPLAYERS + 1];
{
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];
/** /**
* Sends main weapon menu to client. * Sends main weapon menu to client.
* @param client The client index. * @param client The client index.
*/ */
WeaponsMenuMain(client) WeaponsMenuMain(client)
{ {
// Create menu handle. // Create menu handle.
@ -42,17 +28,15 @@ WeaponsMenuMain(client)
SetMenuTitle(menu_weapons_main, "%t\n ", "Weapons menu main title"); SetMenuTitle(menu_weapons_main, "%t\n ", "Weapons menu main title");
decl String:toggleweaponrestriction[64]; decl String:restrict[64];
decl String:togglewgrouprestriction[64];
decl String:zmarket[64]; decl String:zmarket[64];
Format(toggleweaponrestriction, sizeof(toggleweaponrestriction), "%t", "Weapons menu main toggle weapon restrict"); Format(restrict, sizeof(restrict), "%t", "Weapons menu main restrict");
Format(togglewgrouprestriction, sizeof(togglewgrouprestriction), "%t", "Weapons menu main toggle weapon group restrict");
Format(zmarket, sizeof(zmarket), "%t", "Weapons menu main market"); Format(zmarket, sizeof(zmarket), "%t", "Weapons menu main market");
AddMenuItem(menu_weapons_main, "toggleweaponrestriction", toggleweaponrestriction); // Draw items, make unselectable if module is disabled.
AddMenuItem(menu_weapons_main, "togglewgrouprestriction", togglewgrouprestriction); AddMenuItem(menu_weapons_main, "restrict", restrict, MenuGetItemDraw(GetConVarBool(g_hCvarsList[CVAR_WEAPONS_RESTRICT])));
AddMenuItem(menu_weapons_main, "zmarket", zmarket, MenuGetItemDraw(g_bMarket)); AddMenuItem(menu_weapons_main, "zmarket", zmarket, MenuGetItemDraw(GetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET])));
// Create a "Back" button to the weapons main menu. // Create a "Back" button to the weapons main menu.
SetMenuExitBackButton(menu_weapons_main, true); SetMenuExitBackButton(menu_weapons_main, true);
@ -75,17 +59,15 @@ public WeaponsMenuMainHandle(Handle:menu_weapons_main, MenuAction:action, client
{ {
switch(slot) switch(slot)
{ {
// Weapons.
case 0: case 0:
{ {
WeaponsMenuWeapons(client, Weapon); WeaponsMenuTypes(client);
} }
// ZMarket.
case 1: case 1:
{ {
WeaponsMenuWeapons(client, WeaponGroup); WeaponsMenuZMarket(client);
}
case 2:
{
WeaponsMenuMarket(client);
} }
} }
} }
@ -95,7 +77,7 @@ public WeaponsMenuMainHandle(Handle:menu_weapons_main, MenuAction:action, client
// Client hit "Back" button. // Client hit "Back" button.
if (slot == MenuCancel_ExitBack) if (slot == MenuCancel_ExitBack)
{ {
ZRAdminMenu(client); // Re-open admin menu.
} }
} }
// Client hit "Exit" button. // 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. * @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. // Create menu handle.
new Handle:menu_weapons_weapons = CreateMenu(WeaponsMenuWeaponsHandle); new Handle:menu_weapons_types = CreateMenu(WeaponsMenuTypesHandle);
SetGlobalTransTarget(client); SetGlobalTransTarget(client);
// If client wants to perform an action on a single weapon, show weapon list. SetMenuTitle(menu_weapons_types, "%t\n ", "Weapons menu types title");
switch(curMenuWeapons[client])
decl String:typename[WEAPONS_MAX_LENGTH];
// x = Array index.
new size = GetArraySize(arrayWeaponTypes);
for (new x = 0; x < size; x++)
{ {
case Weapon: // Get name of type.
{ RestrictWeaponTypeGetName(x, typename, sizeof(typename));
SetMenuTitle(menu_weapons_weapons, "%t\n ", "Weapons menu weapons weapon title");
// Add item to menu.
decl String:weapon[WEAPONS_MAX_LENGTH]; AddMenuItem(menu_weapons_types, typename, typename);
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);
}
} }
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. * 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 action The action done on the menu (see menus.inc, enum MenuAction).
* @param client The client index. * @param client The client index.
* @param slot The slot index selected (starting from 0). * @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. // Client selected an option.
if (action == MenuAction_Select) if (action == MenuAction_Select)
{ {
decl String:weapon[WEAPONS_MAX_LENGTH]; // Menu slot index is = weapon type index.
GetMenuItem(menu_weapons_weapons, slot, weapon, sizeof(weapon)); g_iCurWeaponType[client] = slot;
switch(curMenuWeapons[client]) // Send weapons of the selected type in a menu to client.
{ WeaponsMenuTypeWeapons(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);
}
}
} }
// Client closed the menu. // Client closed the menu.
if (action == MenuAction_Cancel) if (action == MenuAction_Cancel)
@ -272,118 +158,141 @@ public WeaponsMenuWeaponsHandle(Handle:menu_weapons_weapons, MenuAction:action,
// Client hit "Exit" button. // Client hit "Exit" button.
else if (action == MenuAction_End) 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. // 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:restrictall[64];
decl String:unrestrictall[64]; decl String:unrestrictall[64];
Format(restrictall, sizeof(restrictall), "%t", "Weapons menu weapon group restrict all"); Format(restrictall, sizeof(restrictall), "%t", "Weapons menu types restrict all", typename);
Format(unrestrictall, sizeof(unrestrictall), "%t", "Weapons menu weapon group unrestrict all"); Format(unrestrictall, sizeof(unrestrictall), "%t", "Weapons menu types unrestrict all", typename);
if (RestrictIsGroupRestricted(weapongroup)) // 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_groupweapon, "restrictall", restrictall, ITEMDRAW_DISABLED); AddMenuItem(menu_weapons_typeweapons, "unrestrictall", unrestrictall, MenuGetItemDraw(!RestrictIsTypeUniform(false, g_iCurWeaponType[client])));
}
else
{
AddMenuItem(menu_weapons_groupweapon, "restrictall", restrictall);
}
if (RestrictIsGroupUnrestricted(weapongroup)) decl String:typeweapon[WEAPONS_MAX_LENGTH];
{ decl String:display[WEAPONS_MAX_LENGTH];
AddMenuItem(menu_weapons_groupweapon, "unrestrictall", unrestrictall, ITEMDRAW_DISABLED);
}
else
{
AddMenuItem(menu_weapons_groupweapon, "unrestrictall", unrestrictall);
}
decl String:groupweapon[WEAPONS_MAX_LENGTH]; // Get an array populated with all weapons of the given type.
decl String:display[WEAPONS_MAX_LENGTH + 1]; new Handle:arrayTypeWeapons;
new Handle:arrayGroupWeapons = INVALID_HANDLE; new count = RestrictGetTypeWeapons(g_iCurWeaponType[client], arrayTypeWeapons);
new size = RestrictCreateGroupWeaponsArray(arrayGroupWeapons, weapongroup);
// x = Array index. // 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. // Destroy the array handle.
CloseHandle(arrayGroupWeapons); CloseHandle(arrayTypeWeapons);
SetMenuExitBackButton(menu_weapons_groupweapon, true); // Set menu back button.
SetMenuExitBackButton(menu_weapons_typeweapons, true);
DisplayMenu(menu_weapons_groupweapon, client, MENU_TIME_FOREVER);
// 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. * Called when client selects option in the weapon group menu, and handles it.
* @param menu_weapons_main Handle of the menu being used. * @param menu_weapons_typeweapons Handle of the menu being used.
* @param action The action done on the menu (see menus.inc, enum MenuAction). * @param action The action done on the menu (see menus.inc, enum MenuAction).
* @param client The client index. * @param client The client index.
* @param slot The slot index selected (starting from 0). * @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. // Client selected an option.
if (action == MenuAction_Select) 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) switch(slot)
{ {
case 0: case 0:
{ {
new WpnRestrictQuery:output = RestrictRestrict(curMenuGroup[client]); // Restrict all weapons of this type.
RestrictPrintRestrictOutput(client, output, curMenuGroup[client], false); restrict = true;
query = RestrictWeapon(true, typename, single, returntarget, sizeof(returntarget));
} }
case 1: case 1:
{ {
new WpnRestrictQuery:output = RestrictUnrestrict(curMenuGroup[client]); // Unrestrict all weapons of this type.
RestrictPrintUnrestrictOutput(client, output, curMenuGroup[client], false); restrict = false;
query = RestrictWeapon(false, typename, single, returntarget, sizeof(returntarget));
} }
default: 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]; // Get weapon index.
GetMenuItem(menu_weapons_groupweapon, slot, groupweapon, sizeof(groupweapon)); new weaponindex = WeaponsNameToIndex(typeweapon);
if (!RestrictIsWeaponRestricted(groupweapon)) // If weapon index is -1, then something went very wrong.
if (weaponindex == -1)
{ {
output = RestrictRestrict(groupweapon); CloseHandle(menu_weapons_typeweapons);
RestrictPrintRestrictOutput(client, output, groupweapon, false); }
// 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 else
{ {
output = RestrictUnrestrict(groupweapon); // Unrestrict this weapon.
RestrictPrintUnrestrictOutput(client, output, groupweapon, false); restrict = false;
query = RestrictWeapon(false, typeweapon, single, returntarget, sizeof(returntarget));
} }
} }
} }
// Print query response.
RestrictPrintQueryResponse(client, query, single, restrict, returntarget);
// Resend menu. // Resend menu.
WeaponsMenuWeaponGroup(client, curMenuGroup[client]); WeaponsMenuTypeWeapons(client);
} }
// Client closed the menu. // Client closed the menu.
if (action == MenuAction_Cancel) if (action == MenuAction_Cancel)
@ -391,37 +300,38 @@ public WeaponsMenuWeaponGroupHandle(Handle:menu_weapons_groupweapon, MenuAction:
// Client hit "Back" button. // Client hit "Back" button.
if (slot == MenuCancel_ExitBack) if (slot == MenuCancel_ExitBack)
{ {
WeaponsMenuWeapons(client, curMenuWeapons[client]); WeaponsMenuTypes(client);
} }
} }
// Client hit "Exit" button. // Client hit "Exit" button.
else if (action == MenuAction_End) 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. * @param client The client index.
*/ */
WeaponsMenuMarket(client) WeaponsMenuZMarket(client)
{ {
// Create menu handle. // Create menu handle.
new Handle:menu_weapons_market = CreateMenu(WeaponsMenuMarketHandle); new Handle:menu_weapons_market = CreateMenu(WeaponsMenuZMarketHandle);
SetGlobalTransTarget(client); 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]; // Get "yes" or "no" settings from respective cvar.
ConfigBoolToSetting(GetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE]), curSetting, sizeof(curSetting)); ConfigBoolToSetting(GetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE]), buyzonesetting, sizeof(buyzonesetting));
Format(togglebuyzone, sizeof(togglebuyzone), "%t", "Weapons menu market toggle buyzone", curSetting); // Add options to menu.
Format(buyzone, sizeof(buyzone), "%t", "Weapons menu zmarket buyzone", buyzonesetting);
AddMenuItem(menu_weapons_market, "togglebuyzone", togglebuyzone); AddMenuItem(menu_weapons_market, "buyzone", buyzone);
// Create a "Back" button to the weapons main menu. // Create a "Back" button to the weapons main menu.
SetMenuExitBackButton(menu_weapons_market, true); SetMenuExitBackButton(menu_weapons_market, true);
@ -432,33 +342,29 @@ WeaponsMenuMarket(client)
/** /**
* Called when client selects option in the weapons main menu, and handles it. * 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 action The action done on the menu (see menus.inc, enum MenuAction).
* @param client The client index. * @param client The client index.
* @param slot The slot index selected (starting from 0). * @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. // Client selected an option.
if (action == MenuAction_Select) if (action == MenuAction_Select)
{ {
switch(slot) switch(slot)
{ {
// Buyzone.
case 0: case 0:
{ {
if (GetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE])) // Toggle cvar.
{ new bool:zmarketbuyzone = GetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE]);
SetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE], false); SetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE], !zmarketbuyzone);
}
else
{
SetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE], true);
}
} }
} }
// Resend menu. // Resend menu.
WeaponsMenuMarket(client); WeaponsMenuZMarket(client);
} }
// Client closed the menu. // Client closed the menu.
if (action == MenuAction_Cancel) 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. // Get client's list of weapons.
new weapons[WeaponsType]; new weapons[WeaponsSlot];
WeaponsGetClientWeapons(entity, weapons); WeaponsGetClientWeapons(entity, weapons);
// Loop through array slots and set alpha. // 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 * Maximum length of a weapon name string
*/ */
#define WEAPONS_MAX_LENGTH 32 #define WEAPONS_MAX_LENGTH 32
/**
* @endsection
*/
/** /**
* Number of weapon slots (For CS:S) * Number of weapon slots (For CS:S)
@ -24,27 +21,52 @@
#define WEAPONS_SLOTS_MAX 5 #define WEAPONS_SLOTS_MAX 5
/** /**
* Weapon types. * Weapon config data indexes.
*/ */
enum WeaponsType enum WeaponsData
{ {
Type_Invalid = -1, /** Invalid weapon (slot). */ WEAPONS_DATA_NAME = 0,
Type_Primary = 0, /** Primary weapon slot. */ WEAPONS_DATA_TYPE,
Type_Secondary = 1, /** Secondary weapon slot. */ WEAPONS_DATA_RESTRICTDEFAULT,
Type_Melee = 2, /** Melee (knife) weapon slot. */ WEAPONS_DATA_TOGGLEABLE,
Type_Projectile = 3, /** Projectile (grenades, flashbangs, etc) weapon slot. */ WEAPONS_DATA_AMMOTYPE,
Type_Explosive = 4, /** Explosive (c4) weapon slot. */ WEAPONS_DATA_AMMOPRICE,
WEAPONS_DATA_KNOCKBACK,
WEAPONS_DATA_ZMARKETPRICE,
WEAPONS_DATA_RESTRICTED,
} }
/** /**
* Keyvalue handle to store weapon data. * @endsection
*
* @redir config.inc
*/ */
/**
* 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/restrict"
#include "zr/weapons/weaponammo"
#include "zr/weapons/weaponalpha" #include "zr/weapons/weaponalpha"
#include "zr/weapons/markethandler" #include "zr/weapons/zmarket"
#include "zr/weapons/menu_weapons" #include "zr/weapons/menu_weapons"
/** /**
@ -52,10 +74,26 @@ enum WeaponsType
*/ */
WeaponsInit() WeaponsInit()
{ {
// Forward event to sub-module // Forward event to sub-modules.
RestrictInit(); 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. * Create commands related to weapons here.
*/ */
@ -65,34 +103,13 @@ WeaponsOnCommandsCreate()
RestrictOnCommandsCreate(); RestrictOnCommandsCreate();
} }
/**
* Clears weapon data.
*/
WeaponsClearData()
{
// Load weapon data
if (kvWeapons != INVALID_HANDLE)
{
CloseHandle(kvWeapons);
}
kvWeapons = CreateKeyValues("weapons");
}
/** /**
* Loads weapon data from file. * Loads weapon data from file.
*/ */
WeaponsLoad() WeaponsLoad()
{ {
// Clear weapon data. // Register config file.
WeaponsClearData(); ConfigRegisterConfig(File_Weapons, Structure_Keyvalue, CONFIG_FILE_ALIAS_WEAPONS);
// 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);
// If module is disabled, then stop. // If module is disabled, then stop.
new bool:weapons = GetConVarBool(g_hCvarsList[CVAR_WEAPONS]); new bool:weapons = GetConVarBool(g_hCvarsList[CVAR_WEAPONS]);
@ -101,6 +118,10 @@ WeaponsLoad()
return; 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 file doesn't exist, then log and stop.
if (!exists) if (!exists)
{ {
@ -110,46 +131,121 @@ WeaponsLoad()
return; return;
} }
// Put file data into memory. // Set the path to the config file.
FileToKeyValues(kvWeapons, pathweapons); 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. // 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. // Set config data.
ConfigSetConfigLoaded(ConfigWeapons, true); ConfigSetConfigLoaded(File_Weapons, true);
ConfigSetConfigHandle(ConfigWeapons, kvWeapons); ConfigSetConfigReloadFunc(File_Weapons, GetFunctionByName(GetMyHandle(), "WeaponsOnConfigReload"));
ConfigSetConfigHandle(File_Weapons, arrayWeapons);
// Forward event to sub-module. // Forward event to sub-modules
RestrictLoad(); RestrictLoad();
} }
/** /**
* Called when configs are being reloaded. * Caches weapon data from file into arrays.
* * Make sure the file is loaded before (ConfigLoadConfig) to prep array structure.
* @param config The config being reloaded. (only if 'all' is false)
*/ */
public WeaponsOnConfigReload(ConfigFile:config) WeaponsCacheData()
{ {
// Reload weapons config. // Get config's file path.
if (config == ConfigWeapons) 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); // Reload weapons config.
if (!KvGotoFirstSubKey(kvWeapons)) WeaponsLoad();
{
LogPrintToLog(LOG_FORMAT_TYPE_ERROR, "Weapons", "Config Validation", "No weapons listed in weapons.txt.");
}
} }
/** /**
* Client is joining the server. * Client is joining the server.
* *
@ -195,154 +291,173 @@ WeaponsOnRoundEnd()
} }
/** /**
* Creates an array of all listed weapons in weapons.txt. * Weapon data reading API.
* @param arrayWeapons The handle of the array, don't forget to call CloseHandle
* on it when finished!
* @return The size of the array.
*/ */
stock WeaponsCreateWeaponArray(&Handle:arrayWeapons, maxlen = WEAPONS_MAX_LENGTH)
/**
* Clear cache for a given weapon.
*
* @param index The weapon index.
*/
WeaponsClearCache(index)
{ {
// Initialize array handle. // Get array handle of weapon at given index.
arrayWeapons = CreateArray(maxlen); new Handle:hWeapon = GetArrayCell(arrayWeapons, index);
new count = 0;
// Reset keyvalue's traveral stack. // Clear array.
KvRewind(kvWeapons); ClearArray(hWeapon);
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;
} }
/** /**
* 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. * @param weapon The weapon name.
* @return Returns true if valid, false it not. * @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. return (WeaponsNameToIndex(weapon) != -1);
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;
} }
/** /**
* Looks up a weapon in weapons.txt and returns exact display name. * Gets the name of a weapon at a given index.
* @param weapon The weapon name. * @param index The weapon index.
* @param display Returns with the display name, is not changed if weapon is invalid. * @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. // Get array handle of weapon at given index.
KvRewind(kvWeapons); new Handle:arrayWeapon = GetArrayCell(arrayWeapons, index);
if (KvGotoFirstSubKey(kvWeapons))
{ // Get weapon name.
decl String:validweapon[WEAPONS_MAX_LENGTH]; GetArrayString(arrayWeapon, _:WEAPONS_DATA_NAME, weapon, maxlen);
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));
}
} }
/** /**
* Checks if a weapon restriction can be toggled by the admin menu. * Gets the type of a weapon at a given index.
* @param weapon The weapon name. * @param index The weapon index.
* @return Returns true if restricted, false it not. * @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. // Get array handle of weapon at given index.
KvRewind(kvWeapons); new Handle:arrayWeapon = GetArrayCell(arrayWeapons, index);
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));
}
return false; // Get weapon type.
GetArrayString(arrayWeapon, _:WEAPONS_DATA_TYPE, type, maxlen);
} }
/** /**
* Returns knockback multiplier of the weapon. * Gets if a weapon is restricted by default.
* @param weapon The weapon name. * @param index The weapon index.
* @return The float value of the knockback multiplier, 1.0 if not found. * @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. // Get array handle of weapon at given index.
KvRewind(kvWeapons); new Handle:arrayWeapon = GetArrayCell(arrayWeapons, index);
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));
}
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. * @param weapons The weapon index array.
* -1 if no weapon in slot. * -1 if no weapon in slot.
*/ */
stock WeaponsGetClientWeapons(client, weapons[WeaponsType]) stock WeaponsGetClientWeapons(client, weapons[WeaponsSlot])
{ {
// x = weapon slot. // x = weapon slot.
for (new x = 0; x < WEAPONS_SLOTS_MAX; x++) for (new x = 0; x < WEAPONS_SLOTS_MAX; x++)
@ -384,10 +499,10 @@ stock WeaponsGetDeployedWeaponIndex(client)
* @param client The client index. * @param client The client index.
* @return The slot number of deployed weapon. * @return The slot number of deployed weapon.
*/ */
stock WeaponsType:WeaponsGetDeployedWeaponSlot(client) stock WeaponsSlot:WeaponsGetDeployedWeaponSlot(client)
{ {
// Get all client's weapon indexes. // Get all client's weapon indexes.
new weapons[WeaponsType]; new weapons[WeaponsSlot];
WeaponsGetClientWeapons(client, weapons); WeaponsGetClientWeapons(client, weapons);
// Get client's deployed weapon. // Get client's deployed weapon.
@ -404,7 +519,7 @@ stock WeaponsType:WeaponsGetDeployedWeaponSlot(client)
{ {
if (weapons[x] == deployedweapon) 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) bool:ZRAdminMenu(client)
{ {
if (!ZRIsClientAdmin(client)) if (!ZRIsClientAdmin(client))
@ -27,35 +24,37 @@ bool:ZRAdminMenu(client)
SetMenuTitle(menu_zadmin, "%t\n ", "!zadmin main title"); SetMenuTitle(menu_zadmin, "%t\n ", "!zadmin main title");
decl String:knockbackm[64]; //decl String:knockbackm[64];
decl String:knockback[64]; //decl String:knockback[64];
decl String:nvgs[64]; //decl String:nvgs[64];
decl String:infect[64]; //decl String:infect[64];
decl String:zspawn[64]; //decl String:zspawn[64];
decl String:ztele[64]; //decl String:ztele[64];
decl String:weapons[64]; decl String:weapons[64];
decl String:logflags[64]; //decl String:logflags[64];
Format(knockbackm, sizeof(knockbackm), "%t", "!zadmin main knockbackm"); //Format(knockbackm, sizeof(knockbackm), "%t", "!zadmin main knockbackm");
Format(knockback, sizeof(knockback), "%t", "!zadmin main knockback"); //Format(knockback, sizeof(knockback), "%t", "!zadmin main knockback");
Format(nvgs, sizeof(nvgs), "%t", "!zadmin main nvgs"); //Format(nvgs, sizeof(nvgs), "%t", "!zadmin main nvgs");
Format(infect, sizeof(infect), "%t", "!zadmin main infect"); //Format(infect, sizeof(infect), "%t", "!zadmin main infect");
Format(zspawn, sizeof(zspawn), "%t", "!zadmin main spawn"); //Format(zspawn, sizeof(zspawn), "%t", "!zadmin main spawn");
Format(ztele, sizeof(ztele), "%t", "!zadmin main tele"); //Format(ztele, sizeof(ztele), "%t", "!zadmin main tele");
Format(weapons, sizeof(weapons), "%t", "!zadmin main weapons"); 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, "knockbackm", knockbackm, ITEMDRAW_DISABLED);
AddMenuItem(menu_zadmin, "knockback", knockback, ITEMDRAW_DISABLED); //AddMenuItem(menu_zadmin, "knockback", knockback, ITEMDRAW_DISABLED);
AddMenuItem(menu_zadmin, "nvgs", nvgs, ITEMDRAW_DISABLED); //AddMenuItem(menu_zadmin, "nvgs", nvgs, ITEMDRAW_DISABLED);
AddMenuItem(menu_zadmin, "infect", infect); //AddMenuItem(menu_zadmin, "infect", infect);
AddMenuItem(menu_zadmin, "zspawn", zspawn); //AddMenuItem(menu_zadmin, "zspawn", zspawn);
AddMenuItem(menu_zadmin, "ztele", ztele, ITEMDRAW_DISABLED); //AddMenuItem(menu_zadmin, "ztele", ztele, ITEMDRAW_DISABLED);
AddMenuItem(menu_zadmin, "weapons", weapons); AddMenuItem(menu_zadmin, "weapons", weapons);
AddMenuItem(menu_zadmin, "logflags", logflags); //AddMenuItem(menu_zadmin, "logflags", logflags);
// Set "Back" button.
SetMenuExitBackButton(menu_zadmin, true); SetMenuExitBackButton(menu_zadmin, true);
// Send menu to client.
DisplayMenu(menu_zadmin, client, MENU_TIME_FOREVER); DisplayMenu(menu_zadmin, client, MENU_TIME_FOREVER);
return true; return true;
@ -67,45 +66,21 @@ public ZRAdminMenuHandle(Handle:menu_admin, MenuAction:action, client, slot)
{ {
switch(slot) switch(slot)
{ {
// Weapon management.
case 0: 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); WeaponsMenuMain(client);
} }
case 7:
{
ZRLogFlagsMenu(client);
}
} }
// TODO: Resend menu if feature is disabled or unopenable.
} }
if (action == MenuAction_Cancel) if (action == MenuAction_Cancel)
{ {
if (slot == MenuCancel_ExitBack) if (slot == MenuCancel_ExitBack)
{ {
// Exit back to main menu.
MenuMain(client); MenuMain(client);
} }
} }
@ -113,438 +88,4 @@ public ZRAdminMenuHandle(Handle:menu_admin, MenuAction:action, client, slot)
{ {
CloseHandle(menu_admin); 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;
}