Improved class system with support for multipliers. Minior fixes, see details.

Made class attribute multipliers.
Made admin menus for adjusting class attribute multipliers.
Made console command for setting class attribute multipliers.
Fixed health regen amount class attribute not validated.
Fixed health regen not stopping after surviving a round as a zombie.
Improved ZRIsClientAdmin to support admin flags (optional).
Changed permission flag on admin commands to match action type. Like only admins with config access should be able to do ZR configuration.
Changed log formatting to match style in SourceMod. Removed "-" and ":". The result will be "... [plugin.smx] [mod] [event] message".
This commit is contained in:
richard 2009-06-18 02:09:55 +02:00
parent 4b66f688ab
commit 6f032b79b8
12 changed files with 903 additions and 308 deletions

View File

@ -74,6 +74,23 @@
"en" "This feature requires that you are a human."
}
"Increase by"
{
"#format" "{1:s}"
"en" "Increase by {1}"
}
"Decrease by"
{
"#format" "{1:s}"
"en" "Decrease by {1}"
}
"Current Value"
{
"en" "Current value:"
}
// Menu
"Menu empty"
@ -212,6 +229,78 @@
"en" "Toggle Admin Mode"
}
"Classes Menu Team Select Title"
{
"en" "Select Team:"
}
"Classes Menu Zombies"
{
"en" "Zombies"
}
"Classes Menu Humans"
{
"en" "Humans"
}
"Classes Menu Multiplier Select Title"
{
"en" "Select Multiplier:"
}
"Classes Menu Adjust Value"
{
"en" "Adjust Value:"
}
// Attributes
"Classes Attrib Napalm Time"
{
"en" "Napalm Time"
}
"Classes Attrib Health"
{
"en" "Health"
}
"Classes Attrib Regen Interval"
{
"en" "Health Regeneration Interval"
}
"Classes Attrib Regen Amount"
{
"en" "Health Regeneration Amount"
}
"Classes Attrib Infect Gain"
{
"en" "Infection Health Gain"
}
"Classes Attrib Speed"
{
"en" "Running Speed"
}
"Classes Attrib Knockback"
{
"en" "Knock back"
}
"Classes Attrib Jump Height"
{
"en" "Jump Height"
}
"Classes Attrib Jump Distance"
{
"en" "Jump Distance"
}
// ===========================
// Overlays (core)
// ===========================
@ -627,12 +716,17 @@
// ZAdmin Menu
// ===========================
"!zadmin main title"
"!zadmin title"
{
"en" "ZAdmin\n Select Category:"
}
"!zadmin main weapons"
"!zadmin class multipliers"
{
"en" "Class Multipliers"
}
"!zadmin weapons"
{
"en" "Weapon Management"
}
@ -642,73 +736,6 @@
"en" "Logging Flags"
}
"!zadmin class title"
{
"en" "Select Class to Modify:"
}
"!zadmin knockbackm title"
{
"#format" "{1:f}"
"en" "Modify Knockback Multiplier\nCurrent Knockback: {1}"
}
"!zadmin knockbackm increase"
{
"#format" "{1:s}"
"en" "Increase Knockback Multiplier (+{1})"
}
"!zadmin knockbackm decrease"
{
"#format" "{1:s}"
"en" "Decrease Knockback Multiplier (-{1})"
}
"!zadmin knockback title"
{
"#format" "{1:s},{2:f}"
"en" "Modify Knockback\nClass: {1}\nCurrent Knockback: {2}"
}
"!zadmin knockback increase"
{
"#format" "{1:s}"
"en" "Increase Knockback (+{1})"
}
"!zadmin knockback decrease"
{
"#format" "{1:s}"
"en" "Decrease Knockback (-{1})"
}
"!zadmin nvgs title"
{
"#format" "{1:d}"
"en" "Override NVG Cvar\nCurrent Setting: {1}"
}
"!zadmin nvgs decrease"
{
"en" "Decrease Knockback"
}
"!zadmin nvgs no override"
{
"en" "No Override/Class Specific"
}
"!zadmin nvgs disable"
{
"en" "Disable NVGs"
}
"!zadmin nvgs enable"
{
"en" "Enable NVGs"
}
"!zadmin infect title"
{
"en" "Choose a Player to Infect:"

View File

@ -187,8 +187,8 @@ enum ConfigKvAction
ConfigOnCommandsCreate()
{
// Create config admin commands.
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");
RegAdminCmd("zr_config_reload", ConfigReloadCommand, ADMFLAG_CONFIG, "Reloads a config file. Usage: zr_config_reload <file alias>");
RegAdminCmd("zr_config_reloadall", ConfigReloadAllCommand, ADMFLAG_CONFIG, "Reloads all config files. Usage: zr_config_reloadall");
}
/**

View File

@ -299,7 +299,7 @@ LogEvent(bool:isConsole = false, LogTypes:logType = LogType_Normal, eventType =
LogGetModuleNameString(modulename, sizeof(modulename), module);
// Format
Format(logbuffer, sizeof(logbuffer), "[%s] - [%s]: %s", modulename, description, logbuffer);
Format(logbuffer, sizeof(logbuffer), "[%s] [%s] %s", modulename, description, logbuffer);
// Format other parameters onto the log text.
switch (logType)
@ -446,8 +446,8 @@ LogModuleFilterCacheUpdate()
LogOnCommandsCreate()
{
RegConsoleCmd("zr_log_list", Command_LogList, "List available logging flags and modules with their status values.");
RegConsoleCmd("zr_log_add_module", Command_LogAddModule, "Add one or more modules to the module filter. Usage: zr_log_add_module <module> [module] ...");
RegConsoleCmd("zr_log_remove_module", Command_LogRemoveModule, "Remove one or more modules from the module filter. Usage: zr_log_remove_module <module> [module] ...");
RegAdminCmd("zr_log_add_module", Command_LogAddModule, ADMFLAG_CONFIG, "Add one or more modules to the module filter. Usage: zr_log_add_module <module> [module] ...");
RegAdminCmd("zr_log_remove_module", Command_LogRemoveModule, ADMFLAG_CONFIG, "Remove one or more modules from the module filter. Usage: zr_log_remove_module <module> [module] ...");
}
/**

View File

@ -496,6 +496,8 @@ stock bool:ClassGetHasNapalm(index, cachetype = ZR_CLASS_CACHE_PLAYER)
/**
* Gets the napalm grenades time from the specified class.
*
* Note: Multiplier is used if cache type is player cache.
*
* @param index Index of the class in a class cache or a client index,
* depending on the cache type specified.
* @param cachetype Optional. Specifies what class cache to read from. Options:
@ -519,7 +521,7 @@ stock Float:ClassGetNapalmTime(index, cachetype = ZR_CLASS_CACHE_PLAYER)
}
case ZR_CLASS_CACHE_PLAYER:
{
return ClassPlayerCache[index][class_napalm_time];
return ClassPlayerCache[index][class_napalm_time] * ClassGetAttributeMultiplier(index, ClassM_NapalmTime);
}
}
return -1.0;
@ -635,6 +637,8 @@ stock bool:ClassGetNoFallDamage(index, cachetype = ZR_CLASS_CACHE_PLAYER)
/**
* Gets the health points from the specified class.
*
* Note: Multiplier is used if cache type is player cache.
*
* @param index Index of the class in a class cache or a client index,
* depending on the cache type specified.
* @param cachetype Optional. Specifies what class cache to read from. Options:
@ -658,7 +662,7 @@ stock ClassGetHealth(index, cachetype = ZR_CLASS_CACHE_PLAYER)
}
case ZR_CLASS_CACHE_PLAYER:
{
return ClassPlayerCache[index][class_health];
return RoundToCeil(ClassPlayerCache[index][class_health] * ClassGetAttributeMultiplier(index, ClassM_Health));
}
}
return -1;
@ -667,6 +671,8 @@ stock ClassGetHealth(index, cachetype = ZR_CLASS_CACHE_PLAYER)
/**
* Gets the health regen interval time from the specified class.
*
* Note: Multiplier is used if cache type is player cache.
*
* @param index Index of the class in a class cache or a client index,
* depending on the cache type specified.
* @param cachetype Optional. Specifies what class cache to read from. Options:
@ -691,7 +697,7 @@ stock Float:ClassGetHealthRegenInterval(index, cachetype = ZR_CLASS_CACHE_PLAYER
}
case ZR_CLASS_CACHE_PLAYER:
{
return ClassPlayerCache[index][class_health_regen_interval];
return ClassPlayerCache[index][class_health_regen_interval] * ClassGetAttributeMultiplier(index, ClassM_HealthRegenInterval);
}
}
return -1.0;
@ -700,6 +706,8 @@ stock Float:ClassGetHealthRegenInterval(index, cachetype = ZR_CLASS_CACHE_PLAYER
/**
* Gets the health regen amount value from the specified class.
*
* Note: Multiplier is used if cache type is player cache.
*
* @param index Index of the class in a class cache or a client index,
* depending on the cache type specified.
* @param cachetype Optional. Specifies what class cache to read from. Options:
@ -724,7 +732,7 @@ stock ClassGetHealthRegenAmount(index, cachetype = ZR_CLASS_CACHE_PLAYER)
}
case ZR_CLASS_CACHE_PLAYER:
{
return ClassPlayerCache[index][class_health_regen_amount];
return RoundToCeil(ClassPlayerCache[index][class_health_regen_amount] * ClassGetAttributeMultiplier(index, ClassM_HealthRegenAmount));
}
}
return -1;
@ -733,6 +741,8 @@ stock ClassGetHealthRegenAmount(index, cachetype = ZR_CLASS_CACHE_PLAYER)
/**
* Gets the health infect gain value from the specified class.
*
* Note: Multiplier is used if cache type is player cache.
*
* @param index Index of the class in a class cache or a client index,
* depending on the cache type specified.
* @param cachetype Optional. Specifies what class cache to read from. Options:
@ -757,7 +767,7 @@ stock ClassGetHealthInfectGain(index, cachetype = ZR_CLASS_CACHE_PLAYER)
}
case ZR_CLASS_CACHE_PLAYER:
{
return ClassPlayerCache[index][class_health_infect_gain];
return RoundToCeil(ClassPlayerCache[index][class_health_infect_gain] * ClassGetAttributeMultiplier(index, ClassM_HealthInfectGain));
}
}
return -1;
@ -798,6 +808,8 @@ stock ClassGetKillBonus(index, cachetype = ZR_CLASS_CACHE_PLAYER)
/**
* Gets the running speed value from the specified class.
*
* Note: Multiplier is used if cache type is player cache.
*
* @param index Index of the class in a class cache or a client index,
* depending on the cache type specified.
* @param cachetype Optional. Specifies what class cache to read from. Options:
@ -821,7 +833,7 @@ stock Float:ClassGetSpeed(index, cachetype = ZR_CLASS_CACHE_PLAYER)
}
case ZR_CLASS_CACHE_PLAYER:
{
return ClassPlayerCache[index][class_speed];
return ClassPlayerCache[index][class_speed] * ClassGetAttributeMultiplier(index, ClassM_Speed);
}
}
return -1.0;
@ -830,6 +842,8 @@ stock Float:ClassGetSpeed(index, cachetype = ZR_CLASS_CACHE_PLAYER)
/**
* Gets the knock back boost from the specified class.
*
* Note: Multiplier is used if cache type is player cache.
*
* @param index Index of the class in a class cache or a client index,
* depending on the cache type specified.
* @param cachetype Optional. Specifies what class cache to read from. Options:
@ -853,7 +867,7 @@ stock Float:ClassGetKnockback(index, cachetype = ZR_CLASS_CACHE_PLAYER)
}
case ZR_CLASS_CACHE_PLAYER:
{
return ClassPlayerCache[index][class_knockback];
return ClassPlayerCache[index][class_knockback] * ClassGetAttributeMultiplier(index, ClassM_Knockback);
}
}
return 0.0;
@ -862,6 +876,8 @@ stock Float:ClassGetKnockback(index, cachetype = ZR_CLASS_CACHE_PLAYER)
/**
* Gets the jump height boost from the specified class.
*
* Note: Multiplier is used if cache type is player cache.
*
* @param index Index of the class in a class cache or a client index,
* depending on the cache type specified.
* @param cachetype Optional. Specifies what class cache to read from. Options:
@ -885,7 +901,7 @@ stock Float:ClassGetJumpHeight(index, cachetype = ZR_CLASS_CACHE_PLAYER)
}
case ZR_CLASS_CACHE_PLAYER:
{
return ClassPlayerCache[index][class_jump_height];
return ClassPlayerCache[index][class_jump_height] * ClassGetAttributeMultiplier(index, ClassM_JumpHeight);
}
}
return -1.0;
@ -894,6 +910,8 @@ stock Float:ClassGetJumpHeight(index, cachetype = ZR_CLASS_CACHE_PLAYER)
/**
* Gets the jump distance boost from the specified class.
*
* Note: Multiplier is used if cache type is player cache.
*
* @param index Index of the class in a class cache or a client index,
* depending on the cache type specified.
* @param cachetype Optional. Specifies what class cache to read from. Options:
@ -917,7 +935,7 @@ stock Float:ClassGetJumpDistance(index, cachetype = ZR_CLASS_CACHE_PLAYER)
}
case ZR_CLASS_CACHE_PLAYER:
{
return ClassPlayerCache[index][class_jump_distance];
return ClassPlayerCache[index][class_jump_distance] * ClassGetAttributeMultiplier(index, ClassM_JumpDistance);
}
}
return -1.0;
@ -927,7 +945,7 @@ stock Float:ClassGetJumpDistance(index, cachetype = ZR_CLASS_CACHE_PLAYER)
* Gets the attribute flag that represent the specified attribute.
*
* @param attributename The attribute name.
* @return The flag that reporesent the specified attribute.
* @return The flag that represent the specified attribute.
* -1 on error.
*/
stock ClassAttributeNameToFlag(const String:attributename[])
@ -1038,6 +1056,57 @@ stock ClassAttributeNameToFlag(const String:attributename[])
return -1;
}
/**
* Converts a attribute name to a multiplier type.
*
* @param attributename The attribute name.
* @return The multiplier that represent the specified attribute.
* ClassM_Invalid if failed.
*/
stock ClassMultipliers:ClassAttributeNameToMultiplier(const String:attributename[])
{
// Check attribute names.
if (StrEqual(attributename, "napalm_time", false))
{
return ClassM_NapalmTime;
}
else if (StrEqual(attributename, "health", false))
{
return ClassM_Health;
}
else if (StrEqual(attributename, "health_regen_interval", false))
{
return ClassM_HealthRegenInterval;
}
else if (StrEqual(attributename, "health_regen_interval", false))
{
return ClassM_HealthRegenAmount;
}
else if (StrEqual(attributename, "health_infect_gain", false))
{
return ClassM_HealthInfectGain;
}
else if (StrEqual(attributename, "speed", false))
{
return ClassM_Speed;
}
else if (StrEqual(attributename, "knockback", false))
{
return ClassM_Knockback;
}
else if (StrEqual(attributename, "jump_height", false))
{
return ClassM_JumpHeight;
}
else if (StrEqual(attributename, "jump_distance", false))
{
return ClassM_JumpDistance;
}
// Invalid attribute name or not a multiplier.
return ClassM_Invalid;
}
/**
* Returns the datatype used in the specified attribute.
*

View File

@ -29,7 +29,9 @@ 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]");
RegConsoleCmd("zr_class_dump_multipliers", ClassDumpMultipliersCommand, "Dumps class attribute multipliers for the specified team. Usage: zr_class_dump_multipliers <\"zombies\"|\"humans\">");
RegAdminCmd("zr_class_modify", ClassModifyCommand, ADMFLAG_CONFIG, "Modify class data on one or more classes. Usage: zr_class_modify <classname|\"zombies\"|\"humans\"|\"admins\"> <attribute> <value> [is_multiplier]");
RegAdminCmd("zr_class_set_multiplier", ClassSetMultiplierCommand, ADMFLAG_CONFIG, "Sets the multiplier on a class attribute. Usage: zr_class_set multiplier <\"zombies\"|\"humans\"> <attribute> <value>");
}
/**
@ -50,7 +52,7 @@ ClassOnCommandsHook()
*/
public Action:ClassDumpCommand(client, argc)
{
decl String:syntax[1024];
decl String:syntax[320];
syntax[0] = 0;
if (argc < 2)
@ -144,6 +146,74 @@ public Action:ClassDumpCommand(client, argc)
return Plugin_Handled;
}
/**
* Command callback. (zr_class_dump_multipliers)
* Dumps class attribute multipliers for the specified team.
*
* @param client The client index.
* @param argc Argument count.
*/
public Action:ClassDumpMultipliersCommand(client, argc)
{
decl String:buffer[512];
decl String:linebuffer[128];
decl String:arg[16];
buffer[0] = 0;
if (argc < 1)
{
// Write syntax info.
ReplyToCommand(client, "Dumps class attribute multipliers for the specified team. Usage: zr_class_dump_multipliers <\"zombies\"|\"humans\">");
return Plugin_Handled;
}
new teamid = -1;
// Get team id.
GetCmdArg(1, arg, sizeof(arg));
if (StrEqual(arg, "zombies", false))
{
teamid = ZR_CLASS_TEAM_ZOMBIES;
}
else if (StrEqual(arg, "humans", false))
{
teamid = ZR_CLASS_TEAM_HUMANS;
}
if (teamid >= 0)
{
Format(linebuffer, sizeof(linebuffer), "Dumping multipliers for team: %s\n----------------------------------------\n", arg);
StrCat(buffer, sizeof(buffer), linebuffer);
Format(linebuffer, sizeof(linebuffer), "Napalm time: %f\n", ClassMultiplierCache[teamid][ClassM_NapalmTime]);
StrCat(buffer, sizeof(buffer), linebuffer);
Format(linebuffer, sizeof(linebuffer), "Health: %f\n", ClassMultiplierCache[teamid][ClassM_Health]);
StrCat(buffer, sizeof(buffer), linebuffer);
Format(linebuffer, sizeof(linebuffer), "Health regen interval: %f\n", ClassMultiplierCache[teamid][ClassM_HealthRegenInterval]);
StrCat(buffer, sizeof(buffer), linebuffer);
Format(linebuffer, sizeof(linebuffer), "Health regen amount: %f\n", ClassMultiplierCache[teamid][ClassM_HealthRegenAmount]);
StrCat(buffer, sizeof(buffer), linebuffer);
Format(linebuffer, sizeof(linebuffer), "Health infect gain: %f\n", ClassMultiplierCache[teamid][ClassM_HealthInfectGain]);
StrCat(buffer, sizeof(buffer), linebuffer);
Format(linebuffer, sizeof(linebuffer), "Speed: %f\n", ClassMultiplierCache[teamid][ClassM_Speed]);
StrCat(buffer, sizeof(buffer), linebuffer);
Format(linebuffer, sizeof(linebuffer), "Knock back: %f\n", ClassMultiplierCache[teamid][ClassM_Knockback]);
StrCat(buffer, sizeof(buffer), linebuffer);
Format(linebuffer, sizeof(linebuffer), "Jump height: %f\n", ClassMultiplierCache[teamid][ClassM_JumpHeight]);
StrCat(buffer, sizeof(buffer), linebuffer);
Format(linebuffer, sizeof(linebuffer), "Jump distance: %f", ClassMultiplierCache[teamid][ClassM_JumpDistance]);
StrCat(buffer, sizeof(buffer), linebuffer);
ReplyToCommand(client, buffer);
return Plugin_Handled;
}
else
{
ReplyToCommand(client, "Invalid team name specified.");
return Plugin_Handled;
}
}
/**
* Modifies class data on one or more classes.
*
@ -363,6 +433,85 @@ public Action:ClassModifyCommand(client, argc)
return Plugin_Handled;
}
/**
* Sets the multiplier on a class attribute.
*
* Syntax: zr_class_modify <class> <attribute> <value> [is_multiplier]
*
* class: The class to modify. Can be any class name, or one of the
* following team names; "all", "humans", "zombies" or
* "admins".
* attribute: The name of the class attribute.
* value: Value to set. Use quotes if value is a string.
* is_multiplier: Optional. specifies wether the original value should be
* multiplied by the specified value. Defaults to false.
*
* Note: Original values are retrieved from the original class cache, not the
* modified class cache.
*/
public Action:ClassSetMultiplierCommand(client, argc)
{
decl String:syntax[320];
syntax[0] = 0;
if (argc < 3)
{
// Write syntax info.
StrCat(syntax, sizeof(syntax), "Sets the multiplier on a class attribute. Usage: zr_class_set multiplier <\"zombies\"|\"humans\"> <attribute> <value>\n\n");
StrCat(syntax, sizeof(syntax), "Valid attributes:\n----------------------------------------\n");
StrCat(syntax, sizeof(syntax), "napalm_time\nhealth\nhealth_regen_interval\nhealth_regen_amount\nhealth_infect_gain\nspeed\nknockback\njump_height\njump_distance");
ReplyToCommand(client, syntax);
return Plugin_Handled;
}
decl String:teamname[16];
decl String:attributename[32];
decl String:multiplier[32];
new teamid = -1;
new ClassMultipliers:attribute;
new Float:value;
// Get arguments.
GetCmdArg(1, teamname, sizeof(teamname));
GetCmdArg(2, attributename, sizeof(attributename));
GetCmdArg(3, multiplier, sizeof(multiplier));
// Get team id.
if (StrEqual(teamname, "zombies", false))
{
teamid = ZR_CLASS_TEAM_ZOMBIES;
}
else if (StrEqual(teamname, "humans", false))
{
teamid = ZR_CLASS_TEAM_HUMANS;
}
// Validate team id.
if (teamid < 0)
{
ReplyToCommand(client, "Invalid team name: %s", teamname);
return Plugin_Handled;
}
// Get attribute type.
attribute = ClassAttributeNameToMultiplier(attributename);
// Validate type.
if (attribute == ClassM_Invalid)
{
ReplyToCommand(client, "Attribute is invalid or not a multiplier: %s", attributename);
}
// Get value.
value = StringToFloat(multiplier);
// Set multiplier.
ClassMultiplierCache[teamid][attribute] = value;
return Plugin_Handled;
}
/**
* Modify class boolean attribute on a class.
*
@ -517,9 +666,9 @@ stock ClassModifyInteger(classindex, attributeflag, value, Float:multiplier = 0.
* @param classindex The class index.
* @param attributeflag Attribute to modify (a single attribute flag).
* @param value New value to set, or multiply with.
* @param ismultiplier Optional. Specifies wether to value as a multiplier
* that multiplies with the original class value.
* Not all attributes support multipliers.
* @param ismultiplier Optional. Specifies wether to use value as a
* multiplier that is multiplied with the original
* class value. Unsupported attributes are ignored.
* @return True on success, false otherwise.
*/
stock ClassModifyFloat(classindex, attributeflag, Float:value, bool:ismultiplier = false)

