Merged heads. Fixed conflicts in cvars.inc and zadmin.inc.

Readded some functions in zadmin.inc, but made them as comments. No reason to remove these so we don't have to remake them again.
This commit is contained in:
richard 2009-05-30 04:42:23 +02:00
commit 1fb33b2b13
44 changed files with 2843 additions and 2585 deletions

View File

@ -1,120 +0,0 @@
Changes from Zombie: Reloaded 2.5.1
====================================
Alpha values (transparency)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Support for alpha values in classes. New values in classes.txt (per class):
Key: Value: Default: Description:
alpha_spawn <0-255> 255 initial alpha value (0 = transparent)
alpha_damaged <0-255> 255 alpha value when damaged
alpha_damage <damage> 0 how much damage to do before
alpha_damaged take effect
Knockback multiplier
~~~~~~~~~~~~~~~~~~~~~
If classes are enabled the zr_zombie_knockback cvar is used as a multiplier.
Makes it possible to set custom knockback on maps using per-map configs.
Set zr_zombie_knockback to 1 if you use classes and want it the way it was
before.
knockback = zr_zombie_knockback * class knockback
Full spawn protection
~~~~~~~~~~~~~~~~~~~~~~
Spawn protection makes the players invisible and move faster, and cannot be
infected during protection time.
A centered counter shows the time remaining.
Overriding class night vision
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Support for overrriding class nvgs with the zr_zombie_nvgs cvar. Generally,
any non-zero value is considered as on.
Value: Description:
-1 no override (use value in classes.txt) / nvgs on
0 never give nvgs
1 always give nvgs
Anticamp feature
~~~~~~~~~~~~~~~~~
Define hurt volumes in maps that gives x damage at a custom interval.
When creating volumes they should start a little bit _below_ the floor, so it
covers the players feet.
The volume is rectangular and you only need two locations in the map to create
it; a top corner, and the bottom corner at the oposite side.
zr_anticamp_create_volume <damage> <interval> <x1> <y1> <z1> <x2> <y2> <z2>
- Create a rectangular volume between the specified locations.
zr_anticamp_remove_volume <volume id>
- Remove a volume.
zr_anticamp_list
- List existing volumes.
Set default classes
~~~~~~~~~~~~~~~~~~~~
Setting the default class with a cvar. Works with per-map configs. Use "random"
as classname to set random classes on all players when the map loads or they
connect.
zr_classes_default <classname>
Zombie admin menu
~~~~~~~~~~~~~~~~~~
Basic zombie admin commands like adjusting knockback, nvgs, infecting players
and spawn everyone.
Knockback changes are applied instantly, useful for tuning knockback in-game.
Note that the changes are not saved. They will reset on map change. In a
future version this menu might save the changes.
Knockback multiplier
- Fine tune the knockback multiplier.
Class knockback
- Fine tune a class knockback value.
Night vision settings
- Override night vision settings (explained earlier).
Infect
- Infect a player. Lists all players, but could be changed to only list
humans.
Spawn players
- Spawns all dead players (except spectactors).
(more zombie admin stuff might come...)
Set (and get) class knockback
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Set or get knockback from a class. Changes are not saved. They will be reset on
map change.
zr_set_class_knockback <classname> <knockback>
- Sets knockback to a specified class. Useful when using per-map configs to
fine tune the class knockback for a map.
zr_get_class_knockback <classname>
- Prints the current knockback of a class to the client/server console.
Using the zombie admin menu to read a knockback value is easier sometimes.
More stuff
~~~~~~~~~~~
Other minior and major bug fixes. See changelog.txt.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -16,9 +16,6 @@
#include <cstrike>
#include <zrtools>
#undef REQUIRE_PLUGIN
#include <market>
#define VERSION "3.0-dev"
// Core includes.
@ -37,6 +34,7 @@
#include "zr/playerclasses/playerclasses"
#include "zr/weapons/weapons"
#include "zr/hitgroups"
#include "zr/roundstart"
#include "zr/roundend"
#include "zr/infect"
#include "zr/damage"
@ -62,9 +60,6 @@
#include "zr/jumpboost"
#include "zr/volfeatures/volfeatures"
// Almost replaced! :)
#include "zr/zombie"
/**
* Record plugin info.
*/
@ -106,35 +101,7 @@ public OnPluginStart()
WeaponsInit();
SayHooksInit();
EventInit();
MarketInit();
}
/**
* Library is being removed.
*
* @param name The name of the library.
*/
public OnLibraryRemoved(const String:name[])
{
// If market is being removed, then set variable to false.
if (StrEqual(name, "market", false))
{
g_bMarket = false;
}
}
/**
* Library is being added.
*
* @param name The name of the library.
*/
public OnLibraryAdded(const String:name[])
{
// If market is being added, then set variable to true.
if (StrEqual(name, "market", false))
{
g_bMarket = true;
}
ZMarketInit();
}
/**
@ -165,7 +132,7 @@ public OnMapEnd()
*/
public OnConfigsExecuted()
{
// Forward event to modules.
// Forward event to modules. (OnConfigsExecuted)
ConfigLoad();
ModelsLoad();
DownloadsLoad();
@ -177,6 +144,7 @@ public OnConfigsExecuted()
ClassLoad();
VolLoad();
// Forward event to modules. (OnModulesLoaded)
ConfigOnModulesLoaded();
ClassOnModulesLoaded();
}

View File

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

View File

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

View File

