diff --git a/src/zr/playerclasses/attributes.inc b/src/zr/playerclasses/attributes.inc index 0a0b075..848c398 100644 --- a/src/zr/playerclasses/attributes.inc +++ b/src/zr/playerclasses/attributes.inc @@ -234,6 +234,41 @@ stock ClassGetGroup(index, String:buffer[], maxlen, cachetype = ZR_CLASS_CACHE_P return -1; } +/** + * Gets the class sourcemod flags required to use the class. + * + * @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 ClassGetSM_Flags(index, String:buffer[], maxlen, cachetype = ZR_CLASS_CACHE_PLAYER) +{ + switch (cachetype) + { + case ZR_CLASS_CACHE_ORIGINAL: + { + return strcopy(buffer, maxlen, ClassData[index][Class_SM_Flags]); + } + case ZR_CLASS_CACHE_MODIFIED: + { + return strcopy(buffer, maxlen, ClassDataCache[index][Class_SM_Flags]); + } + case ZR_CLASS_CACHE_PLAYER: + { + return strcopy(buffer, maxlen, ClassPlayerCache[index][Class_SM_Flags]); + } + } + + return -1; +} + /** * Gets the class name displayed in the class menu. * @@ -1157,6 +1192,10 @@ stock ClassAttributeNameToFlag(const String:attributename[]) { return ZR_CLASS_GROUP; } + else if (StrEqual(attributename, "group", false)) + { + return ZR_CLASS_SM_FLAGS; + } else if (StrEqual(attributename, "name", false)) { return ZR_CLASS_NAME; diff --git a/src/zr/playerclasses/classcommands.inc b/src/zr/playerclasses/classcommands.inc index 5b861a7..5276edf 100644 --- a/src/zr/playerclasses/classcommands.inc +++ b/src/zr/playerclasses/classcommands.inc @@ -903,6 +903,11 @@ stock ClassModifyString(classindex, attributeflag, const String:value[]) strcopy(ClassDataCache[classindex][Class_Group], 64, value); return true; } + case ZR_CLASS_SM_FLAGS: + { + strcopy(ClassDataCache[classindex][Class_SM_Flags], 64, value); + return true; + } case ZR_CLASS_NAME: { strcopy(ClassDataCache[classindex][Class_Name], 64, value); diff --git a/src/zr/playerclasses/filtertools.inc b/src/zr/playerclasses/filtertools.inc index 2a89c27..f646e70 100644 --- a/src/zr/playerclasses/filtertools.inc +++ b/src/zr/playerclasses/filtertools.inc @@ -842,6 +842,11 @@ stock bool:ClassFilterMatch(index, filter[ClassFilter], cachetype = ZR_CLASS_CAC groupname[0] = 0; ClassGetGroup(index, groupname, sizeof(groupname), cachetype); + // Get class sm_flags. + decl String:sm_flags[64]; + sm_flags[0] = 0; + ClassGetSM_Flags(index, sm_flags, sizeof(sm_flags), cachetype); + // Check if a client is specified in the filter. new client = filter[ClassFilter_Client]; if (ZRIsClientValid(client)) @@ -855,6 +860,19 @@ stock bool:ClassFilterMatch(index, filter[ClassFilter], cachetype = ZR_CLASS_CAC return false; } } + // Check if there are any sm_flags set. + if (strlen(sm_flags)) + { + int flags = ReadFlagString(sm_flags); + + // No valid flag, blocked for everyone. + if(!flags) + return false; + + // Check if user doesn't have the required flags. + if(GetUserFlagBits(client) & flags != flags) + return false; + } } // Check if classes with groups are set to be excluded. @@ -865,6 +883,12 @@ stock bool:ClassFilterMatch(index, filter[ClassFilter], cachetype = ZR_CLASS_CAC { return false; } + + // Exclude class if it requires flags. + if (strlen(sm_flags)) + { + return false; + } } // The class passed the filter. diff --git a/src/zr/playerclasses/playerclasses.inc b/src/zr/playerclasses/playerclasses.inc index 5c2d139..5504570 100644 --- a/src/zr/playerclasses/playerclasses.inc +++ b/src/zr/playerclasses/playerclasses.inc @@ -104,6 +104,7 @@ #define ZR_CLASS_DEFAULT_TEAM_DEFAULT "yes" #define ZR_CLASS_DEFAULT_FLAGS 0 #define ZR_CLASS_DEFAULT_GROUP "" +#define ZR_CLASS_DEFAULT_SM_FLAGS "" #define ZR_CLASS_DEFAULT_NAME "classic" #define ZR_CLASS_DEFAULT_DESCRIPTION "Need brains!!! Arrrrggghh!" #define ZR_CLASS_DEFAULT_MODEL_PATH "models/player/zh/zh_zombie003.mdl" @@ -190,31 +191,32 @@ #define ZR_CLASS_TEAM_DEFAULT (1<<2) #define ZR_CLASS_FLAGS (1<<3) #define ZR_CLASS_GROUP (1<<4) -#define ZR_CLASS_NAME (1<<5) -#define ZR_CLASS_DESCRIPTION (1<<6) -#define ZR_CLASS_MODEL_PATH (1<<7) -#define ZR_CLASS_MODEL_SKIN_INDEX (1<<8) -#define ZR_CLASS_ALPHA_INITIAL (1<<9) -#define ZR_CLASS_ALPHA_DAMAGED (1<<10) -#define ZR_CLASS_ALPHA_DAMAGE (1<<11) -#define ZR_CLASS_OVERLAY_PATH (1<<12) -#define ZR_CLASS_NVGS (1<<13) -#define ZR_CLASS_FOV (1<<14) -#define ZR_CLASS_HAS_NAPALM (1<<15) -#define ZR_CLASS_NAPALM_TIME (1<<16) -#define ZR_CLASS_IMMUNITY_MODE (1<<17) -#define ZR_CLASS_IMMUNITY_AMOUNT (1<<18) -#define ZR_CLASS_IMMUNITY_COOLDOWN (1<<19) -#define ZR_CLASS_NO_FALL_DAMAGE (1<<20) -#define ZR_CLASS_HEALTH (1<<21) -#define ZR_CLASS_HEALTH_REGEN_INTERVAL (1<<22) -#define ZR_CLASS_HEALTH_REGEN_AMOUNT (1<<23) -#define ZR_CLASS_HEALTH_INFECT_GAIN (1<<24) -#define ZR_CLASS_KILL_BONUS (1<<25) -#define ZR_CLASS_SPEED (1<<26) -#define ZR_CLASS_KNOCKBACK (1<<27) -#define ZR_CLASS_JUMP_HEIGHT (1<<28) -#define ZR_CLASS_JUMP_DISTANCE (1<<29) +#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) /** * @endsection */ @@ -246,6 +248,7 @@ enum ClassAttributes bool:Class_TeamDefault, Class_Flags, String:Class_Group[64], + String:Class_SM_Flags[64], String:Class_Name[64], String:Class_Description[256], @@ -559,6 +562,7 @@ ClassLoad() new String:name[64]; new String:group[64]; + new String:sm_flags[64]; new String:description[256]; new String:model_path[PLATFORM_MAX_PATH]; new String:immunity_mode[32]; @@ -588,6 +592,9 @@ ClassLoad() KvGetString(kvClassData, "group", group, sizeof(group), ZR_CLASS_DEFAULT_GROUP); strcopy(ClassData[ClassCount][Class_Group], 64, group); + KvGetString(kvClassData, "sm_flags", sm_flags, sizeof(sm_flags), ZR_CLASS_DEFAULT_SM_FLAGS); + strcopy(ClassData[ClassCount][Class_SM_Flags], 64, sm_flags); + KvGetString(kvClassData, "name", name, sizeof(name), ZR_CLASS_DEFAULT_NAME); strcopy(ClassData[ClassCount][Class_Name], 64, name); @@ -746,6 +753,7 @@ bool:ClassReloadDataCache() ClassDataCache[classindex][Class_TeamDefault] = ClassData[classindex][Class_TeamDefault]; ClassDataCache[classindex][Class_Flags] = ClassData[classindex][Class_Flags]; strcopy(ClassDataCache[classindex][Class_Group], 64, ClassData[classindex][Class_Group]); + strcopy(ClassDataCache[classindex][Class_SM_Flags], 64, ClassData[classindex][Class_SM_Flags]); strcopy(ClassDataCache[classindex][Class_Name], 64, ClassData[classindex][Class_Name]); strcopy(ClassDataCache[classindex][Class_Description], 256, ClassData[classindex][Class_Description]); @@ -813,6 +821,7 @@ bool:ClassReloadPlayerCache(client, classindex, cachetype = ZR_CLASS_CACHE_MODIF ClassPlayerCache[client][Class_TeamDefault] = ClassData[classindex][Class_TeamDefault]; ClassPlayerCache[client][Class_Flags] = ClassData[classindex][Class_Flags]; strcopy(ClassPlayerCache[client][Class_Group], 64, ClassData[classindex][Class_Group]); + strcopy(ClassPlayerCache[client][Class_SM_Flags], 64, ClassData[classindex][Class_SM_Flags]); strcopy(ClassPlayerCache[client][Class_Name], 64, ClassData[classindex][Class_Name]); strcopy(ClassPlayerCache[client][Class_Description], 256, ClassData[classindex][Class_Description]); @@ -855,6 +864,7 @@ bool:ClassReloadPlayerCache(client, classindex, cachetype = ZR_CLASS_CACHE_MODIF ClassPlayerCache[client][Class_TeamDefault] = ClassDataCache[classindex][Class_TeamDefault]; ClassPlayerCache[client][Class_Flags] = ClassDataCache[classindex][Class_Flags]; strcopy(ClassPlayerCache[client][Class_Group], 64, ClassDataCache[classindex][Class_Group]); + strcopy(ClassPlayerCache[client][Class_SM_Flags], 64, ClassDataCache[classindex][Class_SM_Flags]); strcopy(ClassPlayerCache[client][Class_Name], 64, ClassDataCache[classindex][Class_Name]); strcopy(ClassPlayerCache[client][Class_Description], 256, ClassDataCache[classindex][Class_Description]); @@ -1353,6 +1363,10 @@ ClassDumpData(index, cachetype, String:buffer[], maxlen) Format(attribute, sizeof(attribute), "group: \"%s\"\n", format_buffer); cellcount += StrCat(buffer, maxlen, attribute); + ClassGetSM_Flags(index, format_buffer, sizeof(format_buffer), cachetype); + Format(attribute, sizeof(attribute), "sm_flags: \"%s\"\n", format_buffer); + cellcount += StrCat(buffer, maxlen, attribute); + ClassGetName(index, format_buffer, sizeof(format_buffer), cachetype); Format(attribute, sizeof(attribute), "name: \"%s\"\n", format_buffer); cellcount += StrCat(buffer, maxlen, attribute);