View File

@ -24,6 +24,8 @@
ClassClientInit(client)
{
// Check if there are valid classes and the client is valid.
// To prevent bots or SourceTV causing errors. If classes are invalid this
// event was executed before classes were loaded.
if (ClassValidated && ZRIsClientValid(client))
{
// Set default class indexes on the player.
@ -69,6 +71,9 @@ ClassOnClientSpawn(client)
return;
}
// Reset attributes by triggering death event.
ClassOnClientDeath(client);
new bool:randomclass = GetConVarBool(g_hCvarsList[CVAR_CLASSES_RANDOM]);
decl String:steamid[16];

View File

@ -25,6 +25,7 @@
* ============================================================================
*/
/* ------------------------------------
*
* MAIN CLASS MENU
@ -115,7 +116,7 @@ ClassMenuMain(client)
}
/**
* Main class menu handle.
* Main class menu handler.
*/
public ClassMenuMainHandle(Handle:menu, MenuAction:action, client, slot)
{
@ -230,7 +231,7 @@ ClassMenuSelect(client, teamid)
}
/**
* Class selection menu handle.
* Class selection menu handler.
*/
public ClassMenuSelectHandle(Handle:menu, MenuAction:action, client, slot)
{
@ -290,7 +291,358 @@ public ClassMenuSelectHandle(Handle:menu, MenuAction:action, client, slot)
}
}
ClassToggleAdminMode(client)
/* ------------------------------------
*
* TEAM SELECT MENU (ADMIN)
*
* ------------------------------------
*/
/**
* Displays the team selection admin menu.
*
* @param client The client index.
* @return True if displayed, false otherwise.
*/
bool:ClassTeamSelect(client)
{
// TODO: Move to new file, adminmode.inc.
// Validate client.
if (!ZRIsClientValid(client, false))
{
return false;
}
// Validate permissions.
if (!ZRIsClientAdmin(client, Admin_Config))
{
return false;
}
// Create menu.
new Handle:menu = CreateMenu(ClassTeamSelectHandle);
decl String:title[64];
decl String:zombies[16];
decl String:humans[16];
// Set translation language.
SetGlobalTransTarget(client);
// Translate phrases.
Format(title, sizeof(title), "%t", "Classes Menu Team Select Title");
Format(zombies, sizeof(zombies), "%t", "Classes Menu Zombies");
Format(humans, sizeof(humans), "%t", "Classes Menu Humans");
SetMenuTitle(menu, title);
AddMenuItem(menu, "zombies", zombies);
AddMenuItem(menu, "humans", humans);
SetMenuExitBackButton(menu, true);
DisplayMenu(menu, client, MENU_TIME_FOREVER);
return true;
}
/**
* Team selection menu handler.
*/
public ClassTeamSelectHandle(Handle:menu, MenuAction:action, client, slot)
{
switch (action)
{
case MenuAction_Select:
{
switch(slot)
{
case 0:
{
ClassAdminTeamSelected[client] = ZR_CLASS_TEAM_ZOMBIES;
}
case 1:
{
ClassAdminTeamSelected[client] = ZR_CLASS_TEAM_HUMANS;
}
}
// Display multiplier menu.
ClassMultiplierSelectMenu(client);
}
case MenuAction_End:
{
CloseHandle(menu);
}
case MenuAction_Cancel:
{
if (slot == MenuCancel_ExitBack)
{
ZRAdminMenu(client);
}
}
}
}
/* ------------------------------------
*
* MULTIPLIER SELECT MENU (ADMIN)
*
* ------------------------------------
*/
/**
* Displays the multiplier selection admin menu.
*
* @param client The client index.
*/
ClassMultiplierSelectMenu(client)
{
// Create menu.
new Handle:menu = CreateMenu(ClassMultiplierSelectHandle);
new teamid = ClassAdminTeamSelected[client];
new bool:zombiesselected = bool:(teamid == ZR_CLASS_TEAM_ZOMBIES);
decl String:title[64];
decl String:napalmtime[48];
decl String:health[48];
decl String:regeninterval[48];
decl String:regenamount[48];
decl String:infectgain[48];
decl String:speed[48];
decl String:knockback[48];
decl String:jumpheight[48];
decl String:jumpdistance[48];
new Float:currentnapalmtime;
new Float:currenthealth;
new Float:currentregeninterval;
new Float:currentregenamount;
new Float:currentinfectgain;
new Float:currentspeed;
new Float:currentknockback;
new Float:currentjumpheight;
new Float:currentjumpdistance;
// Set translation language.
SetGlobalTransTarget(client);
// Get current multipliers.
currentnapalmtime = Float:ClassMultiplierCache[teamid][ClassM_NapalmTime];
currenthealth = Float:ClassMultiplierCache[teamid][ClassM_Health];
currentregeninterval = Float:ClassMultiplierCache[teamid][ClassM_HealthRegenInterval];
currentregenamount = Float:ClassMultiplierCache[teamid][ClassM_HealthRegenAmount];
currentinfectgain = Float:ClassMultiplierCache[teamid][ClassM_HealthInfectGain];
currentspeed = Float:ClassMultiplierCache[teamid][ClassM_Speed];
currentknockback = Float:ClassMultiplierCache[teamid][ClassM_Knockback];
currentjumpheight = Float:ClassMultiplierCache[teamid][ClassM_JumpHeight];
currentjumpdistance = Float:ClassMultiplierCache[teamid][ClassM_JumpDistance];
// Translate phrases.
Format(title, sizeof(title), "%t\n", "Classes Menu Multiplier Select Title");
Format(health, sizeof(health), "%t\n %.2f", "Classes Attrib Health", currenthealth);
Format(regeninterval, sizeof(regeninterval), "%t\n %.2f", "Classes Attrib Regen Interval", currentregeninterval);
Format(regenamount, sizeof(regenamount), "%t\n %.2f", "Classes Attrib Regen Amount", currentregenamount);
Format(speed, sizeof(speed), "%t\n %.2f", "Classes Attrib Speed", currentspeed);
Format(jumpheight, sizeof(jumpheight), "%t\n %.2f", "Classes Attrib Jump Height", currentjumpheight);
Format(jumpdistance, sizeof(jumpdistance), "%t\n %.2f", "Classes Attrib Jump Distance", currentjumpdistance);
// Only translate zombie phrases if zombie team is selected.
if (zombiesselected)
{
Format(napalmtime, sizeof(napalmtime), "%t\n %.2f", "Classes Attrib Napalm Time", currentnapalmtime);
Format(infectgain, sizeof(infectgain), "%t\n %.2f", "Classes Attrib Infect Gain", currentinfectgain);
Format(knockback, sizeof(knockback), "%t\n %.2f", "Classes Attrib Knockback", currentknockback);
}
SetMenuTitle(menu, title);
// Add items. Don't add zombie attributes if human team is selected.
if (zombiesselected) AddMenuItem(menu, "napalmtime", napalmtime);
AddMenuItem(menu, "health", health);
AddMenuItem(menu, "regeninterval", regeninterval);
AddMenuItem(menu, "regenamount", regenamount);
if (zombiesselected) AddMenuItem(menu, "infectgain", infectgain);
AddMenuItem(menu, "speed", speed);
if (zombiesselected) AddMenuItem(menu, "knockback", knockback);
AddMenuItem(menu, "jumpheight", jumpheight);
AddMenuItem(menu, "jumpdistance", jumpdistance);
SetMenuExitBackButton(menu, true);
DisplayMenu(menu, client, MENU_TIME_FOREVER);
}
/**
* Multiplier select menu handler.
*/
public ClassMultiplierSelectHandle(Handle:menu, MenuAction:action, client, slot)
{
decl String:attributename[48];
new ClassMultipliers:attribute;
switch (action)
{
case MenuAction_Select:
{
// Get attribute name.
GetMenuItem(menu, slot, attributename, sizeof(attributename));
// Initialize in case of errors.
attribute = ClassM_Knockback;
// Convert type.
if (StrEqual(attributename, "napalmtime", false))
{
attribute = ClassM_NapalmTime;
}
else if (StrEqual(attributename, "health", false))
{
attribute = ClassM_Health;
}
else if (StrEqual(attributename, "regeninterval", false))
{
attribute = ClassM_HealthRegenInterval;
}
else if (StrEqual(attributename, "regenamount", false))
{
attribute = ClassM_HealthRegenAmount;
}
else if (StrEqual(attributename, "infectgain", false))
{
attribute = ClassM_HealthInfectGain;
}
else if (StrEqual(attributename, "speed", false))
{
attribute = ClassM_Speed;
}
else if (StrEqual(attributename, "knockback", false))
{
attribute = ClassM_Knockback;
}
else if (StrEqual(attributename, "jumpheight", false))
{
attribute = ClassM_JumpHeight;
}
else if (StrEqual(attributename, "jumpdistance", false))
{
attribute = ClassM_JumpDistance;
}
// Display multiplier menu for the selected attribute.
ClassMultiplierMenu(client, attribute);
}
case MenuAction_End:
{
CloseHandle(menu);
}
case MenuAction_Cancel:
{
if (slot == MenuCancel_ExitBack)
{
ClassTeamSelect(client);
}
}
}
}
/* ------------------------------------
*
* MULTIPLIER MENU (ADMIN)
*
* ------------------------------------
*/
/**
* Displays multiplier menu for the specified attribute.
*/
ClassMultiplierMenu(client, ClassMultipliers:attribute)
{
// Cache selected attribute.
ClassAdminAttributeSelected[client] = attribute;
new Handle:menu = CreateMenu(ClassMultiplierHandle);
decl String:title[64];
decl String:attributename[48];
decl String:linebuffer[48];
// Set translation language.
SetGlobalTransTarget(client);
// Get attribute string.
ClassMultiplierToString(attribute, attributename, sizeof(attributename));
Format(title, sizeof(title), "%t %s\n%t %.2f\n", "Classes Menu Adjust Value", attributename, "Current Value", Float:ClassMultiplierCache[ClassAdminTeamSelected[client]][attribute]);
SetMenuTitle(menu, title);
Format(linebuffer, sizeof(linebuffer), "%t", "Increase by", "0.5");
AddMenuItem(menu, "increasehalf", linebuffer);
Format(linebuffer, sizeof(linebuffer), "%t", "Increase by", "0.1");
AddMenuItem(menu, "increasedeci", linebuffer);
Format(linebuffer, sizeof(linebuffer), "%t", "Decrease by", "0.1");
AddMenuItem(menu, "decreasedeci", linebuffer);
Format(linebuffer, sizeof(linebuffer), "%t", "Decrease by", "0.5");
AddMenuItem(menu, "decreasehalf", linebuffer);
SetMenuExitBackButton(menu, true);
DisplayMenu(menu, client, MENU_TIME_FOREVER);
}
public ClassMultiplierHandle(Handle:menu, MenuAction:action, client, slot)
{
new Float:value;
switch (action)
{
case MenuAction_Select:
{
switch (slot)
{
case 0:
{
value = 0.5;
}
case 1:
{
value = 0.1;
}
case 2:
{
value = -0.1;
}
case 3:
{
value = -0.5;
}
}
// Update multiplier.
ClassAddToMultiplier(ClassAdminTeamSelected[client], ClassAdminAttributeSelected[client], value);
// Re-display menu.
ClassMultiplierMenu(client, ClassAdminAttributeSelected[client]);
}
case MenuAction_End:
{
CloseHandle(menu);
}
case MenuAction_Cancel:
{
if (slot == MenuCancel_ExitBack)
{
ClassMultiplierSelectMenu(client);
}
}
}
}
/**
* Add to the specified multiplier.
*
* @param teamid The team to filter.
* @param attribute The attribute to add to.
* @param value Value to add.
*/
ClassAddToMultiplier(teamid, ClassMultipliers:attribute, Float:value)
{
ClassMultiplierCache[teamid][attribute] = ClassMultiplierCache[teamid][attribute] + value;
}

