add "identifier" to playerclasses (kv section name) and use it as default for cookies, zr_class_modify, etc.
This commit is contained in:
parent
a7caf1de7b
commit
7265c1922f
@ -55,7 +55,9 @@ public void __pl_zombiereloaded_SetNTVOptional()
|
||||
MarkNativeAsOptional("ZR_GetActiveClass");
|
||||
MarkNativeAsOptional("ZR_SelectClientClass");
|
||||
MarkNativeAsOptional("ZR_GetClassByName");
|
||||
MarkNativeAsOptional("ZR_GetClassByIdentifier");
|
||||
MarkNativeAsOptional("ZR_GetClassDisplayName");
|
||||
MarkNativeAsOptional("ZR_GetClassIdentifier");
|
||||
|
||||
MarkNativeAsOptional("ZR_IsClientZombie");
|
||||
MarkNativeAsOptional("ZR_IsClientHuman");
|
||||
|
@ -116,6 +116,19 @@ native ClassSelectResult ZR_SelectClientClass(int client, int classIndex, bool a
|
||||
*/
|
||||
native int ZR_GetClassByName(const char[] className, int cacheType = ZR_CLASS_CACHE_MODIFIED);
|
||||
|
||||
/**
|
||||
* Gets the class index of the class with the specified identifier.
|
||||
*
|
||||
* Note: This search is linear and probably won't perform well in large loops.
|
||||
*
|
||||
* @param classIdent Class identifier to search for.
|
||||
* @param cacheType Optional. Specifies which class cache to read from,
|
||||
* except player cache.
|
||||
*
|
||||
* @return Class index, or -1 if none found.
|
||||
*/
|
||||
native int ZR_GetClassByIdentifier(const char[] classIdent, int cacheType = ZR_CLASS_CACHE_MODIFIED);
|
||||
|
||||
/**
|
||||
* Gets the class name displayed in the class menu.
|
||||
*
|
||||
|
@ -39,7 +39,9 @@ APIClassInit()
|
||||
CreateNative("ZR_GetZombieClass", APIGetZombieClass);
|
||||
CreateNative("ZR_SelectClientClass", APISelectClientClass);
|
||||
CreateNative("ZR_GetClassByName", APIGetClassByName);
|
||||
CreateNative("ZR_GetClassByIdentifier", APIGetClassByIdentifier);
|
||||
CreateNative("ZR_GetClassDisplayName", APIGetClassDisplayName);
|
||||
CreateNative("ZR_GetClassIdentifier", APIGetClassIdentifier);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -148,7 +150,34 @@ public APIGetClassByName(Handle:plugin, numParams)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ClassGetIndex(className, cacheType);
|
||||
return ClassGetIndexByName(className, cacheType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Native call function (ZR_GetClassByIdentifier)
|
||||
*
|
||||
* native ZR_GetClassByIdentifier(const String:classIdent[], cacheType = ZR_CLASS_CACHE_MODIFIED);
|
||||
*/
|
||||
public APIGetClassByIdentifier(Handle:plugin, numParams)
|
||||
{
|
||||
decl String:classIdent[64];
|
||||
classIdent[0] = 0;
|
||||
|
||||
// Get class name.
|
||||
if (GetNativeString(1, classIdent, sizeof(classIdent)) != SP_ERROR_NONE)
|
||||
{
|
||||
ThrowNativeError(SP_ERROR_NATIVE, "Unexpected error when reading classIdent parameter. Possibly corrupt or missing data.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
new cacheType = GetNativeCell(2);
|
||||
if (cacheType == ZR_CLASS_CACHE_PLAYER)
|
||||
{
|
||||
ThrowNativeError(SP_ERROR_NATIVE, "Invalid cache type. Player cache is not allowed in this function.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ClassGetIndexByIdentifier(classIdent, cacheType);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -197,3 +226,50 @@ public APIGetClassDisplayName(Handle:plugin, numParams)
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Native call function (ZR_GetClassIdentifier)
|
||||
*
|
||||
* native ZR_GetClassIdentifier(classIndex, String:buffer[], maxlen, cacheType = ZR_CLASS_CACHE_MODIFIED);
|
||||
*/
|
||||
public APIGetClassIdentifier(Handle:plugin, numParams)
|
||||
{
|
||||
new index = GetNativeCell(1);
|
||||
new maxlen = GetNativeCell(3);
|
||||
new cacheType = GetNativeCell(4);
|
||||
|
||||
if (maxlen <= 0)
|
||||
{
|
||||
// No buffer size.
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Validate index.
|
||||
if (cacheType == ZR_CLASS_CACHE_PLAYER)
|
||||
{
|
||||
// Client index.
|
||||
APIValidateClientIndex(index, Condition_Either);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Class index.
|
||||
if (!ClassValidateIndex(index))
|
||||
{
|
||||
ThrowNativeError(SP_ERROR_NATIVE, "Invalid class index. (%d)", index);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
decl String:classIdent[maxlen];
|
||||
|
||||
new bytes = ClassGetIdentifier(index, classIdent, maxlen, cacheType);
|
||||
if (bytes <= 0)
|
||||
{
|
||||
// The class doesn't have a name for some reason. Make sure the buffer is empty.
|
||||
classIdent[0] = 0;
|
||||
}
|
||||
|
||||
SetNativeString(2, classIdent, maxlen);
|
||||
|
||||
return bytes;
|
||||
}
|
@ -42,7 +42,7 @@ CookiesInit()
|
||||
* @param client The client index.
|
||||
* @param cookie The handle to the cookie.
|
||||
*/
|
||||
bool:CookiesGetClientCookieBool(client, Handle:cookie)
|
||||
stock bool:CookiesGetClientCookieBool(client, Handle:cookie)
|
||||
{
|
||||
// Get cookie string.
|
||||
decl String:cookievalue[8];
|
||||
@ -59,7 +59,7 @@ bool:CookiesGetClientCookieBool(client, Handle:cookie)
|
||||
* @param cookie The handle to the cookie.
|
||||
* @param cookievalue The bool value to set cookie as.
|
||||
*/
|
||||
CookiesSetClientCookieBool(client, Handle:cookie, bool:cookievalue)
|
||||
stock CookiesSetClientCookieBool(client, Handle:cookie, bool:cookievalue)
|
||||
{
|
||||
// Convert bool to string.
|
||||
decl String:strCookievalue[8];
|
||||
@ -75,7 +75,7 @@ CookiesSetClientCookieBool(client, Handle:cookie, bool:cookievalue)
|
||||
* @param client The client index.
|
||||
* @param cookie The handle to the cookie.
|
||||
*/
|
||||
CookiesGetInt(client, Handle:cookie)
|
||||
stock CookiesGetInt(client, Handle:cookie)
|
||||
{
|
||||
decl String:strValue[16];
|
||||
strValue[0] = 0;
|
||||
@ -91,7 +91,7 @@ CookiesGetInt(client, Handle:cookie)
|
||||
* @param cookie The handle to the cookie.
|
||||
* @param value The value to set.
|
||||
*/
|
||||
CookiesSetInt(client, Handle:cookie, value)
|
||||
stock CookiesSetInt(client, Handle:cookie, value)
|
||||
{
|
||||
// Convert value to string.
|
||||
decl String:strValue[16];
|
||||
|
@ -33,6 +33,41 @@
|
||||
* ------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Gets the class identifier (config class section name).
|
||||
*
|
||||
* @param index Index of the class in a class cache or a client index,
|
||||
* depending on the cache type specified.
|
||||
* @param buffer The destination string buffer.
|
||||
* @param maxlen The length of the destination string buffer.
|
||||
* @param cachetype Optional. Specifies what class cache to read from. Options:
|
||||
* ZR_CLASS_CACHE_ORIGINAL - Unchanced class data.
|
||||
* ZR_CLASS_CACHE_MODIFIED - Changed/newest class data.
|
||||
* ZR_CLASS_CACHE_PLAYER (default) - Player cache. If this one
|
||||
* is used, index will be used as a client index.
|
||||
* @return Number of cells written. -1 on error.
|
||||
*/
|
||||
stock ClassGetIdentifier(index, String:buffer[], maxlen, cachetype = ZR_CLASS_CACHE_PLAYER)
|
||||
{
|
||||
switch (cachetype)
|
||||
{
|
||||
case ZR_CLASS_CACHE_ORIGINAL:
|
||||
{
|
||||
return strcopy(buffer, maxlen, ClassData[index][Class_Identifier]);
|
||||
}
|
||||
case ZR_CLASS_CACHE_MODIFIED:
|
||||
{
|
||||
return strcopy(buffer, maxlen, ClassDataCache[index][Class_Identifier]);
|
||||
}
|
||||
case ZR_CLASS_CACHE_PLAYER:
|
||||
{
|
||||
return strcopy(buffer, maxlen, ClassPlayerCache[index][Class_Identifier]);
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the specified class is enabled.
|
||||
*
|
||||
@ -1401,7 +1436,8 @@ stock ClassDataTypes:ClassGetAttributeType(attributeflag)
|
||||
}
|
||||
|
||||
// String.
|
||||
case ZR_CLASS_GROUP,
|
||||
case ZR_CLASS_IDENTIFIER,
|
||||
ZR_CLASS_GROUP,
|
||||
ZR_CLASS_NAME,
|
||||
ZR_CLASS_DESCRIPTION,
|
||||
ZR_CLASS_MODEL_PATH,
|
||||
|
@ -33,7 +33,7 @@ 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>");
|
||||
RegConsoleCmd("zr_class_dump_multipliers", ClassDumpMultipliersCommand, "Dumps class attribute multipliers for the specified team. Usage: zr_class_dump_multipliers <\"zombies\"|\"humans\">");
|
||||
RegConsoleCmd("zr_class_modify", ClassModifyCommand, "Modify class data on one or more classes. Usage: zr_class_modify <classname|\"zombies\"|\"humans\"|\"admins\"> <attribute> <value> [is_multiplier]");
|
||||
RegConsoleCmd("zr_class_modify", ClassModifyCommand, "Modify class data on one or more classes. Usage: zr_class_modify <identifier|\"zombies\"|\"humans\"|\"admins\"> <attribute> <value> [is_multiplier]");
|
||||
RegConsoleCmd("zr_class_set_multiplier", ClassSetMultiplierCommand, "Sets the multiplier on a class attribute. Usage: zr_class_set_multiplier <\"zombies\"|\"humans\"> <attribute> <value>");
|
||||
RegConsoleCmd("zr_class_reload", ClassReloadCommand, "Refreshes the player cache and reloads class attributes on one or more players. Usage: zr_class_reload <target>");
|
||||
}
|
||||
@ -297,7 +297,7 @@ public Action:ClassModifyCommand(client, argc)
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
decl String:classname[64];
|
||||
decl String:identifier[64];
|
||||
decl String:attributename[128];
|
||||
decl String:value[256];
|
||||
decl String:ismultiplier[4];
|
||||
@ -313,7 +313,7 @@ public Action:ClassModifyCommand(client, argc)
|
||||
classlist = CreateArray();
|
||||
|
||||
// Get command arguments.
|
||||
GetCmdArg(1, classname, sizeof(classname));
|
||||
GetCmdArg(1, identifier, sizeof(identifier));
|
||||
GetCmdArg(2, attributename, sizeof(attributename));
|
||||
GetCmdArg(3, value, sizeof(value));
|
||||
|
||||
@ -342,36 +342,36 @@ public Action:ClassModifyCommand(client, argc)
|
||||
// Get attribute data type.
|
||||
attributetype = ClassGetAttributeType(attributeflag);
|
||||
|
||||
// Check if classname is a group. Add classes to the class list
|
||||
// Check if identifier is a group. Add classes to the class list
|
||||
// and use the specified team filter.
|
||||
if (StrEqual(classname, "all", false))
|
||||
if (StrEqual(identifier, "all", false))
|
||||
{
|
||||
listresult = ClassAddToArray(classlist);
|
||||
isgroup = true;
|
||||
}
|
||||
else if (StrEqual(classname, "humans", false))
|
||||
else if (StrEqual(identifier, "humans", false))
|
||||
{
|
||||
listresult = ClassAddToArray(classlist, ZR_CLASS_TEAM_HUMANS);
|
||||
isgroup = true;
|
||||
}
|
||||
else if (StrEqual(classname, "zombies", false))
|
||||
else if (StrEqual(identifier, "zombies", false))
|
||||
{
|
||||
listresult = ClassAddToArray(classlist, ZR_CLASS_TEAM_ZOMBIES);
|
||||
isgroup = true;
|
||||
}
|
||||
else if (StrEqual(classname, "admins", false))
|
||||
else if (StrEqual(identifier, "admins", false))
|
||||
{
|
||||
listresult = ClassAddToArray(classlist, ZR_CLASS_TEAM_ADMINS);
|
||||
isgroup = true;
|
||||
}
|
||||
|
||||
// Check if classname is a group.
|
||||
// Check if identifier is a group.
|
||||
if (isgroup)
|
||||
{
|
||||
// Check if the list is valid.
|
||||
if (!listresult)
|
||||
{
|
||||
ReplyToCommand(client, "Failed to get classes in the specified team: \"%s\".", classname);
|
||||
ReplyToCommand(client, "Failed to get classes in the specified team: \"%s\".", identifier);
|
||||
CloseHandle(classlist);
|
||||
|
||||
return Plugin_Handled;
|
||||
@ -430,7 +430,7 @@ public Action:ClassModifyCommand(client, argc)
|
||||
else
|
||||
{
|
||||
// It's a single class.
|
||||
classindex = ClassGetIndex(classname);
|
||||
classindex = ClassGetIndexByIdentifier(identifier);
|
||||
|
||||
// Validate classindex.
|
||||
if (!ClassValidateIndex(classindex))
|
||||
|
@ -66,7 +66,7 @@ ClassOnCookiesCreate()
|
||||
ClassOnModulesLoaded()
|
||||
{
|
||||
// Set default classes on all player slots.
|
||||
ClassClientSetDefaultIndexes();
|
||||
ClassClientSetDefaultIdentifiers();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -149,7 +149,7 @@ ClassOnClientPostAdminCheck(client)
|
||||
if (ClassValidated)
|
||||
{
|
||||
// Set default class indexes on the player.
|
||||
ClassClientSetDefaultIndexes(client);
|
||||
ClassClientSetDefaultIdentifiers(client);
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,7 +175,7 @@ ClassOnCookiesCached(client)
|
||||
if (ClassValidated)
|
||||
{
|
||||
// Set default class indexes on the player.
|
||||
ClassClientSetDefaultIndexes(client);
|
||||
ClassClientSetDefaultIdentifiers(client);
|
||||
}
|
||||
}
|
||||
|
||||
@ -447,7 +447,7 @@ ClassOnClientInfected(client, bool:motherzombie = false)
|
||||
else
|
||||
{
|
||||
// Assume it's a class name. Get index for the specified class name.
|
||||
motherindex = ClassGetIndex(motherzombiesetting);
|
||||
motherindex = ClassGetIndexByIdentifier(motherzombiesetting);
|
||||
|
||||
// Validate index.
|
||||
if (ClassValidateIndex(motherindex))
|
||||
|
@ -265,6 +265,7 @@ ClassMenuSelect(client, teamid)
|
||||
new classindex;
|
||||
|
||||
decl String:title[MENU_LINE_TITLE_LENGTH];
|
||||
decl String:classident[64];
|
||||
decl String:classname[MENU_LINE_REG_LENGTH];
|
||||
decl String:description[MENU_LINE_BIG_LENGTH];
|
||||
decl String:menuitem[MENU_LINE_HUGE_LENGTH];
|
||||
@ -319,12 +320,13 @@ ClassMenuSelect(client, teamid)
|
||||
{
|
||||
// Get index, name and description.
|
||||
classindex = GetArrayCell(classarray, i);
|
||||
ClassGetIdentifier(classindex, classident, sizeof(classident));
|
||||
ClassGetName(classindex, classname, sizeof(classname), ZR_CLASS_CACHE_MODIFIED);
|
||||
ClassGetDescription(classindex, description, sizeof(description), ZR_CLASS_CACHE_MODIFIED);
|
||||
|
||||
// Add menu item. Using extra spaces for indention on the second line.
|
||||
Format(menuitem, sizeof(menuitem), "%s\n %s", classname, description);
|
||||
AddMenuItem(menu, classname, menuitem);
|
||||
AddMenuItem(menu, classident, menuitem);
|
||||
}
|
||||
}
|
||||
|
||||
@ -340,7 +342,7 @@ ClassMenuSelect(client, teamid)
|
||||
*/
|
||||
public ClassMenuSelectHandle(Handle:menu, MenuAction:action, client, slot)
|
||||
{
|
||||
decl String:className[MENU_LINE_REG_LENGTH];
|
||||
decl String:classIdent[MENU_LINE_REG_LENGTH];
|
||||
new classIndex;
|
||||
new bool:autoclose = GetConVarBool(g_hCvarsList[CVAR_CLASSES_MENU_AUTOCLOSE]);
|
||||
|
||||
@ -349,10 +351,10 @@ public ClassMenuSelectHandle(Handle:menu, MenuAction:action, client, slot)
|
||||
case MenuAction_Select:
|
||||
{
|
||||
// Get class name from the information string.
|
||||
GetMenuItem(menu, slot, className, sizeof(className));
|
||||
GetMenuItem(menu, slot, classIdent, sizeof(classIdent));
|
||||
|
||||
// Solve class index from the name.
|
||||
classIndex = ClassGetIndex(className);
|
||||
classIndex = ClassGetIndexByIdentifier(classIdent);
|
||||
|
||||
// Select (and eventually apply) class.
|
||||
ClassSelectClientClass(client, classIndex);
|
||||
|
@ -105,6 +105,44 @@ stock ClassValidateAttributes(classindex, bool:logErrors = false)
|
||||
{
|
||||
new flags;
|
||||
|
||||
// Identifier
|
||||
decl String:identifier[64];
|
||||
identifier[0] = 0;
|
||||
if (strcopy(identifier, sizeof(identifier), ClassData[classindex][Class_Identifier]) < ZR_CLASS_IDENTIFIER_MIN)
|
||||
{
|
||||
flags += ZR_CLASS_IDENTIFIER;
|
||||
if (logErrors)
|
||||
{
|
||||
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Warning: Missing identifier at index %d.", classindex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check for reserved identifier keyworks. These aren't allowed as identifiers.
|
||||
if (StrEqual(identifier, "all", false) ||
|
||||
StrEqual(identifier, "humans", false) ||
|
||||
StrEqual(identifier, "zombies", false) ||
|
||||
StrEqual(identifier, "admins", false))
|
||||
{
|
||||
flags += ZR_CLASS_IDENTIFIER;
|
||||
if (logErrors)
|
||||
{
|
||||
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Warning: Invalid identifier at index %d. Cannot be a team identifier: \"%s\"", classindex, identifier);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for duplicate use.
|
||||
int duplicate = ClassGetIndexByIdentifier(identifier);
|
||||
if (duplicate >= 0)
|
||||
{
|
||||
flags += ZR_CLASS_IDENTIFIER;
|
||||
if (logErrors)
|
||||
{
|
||||
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Warning: Invalid identifier at index %d. Already exists at index %d: \"%s\".", classindex, duplicate, identifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Team.
|
||||
new team = ClassData[classindex][Class_Team];
|
||||
if (team < ZR_CLASS_TEAM_MIN || team > ZR_CLASS_TEAM_MAX)
|
||||
@ -710,7 +748,7 @@ stock bool:ClassTeamCompare(index, teamid, cachetype = ZR_CLASS_CACHE_MODIFIED)
|
||||
* data.
|
||||
* @return The class index if successful, -1 otherwise.
|
||||
*/
|
||||
stock ClassGetIndex(const String:name[], cachetype = ZR_CLASS_CACHE_MODIFIED)
|
||||
stock ClassGetIndexByName(const String:name[], cachetype = ZR_CLASS_CACHE_MODIFIED)
|
||||
{
|
||||
decl String:current_name[64];
|
||||
|
||||
@ -735,6 +773,42 @@ stock ClassGetIndex(const String:name[], cachetype = ZR_CLASS_CACHE_MODIFIED)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first class index of a class with the specified identifier (not a case
|
||||
* sensitive search).
|
||||
*
|
||||
* @param ident The identifier to search for.
|
||||
* @param cachetype Optional. Specifies what class cache to read from. Options:
|
||||
* ZR_CLASS_CACHE_ORIGINAL - Unchanced class data.
|
||||
* ZR_CLASS_CACHE_MODIFIED (default) - Changed/newest class
|
||||
* data.
|
||||
* @return The class index if successful, -1 otherwise.
|
||||
*/
|
||||
stock ClassGetIndexByIdentifier(const String:ident[], cachetype = ZR_CLASS_CACHE_MODIFIED)
|
||||
{
|
||||
decl String:current_ident[64];
|
||||
|
||||
// Check if there are no classes, or reading from player cache.
|
||||
if (ClassCount == 0 || cachetype == ZR_CLASS_CACHE_PLAYER)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Loop through all classes.
|
||||
for (new classindex = 0; classindex < ClassCount; classindex++)
|
||||
{
|
||||
// Get its ident and compare it with the specified class ident.
|
||||
ClassGetIdentifier(classindex, current_ident, sizeof(current_ident), cachetype);
|
||||
if (strcmp(ident, current_ident, false) == 0)
|
||||
{
|
||||
return classindex;
|
||||
}
|
||||
}
|
||||
|
||||
// The class index wasn't found.
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the currently active class index that the player is using.
|
||||
* Note: Does not check if the player is dead.
|
||||
@ -1301,7 +1375,7 @@ stock ClassGetDefaultClass(teamid, filter[ClassFilter] = ClassNoSpecialClasses,
|
||||
*/
|
||||
stock ClassGetDefaultSpawnClass(teamid, filter[ClassFilter] = ClassNoSpecialClasses, cachetype = ZR_CLASS_CACHE_MODIFIED)
|
||||
{
|
||||
decl String:classname[64];
|
||||
decl String:classident[64];
|
||||
new classindex;
|
||||
|
||||
// Get the default class name from the correct CVAR depending on teamid.
|
||||
@ -1309,15 +1383,15 @@ stock ClassGetDefaultSpawnClass(teamid, filter[ClassFilter] = ClassNoSpecialClas
|
||||
{
|
||||
case ZR_CLASS_TEAM_ZOMBIES:
|
||||
{
|
||||
GetConVarString(g_hCvarsList[CVAR_CLASSES_DEFAULT_ZOMBIE], classname, sizeof(classname));
|
||||
GetConVarString(g_hCvarsList[CVAR_CLASSES_DEFAULT_ZOMBIE], classident, sizeof(classident));
|
||||
}
|
||||
case ZR_CLASS_TEAM_HUMANS:
|
||||
{
|
||||
GetConVarString(g_hCvarsList[CVAR_CLASSES_DEFAULT_HUMAN], classname, sizeof(classname));
|
||||
GetConVarString(g_hCvarsList[CVAR_CLASSES_DEFAULT_HUMAN], classident, sizeof(classident));
|
||||
}
|
||||
case ZR_CLASS_TEAM_ADMINS:
|
||||
{
|
||||
GetConVarString(g_hCvarsList[CVAR_CLASSES_DEFAULT_ADMIN_MODE], classname, sizeof(classname));
|
||||
GetConVarString(g_hCvarsList[CVAR_CLASSES_DEFAULT_ADMIN_MODE], classident, sizeof(classident));
|
||||
}
|
||||
default:
|
||||
{
|
||||
@ -1327,10 +1401,10 @@ stock ClassGetDefaultSpawnClass(teamid, filter[ClassFilter] = ClassNoSpecialClas
|
||||
}
|
||||
|
||||
// Check if the class name isn't empty.
|
||||
if (strlen(classname) > 0)
|
||||
if (strlen(classident) > 0)
|
||||
{
|
||||
// Check if the user set "random" as default class.
|
||||
if (StrEqual(classname, "random", false))
|
||||
if (StrEqual(classident, "random", false))
|
||||
{
|
||||
// Get a list of all classes with the specified team ID. Deny
|
||||
// classes with special flags.
|
||||
@ -1354,7 +1428,7 @@ stock ClassGetDefaultSpawnClass(teamid, filter[ClassFilter] = ClassNoSpecialClas
|
||||
// The user set a spesific class.
|
||||
|
||||
// Try to get the class index with the specified class name.
|
||||
classindex = ClassGetIndex(classname, cachetype);
|
||||
classindex = ClassGetIndexByIdentifier(classident, cachetype);
|
||||
|
||||
// Validate the class index and check if the team IDs match.
|
||||
if (ClassValidateIndex(classindex) && (teamid == ClassGetTeamID(classindex, cachetype)))
|
||||
@ -1368,7 +1442,7 @@ stock ClassGetDefaultSpawnClass(teamid, filter[ClassFilter] = ClassNoSpecialClas
|
||||
// in the specified team, and log a warning.
|
||||
classindex = ClassGetFirstClass(teamid, filter, cachetype);
|
||||
|
||||
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Default Spawn Class", "Warning: Failed to set \"%s\" as default spawn class for team %d. The class doesn't exist or the team IDs doesn't match. Falling back to the first class in the team.", classname, teamid);
|
||||
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Default Spawn Class", "Warning: Failed to set \"%s\" as default spawn class for team %d. The class doesn't exist or the team IDs doesn't match. Falling back to the first class in the team.", classident, teamid);
|
||||
|
||||
// Validate the new index.
|
||||
if (ClassValidateIndex(classindex))
|
||||
|
@ -137,6 +137,7 @@
|
||||
/**
|
||||
* @section Attribute limit values. Used when validating.
|
||||
*/
|
||||
#define ZR_CLASS_IDENTIFIER_MIN 1
|
||||
#define ZR_CLASS_TEAM_MIN 0
|
||||
#define ZR_CLASS_TEAM_MAX 2
|
||||
#define ZR_CLASS_FLAGS_MIN 0
|
||||
@ -186,37 +187,38 @@
|
||||
/**
|
||||
* @section Class attribute flags.
|
||||
*/
|
||||
#define ZR_CLASS_ENABLED (1<<0)
|
||||
#define ZR_CLASS_TEAM (1<<1)
|
||||
#define ZR_CLASS_TEAM_DEFAULT (1<<2)
|
||||
#define ZR_CLASS_FLAGS (1<<3)
|
||||
#define ZR_CLASS_GROUP (1<<4)
|
||||
#define ZR_CLASS_SM_FLAGS (1<<5)
|
||||
#define ZR_CLASS_NAME (1<<6)
|
||||
#define ZR_CLASS_DESCRIPTION (1<<7)
|
||||
#define ZR_CLASS_MODEL_PATH (1<<8)
|
||||
#define ZR_CLASS_MODEL_SKIN_INDEX (1<<9)
|
||||
#define ZR_CLASS_ALPHA_INITIAL (1<<10)
|
||||
#define ZR_CLASS_ALPHA_DAMAGED (1<<11)
|
||||
#define ZR_CLASS_ALPHA_DAMAGE (1<<12)
|
||||
#define ZR_CLASS_OVERLAY_PATH (1<<13)
|
||||
#define ZR_CLASS_NVGS (1<<14)
|
||||
#define ZR_CLASS_FOV (1<<15)
|
||||
#define ZR_CLASS_HAS_NAPALM (1<<16)
|
||||
#define ZR_CLASS_NAPALM_TIME (1<<17)
|
||||
#define ZR_CLASS_IMMUNITY_MODE (1<<18)
|
||||
#define ZR_CLASS_IMMUNITY_AMOUNT (1<<19)
|
||||
#define ZR_CLASS_IMMUNITY_COOLDOWN (1<<20)
|
||||
#define ZR_CLASS_NO_FALL_DAMAGE (1<<21)
|
||||
#define ZR_CLASS_HEALTH (1<<22)
|
||||
#define ZR_CLASS_HEALTH_REGEN_INTERVAL (1<<23)
|
||||
#define ZR_CLASS_HEALTH_REGEN_AMOUNT (1<<24)
|
||||
#define ZR_CLASS_HEALTH_INFECT_GAIN (1<<25)
|
||||
#define ZR_CLASS_KILL_BONUS (1<<26)
|
||||
#define ZR_CLASS_SPEED (1<<27)
|
||||
#define ZR_CLASS_KNOCKBACK (1<<28)
|
||||
#define ZR_CLASS_JUMP_HEIGHT (1<<29)
|
||||
#define ZR_CLASS_JUMP_DISTANCE (1<<30)
|
||||
#define ZR_CLASS_IDENTIFIER (1<<0)
|
||||
#define ZR_CLASS_ENABLED (1<<1)
|
||||
#define ZR_CLASS_TEAM (1<<2)
|
||||
#define ZR_CLASS_TEAM_DEFAULT (1<<3)
|
||||
#define ZR_CLASS_FLAGS (1<<4)
|
||||
#define ZR_CLASS_GROUP (1<<5)
|
||||
#define ZR_CLASS_SM_FLAGS (1<<6)
|
||||
#define ZR_CLASS_NAME (1<<7)
|
||||
#define ZR_CLASS_DESCRIPTION (1<<8)
|
||||
#define ZR_CLASS_MODEL_PATH (1<<9)
|
||||
#define ZR_CLASS_MODEL_SKIN_INDEX (1<<10)
|
||||
#define ZR_CLASS_ALPHA_INITIAL (1<<11)
|
||||
#define ZR_CLASS_ALPHA_DAMAGED (1<<12)
|
||||
#define ZR_CLASS_ALPHA_DAMAGE (1<<13)
|
||||
#define ZR_CLASS_OVERLAY_PATH (1<<14)
|
||||
#define ZR_CLASS_NVGS (1<<15)
|
||||
#define ZR_CLASS_FOV (1<<16)
|
||||
#define ZR_CLASS_HAS_NAPALM (1<<17)
|
||||
#define ZR_CLASS_NAPALM_TIME (1<<18)
|
||||
#define ZR_CLASS_IMMUNITY_MODE (1<<19)
|
||||
#define ZR_CLASS_IMMUNITY_AMOUNT (1<<20)
|
||||
#define ZR_CLASS_IMMUNITY_COOLDOWN (1<<21)
|
||||
#define ZR_CLASS_NO_FALL_DAMAGE (1<<22)
|
||||
#define ZR_CLASS_HEALTH (1<<23)
|
||||
#define ZR_CLASS_HEALTH_REGEN_INTERVAL (1<<24)
|
||||
#define ZR_CLASS_HEALTH_REGEN_AMOUNT (1<<25)
|
||||
#define ZR_CLASS_HEALTH_INFECT_GAIN (1<<26)
|
||||
#define ZR_CLASS_KILL_BONUS (1<<27)
|
||||
#define ZR_CLASS_SPEED (1<<28)
|
||||
#define ZR_CLASS_KNOCKBACK (1<<29)
|
||||
#define ZR_CLASS_JUMP_HEIGHT (1<<30)
|
||||
#define ZR_CLASS_JUMP_DISTANCE (1<<31)
|
||||
/**
|
||||
* @endsection
|
||||
*/
|
||||
@ -243,6 +245,7 @@
|
||||
enum ClassAttributes
|
||||
{
|
||||
/* General */
|
||||
String:Class_Identifier[64],
|
||||
bool:Class_Enabled,
|
||||
Class_Team,
|
||||
bool:Class_TeamDefault,
|
||||
@ -560,6 +563,7 @@ ClassLoad()
|
||||
LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Can't find any classes in \"%s\"", pathclasses);
|
||||
}
|
||||
|
||||
new String:section_name[64];
|
||||
new String:name[64];
|
||||
new String:group[64];
|
||||
new String:sm_flags[64];
|
||||
@ -583,6 +587,10 @@ ClassLoad()
|
||||
break;
|
||||
}
|
||||
|
||||
/* Class identifier = section name */
|
||||
KvGetSectionName(kvClassData, section_name, sizeof(section_name));
|
||||
strcopy(ClassData[ClassCount][Class_Identifier], 64, section_name);
|
||||
|
||||
/* General */
|
||||
ClassData[ClassCount][Class_Enabled] = ConfigKvGetStringBool(kvClassData, "enabled", ZR_CLASS_DEFAULT_ENABLED);
|
||||
ClassData[ClassCount][Class_Team] = KvGetNum(kvClassData, "team", ZR_CLASS_DEFAULT_TEAM);
|
||||
@ -748,6 +756,7 @@ bool:ClassReloadDataCache()
|
||||
for (new classindex = 0; classindex < ClassCount; classindex++)
|
||||
{
|
||||
/* General */
|
||||
strcopy(ClassDataCache[classindex][Class_Identifier], 64, ClassData[classindex][Class_Identifier]);
|
||||
ClassDataCache[classindex][Class_Enabled] = ClassData[classindex][Class_Enabled];
|
||||
ClassDataCache[classindex][Class_Team] = ClassData[classindex][Class_Team];
|
||||
ClassDataCache[classindex][Class_TeamDefault] = ClassData[classindex][Class_TeamDefault];
|
||||
@ -816,6 +825,7 @@ bool:ClassReloadPlayerCache(client, classindex, cachetype = ZR_CLASS_CACHE_MODIF
|
||||
case ZR_CLASS_CACHE_ORIGINAL:
|
||||
{
|
||||
/* General */
|
||||
strcopy(ClassPlayerCache[client][Class_Identifier], 64, ClassData[classindex][Class_Identifier]);
|
||||
ClassPlayerCache[client][Class_Enabled] = ClassData[classindex][Class_Enabled];
|
||||
ClassPlayerCache[client][Class_Team] = ClassData[classindex][Class_Team];
|
||||
ClassPlayerCache[client][Class_TeamDefault] = ClassData[classindex][Class_TeamDefault];
|
||||
@ -859,6 +869,7 @@ bool:ClassReloadPlayerCache(client, classindex, cachetype = ZR_CLASS_CACHE_MODIF
|
||||
case ZR_CLASS_CACHE_MODIFIED:
|
||||
{
|
||||
/* General */
|
||||
strcopy(ClassPlayerCache[client][Class_Identifier], 64, ClassDataCache[classindex][Class_Identifier]);
|
||||
ClassPlayerCache[client][Class_Enabled] = ClassDataCache[classindex][Class_Enabled];
|
||||
ClassPlayerCache[client][Class_Team] = ClassDataCache[classindex][Class_Team];
|
||||
ClassPlayerCache[client][Class_TeamDefault] = ClassDataCache[classindex][Class_TeamDefault];
|
||||
@ -1042,20 +1053,25 @@ ClassRestoreNextIndexes(client, excludeTeam = -1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets default class indexes for each team on all players, or a single player
|
||||
* Sets default class identifiers for each team on all players, or a single player
|
||||
* if specified.
|
||||
*
|
||||
* @param client Optional. The client index. If specified, cookies are used.
|
||||
*/
|
||||
ClassClientSetDefaultIndexes(client = -1)
|
||||
ClassClientSetDefaultIdentifiers(client = -1)
|
||||
{
|
||||
new bool:clientvalid = ZRIsClientValid(client);
|
||||
new filter[ClassFilter];
|
||||
new filter_valid[ClassFilter];
|
||||
new bool:saveclasses = GetConVarBool(g_hCvarsList[CVAR_CLASSES_SAVE]);
|
||||
|
||||
new zombieindex;
|
||||
new humanindex;
|
||||
new adminindex;
|
||||
char zombie_ident[64];
|
||||
char human_ident[64];
|
||||
char admin_ident[64];
|
||||
|
||||
new zombieindex = -1;
|
||||
new humanindex = -1;
|
||||
new adminindex = -1;
|
||||
|
||||
new bool:haszombie;
|
||||
new bool:hashuman;
|
||||
@ -1066,17 +1082,26 @@ ClassClientSetDefaultIndexes(client = -1)
|
||||
* SETUP CLASS FILTER
|
||||
*/
|
||||
|
||||
// Do not require class to be enabled.
|
||||
// Disabled classes should not be deleted from the client cookies.
|
||||
// We'll manually check if the class is disabled later.
|
||||
filter_valid[ClassFilter_IgnoreEnabled] = true;
|
||||
|
||||
// Do not require any class flags to be set.
|
||||
filter[ClassFilter_RequireFlags] = 0;
|
||||
filter_valid[ClassFilter_RequireFlags] = 0;
|
||||
|
||||
// Set filter to hide mother zombie classes.
|
||||
filter[ClassFilter_DenyFlags] = ZR_CLASS_FLAG_MOTHER_ZOMBIE;
|
||||
filter_valid[ClassFilter_DenyFlags] = ZR_CLASS_FLAG_MOTHER_ZOMBIE;
|
||||
|
||||
// Set filter to also hide admin-only classes if not admin.
|
||||
filter[ClassFilter_DenyFlags] += !ZRIsClientAdmin(client) ? ZR_CLASS_FLAG_ADMIN_ONLY : 0;
|
||||
filter_valid[ClassFilter_DenyFlags] += !ZRIsClientAdmin(client) ? ZR_CLASS_FLAG_ADMIN_ONLY : 0;
|
||||
|
||||
// Specify client so it can check group permissions.
|
||||
filter[ClassFilter_Client] = client;
|
||||
filter_valid[ClassFilter_Client] = client;
|
||||
|
||||
|
||||
/*
|
||||
@ -1089,61 +1114,61 @@ ClassClientSetDefaultIndexes(client = -1)
|
||||
// Get cookie indexes if enabled.
|
||||
if (saveclasses)
|
||||
{
|
||||
zombieindex = CookiesGetInt(client, g_hClassCookieClassSelected[ZR_CLASS_TEAM_ZOMBIES]);
|
||||
humanindex = CookiesGetInt(client, g_hClassCookieClassSelected[ZR_CLASS_TEAM_HUMANS]);
|
||||
adminindex = CookiesGetInt(client, g_hClassCookieClassSelected[ZR_CLASS_TEAM_ADMINS]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Do not use indexes in cookies. Set invalid values so it will
|
||||
// fall back to default class.
|
||||
zombieindex = 0;
|
||||
humanindex = 0;
|
||||
adminindex = 0;
|
||||
GetClientCookie(client, g_hClassCookieClassSelected[ZR_CLASS_TEAM_ZOMBIES], zombie_ident, sizeof(zombie_ident));
|
||||
GetClientCookie(client, g_hClassCookieClassSelected[ZR_CLASS_TEAM_HUMANS], human_ident, sizeof(human_ident));
|
||||
GetClientCookie(client, g_hClassCookieClassSelected[ZR_CLASS_TEAM_ADMINS], admin_ident, sizeof(admin_ident));
|
||||
|
||||
zombieindex = ClassGetIndexByIdentifier(zombie_ident);
|
||||
humanindex = ClassGetIndexByIdentifier(human_ident);
|
||||
adminindex = ClassGetIndexByIdentifier(admin_ident);
|
||||
}
|
||||
|
||||
// Note: When class indexes are set on cookies, they're incremented by
|
||||
// one so zero means no class set and will result in a invalid
|
||||
// class index when restored.
|
||||
|
||||
// Check if class indexes are set and that the client pass the filter.
|
||||
// Check if class identifiers are set and that the client pass the filter.
|
||||
// Also check that the saved class' team id match with the loaded class.
|
||||
// If not, fall back to default class indexes. Otherwise substract
|
||||
// index by one.
|
||||
if (zombieindex <= 0 ||
|
||||
!ClassTeamCompare(zombieindex - 1, ZR_CLASS_TEAM_ZOMBIES) ||
|
||||
!ClassFilterMatch(zombieindex - 1, filter))
|
||||
// If not, fall back to default class indexes.
|
||||
if (zombieindex < 0 ||
|
||||
!ClassTeamCompare(zombieindex, ZR_CLASS_TEAM_ZOMBIES) ||
|
||||
!ClassFilterMatch(zombieindex, filter_valid))
|
||||
{
|
||||
zombieindex = ClassGetDefaultSpawnClass(ZR_CLASS_TEAM_ZOMBIES, filter);
|
||||
}
|
||||
else
|
||||
{
|
||||
zombieindex--;
|
||||
haszombie = true;
|
||||
if (!ClassIsEnabled(zombieindex))
|
||||
{
|
||||
zombieindex = ClassGetDefaultSpawnClass(ZR_CLASS_TEAM_ZOMBIES, filter);
|
||||
}
|
||||
}
|
||||
|
||||
if (humanindex <= 0 ||
|
||||
!ClassTeamCompare(humanindex - 1, ZR_CLASS_TEAM_HUMANS) ||
|
||||
!ClassFilterMatch(humanindex - 1, filter))
|
||||
if (humanindex < 0 ||
|
||||
!ClassTeamCompare(humanindex, ZR_CLASS_TEAM_HUMANS) ||
|
||||
!ClassFilterMatch(humanindex, filter_valid))
|
||||
{
|
||||
humanindex = ClassGetDefaultSpawnClass(ZR_CLASS_TEAM_HUMANS, filter);
|
||||
}
|
||||
else
|
||||
{
|
||||
humanindex--;
|
||||
hashuman = true;
|
||||
if (!ClassIsEnabled(humanindex))
|
||||
{
|
||||
humanindex = ClassGetDefaultSpawnClass(ZR_CLASS_TEAM_HUMANS, filter);
|
||||
}
|
||||
}
|
||||
|
||||
if (adminindex <= 0 ||
|
||||
!ClassTeamCompare(adminindex - 1, ZR_CLASS_TEAM_ADMINS) ||
|
||||
!ClassFilterMatch(adminindex - 1, filter))
|
||||
if (adminindex < 0 ||
|
||||
!ClassTeamCompare(adminindex, ZR_CLASS_TEAM_ADMINS) ||
|
||||
!ClassFilterMatch(adminindex, filter_valid))
|
||||
{
|
||||
adminindex = ClassGetDefaultSpawnClass(ZR_CLASS_TEAM_ADMINS, filter);
|
||||
}
|
||||
else
|
||||
{
|
||||
adminindex--;
|
||||
hasadmin = true;
|
||||
if (!ClassIsEnabled(adminindex))
|
||||
{
|
||||
adminindex = ClassGetDefaultSpawnClass(ZR_CLASS_TEAM_ADMINS, filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1211,17 +1236,20 @@ ClassClientSetDefaultIndexes(client = -1)
|
||||
// Save indexes in cookies if enabled, and not already saved.
|
||||
if (saveclasses)
|
||||
{
|
||||
if (!haszombie)
|
||||
if (!haszombie && zombieindex != -1)
|
||||
{
|
||||
CookiesSetInt(client, g_hClassCookieClassSelected[ZR_CLASS_TEAM_ZOMBIES], zombieindex + 1);
|
||||
ClassGetIdentifier(zombieindex, zombie_ident, sizeof(zombie_ident));
|
||||
SetClientCookie(client, g_hClassCookieClassSelected[ZR_CLASS_TEAM_ZOMBIES], zombie_ident);
|
||||
}
|
||||
if (!hashuman)
|
||||
if (!hashuman && humanindex != -1)
|
||||
{
|
||||
CookiesSetInt(client, g_hClassCookieClassSelected[ZR_CLASS_TEAM_HUMANS], humanindex + 1);
|
||||
ClassGetIdentifier(humanindex, human_ident, sizeof(human_ident));
|
||||
SetClientCookie(client, g_hClassCookieClassSelected[ZR_CLASS_TEAM_HUMANS], human_ident);
|
||||
}
|
||||
if (!hasadmin)
|
||||
if (!hasadmin && adminindex != -1)
|
||||
{
|
||||
CookiesSetInt(client, g_hClassCookieClassSelected[ZR_CLASS_TEAM_ADMINS], adminindex + 1);
|
||||
ClassGetIdentifier(adminindex, admin_ident, sizeof(admin_ident));
|
||||
SetClientCookie(client, g_hClassCookieClassSelected[ZR_CLASS_TEAM_ADMINS], admin_ident);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1350,6 +1378,10 @@ ClassDumpData(index, cachetype, String:buffer[], maxlen)
|
||||
cellcount += StrCat(buffer, maxlen, format_buffer);
|
||||
cellcount += StrCat(buffer, maxlen, "-------------------------------------------------------------------------------\n");
|
||||
|
||||
ClassGetIdentifier(index, format_buffer, sizeof(format_buffer), cachetype);
|
||||
Format(attribute, sizeof(attribute), "identifier: \"%s\"\n", format_buffer);
|
||||
cellcount += StrCat(buffer, maxlen, attribute);
|
||||
|
||||
Format(attribute, sizeof(attribute), "enabled: \"%d\"\n", ClassIsEnabled(index, cachetype));
|
||||
cellcount += StrCat(buffer, maxlen, attribute);
|
||||
|
||||
|
@ -476,7 +476,7 @@ VolClassEditApply(client, dataIndex)
|
||||
case ClassEditMode_Name:
|
||||
{
|
||||
// Cache volume attributes.
|
||||
new classindex = ClassGetIndex(VolClassEditData[dataIndex][VolClassEdit_ClassName]);
|
||||
new classindex = ClassGetIndexByName(VolClassEditData[dataIndex][VolClassEdit_ClassName]);
|
||||
|
||||
// Save player's selected class.
|
||||
VolClassEditSelectedClass[client] = ClassGetActiveIndex(client);
|
||||
|
Loading…
Reference in New Issue
Block a user