@ -17,6 +17,7 @@ CommandsInit()
{
// Forward event to modules. (create commands)
ConfigOnCommandsCreate();
ClassOnCommandsCreate();
WeaponsOnCommandsCreate();
VolOnCommandsCreate();
@ -42,10 +43,6 @@ CommandsInit()
RegAdminCmd("zr_anticamp_list", Command_AnticampList, ADMFLAG_GENERIC, "List current volumes.");
RegConsoleCmd("zr_log_flags", Command_LogFlags, "List available logging flags.");
RegConsoleCmd("zr_class_dump", Command_ClassDump, "Dumps class data at a specified index in the specified cache. Usage: zr_class_dump <cachetype> <index|targetname>");
RegAdminCmd("zr_class_modify", Command_ClassModify, ADMFLAG_GENERIC, "Modify class data on one or more classes. Usage: zr_class_modify <classname|\"zombies\"|\"humans\"|\"admins\"> <attribute> <value> [is_multiplier]");
}*/
/*public Action:Command_Infect(client, argc)

View File

@ -10,6 +10,94 @@
* ============================================================================
*/
/*
Using config API:
-Before any of these helper functions can be used on a config file you must
"register" the module handling the data.
Example:
ConfigRegisterConfig(File_Example, Structure_List, "example");
* The first parameter of this call is the config file we want to register.
this needs to be listed in the "ConfigFile" enum in config.inc.
* The second parameter is the structure of the config file we are loading.
The supported structures are listed in the "ConfigStructure" enum in config.inc
* The last parameter is the file's alias. Or what we use to refer to the
config file from a non-developer's point of view. For example zr_config_reload
requires the file alias to identify the config file the user wants to reload.
-Next we need to define the config file's path. To do this we first need to
retrieve the path file from cvar.
Example:
new bool:exists = ConfigGetCvarFilePath(CVAR_CONFIG_PATH_EXAMPLE, pathexample);
* The first parameter is the cvar handle we are looking into.
* The second parameter is the string to store the path in.
* The return value is true if the file exists on the server, false if not.
If the file doesn't exist, handle it. (Print log, stop plugin, etc)
Then store it in the config file data.
Example:
ConfigSetConfigPath(File_Example, pathexample);
* The first parameter is the config file we want to set path to.
* The second parameter is the path we want to set to the config file.
-Next we load config file and prepare its nested array structure.
Example:
new bool:success = ConfigLoadConfig(File_Example, arrayExample);
* The first parameter is the config file we want to load.
* The second parameter is the array handle we want to prepare data structure in.
* The return value is true if the file was successfully loaded, false if the
config file couldn't be loaded. (Invalid data, missing quotes, brackets, etc)
-Next validate the config so far, stopping if no data was found or if ConfigLoadConfig
returned false.
-Then cache the config file data into the arrays (only for Keyvalue structures)
by iterating through the data and pushing the values into the array.
-Validate the values of the data.
-Lastly we need to set specific info to the module now that it has successfully
loaded.
Example:
ConfigSetConfigLoaded(File_Example, true);
ConfigSetConfigReloadFunc(File_Example, GetFunctionByName(GetMyHandle(), "ExampleOnConfigReload"));
ConfigSetConfigHandle(File_Example, arrayExample);
These functions will modify the config file data for other things to use.
(such as zr_config_reload)
* The first function call will set the loaded state of the config file to
true, failing to do this will cause the config module to think your
config file isn't loaded, therefore causing some undesired erroring.
* The second function sets the reload function of the config file. This
function will be called upon its config file being reloaded.
* The third function stores the array handle for use by other parts of the
module.
*/
/**
* The max length of any config string value.
*/
@ -22,23 +110,31 @@
#define CONFIG_FILE_ALIAS_DOWNLOADS "downloads"
#define CONFIG_FILE_ALIAS_CLASSES "classes"
#define CONFIG_FILE_ALIAS_WEAPONS "weapons"
#define CONFIG_FILE_ALIAS_WEAPONGROUPS "weapongroups"
#define CONFIG_FILE_ALIAS_HITGROUPS "hitgroups"
/**
* @endsection
*/
/**
* List of config formats used by the plugin.
*/
enum ConfigStructure
{
Structure_List, /** Config is structured as a simple list of strings. */
Structure_Keyvalue, /** Config is a keyvalue structure */
}
/**
* List of config files used by the plugin.
*/
enum ConfigFile
{
ConfigInvalid = -1, /** Invalid config file. */
ConfigModels, /** <sourcemod root>/configs/zr/models.txt (default) */
ConfigDownloads, /** <sourcemod root>/configs/zr/downloads.txt (default) */
ConfigClasses, /** <sourcemod root>/configs/zr/playerclasses.txt (default) */
ConfigWeapons, /** <sourcemod root>/configs/zr/weapons/weapons.txt/weapongroups.txt (default) */
ConfigHitgroups, /** <sourcemod root>/configs/zr/hitgroups.txt (default) */
File_Invalid = -1, /** Invalid config file. */
File_Models, /** <sourcemod root>/configs/zr/models.txt (default) */
File_Downloads, /** <sourcemod root>/configs/zr/downloads.txt (default) */
File_Classes, /** <sourcemod root>/configs/zr/playerclasses.txt (default) */
File_Weapons, /** <sourcemod root>/configs/zr/weapons.txt (default) */
File_Hitgroups, /** <sourcemod root>/configs/zr/hitgroups.txt (default) */
}
/**
@ -46,11 +142,12 @@ enum ConfigFile
*/
enum ConfigData
{
bool:ConfigLoaded, /** True if config is loaded, false if not. */
Function:ConfigReloadFunc, /** Function to call to reload config. */
Handle:ConfigHandle, /** Handle of the config file. */
String:ConfigPath[PLATFORM_MAX_PATH], /** Full path to config file. */
String:ConfigAlias[CONFIG_MAX_LENGTH], /** Config file alias, used for client interaction. */
bool: Data_Loaded, /** True if config is loaded, false if not. */
ConfigStructure: Data_Structure, /** Format of the config */
Function: Data_ReloadFunc, /** Function to call to reload config. */
Handle: Data_Handle, /** Handle of the config file. */
String: Data_Path[PLATFORM_MAX_PATH], /** Full path to config file. */
String: Data_Alias[CONFIG_MAX_LENGTH], /** Config file alias, used for client interaction. */
}
/**
@ -61,32 +158,22 @@ new g_ConfigData[ConfigFile][ConfigData];
/**
* Actions to use when working on key/values.
*/
enum ConfigKeyvalueAction
enum ConfigKvAction
{
ConfigKVCreate, /** Create a key. */
ConfigKVDelete, /** Delete a key. */
ConfigKVSet, /** Modify setting of a key. */
ConfigKVGet, /** Get setting of a key. */
KvAction_Create, /** Create a key. */
KvAction_KVDelete, /** Delete a key. */
KvAction_KVSet, /** Modify setting of a key. */
KvAction_KVGet, /** Get setting of a key. */
}
/**
* @section Global data handle initializations.
*/
new Handle:arrayModelsList = INVALID_HANDLE;
new Handle:arrayDownloadsList = INVALID_HANDLE;
new Handle:kvClassData = INVALID_HANDLE;
new Handle:kvWeapons = INVALID_HANDLE;
new Handle:kvWeaponGroups = INVALID_HANDLE;
new Handle:kvHitgroups = INVALID_HANDLE;
/**
* Create commands related to config here.
*/
ConfigOnCommandsCreate()
{
// Create config admin commands.
RegAdminCmd("zr_reloadconfig", ConfigReloadCommand, ADMFLAG_GENERIC, "zr_reloadconfig <file alias> - Reloads a config file.");
RegAdminCmd("zr_reloadconfigall", ConfigReloadAllCommand, ADMFLAG_GENERIC, "zr_reloadconfigall - Reloads all config files.");
RegAdminCmd("zr_config_reload", ConfigReloadCommand, ADMFLAG_GENERIC, "Reloads a config file. Usage: zr_config_reload <file alias>");
RegAdminCmd("zr_config_reloadall", ConfigReloadAllCommand, ADMFLAG_GENERIC, "Reloads all config files. Usage: zr_config_reloadall");
}
/**
@ -157,20 +244,20 @@ ConfigOnModulesLoaded()
/**
* Used by modules that rely on configs to register their config file info.
* (Don't forget to set 'loaded' to 'true' (ConfigSetConfigLoaded) in config load function)
*
* @param file Config file entry to register.
* @param loaded True if the config should be loaded, false if not.
* @param path (Optional) Full path to config file.
* @param alias (Optional) Config file alias, used for client interaction.
* @param alias Config file alias, used for client interaction.
*/
stock ConfigRegisterConfig(ConfigFile:file, bool:loaded, Function:reloadfunc, Handle:filehandle = INVALID_HANDLE, const String:path[] = "", const String:alias[] = "")
stock ConfigRegisterConfig(ConfigFile:file, ConfigStructure:structure, const String:alias[] = "")
{
// Copy file info to data container.
g_ConfigData[file][ConfigLoaded] = loaded;
g_ConfigData[file][ConfigHandle] = filehandle;
g_ConfigData[file][ConfigReloadFunc] = reloadfunc;
strcopy(g_ConfigData[file][ConfigPath], PLATFORM_MAX_PATH, path);
strcopy(g_ConfigData[file][ConfigAlias], CONFIG_MAX_LENGTH, alias);
g_ConfigData[file][Data_Loaded] = false;
g_ConfigData[file][Data_Structure] = structure;
g_ConfigData[file][Data_Handle] = INVALID_HANDLE;
g_ConfigData[file][Data_ReloadFunc] = INVALID_FUNCTION;
strcopy(g_ConfigData[file][Data_Path], PLATFORM_MAX_PATH, "");
strcopy(g_ConfigData[file][Data_Alias], CONFIG_MAX_LENGTH, alias);
}
/**
@ -182,7 +269,19 @@ stock ConfigRegisterConfig(ConfigFile:file, bool:loaded, Function:reloadfunc, Ha
stock ConfigSetConfigLoaded(ConfigFile:config, bool:loaded)
{
// Set load state.
g_ConfigData[config][ConfigLoaded] = loaded;
g_ConfigData[config][Data_Loaded] = loaded;
}
/**
* Set the structure type of a config file entry.
*
* @param config Config file to set structure type of.
* @param structure Structure to set as.
*/
stock ConfigSetConfigStructure(ConfigFile:config, ConfigStructure:structure)
{
// Set load state.
g_ConfigData[config][Data_Structure] = structure;
}
/**
@ -194,7 +293,7 @@ stock ConfigSetConfigLoaded(ConfigFile:config, bool:loaded)
stock ConfigSetConfigReloadFunc(ConfigFile:config, Function:reloadfunc)
{
// Set reload function.
g_ConfigData[config][ConfigReloadFunc] = reloadfunc;
g_ConfigData[config][Data_ReloadFunc] = reloadfunc;
}
/**
@ -206,7 +305,7 @@ stock ConfigSetConfigReloadFunc(ConfigFile:config, Function:reloadfunc)
stock ConfigSetConfigHandle(ConfigFile:config, Handle:file)
{
// Set file handle.
g_ConfigData[config][ConfigHandle] = file;
g_ConfigData[config][Data_Handle] = file;
}
/**
@ -218,7 +317,7 @@ stock ConfigSetConfigHandle(ConfigFile:config, Handle:file)
stock ConfigSetConfigPath(ConfigFile:config, const String:path[])
{
// Set config file path.
strcopy(g_ConfigData[config][ConfigPath], PLATFORM_MAX_PATH, path);
strcopy(g_ConfigData[config][Data_Path], PLATFORM_MAX_PATH, path);
}
/**
@ -230,7 +329,7 @@ stock ConfigSetConfigPath(ConfigFile:config, const String:path[])
stock ConfigSetConfigAlias(ConfigFile:config, const String:alias[])
{
// Set config alias.
strcopy(g_ConfigData[config][ConfigAlias], CONFIG_MAX_LENGTH, alias);
strcopy(g_ConfigData[config][Data_Alias], CONFIG_MAX_LENGTH, alias);
}
/**
@ -242,7 +341,19 @@ stock ConfigSetConfigAlias(ConfigFile:config, const String:alias[])
stock bool:ConfigIsConfigLoaded(ConfigFile:config)
{
// Return load status.
return g_ConfigData[config][ConfigLoaded];
return g_ConfigData[config][Data_Loaded];
}
/**
* Returns config's structure type.
*
* @param config Config file to get structure type of.
* @return Config structure type.
*/
stock ConfigStructure:ConfigGetConfigStructure(ConfigFile:config)
{
// Return load status.
return g_ConfigData[config][Data_Structure];
}
/**
@ -254,7 +365,7 @@ stock bool:ConfigIsConfigLoaded(ConfigFile:config)
stock Function:ConfigGetConfigReloadFunc(ConfigFile:config)
{
// Return load status.
return g_ConfigData[config][ConfigReloadFunc];
return g_ConfigData[config][Data_ReloadFunc];
}
/**
@ -266,7 +377,7 @@ stock Function:ConfigGetConfigReloadFunc(ConfigFile:config)
stock Handle:ConfigGetConfigHandle(ConfigFile:config)
{
// Return load status.
return g_ConfigData[config][ConfigHandle];
return g_ConfigData[config][Data_Handle];
}
/**
@ -277,7 +388,7 @@ stock Handle:ConfigGetConfigHandle(ConfigFile:config)
stock ConfigGetConfigPath(ConfigFile:config, String:path[], maxlen)
{
// Copy path to return string.
strcopy(path, maxlen, g_ConfigData[config][ConfigPath]);
strcopy(path, maxlen, g_ConfigData[config][Data_Path]);
}
/**
@ -288,7 +399,131 @@ stock ConfigGetConfigPath(ConfigFile:config, String:path[], maxlen)
stock ConfigGetConfigAlias(ConfigFile:config, String:alias[], maxlen)
{
// Copy alias to return string.
strcopy(alias, maxlen, g_ConfigData[config][ConfigAlias]);
strcopy(alias, maxlen, g_ConfigData[config][Data_Alias]);
}
/**
* Loads a config file and sets up a nested array type data storage.
*
* @param config The config file to load.
* @param arrayConfig Handle of the main array containing file data.
* @return True if file was loaded successfuly, false otherwise.
*/
stock bool:ConfigLoadConfig(ConfigFile:config, &Handle:arrayConfig)
{
// Get config's structure.
new ConfigStructure:structure = ConfigGetConfigStructure(config);
// Get config's alias
decl String:configalias[CONFIG_MAX_LENGTH];
ConfigGetConfigAlias(config, configalias, sizeof(configalias));
// Get config's file path.
decl String:configpath[PLATFORM_MAX_PATH];
ConfigGetConfigPath(config, configpath, sizeof(configpath));
// If handle is still open, then close it before creating a new one.
if (arrayConfig == INVALID_HANDLE)
{
// 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 +532,7 @@ stock ConfigGetConfigAlias(ConfigFile:config, String:alias[], maxlen)
* @param config The config file entry to reload.
* @return True if the config is loaded, false if not.
*/
stock bool:ConfigReloadFile(ConfigFile:config)
stock bool:ConfigReloadConfig(ConfigFile:config)
{
// If file isn't loaded, then stop.
new bool:loaded = ConfigIsConfigLoaded(config);
@ -309,6 +544,7 @@ stock bool:ConfigReloadFile(ConfigFile:config)
// Call reload function
new Function:reloadfunc = ConfigGetConfigReloadFunc(config);
// This should never be true unless someone has tampered with the code.
if (reloadfunc == INVALID_FUNCTION)
{
// Get config alias.
@ -323,12 +559,169 @@ stock bool:ConfigReloadFile(ConfigFile:config)
// Call reload function.
Call_StartFunction(GetMyHandle(), reloadfunc);
Call_PushCell(config);
Call_Finish();
return true;
}
/**
* Opens a config file with appropriate method.
*
* @param config The config file.
* @param structure The structure of the config file.
* @param hConfig The handle of the opened file.
*/
stock bool:ConfigOpenConfigFile(ConfigFile:config, &Handle:hConfig)
{
// Get config's structure
new ConfigStructure:structure = ConfigGetConfigStructure(config);
// Get config's file path.
decl String:configpath[PLATFORM_MAX_PATH];
ConfigGetConfigPath(config, configpath, sizeof(configpath));
// Get config's alias
decl String:configalias[CONFIG_MAX_LENGTH];
ConfigGetConfigAlias(config, configalias, sizeof(configalias));
switch(structure)
{
case Structure_List:
{
// Open file.
hConfig = OpenFile(configpath, "r");
// If file couldn't be opened, then stop.
if (hConfig == INVALID_HANDLE)
{
return false;
}
return true;
}
case Structure_Keyvalue:
{
hConfig = CreateKeyValues(configalias);
return FileToKeyValues(hConfig, configpath);
}
}
return false;
}
/**
* Creates, deletes, sets, or gets any key/setting of any ZR config keyvalue file in memory.
* Only use when interacting with a command or manipulating single keys/values,
* using this function everywhere would be EXTREMELY inefficient.
*
* @param config Config file to modify.
* @param action Action to perform on keyvalue tree. (see enum ConfigKeyvalueAction)
* @param keys Array containing keys to traverse into.
* @param keysMax The size of the 'keys' array.
* @param setting (Optional) The name of the setting to modify.
* @param value (Optional) The new value to set.
* @param maxlen (Optional) The maxlength of the retrieved value.
* @return True if the change was made successfully, false otherwise.
*/
stock bool:ConfigKeyvalueTreeSetting(ConfigFile:config, ConfigKvAction:action = KvAction_Create, const String:keys[][], keysMax, const String:setting[] = "", String:value[] = "", maxlen = 0)
{
// Get config file's structure.
new ConfigStructure:structure = ConfigGetConfigStructure(config);
// If the config is any other structure beside keyvalue, then stop.
if (structure != Structure_Keyvalue)
{
return false;
}
// Retrieve handle of the keyvalue tree.
new Handle:hConfig;
new bool:success = ConfigOpenConfigFile(config, hConfig);
// If the file couldn't be opened, then stop.
if (!success)
{
return false;
}
// Rewind keyvalue tree.
KvRewind(hConfig);
// x = keys index.
// Traverse into the keygroup, stop if it fails.
for (new x = 0; x < keysMax; x++)
{
// If key is empty, then break the loop.
if (!keys[x][0])
{
break;
}
// Try to jump to next level in the transversal stack, create key if specified.
new bool:exists = KvJumpToKey(hConfig, keys[x], (action == KvAction_Create));
// If exists is false, then stop.
if (!exists)
{
// Key doesn't exist.
return false;
}
}
switch(action)
{
case KvAction_Create:
{
if (!setting[0] || !value[0])
{
// We created the key already, so return true.
return true;
}
// Set new value.
KvSetString(hConfig, setting, value);
}
case KvAction_Delete:
{
// Return deletion result.
return KvDeleteKey(hConfig, setting);
}
case KvAction_Set:
{
// Set new value.
KvSetString(hConfig, setting, value);
}
case KvAction_Get:
{
// Get current value.
KvGetString(hConfig, setting, value, maxlen);
}
}
// We successfully set or got the value.
return true;
}
/**
* Destroy all array handles within an array, and clear main array.
*
* @param arrayKv The array converted from a keyvalue structure.
*/
ConfigClearKvArray(Handle:arrayKv)
{
// x = array index
new size = GetArraySize(arrayKv);
for (new x = 0; x < size; x++)
{
// Destroy nested arrays.
new Handle:arrayKvKey = GetArrayCell(arrayKv, x);
CloseHandle(arrayKvKey);
}
// Now that all data within has been destroyed, we can clear the main array.
ClearArray(arrayKv);
}
/**
* Load config file.
*
@ -374,94 +767,11 @@ stock ConfigFile:ConfigAliasToConfigFile(const String:alias[])
}
// Invalid config file.
return ConfigInvalid;
return File_Invalid;
}
/**
* Creates, deletes, sets, or gets any key/setting of any ZR config keyvalue file in memory.
* Only use when interacting with a command or manipulating single keys/values,
* using this function everywhere would be EXTREMELY inefficient.
*
* @param config Config index of config to modify. (see CONFIG_FILE_* defines)
* @param action Action to perform on keyvalue tree. (see enum ConfigKeyvalueAction)
* @param keys Array containing keys to traverse into.
* @param keysMax The size of the 'keys' array.
* @param setting (Optional) The name of the setting to modify.
* @param value (Optional) The new value to set.
* @param maxlen (Optional) The maxlength of the gotten value.
* @return True if the change was made successfully, false otherwise.
*/
stock bool:ConfigKeyvalueTreeSetting(config, ConfigKeyvalueAction:action = ConfigKVCreate, const String:keys[][], keysMax, const String:setting[] = "", String:value[] = "", maxlen = 0)
{
// Retrieve handle of the keyvalue tree.
new Handle:hConfig = ConfigGetConfigHandle(config);
// If handle is invalid, then stop.
if (hConfig == INVALID_HANDLE)
{
return false;
}
// Rewind keyvalue tree.
KvRewind(hConfig);
// x = keys index.
// Traverse into the keygroup, stop if it fails.
for (new x = 0; x < keysMax; x++)
{
// If key is empty, then break the loop.
if (!keys[x][0])
{
break;
}
// Try to jump to next level in the transversal stack, create key if specified.
new bool:exists = KvJumpToKey(hConfig, keys[x], (action == Create));
// If exists is false, then stop.
if (!exists)
{
// Key doesn't exist.
return false;
}
}
switch(action)
{
case ConfigKVCreate:
{
if (!setting[0] || !value[0])
{
// We created the key already, so return true.
return true;
}
// Set new value.
KvSetString(hConfig, setting, value);
}
case ConfigKVDelete:
{
// Return deletion result.
return KvDeleteKey(hConfig, setting);
}
case ConfigKVSet:
{
// Set new value.
KvSetString(hConfig, setting, value);
}
case ConfigKVGet:
{
// Get current value.
KvGetString(hConfig, setting, value, maxlen);
}
}
// We successfully set or got the value.
return true;
}
/**
* Command callback (zr_reloadconfig)
* Command callback (zr_config_reload)
* Reloads a config file and forwards event to modules.
*
* @param client The client index.
@ -472,7 +782,7 @@ public Action:ConfigReloadCommand(client, argc)
// If not enough arguments given, then stop.
if (argc < 1)
{
TranslationReplyToCommand(client, "Config command reload syntax", CONFIG_FILE_ALIAS_MODELS, CONFIG_FILE_ALIAS_DOWNLOADS, CONFIG_FILE_ALIAS_CLASSES, CONFIG_FILE_ALIAS_WEAPONS, CONFIG_FILE_ALIAS_WEAPONGROUPS, CONFIG_FILE_ALIAS_HITGROUPS);
TranslationReplyToCommand(client, "Config command reload syntax", CONFIG_FILE_ALIAS_MODELS, CONFIG_FILE_ALIAS_DOWNLOADS, CONFIG_FILE_ALIAS_CLASSES, CONFIG_FILE_ALIAS_WEAPONS, CONFIG_FILE_ALIAS_HITGROUPS);
return Plugin_Handled;
}
@ -482,14 +792,14 @@ public Action:ConfigReloadCommand(client, argc)
// If alias is invalid, then stop.
new ConfigFile:config = ConfigAliasToConfigFile(arg1);
if (config == ConfigInvalid)
if (config == File_Invalid)
{
TranslationReplyToCommand(client, "Config command reload invalid", arg1);
return Plugin_Handled;
}
// Reload config file.
new bool:loaded = ConfigReloadFile(config);
new bool:loaded = ConfigReloadConfig(config);
// Get config file path.
decl String:path[PLATFORM_MAX_PATH];
@ -506,7 +816,7 @@ public Action:ConfigReloadCommand(client, argc)
}
/**
* Command callback (zr_reloadconfigall)
* Command callback (zr_config_reloadall)
* Reloads all config files and forwards event to all modules.
*
* @param client The client index.
@ -523,7 +833,7 @@ public Action:ConfigReloadAllCommand(client, argc)
for (new x = 0; x < sizeof(g_ConfigData); x++)
{
// Reload config file.
new bool:successful = ConfigReloadFile(ConfigFile:x);
new bool:successful = ConfigReloadConfig(ConfigFile:x);
// Get config's alias.
ConfigGetConfigAlias(ConfigFile:x, configalias, sizeof(configalias));
@ -539,71 +849,13 @@ public Action:ConfigReloadAllCommand(client, argc)
}
}
/**
* Iterate through a file and store each line in an array.
*
* @param path Path to the file to iterate through.
* @return The handle of the array, don't forget to call CloseHandle
* on it when finished!
*/
Handle:ConfigLinesToArray(const String:path[])
{
new Handle:arrayLines = CreateArray(PLATFORM_MAX_PATH);
decl String:line[PLATFORM_MAX_PATH];
// Open file.
new Handle:hFile = OpenFile(path, "r");
// If file couldn't be opened, then stop.
if (hFile == INVALID_HANDLE)
{
return INVALID_HANDLE;
}
while(!IsEndOfFile(hFile))
{
// Get current line text.
ReadFileLine(hFile, line, sizeof(line));
// If line contains a ";", then stop.
if (StrContains(line, ";") > -1)
{
continue;
}
// Cut out comments at the end of a line.
if (StrContains(line, "//") > -1)
{
SplitString(line, "//", line, sizeof(line));
}
// Trim off whitespace.
TrimString(line);
// If line is empty, then stop.
if (!line[0])
{
continue;
}
// Push line into array.
PushArrayString(arrayLines, line);
}
// Close file handle.
CloseHandle(hFile);
// Return array handle.
return arrayLines;
}
/**
* Converts string of "yes" or "no" to a boolean value.
*
* @param option "yes" or "no" string to be converted.
* @return True if string is "yes", false otherwise.
*/
bool:ConfigSettingToBool(const String:option[])
stock bool:ConfigSettingToBool(const String:option[])
{
// If option is equal to "yes," then return true.
if (StrEqual(option, "yes", false))
@ -620,9 +872,9 @@ bool:ConfigSettingToBool(const String:option[])
*
* @param bOption True/false value to be converted to "yes"/"no", respectively.
* @param option Destination string buffer to store "yes" or "no" in.
* @param maxlen Length of destination string buffer (can't be more than 4).
* @param maxlen Length of destination string buffer (wont't be more than 4).
*/
ConfigBoolToSetting(bool:bOption, String:option[], maxlen)
stock ConfigBoolToSetting(bool:bOption, String:option[], maxlen)
{
// If option is true, then copy "yes" to return string.
if (bOption)
@ -635,3 +887,11 @@ ConfigBoolToSetting(bool:bOption, String:option[], maxlen)
strcopy(option, maxlen, "no");
}
}
stock bool:ConfigKvGetStringBool(Handle:kv, const String:key[], const String:defaultvalue[] = "yes")
{
decl String:value[CONFIG_MAX_LENGTH];
KvGetString(kv, key, value, sizeof(value), defaultvalue);
return ConfigSettingToBool(value);
}

View File

@ -38,7 +38,6 @@ enum CvarsList
Handle:CVAR_CONFIG_PATH_DOWNLOADS,
Handle:CVAR_CONFIG_PATH_CLASSES,
Handle:CVAR_CONFIG_PATH_WEAPONS,
Handle:CVAR_CONFIG_PATH_WEAPONGROUPS,
Handle:CVAR_CONFIG_PATH_HITGROUPS,
Handle:CVAR_CLASSES_SPAWN,
Handle:CVAR_CLASSES_RANDOM,
@ -51,6 +50,7 @@ enum CvarsList
Handle:CVAR_CLASSES_OVERLAY_DEFAULT,
Handle:CVAR_WEAPONS,
Handle:CVAR_WEAPONS_RESTRICT,
Handle:CVAR_WEAPONS_ZMARKET,
Handle:CVAR_WEAPONS_ZMARKET_BUYZONE,
Handle:CVAR_HITGROUPS,
Handle:CVAR_DAMAGE_HITGROUPS,
@ -211,8 +211,7 @@ CvarsCreate()
g_hCvarsList[CVAR_CONFIG_PATH_MODELS] = CreateConVar("zr_config_path_models", "configs/zr/models.txt", "Path, relative to root sourcemod directory, to models config file.");
g_hCvarsList[CVAR_CONFIG_PATH_DOWNLOADS] = CreateConVar("zr_config_path_downloads", "configs/zr/downloads.txt", "Path, relative to root sourcemod directory, to downloads file.");
g_hCvarsList[CVAR_CONFIG_PATH_CLASSES] = CreateConVar("zr_config_path_playerclasses", "configs/zr/playerclasses.txt", "Path, relative to root sourcemod directory, to playerclasses config file.");
g_hCvarsList[CVAR_CONFIG_PATH_WEAPONS] = CreateConVar("zr_config_path_weapons", "configs/zr/weapons/weapons.txt", "Path, relative to root sourcemod directory, to weapons config file.");
g_hCvarsList[CVAR_CONFIG_PATH_WEAPONGROUPS] = CreateConVar("zr_config_path_weapongroups", "configs/zr/weapons/weapongroups.txt", "Path, relative to root sourcemod directory, to weapongroups config file.");
g_hCvarsList[CVAR_CONFIG_PATH_WEAPONS] = CreateConVar("zr_config_path_weapons", "configs/zr/weapons.txt", "Path, relative to root sourcemod directory, to weapons config file.");
g_hCvarsList[CVAR_CONFIG_PATH_HITGROUPS] = CreateConVar("zr_config_path_hitgroups", "configs/zr/hitgroups.txt", "Path, relative to root sourcemod directory, to hitgroups config file.");
@ -260,8 +259,9 @@ CvarsCreate()
// Restrict
g_hCvarsList[CVAR_WEAPONS_RESTRICT] = CreateConVar("zr_weapons_restrict", "1", "Enable weapon restriction module, disabling this will disable weapon restriction commands.");
// Market Handler
g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE] = CreateConVar("zr_weapons_zmarket_buyzone", "1", "Requires player to be inside a buyzone to use ZMarket.");
// 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]");
// ===========================

View File

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

View File

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

View File

@ -72,6 +72,7 @@ public Action:EventRoundStart(Handle:event, const String:name[], bool:dontBroadc
// Forward event to sub-modules.
OverlaysOnRoundStart();
WeaponsOnRoundStart();
RoundStartOnRoundStart();
RoundEndOnRoundStart();
InfectOnRoundStart();
SEffectsOnRoundStart();
@ -90,8 +91,6 @@ public Action:EventRoundStart(Handle:event, const String:name[], bool:dontBroadc
*/
public Action:EventRoundFreezeEnd(Handle:event, const String:name[], bool:dontBroadcast)
{
RemoveObjectives();
// Forward events to modules.
RoundEndOnRoundFreezeEnd();
InfectOnRoundFreezeEnd();
@ -154,32 +153,9 @@ public Action:EventPlayerSpawn(Handle:event, const String:name[], bool:dontBroad
// Get all required event info.
new index = GetClientOfUserId(GetEventInt(event, "userid"));
// Reset FOV and overlay.
ToolsSetClientDefaultFOV(index, 90);
ClientCommand(index, "r_screenoverlay \"\"");
// Check if client is on a team.
if (ZRIsClientOnTeam(index))
{
// Turn off nightvision.
ToolsClientNightVision(index, false, false);
// Take nightvision away.
ToolsClientNightVision(index, false);
if (g_bZombieSpawned)
{
if (ZRIsClientOnTeam(index, CS_TEAM_T))
{
CS_SwitchTeam(index, CS_TEAM_CT);
CS_RespawnPlayer(index);
}
}
}
// Forward event to modules.
InfectOnClientSpawn(index);
ClassOnClientSpawn(index); // Module event depends on infect module.
InfectOnClientSpawn(index); // Some modules depend on this to finish first.
ClassOnClientSpawn(index);
RestrictOnClientSpawn(index);
SEffectsOnClientSpawn(index);
AccountOnClientSpawn(index);
@ -267,28 +243,14 @@ public Action:EventPlayerDeath(Handle:event, const String:name[], bool:dontBroad
new index = GetClientOfUserId(GetEventInt(event, "userid"));
new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
// Extinguish any flames to stop burning sounds.
ExtinguishEntity(index);
// If the attacker is valid, then continue.
if (ZRIsClientValid(attacker))
{
// If the client is a zombie, then continue.
if (InfectIsClientInfected(index))
{
// Add kill bonus to attacker's score.
new bonus = ClassGetKillBonus(attacker);
new score = ToolsClientScore(index, true, false);
ToolsClientScore(index, true, true, score + bonus);
}
}
// Forward event to modules.
ClassOnClientDeath(index);
RoundEndOnClientDeath();
InfectOnClientDeath(index, attacker);
SEffectsOnClientDeath(index);
SpawnProtectOnClientDeath(index);
RespawnOnClientDeath(index, attacker, weapon);
NapalmOnClientDeath(index);
ZSpawnOnClientDeath(index);
ZTeleOnClientDeath(index);
ZHPOnClientDeath(index);

View File

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

View File

@ -213,6 +213,48 @@ InfectOnClientSpawn(client)
{
// Disable zombie flag on client.
bZombie[client] = false;
// Check if client is spawning on the terrorist team.
if (ZRIsClientOnTeam(client, CS_TEAM_T))
{
if (g_bZombieSpawned)
{
CS_SwitchTeam(client, CS_TEAM_CT);
CS_RespawnPlayer(client);
}
}
}
/**
* Client has been killed.
*
* @param client The client index.
* @param attacker The attacker index.
*/
InfectOnClientDeath(client, attacker)
{
// If attacker isn't valid, then stop.
if (!ZRIsClientValid(attacker))
{
return;
}
// If attacker isn't a human, then stop.
if (!InfectIsClientHuman(attacker))
{
return;
}
// If client isn't a zombie, then stop.
if (!InfectIsClientInfected(client))
{
return;
}
// Add kill bonus to attacker's score.
new bonus = ClassGetKillBonus(client);
new score = ToolsClientScore(attacker, true, false);
ToolsClientScore(attacker, true, true, score + bonus);
}
/** Client has been hurt.
@ -348,7 +390,7 @@ public Action:InfectMotherZombie(Handle:timer)
new client;
// Prune list of immune clients.
// x = array index.
// x = Array index.
// client = client index.
for (new x = 0; x < eligibleclients; x++)
{
@ -480,7 +522,7 @@ InfectClient(client, attacker = -1, bool:motherinfect = false)
bZombie[client] = true;
// Get a list of all client's weapon indexes.
new weapons[WeaponsType];
new weapons[WeaponsSlot];
WeaponsGetClientWeapons(client, weapons);
// Check if weapons drop is enabled.
@ -499,7 +541,7 @@ InfectClient(client, attacker = -1, bool:motherinfect = false)
if (weaponsdrop)
{
// If this is the knife slot, then stop.
if (WeaponsType:x == Type_Melee)
if (WeaponsSlot:x == Slot_Melee)
{
continue;
}
@ -515,7 +557,7 @@ InfectClient(client, attacker = -1, bool:motherinfect = false)
}
// If client has no knife, give them one.
if (GetPlayerWeaponSlot(client, _:Type_Melee) == -1)
if (GetPlayerWeaponSlot(client, _:Slot_Melee) == -1)
{
GivePlayerItem(client, "weapon_knife");
}

View File

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

View File

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

View File

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

View File

@ -47,6 +47,17 @@ NapalmOnClientHurt(client, const String:weapon[])
}
}
/**
* Client has been killed.
*
* @param client The client index.
*/
NapalmOnClientDeath(client)
{
// Extinguish any flames to stop burning sounds.
ExtinguishEntity(client);
}
/**
* Weapon has been fired.
*

View File

@ -164,6 +164,7 @@ OverlaysClientUpdateOverlay(client, OverlaysChannel:channel = OVERLAYS_CHANNEL_N
{
channel = OverlaysClientFindChannel(client);
}
// Stop here if client has no overlay channel enabled.
if (channel == OVERLAYS_CHANNEL_NONE)
{
@ -172,6 +173,12 @@ OverlaysClientUpdateOverlay(client, OverlaysChannel:channel = OVERLAYS_CHANNEL_N
return;
}
// If channel we are updating is disabled, then stop.
if (!g_bOverlayChannel[client][channel])
{
return;
}
// If dxLevel is 0, then query on client failed, so try again, then stop.
if (!g_iOverlaysDXL[client])
{

View File

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

View File

@ -9,10 +9,30 @@
* ============================================================================
*/
ClassOnCommandsCreate()
{
// Create base class commands.
RegConsoleCmd("zr_class_dump", ClassDumpCommand, "Dumps class data at a specified index in the specified cache. Usage: zr_class_dump <cachetype> <index|targetname>");
RegAdminCmd("zr_class_modify", ClassModifyCommand, ADMFLAG_GENERIC, "Modify class data on one or more classes. Usage: zr_class_modify <classname|\"zombies\"|\"humans\"|\"admins\"> <attribute> <value> [is_multiplier]");
}
/**
* Dumps class data at a specified index in the specified cache.
* Hook commands related to classes here.
*/
public Action:Command_ClassDump(client, argc)
ClassOnCommandsHook()
{
// Forward event to sub-modules.
ClassOverlayOnCommandsHook();
}
/**
* Command callback. (zr_class_dump)
* Dumps class data at a specified index in the specified cache.
*
* @param client The client index.
* @param argc Argument count.
*/
public Action:ClassDumpCommand(client, argc)
{
decl String:syntax[1024];
syntax[0] = 0;
@ -124,7 +144,7 @@ public Action:Command_ClassDump(client, argc)
* Note: Original values are retrieved from the original class cache, not the
* modified class cache.
*/
public Action:Command_ClassModify(client, argc)
public Action:ClassModifyCommand(client, argc)
{
decl String:syntax[1024];
syntax[0] = 0;
@ -335,7 +355,7 @@ public Action:Command_ClassModify(client, argc)
* @param value New value to set.
* @return True on success, false otherwise.
*/
bool:ClassModifyBoolean(classindex, attributeflag, bool:value)
stock bool:ClassModifyBoolean(classindex, attributeflag, bool:value)
{
// Validate class index.
if (!ClassValidateIndex(classindex))
@ -378,7 +398,7 @@ bool:ClassModifyBoolean(classindex, attributeflag, bool:value)
* disable. Value is ignored if this is non-zero.
* @return True on success, false otherwise.
*/
ClassModifyInteger(classindex, attributeflag, value, Float:multiplier = 0.0)
stock ClassModifyInteger(classindex, attributeflag, value, Float:multiplier = 0.0)
{
// Validate class index.
if (!ClassValidateIndex(classindex))
@ -481,7 +501,7 @@ ClassModifyInteger(classindex, attributeflag, value, Float:multiplier = 0.0)
* Not all attributes support multipliers.
* @return True on success, false otherwise.
*/
ClassModifyFloat(classindex, attributeflag, Float:value, bool:ismultiplier = false)
stock ClassModifyFloat(classindex, attributeflag, Float:value, bool:ismultiplier = false)
{
// Validate class index.
if (!ClassValidateIndex(classindex))
@ -568,7 +588,7 @@ ClassModifyFloat(classindex, attributeflag, Float:value, bool:ismultiplier = fal
* @param value New value to set.
* @return True on success, false otherwise.
*/
ClassModifyString(classindex, attributeflag, const String:value[])
stock ClassModifyString(classindex, attributeflag, const String:value[])
{
// Validate class index.
if (!ClassValidateIndex(classindex))

View File

@ -34,15 +34,6 @@ ClassClientInit(client)
ClassOverlayClientInit(client);
}
/**
* Hook commands related to classes here.
*/
ClassOnCommandsHook()
{
// Forward event to sub-modules.
ClassOverlayOnCommandsHook();
}
/**
* Called when all modules are done loading.
*/
@ -108,7 +99,6 @@ ClassOnClientSpawn(client)
// Check if the player should spawn in admin mode.
if (ClassPlayerAdminMode[client])
{
// Mark player as in admin mode.
ClassPlayerInAdminMode[client] = true;
@ -137,11 +127,11 @@ ClassOnClientDeath(client)
// Disable class attributes with timers.
ClassHealthRegenStop(client);
// Disable overlay.
OverlaysClientSetChannelState(client, OVERLAYS_CHANNEL_CLASSES, true, false, false, true);
// Set client's FOV back to normal.
ToolsSetClientDefaultFOV(client, 90);
// Forward event to sub-modules.
ClassOverlayOnClientDeath(client);
}
ClassOnClientInfected(client, bool:motherzombie = false)

View File

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

View File

@ -54,7 +54,7 @@ ClassOverlayOnCommandsHook()
// Explode string into array indexes.
new cmdcount = ExplodeString(togglecmds, ", ", arrayCmds, CLASSOVERLAY_TOGGLE_MAX_CMDS, CLASSOVERLAY_TOGGLE_MAX_LENGTH);
// x = array index.
// x = Array index.
// arrayCmds[x] = suicide command.
for (new x = 0; x <= cmdcount - 1; x++)
{
@ -83,6 +83,20 @@ ClassOverlayOnClientSpawn(client)
TranslationPrintHUDText(client, "Classes overlay toggle", togglecmds);
}
// Update class overlay.
OverlaysClientUpdateOverlay(client, OVERLAYS_CHANNEL_CLASSES);
}
/**
* Client has been killed.
*
* @param client The client index.
*/
ClassOverlayOnClientDeath(client)
{
// Disable overlay.
OverlaysClientSetChannelState(client, OVERLAYS_CHANNEL_CLASSES, true, false, false, true);
}
/**
@ -127,7 +141,7 @@ ClassOverlayInitialize(client, const String:overlay[])
}
/**
* Command callback (See zr_classes_overlay_togglecmds)
* Command callback. (See zr_classes_overlay_togglecmds)
* Toggles nightvision of a client.
*
* @param client The client index.

View File

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

View File

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

58
src/zr/roundstart.inc Normal file
View File

@ -0,0 +1,58 @@
/*
* ============================================================================
*
* Zombie:Reloaded
*
* File: roundstart.inc
* Type: Core
* Description: Handles round start actions.
*
* ============================================================================
*/
/**
* List of objective entities.
*/
#define ROUNDSTART_OBJECTIVE_ENTITIES "func_bomb_target|func_hostage_rescue|c4|hostage_entity"
/**
* The round is starting.
*/
RoundStartOnRoundStart()
{
// Kill all objective entities.
RoundStartKillObjectives();
}
/**
* Kills all objective entities.
*/
RoundStartKillObjectives()
{
decl String:classname[64];
// Get max entity count.
new maxentities = GetMaxEntities();
// x = entity index.
for (new x = 0; x <= maxentities; x++)
{
// If entity isn't valid, then stop.
if(!IsValidEdict(x))
{
continue;
}
// Get valid edict's classname.
GetEdictClassname(x, classname, sizeof(classname));
// Check if it matches any objective entities, then stop if it doesn't.
if(StrContains(ROUNDSTART_OBJECTIVE_ENTITIES, classname) == -1)
{
continue;
}
// Entity is an objective, kill it.
RemoveEdict(x);
}
}

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

@ -10,9 +10,6 @@
* ============================================================================
*/
#include "include/adminmenu.inc"
//new curMenuClass[MAXPLAYERS + 1];
bool:ZRAdminMenu(client)
{
if (!ZRIsClientAdmin(client))
@ -27,35 +24,34 @@ bool:ZRAdminMenu(client)
SetMenuTitle(menu_zadmin, "%t\n ", "!zadmin main title");
decl String:knockbackm[64];
decl String:knockback[64];
decl String:nvgs[64];
decl String:infect[64];
decl String:zspawn[64];
decl String:ztele[64];
//decl String:knockbackm[64];
//decl String:knockback[64];
//decl String:infect[64];
//decl String:zspawn[64];
//decl String:ztele[64];
decl String:weapons[64];
decl String:logflags[64];
//decl String:logflags[64];
Format(knockbackm, sizeof(knockbackm), "%t", "!zadmin main knockbackm");
Format(knockback, sizeof(knockback), "%t", "!zadmin main knockback");
Format(nvgs, sizeof(nvgs), "%t", "!zadmin main nvgs");
Format(infect, sizeof(infect), "%t", "!zadmin main infect");
Format(zspawn, sizeof(zspawn), "%t", "!zadmin main spawn");
Format(ztele, sizeof(ztele), "%t", "!zadmin main tele");
//Format(knockbackm, sizeof(knockbackm), "%t", "!zadmin main knockbackm");
//Format(knockback, sizeof(knockback), "%t", "!zadmin main knockback");
//Format(infect, sizeof(infect), "%t", "!zadmin main infect");
//Format(zspawn, sizeof(zspawn), "%t", "!zadmin main spawn");
//Format(ztele, sizeof(ztele), "%t", "!zadmin main tele");
Format(weapons, sizeof(weapons), "%t", "!zadmin main weapons");
Format(logflags, sizeof(logflags), "%t", "!zadmin main logflags");
//Format(logflags, sizeof(logflags), "%t", "!zadmin main logflags");
AddMenuItem(menu_zadmin, "knockbackm", knockbackm, ITEMDRAW_DISABLED);
AddMenuItem(menu_zadmin, "knockback", knockback, ITEMDRAW_DISABLED);
AddMenuItem(menu_zadmin, "nvgs", nvgs, ITEMDRAW_DISABLED);
AddMenuItem(menu_zadmin, "infect", infect);
AddMenuItem(menu_zadmin, "zspawn", zspawn);
AddMenuItem(menu_zadmin, "ztele", ztele, ITEMDRAW_DISABLED);
//AddMenuItem(menu_zadmin, "knockbackm", knockbackm, ITEMDRAW_DISABLED);
//AddMenuItem(menu_zadmin, "knockback", knockback, ITEMDRAW_DISABLED);
//AddMenuItem(menu_zadmin, "infect", infect);
//AddMenuItem(menu_zadmin, "zspawn", zspawn);
//AddMenuItem(menu_zadmin, "ztele", ztele, ITEMDRAW_DISABLED);
AddMenuItem(menu_zadmin, "weapons", weapons);
AddMenuItem(menu_zadmin, "logflags", logflags);
//AddMenuItem(menu_zadmin, "logflags", logflags);
// Set "Back" button.
SetMenuExitBackButton(menu_zadmin, true);
// Send menu to client.
DisplayMenu(menu_zadmin, client, MENU_TIME_FOREVER);
return true;
@ -67,45 +63,21 @@ public ZRAdminMenuHandle(Handle:menu_admin, MenuAction:action, client, slot)
{
switch(slot)
{
// Weapon management.
case 0:
{
//ZRKnockbackMMenu(client);
}
case 1:
{
//ZRClassSelectMenu(client);
}
case 2:
{
//ZRNVGSMenu(client);
}
case 3:
{
ZRInfectMenu(client);
}
case 4:
{
ZRSpawnAll(client);
}
case 5:
{
ZRZTeleMenu(client);
}
case 6:
{
WeaponsMenuMain(client);
}
case 7:
{
ZRLogFlagsMenu(client);
}
}
// TODO: Resend menu if feature is disabled or unopenable.
}
if (action == MenuAction_Cancel)
{
if (slot == MenuCancel_ExitBack)
{
// Exit back to main menu.
MenuMain(client);
}
}
@ -145,9 +117,9 @@ public ZRAdminMenuHandle(Handle:menu_admin, MenuAction:action, client, slot)
SetMenuExitBackButton(menu_knockbackm, true);
DisplayMenu(menu_knockbackm, client, MENU_TIME_FOREVER);
}
}*/
public ZRKnockbackMHandle(Handle:menu_knockbackm, MenuAction:action, client, slot)
/*public ZRKnockbackMHandle(Handle:menu_knockbackm, MenuAction:action, client, slot)
{
if (action == MenuAction_Select)
{
@ -186,9 +158,9 @@ public ZRKnockbackMHandle(Handle:menu_knockbackm, MenuAction:action, client, slo
{
CloseHandle(menu_knockbackm);
}
}
}*/
ZRClassSelectMenu(client)
/*ZRClassSelectMenu(client)
{
new Handle:menu_class = CreateMenu(ZRClassSelectHandle);
@ -204,9 +176,9 @@ ZRClassSelectMenu(client)
SetMenuExitBackButton(menu_class, true);
DisplayMenu(menu_class, client, MENU_TIME_FOREVER);
}
}*/
public ZRClassSelectHandle(Handle:menu_class, MenuAction:action, client, slot)
/*public ZRClassSelectHandle(Handle:menu_class, MenuAction:action, client, slot)
{
if (action == MenuAction_Select)
{
@ -224,9 +196,9 @@ public ZRClassSelectHandle(Handle:menu_class, MenuAction:action, client, slot)
{
CloseHandle(menu_class);
}
}
}*/
ZRClassKnockbackMenu(client, classindex)
/*ZRClassKnockbackMenu(client, classindex)
{
new Handle:menu_knockback = CreateMenu(ZRClassKnockbackHandle);
@ -257,9 +229,9 @@ ZRClassKnockbackMenu(client, classindex)
SetMenuExitBackButton(menu_knockback, true);
DisplayMenu(menu_knockback, client, MENU_TIME_FOREVER);
}
}*/
public ZRClassKnockbackHandle(Handle:menu_knockback, MenuAction:action, client, slot)
/*public ZRClassKnockbackHandle(Handle:menu_knockback, MenuAction:action, client, slot)
{
if (action == MenuAction_Select)
{
@ -296,71 +268,9 @@ public ZRClassKnockbackHandle(Handle:menu_knockback, MenuAction:action, client,
{
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)
/*ZRInfectMenu(client)
{
new Handle:menu_infect = CreateMenu(ZRInfectHandle);
@ -373,9 +283,9 @@ ZRInfectMenu(client)
SetMenuExitBackButton(menu_infect, true);
DisplayMenu(menu_infect, client, MENU_TIME_FOREVER);
}
}*/
public ZRInfectHandle(Handle:menu_infect, MenuAction:action, client, slot)
/*public ZRInfectHandle(Handle:menu_infect, MenuAction:action, client, slot)
{
if (action == MenuAction_Select)
{
@ -417,9 +327,9 @@ public ZRInfectHandle(Handle:menu_infect, MenuAction:action, client, slot)
{
CloseHandle(menu_infect);
}
}
}*/
ZRSpawnAll(client)
/*ZRSpawnAll(client)
{
// x = client index.
for (new x = 1; x < MaxClients; x++)
@ -430,9 +340,9 @@ ZRSpawnAll(client)
}
}
ZRAdminMenu(client);
}
}*/
ZRZTeleMenu(client)
/*ZRZTeleMenu(client)
{
new Handle:menu_ztele = CreateMenu(ZRTeleHandle);
@ -457,9 +367,9 @@ ZRZTeleMenu(client)
SetMenuExitBackButton(menu_ztele, true);
DisplayMenu(menu_ztele, client, MENU_TIME_FOREVER);
}
}*/
public ZRTeleHandle(Handle:menu_ztele , MenuAction:action, client, slot)
/*public ZRTeleHandle(Handle:menu_ztele , MenuAction:action, client, slot)
{
if (action == MenuAction_Select)
{
@ -494,9 +404,9 @@ public ZRTeleHandle(Handle:menu_ztele , MenuAction:action, client, slot)
{
CloseHandle(menu_ztele);
}
}
}*/
ZRLogFlagsMenu(client)
/*ZRLogFlagsMenu(client)
{
new Handle:menu_log_flags = CreateMenu(ZRLogFlagsMenuHandle);
@ -515,9 +425,9 @@ ZRLogFlagsMenu(client)
SetMenuExitBackButton(menu_log_flags, true);
DisplayMenu(menu_log_flags, client, MENU_TIME_FOREVER);
}
}*/
public ZRLogFlagsMenuHandle(Handle:menu_log_flags, MenuAction:action, client, slot)
/*public ZRLogFlagsMenuHandle(Handle:menu_log_flags, MenuAction:action, client, slot)
{
if (action == MenuAction_Select)
{
@ -536,4 +446,4 @@ public ZRLogFlagsMenuHandle(Handle:menu_log_flags, MenuAction:action, client, sl
{
CloseHandle(menu_log_flags);
}
}
}*/

View File

@ -1,22 +0,0 @@
RemoveObjectives()
{
decl String:classname[64];
new maxentities = GetMaxEntities();
for (new x = 0; x <= maxentities; x++)
{
if(!IsValidEdict(x))
{
continue;
}
GetEdictClassname(x, classname, sizeof(classname));
if( StrEqual(classname, "func_bomb_target") ||
StrEqual(classname, "func_hostage_rescue") ||
StrEqual(classname, "c4") ||
StrEqual(classname, "hostage_entity"))
{
RemoveEdict(x);
}
}
}

View File

@ -1,46 +0,0 @@
Section content is listed in order of importance. Some of these can be ideas too.
---- CRITICAL/IMPORTANT ----
---- NORMAL/GAMEPLAY ----
* Fix zvision not displayed if classes are disabled.
* Make admin commands to get or set player classes:
zr_classes_set <classname> <target>
zr_classes_get <#userid|name>
* Make it possible to disable certain classes on certain maps. Only specify the
class name to read the value:
zr_class_enabled <classname> [<0/1>]
* Per-weapon clip sizes. A new module with detailed control of ammo (modes, limits, timers).
* Remove dead bodies to improve performance (CVAR).
* More grenades for humans (probably with a buy-command or something). It's on
the edge to become a RPG-like feature.
* Super features for both zombies and humans:
- Humans: No fall damage for X seconds. X limits per round.
- Zombies: No knockback/damage for X seconds. X limits per round.
* Make a admin command to read and write settings to a spesific class,
using key/value. Integrate it with the zr_admin menu.
* Knockback presets (integrated into zombie admin menu).
Temporary do many changes on the zombies (by executing configs). Useful
settings or fun settings. SourceMod already has a execute config menu, but it
would be better if this was integrated in ZR.
* zombie.inc:KnockBack / cvars.inc
Make a CVAR for adjusting shotgun/hegrenade knockback boost.
* Validate ALL configs and cvars while loading the plugin. Log messages and unload ZR (or use default) if invalid data is found.
* Make a jetpack feature.
* Fix some zombies not able to zombify some humans when using the infect
command before the first zombie. (make him a mother zombie, kill infect timer,
set some switches)