View File

@ -146,8 +146,8 @@ stock ClassValidateAttributes(classindex)
}
else
{
// Check if default or random model is specified.
if (strcmp(model_path, "random", false) != 0 && strcmp(model_path, "default", false) != 0)
// Check if a model different from default or random is specified.
if (!StrEqual(model_path, "random", false) && !StrEqual(model_path, "default", false))
{
// Check if the file exists.
if (!FileExists(model_path))
@ -217,14 +217,14 @@ stock ClassValidateAttributes(classindex)
if (!(regen_interval >= ZR_CLASS_HEALTH_REGEN_INTERVAL_MIN && regen_interval <= ZR_CLASS_HEALTH_REGEN_INTERVAL_MAX))
{
flags += ZR_CLASS_FLAG_HEALTH_REGEN_INTERVAL;
}
// Health regen amount. Only validating if interval is set.
// Health regen amount.
new regen_amount = ClassData[classindex][class_health_regen_amount];
if (!(regen_amount >= ZR_CLASS_HEALTH_REGEN_AMOUNT_MIN && regen_amount <= ZR_CLASS_HEALTH_REGEN_AMOUNT_MAX))
{
flags += ZR_CLASS_FLAG_HEALTH_REGEN_AMOUNT;
}
}
// Health infect gain.
new infect_gain = ClassData[classindex][class_health_infect_gain];
@ -409,6 +409,41 @@ stock ClassGetActiveIndex(client)
return ClassSelected[client][teamid];
}
/**
* Gets the multiplier for the specified team and attribute.
*
* @param client The client index.
* @param attribute Specifies what attribute multiplier to get.
* @return Multiplier for the specified team and attribute. 1.0 if the
* client is in admin mode.
*/
stock Float:ClassGetAttributeMultiplier(client, ClassMultipliers:attribute)
{
new teamid;
// Check if player is not in admin mode.
if (!ClassPlayerInAdminMode[client])
{
// Not in admin mode, check if player is human or zombie.
if (InfectIsClientHuman(client))
{
teamid = ZR_CLASS_TEAM_HUMANS;
}
else
{
teamid = ZR_CLASS_TEAM_ZOMBIES;
}
// Get multiplier for the specified team and attribute.
return Float:ClassMultiplierCache[teamid][attribute];
}
else
{
// Do not use multipliers on admin classes.
return 1.0;
}
}
/**
* Gets all class indexes or from a specified team, and adds them to the
* specified array.

View File

@ -162,7 +162,7 @@
#define ZR_CLASS_HEALTH_MAX 20000
#define ZR_CLASS_HEALTH_REGEN_INTERVAL_MIN 0.0
#define ZR_CLASS_HEALTH_REGEN_INTERVAL_MAX 900.0
#define ZR_CLASS_HEALTH_REGEN_AMOUNT_MIN 0.0
#define ZR_CLASS_HEALTH_REGEN_AMOUNT_MIN 0
#define ZR_CLASS_HEALTH_REGEN_AMOUNT_MAX 10000
#define ZR_CLASS_HEALTH_INFECT_GAIN_MIN 0
#define ZR_CLASS_HEALTH_INFECT_GAIN_MAX 20000
@ -258,6 +258,34 @@ enum ClassAttributes
Float:class_jump_distance
}
/**
* Class attributes that support multipliers.
*/
enum ClassMultipliers
{
ClassM_Invalid = 0,
Float:ClassM_NapalmTime,
Float:ClassM_Health,
Float:ClassM_HealthRegenInterval,
Float:ClassM_HealthRegenAmount,
Float:ClassM_HealthInfectGain,
Float:ClassM_Speed,
Float:ClassM_Knockback,
Float:ClassM_JumpHeight,
Float:ClassM_JumpDistance
}
/**
* Available class teams, used to specify targets.
*/
enum ClassTeams
{
ClassTeam_Zombies = 0,
ClassTeam_Humans,
ClassTeam_Admins,
ClassTeam_All
}
/**
* Data types used in class attributes.
*/
@ -294,6 +322,13 @@ new ClassDataCache[ZR_CLASS_MAX][ClassAttributes];
*/
new ClassPlayerCache[MAXPLAYERS + 1][ClassAttributes];
/**
* Cache for storing global multipliers, per team and per attribute when
* possible. Only attributes that support multipliers will be used, others are
* ignored.
*/
new Float:ClassMultiplierCache[ZR_CLASS_TEAMCOUNT][ClassMultipliers];
/**
* Number of classes loaded.
*/
@ -310,6 +345,16 @@ new bool:ClassValidated;
*/
new ClassSelected[MAXPLAYERS + 1][ZR_CLASS_TEAMCOUNT];
/**
* Cache for the currently selected team (admin menus).
*/
new ClassAdminTeamSelected[MAXPLAYERS + 1];
/**
* Cache for the currently selected attribute multiplier (admin menus).
*/
new ClassMultipliers:ClassAdminAttributeSelected[MAXPLAYERS + 1];
/**
* Specifies whether a player is currently in admin mode.
*/
@ -338,8 +383,11 @@ new ClassPlayerNextAdminClass[MAXPLAYERS + 1];
/**
* Loads class attributes from the class file into ClassData array. If any
* error occur the plugin load will fail, and errors will be logged.
*
* @param keepMultipliers Optional. Don't reset multipliers. Default is
* false.
*/
ClassLoad()
ClassLoad(bool:keepMultipliers = false)
{
// Register config file.
ConfigRegisterConfig(File_Classes, Structure_Keyvalue, CONFIG_FILE_ALIAS_CLASSES);
@ -476,6 +524,12 @@ ClassLoad()
// Cache class data.
ClassReloadDataCache();
// Reset attribute multipliers, if not keeping.
if (!keepMultipliers)
{
ClassResetMultiplierCache();
}
// Mark classes as valid.
ClassValidated = true;
@ -497,6 +551,7 @@ ClassLoad()
public ClassOnConfigReload(ConfigFile:config)
{
// Reload class config.
ClassLoad(true);
}
/**
@ -556,8 +611,7 @@ bool:ClassReloadDataCache()
}
/**
* Clears the players class data and copies data from the specified class data
* cache.
* Refresh the specified player's cache from the specified class data cache.
*
* @param client The client index.
* @param classindex The index of the class to read from.
@ -663,6 +717,26 @@ bool:ClassReloadPlayerCache(client, classindex, cachetype = ZR_CLASS_CACHE_MODIF
return true;
}
/**
* Reset all class attribute multipliers to 1.0.
*/
ClassResetMultiplierCache()
{
// Loop through all teams.
for (new teamid = 0; teamid < ZR_CLASS_TEAMCOUNT; teamid++)
{
ClassMultiplierCache[teamid][ClassM_NapalmTime] = 1.0;
ClassMultiplierCache[teamid][ClassM_Health] = 1.0;
ClassMultiplierCache[teamid][ClassM_HealthRegenInterval] = 1.0;
ClassMultiplierCache[teamid][ClassM_HealthRegenAmount] = 1.0;
ClassMultiplierCache[teamid][ClassM_HealthInfectGain] = 1.0;
ClassMultiplierCache[teamid][ClassM_Speed] = 1.0;
ClassMultiplierCache[teamid][ClassM_Knockback] = 1.0;
ClassMultiplierCache[teamid][ClassM_JumpHeight] = 1.0;
ClassMultiplierCache[teamid][ClassM_JumpDistance] = 1.0;
}
}
/**
* Sets default class indexes for each team on all players, or a single player
* if specified.
@ -847,3 +921,67 @@ ClassDumpData(index, cachetype, String:buffer[], maxlen)
return cellcount;
}
/**
* Converts a multiplier attribute to a human readable string.
*
* @param attribute Attribute to convert.
* @param buffer Destination string buffer.
* @param maxlen Size of buffer.
* @return Number of cells written.
*/
ClassMultiplierToString(ClassMultipliers:attribute, String:buffer[], maxlen)
{
decl String:phrase[48];
switch (attribute)
{
case ClassM_NapalmTime:
{
Format(phrase, sizeof(phrase), "%t", "Classes Attrib Napalm Time");
return strcopy(buffer, maxlen, phrase);
}
case ClassM_Health:
{
Format(phrase, sizeof(phrase), "%t", "Classes Attrib Health");
return strcopy(buffer, maxlen, phrase);
}
case ClassM_HealthRegenInterval:
{
Format(phrase, sizeof(phrase), "%t", "Classes Attrib Regen Interval");
return strcopy(buffer, maxlen, phrase);
}
case ClassM_HealthRegenAmount:
{
Format(phrase, sizeof(phrase), "%t", "Classes Attrib Regen Amount");
return strcopy(buffer, maxlen, phrase);
}
case ClassM_HealthInfectGain:
{
Format(phrase, sizeof(phrase), "%t", "Classes Attrib Infect Gain");
return strcopy(buffer, maxlen, phrase);
}
case ClassM_Speed:
{
Format(phrase, sizeof(phrase), "%t", "Classes Attrib Speed");
return strcopy(buffer, maxlen, phrase);
}
case ClassM_Knockback:
{
Format(phrase, sizeof(phrase), "%t", "Classes Attrib Knockback");
return strcopy(buffer, maxlen, phrase);
}
case ClassM_JumpHeight:
{
Format(phrase, sizeof(phrase), "%t", "Classes Attrib Jump Height");
return strcopy(buffer, maxlen, phrase);
}
case ClassM_JumpDistance:
{
Format(phrase, sizeof(phrase), "%t", "Classes Attrib Jump Distance");
return strcopy(buffer, maxlen, phrase);
}
}
return 0;
}

View File

@ -121,8 +121,8 @@ RestrictLoad()
RestrictOnCommandsCreate()
{
// Create weapon admin commands.
RegAdminCmd("zr_restrict", RestrictCommand, ADMFLAG_GENERIC, "Restricts a weapon or a weapon type. Usage: zr_restrict <weapon|weapon type> [weapon2|weapontype2] ...");
RegAdminCmd("zr_unrestrict", UnrestrictCommand, ADMFLAG_GENERIC, "Unrestricts a weapon or a weapon type. Usage: zr_unrestrict <weapon|weapon type> [weapon2|weapontype2] ...");
RegAdminCmd("zr_restrict", RestrictCommand, ADMFLAG_CONFIG, "Restricts a weapon or a weapon type. Usage: zr_restrict <weapon|weapon type> [weapon2|weapontype2] ...");
RegAdminCmd("zr_unrestrict", UnrestrictCommand, ADMFLAG_CONFIG, "Unrestricts a weapon or a weapon type. Usage: zr_unrestrict <weapon|weapon type> [weapon2|weapontype2] ...");
}
/**

View File

@ -33,46 +33,43 @@ bool:ZRAdminMenu(client)
return false;
}
new Handle:menu_zadmin = CreateMenu(ZRAdminMenuHandle);
new Handle:menu = CreateMenu(ZRAdminMenuHandle);
SetGlobalTransTarget(client);
SetMenuTitle(menu_zadmin, "%t\n ", "!zadmin main title");
SetMenuTitle(menu, "%t\n ", "!zadmin title");
//decl String:knockbackm[64];
//decl String:knockback[64];
decl String:classmultipliers[64];
//decl String:infect[64];
//decl String:zspawn[64];
//decl String:ztele[64];
decl String:weapons[64];
//decl String:logflags[64];
//Format(knockbackm, sizeof(knockbackm), "%t", "!zadmin main knockbackm");
//Format(knockback, sizeof(knockback), "%t", "!zadmin main knockback");
Format(classmultipliers, sizeof(classmultipliers), "%t", "!zadmin class multipliers");
//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(weapons, sizeof(weapons), "%t", "!zadmin weapons");
//Format(logflags, sizeof(logflags), "%t", "!zadmin main logflags");
//AddMenuItem(menu_zadmin, "knockbackm", knockbackm, ITEMDRAW_DISABLED);
//AddMenuItem(menu_zadmin, "knockback", knockback, ITEMDRAW_DISABLED);
AddMenuItem(menu, "classmultipliers", classmultipliers);
//AddMenuItem(menu_zadmin, "infect", infect);
//AddMenuItem(menu_zadmin, "zspawn", zspawn);
//AddMenuItem(menu_zadmin, "ztele", ztele, ITEMDRAW_DISABLED);
AddMenuItem(menu_zadmin, "weapons", weapons);
AddMenuItem(menu, "weapons", weapons);
//AddMenuItem(menu_zadmin, "logflags", logflags);
// Set "Back" button.
SetMenuExitBackButton(menu_zadmin, true);
SetMenuExitBackButton(menu, true);
// Send menu to client.
DisplayMenu(menu_zadmin, client, MENU_TIME_FOREVER);
DisplayMenu(menu, client, MENU_TIME_FOREVER);
return true;
}
public ZRAdminMenuHandle(Handle:menu_admin, MenuAction:action, client, slot)
public ZRAdminMenuHandle(Handle:menu, MenuAction:action, client, slot)
{
if (action == MenuAction_Select)
{
@ -81,8 +78,13 @@ public ZRAdminMenuHandle(Handle:menu_admin, MenuAction:action, client, slot)
switch(slot)
{
// Weapon management.
case 0:
{
resend = !ClassTeamSelect(client);
}
// Weapon management.
case 1:
{
resend = !WeaponsMenuMain(client);
}
@ -105,193 +107,10 @@ public ZRAdminMenuHandle(Handle:menu_admin, MenuAction:action, client, slot)
}
else if (action == MenuAction_End)
{
CloseHandle(menu_admin);
CloseHandle(menu);
}
}
/**
* Needs to be recoded to support new modules.
*/
/*ZRKnockbackMMenu(client)
{
new Handle:menu_knockbackm = CreateMenu(ZRKnockbackMHandle);
new Float:curknockback = GetConVarFloat(g_hCvarsList[CVAR_ZOMBIE_KNOCKBACK]);
SetGlobalTransTarget(client);
SetMenuTitle(menu_knockbackm, "%t\n ", "!zadmin knockbackm title", curknockback);
decl String:knockbackmincrease1[64];
decl String:knockbackmdecrease1[64];
decl String:knockbackmincrease2[64];
decl String:knockbackmdecrease2[64];
Format(knockbackmincrease1, sizeof(knockbackmincrease1), "%t", "!zadmin knockbackm increase", "0.1");
Format(knockbackmdecrease1, sizeof(knockbackmdecrease1), "%t", "!zadmin knockbackm decrease", "0.1");
Format(knockbackmincrease2, sizeof(knockbackmincrease2), "%t", "!zadmin knockbackm increase", "0.5");
Format(knockbackmdecrease2, sizeof(knockbackmdecrease2), "%t", "!zadmin knockbackm decrease", "0.5");
AddMenuItem(menu_knockbackm, "knockbackmincrease1", knockbackmincrease1);
AddMenuItem(menu_knockbackm, "knockbackmdecrease1", knockbackmdecrease1);
AddMenuItem(menu_knockbackm, "knockbackmincrease2", knockbackmincrease2);
AddMenuItem(menu_knockbackm, "knockbackmdecrease2", knockbackmdecrease2);
SetMenuExitBackButton(menu_knockbackm, true);
DisplayMenu(menu_knockbackm, client, MENU_TIME_FOREVER);
}*/
/*public ZRKnockbackMHandle(Handle:menu_knockbackm, MenuAction:action, client, slot)
{
if (action == MenuAction_Select)
{
switch(slot)
{
case 0:
{
AddToKnockbackMultiplier(0.1);
ZRKnockbackMMenu(client);
}
case 1:
{
AddToKnockbackMultiplier(-0.1);
ZRKnockbackMMenu(client);
}
case 2:
{
AddToKnockbackMultiplier(0.5);
ZRKnockbackMMenu(client);
}
case 3:
{
AddToKnockbackMultiplier(-0.5);
ZRKnockbackMMenu(client);
}
}
}
if (action == MenuAction_Cancel)
{
if (slot == MenuCancel_ExitBack)
{
ZRAdminMenu(client);
}
}
if (action == MenuAction_End)
{
CloseHandle(menu_knockbackm);
}
}*/
/*ZRClassSelectMenu(client)
{
new Handle:menu_class = CreateMenu(ZRClassSelectHandle);
SetGlobalTransTarget(client);
SetMenuTitle(menu_class, "%t\n ", "!zadmin class title");
// x = index of class
for (new x = 0; x < classCount; x++)
{
AddMenuItem(menu_class, arrayClasses[x][data_name], arrayClasses[x][data_name]);
}
SetMenuExitBackButton(menu_class, true);
DisplayMenu(menu_class, client, MENU_TIME_FOREVER);
}*/
/*public ZRClassSelectHandle(Handle:menu_class, MenuAction:action, client, slot)
{
if (action == MenuAction_Select)
{
curMenuClass[client] = slot;
ZRClassKnockbackMenu(client, slot);
}
if (action == MenuAction_Cancel)
{
if (slot == MenuCancel_ExitBack)
{
ZRAdminMenu(client);
}
}
if (action == MenuAction_End)
{
CloseHandle(menu_class);
}
}*/
/*ZRClassKnockbackMenu(client, classindex)
{
new Handle:menu_knockback = CreateMenu(ZRClassKnockbackHandle);
new Float:curknockback = arrayClasses[classindex][data_knockback];
new String:classname[64];
GetClassName(classindex, classname, sizeof(classname));
SetGlobalTransTarget(client);
SetMenuTitle(menu_knockback, "%t\n ", "!zadmin knockback title", classname, curknockback);
decl String:knockbackincrease1[64];
decl String:knockbackdecrease1[64];
decl String:knockbackincrease2[64];
decl String:knockbackdecrease2[64];
Format(knockbackincrease1, sizeof(knockbackincrease1), "%t", "!zadmin knockback increase", "0.1");
Format(knockbackdecrease1, sizeof(knockbackdecrease1), "%t", "!zadmin knockback decrease", "0.1");
Format(knockbackincrease2, sizeof(knockbackincrease2), "%t", "!zadmin knockback increase", "0.5");
Format(knockbackdecrease2, sizeof(knockbackdecrease2), "%t", "!zadmin knockback decrease", "0.5");
AddMenuItem(menu_knockback, "knockbackincrease1", knockbackincrease1);
AddMenuItem(menu_knockback, "knockbackdecrease1", knockbackdecrease1);
AddMenuItem(menu_knockback, "knockbackincrease2", knockbackincrease2);
AddMenuItem(menu_knockback, "knockbackdecrease2", knockbackdecrease2);
SetMenuExitBackButton(menu_knockback, true);
DisplayMenu(menu_knockback, client, MENU_TIME_FOREVER);
}*/
/*public ZRClassKnockbackHandle(Handle:menu_knockback, MenuAction:action, client, slot)
{
if (action == MenuAction_Select)
{
switch(slot)
{
case 0:
{
AddToClassKnockback(curMenuClass[client], 0.1);
}
case 1:
{
AddToClassKnockback(curMenuClass[client], -0.1);
}
case 2:
{
AddToClassKnockback(curMenuClass[client], 0.5);
}
case 3:
{
AddToClassKnockback(curMenuClass[client], -0.5);
}
}
ZRClassKnockbackMenu(client, curMenuClass[client]);
}
if (action == MenuAction_Cancel)
{
if (slot == MenuCancel_ExitBack)
{
ZRClassSelectMenu(client);
}
}
if (action == MenuAction_End)
{
CloseHandle(menu_knockback);
}
}*/
/*ZRInfectMenu(client)
{
new Handle:menu_infect = CreateMenu(ZRInfectHandle);

View File

@ -235,9 +235,10 @@ stock bool:ZRTeamHasClients(team = -1)
* Returns whether a player is a generic admin or not.
*
* @param client The client index.
* @param flag Optional. Flag to check. Default is generic admin flag.
* @return True if generic admin, false otherwise.
*/
stock bool:ZRIsClientAdmin(client)
stock bool:ZRIsClientAdmin(client, AdminFlag:flag = Admin_Generic)
{
// If index is invalid, then stop.
if (!ZRIsClientValid(client))
@ -245,7 +246,7 @@ stock bool:ZRIsClientAdmin(client)
return false;
}
// If client doesn't have the Admin_Generic flag, then stop.
if (!GetAdminFlag(GetUserAdmin(client), Admin_Generic))
if (!GetAdminFlag(GetUserAdmin(client), flag))
{
return false;
}