2009-04-06 03:20:13 +02:00
/*
* ============================================================================
*
2009-07-05 08:49:23 +02:00
* Zombie : Reloaded
2009-04-06 03:20:13 +02:00
*
2009-06-12 05:51:26 +02:00
* File : filtertools . inc
* Type : Core
* Description : Class system tools ; validating , getting indexes or lists
*
* Copyright ( C ) 2009 Greyscale , Richard Helgeby
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http :// www . gnu . org / licenses />.
2009-04-06 03:20:13 +02:00
*
* ============================================================================
*/
/**
* Validates the team requirements in a class cache and check that theres at
* least one class for each team . Minium team requirements are zombies and
2009-04-11 01:56:22 +02:00
* humans . The admin team is optinal and not validated .
2009-04-06 03:20:13 +02:00
*
* @ param cachetype Optional . Specifies what class cache to validate . Options :
* ZR_CLASS_CACHE_ORIGINAL ( default , unchanged class data ),
* ZR_CLASS_CACHE_MODIFIED ( modified class data ) .
* @ return True if validation was successful , false otherwise .
*/
2009-05-30 04:17:01 +02:00
stock bool : ClassValidateTeamRequirements ( cachetype = ZR_CLASS_CACHE_ORIGINAL )
2009-04-06 03:20:13 +02:00
{
new zombieindex ;
new humanindex ;
// Check if there are no classes.
if ( ClassCount == 0 )
{
return false ;
}
// Test if a zombie and human class was found.
2009-06-22 01:09:51 +02:00
zombieindex = ClassGetFirstClass ( ZR_CLASS_TEAM_ZOMBIES , _ , _ , ZR_CLASS_SPECIALFLAGS , cachetype );
humanindex = ClassGetFirstClass ( ZR_CLASS_TEAM_HUMANS , _ , _ , ZR_CLASS_SPECIALFLAGS , cachetype );
2009-04-06 03:20:13 +02:00
2009-04-11 01:56:22 +02:00
// Validate indexes.
if ( ClassValidateIndex ( zombieindex ) && ClassValidateIndex ( humanindex ))
2009-04-06 03:20:13 +02:00
{
return true ;
}
return false ;
}
2009-04-11 01:56:22 +02:00
/**
* Validates that there ' s a class marked as team default for each team .
*
* @ param cachetype Optional . Specifies what class cache to validate . Options :
* ZR_CLASS_CACHE_ORIGINAL ( default , unchanged class data ),
* ZR_CLASS_CACHE_MODIFIED ( modified class data ) .
* @ return True if validation was successful , false otherwise .
*/
2009-05-30 04:17:01 +02:00
stock bool : ClassValidateTeamDefaults ( cachetype = ZR_CLASS_CACHE_ORIGINAL )
2009-04-11 01:56:22 +02:00
{
new zombieindex ;
new humanindex ;
// Check if there are no classes.
if ( ClassCount == 0 )
{
return false ;
}
// Test if a default zombie and human class was found.
2009-06-22 01:09:51 +02:00
zombieindex = ClassGetDefaultClass ( ZR_CLASS_TEAM_ZOMBIES , _ , _ , _ , cachetype );
humanindex = ClassGetDefaultClass ( ZR_CLASS_TEAM_HUMANS , _ , _ , _ , cachetype );
2009-04-11 01:56:22 +02:00
// Validate indexes.
if ( ClassValidateIndex ( zombieindex ) && ClassValidateIndex ( humanindex ))
{
return true ;
}
else
{
return false ;
}
}
2009-04-06 03:20:13 +02:00
/**
* Validates all the class attributes in the original class data array , to
2009-04-07 04:44:37 +02:00
* check if they have invalid values . Boolean settings are not validated .
2009-04-06 03:20:13 +02:00
*
* @ param classindex The index of the class to validate .
2009-04-07 04:44:37 +02:00
* @ return A value with attribute error flags .
2009-04-06 03:20:13 +02:00
*/
2009-05-30 04:17:01 +02:00
stock ClassValidateAttributes ( classindex )
2009-04-06 03:20:13 +02:00
{
2009-04-07 04:44:37 +02:00
// TODO: Validate immunity mode and amount.
new flags ;
2009-06-14 19:10:30 +02:00
// Team.
if ( ClassData [ classindex ][ class_team ] < ZR_CLASS_TEAM_MIN || ClassData [ classindex ][ class_team ] > ZR_CLASS_TEAM_MAX )
{
2009-06-22 01:09:51 +02:00
flags += ZR_CLASS_TEAM ;
}
// Class flags.
if ( ClassData [ classindex ][ class_flags ] < ZR_CLASS_FLAGS_MIN || ClassData [ classindex ][ class_flags ] > ZR_CLASS_FLAGS_MAX )
{
flags += ZR_CLASS_FLAGS ;
2009-06-14 19:10:30 +02:00
}
2009-04-07 04:44:37 +02:00
// Name.
2009-04-25 14:19:14 +02:00
if ( strlen ( ClassData [ classindex ][ class_name ]) < ZR_CLASS_NAME_MIN )
2009-04-07 04:44:37 +02:00
{
2009-06-22 01:09:51 +02:00
flags += ZR_CLASS_NAME ;
2009-04-07 04:44:37 +02:00
}
2009-05-10 18:49:47 +02:00
else
{
decl String : name [ 64 ];
strcopy ( name , sizeof ( name ), ClassData [ classindex ][ class_name ]);
2009-06-14 19:10:30 +02:00
// Check for reserved name keyworks. These aren't allowed as names.
2009-05-10 18:49:47 +02:00
if ( StrEqual ( name , " all " , false ) ||
StrEqual ( name , " humans " , false ) ||
StrEqual ( name , " zombies " , false ) ||
StrEqual ( name , " admins " , false ))
{
2009-06-22 01:09:51 +02:00
flags += ZR_CLASS_NAME ;
2009-05-10 18:49:47 +02:00
}
}
2009-04-07 04:44:37 +02:00
// Description.
2009-04-25 14:19:14 +02:00
if ( strlen ( ClassData [ classindex ][ class_description ]) < ZR_CLASS_DESCRIPTION_MIN )
2009-04-07 04:44:37 +02:00
{
2009-06-22 01:09:51 +02:00
flags += ZR_CLASS_DESCRIPTION ;
2009-04-07 04:44:37 +02:00
}
// Model path.
2009-04-25 14:19:14 +02:00
decl String : model_path [ PLATFORM_MAX_PATH ];
2009-04-07 04:44:37 +02:00
if ( strcopy ( model_path , sizeof ( model_path ), ClassData [ classindex ][ class_model_path ]) == 0 )
{
2009-06-22 01:09:51 +02:00
flags += ZR_CLASS_MODEL_PATH ;
2009-04-07 04:44:37 +02:00
}
else
{
2009-06-18 02:09:55 +02:00
// Check if a model different from default or random is specified.
if ( ! StrEqual ( model_path , " random " , false ) && ! StrEqual ( model_path , " default " , false ))
2009-04-07 04:44:37 +02:00
{
// Check if the file exists.
if ( ! FileExists ( model_path ))
{
2009-06-22 01:09:51 +02:00
flags += ZR_CLASS_MODEL_PATH ;
2009-04-07 04:44:37 +02:00
}
}
}
// Alpha, initial.
new alpha_initial = ClassData [ classindex ][ class_alpha_initial ];
2009-04-25 14:19:14 +02:00
if ( ! ( alpha_initial >= ZR_CLASS_ALPHA_INITIAL_MIN && alpha_initial <= ZR_CLASS_ALPHA_INITIAL_MAX ))
2009-04-07 04:44:37 +02:00
{
2009-06-22 01:09:51 +02:00
flags += ZR_CLASS_ALPHA_INITIAL ;
2009-04-07 04:44:37 +02:00
}
// Alpha, damaged.
new alpha_damaged = ClassData [ classindex ][ class_alpha_damaged ];
2009-04-25 14:19:14 +02:00
if ( ! ( alpha_damaged >= ZR_CLASS_ALPHA_DAMAGED_MIN && alpha_damaged <= ZR_CLASS_ALPHA_DAMAGED_MAX ))
2009-04-07 04:44:37 +02:00
{
2009-06-22 01:09:51 +02:00
flags += ZR_CLASS_ALPHA_DAMAGED ;
2009-04-07 04:44:37 +02:00
}
// Alpha, damage.
new alpha_damage = ClassData [ classindex ][ class_alpha_damage ];
2009-04-25 14:19:14 +02:00
if ( ! ( alpha_damage >= ZR_CLASS_ALPHA_DAMAGE_MIN && alpha_damage <= ZR_CLASS_ALPHA_DAMAGE_MAX ))
2009-04-07 04:44:37 +02:00
{
2009-06-22 01:09:51 +02:00
flags += ZR_CLASS_ALPHA_DAMAGE ;
2009-04-07 04:44:37 +02:00
}
// Overlay path.
2009-04-25 14:19:14 +02:00
decl String : overlay_path [ PLATFORM_MAX_PATH ];
decl String : overlay [ PLATFORM_MAX_PATH ];
2009-04-11 01:56:22 +02:00
if ( strcopy ( overlay_path , sizeof ( overlay_path ), ClassData [ classindex ][ class_overlay_path ]) > 0 )
2009-04-07 04:44:37 +02:00
{
// Check if the file exists.
2009-04-11 01:56:22 +02:00
Format ( overlay , sizeof ( overlay ), " materials/%s.vmt " , overlay_path );
if ( ! FileExists ( overlay ))
2009-04-07 04:44:37 +02:00
{
2009-06-22 01:09:51 +02:00
flags += ZR_CLASS_OVERLAY_PATH ;
2009-04-07 04:44:37 +02:00
}
}
// Field of view.
new fov = ClassData [ classindex ][ class_fov ];
2009-04-25 14:19:14 +02:00
if ( ! ( fov >= ZR_CLASS_FOV_MIN && fov <= ZR_CLASS_FOV_MAX ))
2009-04-07 04:44:37 +02:00
{
2009-06-22 01:09:51 +02:00
flags += ZR_CLASS_FOV ;
2009-04-07 04:44:37 +02:00
}
// Napalm time.
new Float : napalm_time = ClassData [ classindex ][ class_napalm_time ];
2009-04-25 14:19:14 +02:00
if ( ! ( napalm_time >= ZR_CLASS_NAPALM_TIME_MIN && napalm_time <= ZR_CLASS_NAPALM_TIME_MAX ))
2009-04-07 04:44:37 +02:00
{
2009-06-22 01:09:51 +02:00
flags += ZR_CLASS_NAPALM_TIME ;
2009-04-25 14:19:14 +02:00
}
// Health.
new health = ClassData [ classindex ][ class_health ];
if ( ! ( health >= ZR_CLASS_HEALTH_MIN && health <= ZR_CLASS_HEALTH_MAX ))
{
2009-06-22 01:09:51 +02:00
flags += ZR_CLASS_HEALTH ;
2009-04-07 04:44:37 +02:00
}
// Health regen interval.
new Float : regen_interval = ClassData [ classindex ][ class_health_regen_interval ];
2009-06-22 01:09:51 +02:00
if ( ! ( regen_interval >= ZR_CLASS_REGEN_INTERVAL_MIN && regen_interval <= ZR_CLASS_REGEN_INTERVAL_MAX ))
2009-04-07 04:44:37 +02:00
{
2009-06-22 01:09:51 +02:00
flags += ZR_CLASS_HEALTH_REGEN_INTERVAL ;
2009-06-18 02:09:55 +02:00
}
// Health regen amount.
new regen_amount = ClassData [ classindex ][ class_health_regen_amount ];
2009-06-22 01:09:51 +02:00
if ( ! ( regen_amount >= ZR_CLASS_REGEN_AMOUNT_MIN && regen_amount <= ZR_CLASS_REGEN_AMOUNT_MAX ))
2009-06-18 02:09:55 +02:00
{
2009-06-22 01:09:51 +02:00
flags += ZR_CLASS_HEALTH_REGEN_AMOUNT ;
2009-04-07 04:44:37 +02:00
}
// Health infect gain.
new infect_gain = ClassData [ classindex ][ class_health_infect_gain ];
2009-04-25 14:19:14 +02:00
if ( ! ( infect_gain >= ZR_CLASS_HEALTH_INFECT_GAIN_MIN && infect_gain <= ZR_CLASS_HEALTH_INFECT_GAIN_MAX ))
2009-04-07 04:44:37 +02:00
{
2009-06-22 01:09:51 +02:00
flags += ZR_CLASS_HEALTH_INFECT_GAIN ;
2009-04-07 04:44:37 +02:00
}
// Kill bonus.
new kill_bonus = ClassData [ classindex ][ class_kill_bonus ];
2009-04-25 14:19:14 +02:00
if ( ! ( kill_bonus >= ZR_CLASS_KILL_BONUS_MIN && kill_bonus <= ZR_CLASS_KILL_BONUS_MAX ))
2009-04-07 04:44:37 +02:00
{
2009-06-22 01:09:51 +02:00
flags += ZR_CLASS_KILL_BONUS ;
2009-04-07 04:44:37 +02:00
}
// Speed.
new Float : speed = ClassData [ classindex ][ class_speed ];
2009-04-25 14:19:14 +02:00
if ( ! ( speed >= ZR_CLASS_SPEED_MIN && speed <= ZR_CLASS_SPEED_MAX ))
2009-04-07 04:44:37 +02:00
{
2009-06-22 01:09:51 +02:00
flags += ZR_CLASS_SPEED ;
2009-04-07 04:44:37 +02:00
}
// Knockback.
new Float : knockback = ClassData [ classindex ][ class_knockback ];
2009-04-25 14:19:14 +02:00
if ( ! ( knockback >= ZR_CLASS_KNOCKBACK_MIN && knockback <= ZR_CLASS_KNOCKBACK_MAX ))
{
2009-06-22 01:09:51 +02:00
flags += ZR_CLASS_KNOCKBACK ;
2009-04-25 14:19:14 +02:00
}
// Jump height.
new Float : jump_height = ClassData [ classindex ][ class_jump_height ];
if ( ! ( jump_height >= ZR_CLASS_JUMP_HEIGHT_MIN && jump_height <= ZR_CLASS_JUMP_HEIGHT_MAX ))
{
2009-06-22 01:09:51 +02:00
flags += ZR_CLASS_JUMP_HEIGHT ;
2009-04-25 14:19:14 +02:00
}
// Jump distance.
new Float : jump_distance = ClassData [ classindex ][ class_jump_distance ];
if ( ! ( jump_distance >= ZR_CLASS_JUMP_DISTANCE_MIN && jump_distance <= ZR_CLASS_JUMP_DISTANCE_MAX ))
2009-04-07 04:44:37 +02:00
{
2009-06-22 01:09:51 +02:00
flags += ZR_CLASS_JUMP_DISTANCE ;
2009-04-07 04:44:37 +02:00
}
return flags ;
2009-04-06 03:20:13 +02:00
}
/**
2009-06-22 01:09:51 +02:00
* Checks if the specified class index is a valid index .
2009-04-06 03:20:13 +02:00
*
* @ param classindex The class index to validate .
* @ return True if the class exist , false otherwise .
*/
2009-05-30 04:17:01 +02:00
stock bool : ClassValidateIndex ( classindex )
2009-04-06 03:20:13 +02:00
{
2009-04-07 04:44:37 +02:00
if ( classindex >= 0 && classindex < ClassCount )
2009-04-06 03:20:13 +02:00
{
return true ;
}
else
{
return false ;
}
}
/**
* Compares the class team ID with a team ID .
*
* @ param index Index of the class in a class cache or a client index ,
* depending on the cache type specified .
* @ param teamid The team ID to compare with the class .
* @ 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 .
* ZR_CLASS_CACHE_PLAYER - Player cache . If this one is used ,
* index will be used as a client index .
* @ return True if equal , false otherwise .
*/
2009-05-30 04:17:01 +02:00
stock bool : ClassTeamCompare ( index , teamid , cachetype = ZR_CLASS_CACHE_MODIFIED )
2009-04-06 03:20:13 +02:00
{
switch ( cachetype )
{
case ZR_CLASS_CACHE_ORIGINAL :
{
if ( ClassData [ index ][ class_team ] == teamid )
{
return true ;
}
}
case ZR_CLASS_CACHE_MODIFIED :
{
if ( ClassDataCache [ index ][ class_team ] == teamid )
{
return true ;
}
}
case ZR_CLASS_CACHE_PLAYER :
{
if ( ClassPlayerCache [ index ][ class_team ] == teamid )
{
return true ;
}
}
}
return false ;
}
/**
* Gets the first class index of a class with the specified name ( not a case
* sensitive search ) .
*
* @ param name The name 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 .
*/
2009-05-30 04:17:01 +02:00
stock ClassGetIndex ( const String : name [], cachetype = ZR_CLASS_CACHE_MODIFIED )
2009-04-06 03:20:13 +02:00
{
decl String : current_name [ 64 ];
// Check if there are no classes.
if ( ClassCount == 0 )
{
return false ;
}
// Loop through all classes.
for ( new classindex = 0 ; classindex < ClassCount ; classindex ++ )
{
// Get its name and compare it with the specified class name.
2009-04-11 01:56:22 +02:00
ClassGetName ( classindex , current_name , sizeof ( current_name ), cachetype );
2009-04-06 03:20:13 +02:00
if ( strcmp ( name , current_name , 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 .
*
* @ param client The client index .
* @ return The active class index . - 1 on error or if a spectactor .
*/
2009-05-30 04:17:01 +02:00
stock ClassGetActiveIndex ( client )
2009-04-06 03:20:13 +02:00
{
2009-07-16 10:05:40 +02:00
new teamid ;
2009-04-06 03:20:13 +02:00
2009-04-25 14:19:14 +02:00
if ( ! ZRIsClientOnTeam ( client ))
2009-04-06 03:20:13 +02:00
{
// No active team.
return - 1 ;
}
2009-04-25 14:19:14 +02:00
// Check if the player currently is in admin mode.
if ( ClassPlayerInAdminMode [ client ])
2009-04-06 03:20:13 +02:00
{
2009-04-25 14:19:14 +02:00
teamid = ZR_CLASS_TEAM_ADMINS ;
2009-04-06 03:20:13 +02:00
}
else
{
2009-04-25 14:19:14 +02:00
// Not in admin mode, check if player is human or zombie.
2009-04-27 19:51:29 +02:00
if ( InfectIsClientHuman ( client ))
2009-04-25 14:19:14 +02:00
{
teamid = ZR_CLASS_TEAM_HUMANS ;
}
else
{
teamid = ZR_CLASS_TEAM_ZOMBIES ;
}
2009-04-06 03:20:13 +02:00
}
2009-04-25 14:19:14 +02:00
// Return the active class for the active team.
2009-04-11 01:56:22 +02:00
return ClassSelected [ client ][ teamid ];
2009-04-06 03:20:13 +02:00
}
2009-06-18 02:09:55 +02:00
/**
* 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 ;
}
}
2009-06-22 01:09:51 +02:00
/**
* Check if a class pass the specified flag filters .
*
* @ param index Index of the class in a class cache or a client index ,
* depending on the cache type specified .
* @ param require Class flags to require . 0 for no filter .
* @ param deny Class flags to exclude . 0 for no filter .
* @ param cachetype Specifies what class cache to read from . Options :
* ZR_CLASS_CACHE_ORIGINAL - Unchanced class data .
* ZR_CLASS_CACHE_MODIFIED ( default ) - Changed / newest
* class data .
* ZR_CLASS_CACHE_PLAYER - Player cache . If this one is
* used index will be used as a client index .
* @ return True if passed , false otherwise .
*/
stock bool : ClassFlagFilterMatch ( index , require , deny , cachetype )
{
new flags ;
new bool : requirepassed ;
new bool : denypassed ;
// Do quick check for optimization reasons: Check if no flags are specified.
if ( require == 0 && deny == 0 )
{
return true ;
}
// Cache flags.
flags = ClassGetFlags ( index , cachetype );
// Match require filter.
if ( require == 0 || flags & require )
{
// All required flags are set.
requirepassed = true ;
}
else
{
// Not all required flags are set.
requirepassed = false ;
}
// Match deny filter.
2009-06-22 16:10:40 +02:00
if ( deny == 0 || ! ( flags & deny ))
2009-06-22 01:09:51 +02:00
{
// No denied flags are set.
denypassed = true ;
}
else
{
// It has denied flags set.
denypassed = false ;
}
// Check if required and denied flags passed the filter.
if ( requirepassed && denypassed )
{
// The class pass the filter.
return true ;
}
else
{
// The class didn't pass the filter.
return false ;
}
}
2009-08-09 22:44:28 +02:00
/**
* Decides whether a class selection menu should be enabled . The decision is
* based on zr_class_allow_ * console variables .
*
* @ param team Optional . Team ID to match . Default is all .
* @ return True if allowed , false otherwise .
*/
bool : ClassAllowSelection ( client , team = - 1 )
{
// Get selection settings.
new bool : zombie = GetConVarBool ( g_hCvarsList [ CVAR_CLASSES_ZOMBIE_SELECT ]);
new bool : human = GetConVarBool ( g_hCvarsList [ CVAR_CLASSES_HUMAN_SELECT ]);
new bool : admin = GetConVarBool ( g_hCvarsList [ CVAR_CLASSES_ADMIN_SELECT ]);
// Since admin mode classes are optional they must be counted to verify
// that they exist.
new bool : adminexist ;
// Check if player is admin.
new bool : isadmin = ZRIsClientAdmin ( client );
// Only count admin mode classes if client is admin for better performance.
if ( isadmin )
{
adminexist = ClassCountTeam ( ZR_CLASS_TEAM_ADMINS ) > 0 ;
}
// Check if a team id is specified.
if ( team >= 0 )
{
// Check team and return the corresponding selection setting.
switch ( team )
{
case ZR_CLASS_TEAM_ZOMBIES :
{
return zombie ;
}
case ZR_CLASS_TEAM_HUMANS :
{
return human ;
}
case ZR_CLASS_TEAM_ADMINS :
{
// Player must be admin to select admin mode classes.
return admin && isadmin && adminexist ;
}
}
// Team ID didn't match.
return false ;
}
else
{
// Check zombie and human.
return zombie || human ;
}
}
2009-04-06 03:20:13 +02:00
/**
* Gets all class indexes or from a specified team , and adds them to the
* specified array .
*
2009-06-19 02:31:05 +02:00
* @ param array The destination array to add class indexes .
* @ param teamfilter Optional . The team ID to filter . A negative value
* for no filter ( default ) .
* @ param ignoreEnabled Optional . Ignore whether the class is enabled or
* not . Default is false .
2009-06-22 01:09:51 +02:00
* @ param requireflags Optional . Require certain class flags to be set .
* Default is no filtering .
* @ param denyflags Optional . Require certain class flags to be off .
* Default is no filtering .
2009-06-19 02:31:05 +02:00
* @ 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 .
2009-04-06 03:20:13 +02:00
* @ return True on success . False on error or if no classes were added or
* found .
*/
2009-06-22 01:09:51 +02:00
stock bool : ClassAddToArray ( Handle : array , teamfilter = - 1 , bool : ignoreEnabled = false , requireflags = 0 , denyflags = 0 , cachetype = ZR_CLASS_CACHE_MODIFIED )
2009-04-06 03:20:13 +02:00
{
// Validate the array.
if ( array == INVALID_HANDLE )
{
return false ;
}
// Check if there are no classes.
if ( ClassCount == 0 )
{
return false ;
}
// Store a local boolean that says if the user specified a team filter or not.
new bool : has_filter = bool : ( teamfilter >= 0 );
new classes_added ;
// Loop through all classes.
for ( new classindex = 0 ; classindex < ClassCount ; classindex ++ )
{
if ( ! ignoreEnabled && ! ClassIsEnabled ( classindex , cachetype ))
{
// The class is disabled and the enabled attribute is NOT ignored.
// Skip to the next class.
continue ;
}
2009-06-22 01:09:51 +02:00
// Check flag filter match.
if ( ! ClassFlagFilterMatch ( classindex , requireflags , denyflags , cachetype ))
2009-06-19 02:31:05 +02:00
{
2009-06-22 01:09:51 +02:00
// The class didn't pass filter.
2009-06-19 02:31:05 +02:00
continue ;
}
2009-04-06 03:20:13 +02:00
// Check team filtering.
if ( has_filter )
{
// Only add classes with matching team ID.
if ( ClassGetTeamID ( classindex , cachetype ) == teamfilter )
{
// Team ID match. Add class index to array.
PushArrayCell ( array , classindex );
classes_added ++ ;
}
}
else
{
// No filter. Add any class to the array.
PushArrayCell ( array , classindex );
classes_added ++ ;
}
}
if ( classes_added )
{
return true ;
}
else
{
// No classes were found/added.
return false ;
}
}
2009-04-18 02:22:13 +02:00
/**
* Counts total classes or classes in the specified team .
*
* @ param teamfilter Optional . The team ID to filter . Negative value for
* no filter ( default ) .
2009-06-19 02:31:05 +02:00
* @ param ignoreEnabled Optional . Ignore whether the class is enabled or
* not . Default is false .
2009-06-22 01:09:51 +02:00
* @ param requireflags Optional . Require certain class flags to be set .
* Default is no filtering .
* @ param denyflags Optional . Require certain class flags to be off .
* Default is no filtering .
2009-04-18 02:22:13 +02:00
* @ 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 Number of total classes or classes in the specified team .
*/
2009-06-22 01:09:51 +02:00
stock ClassCountTeam ( teamfilter = - 1 , bool : ignoreEnabled = false , requireflags = 0 , denyflags = 0 , cachetype = ZR_CLASS_CACHE_MODIFIED )
2009-04-18 02:22:13 +02:00
{
// Check if there are no classes.
if ( ClassCount == 0 )
{
return 0 ;
}
// Store a local boolean that says if the user specified a team filter or not.
new bool : has_filter = bool : ( teamfilter >= 0 );
new count ;
// Loop through all classes.
for ( new classindex = 0 ; classindex < ClassCount ; classindex ++ )
{
if ( ! ignoreEnabled && ! ClassIsEnabled ( classindex , cachetype ))
{
// The class is disabled and the enabled attribute is NOT ignored.
// Skip to the next class.
continue ;
}
2009-06-22 01:09:51 +02:00
// Check flag filter match.
if ( ! ClassFlagFilterMatch ( classindex , requireflags , denyflags , cachetype ))
2009-06-19 02:31:05 +02:00
{
2009-06-22 01:09:51 +02:00
// The class didn't pass filter.
2009-06-19 02:31:05 +02:00
continue ;
}
2009-04-18 02:22:13 +02:00
// Check team filtering.
if ( has_filter )
{
// Only add classes with matching team ID.
if ( ClassGetTeamID ( classindex , cachetype ) == teamfilter )
{
// Team ID match. Increment counter.
count ++ ;
}
}
else
{
// No filter. Increment counter.
count ++ ;
}
}
// Return number of classes found.
return count ;
}
2009-04-06 03:20:13 +02:00
/**
* Gets a random class index from a specified team or from all classes .
*
2009-06-19 02:31:05 +02:00
* @ param teamfilter Optional . The team ID to filter . A negative value
* for no filter ( default ) .
* @ param ignoreEnabled Optional . Ignore whether the class is enabled or
* not . Default is false .
2009-06-22 01:09:51 +02:00
* @ param requireflags Optional . Require certain class flags to be set .
* Default is no filtering .
* @ param denyflags Optional . Require certain class flags to be off .
* Default is no filtering .
2009-06-19 02:31:05 +02:00
* @ 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 .
2009-04-06 03:20:13 +02:00
* @ return The class index if successful , or - 1 on error .
*/
2009-06-22 01:09:51 +02:00
stock ClassGetRandomClass ( teamfilter = - 1 , bool : ignoreEnabled = false , requireflags = 0 , denyflags = 0 , cachetype = ZR_CLASS_CACHE_MODIFIED )
2009-04-06 03:20:13 +02:00
{
new Handle : classarray ;
new arraycount ;
new randnum ;
2009-06-22 18:11:31 +02:00
new buffer ;
2009-04-06 03:20:13 +02:00
classarray = CreateArray ();
// Try to get a class list.
2009-06-22 01:09:51 +02:00
if ( ClassAddToArray ( classarray , teamfilter , ignoreEnabled , requireflags , denyflags , cachetype ))
2009-04-06 03:20:13 +02:00
{
// Get a random index from the new class array.
arraycount = GetArraySize ( classarray );
randnum = GetRandomInt ( 0 , arraycount - 1 );
// Return the value at the random index.
2009-06-22 18:11:31 +02:00
buffer = GetArrayCell ( classarray , randnum );
CloseHandle ( classarray );
return buffer ;
2009-04-06 03:20:13 +02:00
}
else
{
// Failed to get a random class.
2009-06-22 18:11:31 +02:00
CloseHandle ( classarray );
2009-04-06 03:20:13 +02:00
return - 1 ;
}
}
/**
* Gets the first class index , or the first class index with the specified team
* ID .
*
2009-06-19 02:31:05 +02:00
* @ param teamfilter Optional . The team ID to filter . A negative value
* for no filter ( default ) .
* @ param ignoreEnabled Optional . Ignore whether the class is enabled or
* not . Default is false .
2009-06-22 01:09:51 +02:00
* @ param requireflags Optional . Require certain class flags to be set .
* Default is no filtering .
* @ param denyflags Optional . Require certain class flags to be off .
* Default is no filtering .
2009-06-19 02:31:05 +02:00
* @ 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 .
2009-04-06 03:20:13 +02:00
* @ return The first class index , or the first class index with the specified
* team ID . - 1 on error .
*/
2009-06-22 01:09:51 +02:00
stock ClassGetFirstClass ( teamfilter = - 1 , bool : ignoreEnabled = false , requireflags = 0 , denyflags = 0 , cachetype = ZR_CLASS_CACHE_MODIFIED )
2009-04-06 03:20:13 +02:00
{
// Check if there are no classes.
if ( ClassCount == 0 )
{
return false ;
}
new bool : has_filter = bool : ( teamfilter >= 0 );
// Loop through all classes.
for ( new classindex = 0 ; classindex < ClassCount ; classindex ++ )
{
if ( ! ignoreEnabled && ! ClassIsEnabled ( classindex , cachetype ))
{
2009-06-19 02:31:05 +02:00
// The class is disabled and the enabled attribute is NOT ignored.
// Skip to the next class.
continue ;
}
2009-06-22 01:09:51 +02:00
// Check flag filter match.
if ( ! ClassFlagFilterMatch ( classindex , requireflags , denyflags , cachetype ))
2009-06-19 02:31:05 +02:00
{
2009-06-22 01:09:51 +02:00
// The class didn't pass filter.
2009-04-06 03:20:13 +02:00
continue ;
}
if ( has_filter )
{
if ( teamfilter == ClassGetTeamID ( classindex , cachetype ))
{
// Team ID match. Return the class index.
return classindex ;
}
}
else
{
// No team filter. Return the class index.
return classindex ;
}
}
return - 1 ;
}
2009-04-11 01:56:22 +02:00
/**
* Gets the first class marked as default for the specified team .
*
2009-06-19 02:31:05 +02:00
* @ param teamid The team ID .
* @ param ignoreEnabled Optional . Ignore whether the class is enabled or
* not . Default is false .
2009-06-22 01:09:51 +02:00
* @ param requireflags Optional . Require certain class flags to be set .
* Default is no filtering .
* @ param denyflags Optional . Require certain class flags to be off .
* Default is to deny classes with special flags
* ( ZR_CLASS_SPECIALFLAGS ) .
2009-06-19 02:31:05 +02:00
* @ 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 .
2009-04-11 01:56:22 +02:00
* @ return The first default class index . - 1 on error .
*/
2009-06-22 01:09:51 +02:00
stock ClassGetDefaultClass ( teamid , bool : ignoreEnabled = false , requireflags = 0 , denyflags = ZR_CLASS_SPECIALFLAGS , cachetype = ZR_CLASS_CACHE_MODIFIED )
2009-04-11 01:56:22 +02:00
{
new Handle : classarray ;
new arraycount ;
new classindex ;
classarray = CreateArray ();
// Get all classes from the specified team.
2009-06-22 01:09:51 +02:00
if ( ! ClassAddToArray ( classarray , teamid , ignoreEnabled , requireflags , denyflags , cachetype ))
2009-04-11 01:56:22 +02:00
{
// Failed to get classes.
2009-06-22 18:11:31 +02:00
CloseHandle ( classarray );
2009-04-11 01:56:22 +02:00
return - 1 ;
}
// Loop through all classes and return the first class marked as team default.
arraycount = GetArraySize ( classarray );
for ( new i = 0 ; i < arraycount ; i ++ )
{
// Get class index from the array.
classindex = GetArrayCell ( classarray , i );
// Check if the current class is marked as team default.
if ( ClassGetTeamDefault ( classindex , cachetype ))
{
// Default class found.
2009-06-22 18:11:31 +02:00
CloseHandle ( classarray );
2009-04-11 01:56:22 +02:00
return classindex ;
}
}
2009-06-22 18:11:31 +02:00
CloseHandle ( classarray );
2009-04-11 01:56:22 +02:00
return - 1 ;
}
2009-04-06 03:20:13 +02:00
/**
* Gets the default class index for the specified team configured to be used
* when players join the server .
*
* @ param teamid The team ID .
* @ 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 of the default class for the specified team if
* successful . - 1 on critical errors . Otherwise it will try to fall
* back on the first class in the specified team .
*/
2009-05-30 04:17:01 +02:00
stock ClassGetDefaultSpawnClass ( teamid , cachetype = ZR_CLASS_CACHE_MODIFIED )
2009-04-06 03:20:13 +02:00
{
decl String : classname [ 64 ];
new classindex ;
// Get the default class name from the correct CVAR depending on teamid.
switch ( teamid )
{
case ZR_CLASS_TEAM_ZOMBIES :
{
2009-04-20 02:56:26 +02:00
GetConVarString ( g_hCvarsList [ CVAR_CLASSES_DEFAULT_ZOMBIE ], classname , sizeof ( classname ));
2009-04-06 03:20:13 +02:00
}
case ZR_CLASS_TEAM_HUMANS :
{
2009-04-20 02:56:26 +02:00
GetConVarString ( g_hCvarsList [ CVAR_CLASSES_DEFAULT_HUMAN ], classname , sizeof ( classname ));
2009-04-06 03:20:13 +02:00
}
case ZR_CLASS_TEAM_ADMINS :
{
2009-04-20 02:56:26 +02:00
GetConVarString ( g_hCvarsList [ CVAR_CLASSES_DEFAULT_ADMIN ], classname , sizeof ( classname ));
2009-04-06 03:20:13 +02:00
}
default :
{
// Invalid team ID.
return - 1 ;
}
}
// Check if the class name isn't empty.
2009-04-11 01:56:22 +02:00
if ( strlen ( classname ) > 0 )
2009-04-06 03:20:13 +02:00
{
// Check if the user set "random" as default class.
if ( strcmp ( classname , " random " , false ) == 0 )
{
2009-06-22 01:09:51 +02:00
// Get a list of all classes with the specified team ID. Deny
// classes with special flags.
classindex = ClassGetRandomClass ( teamid , _ , _ , ZR_CLASS_SPECIALFLAGS , cachetype );
2009-04-06 03:20:13 +02:00
// Validate the result, in case there were errors.
if ( ClassValidateIndex ( classindex ))
{
return classindex ;
}
else
{
// Invalid index. The ClassGetRandomClass function is pretty
// failsafe. So if we can't get a class index here, it's a
// critical error. No reason to fall back on other solutions.
return - 1 ;
}
}
else
{
// The user set a spesific class.
// Try to get the class index with the specified class name.
2009-04-11 01:56:22 +02:00
classindex = ClassGetIndex ( classname , cachetype );
2009-04-06 03:20:13 +02:00
// Validate the class index and check if the team IDs match.
if ( ClassValidateIndex ( classindex ) && ( teamid == ClassGetTeamID ( classindex , cachetype )))
{
return classindex ;
}
else
{
// The class index is invalid or the team IDs didn't match.
// Because it's user input, we'll fall back to the first class
// in the specified team, and log a warning.
2009-06-22 16:29:13 +02:00
classindex = ClassGetFirstClass ( teamid , _ , _ , ZR_CLASS_SPECIALFLAGS , cachetype );
2009-04-06 03:20:13 +02:00
2009-06-01 23:29:26 +02:00
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 );
2009-04-06 03:20:13 +02:00
// Validate the new index.
if ( ClassValidateIndex ( classindex ))
{
// Log a warning.
2009-06-01 23:29:26 +02:00
LogEvent ( false , LogType_Error , LOG_CORE_EVENTS , LogModule_Playerclasses , " Default Spawn Class " , " Warning: The default class name \" %s \" does not exist or matches the team ID. " , classname );
2009-04-06 03:20:13 +02:00
return classindex ;
}
else
{
// Something went wrong. This is a critical error.
return - 1 ;
}
}
}
}
else
{
2009-04-11 01:56:22 +02:00
// Blank class name, get the default class and return the index.
2009-06-22 01:09:51 +02:00
return ClassGetDefaultClass ( teamid , _ , _ , ZR_CLASS_SPECIALFLAGS , cachetype );
2009-04-06 03:20:13 +02:00
}
}